尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Turf isobands 深度指南:使用 @turf/isobands 从点网格生成填充等值面

发布时间:2026/9/25 17:38:19

资讯中心
01
ARTICLE

Turf isobands 深度指南:使用 @turf/isobands 从点网格生成填充等值面

Turf isobands 深度指南:使用 @turf/isobands 从点网格生成填充等值面
数据分析【免费下载链接】turfA modular geospatial engine written in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/tu/turf点击查看免费下载turf/isobands是 Turf 模块化地理空间引擎中负责**填充等值面filled contour isobands**生成的模块。它以带 z 值的点网格FeatureCollection of Point和一组数值断点breaks为输入输出一组表示值落于某个区间的面状 MultiPolygon。本文从 packages/turf-isobands/README.md 出发结合 index.ts 源码、内部工具库与测试用例完整讲解参数语义、网格输入约束、marching squares 核心算法、坐标重缩放原理、错误处理与测试验证方法读者读完可直接在自己的项目中用它生成高程分层、人口密度、温度区间等填充等值面。一、isobands 是什么与 isolines 的关系等值线族分为两类**等值线isolines**输出线状要素MultiLineString刻画值恰好等于某个阈值的边界等值面isobands则输出面状要素MultiPolygon刻画值落于两个相邻断点之间的连续区域通常以渐变填充色渲染。从源码结构看两者共用同一套 marching squares 分段思路但 isobands 的核心差异在于 index.ts 中createContourLines的注释所强调的Using segments from two different breaks[], and enforcing closed polygons are the two major difference between the implementation of turf/isolines and turf/isobands——isobands 需要同时使用相邻两个断点的分段来闭合多边形从而形成带状填充区域而 isolines 只需单层分段。在 package.json 中该模块被描述为Takes a grid of values (GeoJSON format) and a set of threshold ranges. It outputs polygons that group areas within those ranges, effectively creating filled contour isobands.二、安装与引入官方 README 提供了两种安装方式。当前仓库packages/turf-isobands的package.json声明version: 7.4.0、type: module且engines: { node: 22 }安装使用环境需满足该 Node 版本要求。单独安装本模块$ npm install turf/isobands或安装包含全部模块的一体化包所有模块以函数形式挂载$ npm install turf/turf在 ES Module 环境中导入import { isobands } from turf/isobands; // 使用一体化包时 import * as turf from turf/turf; turf.isobands(pointGrid, breaks, options);三、函数签名与参数详解README 中给出的isobands完整签名如下参数含义、默认值与类型约束是本文重点参数类型必填默认值说明pointGridFeatureCollectionPoint是—输入点网格必须是正方形或矩形、已规则网格化x/y 维度一致且至少 2x2breaksArraynumber是—等值面分段的断点数组决定在哪里切分等高带optionsObject否{}输出选项options.zPropertystring否elevation从点的 properties 中读取 z 值的属性名options.commonPropertiesObject否{}传递给所有等值面要素的公共 GeoJSON 属性options.breaksPropertiesArrayObject否[]按断点顺序依次传递给对应等值面要素的属性对象返回值FeatureCollectionMultiPolygon即一组代表等值面的 MultiPolygon 要素。源码 index.ts 对可选参数做了如下兜底与校验理解这些有助于排查问题options options || {}; if (!isObject(options)) throw new Error(options is invalid); const zProperty options.zProperty || elevation; const commonProperties options.commonProperties || {}; const breaksProperties options.breaksProperties || []; // Validation collectionOf(pointGrid, Point, Input must contain Points); if (!breaks) throw new Error(breaks is required); if (!Array.isArray(breaks)) throw new Error(breaks is not an Array); if (!isObject(commonProperties)) throw new Error(commonProperties is not an Object); if (!Array.isArray(breaksProperties)) throw new Error(breaksProperties is not an Array);pointGrid必须全部为 Point 要素否则抛错Input must contain Pointsbreaks为必填且必须是数组commonProperties必须是对象、breaksProperties必须是数组遍历生成每个等值面时还会校验breaksProperties中每一项必须是对象见 index.ts。四、快速上手完整可运行示例沿用官方 README 的文档约定README 由源码注释自动生成示例风格与 turf-isolines/README.md 一致构造一个 4x4 以上、带随机 z 值的点网格并生成等值面import { pointGrid } from turf/point-grid; import { isobands } from turf/isobands; // 1. 生成规则点网格extent 为 [minX, minY, maxX, maxY] const extent [0, 30, 20, 50]; const cellWidth 100; // 网格间距单位默认 kilometers const pointGrid pointGrid(extent, cellWidth, { units: miles }); // 2. 为每个点写入 z 值属性名默认为 elevation for (let i 0; i pointGrid.features.length; i) { pointGrid.features[i].properties.temperature Math.random() * 10; } // 3. 定义断点将生成 N-1 个等值面带 const breaks [0, 2, 4, 6, 8, 10]; // 4. 生成填充等值面 const bands isobands(pointGrid, breaks, { zProperty: temperature, // 指定 z 值属性名 commonProperties: { fill: #f00 }, // 公共属性加到所有要素上 breaksProperties: [ { fill-opacity: 0.2 }, { fill-opacity: 0.4 }, { fill-opacity: 0.6 }, { fill-opacity: 0.8 }, { fill-opacity: 1 }, ], // 按断点顺序逐个传入 }); // 5. 渲染bands.features.length 即断点数量减一 console.log(bands.type); // FeatureCollection console.log(bands.features[0].geometry.type); // MultiPolygon断点数量与输出数量的关系breaks有 N 个数值时输出 N-1 个等值面要素。源码createContourLines中循环for (let i 1; i breaks.length; i)每次以breaks[i-1]下界与breaks[i]上界构成一个区间带并在每个输出要素的属性上写入[zProperty] lowerBand - upperBand见 index.ts。以仓库测试数据 test/in/pointGrid.geojson 为例breaks: [0, 20, 40, 80, 160]会得到 4 个等值面其people属性值分别为0-20、20-40、40-80、80-160配合breaksProperties中由低到高的fill-opacity0.5 → 0.8即可在渲染层实现渐变分层。五、输入网格的硬性约束README 明确要求输入必须是正方形或矩形square or rectangular、已经规则网格化already gridded即 x、y 维度一致且至少 2x2。源码从两个方面强制校验矩阵维度校验index.tsgridToMatrix将点网格转换为二维数值矩阵后检查matrix.length 2 || dx 2则抛错Matrix of points must be at least 2x2随后逐行检查每行长度是否一致不一致则抛错Matrix of points is not uniform in the x dimension。内部工具校验gridToMatrix见 lib/grid-to-matrix.ts按纬度分组、组内按经度排序生成矩阵测试用例 test.ts 专门构造了一个点的经度是1e-10、与其他点几乎相同却不足以构成规则网格的输入验证此时isobands会抛出异常——这从侧面说明网格点必须严格按行列规则对齐否则排序后无法形成均匀矩阵。关于矩阵方向源码在注释中提醒矩阵坐标系的上/下与地理坐标相反——南半球用负数表示纬度因此矩阵 Y 为 0 处实际是底部Y 为dy - 1处是顶部见 index.ts。gridToMatrix默认按纬度从大到小排序而 isobands 内部以flip: true调用得到自下而上的矩阵保证 marching squares 输出的多边形绕向符合 GeoJSON 的右手逆时针约定。六、输出结构与属性语义geometry 类型每个输出要素为MultiPolygon即使只有一个外环也会以 MultiPolygon 形式返回z 值区间属性每个要素的properties[zProperty]为形如20-40的字符串下界-上界可以直接用于图例文本属性合并顺序contourProperties { ...commonProperties, ...breaksProperties[index] }index.ts即breaksProperties中的同名属性会覆盖commonProperties最后再写入zProperty区间值环的组织每个 MultiPolygon 内部按外环在前、内环洞在后的 GeoJSON 规则组织避免渲染时出现重叠错误。源码orderByArea用turf/area计算各环面积并降序排列index.tsgroupNestedRings再借助turf/boolean-point-in-polygon与turf/explode将互相包含的环分组index.ts。七、核心算法原理marching squares 源码级解读isobands 的实现是一条清晰的流水线gridToMatrix→createContourLines内含getSegments、assembleRings、orderByArea、groupNestedRings→rescaleContours→ 包装为 MultiPolygon 要素。7.1 网格转矩阵gridToMatrixlib/grid-to-matrix.ts 中的sortPointsByLatLng将点按纬度分成多行、每行按经度升序排列矩阵元素取properties[zProperty]缺失该属性时填入 0else row.push(0)见 grid-to-matrix.ts。这一点在使用时需要注意z 属性缺失会被静默当作 0 参与计算。7.2 分段提取getSegments 与 16 种单元格情形getSegmentsindex.ts对矩阵的每个 2x2 单元计算四个角tl 左上、tr 右上、br 右下、bl 左下是否超过阈值组合成 0~15 的二进制掩码let grid (tl threshold ? 8 : 0) | (tr threshold ? 4 : 0) | (br threshold ? 2 : 0) | (bl threshold ? 1 : 0);掩码为 0全部低于或 15全部高于时跳过其余情形在单元格边上产生一段逆时针线段。关键细节线性插值frac线段落点用阈值在相邻两角值间的比例插值t (threshold - z0) / (z1 - z0)并裁剪到 [0,1]若z0 z1取 0.5index.ts。这保证了等值面边界平滑而不是生硬地切在单元格角点上。鞍点处理case 5 与 10当对角线两角同高如 tl、br 高于阈值而 tr、bl 低于时存在歧义源码取四角平均值avg决定分段连接方向以保证整体环的逆时针绕向一致index.ts、index.ts。7.3 组装闭环assembleRingsassembleRingsindex.ts将上一断点的分段prevSegments与当前断点分段reverseSegments拼接当前断点分段来自更高阈值从低带视角看为顺时针因此先reverse再与低带分段合并以维持统一的逆时针顺序。随后将首尾相连的连续分段拼成 contour未闭合的 contour 必然触及矩阵边界沿矩阵四边逆时针寻找相邻 contour 或拐角最终闭合为环过滤掉长度小于 4 的零面积环。7.4 边界情形整带覆盖网格如果某个区间带内没有任何闭合多边形且矩阵原点值恰好落于该区间内matrix[0][0] upperBand matrix[0][0] lowerBand说明整个网格的值都落在该区间此时直接以整个网格边界构造一个外环index.ts。此逻辑对应 issue #1797/#2956 的修复测试用例isobands - flat data, from issue #1797test.ts验证了全等值所有点elevation: 1时仍能输出有效多边形。7.5 坐标重缩放rescaleContoursmarching squares 假定网格点间距为 1 个单位因此结果需要映射回真实地理坐标。rescaleContoursindex.ts完成这一步用turf/bbox计算输入点网格的包围盒[minX, minY, maxX, maxY]得到真实宽度与高度以包围盒左下角为原点除以矩阵格数得到scaleX、scaleY对每个坐标执行x * scaleX x0、y * scaleY y0。这就是为什么即使输入网格不规则间距也能正确还原到地图坐标的原因只要点网格是规则矩形排列包围盒与矩阵格数即可推导出精确缩放。八、错误处理速查表结合源码校验逻辑与 test.ts 的 throws 用例常见报错与触发条件如下报错信息触发条件源码位置options is invalidoptions 不是对象index.tsInput must contain Points输入含非 Point 要素index.tsbreaks is required/breaks is not an Arraybreaks 缺失或非数组index.tscommonProperties is not an ObjectcommonProperties 非对象index.tsbreaksProperties is not an ArraybreaksProperties 非数组index.tsEach mappedProperty is required to be an ObjectbreaksProperties 中某项非对象index.tsMatrix of points must be at least 2x2网格不足 2x2index.tsMatrix of points is not uniform in the x dimension各行点数不一致index.ts九、从矩阵直接生成网格matrixToGrid 与测试输入仓库在 lib/matrix-to-grid.ts 提供了逆向工具matrixToGrid给定二维数值矩阵、左下角原点origin、cellSize单位可用units指定支持 Turf 全部 Units如kilometers、miles借助turf/rhumb-destination逐行逐列生成规则点网格。这正是测试与基准中矩阵输入的用法。仓库测试数据 test/in/matrix1.json 展示了一个可直接运行的输入示例{ matrix: [ [1, 1, 1, 1, 1, 1, 1], [1, 5, 5, 5, 5, 5, 1], [1, 5, 15, 15, 15, 5, 1], [1, 5, 10, 10, 10, 5, 1], [1, 5, 5, 5, 5, 5, 1], [1, 1, 1, 1, 1, 1, 1] ], origin: [10.8, 44.1], cellSize: 20, breaks: [2, 4, 8, 12], zProperty: temperature }配合matrixToGrid(matrix, [10.8, 44.1], 20, { zProperty: temperature })即可得到isobands的标准输入。测试用例isobandstest.ts对test/in/下全部 fixturematrix1、matrix2、bigMatrix、1084、2956、pointGrid逐一执行若输入自带 GeoJSON properties 则直接使用否则先用matrixToGrid转换输出经turf/truncate截断坐标后与test/out/中的期望结果做deepEqual断言并附加包围盒调试线envelope。十、性能与基准bench.ts 基于benchmark对同一组 fixture 做吞吐测试文件头注释记录了作者在本仓库环境的参考运行结果数据仅供参考实际性能取决于机器与输入规模bigMatrix x 73.43 ops/sec ±2.12% (62 runs sampled) matrix1 x 5,205 ops/sec ±3.13% (78 runs sampled) matrix2 x 2,333 ops/sec ±9.38% (71 runs sampled) pointGrid x 3,201 ops/sec ±1.81% (78 runs sampled)可以推断性能主要受网格规模矩阵格数影响bigMatrix这类大矩阵吞吐量显著下降同时 bench.ts 也演示了矩阵输入matrixToGrid转换与GeoJSON 输入两种调用路径的统一处理方式。十一、应用场景与模块协同isobands 常用于以下场景均可直接复用本模块输出高程分层以 DEM 采样点网格 breaks生成地形分层设色面气象/环境插值温度、降水、污染物浓度等连续场量的区间可视化人口/统计密度将聚合到网格点的计数如 test/in/pointGrid.geojson 的people属性转为色阶面与 isolines 叠加turf/isolines输出边界线、turf/isobands输出填充带两者叠加即为完整的等值线图。输入网格可由turf/point-grid、turf/hex-grid等网格工具生成插值可配合turf/interpolate。十二、小结turf/isobands是一条结构清晰的算法流水线规则点网格 → 二维数值矩阵 → marching squares 分段 → 相邻断点闭合环 → 按面积分组嵌套 → 坐标重缩放 → MultiPolygon 要素集合。使用时的三个关键约束是网格必须规则且至少 2x2、breaks必须为升序数值数组、z 属性缺失会按 0 处理。掌握这些约束与源码中的校验逻辑即可在任意 Turf 项目中稳定、高效地生成填充等值面。赞分享数据分析【免费下载链接】turfA modular geospatial engine written in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/tu/turf点击查看免费下载相关推荐Qwen3-Coder 评测集解读DevQualityEval v0.5.0 中 Mistral 7B Instruct v0.3 的代码开发质量报告Qwen3 Coder 评测集解读DevQualityEval v0.5.0 中 Mistral 7B Instruct v0.3 的代码开发质量报告 本文围数据分析Juice 主题实战指南基于 Zola 搭建优雅的产品官网Juice 主题实战指南基于 Zola 搭建优雅的产品官网 Juice 是一个定位为 产品站点product sites 而设计的 Zola 主题主打直数据分析Cilium IPsec 透明加密实战指南基于 Kubernetes Secret 的密钥分发、密钥轮换与 XFRM 排障Cilium IPsec 透明加密实战指南基于 Kubernetes Secret 的密钥分发、密钥轮换与 XFRM 排障 在 Kubernetes 环境中数据分析上一篇Opik Guardrails Backend 实战指南基于 GPU/CPU 双镜像的内容安全校验服务部署与 API 调用下一篇Genkit JS Agent Branching 实战基于不可变快照的分支会话Beta创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。