@turf/line-to-polygon 完全指南:将 LineString / MultiLineString 转换为 Polygon 的实现原理与实战用法
数据分析【免费下载链接】turfA modular geospatial engine written in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/tu/turf点击查看免费下载turf/line-to-polygon是 Turf 模块化地理引擎中的核心转换模块负责将 (Multi)LineString 线要素转换为 Polygon 面要素是处理海岸线闭合、地块边界成面、线状要素栅格化前的必备工具。读完本文你将掌握该函数的全部参数语义autoComplete / orderCoords / mutate、三种输入形态Feature / FeatureCollection / 裸 Geometry的差异、环排序与自动闭合的底层算法以及如何用测试夹具验证转换结果。模块概览一行代码完成线到面的转换GeoJSON 规范中Polygon 的第一环是外环、其余环是内环孔洞且每个环必须是闭合的首尾坐标相同。但真实数据中的线要素往往是不闭合的、或者孔洞线与外轮廓线混在同一个 MultiLineString 中。lineToPolygon正是为了解决这些现实问题而生var line turf.lineString([[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]); var polygon turf.lineToPolygon(line);它支持三种输入形态见 index.ts 的类型签名输入形态TypeScript 类型输出单个 LineStringFeatureLineString \| LineString裸几何FeaturePolygon单个 MultiLineStringFeatureMultiLineString \| MultiLineStringFeaturePolygon多条线构成外环内环要素集合FeatureCollectionLineString \| MultiLineStringFeatureMultiPolygon每条线各成一个面输出始终是FeaturePolygon | MultiPolygon与 README.md 中描述的签名完全一致。参数详解四个选项决定转换结果函数签名为lineToPolygon(lines, options)options默认值为{}包含四个可选项。源码在 index.ts 中使用空值合并运算符处理默认值var properties options.properties; var autoComplete options.autoComplete ?? true; var orderCoords options.orderCoords ?? true; var mutate options.mutate ?? false;参数类型默认值作用linesFeatureCollection \| FeatureLineString \| MultiLineString必填待转换的线要素也接受裸 Geometry见 geometry-linestring.geojson 测试夹具options.propertiesObject{}显式指定输出 Feature 的 properties未传时继承输入 Feature 自身的 properties裸几何则得到{}options.autoCompletebooleantrue自动闭合线环当首尾坐标不一致时把首坐标追加到末尾GeoJSON Polygon 环必须是闭合的options.orderCoordsbooleantrue对 MultiLineString 的各条线按面积排序使外环面积最大者位于坐标数组第一位符合 GeoJSON 外环在前的规范options.mutatebooleanfalse是否直接修改输入数据。false时内部先clone一份保证原输入不被改动关键行为一properties 的继承优先级源码 index.ts 展示了一个三档回退逻辑properties properties ? properties : line.type Feature ? line.properties : {};即显式传入的options.properties优先级最高未传入且输入是 Feature 时继承该 Feature 的properties输入是裸 Geometry 时得到空对象。关键行为二mutate 与原数据保护当mutate为false默认时函数会先对输入执行clone(lines)来自turf/clone任何闭合、排序操作都发生在副本上。这意味着即使autoComplete往坐标数组 push 了新坐标也不会污染调用方的原始数据——测试 test.ts 中专门断言了t.deepEqual(originalInput, geojson)来验证输入未被修改。核心算法三条线如何变成一个面转换逻辑的核心是私有函数lineStringToPolygonindex.ts其流程为校验坐标通过turf/invariant的getGeom取出几何体若coords为空抛出line must contain coordinates。按类型分派LineString若开启autoComplete调用autoCompleteCoords闭合环然后包装成单环 PolygonMultiLineString逐条线处理配合orderCoords排序后打包成多环 Polygon第一个环为外环其余为内环其他类型抛出geometry type X is not supported测试 test.ts 用 Point 输入验证了该错误。FeatureCollection 分支入口函数中遍历每条线各自转成 Polygon 后收集其坐标最终组装为一个 MultiPolygon。autoCompleteCoords首尾坐标的自动缝合实现位于 index.tsfunction autoCompleteCoords(coords: Position[]) { var first coords[0]; var x1 first[0]; var y1 first[1]; var last coords[coords.length - 1]; var x2 last[0]; var y2 last[1]; if (x1 ! x2 || y1 ! y2) { coords.push(first); } return coords; }它比较首、尾坐标的 x/y 是否完全相等不相等就把首坐标追加到末尾从而形成闭合环。测试夹具 linestring-incomplete.geojson 提供了一条 8 个点、首尾不重合的开放线正是用于验证该逻辑。注意闭合判断是严格的坐标相等比较不涉及容差或投影计算。orderCoords按包围盒面积把外环排到第一位GeoJSON 规范要求 Polygon 坐标数组的第一个环必须是外环。当 MultiLineString 的各条线在输入中乱序排列时orderCoords负责重排。排序依据是各线的包围盒面积index.tsif (orderCoords) { var area calculateArea(turfBBox(lineString(coord))); if (area largestArea) { multiCoords.unshift(coord); largestArea area; } else multiCoords.push(coord); }辅助函数calculateAreaindex.ts用包围盒的跨度估算面积return Math.abs(west - east) * Math.abs(south - north);这里通过turf/bbox计算每条线的包围盒再取东西跨度 × 南北跨度作为面积排序键。面积最大的线被unshift到数组头部外环其余依次追加内环。需要说明的是这只是快速近似排序源码注释称之为 quick approximate area calculation (used to sort)并不做精确的地理面积计算——对于正常的外环包含内环场景已足够。测试夹具 multi-linestring-outer-ring-middle-position.geojson 专门构造了外环不在首位的输入用于验证重排逻辑multi-linestring-with-hole.geojson 则展示了一个外环 一个内环孔洞的标准甜甜圈结构内环坐标[100.2, 0.2] → [100.8, 0.8]明显小于外环会被正确排到外环之后。实战示例从零开始构建你的转换流程示例一闭合的单线README 原始示例import { lineString, lineToPolygon } from turf/turf; var line turf.lineString([[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]); var polygon turf.lineToPolygon(line); // polygon.geometry.type Polygon // polygon.geometry.coordinates[0] 即外环由于示例输入首尾坐标相同[125, -30]出现两次autoComplete检测到已闭合不会重复追加。示例二开放线自动闭合var openLine turf.lineString([ [131.0, -30.9], [125.4, -29.8], [121.7, -26.0], [121.5, -21.9], [127.7, -16.1], ]); var polygon turf.lineToPolygon(openLine); // autoCompletetrue默认时自动补上首坐标环闭合数据形态同 linestring-incomplete.geojson。如果你明确不想要闭合行为例如只想保留原始线段数可传入{ autoComplete: false }——测试 test.ts 验证了该选项下函数依然能正常返回结果。示例三FeatureCollection → MultiPolygonvar collection turf.featureCollection([ turf.lineString([[102, 2], [103, 2], [103, 3], [102, 3], [102, 2]]), turf.lineString([[100, 0], [101, 0], [101, 1], [100, 1], [100, 0]]), ]); var multiPolygon turf.lineToPolygon(collection); // 输出 FeatureMultiPolygon两条线各自成为一个 Polygon测试夹具 collection-linestring.geojson 与 linestrings-to-multipolygons.geojson 对应的正是这一形态。示例四外环 孔洞MultiLineString 甜甜圈var doughnut turf.multiLineString([ // 外环 [[100, 0], [101, 0], [101, 1], [100, 1], [100, 0]], // 内环孔洞 [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]], ]); var polygon turf.lineToPolygon(doughnut); // coordinates[0] 外环coordinates[1] 内环孔洞数据形态同 multi-linestring-with-hole.geojson。更复杂的多孔洞场景见 multi-linestrings-with-holes.geojson 与 multi-linestrings-outer-doughnut.geojson。注意嵌套孔洞等复杂拓扑如 multi-linestring-nested.geojson 系列建议配合turf/unkink-polygon等工具做后续拓扑清理。安装与使用方式按 README.md 的说明有两种安装途径# 方式一仅安装本模块 $ npm install turf/line-to-polygon # 方式二安装 Turf 全家桶包含全部模块 $ npm install turf/turf本仓库基于 pnpm workspace 管理模块自身以 ESM 发布type: module见 package.json运行时要求node 22。它的运行时依赖是四个工作区模块turf/bbox包围盒计算、turf/clone数据克隆、turf/helperspolygon / multiPolygon / lineString 构造器、turf/invariant几何与坐标提取。如果你想在完整 Turf 项目中运行本模块测试可在仓库根目录执行pnpm --filter turf/line-to-polygon test源码结构、测试与性能验证源码组织本模块仅由一个入口文件构成index.ts包含导出函数lineToPolygon同时作为 default 导出兼容两种 import 风格私有辅助函数lineStringToPolygon、autoCompleteCoords、calculateArea。文档注释JSDoc直接写在源码中README 由documentation.js从注释自动生成因此源码注释与 README 始终同步。测试覆盖测试文件 test.ts 基于 tape 编写覆盖了 13 个输入夹具位于 test/in并通过process.env.REGEN支持一键重新生成期望输出out目录。测试断言除了结果深度相等外还额外校验输入未被 mutate。错误路径覆盖传入 Point → 抛出geometry type Point is not supported传入空坐标的 LineString → 抛出line must contain coordinates。类型安全由 types.ts 配合tsc --strict校验见 package.json 的test:types脚本。性能参考bench.ts 使用 benchmark 套件对全部夹具进行压测文件注释中记录了仓库维护时的历史数据例如单条闭合线约 6,752,969 ops/sec、带孔洞的 MultiLineString 约 1,018,657 ops/sec、多孔洞嵌套场景约 421,758 ops/sec。这些数值属于历史基准快照实际性能会随机器与 Node 版本浮动但它们可以说明得益于纯函数式设计与轻量依赖本模块在批量转换场景下开销很低可以作为数据流水线中的高频基础操作。常见问题与边界提醒输入会被修改吗默认mutate: false输入会被克隆绝对安全仅当你确认可以接受原数据被修改时才开启mutate以省去克隆开销。不闭合的线会怎样默认autoComplete: true会自动补上首坐标完成闭合关闭后输出的 Polygon 环可能不闭合需自行确保下游消费方接受GeoJSON 严格校验器会拒绝。环的顺序重要吗默认orderCoords: true按包围盒面积排序保证外环在第一位关闭后环序保持输入原样若外环不在首位部分 GIS 渲染与拓扑工具可能将其误判为内环。FeatureCollection 输出什么永远是MultiPolygon即使集合中只有一条线若你需要的是单个 Polygon请直接传 Feature 而非 FeatureCollection。孔洞判断依据是什么不是包含关系检测而是纯粹的面积最大者为外环近似排序极端情况下多条互不相交的大线会被排成外环 内环语义转换前应确认数据的拓扑预期。延伸阅读模块入口与核心实现index.ts官方 API 文档与源码 JSDoc 同步README.md测试套件与夹具目录test.ts、test/in性能压测脚本bench.ts依赖的底层模块packages/turf-bbox、packages/turf-clone、packages/turf-helpers、packages/turf-invariant聚合入口如需直接使用turf.lineToPolygonpackages/turf赞分享数据分析【免费下载链接】turfA modular geospatial engine written in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/tu/turf点击查看免费下载相关推荐arduino-esp32 OpenThread 实战CoAP SimpleGet 客户端——仅凭 Network Key 入网并向 Leader RLOC 发起确认式 GETarduino esp32 OpenThread 实战CoAP SimpleGet 客户端——仅凭 Network Key 入网并向 Leader RLOC数据分析PyArrow 读写 Parquet 文件时如何只读取部分列并控制写入选项PyArrow 读写 Parquet 文件时如何只读取部分列并控制写入选项 用 PyArrow 处理 Parquet 文件时一个常见需求是文件里有几十列但数据分析turf/line-chunk 源码解析用 Turf.js 按指定长度切分 LineString 的完整实战指南turf/line chunk 源码解析用 Turf.js 按指定长度切分 LineString 的完整实战指南 导读 turf/line chunk 是数据分析上一篇WarcraftHelper经典游戏的现代系统适配与兼容性工具下一篇Hermes WebUI终极指南如何简单快速搭建你的本地AI助手创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

用 Hypothesis 将测试写成完整规格:以二分查找的属性测试实战为例

用 Hypothesis 将测试写成完整规格:以二分查找的属性测试实战为例

测试开发工具 【免费下载链接】hypothesis The property-based testing library for Python 项目地址: https://gitcode.com/gh_mirrors/hy/hypothesis 点击查看 免费下载 导读 当一个问题被少数几条简单属性完全规定时,它的实现可能依然极其繁琐&…

2026/9/25 6:09:51 阅读更多 →
Learn-Algorithms 海量数据处理实战:分布处理之 MapReduce 原理与 Hadoop 生态

Learn-Algorithms 海量数据处理实战:分布处理之 MapReduce 原理与 Hadoop 生态

教程 【免费下载链接】Learn-Algorithms 算法学习笔记 项目地址: https://gitcode.com/gh_mirrors/le/Learn-Algorithms 点击查看 免费下载 MapReduce 是 Google 提出的并行计算软件架构,专门面向超过 1TB 量级的大规模数据集;它的核心思想—…

2026/9/25 6:09:51 阅读更多 →
OpenCore Legacy Patcher 完整教程:如何给 2007-2017 老 Mac 安装 Sonoma 与 Sequoia

OpenCore Legacy Patcher 完整教程:如何给 2007-2017 老 Mac 安装 Sonoma 与 Sequoia

OpenCore Legacy Patcher 完整教程:如何给 2007-2017 老 Mac 安装 Sonoma 与 Sequoia 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 上周清理旧笔…

2026/9/25 6:09:51 阅读更多 →

最新新闻

CTF入门实战复盘:从图片隐写到栈溢出的解题思路

CTF入门实战复盘:从图片隐写到栈溢出的解题思路

SUSCTF 2018那场比赛的周末,我是从一道Misc题开始的。当时刚入CTF圈不久,最大的感受是:题目不会按你“擅长”的来,但如果你能把每道题的思路记录下来,后面进步会很快。这篇做题记录不是完整题解,更像是我个…

2026/9/25 6:43:14 阅读更多 →
AI API接口安全实战:成本控制、限流与密钥管理落地指南

AI API接口安全实战:成本控制、限流与密钥管理落地指南

1. 为什么2026年还要重提AI API接口安全这两年跟不少做AI应用的朋友聊,发现一个挺普遍的现象:模型能力越强,大家越容易把注意力全放在效果调优上,接口安全反而成了“上线前随便加个key”的附属品。但真跑起来之后,账单…

2026/9/25 6:43:14 阅读更多 →
CVE-2024-7262本质是进程接管漏洞而非路径穿越

CVE-2024-7262本质是进程接管漏洞而非路径穿越

1. 漏洞本质:不是“文件读取”,而是“进程接管”的失控链很多人看到CVE-2024-7262的第一反应是:“哦,又一个路径穿越漏洞”。这种理解偏差,直接导致复现失败、防护失效,甚至在真实攻防对抗中误判风险等级。…

2026/9/25 6:43:14 阅读更多 →
CTF MISC签到题复盘:从文件识别到LSB隐写的完整解题链

CTF MISC签到题复盘:从文件识别到LSB隐写的完整解题链

1. 初见题目:从签到题里嗅到的MISC气息1.1 为什么MISC常以签到题出现每次CTF比赛开始,签到题总是最让人又爱又恨的一类。爱的是它送分,恨的是如果连签到题都卡住,心态会直接崩掉。MISC方向尤其喜欢出现在签到题里,因为…

2026/9/25 6:43:14 阅读更多 →
OWASP ZAP 实战指南:从环境搭建到主动扫描的完整流程

OWASP ZAP 实战指南:从环境搭建到主动扫描的完整流程

前几天一个做后端的朋友跟我抱怨,说他们系统上线前被安全测试搅得焦头烂额,排查半天才发现是登录接口没做频控、文件上传路径没校验。我直接问他:有没有先用 OWASP ZAP 扫过一遍?他愣了一下,说听过这个名字&#xff0c…

2026/9/25 6:43:14 阅读更多 →
Nginx 403错误排查全攻略:从权限到SELinux的根因分析

Nginx 403错误排查全攻略:从权限到SELinux的根因分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 6:42:13 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →