讲师中心 微信公众号
AI工具推荐 视频效率加速

C# 操作OSM地图文件 C#如何读取和处理OpenStreetMap的XML或PBF数据

老雪吖_6983

老雪吖_6983

发布时间:2026-02-25 08:03:10

|

617人浏览过

|

来源于php中文网

原创

OsmSharp是C#中唯一成熟支持PBF流式解析的库,推荐用OsmStreamSource+OsmStreamTarget流式处理、启用includeTags:true、WGS84坐标单位为度;XML解析需跳过无关节点防OOM;过滤应在流式读取时完成,地理裁剪PBF用WithBoundingBox(),写入用OsmStreamTarget确保格式合规。

c# 操作osm地图文件 c#如何读取和处理openstreetmap的xml或pbf数据

用 OsmSharp 读取 PBF 文件最省事

OSM 原始数据分 XML(.osm)和二进制 PBF(.osm.pbf)两种,PBF 是主流发布格式,体积小、解析快。C# 生态里,OsmSharp 是目前唯一成熟支持 PBF 流式解析的开源库,别折腾 XmlReader 手撕大 XML —— 内存爆、速度慢、节点嵌套深容易栈溢出。

实操建议:

  • 用 NuGet 安装 OsmSharp(注意选官方包 OsmSharp,不是旧版 OsmSharp.Core)
  • 优先走流式处理:OsmStreamSource + OsmStreamTarget,避免全量加载到内存
  • PBF 解析默认不带标签(tags),需显式启用:构造 PbfStreamSource 时传 includeTags: true
  • 坐标是 WGS84 经纬度(double),单位是度,不是米 —— 别直接拿去算距离

XmlReader 解析 .osm 文件要防内存炸

小范围数据(比如一个街区导出的 .osm)可用 XmlReader 手动遍历,但必须跳过无关节点、边、关系里的完整子树,否则极易 OOM。XML 没压缩,10MB 的 .osm 可能撑爆几百 MB 内存。

常见错误现象:

  • 用 XDocument.Load() 直接加载 —— 瞬间卡死或 OutOfMemoryException
  • 在 StartElement 里无条件读取所有 node 子元素(如 Tag),导致深度递归
  • 把全部 way 的 nd 节点 ID 缓存成 List<long></long> 再查 —— 实际应边读边建索引

正确做法:

C#
C#

"避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

下载
  • 只监听 node、way、relation 三级开始标签,其余用 ReadToNextSibling() 跳过
  • 每个 node 提取 id、lat、lon 和必要 tag 后立即处理,不缓存整棵树
  • 若需拓扑(如路网连通性),用 Dictionary<long node></long> 按需查,但限制缓存大小(比如只存最近 10 万节点)

过滤和投影:别在解析后才想“我要某城市道路”

OSM 数据全球一份,原始文件含所有类型要素。等全量解析完再 .Where(x => x.Tags.ContainsKey("highway")),既浪费 CPU 又拖慢 IO —— 特别是 PBF,解压+解析本就耗时。

性能关键点:

  • 用 OsmSharp 的 Filter 功能,在流式读取时就丢弃不需要的元素:new OsmStreamFilter().Add(new TagFilter(true, "highway", null))
  • 地理范围裁剪必须在解析前做:PBF 支持按 bbox 预过滤(需用 OsmSharp 的 PbfStreamSource.WithBoundingBox()),XML 则只能靠外部工具(如 osmium extract)先切片
  • WGS84 坐标转 Web Mercator(EPSG:3857)用 Math.Log(Math.Tan(...)) 公式即可,别调用重型 GIS 库;但注意极地附近会发散,实际只用于可视化时再转

写入 OSM 数据:别手动拼 XML 字符串

生成 .osm 文件或上传数据时,手写 XML 容易漏转义(比如 tag value="a & b" 不转义会解析失败)、属性顺序错乱、缺少命名空间声明,导致 OSM 编辑器拒绝导入。

可靠方案:

  • 用 OsmSharp 的 OsmStreamTarget 系列(如 OsmXmlStreamTarget)生成标准格式,它自动处理命名空间、转义、缩进
  • 写 PBF 必须用 OsmPbfStreamTarget,且输入数据需严格按 OSM 模型结构(Node、Way、Relation 分开送入)
  • 时间戳字段(timestamp)必须是 ISO 8601 格式("2024-05-20T12:00:00Z"),不能用本地时区字符串,否则 OSM API 拒绝接收

真正麻烦的是关系(Relation)里的成员角色(role)和循环引用 —— 比如一个行政区划包含多个 way,而这些 way 又被其他 relation 引用。解析时得自己维护 ID 映射表,写入时更要确保成员先于关系出现。这点很容易被忽略,一跑就报 “member not found” 错误。

热门AI工具

更多
超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

4844

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

6277

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

2542

2024.11.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1838

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2924

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6224

2023.10.24

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn