Turf.js前端分析怎么做?常用功能有哪些?

GIS基础理论
Dr.GIS
wowwwai GIS研习社 · 工具流程与项目排障

引言

Turf.js前端分析怎么做?常用功能有哪些? 这是很多 WebGIS 开发者在做浏览器端空间计算时会遇到的问题:明明已经能用 Leaflet、OpenLayers 或 Mapbox GL JS 把地图展示出来,但一到缓冲区、点线面判断、距离计算、叠加分析,就不知道该放在前端、后端还是数据库里处理。

Turf.js 是一个面向 JavaScript 的地理空间分析库,主要处理 GeoJSON 数据。它适合在浏览器端完成轻量级、交互式、即时反馈的空间分析,例如点击地图后计算周边范围、判断点是否落在行政区内、测量两点距离、合并面要素、生成等距点等。

本文以 WebGIS 实际开发为主线,讲清楚 Turf.js 前端分析的适用场景、常用功能、基本代码写法、常见坑和方法选择,帮助 GIS 学生、前端 GIS 工程师和空间数据分析人员快速上手。

Turf.js前端分析常用功能和GeoJSON空间计算流程
Turf.js 前端分析通常围绕 GeoJSON 输入、空间计算和地图交互结果展示展开。

背景:什么时候适合用 Turf.js 做前端空间分析

Turf.js 前端分析并不是要替代 PostGIS、ArcGIS Server 或 GeoServer 的空间分析能力。它更适合处理“数据量不大、交互频繁、需要即时反馈”的场景。

典型使用场景包括:

  • 用户点击地图后,计算点击点到目标点的距离。
  • 在前端根据一个点生成 500 米缓冲区,并显示在地图上。
  • 判断一个 GPS 点是否落在某个电子围栏面内。
  • 根据线数据计算长度,或沿线生成等距采样点。
  • 对前端加载的 GeoJSON 面数据做相交、包含、合并等轻量分析。
  • 在地图交互中实时更新统计结果,例如框选范围内有多少点。

如果你的数据已经在浏览器中,且要做的是轻量计算,那么 Turf.js 很方便。如果数据量很大、分析逻辑复杂、需要严谨拓扑处理或需要长期稳定批处理,通常应优先考虑 PostGIS、QGIS、ArcGIS Pro 或后端 GIS 服务。

原理:Turf.js 前端分析的核心数据模型

Turf.js 的核心是 GeoJSON。GeoJSON 是 WebGIS 中常用的矢量数据格式,用 JSON 表达点、线、面和属性信息。Turf.js 的大多数函数都接收 GeoJSON Feature 或 FeatureCollection,并返回新的 GeoJSON 对象。

常见 GeoJSON 几何类型包括:

  • Point:点,例如摄像头、站点、GPS 位置。
  • LineString:线,例如道路、河流、轨迹。
  • Polygon:面,例如行政区、地块、电子围栏。
  • MultiPointMultiLineStringMultiPolygon:多点、多线、多面。

使用 Turf.js 时要特别注意一个基础规则:GeoJSON 坐标顺序是 [经度, 纬度],不是 [纬度, 经度]。很多 Turf.js 前端分析错误都来自坐标顺序写反。

另一个关键点是单位。Turf.js 的距离、面积、缓冲区等函数通常提供单位参数,例如 kilometers、meters、miles。前端分析结果是否可信,很大程度取决于坐标、单位和数据范围是否设置正确。

步骤:Turf.js 前端分析怎么做

步骤 1:安装或引入 Turf.js

如果是现代前端项目,例如 Vite、Vue、React 或 Webpack 项目,推荐使用 npm 安装:

npm install @turf/turf

在代码中引入:

import * as turf from '@turf/turf';

如果是简单 HTML 页面,也可以通过 CDN 引入:

<script src="https://cdn.jsdelivr.net/npm/@turf/turf@7/turf.min.js"></script>

实际项目中建议使用 npm 方式,便于打包、版本管理和按需优化。

步骤 2:准备 GeoJSON 数据

下面先创建一个点和一个面。点可以代表用户当前位置,面可以代表一个业务区域或电子围栏。

import * as turf from '@turf/turf';

const point = turf.point([116.3913, 39.9075], {
  name: '用户位置'
});

const polygon = turf.polygon([[
  [116.3800, 39.9000],
  [116.4050, 39.9000],
  [116.4050, 39.9200],
  [116.3800, 39.9200],
  [116.3800, 39.9000]
]], {
  name: '业务区域'
});

注意 Polygon 的首尾坐标必须闭合,也就是第一个点和最后一个点相同。否则部分空间分析函数可能返回异常结果。

步骤 3:判断点是否在面内

点在面内判断是 Turf.js 前端分析中最常见的功能之一,适用于电子围栏、行政区匹配、区域权限判断等场景。

const inside = turf.booleanPointInPolygon(point, polygon);

if (inside) {
  console.log('点在面内');
} else {
  console.log('点不在面内');
}

如果你在 Leaflet 或 OpenLayers 中监听地图点击事件,可以把点击坐标转成 Turf.js 的 point,再用 booleanPointInPolygon 判断是否落入指定区域。

步骤 4:计算两点之间的距离

Turf.js 的 distance 函数可以计算两点之间的球面距离。适合测距、最近设施判断、范围提示等场景。

const start = turf.point([116.3913, 39.9075]);
const end = turf.point([116.3970, 39.9088]);

const distance = turf.distance(start, end, {
  units: 'kilometers'
});

console.log(`两点距离约为 ${distance.toFixed(3)} 公里`);

如果要显示米,可以使用 units: ‘meters’。前端展示时建议保留合理小数位,避免给用户造成“厘米级精度”的错觉。

步骤 5:生成缓冲区

缓冲区是 GIS 分析中非常常见的操作。比如计算某个点 500 米范围内的区域,或生成道路两侧影响范围。

const center = turf.point([116.3913, 39.9075]);

const buffer = turf.buffer(center, 500, {
  units: 'meters',
  steps: 64
});

console.log(buffer);

steps 控制缓冲区边界的平滑程度。数值越大,圆越平滑,但几何点也越多,前端渲染和计算压力会更大。普通 WebGIS 交互场景中,32 或 64 通常已经够用。

步骤 6:计算线长度

对于轨迹、道路、管线等线数据,可以使用 length 函数计算长度。

const line = turf.lineString([
  [116.3800, 39.9000],
  [116.3900, 39.9050],
  [116.4000, 39.9100]
]);

const length = turf.length(line, {
  units: 'kilometers'
});

console.log(`线长度约为 ${length.toFixed(3)} 公里`);

如果你的轨迹点很多,建议先检查是否有重复点、异常跳点和坐标顺序错误,否则长度结果可能明显偏大。

步骤 7:计算面面积

面积统计常用于地块、行政区、服务范围、缓冲区结果评估。Turf.js 的 area 返回平方米。

const area = turf.area(polygon);

console.log(`面积约为 ${area.toFixed(2)} 平方米`);

需要注意,Turf.js 面积计算适合前端快速估算。如果涉及国土、测绘、工程结算等高精度面积,建议使用正确投影坐标系,并在 QGIS、ArcGIS Pro、PostGIS 或专业测绘软件中计算。

步骤 8:做相交和裁剪判断

在 WebGIS 中,经常需要判断两个面是否相交,或判断一个缓冲区是否覆盖业务区域。可以使用 booleanIntersects。

const intersects = turf.booleanIntersects(buffer, polygon);

if (intersects) {
  console.log('缓冲区与业务区域相交');
}

如果需要得到相交后的几何结果,可以使用 intersect。注意 intersect 对几何合法性要求更高,输入面如果自相交或不闭合,可能无法得到预期结果。

const intersection = turf.intersect(turf.featureCollection([buffer, polygon]));

if (intersection) {
  console.log('相交区域:', intersection);
} else {
  console.log('没有相交区域');
}

步骤 9:在 Leaflet 中显示 Turf.js 分析结果

Turf.js 只负责空间计算,不负责地图渲染。实际项目中通常与 Leaflet、OpenLayers 或 Mapbox GL JS 配合使用。下面是 Leaflet 的简化示例:

import L from 'leaflet';
import * as turf from '@turf/turf';

const map = L.map('map').setView([39.9075, 116.3913], 13);

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

map.on('click', function (e) {
  const clickedPoint = turf.point([e.latlng.lng, e.latlng.lat]);

  const buffer = turf.buffer(clickedPoint, 500, {
    units: 'meters'
  });

  L.geoJSON(buffer, {
    style: {
      color: '#0078ff',
      weight: 2,
      fillOpacity: 0.2
    }
  }).addTo(map);
});

这里最容易写错的是 e.latlng 的顺序。Leaflet 事件中通常是 lat、lng,而 GeoJSON 和 Turf.js 需要 lng、lat。

常见坑:Turf.js 前端分析结果不对的原因

1. 经纬度顺序写反

GeoJSON 坐标顺序是 [经度, 纬度]。如果写成 [纬度, 经度],点会跑到错误位置,距离、面积、包含关系都会异常。

// 正确:北京附近
const p1 = turf.point([116.3913, 39.9075]);

// 错误:顺序反了
const p2 = turf.point([39.9075, 116.3913]);

2. 把投影坐标当成经纬度坐标

Turf.js 主要面向 GeoJSON,经常处理 WGS84 经纬度坐标。如果你把 Web Mercator 米制坐标或本地投影坐标直接传进去,结果很可能不正确。

常见错误示例是把 EPSG:3857 的坐标直接传给 turf.point。EPSG:3857 的数值通常是几百万级,而经纬度通常在 -180 到 180、-90 到 90 范围内。

3. 数据量太大导致浏览器卡顿

Turf.js 前端分析运行在用户浏览器中。几百个、几千个要素通常可以处理,但如果一次加载几十万点或大量复杂面,页面很容易卡顿。

优化思路包括:

  • 先在后端或 PostGIS 中筛选数据,再传给前端。
  • 使用 bbox 过滤,减少参与计算的要素数量。
  • 对复杂面做简化,但要确认简化后不影响业务判断。
  • 把耗时分析放到 Web Worker,避免阻塞主线程。

4. Polygon 没有闭合或几何无效

Polygon 的外环和内环都应闭合。面自相交、重复点过多、孔洞方向混乱等问题也可能导致叠加分析失败。

如果 Turf.js 的 intersect、union、difference 结果异常,建议先用 QGIS 的“检查几何有效性”和“修复几何”工具处理数据。

5. 把前端结果当成权威测绘结果

Turf.js 非常适合 WebGIS 交互分析,但它不是严肃测绘成果生产工具。对于法律边界、地籍面积、工程量结算等场景,不建议只依赖浏览器端分析结果。

方法比较:Turf.js、PostGIS、QGIS 和 ArcGIS Pro 怎么选

方法 适合场景 优点 限制
Turf.js 浏览器端即时分析、地图交互、轻量 GeoJSON 计算 部署简单、反馈快、与 WebGIS 前端结合方便 不适合超大数据和高精度生产分析
PostGIS 服务端空间查询、批量分析、大数据筛选 空间索引强、适合数据库级查询和稳定服务 需要数据库环境和 SQL 能力
QGIS 桌面 GIS 分析、数据检查、格式转换、可视化制图 工具丰富、适合人工处理和结果核查 不适合作为高并发在线分析服务
ArcGIS Pro 专业 GIS 分析、企业流程、测绘和制图生产 分析工具体系完整、适合规范化生产 软件授权和环境成本较高

一个比较稳妥的实践是:前端用 Turf.js 做交互预判和即时展示,后端用 PostGIS 或 GIS 服务做正式查询,桌面端用 QGIS 或 ArcGIS Pro 做数据清洗和结果核查。

检查清单:上线前如何检查 Turf.js 前端分析

  • 确认输入数据是合法 GeoJSON。
  • 确认坐标顺序为 [经度, 纬度]。
  • 确认数据坐标系适合 Turf.js 处理,不要误传投影坐标。
  • 确认距离、缓冲区、长度等函数的 units 参数设置正确。
  • 确认 Polygon 首尾闭合,复杂面已做几何有效性检查。
  • 确认前端一次参与分析的数据量不会导致页面卡顿。
  • 确认分析结果在地图上可视化后与人工判断一致。
  • 确认关键业务结果有后端或桌面 GIS 工具复核机制。
  • 确认异常情况有提示,例如无相交结果、空数据、坐标缺失。
  • 确认生产环境固定 Turf.js 版本,避免依赖升级后行为变化。

FAQ:Turf.js 前端分析常见问题

Turf.js 前端分析能不能替代 PostGIS?

不能简单替代。Turf.js 适合浏览器端轻量分析和交互反馈,PostGIS 适合服务端空间查询、大数据分析、空间索引和稳定业务服务。实际项目中,两者经常配合使用。

Turf.js 常用功能有哪些?

Turf.js 常用功能包括距离计算、面积计算、缓冲区生成、点在面内判断、线长度计算、相交判断、裁剪、合并、中心点计算、bbox 计算、沿线取点和要素筛选等。其中距离、缓冲区和点面关系是 WebGIS 项目里最常见的功能。

Turf.js 计算面积准不准?

对于 WebGIS 前端展示和快速估算,Turf.js 面积计算通常够用。但如果涉及高精度面积统计、地籍、测绘或工程结算,应使用合适的投影坐标系,并在 QGIS、ArcGIS Pro 或 PostGIS 中进行正式计算。

Turf.js 为什么缓冲区看起来变形?

常见原因有三个:底图投影显示造成视觉差异、坐标输入顺序错误、单位参数设置错误。还要注意,在高纬度地区或大范围缓冲区中,前端地图显示效果可能与实际地表距离存在差异。

Turf.js 可以处理 Shapefile 吗?

Turf.js 本身主要处理 GeoJSON,不直接处理 Shapefile。通常需要先在 QGIS、GDAL、GeoServer、后端接口或前端转换库中把 Shapefile 转成 GeoJSON,再交给 Turf.js 分析。

OpenLayers 或 Leaflet 已经有空间分析功能,还需要 Turf.js 吗?

Leaflet 和 OpenLayers 主要负责地图展示、图层管理和交互。它们有一些几何辅助能力,但完整的空间分析函数不如 Turf.js 集中。对于 GeoJSON 距离、缓冲区、点面关系、叠加分析等需求,引入 Turf.js 更直接。

Turf.js 前端分析卡顿怎么办?

先减少参与分析的数据量,例如使用 bbox 过滤或服务端预筛选;再考虑简化几何、分页加载、空间索引、Web Worker 或把核心分析迁移到后端。不要把所有原始大数据一次性塞进浏览器。

结论

Turf.js前端分析怎么做?常用功能有哪些? 简单来说,就是以 GeoJSON 为输入,在浏览器中使用 Turf.js 完成距离、面积、缓冲区、点面判断、相交分析等轻量空间计算,再把结果交给 Leaflet、OpenLayers 或 Mapbox GL JS 渲染出来。

它的优势是开发快、交互自然、适合 WebGIS 即时反馈;限制是数据量、几何复杂度和精度控制。项目中不要把 Turf.js 当成万能 GIS 引擎,而应把它放在合适的位置:前端负责快速交互,后端和专业 GIS 工具负责正式分析与数据质量控制。

如果你刚开始做 WebGIS 空间分析,建议先掌握四个基础功能:距离计算、缓冲区、点在面内判断、面积计算。把坐标顺序、单位参数和 GeoJSON 合法性这三件事检查好,大部分 Turf.js 前端分析问题都能避免。