GeoJSON 中的孔洞Hole与蒙版Mask详解1. 为什么会有“孔洞”真实工程场景你一定见过这些需求地图中显示一个区域但排除某些子区域比如飞地行政区中间有“湖泊 / 空白区域”高亮某区域但中间留空 本质就是❗一个 Polygon 内部“挖掉一部分”2. Polygon 的孔洞结构核心GeoJSON 其实早就支持“孔洞”只是很多人没理解结构。标准结构{type:Polygon,coordinates:[[外边界],[孔洞1],[孔洞2]]}示例带一个孔洞{type:Polygon,coordinates:[[[0,0],[10,0],[10,10],[0,10],[0,0]],[[3,3],[7,3],[7,7],[3,7],[3,3]]]} 解释第一层大正方形外轮廓第二层中间被“挖掉”的小正方形3. ❗ 最容易踩的坑非常关键❌ 坐标方向错误致命GeoJSON 对“环方向”是有约定的类型方向外环逆时针CCW内环孔洞顺时针CW 如果方向错了会发生孔洞变成“填充”渲染异常尤其在 Mapbox / OpenLayers❌ 忘记闭合[0,0] ... [0,0] ✔ 必须首尾相同❌ 把孔洞写成 MultiPolygon 很多人会写成MultiPolygon ❌ 实际应该是Polygon 内环 ✔4. 蒙版Mask的本质 什么是 Mask所谓“蒙版”本质是❗反向 Polygon用一个大区域减去一个小区域典型场景地图只显示某一个区域其它地方“变暗”突出某城市其它区域遮罩做“聚焦效果”5. Mask 的实现方式GeoJSON 核心思路用一个“超大 Polygon”中间挖一个洞示例地图遮罩{type:Polygon,coordinates:[[[-180,-90],[180,-90],[180,90],[-180,90],[-180,-90]],[[100,20],[120,20],[120,40],[100,40],[100,20]]]} 解释外层整个世界超大矩形内层你要“显示”的区域被挖掉 渲染效果外部被遮罩内部透明突出6. 前端实现Mapbox GL 实战map.addLayer({id:mask-layer,type:fill,source:{type:geojson,data:maskGeoJSON},paint:{fill-color:#000,fill-opacity:0.6}}); 关键点使用 fill 图层控制透明度内环自动形成“洞”7. 高级工程技巧很关键✔ 技巧1动态生成 MaskfunctioncreateMask(polygon){return{type:Feature,geometry:{type:Polygon,coordinates:[WORLD_BOUNDS,polygon]}}}✔ 技巧2配合 Turf.js 做裁剪可以用differenceunionintersect 实现复杂区域挖洞✔ 技巧3避免精度问题坐标必须一致精度避免边界重叠8. 架构层理解重点 孔洞 Mask 的本质是✔布尔几何运算Geometry Boolean Operations包括差集difference并集union交集intersect 所以真正的能力是❗ 不是会写 GeoJSON✔ 而是理解“空间关系建模”9. 总结非常关键 记住这三句话✔ Polygon 外环 内环孔洞✔ Mask 大区域 - 小区域✔ 本质 几何布尔运算10. 延伸思考 为什么很多 GIS 引擎内部都用拓扑结构Topo而不是纯 GeoJSON 提示GeoJSON 不关心“边界共享”也不关心“空间关系”完结撒花✿✿ヽ(°▽°)ノ✿