leaflet 叠加天地图经纬度瓦片绘制网格

1、index.html

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.min.css" rel="stylesheet">
    <style>
        * {
            padding: 0;
            margin: 0;
        }
 
        html,
        body,
        #map {
            height: 100%;
            width: 100%;
            overflow: hidden;
        }
    </style>
</head>
 
<body>
    <div id="map"></div>
    <script type="module">
        import {bboxToGrid, gridToBbox, getGridDatasOfView} from './util.js'
 
        L.CRS.CustomEPSG4326 = L.extend({}, L.CRS.Earth, {
            code: 'EPSG:4326',
            projection: L.Projection.LonLat,
            transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),
            scale: function (zoom) {
                return 256 * Math.pow(2, zoom - 1);
            }
        });
 
        const token = '天地图的key';
        let map = L.map('map', {
            crs: L.CRS.CustomEPSG4326
        }).setView([39.92, 116.39], 18);
        let gridLayers = {};  // 格网图层
 
        L.tileLayer(
            'https://t{s}.tianditu.gov.cn/img_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=' +
            token, {
                attribution: false,
                subdomains: [0, 1, 2],
            }
        ).addTo(map);
 
        map.on('load', init());
 
        map.on('moveend', () => {
            init();
        });
 
        function init(){
            const zoom = map.getZoom();
            
            const bounds = map.getBounds();
            const southWest = bounds.getSouthWest();
            const northEast = bounds.getNorthEast();
            const [x1,y1,x2,y2] = [southWest.lng, southWest.lat, northEast.lng, northEast.lat];
 
            // 网格行列号范围获取
            const gridBound = bboxToGrid([x1, y1, x2, y2], zoom);
           
            // 视野范围内行列号数据获取
            const gridDatas = getGridDatasOfView(gridBound, zoom);
 
            drawGrids(gridDatas,zoom);
            
        }
 
        // 绘制格网图层
        function drawGrids(gridDatas, zoom){
            removeGridLayers();
            gridDatas.forEach(gridData => {
                const {x, y} = gridData;
                // 网格经纬度范围获取
                const bbox = gridToBbox(x, y, zoom);
                var bounds = [[bbox[1], bbox[0]], [bbox[3], bbox[2]]];
 
                const layer = L.rectangle(bounds, {color: "#ff7800", weight: 1});
 
                const gridName = `${x}_${y}_${zoom}`;
                gridLayers[gridName] = layer;
                map.addLayer(layer);
                // 绘制网格的名称
                addGridNameText(layer.getCenter(), x, y, zoom);
            });
        }
        
         /**
         * 绘制网格的名称
         **/
        function addGridNameText(latlon, x, y, zoom) {
          const text = `${x}x${y}_${zoom}`;
          const myIcon = L.divIcon({
            html: text,
            className: 'my-div-icon',
            iconSize: 30
          });
          const gridNameText = `${text}_txt`;
          const marker = L.marker(latlon, { icon: myIcon });
          gridLayers[gridNameText] = marker;
          map.addLayer(marker);
        }
 
 
        // 删除格网图层
        function removeGridLayers(){
            Object.keys(gridLayers).forEach(key => {
                map.removeLayer(gridLayers[key]);
            });
            gridLayers = {};
        }
 
    </script>
</body>
 
</html>

2、util.js

/**
 * 根据bbox获取瓦片行列号范围
 * @param {*} bbox 
 * @param {*} zoom 
 * @returns 
 */
 export function bboxToGrid(bbox, zoom) {
    const x1 = Math.floor((bbox[0] + 180) / (360 / Math.pow(2, zoom)));
    const y1 = Math.ceil((90 - bbox[1]) / (180 / Math.pow(2, zoom - 1)));
    const x2 = Math.ceil((bbox[2] + 180) / (360 / Math.pow(2, zoom)));
    const y2 = Math.floor((90 - bbox[3]) / (180 / Math.pow(2, zoom - 1)));
    return [x1, y1, x2, y2];
}
 
 
// 视野范围内行列号数据获取
export function getGridDatasOfView(grids) {
    const gridDatas = [];
    for (let i = grids[0]; i < grids[2]; i++) {
        for (let j = grids[3]; j <= grids[1]; j++) {
            const gridData = { x: i, y: j };
            gridDatas.push(gridData);
        }
    }
    return gridDatas;
}
 
/**
 * 根据行列号获取经纬度范围
 * @param {*} x 列号
 * @param {*} y 行号
 * @param {*} z 级别
 * @returns 
 */
 export function gridToBbox(x,y,z) {
    const x1 = x * 256 * (360 / (Math.pow(2, z) * 256)) - 180;
    const y1 = 90 - y * 256 * (180 / (Math.pow(2, z - 1) * 256));
    const x2 = x1 + 360 / Math.pow(2, z);
    const y2 = y1 + 180 / Math.pow(2, z - 1);
    return [x1, y1, x2, y2];
}

效果在这里插入图片描述

参考:
leaflet 叠加天地图经纬度瓦片绘制网格

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值