为什么一个wgs84框架的渲染引擎,可以正确渲染gcj02的坐标?

背景

在地图公司工作过的朋友应该了解,我们的地图数据是不能直接用wgs84坐标系来存储或者表达的,必须做一定的转换,例如百度地图的bd09,或者国测局的gcj02。而我们的渲染引擎,例如cesium或者openlayer,正常情况下,使用的肯定是wgs84的。那么当gcj02的坐标,渲染到wgs84的框架下,为什么能正确渲染呢?

渲染引擎的地图原理

一个经纬度点渲染到地图上,需要经过几步转换:

经纬度坐标(lng,lat)->Web墨卡托平面坐标(x,y)->屏幕像素坐标(px,py)

那么,同一个经纬度坐标,无论是wgs84坐标系,或者gcj02坐标系,最后投影到屏幕上,都会对应同一个像素坐标。但是其在真实世界中表达的地理位置,是不同的。

因此,在相同的bbox范围内,wgs84和gcj02投影得到的地图是不同的。

如果我们的数据都是gcj02坐标系的,那么渲染到地图上,你任意点击一个位置,这个位置的经纬度坐标就是gcj02坐标系的。

gcj02和wgs84只是在经纬度上有所偏移,在web墨卡托投影和转像素坐标的公式是完全一致的。经纬度转墨卡托认为是正算,墨卡托转经纬度认为是反算,正反算是可逆的。这也是为什么我们的渲染引擎没有特殊处理,就能正确渲染gcj02坐标的原因。

gcj02的瓦片如何生成

国内的卫星图,按照规定,也是需要转换为gcj02坐标系的瓦片。如何生成?

在wgs84下,每一个层级的每一个瓦片,都有自己对应的经纬度范围。同理,gcj02表达同一片范围的经纬度应该经过偏移。

因此,我们应该先对原始数据做偏移,然后再切瓦片。这样,相同瓦片行列号得到的84和02的卫星图是不同的。

wgs84坐标系切出的瓦片如何放在gcj02的地图上

如果我们得到的是已经切好的84瓦片,但是国内地图必须是用gcj02的坐标系,如何才能对应上?

在Cesium中,ImageryLayer会接收一个imageryProvider,我们需要在这个imageryProvider上做文章,把瓦片的经纬度范围进行修改。

imageryProvider有一个变量是tilingScheme,这个变量控制了瓦片的坐标转换公式。

其中,projection遍历变量,就是坐标转换。其余的很多内置方法都调用了这个变量。我们需要重写坐标投影正算和反算的方法。

重写也很简单,正算时拿到的经纬度是gcj02的,只需要gcj02转wgs84,然后再做web墨卡托投影,得到墨卡托坐标即可。

反算时先通过墨卡托投影反算出wgs84坐标,再把wgs94转gcj02坐标输出即可。

注意,上述的前提是切出来的瓦片,也是以左上角为原点。如果是Google Earth的瓦片,瓦片原点以地球经纬度(0,0),那就需要重写positionToTileXY和tileXYToNativeRectangle、tileXYToRectangle方法。重点在于瓦片行列号的转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HouGISer

HouGiser需要你的鼓励~

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

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

打赏作者

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

抵扣说明:

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

余额充值