1. 需求背景:为什么要在2D地图上“挖洞”?
最近在做一个项目,客户提了个挺有意思的需求:他们希望在高德地图上,只展示某个特定区域内的地图信息,比如一个工业园区或者一个景区范围,而区域之外的所有地方,都用一个半透明的遮罩盖住,让用户一眼就能聚焦在核心区域。说白了,就是给地图“挖个洞”,只让洞里那块地儿露出来。
这需求听起来简单,但实际动手时,我踩了个不大不小的坑。我第一时间去翻高德地图的JS API文档,发现官方确实提供了一个叫“区域遮掩”(mask)的功能。我心想,这不正好吗?结果仔细一看文档说明,心凉了半截——这个功能必须使用3D地图才能生效。如果你用的是2D地图,它只会在地图上给你指定的区域边界描个边,区域外的地图内容依然一览无余,完全达不到“遮掩”的效果。
这就尴尬了。我的项目因为性能和一些兼容性考虑,必须使用2D地图。难道为了这个功能,就得把整个项目升级到3D地图?成本太高,也不现实。那段时间,我几乎把高德地图的API文档翻了个底朝天,各种社区、论坛也搜遍了,都没找到2D地图下直接实现区域遮掩的现成方案。
就在我快要放弃,准备跟客户商量换方案的时候,我无意中在高德地图的示例中心,看到了一个关于“设定楼块样式”的demo。它展示了如何通过一组坐标点,绘制一个多边形并填充颜色。我脑子里灵光一闪:既然能填充多边形内部,那我能不能反过来操作?我能不能画一个巨大的、覆盖整个地图的矩形,然后在这个矩形里“挖掉”我想要的区域,这样剩下的部分(也就是区域外部)填充上半透明颜色,不就把区域外给遮住了吗?
这个“反选”的思路,成了解决整个问题的关键。接下来,我就把从构思到实现的完整过程,以及中间遇到的各种“坑”和技巧,毫无保留地分享给你。
2. 核心思路:用“反选”思维破解2D遮掩难题
官方3D地图的“区域遮掩”之所以能工作,是因为它的渲染引擎支持更复杂的图层合成操作,可以直接告诉地图:“除了这块区域,其他地方都别画”。但在2D地图的Canvas渲染环境下,我们没有这么直接的指令。
所以,我们必须换个思路,从“画什么”变成“遮什么”。我们的目标不再是“让地图只画A区域”,而是“先让地图画出全世界,然后我们在上面盖一层遮罩,只在A区域开个天窗”。
生活化类比:你可以把整张地图想象成一块完整的玻璃。我们的需求不是换一块只有特定图案的玻璃,而是在这块完整的玻璃上,贴一层深色玻璃膜,然后把你想要展示的区域(比如一个圆形)的膜给精准地裁掉。这样,光线(地图信息)就只能从那个被裁掉的圆形区域透过来。
落实到高德地图的API上,这个“深色玻璃膜”就是 AMap.Polygon(多边形)对象。这个对象可以绘制一个由一系列坐标点连接而成的封闭形状,并设置填充色和边框。高德地图的Polygon有一个非常实用的特性:它支持复杂路径(path)。这个 path 参数不仅可以接收一个简单的坐标数组来画一个实心多边形,还可以接收一个“环”数组,来定义“带洞”的多边形。
什么是“带洞”的多边形?想象一个甜甜圈。它有一个外圈和一个内圈,内圈的部分是空的。在几何上,这被称为“多边形环”。我们的“反选”操作,本质上就是在创建一个“甜甜圈”:
- 外环:一个巨大的、覆盖整个地图可视区域(甚至超出)的矩形。这个环定义了遮罩的范围(整个玻璃膜)。
- 内环:由你想要的特定区域的边界坐标点构成的环。这个环定义了“天窗”的范围(被裁掉的部分)。
当我们将这两个环按顺序(通常是外环顺时针,内环逆时针)传入 AM
2080



被折叠的 条评论
为什么被折叠?



