长度、面积、中心与包围盒
度量类函数是 Turf 最常被调用的部分。它们看起来简单,真正容易出错的只有两处: 单位怎么传、以及「中心」到底指哪一种中心。
长度用 length,不是 distance
distance 算两点之间的大圆距离,length 算整条线的累计长度。
把线的坐标数组直接传给 distance 会得到 NaN,
因为它的入参是点要素。
var route = turf.lineString([
[116.391263, 39.907359],
[116.407000, 39.899000],
[116.430000, 39.910000]
]);
var km = turf.length(route, { units: 'kilometers' });
var mi = turf.length(route, { units: 'miles' });
var deg = turf.length(route, { units: 'degrees' });
console.log(km.toFixed(3), mi.toFixed(3), deg.toFixed(3));
units 支持 kilometers、miles、
nauticalmiles、meters、feet、
yards、radians、degrees。
不传时默认 kilometers,很容易让「以为拿到米」的代码差三个数量级。
面积恒为平方米
turf.area 没有 units 参数,返回值固定是平方米。
需要平方公里、公顷、亩时自己换算。
var plot = turf.polygon([[
[116.380, 39.900],
[116.400, 39.900],
[116.400, 39.915],
[116.380, 39.915],
[116.380, 39.900]
]]);
var m2 = turf.area(plot);
var km2 = m2 / 1e6;
var ha = m2 / 1e4;
var mu = m2 / 666.6667; // 1 亩 ≈ 666.67 平方米
console.log(m2.toFixed(1), km2.toFixed(4), ha.toFixed(2), mu.toFixed(2));
area 用的是球面公式,结果与投影无关,因此不会因为地图缩放而变化。
Web 墨卡托的平面面积在高纬度会严重失真,两者数值不能互相校验。
三种中心,结果不同
| 函数 | 定义 | 适用 |
|---|---|---|
center | 外包矩形的中心 | 放置注记、视野居中 |
centroid | 所有顶点的平均值 | 顶点分布均匀的规则图形 |
centerOfMass | 面按面积加权的重心 | 不规则面、需要「落在面内」时 |
pointOnFeature | 保证落在几何内部的点 | 标注位置必须在地块内 |
var c1 = turf.center(plot); // 外包矩形中心,可能落在面外
var c2 = turf.centroid(plot); // 顶点平均,L 形地块会偏
var c3 = turf.centerOfMass(plot); // 面积重心,通常在面内
var c4 = turf.pointOnFeature(plot);// 保证在面内
console.log(turf.getCoord(c1));
console.log(turf.getCoord(c2));
console.log(turf.getCoord(c3));
console.log(turf.getCoord(c4));
狭长或 L 形地块上,三者的差距很明显。放标注优先用
centerOfMass 或 pointOnFeature,
用 center 常出现「标注跑到地块外面」。
包围盒与方位角
bbox 返回 [minX, minY, maxX, maxY],
也就是 [西, 南, 东, 北]。这个顺序与 Leaflet 的
[[南, 西], [北, 东]] 不同,是跨库协作最常见的错位来源。
var box = turf.bbox(plot); // [116.38, 39.9, 116.4, 39.915]
var boxPolygon = turf.bboxPolygon(box); // 转成面要素
var boxCenter = turf.center(boxPolygon);
// 与地图库配合时按对方要求重排
var leafletBounds = [[box[1], box[0]], [box[3], box[2]]]; // [[南,西],[北,东]]
console.log(JSON.stringify(boxPolygon.geometry.type)); // "Polygon"
console.log(turf.getCoord(boxCenter));
bboxPolygon 生成的是一个闭合的矩形面,可以直接交给
intersect 做范围裁剪,或者作为 buffer 的粗筛容器。
注意事项
把 GeoJSON 坐标顺序当成 [lat, lng]
Turf 全线遵循 GeoJSON 规范,坐标是 [经度, 纬度]。
从 GPS 设备或某些后端拿到的 [纬度, 经度] 必须先翻转,
否则面积与长度会算出一个看似合理、实际毫无意义的数字。
用 degrees 当米用
units: 'degrees' 返回的是度数,1 度约 111 公里。
把 length(..., {units:'degrees'}) 的结果直接当米展示,
量级会差五个数量级,且不同纬度上的换算比例还不同。
面对自相交多边形求面积
自相交的环会让球面面积公式得到明显偏离真实值的结果,甚至出现负数。入库前用
turf.kinks 检查自相交点,或者先用
turf.rewind 统一环方向。
经纬志(2026)。《长度、面积、中心与包围盒》。https://www.jingweizhi.com/turf/tutorial/measurement.html(访问日期 2026-11-03)。