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

缓冲区与距离

先看结论

距离回答「多远」,缓冲区回答「影响范围有多大」。 Turf 把这两件事都算在球面上,半径单位默认公里, 所以「500 米缓冲」必须显式写成 { units: 'meters' }。

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

三个距离函数,用途不同

函数输入用途
turf.distance(from, to) 两个点 两点间的大圆距离,最常用
turf.length(line) 线或面 整条折线累加长度;传面时得到环的周长
turf.pointToLineDistance(pt, line) 点与线 点到线段的垂直距离,用于偏离检测
var a = turf.point([116.391263, 39.907359]);
var b = turf.point([116.410600, 39.914700]);

console.log(turf.distance(a, b));                        // 1.84 km,默认公里
console.log(turf.distance(a, b, { units: 'meters' }));   // 1840 米左右
console.log(turf.distance(a, b, { units: 'miles' }));    // 1.14 英里左右

distance 内部用 haversine 公式,把地球当作半径 6371 公里的球体。 两点重合时返回 0;坐标含 NaN 时返回 NaN, 不会抛错,所以结果过滤要在调用方做。

buffer 的三个参数

turf.buffer(geojson, radius, options) → Feature<Polygon | MultiPolygon>
参数默认说明
radius—缓冲距离,单位由 options.units 决定
unitskilometers可写 kilometers、meters、miles 等
steps8一个点扩展成多少段,决定圆的光滑程度

默认 steps: 8 得到的是一个八边形,放大后棱角明显。 展示用的缓冲区一般给 64,顶点数变成 64 个,视觉上接近圆; 而只做点落区判断时,8 到 16 就够了,几何顶点少,后续相交计算也更快。

var site = turf.point([116.391263, 39.907359], { name: '站点' });

var strict = turf.buffer(site, 1, { units: 'kilometers', steps: 64 });
var coarse = turf.buffer(site, 1, { units: 'kilometers', steps: 8 });

console.log(turf.area(strict).toFixed(0));   // 约 3 140 000 平方米
console.log(turf.area(coarse).toFixed(0));   // 明显偏小,八边形内接于圆

steps 小带来的不只是外观差异:内接多边形的面积小于同半径的圆, 半径 1 公里时八边形面积约为圆的 90%。如果业务用缓冲区面积做容量估算, 这个偏差不能忽略。

线要素的缓冲区是一条走廊

对 LineString 做缓冲,得到的是沿线两侧各扩展 radius 的带状面, 端点处用半圆收口。道路噪声影响范围、河流的保护带都属于这种用法。

var road = turf.lineString([
  [116.35, 39.90], [116.40, 39.905], [116.45, 39.912], [116.50, 39.920]
]);

var corridor = turf.buffer(road, 0.3, { units: 'kilometers', steps: 16 });
console.log(corridor.geometry.type);   // Polygon 或 MultiPolygon

线缓冲的结果类型不固定:几何自相交或拐角很急时,结果会变成 MultiPolygon。 后续代码不要假设它一定是单面,渲染和相交计算都要按多面处理。

半径单位写错的后果

「给这个点做 500 米缓冲」写成 turf.buffer(pt, 500), 得到的是 500 公里,覆盖小半个省。这个错误不会报错,只会让图上的面大得离谱。 经验做法是把单位统一封装一次:

function bufferMeters(feature, meters, steps) {
  return turf.buffer(feature, meters, {
    units: 'meters',
    steps: steps || 32
  });
}

缓冲与投影的差异

在 GIS 桌面软件里对投影坐标做缓冲,得到的是平面上的正圆; Turf 在球面上扩展,得到的是测地圆。低纬度差别很小, 北纬 60 度以上、半径几十公里时,两者投影到屏幕上会出现可见的形变差异。 跨软件比对面积时,先确认双方用的是哪种缓冲。

缓冲不能代替真实服务范围。道路可达性、行政边界、水系阻隔都会让实际范围变形。 缓冲区只表示「直线距离内」,在结果说明里写清这一点,能避免大量误读。

常见错误

对空几何做缓冲

空数组或 null 坐标会让 buffer 返回 undefined, 后续读取 geometry 直接抛错。批量处理前先过滤空要素。

用缓冲结果反复叠加

每叠加一次,顶点数量就翻倍。对已经缓冲过的面再缓冲,不如直接按 「原始半径 + 新增距离」重新生成一次,结果更干净。

拿面积当半径校验

想验证缓冲区是否正确,直接量它到中心点的距离,不要用面积反推半径: 多边形近似和球面公式都会带来偏差,反推出来的半径总比设定值小一点。

引用本文

经纬志(2026)。《缓冲区与距离》。https://www.jingweizhi.com/turf/tutorial/buffer-distance.html(访问日期 2026-11-03)。