webgis原理剖析系列-以openlayers为例 -04 请求地图行列号的计算

首先要了解一些基础知识

1:经纬度所对应的投影坐标范围

Google地图采用的是Web墨卡托投影(如下图),为了方便忽略了两极变形较大的地区,把世界地图做成了一个边长等于赤道周长的正方形(赤道长度为6378137米),原点在正方形中心,即经纬度为(0,0)处。Web墨卡托投影的X,Y坐标取值范围为:[-20037508.3427892,20037508.3427892],对应的经度取值范围为[-180,180],对应的纬度范围则为[-85.05112877980659,85.05112877980659]

在使用ol-debug.js调试可以看到,不指定坐标系,会默认为3857,构造函数会初始化其范围(好像最后几位不太相同)

2 根据屏幕坐标系到地理坐标系的转换 

Level:0, Scale:591657527.591555, Resolution:156543.033928023
Level:1, Scale:295828763.795778, Resolution:78271.5169640117
Level:2, Scale:147914381.897889, Resolution:39135.7584820059
Level:3, Scale:73957190.9489444, Resolution:19567.8792410029
Level:4, Scale:36978595.4744722, Resolution:9783.93962050147
Level:5, Scale:18489297.7372361, Resolution:4891.96981025073
Level:6, Scale:9244648.86861805, Resolution:2445.98490512537
Level:7, Scale:4622324.43430902, Resolution:1222.99245256268
Level:8, Scale:2311162.21715451, Resolution:611.496226281342
Level:9, Scale:1155581.10857726, Resolution:305.748113140671
Level:10, Scale:577790.554288628, Resolution:152.874056570335
Level:11, Scale:288895.277144314, Resolution:76.4370282851677
Level:12, Scale:144447.638572157, Resolution:38.2185141425838
Level:13, Scale:72223.8192860785, Resolution:19.1092570712919
Level:14, Scale:36111.9096430392, Resolution:9.55462853564596
Level:15, Scale:18055.9548215196, Resolution:4.77731426782298
Level:16, Scale:9027.97741075981, Resolution:2.38865713391149
Level:17, Scale:4513.98870537991, Resolution:1.19432856695575
Level:18, Scale:2256.99435268995, Resolution:0.597164283477873
Level:19, Scale:1128.49717634498, Resolution:0.298582141738936

3 以下原理来自于https://www.cnblogs.com/naaoveGIS/p/3899821.html博客。

被困住的主要一点在于切片起始点的设置,当然文中还有很多处理逻辑,本文不细展开,待后续研究。主要涉及瓦片行列号的请求。全部代码及注释如下。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Using Parcel </title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #map {
            width: 800px;
            height: 700px;
            overflow: hidden;
        }
    </style>
</head>
<body>
<div id="map"></div>
<div class="tip">图片第一次可能会出不来,多刷几次,有知道的朋友欢迎留言</div>
<script >
    var oDiv=document.getElementById("map")
    var canvas = document.createElement('canvas');
    oDiv.appendChild(canvas);
    canvas.id="myCanvas"
    canvas.width=oDiv.getBoundingClientRect().width
    canvas.height=oDiv.getBoundingClientRect().height
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
var center=[0,0]//特别注意,此坐标是3857下的,如果是4326,应该作对应转换
//zoom和resolution必须同时对应修改
    var zoom=4
    var resolution=9783.93962050147
    //计算出地理数据的范围
    var minX =center[0] - (resolution* canvas.width)/2;
    var minY =center[1] - (resolution* canvas.height)/2;
    var tileSize=256

    var originX= -20037508.342789244
    var originY=-20037508.342789244
    //用中心点的坐标减去最小的坐标即可得到左边的切片编号,计算出左边需要请求多少张,右边就对应出来了
    //理解:一张图片的大小是256,而resolution代表1px代表的实际距离,因此即为图上的距离需要请求多少张
    var fixedTileLeftTopNumX = Math.floor((Math.abs(originX -minX))/(resolution*tileSize));
    var fixedTileLeftTopNums = Math.floor((Math.abs(originX))/(resolution*tileSize));

    var fixedTileLeftTopNumY = Math.floor((Math.abs(originY - minY))/(resolution*tileSize));

    var maxX=fixedTileLeftTopNumX+2*(fixedTileLeftTopNums-fixedTileLeftTopNumX)
    let disTop=0;
    let disleft=0
         function draw(i1,j1) {
                disTop=(i1-fixedTileLeftTopNumX)*256;
                disleft=(j1-fixedTileLeftTopNumY)*256
                     var img = new Image();
                     img.src = `https://c.tile.openstreetmap.org/${zoom}/${i1}/${j1}.png`;
                            console.log("绘制"+(j1-fixedTileLeftTopNumY)*256,disTop)
                    ctx.drawImage(img,disTop, disleft);
         }
        for(let i=fixedTileLeftTopNumX;i<maxX;i++){
            for(let j=fixedTileLeftTopNumY;j<=maxX;j++){

                draw(i,j)
            }
        }




</script>
</body>
</html>

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值