Turf.js正确使用超详细案例
作者:DRAGON_SIR_
Turf是用于空间分析的JavaScript库,它包括传统的空间操作、用于创建GeoJSON数据的辅助函数,以及数据分类和统计工具,这篇文章主要介绍了Turf.js正确使用的相关资料,需要的朋友可以参考下
概述
Turf.js 是一个用 JavaScript 和 TypeScript 编写的模块化地理空间分析引擎。它是一个强大的空间分析库,可以在浏览器端或 Node.js 服务器端运行。
- 官网: https://turfjs.org
- GitHub: https://github.com/turfjs/turf
- npm:
@turf/turf - 当前版本: 7.3.0
- 许可证: MIT(开源免费)
核心特点
主要功能
- 传统空间操作: 缓冲区分析、叠加分析、距离计算等
- GeoJSON 辅助函数: 创建和处理 GeoJSON 地理数据
- 数据分类和统计工具: 空间数据分析和可视化
- 客户端分析: 无需服务器往返,直接在浏览器中执行空间运算
运行环境
- Node.js: 推荐使用 Active 或 Maintenance LTS 版本
- 浏览器: 支持所有现代浏览器(>0.25%, last 2 versions, fully supports es5, not dead)
- 其他运行时: Deno、Bun 等(非官方支持,但可使用)
详细功能示例
1. 缓冲区分析 (Buffer)
创建地理要素周围的缓冲区,用于邻近度分析、创建捕获区域等。
// 创建围绕 TCU 大学的 2 英里缓冲区
const tcu = turf.point([-97.364, 32.708]);
const buffered = turf.buffer(tcu, 2, {units: 'miles'});
// 可视化:紫色半透明缓冲区
// 用途:学校服务范围、噪音影响区域、配送范围
实际应用场景:
- 🏪 商店配送范围分析
- 🏫 学校招生区域划定
- 🏥 医院服务覆盖范围
- 📡 信号塔覆盖区域
2. 距离计算 (Distance)
使用 Haversine 公式计算两个坐标点之间的距离,考虑地球曲率。
// 计算纽约和伦敦之间的距离
const from = turf.point([-74.0060, 40.7128]); // 纽约
const to = turf.point([-0.1278, 51.5074]); // 伦敦
const distance = turf.distance(from, to, {units: 'kilometers'});
console.log(distance); // 约 5570 公里
// 支持单位:degrees, radians, miles, kilometers
实际应用场景:
- ✈️ 航班距离计算
- 🚗 导航路线规划
- 📦 物流配送距离估算
- 🏃 运动轨迹分析
3. 空间过滤 (Spatial Filtering)
根据空间关系过滤地理要素,支持 5 种空间谓词:
// 查找与缓冲区相交的所有人口普查区
const filtered = turf.filter(tracts, bufferZone, {
predicate: 'intersects' // 或 'within', 'contains', 'crosses', 'disjoint'
});
5 种空间谓词:
| 谓词 | 说明 | 示例 |
|---|---|---|
intersects | 重叠或接触 | 查找与洪水区相交的建筑物 |
within | 完全在内部 | 查找完全在学区内的房屋 |
contains | 完全包含 | 查找包含公园的行政区 |
crosses | 穿越边界 | 查找穿越河流的道路 |
disjoint | 完全不接触 | 查找远离污染源的居民区 |
实际应用场景:
- 🗺️ 城市规划:查找特定区域内的设施
- 🚨 灾害管理:识别受影响区域
- 🏘️ 房地产:筛选符合位置条件的物业
- 🌲 生态保护:识别保护区内的活动
4. 几何中心计算 (Centroid & Center of Mass)
计算多边形的几何中心或质心。
// 几何中心(几何中心点) const centroid = turf.centroid(polygon); // 质心(面积加权中心,适用于不规则形状) const centerOfMass = turf.centerOfMass(polygon); // 两者可能不同:对于不规则多边形,质心更准确
实际应用场景:
- 📍 地图标记:在多边形中心放置标签
- 🏢 设施选址:找到区域的中心位置
- 📊 数据可视化:聚合数据的中心点显示
- 🚚 物流中心:优化配送中心位置
5. 凸包分析 (Convex Hull)
创建包含一组点的最小凸多边形。
// 为一系列点创建凸包 const points = turf.featureCollection([ turf.point([-76, 39]), turf.point([-76, 41]), turf.point([-78, 40]), turf.point([-77, 38]) ]); const hull = turf.convexHull(points); // 结果:包围所有点的最小凸多边形
实际应用场景:
- 🗺️ 势力范围:确定一组地点的覆盖边界
- 🦅 动物追踪:分析动物活动范围
- 🚁 无人机巡检:规划飞行区域边界
- 📈 市场分析:确定客户分布范围
6. 泰森多边形 (Voronoi)
从点集生成 Voronoi 多边形,每个多边形包含距离该点最近的所有区域。
// 为一系列点生成 Voronoi 图
const points = turf.featureCollection([...]); // 多个点
const voronoi = turf.voronoi(points, {
bbox: [-77, 38, -76, 40] // 边界框
});
// 每个多边形代表该点的"影响区域"
实际应用场景:
- 🏪 商业区划分:每个商店的服务区域
- 📡 基站覆盖:手机信号塔的服务范围
- 🚒 应急响应:消防站的责任区域
- 🏫 学区划分:学校的服务范围
7. 叠加分析 (Overlay Analysis)
7.1 相交分析 (Intersect)
返回两个要素的实际重叠区域几何。
// 创建两个重叠的缓冲区
const buffer1 = turf.buffer(point1, 1, {units: 'miles'});
const buffer2 = turf.buffer(point2, 1, {units: 'miles'});
// 计算重叠区域
const intersection = turf.intersect(buffer1, buffer2);
// 如果无重叠,返回 null
实际应用场景:
- 🌊 洪水分析:多个洪水区的重叠区域
- 🏗️ 项目规划:多个限制条件的共同区域
- 🌳 生态研究:多个物种栖息地的交集
- 📶 信号分析:多个信号塔的覆盖重叠区
7.2 联合分析 (Union)
合并多个多边形为一个。
const union = turf.union(polygon1, polygon2, polygon3); // 结果:所有多边形合并后的单一多边形
7.3 差异分析 (Difference)
从一个多边形中减去另一个。
const difference = turf.difference(protectedArea, developmentZone); // 结果:保护区内未开发的区域
8. 几何操作 (Geometric Operations)
8.1 创建几何要素
// 创建点 const point = turf.point([-76.5, 39.5]); // 创建线 const line = turf.lineString([ [-76.5, 39.5], [-76.4, 39.6], [-76.3, 39.7] ]); // 创建多边形 const polygon = turf.polygon([[ [-76.5, 39.5], [-76.4, 39.5], [-76.4, 39.6], [-76.5, 39.6], [-76.5, 39.5] // 闭合 ]]); // 创建矩形 const bbox = [-76.5, 39.5, -76.3, 39.7]; // [minX, minY, maxX, maxY] const rectangle = turf.bboxPolygon(bbox);
8.2 几何变换
// 旋转多边形
const rotated = turf.rotate(polygon, 45, {pivot: 'center'});
// 缩放
const scaled = turf.transformScale(polygon, 2); // 放大 2 倍
// 平移
const translated = turf.translate(polygon, [1, 1]); // 向东北移动
9. 📊 空间统计 (Spatial Statistics)
9.1 点聚合分析
// 计算点的密度
const density = turf.nearestPointDensity(points, {
radius: 100,
units: 'kilometers'
});
// 查找最近点
const nearest = turf.nearestPoint(targetPoint, pointCollection);
9.2 网格分析
// 创建网格
const grid = turf.rectangleGrid(bbox, 1, 1, {units: 'kilometers'});
// 六边形网格(更适合空间分析)
const hexGrid = turf.hexGrid(bbox, 1, {units: 'kilometers'});
实际应用场景:
- 📱 人口密度热力图
- 🌡️ 气象数据插值
- 🏠 房价空间分析
- 🦠 疾病传播模型
10. 路径和导航 (Routing & Navigation)
// 计算两点间的测地线(最短路径)
const greatCircle = turf.greatCircle(start, end);
// 沿线创建点
const along = turf.along(lineString, 5, {units: 'kilometers'});
// 返回从起点开始 5 公里处的点
// 线的长度
const length = turf.length(lineString, {units: 'kilometers'});
实际应用场景:
- ✈️ 航线规划
- 🚢 航海路线
- 🚴 骑行路线分析
- 📏 管线/电缆铺设
安装和使用
Node.js 环境
npm install @turf/turf
// 导入整个库
const turf = require('@turf/turf');
// 或按需导入(推荐,减小打包体积)
const buffer = require('@turf/buffer');
const distance = require('@turf/distance');
const intersect = require('@turf/intersect');
浏览器环境
<!-- CDN 方式 -->
<script src="https://unpkg.com/@turf/turf@7/turf.min.js"></script>
<script>
const point = turf.point([-76.5, 39.5]);
const buffered = turf.buffer(point, 1, {units: 'miles'});
</script>
现代 JavaScript (ES Modules)
import { buffer, distance, intersect } from '@turf/turf';
const point = turf.point([-76.5, 39.5]);
实际应用案例
案例 1: 共享单车站点优化
// 分析现有站点的覆盖范围
const stations = [...]; // 站点位置
const coverage = stations.map(station =>
turf.buffer(station, 0.5, {units: 'kilometers'}) // 500 米覆盖
);
// 找出未覆盖的区域
const cityBounds = turf.polygon([...]);
const unionCoverage = turf.union(...coverage);
const gaps = turf.difference(cityBounds, unionCoverage);
// 在缺口处建议新站点
const suggestedLocations = turf.centroid(gaps);
案例 2: 紧急医疗服务分析
// 计算每个医院的服务范围(15 分钟车程 ≈ 10 公里)
const hospitals = [...];
const serviceAreas = hospitals.map(h =>
turf.buffer(h, 10, {units: 'kilometers'})
);
// 查找未被覆盖的居民区
const residentialAreas = [...];
const uncovered = residentialAreas.filter(area =>
!serviceAreas.some(service => turf.booleanIntersects(area, service))
);
// 建议新医院位置
const optimalLocation = turf.centerOfMass(turf.union(...uncovered));
案例 3: 城市绿地分析
// 计算每个社区的绿地可达性
const parks = [...];
const communities = [...];
communities.forEach(community => {
const nearbyParks = parks.filter(park => {
const dist = turf.distance(community, park, {units: 'kilometers'});
return dist < 0.5; // 500 米内有公园
});
community.properties.greenSpaceAccess = nearbyParks.length > 0;
});
性能优势
客户端分析的优势
- 实时响应: 无需等待服务器,用户操作即时反馈
- 降低服务器负载: 空间计算在用户设备上进行
- 离线工作: 数据加载后可离线分析
- 隐私保护: 敏感地理数据不必上传到服务器
交互式应用示例
// Shiny/R 或 React 应用中的实时空间过滤
map.on('draw:created', (e) => {
const drawnPolygon = e.layer;
// 立即过滤显示结果
const filtered = turf.filter(allFeatures, drawnPolygon, {
predicate: 'intersects'
});
// 即时更新地图显示
updateMapLayer(filtered);
});
支持的模块列表(部分)
| 类别 | 模块 |
|---|---|
| 测量 | distance, length, area, bbox |
| 插值 | interpolate, idw, tin |
| 变换 | buffer, rotate, scale, translate |
| 叠加 | intersect, union, difference, symDifference |
| 要素 | point, lineString, polygon, featureCollection |
| 聚合 | collect, combine, explode |
| 集合 | nearestPoint, nearestPointOnLine, clusterEach |
| 网格 | rectangleGrid, hexGrid, pointGrid |
| 随机 | randomPoint, randomPolygon, randomPosition |
| 辅助 | centroid, center, centerOfMass, bboxPolygon |
完整 API 文档:https://turfjs.org/docs/api
总结
Turf.js 是一个功能强大、灵活易用的地理空间分析库,适用于:
- 🌐 Web 地图应用: Leaflet、Mapbox、OpenLayers 等
- 📱 移动应用: React Native、Ionic 等
- 🖥️ 桌面应用: Electron、Node.js 后端
- 📊 数据分析: Jupyter、R Shiny、数据科学工作流
- 🎮 游戏开发: 需要空间逻辑的游戏
核心优势:
- ✅ 纯 JavaScript,无需原生依赖
- ✅ 模块化设计,按需使用
- ✅ 支持 GeoJSON 标准,兼容性好
- ✅ 客户端运行,响应快速
- ✅ 活跃的社区和完善的文档
到此这篇关于Turf.js正确使用超详细案例的文章就介绍到这了,更多相关Turf.js使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
