You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Leaflet地图中添加经多边形裁剪的Voronoi图?

实现多边形裁剪的Voronoi图方案

方案一:d3-delaunay + Turf.js 二次裁剪

d3-delaunay仅支持矩形裁剪,但可结合现代GIS处理库Turf.js完成多边形裁剪,步骤如下:

  • 先通过d3-delaunay生成基于边界外接矩形的Voronoi图,过滤掉明显在边界外的Voronoi多边形
  • 遍历每个Voronoi多边形,将其与你的边界多边形做交集运算,保留落在边界内的部分
  • 将裁剪后的多边形转换为GeoJSON格式,添加到Leaflet地图

核心代码示例

// 假设points是区域内点的经纬度数组,boundary是边界多边形的GeoJSON
const [xmin, ymin, xmax, ymax] = d3.extent(points, d => d[0]).concat(d3.extent(points, d => d[1]));
const delaunay = d3.Delaunay.from(points.map(p => [p[0], p[1]]));
const voronoi = delaunay.voronoi([xmin, ymin, xmax, ymax]);

// 遍历每个Voronoi多边形
const clippedVoronoi = [];
for (let i = 0; i < points.length; i++) {
  const cell = voronoi.cellPolygon(i);
  if (!cell) continue;
  // 转换为Turf支持的Polygon格式
  const voronoiPoly = turf.polygon([cell]);
  // 计算与边界的交集
  const clipped = turf.intersect(voronoiPoly, boundary);
  if (clipped) {
    clippedVoronoi.push(clipped);
  }
}

// 添加到Leaflet地图
L.geoJSON(clippedVoronoi, {
  style: { fillColor: '#ccc', weight: 1 }
}).addTo(map);

方案二:使用支持多边形裁剪的Voronoi库

直接使用原生支持任意多边形裁剪的现代Voronoi库,避免二次裁剪的性能损耗,推荐**@thi.ng/voronoi**(活跃维护的功能库):

  • 支持将自定义多边形作为裁剪区域,直接生成符合边界的Voronoi图
  • 需注意坐标转换:Leaflet的经纬度是球面坐标,需先转换为平面坐标(如EPSG3857)再计算,完成后转回经纬度

核心代码示例

import { voronoi } from "@thi.ng/voronoi";

// 将经纬度转换为平面坐标(EPSG3857)
const project = (latlng) => {
  const point = L.CRS.EPSG3857.project(L.latLng(latlng));
  return [point.x, point.y];
};

// 将平面坐标转回经纬度
const unproject = (point) => {
  const latlng = L.CRS.EPSG3857.unproject(L.point(point[0], point[1]));
  return [latlng.lng, latlng.lat];
};

// 准备平面坐标的点和边界
const planarPoints = points.map(project);
const planarBoundary = boundary.geometry.coordinates[0].map(project);

// 生成带多边形裁剪的Voronoi图
const result = voronoi({
  points: planarPoints,
  clipPolygon: planarBoundary
});

// 转换为GeoJSON并添加到地图
const geojson = {
  type: "FeatureCollection",
  features: result.cells.map(cell => ({
    type: "Feature",
    geometry: {
      type: "Polygon",
      coordinates: [cell.map(unproject)]
    }
  }))
};

L.geoJSON(geojson, { style: { fillColor: '#ccc', weight: 1 } }).addTo(map);

关键注意事项

  • 坐标转换:所有多边形计算需在平面坐标系下进行,避免球面坐标带来的误差
  • 性能优化:提前过滤掉边界外的点,减少无效计算;点数量极大时可考虑分块处理
  • 边界兼容性:确保边界多边形是闭合的、无自相交的单连通多边形,否则裁剪库可能出错

内容的提问来源于stack exchange,提问作者Alasdair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 09:10:15