LineUtil
折线的几何工具:简化、裁剪、点到线段距离与中心点,全部在像素坐标上运算。
输入输出都是 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)。