坐标处理
真实数据里总有重复顶点、多余小数、方向反了的环。这一组函数不改几何形状, 只做规整:降精度、去冗余、统一方向、翻转坐标顺序。
降精度:truncate 与 round
truncate 按小数位截断,不四舍五入;round 四舍五入。
经纬度保留 6 位约等于 0.1 米,5 位约 1 米,超出业务需要的位数只是浪费带宽。
var raw = turf.point([116.39126345678, 39.90735912345], { id: 7 });
var cut = turf.truncate(raw, 6);
var rnd = turf.round(raw, 6);
console.log(turf.getCoord(cut)); // [116.391263, 39.907359]
console.log(turf.getCoord(rnd)); // [116.391263, 39.907359]
// 批量处理整个数据集
var cleaned = turf.truncate(turf.featureCollection([raw]), 6, { mutate: true });
截断会引入最多 1 个精度单位的偏移。做面积、距离计算前先截断, 可以消除同一位置不同精度的重复记录;但截断后再求和,结果会有细微差异。
去冗余:cleanCoords
重复顶点、共线的中间点都不影响形状,却会增加体积与渲染开销。
cleanCoords 把它们去掉。抽取自 GPS 轨迹的数据尤其需要。
var messy = turf.lineString([
[116.391263, 39.907359],
[116.391263, 39.907359], // 重复
[116.400000, 39.907359], // 共线
[116.410000, 39.907359],
[116.410000, 39.920000]
]);
console.log('原始', messy.geometry.coordinates.length);
var clean = turf.cleanCoords(messy);
console.log('清理后', clean.geometry.coordinates.length);
统一环方向:rewind
GeoJSON 规范建议外环逆时针、内环顺时针。方向不一致的面在
intersect、dissolve 里可能被当成「洞」处理,
结果多出一块空白。
var fixed = turf.rewind(polygon); // 按规范方向重排
var flipped = turf.rewind(polygon, { reverse: true }); // 全部反向
console.log(turf.rewind(polygon) === polygon); // false,默认返回新对象
翻转经纬度:flip
后端返回 [纬度, 经度] 时,flip 一次性把整份数据换过来。
它只处理坐标数组,属性不动。
var wrongOrder = turf.point([39.907359, 116.391263]);
var right = turf.flip(wrongOrder, { mutate: true });
console.log(turf.getCoord(right)); // [116.391263, 39.907359]
flip 用错比不用更危险。数据本来是对的,多翻一次就全错, 而且地图上仍能画出形状(只是位置在南极附近)。 翻转只能在数据入口做一次,不要放在渲染流程里。
遍历坐标:coordEach
需要自定义清洗规则时,coordEach 是底层入口。
直接遍历坐标数组,比先拆成 Feature 再处理的分配开销小得多。
var minLng = Infinity, maxLng = -Infinity;
var bad = 0;
turf.coordEach(bigCollection, function (coord, index) {
if (coord[0] < -180 || coord[0] > 180 ||
coord[1] < -90 || coord[1] > 90) {
bad++;
return;
}
if (coord[0] < minLng) minLng = coord[0];
if (coord[0] > maxLng) maxLng = coord[0];
});
console.log('越界坐标', bad, '经度范围', minLng, maxLng);
coordEach 的回调第一个参数是坐标,第二个是坐标序号,
后面还带要素与几何的层级索引;单部件几何里最后几项没有区分意义。
按方位角推算
destination 从一点出发,沿给定方位角走给定距离,得到新点;
bearing 反过来算两点之间的方位角。方位角以正北为 0,顺时针增加。
var origin = turf.point([116.391263, 39.907359]);
var north = turf.destination(origin, 5, 0, { units: 'kilometers' });
var east = turf.destination(origin, 5, 90, { units: 'kilometers' });
console.log(turf.bearing(origin, north)); // 0
console.log(turf.bearing(origin, east)); // 90
// 以原点为中心,画一圈等距采样点
var ring = [];
for (var deg = 0; deg < 360; deg += 30) {
ring.push(turf.getCoord(turf.destination(origin, 3, deg, { units: 'kilometers' })));
}
console.log(ring.length);
| 函数 | 作用 | 是否返回新对象 |
|---|---|---|
truncate | 按小数位截断,不四舍五入 | 是,除非传 mutate |
round | 按小数位四舍五入 | 是,除非传 mutate |
cleanCoords | 删重复顶点与共线中间点 | 是,除非传 mutate |
rewind | 统一环的方向 | 是 |
flip | 交换经纬度顺序 | 是,除非传 mutate |
coordEach | 遍历所有坐标,不复制数据 | 否,只做回调 |
destination | 按方位角与距离推算新点 | 是,返回新的 Point |
注意事项
truncate 的精度上限
精度参数只接受 0 到 6 位。写 8 会被夹到 6,
以为保留了原始精度,实际已经被截短。
cleanCoords 会删掉必要顶点
共线判断有浮点容差。对精度要求高的面(例如小于 1 米的宗地), 清理后面积可能变化。这类数据只去重复点,不做共线清理。
rewind 与自相交
rewind 只调整顶点顺序,不修复自相交。自相交的面在重排后
可能被判成「洞」,看起来像是凭空缺了一块。先用 turf.kinks 定位问题。
经纬志(2026)。《坐标处理》。https://www.jingweizhi.com/turf/tutorial/coordinates.html(访问日期 2026-11-03)。