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

简化、平滑与合并

先看结论

这一组函数处理几何的「外观」而不是「关系」:抽稀顶点减小体积、 用曲线替换折线、把相邻且属性相同的面合成一个。它们都改变几何本身,不可逆。

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

simplify:容差按坐标系单位

容差的单位不是米,而是与坐标相同的单位。经纬度数据里, 0.001 大约对应 100 米。这个误解会让简化结果要么毫无变化, 要么把整条线压成一个点。

var track = turf.lineString([/* 几千个顶点 */]);

console.log('原始顶点', track.geometry.coordinates.length);

var coarse = turf.simplify(track, {
  tolerance: 0.001,        // 约 100 米
  highQuality: true        // 更接近原始形状,代价是更慢
});

console.log('简化后', coarse.geometry.coordinates.length);

var rough = turf.simplify(track, { tolerance: 0.01 });
console.log('更粗', rough.geometry.coordinates.length);

highQuality: false(默认)用快速算法,可能产生自相交; 用于展示的线建议开启。数据量很大且只做粗筛时,关掉更划算。

bezierSpline:把折线画成曲线

用贝塞尔曲线重采样,顶点密度由 resolution 决定, 弯曲强度由 sharpness 控制。它不减少顶点,只会增加, 适合视觉呈现,不适合传输。

var smooth = turf.bezierSpline(track, {
  resolution: 20000,       // 采样间隔,值越小点越密
  sharpness: 0.85          // 0 到 1,越大越贴近原折线
});

console.log(turf.length(smooth, { units: 'kilometers' }).toFixed(3));
参数默认调大后的效果
resolution10000采样更稀疏,顶点更少,曲线更「方」
sharpness0.85更贴近原始折线,拐角更明显

dissolve:按属性合并相邻面

dissolve 把属性值相同的相邻面合并成一个。它不会跨越不相邻的区域, 所以合并结果可能是 MultiPolygon,而不是一整块。

var districts = turf.featureCollection([
  turf.polygon([[/* ... */]], { zone: 'A' }),
  turf.polygon([[/* ... */]], { zone: 'A' }),
  turf.polygon([[/* ... */]], { zone: 'B' })
]);

var merged = turf.dissolve(districts, { propertyName: 'zone' });

merged.features.forEach(function (f) {
  console.log(f.properties.zone, f.geometry.type);
});

不传 propertyName 时,所有面会合并成一块(能合并的部分)。 合并后的属性只保留参与合并的那一个字段,其他字段丢失, 需要汇总统计时自己先算好再回填。

凸包与凹包

点集的外轮廓有两种取法:convex 一定得到凸多边形, concave 会沿着点集的凹陷走,更贴合真实形状。

var pts = turf.featureCollection(points);

var hull    = turf.convex(pts);
var concave = turf.concave(pts, { maxEdge: 0.5, units: 'kilometers' });

console.log(hull.geometry.coordinates[0].length);
console.log(concave.geometry.coordinates[0].length);

maxEdge 是凹包允许的最长边,单位由 units 指定。 值越小,轮廓越贴合点集,也越容易切出锯齿;值过大就退化成凸包。

注意事项

简化后再算面积

simplify 删掉顶点,面积、周长都会变。先算指标、再简化展示, 或者把简化容差控制在业务可接受的误差内,并在界面标注「示意边界」。

dissolve 合并不了有间隙的面

相邻只是「看起来贴着」,实际顶点不重合或存在细缝时, dissolve 仍然视为两块。先做一次 turf.cleanCoords 或把顶点吸附到统一精度,再合并。

平滑后首尾不重合

面要素做 bezierSpline 时首尾不会自动闭合。需要闭合环时, 把首点追加到末尾,或者只对线要素使用平滑。

引用本文

经纬志(2026)。《简化、平滑与合并》。https://www.jingweizhi.com/turf/tutorial/simplify-smooth.html(访问日期 2026-11-03)。