3.透过现象看本质-webgl加载geojson

通过canvas加载geojson深入解析添加矢量数据本质

// 自行获取json数据
const [state, rs, err] = await getData('./sx.json')
//公共数据
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext("2d"); // canvas元素的contex对象
let width = window.innerWidth; // 画布宽度
let height = window.innerHeight; // 画布高度
canvas.width = width;
canvas.height = height;
let center = [108, 36]
let scale = 100
let zoom = 5
let zooms = {
    5: 100,
    6: 110,
    7: 130,
    8: 170,
    9: 250,
    10: 410,
    11: 730,
    12: 1470,
    13: 2600,
    14: 5000,
    15: 10000,
    16: 20000,
    17: 40000
}
// 坐标转换
function coordTrans(coord, center) {
    // coord和center传入的都要是原始经纬度坐标
    // 经纬度坐标,纬度大的点在canvas的坐标系中会处于下方,而现实中应该处于上方,
    // 所以对所有点纬度坐标进行取反修正
    coord = [coord[0], -coord[1]]
    center = [center[0], -center[1]]

    // 然后把中心点已到坐标系原点,重新计算其他点坐标
    return [coord[0] - center[0], coord[1] - center[1]]
}

// 渲染地图
function draw() {
    //清除画布
    ctx.clearRect(0, 0, width, height);
    ctx.save(); //保存初始状态
    ctx.translate(width / 2, height / 2) // 移动坐标系原点到canvas画布中心
    ctx.strokeStyle = '#00ff00'
    ctx.strokeWidth = '1px'

    // 开始设置路径
    ctx.beginPath();

    // 陕西地市
    rs.features.forEach((feature, featureIndex) => {

        feature.geometry.coordinates.forEach((subCoordss, index) => {
            subCoordss.forEach((subCoords, index1) => {
                ctx.beginPath();
                // 
                subCoords.forEach((coord, index1) => {
                    // 坐标转换
                    const real_coord = coordTrans(coord, center)
                    if(index1 == 0) {
                        // 设置成跳跃点
                        ctx.moveTo(real_coord[0] * scale, real_coord[1] * scale);

                    } else {
                        // 非起点
                        ctx.lineTo(real_coord[0] * scale, real_coord[1] * scale);
                    }
                })
                ctx.closePath(); //当前路径封闭
                ctx.fillStyle = 'skyblue'; //颜色填充
                ctx.fill(); //执行
                ctx.strokeStyle = 'red';
                ctx.stroke();

            })
        })
        if(zoom <= 8) {
            ctx.textAlign = 'center'
            ctx.font = "normal bold 20px 楷体"
            ctx.textBaseline = 'middle'

            ctx.fillStyle = 'black'
            const real_coordt = coordTrans(feature.properties.centroid, center)
            ctx.fillText(feature.properties.name, real_coordt[0] * scale, real_coordt[1] * scale)
        }

    })

    

    ctx.restore(); //回退状态
    window.requestAnimationFrame(draw)
}

// 请求关键帧
window.requestAnimationFrame(draw)
canvas.addEventListener('mousewheel', function(e) {

    if(e.wheelDelta > 0) { //当滑轮向上滚动时
        if(zoom < 17) {
            zoom++

        }

    } else if(e.wheelDelta < 0) { //当滑轮向下滚动时
        if(zoom > 5) {
            zoom--
        }

    }
    scale = zooms[zoom]

})
window.addEventListener('resize', function(e) {
    width = window.innerWidth; // 画布宽度
    height = window.innerHeight; // 画布高度
    canvas.width = width;
    canvas.height = height;
});

let ppxy = [0, 0]
let ppcenter = [108, 36]
canvas.addEventListener('mousedown', function(e) {
    if(e.buttons==1){
    ppxy = [e.offsetX, e.offsetY]
    ppcenter = [center[0], center[1]]
    canvas.addEventListener('mousemove', movto, false)
    canvas.addEventListener('mouseup', moup, false)
    }
})
canvas.addEventListener('click', mapclick, false)

function moup(e) {
    ppxy = [0, 0]
    e.stopPropagation()
    canvas.removeEventListener('mousemove', movto)
}

function movto(e) {

    let offx = ppcenter[0] - (e.offsetX - ppxy[0]) / scale
    let offy = ppcenter[1] + (e.offsetY - ppxy[1]) / scale
    center = [offx, offy]

}

function mapclick(e) {
    if(e.button==0){
        
    
    console.log(center[0] - (e.offsetX - canvas.width / 2) / scale, center[1] - (e.offsetY - canvas.height / 2) / scale)
    }

}

加载完成如图所示:
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫雪giser

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值