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

如何在OpenLayers中将Polygon分割为指定数量的等面积区块并设置不同颜色

实现步骤
  • 第一步:实现多边形等面积分割逻辑
    OpenLayers本身没有内置多边形等面积分割API,针对凸多边形场景可以直接使用扫描线二分法实现分割,凹多边形场景可先做三角剖分再做面积合并分配。
  • 第二步:调用分割函数处理原始多边形,生成子要素
    分割得到等面积的子多边形集合后,逐个转为OpenLayers的Feature实例,分别设置不同的填充样式。
  • 第三步:将生成的子要素添加到矢量图层完成渲染
完整代码示例
// 工具函数:将凸多边形水平分割为N个等面积子多边形,可修改为垂直分割逻辑
function splitPolygonIntoEqualAreaParts(polygon, splitCount) {
  const extent = polygon.getExtent();
  const [minX, minY, maxX, maxY] = extent;
  const totalArea = polygon.getArea();
  const targetArea = totalArea / splitCount;
  const parts = [];
  let currentY = minY;

  for (let i = 0; i < splitCount; i++) {
    // 最后一个区块直接取剩余范围,避免精度误差
    if (i === splitCount - 1) {
      const clipExtent = [minX, currentY, maxX, maxY];
      const part = polygon.intersectsExtent(clipExtent) ? polygon.clone().intersectExtent(clipExtent) : null;
      part && parts.push(part);
      break;
    }
    // 二分法迭代查找准确分割线位置,迭代20次精度足够满足业务需求
    let low = currentY, high = maxY, midY;
    for (let j = 0; j < 20; j++) {
      midY = (low + high) / 2;
      const clipExtent = [minX, currentY, maxX, midY];
      const tempPart = polygon.intersectsExtent(clipExtent) ? polygon.clone().intersectExtent(clipExtent) : null;
      const tempArea = tempPart ? tempPart.getArea() : 0;
      tempArea < targetArea ? low = midY : high = midY;
    }
    const finalClipExtent = [minX, currentY, maxX, midY];
    const part = polygon.intersectsExtent(finalClipExtent) ? polygon.clone().intersectExtent(finalClipExtent) : null;
    part && parts.push(part);
    currentY = midY;
  }
  return parts;
}

// 你原有逻辑生成原始多边形
const originalPolygon = new Polygon([
  xPos.map((x, index) => {
    return transform([parseFloat(x), parseFloat(yPos[index])], 'EPSG:3857', projection);
  })
]);

// 按需求填写分割数量,示例为分割为5个等面积区块
const splitCount = 5;
const subPolygons = splitPolygonIntoEqualAreaParts(originalPolygon, splitCount);

// 自定义填充色数组,可按业务规则动态生成
const fillColors = ['#FF5733', '#33FF57', '#3357FF', '#F3FF33', '#FF33F3'];
const subFeatures = subPolygons.map((subPolygon, index) => {
  const feature = new Feature(subPolygon);
  feature.setStyle(new Style({
    stroke: new Stroke({
      color: 'rgba(0,0,0,0)'
    }),
    fill: new Fill({
      color: fillColors[index % fillColors.length]
    })
  }));
  return feature;
});

// 将生成的子要素添加到你的矢量数据源即可渲染
vectorSource.addFeatures(subFeatures);
注意事项
  • 如果需要分割凹多边形,需要先对多边形做三角剖分,再对三角网做面积合并分配,才能保证分割后的子区块面积相等
  • 计算面积时请使用等积投影,避免地理坐标系下的面积计算误差
  • 分割方向可根据需求修改为垂直方向,只需要调整扫描线的计算逻辑即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:36:08