缓冲区与距离
距离回答「多远」,缓冲区回答「影响范围有多大」。
Turf 把这两件事都算在球面上,半径单位默认公里,
所以「500 米缓冲」必须显式写成 { units: 'meters' }。
三个距离函数,用途不同
| 函数 | 输入 | 用途 |
|---|---|---|
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 的三个参数
| 参数 | 默认 | 说明 |
|---|---|---|
radius | — | 缓冲距离,单位由 options.units 决定 |
units | kilometers | 可写 kilometers、meters、miles 等 |
steps | 8 | 一个点扩展成多少段,决定圆的光滑程度 |
默认 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)。