实现地图遮罩 leaflet

发布时间 2023-08-04 11:22:16作者: csincs

1 前言

在地图中加载的底图是瓦片服务(固定大小的规则矩形),底图的范围很大,铺满了整个div,但是我们的感兴趣的部门可能只是其中一部分,如何在整个屏幕中突出感兴趣的部分-- 地图遮罩(遮挡图像中不感兴趣的部分)。最常见的用处是突出行政区内部区域。
image.png
图1 湖南省遮罩

2 实现方法

地图遮罩实现思路:在大范围区域的内部挖洞(感兴趣部分),矩形中挖出行政区边界
在leaflet中常用L.polygon来实现面中挖洞,上代码

var latlngs = [
  [[-91, -181], [ 91, -181], [91, 181], [-90, 181]], // 外环
  [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // 洞
];
var polygon = L.polygon(latlngs, { style: {fillColor: '#000',
    stroke: false,
    fillOpacity: 0.5,
    color: '#000000',
    weight: 1 }}).addTo(map)
map.setView([38, -107], 7)

坐标数组latlngs:第一元素是外环的坐标数组,是整个世界范围,第二个元素就是洞的坐标数组
image.png
图二 简单遮罩实例

3 重点讨论

上面用L.polygon实现了在简单的遮罩(挖了一个矩形洞),针对具有飞地、复杂边界线的行政区
例如湖南 整个湖南省境内(指的是最外围、最大的边界线内)有多个属于外省的飞地,同时在外省也有多个飞地
图三选取怀化部分区域,有一个在贵州的飞地A(亮),同时怀化境内有一块属于贵州的飞地B(暗)
image.png
图三 怀化部分区域
绘制准确的湖南省地图遮罩,需要满足这两个条件:1 有多个洞 2 洞中有洞
实现方法:** **L.geoJSON + GeoJSON Multipolygon数据
GeoJSON数据中的每个Multipolygon由一个外环和零个或多个内环(洞)组成。外环定义了整个多边形的边界,而内环定义了洞的边界,洞也可以是外环和洞组成(嵌套)。每个环都是由一组经纬度坐标构成的闭合路径。数据格式如下:

{
  "type": "Feature",
  "geometry": {
    "type": "MultiPolygon",
    "coordinates": [
      // 第一个Multipolygon
      [
        // 外环1
        [
          [longitude1, latitude1],
          [longitude2, latitude2],
          ...
        ],
        // 内环1(洞1)
        [
          [
            [longitude_hole1_1, latitude_hole1_1],
            [longitude_hole1_2, latitude_hole1_2],
            ...
          ]
        ],
        // 内环2(洞2)
        [
          [
            [longitude_hole2_1, latitude_hole2_1],
            [longitude_hole2_2, latitude_hole2_2],
            ...
          ],
          // 内环2的洞
    			...
        ]
      ],
      // 更多Multipolygon...
    ]
  },
  "properties": {
    // 可选的属性
  }
}

代码

// 准备 geojson 数据

L.geoJSON(geojson, {style: function (feature) {
  return {
    fillColor: '#000',
    stroke: false,
    fillOpacity: 0.5,
    color: '#000000',
    weight: 1
  }
}).addTo(map)