经纬志
首页 / Turf.js / 教程

线要素处理:截取、分段与最近点

先看结论

线数据上的操作几乎都围绕「里程」展开:第几公里处有什么、从 A 点到 B 点截一段、 每隔五百米打一个桩。这一组函数都以 units 为共同前提。

最后验证 2026-11-03 · Turf.js 7.x · 更新 2026-10-29 · 引用本文

沿线取点:along

along 从线的起点出发,按给定里程走,返回该处的点。 里程超出线长时返回终点,不会报错。

var line = turf.lineString([
  [116.391263, 39.907359],
  [116.407000, 39.899000],
  [116.430000, 39.910000]
]);

var total = turf.length(line, { units: 'kilometers' });
console.log('全长', total.toFixed(3), '公里');

[0, 0.5, 1, total].forEach(function (d) {
  var p = turf.along(line, d, { units: 'kilometers' });
  console.log(d, turf.getCoord(p));
});

units 必须与 length 的结果一致。用公里算出的总长, 却传给 along 一个 units: 'meters', 走出的距离会短一千倍。

截取一段:lineSlice 与 lineSliceAlong

两个函数都返回线的子集,区别在入参:lineSlice 按两个点截, lineSliceAlong 按两个里程截。前者适合「从站点 A 到站点 B」, 后者适合「第 2 到第 5 公里」。

var a = turf.point([116.400000, 39.903000]);
var b = turf.point([116.425000, 39.909500]);

var partByPoints = turf.lineSlice(a, b, line);
var partByKm     = turf.lineSliceAlong(line, 0.8, 2.4, { units: 'kilometers' });

console.log(partByPoints.geometry.coordinates.length);
console.log(partByKm.geometry.coordinates.length);

lineSlice 会先把两个点投影到线上最近的垂足,再按线上的位置截取。 如果点在线的「后方」,截出来的可能是反向的一段,需要自己检查首尾坐标。

等距分段:lineChunk

把长线切成固定长度的若干段,返回 FeatureCollection。 最后一段通常不足给定长度,这是预期行为。

var chunks = turf.lineChunk(line, 0.5, { units: 'kilometers' });

console.log('段数', chunks.features.length);

chunks.features.forEach(function (seg, i) {
  var len = turf.length(seg, { units: 'kilometers' });
  console.log(i, len.toFixed(3), '公里');
});

平行偏移:lineOffset

lineOffset 生成一条与原线平行、相距给定距离的线。 距离正负决定在左侧还是右侧(沿线的行进方向)。 弧线、急弯处会自相交,这是几何偏移的固有现象。

var left  = turf.lineOffset(line,  0.02, { units: 'kilometers' });
var right = turf.lineOffset(line, -0.02, { units: 'kilometers' });

console.log(left.geometry.coordinates.length);
console.log(right.geometry.coordinates.length);

最近点与点到线距离

nearestPointOnLine 返回垂足点,并把距离、所在线段索引、 沿线位置放在 properties 里。 pointToLineDistance 只给距离。

var target = turf.point([116.415000, 39.895000]);

var near = turf.nearestPointOnLine(line, target, { units: 'kilometers' });
console.log(near.properties.dist);      // 点到线的距离
console.log(near.properties.index);     // 落在第几段
console.log(near.properties.location);  // 沿线里程

var d = turf.pointToLineDistance(target, line, { units: 'kilometers' });
console.log(d === near.properties.dist); // true
函数输入输出
along线 + 里程点
lineSlice线 + 两个点线段
lineSliceAlong线 + 两个里程线段
lineChunk线 + 段长线段集合
lineOffset线 + 偏移距离平行线
nearestPointOnLine线 + 点点,带距离与位置属性
pointToLineDistance点 + 线数值

注意事项

lineChunk 的分段点落在原线之外

lineChunk 会在里程处插值出新的点,但不会改变原线的顶点。 需要「在分段点插入桩号标记」时,用 along 逐个取点, 比从分段结果里取首点更直接。

Point 必须真的落在附近

lineSlice 对两个点做垂足投影,如果两个点投影到同一位置, 截出的线段长度为 0,几何上退化成一条重复的线。调用前先比较 properties.location,差值过小就直接返回空结果。

偏移距离写成了度数

lineOffset 的距离默认是公里。传 0.0001 以为在偏移 0.0001 度,实际偏移了 0.1 米,肉眼完全看不出来。 统一用米或公里,并在代码里显式写 units。

引用本文

经纬志(2026)。《线要素处理:截取、分段与最近点》。https://www.jingweizhi.com/turf/tutorial/line-ops.html(访问日期 2026-11-03)。