经纬志
首页 / Leaflet / API 文档

LineUtil

先看结论

折线的几何工具:简化、裁剪、点到线段距离与中心点,全部在像素坐标上运算。

最后验证 2026-11-03 · Leaflet 1.9.4 · 更新 2026-10-29 · 引用本文
L.LineUtil.simplify(points, tolerance) → Point[]

输入输出都是 L.Point 数组。先把经纬度转成图层像素坐标,处理完再转回去。

方法

方法返回说明
simplify(points, tolerance)Point[]顶点抽稀加 Douglas-Peucker,tolerance 单位像素,越大顶点越少
pointToSegmentDistance(p, p1, p2)number点到线段的垂直距离,像素
closestPointOnSegment(p, p1, p2)Point线段上离目标点最近的位置
clipSegment(a, b, bounds, useLastCode?, round?)Point[] | false用矩形裁剪线段;整段在外返回 false
isFlat(latlngs)boolean判断坐标数组是一维点列还是嵌套的多段
polylineCenter(latlngs, crs)LatLng沿折线长度取中点,比包围盒中心更贴合线形

clipSegment 的 bounds 是像素空间的 L.Bounds, 不是 LatLngBounds。useLastCode 用于连续线段复用上一次的编码, round 控制交点是否取整。

按像素容差抽稀

var latlngs = polyline.getLatLngs();

var pts = latlngs.map(function (latlng) {
  return map.latLngToLayerPoint(latlng);
});

/* 容差 1.5 像素:缩放后肉眼几乎看不出差别 */
var thin = L.LineUtil.simplify(pts, 1.5);

var back = thin.map(function (p) {
  return map.layerPointToLatLng(p);
});

console.log(pts.length, '→', thin.length);
polyline.setLatLngs(back);

抽稀结果与当前缩放绑定。如果要把简化后的坐标存回数据源, 必须在高层级缩放下做,否则放大后线形会明显走样。 展示用途一般不必写回,交给渲染阶段的裁剪即可。

把线段裁到视口内

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

var a = map.latLngToLayerPoint(latlngA);
var b = map.latLngToLayerPoint(latlngB);

var clipped = L.LineUtil.clipSegment(a, b, box, false, true);

if (clipped) {
  drawLine(clipped[0], clipped[1]);
}

两个端点都在框外且方向相同的时候,函数返回 false, 直接跳过这一段,画布上不会出现穿过视野的误连线。

点到线段的距离

这两种算法都用平方距离比较,避免开方开销。差别在返回值: 一个给距离,一个给坐标。命中判断只关心阈值时用前者。

var p = map.latLngToLayerPoint(cursorLatLng);
var a = map.latLngToLayerPoint(segStart);
var b = map.latLngToLayerPoint(segEnd);

var dist = L.LineUtil.pointToSegmentDistance(p, a, b);

if (dist < 8) {
  var hit = L.LineUtil.closestPointOnSegment(p, a, b);
  showSnapMarker(map.layerPointToLatLng(hit));
}

折线中心

polylineCenter 沿累计长度找中点,适合给线要素放标签。 第二个参数必须是 CRS 对象,因为它需要投影后再求长度与反投影:

var mid = L.LineUtil.polylineCenter(
  polyline.getLatLngs(),
  map.options.crs
);

L.marker(mid).bindTooltip('线路中点').addTo(map);

传入嵌套数组时只取第一段,控制台会给出提示。 多段线要分别求中心,或先合并成一条。

这些函数不认识经纬度。 直接传 LatLng 数组不会报错,但所有距离与容差都会被当成像素, 结果毫无意义。调用前统一用 latLngToLayerPoint 转换。

引用本文

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