Turf.js正確使用超詳細案例
概述
Turf.js 是一個用 JavaScript 和 TypeScript 編寫的模塊化地理空間分析引擎。它是一個強大的空間分析庫,可以在瀏覽器端或 Node.js 服務(wù)器端運行。
- 官網(wǎng): https://turfjs.org
- GitHub: https://github.com/turfjs/turf
- npm:
@turf/turf - 當前版本: 7.3.0
- 許可證: MIT(開源免費)
核心特點
主要功能
- 傳統(tǒng)空間操作: 緩沖區(qū)分析、疊加分析、距離計算等
- GeoJSON 輔助函數(shù): 創(chuàng)建和處理 GeoJSON 地理數(shù)據(jù)
- 數(shù)據(jù)分類和統(tǒng)計工具: 空間數(shù)據(jù)分析和可視化
- 客戶端分析: 無需服務(wù)器往返,直接在瀏覽器中執(zhí)行空間運算
運行環(huán)境
- Node.js: 推薦使用 Active 或 Maintenance LTS 版本
- 瀏覽器: 支持所有現(xiàn)代瀏覽器(>0.25%, last 2 versions, fully supports es5, not dead)
- 其他運行時: Deno、Bun 等(非官方支持,但可使用)
詳細功能示例
1. 緩沖區(qū)分析 (Buffer)
創(chuàng)建地理要素周圍的緩沖區(qū),用于鄰近度分析、創(chuàng)建捕獲區(qū)域等。
// 創(chuàng)建圍繞 TCU 大學(xué)的 2 英里緩沖區(qū)
const tcu = turf.point([-97.364, 32.708]);
const buffered = turf.buffer(tcu, 2, {units: 'miles'});
// 可視化:紫色半透明緩沖區(qū)
// 用途:學(xué)校服務(wù)范圍、噪音影響區(qū)域、配送范圍
實際應(yīng)用場景:
- ?? 商店配送范圍分析
- ?? 學(xué)校招生區(qū)域劃定
- ?? 醫(yī)院服務(wù)覆蓋范圍
- ?? 信號塔覆蓋區(qū)域
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
實際應(yīng)用場景:
- ?? 航班距離計算
- ?? 導(dǎo)航路線規(guī)劃
- ?? 物流配送距離估算
- ?? 運動軌跡分析
3. 空間過濾 (Spatial Filtering)
根據(jù)空間關(guān)系過濾地理要素,支持 5 種空間謂詞:
// 查找與緩沖區(qū)相交的所有人口普查區(qū)
const filtered = turf.filter(tracts, bufferZone, {
predicate: 'intersects' // 或 'within', 'contains', 'crosses', 'disjoint'
});
5 種空間謂詞:
| 謂詞 | 說明 | 示例 |
|---|---|---|
intersects | 重疊或接觸 | 查找與洪水區(qū)相交的建筑物 |
within | 完全在內(nèi)部 | 查找完全在學(xué)區(qū)內(nèi)的房屋 |
contains | 完全包含 | 查找包含公園的行政區(qū) |
crosses | 穿越邊界 | 查找穿越河流的道路 |
disjoint | 完全不接觸 | 查找遠離污染源的居民區(qū) |
實際應(yīng)用場景:
- ??? 城市規(guī)劃:查找特定區(qū)域內(nèi)的設(shè)施
- ?? 災(zāi)害管理:識別受影響區(qū)域
- ??? 房地產(chǎn):篩選符合位置條件的物業(yè)
- ?? 生態(tài)保護:識別保護區(qū)內(nèi)的活動
4. 幾何中心計算 (Centroid & Center of Mass)
計算多邊形的幾何中心或質(zhì)心。
// 幾何中心(幾何中心點) const centroid = turf.centroid(polygon); // 質(zhì)心(面積加權(quán)中心,適用于不規(guī)則形狀) const centerOfMass = turf.centerOfMass(polygon); // 兩者可能不同:對于不規(guī)則多邊形,質(zhì)心更準確
實際應(yīng)用場景:
- ?? 地圖標記:在多邊形中心放置標簽
- ?? 設(shè)施選址:找到區(qū)域的中心位置
- ?? 數(shù)據(jù)可視化:聚合數(shù)據(jù)的中心點顯示
- ?? 物流中心:優(yōu)化配送中心位置
5. 凸包分析 (Convex Hull)
創(chuàng)建包含一組點的最小凸多邊形。
// 為一系列點創(chuàng)建凸包 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); // 結(jié)果:包圍所有點的最小凸多邊形
實際應(yīng)用場景:
- ??? 勢力范圍:確定一組地點的覆蓋邊界
- ?? 動物追蹤:分析動物活動范圍
- ?? 無人機巡檢:規(guī)劃飛行區(qū)域邊界
- ?? 市場分析:確定客戶分布范圍
6. 泰森多邊形 (Voronoi)
從點集生成 Voronoi 多邊形,每個多邊形包含距離該點最近的所有區(qū)域。
// 為一系列點生成 Voronoi 圖
const points = turf.featureCollection([...]); // 多個點
const voronoi = turf.voronoi(points, {
bbox: [-77, 38, -76, 40] // 邊界框
});
// 每個多邊形代表該點的"影響區(qū)域"
實際應(yīng)用場景:
- ?? 商業(yè)區(qū)劃分:每個商店的服務(wù)區(qū)域
- ?? 基站覆蓋:手機信號塔的服務(wù)范圍
- ?? 應(yīng)急響應(yīng):消防站的責任區(qū)域
- ?? 學(xué)區(qū)劃分:學(xué)校的服務(wù)范圍
7. 疊加分析 (Overlay Analysis)
7.1 相交分析 (Intersect)
返回兩個要素的實際重疊區(qū)域幾何。
// 創(chuàng)建兩個重疊的緩沖區(qū)
const buffer1 = turf.buffer(point1, 1, {units: 'miles'});
const buffer2 = turf.buffer(point2, 1, {units: 'miles'});
// 計算重疊區(qū)域
const intersection = turf.intersect(buffer1, buffer2);
// 如果無重疊,返回 null
實際應(yīng)用場景:
- ?? 洪水分析:多個洪水區(qū)的重疊區(qū)域
- ??? 項目規(guī)劃:多個限制條件的共同區(qū)域
- ?? 生態(tài)研究:多個物種棲息地的交集
- ?? 信號分析:多個信號塔的覆蓋重疊區(qū)
7.2 聯(lián)合分析 (Union)
合并多個多邊形為一個。
const union = turf.union(polygon1, polygon2, polygon3); // 結(jié)果:所有多邊形合并后的單一多邊形
7.3 差異分析 (Difference)
從一個多邊形中減去另一個。
const difference = turf.difference(protectedArea, developmentZone); // 結(jié)果:保護區(qū)內(nèi)未開發(fā)的區(qū)域
8. 幾何操作 (Geometric Operations)
8.1 創(chuàng)建幾何要素
// 創(chuàng)建點 const point = turf.point([-76.5, 39.5]); // 創(chuàng)建線 const line = turf.lineString([ [-76.5, 39.5], [-76.4, 39.6], [-76.3, 39.7] ]); // 創(chuàng)建多邊形 const polygon = turf.polygon([[ [-76.5, 39.5], [-76.4, 39.5], [-76.4, 39.6], [-76.5, 39.6], [-76.5, 39.5] // 閉合 ]]); // 創(chuàng)建矩形 const bbox = [-76.5, 39.5, -76.3, 39.7]; // [minX, minY, maxX, maxY] const rectangle = turf.bboxPolygon(bbox);
8.2 幾何變換
// 旋轉(zhuǎn)多邊形
const rotated = turf.rotate(polygon, 45, {pivot: 'center'});
// 縮放
const scaled = turf.transformScale(polygon, 2); // 放大 2 倍
// 平移
const translated = turf.translate(polygon, [1, 1]); // 向東北移動
9. ?? 空間統(tǒng)計 (Spatial Statistics)
9.1 點聚合分析
// 計算點的密度
const density = turf.nearestPointDensity(points, {
radius: 100,
units: 'kilometers'
});
// 查找最近點
const nearest = turf.nearestPoint(targetPoint, pointCollection);
9.2 網(wǎng)格分析
// 創(chuàng)建網(wǎng)格
const grid = turf.rectangleGrid(bbox, 1, 1, {units: 'kilometers'});
// 六邊形網(wǎng)格(更適合空間分析)
const hexGrid = turf.hexGrid(bbox, 1, {units: 'kilometers'});
實際應(yīng)用場景:
- ?? 人口密度熱力圖
- ??? 氣象數(shù)據(jù)插值
- ?? 房價空間分析
- ?? 疾病傳播模型
10. 路徑和導(dǎo)航 (Routing & Navigation)
// 計算兩點間的測地線(最短路徑)
const greatCircle = turf.greatCircle(start, end);
// 沿線創(chuàng)建點
const along = turf.along(lineString, 5, {units: 'kilometers'});
// 返回從起點開始 5 公里處的點
// 線的長度
const length = turf.length(lineString, {units: 'kilometers'});
實際應(yīng)用場景:
- ?? 航線規(guī)劃
- ?? 航海路線
- ?? 騎行路線分析
- ?? 管線/電纜鋪設(shè)
安裝和使用
Node.js 環(huán)境
npm install @turf/turf
// 導(dǎo)入整個庫
const turf = require('@turf/turf');
// 或按需導(dǎo)入(推薦,減小打包體積)
const buffer = require('@turf/buffer');
const distance = require('@turf/distance');
const intersect = require('@turf/intersect');
瀏覽器環(huán)境
<!-- 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>
現(xiàn)代 JavaScript (ES Modules)
import { buffer, distance, intersect } from '@turf/turf';
const point = turf.point([-76.5, 39.5]);
實際應(yīng)用案例
案例 1: 共享單車站點優(yōu)化
// 分析現(xiàn)有站點的覆蓋范圍
const stations = [...]; // 站點位置
const coverage = stations.map(station =>
turf.buffer(station, 0.5, {units: 'kilometers'}) // 500 米覆蓋
);
// 找出未覆蓋的區(qū)域
const cityBounds = turf.polygon([...]);
const unionCoverage = turf.union(...coverage);
const gaps = turf.difference(cityBounds, unionCoverage);
// 在缺口處建議新站點
const suggestedLocations = turf.centroid(gaps);
案例 2: 緊急醫(yī)療服務(wù)分析
// 計算每個醫(yī)院的服務(wù)范圍(15 分鐘車程 ≈ 10 公里)
const hospitals = [...];
const serviceAreas = hospitals.map(h =>
turf.buffer(h, 10, {units: 'kilometers'})
);
// 查找未被覆蓋的居民區(qū)
const residentialAreas = [...];
const uncovered = residentialAreas.filter(area =>
!serviceAreas.some(service => turf.booleanIntersects(area, service))
);
// 建議新醫(yī)院位置
const optimalLocation = turf.centerOfMass(turf.union(...uncovered));
案例 3: 城市綠地分析
// 計算每個社區(qū)的綠地可達性
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 米內(nèi)有公園
});
community.properties.greenSpaceAccess = nearbyParks.length > 0;
});
性能優(yōu)勢
客戶端分析的優(yōu)勢
- 實時響應(yīng): 無需等待服務(wù)器,用戶操作即時反饋
- 降低服務(wù)器負載: 空間計算在用戶設(shè)備上進行
- 離線工作: 數(shù)據(jù)加載后可離線分析
- 隱私保護: 敏感地理數(shù)據(jù)不必上傳到服務(wù)器
交互式應(yīng)用示例
// Shiny/R 或 React 應(yīng)用中的實時空間過濾
map.on('draw:created', (e) => {
const drawnPolygon = e.layer;
// 立即過濾顯示結(jié)果
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 |
| 網(wǎng)格 | rectangleGrid, hexGrid, pointGrid |
| 隨機 | randomPoint, randomPolygon, randomPosition |
| 輔助 | centroid, center, centerOfMass, bboxPolygon |
完整 API 文檔:https://turfjs.org/docs/api
總結(jié)
Turf.js 是一個功能強大、靈活易用的地理空間分析庫,適用于:
- ?? Web 地圖應(yīng)用: Leaflet、Mapbox、OpenLayers 等
- ?? 移動應(yīng)用: React Native、Ionic 等
- ??? 桌面應(yīng)用: Electron、Node.js 后端
- ?? 數(shù)據(jù)分析: Jupyter、R Shiny、數(shù)據(jù)科學(xué)工作流
- ?? 游戲開發(fā): 需要空間邏輯的游戲
核心優(yōu)勢:
- ? 純 JavaScript,無需原生依賴
- ? 模塊化設(shè)計,按需使用
- ? 支持 GeoJSON 標準,兼容性好
- ? 客戶端運行,響應(yīng)快速
- ? 活躍的社區(qū)和完善的文檔
到此這篇關(guān)于Turf.js正確使用超詳細案例的文章就介紹到這了,更多相關(guān)Turf.js使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript用函數(shù)實現(xiàn)對象的方法
這篇文章主要介紹了javascript用函數(shù)實現(xiàn)對象的方法,涉及javascript函數(shù)使用技巧,需要的朋友可以參考下2015-05-05
JavaScript 獲取用戶客戶端操作系統(tǒng)版本
今天,同事反映部分電腦訪問系統(tǒng),安裝播放器(Media Player)報錯,自己本機測試沒問題,但是去用戶現(xiàn)場查看情況,部分電腦確實存在此類問題,不知道問題出在何處,希望我?guī)椭鉀Q一下。2009-08-08
JavaScript判斷表單提交時哪個radio按鈕被選中的方法
這篇文章主要介紹了JavaScript判斷表單提交時哪個radio按鈕被選中的方法,實例分析了javascript操作表單radio按鈕的技巧,非常具有實用價值,需要的朋友可以參考下2015-03-03

