经纬志
首页 / Leaflet / API 文档

PolyUtil

先看结论

多边形的底层工具:按矩形裁剪环、计算面积重心、计算顶点平均中心。

最后验证 2026-11-03 · Leaflet 1.9.4 · 更新 2026-10-29 · 引用本文
L.PolyUtil.clipPolygon(points, bounds, round?) → Point[]

裁剪在像素坐标上做,bounds 是像素空间的 L.Bounds。

方法

方法返回说明
clipPolygon(points, bounds, round?)Point[]用 Sutherland-Hodgman 算法把环裁到矩形内
polygonCenter(latlngs, crs)LatLng投影后按面积求重心,再反投影回经纬度
centroid(latlngs)LatLng所有顶点的算术平均,不做面积加权

裁剪到视口

渲染器画多边形前会先裁剪,屏幕外的顶点不参与路径构建。 自己写 Canvas 渲染逻辑时可以复用同一套算法,保证裁剪边界与 Leaflet 一致。

var size = map.getSize();
var box = new L.Bounds(L.point(0, 0), L.point(size.x, size.y));

var ring = polygon.getLatLngs()[0].map(function (latlng) {
  return map.latLngToLayerPoint(latlng);
});

var clipped = L.PolyUtil.clipPolygon(ring, box, true);

ctx.beginPath();
clipped.forEach(function (p, i) {
  if (i === 0) { ctx.moveTo(p.x, p.y); }
  else { ctx.lineTo(p.x, p.y); }
});
ctx.closePath();
ctx.fill();

round 传 true 时交点坐标取整,适合像素对齐的绘制; SVG 路径可以保持小数,交给浏览器做抗锯齿。

面积重心与顶点平均

调用算法表现
polygonCenter(latlngs, crs)投影后按面积加权形状的重心,可能落在多边形之外(凹形)
centroid(latlngs)顶点算术平均顶点密集处会把中心拉过去,计算快
var ring = polygon.getLatLngs()[0];

var center = L.PolyUtil.polygonCenter(ring, map.options.crs);
var average = L.PolyUtil.centroid(ring);

L.marker(center).bindTooltip('面积重心').addTo(map);
L.circleMarker(average, { radius: 4 }).bindTooltip('顶点平均').addTo(map);

polygonCenter 必须传 CRS,它需要先把经纬度投影到平面, 否则面积计算没有意义。传嵌套数组时只处理第一个环,控制台给出提示。

带洞多边形

两个函数都只接受单环。带洞的面要分别处理外环与内环: 标签位置用外环重心,洞的裁剪各自独立进行。 clipPolygon 本身不区分外环内环,传入哪一圈就裁哪一圈。

重心不一定在面上

L 形、C 形等凹多边形的面积重心可能落在图形外部。 标注位置要求「必须在面内」时,不能直接用重心, 需要在重心处做一次点面判断(booleanPointInPolygon 之类的工具), 失败再退回到包围盒中心的候选点。

裁剪只对当前视图有效。 裁剪结果带着当前缩放与像素原点,缓存到下一次缩放就会错位。 每次重绘重新计算,或直接交给 Leaflet 的渲染器处理。

引用本文

经纬志(2026)。《PolyUtil》。https://www.jingweizhi.com/leaflet/api/poly-util.html(访问日期 2026-11-03)。