GIS重投影:在线动态地图投影(4490至3857)与实时切图

2,478 阅读4分钟

起因

Mapbox是一款广泛应用于各类Web和移动应用中的地图引擎。它提供了丰富的地图展示和交互功能,使得开发者能够轻松地实现各种地图应用。

项目上采用了mapbox作为前端的地图引擎。在早期阶段,项目主要使用的是国家地理信息公共服务平台提供的天地图作为底图。 国家地理信息公共服务平台提供的天地图具有以下两个显著特点:

  • 投影类型:支持经纬度投影(EPSG:4490/EPSG:4326)和球面墨卡托投影(EPSG:3857/EPSG:900913);
  • 瓦片层级:提供高达18级的地图瓦片,超出18级则无图,地图放大后会显示空白区域; image.png

然而,mapbox默认使用EPSG:3857坐标系统,当请求EPSG:4490或EPSG:4326坐标系的地图瓦片时,地图无法正常显示。 这对于ZF项目来说,很多客户要求使用地方天地图(如:浙江天地图),或者政务内网发布的专线地图,这些地图服务无疑都是使用ESPG:4490坐标系的切图方案,官方维护的Mapbox版本无法正常加载这些地图服务。

在GitHub上,有开发者提供了一个针对CGCS2000坐标系(即EPSG:4490)的Mapbox“魔改版”: github.com/cgcs2000/ma…, 这个版本在行业内都称为mapbox“魔改版”, 是基于mapbox v2.3.0版本开发的,提供了加载CGCS2000坐标系的能力。但是,这个版本过于陈旧,许多Mapbox的新功能无法使用:

  • 由于这个版本存在已知BUG,而且这些问题无人负责修复;
  • 如:无法使用mapbox+deck.gl解决方案,去加载3dTiles格式的3D服务;
  • 截至当前,官方的Mapbox已经更新到了v3.2.0,新的特性和改进都无法在旧版本中使用;
  • 另外,对于构建iOS 和 Android原生应用的SDK,并没有对应支持CGCS2000坐标系的“魔改版”提供使用,只能在原生应用中通过WEB的方式嵌入地图。

早期方案

面对客户对地方天地图或专线地图服务使用的需求,即底图必须采用EPSG:4490坐标系,我们采取了如下解决方案:

  • 在WEB端和移动端均采用了Mapbox“魔改版”。具体来说,我们对原有的原生应用进行了改造,以便支持WEB APP的应用场景。然而,这种改造工作量巨大,并且我们不得不同时维护使用官方Mapbox版本和“魔改版”Mapbox的两个项目,这无疑增加了BUG修复的复杂性和难度。

重投影方案

在某技术讨论群,有技术大佬通过服务端重投影的方式,实现地图瓦片的重投影:

  • 即 将经纬度投影EPSG:4490 -----服务端重投影-----> web墨卡托投影EPSG:3857

从而解决了官方版本不能加载EPSG:4490地图服务的问题,彻底摆脱“魔改版”。

但是该技术方案并不开源,提供的实现思路也比较少。

实现重投影

1. 观察

image.png

使用某地图引擎具备同时加载EPSG:4490和EPSG:3857坐标系瓦片的能力,在调试模式下,可以清晰地看到不同坐标系瓦片的边框和编号:绿色代表EPSG:3857地图瓦片边框和编号,红色则代表EPSG:4490地图瓦片边框和编号。发现不同坐标系下:

  • 两者瓦片位置发生平移,且瓦片编号不一样,但瓦片的层级是相同的;
  • 在不同的缩放层级下,瓦片平移的偏移量是不一样的;
  • 瓦片平移之后,使两者地图表示的地方是正确的。

2. 实现

核心思路:计算两个坐标系的地图瓦片参数,然后在服务端进行地图瓦片的合并裁剪,从而达到动态平移的目的。

2. 效果

当前已实现将项目上碰到的浙江天地图山东天地图通过重投影技术,将原EPSG:4490的在线地图瓦片实时转成EPSG:3857,从而在官方维护版本的mapbox上可以正确显示。

同时支持缩放地图之后动态切图,避免出现无图的情况。

2.1 在mapbox v3.2.0中的演示效果

GIF 2024-3-30 20-59-25.gif

官方版本的mapbox加载地图

2.2 在cesium中的演示效果

GIF 2024-3-30 21-42-48.gif

使用mars3d加载浙江天地图↑