高德地图跨日界线显示

跨日界线问题

调用高德地图自身的api使地图居中时,如果路线跨越了太平洋,地图自动居中到大西洋;

在查阅了官方文档,网上搜索之后,并没有找到解决方案。

问题复现demo

实际显示 image-20241212235647185 预期显示 image-20241212235603295

问题分析

地图坐标系标准

地图的坐标系范围:经度范围是[-180,180], 纬度 [-90,90]

球体模式坐标系

image

0度线展开平面模式坐标系

facec2c90f26c464f042aa615801a1c2

高德地图显示API

API参考手册

getBounds: 获取当前地图视图范围/可视区域。可视区域是一个矩形,通过Bound对象我们可以获取矩形四个角的坐标。

image-20241214185726124

setFitView: 根据地图上添加的覆盖物分布情况,自动缩放地图到合适的视野级别。这个方法大致上可看作找到一个Bound

image-20241214190017107
image-20241214190033490

猜想

鉴于高德地图实际显示与预期显示的区别,参照上文平面地图的展开方式,推测高德地图API会将地图上覆盖物的坐标点放入[-180,180]的经度范围来计算Bound(可视区域)。所以,我们所有想要跨越日界线的Bound,都会被转化为180度线展开平面模式坐标系中的bound。

image-20241214191000215
image-20241214191548741

解决方法

步骤一:获得正确的bound。通过遍历点的集合,不断扩张出正确的bound。

步骤二:将正确的bound设法渲染到地图上。如果调用地图方法设置的bound是跨越日界线的,会自动被转为不跨越0经线的bound,及时bound的API写的是第一个参数是西南,第二个参数是东北。所以这也就导致了,无法使用现有API设置合适的bound就能实现地图的正确显示。我们必须手动指定地图中心点和缩放级别。也就是setZoomAndCenter

1
2
3
AMap.Bounds
地物对象的经纬度矩形范围。
new AMap.Bounds(southWest: LngLat, northEast: LngLat)

获取bound

image-20241215192502664

假设路径为A->B->C->D

1.将AB点的坐标,设置初始bound,确实东北和西南。

2.判断C点是否在bound内,若在,则不改变bound,若越过bound,则判断是影响到了bound的哪个角点,如图,C影响了东北,则更新bound的东北点

3.重复以上步骤,直到获得了最大bound

渲染bound

渲染bound需要使用setZoomAndCenter方法,所以我们要找到地图的中心点和缩放级别。中心点可以通过我们计算出的bound取得。而缩放级别则需要我们自己找到计算的方法

基本信息搜集

地图缩放官方示例

最大缩放级别是2,最小缩放级别是20,缩放的灵敏读是0.2,也就是说,鼠标滚轮事件,每次会改变0.2缩放级别。

image-20241215200008924

拖拽选点实例

在最小缩放下,经度的范围是0.001,最大缩放默认是360。

image-20241215195320875

观察地图缩放,我们发现,在使用中,缩放级别越小,地图显示越详细,此时我们触发缩放,缩放的变化对经度的改变越少,缩放级别到国家,我们每次触发缩放,缩放的变化对经度的改变越大。

推导过程

综合以上信息,我们有下面的条件,

地图zoom灵敏度为0.2,范围是2-20,总共有90次变化。经度范围从0.001到360

也就是说,从0.001到360,总共变化了90次。

如果每次变化都有相同的增长率 ,地图的经度值是我们可以有以下的表达式 然后根据此公式,我们可以得到的值 所以经度值和变化次数的关系式为 地图经度函数Lng-t

image-20241215220120754

得到经度变化函数后,让我们回到缩放计算上来,我们在缩放时,对应了第0到90次缩放,也就是zoom从2到20。在地图经度函数中,变成因变化,而得到的结果,即

已知缩放的范围是[2,20],其对应了0到90次缩放。我们前面提到过,最小的缩放,经度尺度是最小的,是0.001,为0;最大的缩放,经度尺度是最大的,是360,为90;而的关系是线性函数即, 带入的值,我们可以得到 变化次数t与缩放关系图t-zoom

image-20241215220019437

我们将函数带入函数,得到函数 此时我们就得到了zoom与经度Lng的关系式,当我们通过bound计算得到合适的bound后,此时我们是可以得到页面需要显示的最大经度Lng,此时我们通过函数,就可以得知此时需要设置多大的缩放,就能显示所有的路线,标点。所以,我们最终需要的是以为参数的函数,即函数 缩放与经度Lng关系图zoom-Lng

image-20241215220525433