当前位置: 首页 > article >正文

C# NetTopologySuite+ProjNet 实现复杂几何图形坐标转换实战

1. 为什么需要坐标转换在地理信息系统GIS开发中我们经常会遇到不同坐标系之间的数据转换问题。比如你拿到一份建筑用地红线图用的是地方坐标系而地图平台要求使用国家2000坐标系这时候就需要进行坐标转换。我去年做智慧城市项目时就遇到过这种情况某区的CAD图纸导入地图平台后全部偏移了300多米就是因为坐标系没统一。传统做法是手动计算转换参数但对于复杂几何图形比如包含几十个拐点的多边形简直是一场噩梦。这时候NetTopologySuite和ProjNet这对黄金组合就派上用场了。前者是.NET平台最强大的空间几何库后者则是专业的坐标转换工具配合使用可以轻松实现点、线、面等任意几何图形的批量转换支持2000种预定义的坐标系EPSG代码转换过程保留所有几何属性关系性能比手动计算快10倍以上2. 环境准备与基础概念2.1 安装必要的NuGet包打开Visual Studio的NuGet包管理器搜索安装这三个关键包Install-Package NetTopologySuite Install-Package ProjNet Install-Package ProjNet.SRID这里有个坑要注意ProjNet.SRID这个包经常被忽略但它包含了全球常用的坐标系定义数据。有次我调试半天转换结果不对最后发现就是漏装了这个包。2.2 理解核心概念坐标系就像地图的语言常见的有地理坐标系如WGS84用经纬度表示位置投影坐标系如CGCS2000将球面投影到平面EPSG代码是坐标系的身份证号比如4490中国国家2000地理坐标系4527北京54坐标系3. 实战多边形坐标转换3.1 定义坐标系先创建转换工厂和坐标系对象// 获取北京54坐标系EPSG:4527 CoordinateSystem beijing54 SRIDReader.GetCSbyID(4527); // 获取国家2000坐标系EPSG:4490 CoordinateSystem cgcs2000 SRIDReader.GetCSbyID(4490); // 创建转换工厂 var ctFactory new CoordinateTransformationFactory(); // 生成转换器 ICoordinateTransformation transformer ctFactory.CreateFromCoordinateSystems(beijing54, cgcs2000);3.2 构建测试多边形用NetTopologySuite创建一个四边形Polygon polygon new Polygon( new LinearRing(new Coordinate[] { new Coordinate(39498340.1151, 4807100.9600), // 点A new Coordinate(39499340.1151, 4809100.9600), // 点B new Coordinate(39497340.1151, 4806100.9600), // 点C new Coordinate(39498340.1151, 4807100.9600) // 闭合点 }));3.3 实现转换过滤器关键是要创建这个过滤器类public class MathTransformFilter : ICoordinateSequenceFilter { private readonly MathTransform _transform; public MathTransformFilter(MathTransform transform) _transform transform; public bool Done false; public bool GeometryChanged true; public void Filter(CoordinateSequence seq, int index) { // 执行坐标转换 var (x, y, z) _transform.Transform( seq.GetX(index), seq.GetY(index), seq.GetZ(index)); seq.SetX(index, x); seq.SetY(index, y); seq.SetZ(index, z); } }3.4 执行转换并输出结果// 转换前坐标 Console.WriteLine(转换前); foreach(var coord in polygon.Coordinates) { Console.WriteLine(${coord.X}, {coord.Y}); } // 执行转换 Geometry result polygon.Copy(); result.Apply(new MathTransformFilter(transformer.MathTransform)); // 转换后坐标 Console.WriteLine(\n转换后); foreach(var coord in result.Coordinates) { Console.WriteLine(${coord.X}, {coord.Y}); }4. 高级应用技巧4.1 批量转换几何集合实际项目中经常要处理GeometryCollectionGeometryCollection geometries LoadFromGeoJSON(); // 从文件加载 foreach(var geom in geometries) { geom.Apply(new MathTransformFilter(transformer.MathTransform)); }4.2 性能优化建议处理大量数据时要注意复用CoordinateTransformationFactory实例对MultiPolygon先合并再转换使用Parallel.ForEach并行处理4.3 常见问题排查坐标偏移异常检查源/目标坐标系定义是否正确确认EPSG代码是否匹配实际数据测试单点转换验证参数内存泄漏Geometry对象使用后及时Dispose避免在循环中重复创建转换器5. 真实项目案例去年为某省自然资源厅开发审批系统时需要将全省120万条用地红线从地方坐标系转换到国家2000坐标系。最初尝试用Python脚本处理转换一条复杂多边形要2秒后来改用本文方案使用Geometry批量读取Shapefile建立转换管道多线程并行处理最终性能提升到每秒处理300多边形整个转换任务在1小时内完成。关键代码片段var options new ParallelOptions { MaxDegreeOfParallelism 8 }; Parallel.ForEach(polygons, options, poly { poly.Apply(new MathTransformFilter(transform)); });这个案例让我深刻体会到好的工具组合正确的架构设计能带来数量级的效率提升。特别是在处理带岛洞的多边形时NetTopologySuite能完美保持几何拓扑关系这是手动算法很难实现的。

相关文章:

C# NetTopologySuite+ProjNet 实现复杂几何图形坐标转换实战

1. 为什么需要坐标转换? 在地理信息系统(GIS)开发中,我们经常会遇到不同坐标系之间的数据转换问题。比如你拿到一份建筑用地红线图,用的是地方坐标系,而地图平台要求使用国家2000坐标系,这时候就…...

别再让机械臂乱动了!详解ROS2中Gazebo与MoveIt2的控制器配置与通信原理

别再让机械臂乱动了!详解ROS2中Gazebo与MoveIt2的控制器配置与通信原理 当你在RViz2中精心规划的轨迹,到了Gazebo仿真中却变成机械臂抽搐乱舞的"迷惑行为"时,问题往往出在控制器配置这个关键环节。本文将带你深入ros2_control框架…...

全网最细!OpenClaw 工具系统深度解析:从原子能力到企业级安全,AI 智能体的“万能手脚“完全指南

一、前言:OpenClaw 工具——AI 智能体从"聊天"到"干活"的核心分水岭 当 AI 大模型(GPT/Claude/Gemini)解决了"思考与理解"的问题后,真正决定智能体价值的,是它能否落地执行、操作现实与…...

ESP32-S3单片机入门:点灯

硬件准备 所需硬件:ESP32-S3开发板、LED、电阻、杜邦线、面包板、USB线(可传输数据) 了解硬件 ESP32-S3开发板 ESP32-S3 技术规格书 | 乐鑫科技文档 LED 电阻 作用:把电能转化为热能或其它形式的能量&#xff0…...

别再死记硬背栈顶指针了!用C语言手把手实现顺序栈(附完整可运行代码)

从零构建C语言顺序栈:破解栈顶指针的终极迷思 初学数据结构时,栈顶指针的初始值设定总是让人困惑——为什么有的教材用top -1,有的却用top 0?这看似简单的数字差异,背后却隐藏着对栈本质理解的深刻分歧。本文将用300…...

YOLOv8模型部署避坑指南:从.pt到ONNX转换,这些细节决定了推理速度与精度

YOLOv8模型部署性能优化实战:从ONNX转换到推理加速的深度调优 在计算机视觉领域,YOLOv8凭借其出色的实时检测性能已经成为工业界的热门选择。但许多开发者发现,即使训练出了高精度的.pt模型,在实际部署为ONNX格式后,推…...

数据链路层核心技术:封装成帧与透明传输的实战解析

1. 数据链路层功能概述 数据链路层是计算机网络体系结构中承上启下的关键层级。想象一下,如果把网络通信比作寄快递,物理层负责的是"把包裹从一个站点运到另一个站点"这个基础动作,而数据链路层则是确保"包裹完整无误地送达&q…...

图图的嗨丝造相-Z-Image-Turbo部署案例:高校数字艺术课程AI绘图实验平台搭建实践

图图的嗨丝造相-Z-Image-Turbo部署案例:高校数字艺术课程AI绘图实验平台搭建实践 1. 引言:当AI绘图走进艺术课堂 想象一下,在高校的数字艺术设计课上,学生们不再仅仅学习传统的Photoshop或手绘板技巧。他们打开浏览器&#xff0…...

vivado hls中对设计进行最优化

一、vivado hls优化本质 vivado hls设计优化,是利用指令对c/c串行代码进行并行化优化。 这个优化是通过directives指令来指导HLS综合工具来实现的,至于底层怎么优化,设计者是没办法知道和窥探的。二、vivado hls优化策略的核心指标 1.through…...

艾默生15kW直流充电模块DCDC控制软件分析

系统概述 艾默生15kW直流充电模块是一款高性能的电力转换设备,采用DSP2803x系列数字信号处理器作为核心控制器。该软件系统实现了对直流-直流(DCDC)转换器的精确控制,具备完善的保护机制和通信功能。 核心架构设计 1. 控制系统…...

vivado hls的ap_ctrl_none的使用

一、说明 1.ap_ctrl_none:最精简的模式,不产生任何握手信号,模块依靠数据有效信号持续工作 2.ap_ctrl_none也就是free-run模式,永动机模式 3.ap_ctrl_none的应用高度依赖于#pragma HLS dataflow指令,目的是在数据流区域…...

三相PFC控制固件代码功能解析

概述 本文档详细分析了一个用于三相功率因数校正(PFC)控制系统的嵌入式固件代码。该代码基于特定的处理器架构,实现了复杂的电力电子控制算法,主要用于车载充电系统等高性能电源应用场景。 系统架构 硬件抽象层 代码通过硬件抽象层…...

Attify OS 1.3:一站式IoT安全评估虚拟环境的搭建与核心工具实战

1. Attify OS 1.3:物联网安全测试的瑞士军刀 第一次接触物联网设备安全测试时,我被各种工具链的配置折磨得够呛。直到发现Attify OS这个神器,才明白原来环境搭建可以这么简单。Attify OS 1.3是专为物联网安全评估设计的Linux发行版&#xff0…...

K8s 工具安装文档 — Harbor + ArgoCD

环境信息 项目详情主机 IP8.147.67.244(内网 172.16.78.0)操作系统Rocky Linux 9.7 (Blue Onyx)内核5.14.0-611.36.1.el9_7.x86_64Kubernetesv1.35.0容器运行时containerd 2.2.2CNICalico v3.29.1内存14Gi磁盘50G (已用 ~6.5G)节点单节点 (k8s-master, …...

三合一跨平台音乐播放器:VutronMusic 完整使用指南

三合一跨平台音乐播放器:VutronMusic 完整使用指南 【免费下载链接】VutronMusic 高颜值的第三方网易云播放器;支持流媒体音乐,如navidrome、jellyfin、emby;支持本地音乐播放、离线歌单、逐字歌词、桌面歌词、Touch Bar歌词、Mac…...

WixSharp实战:从零构建MSI安装包的完整指南

1. WixSharp简介与环境准备 第一次接触软件打包时,我被各种XML配置搞得头大,直到发现了WixSharp这个神器。简单来说,WixSharp允许你用熟悉的C#代码来生成MSI安装包,完全避开了传统WiX工具需要手动编写XML的繁琐流程。就像用高级语…...

MathLive CSS路径重构指南:从dist到根目录的平滑迁移方案

MathLive CSS路径重构指南:从dist到根目录的平滑迁移方案 【免费下载链接】mathlive Web components for math display and input 项目地址: https://gitcode.com/gh_mirrors/ma/mathlive 还在为升级MathLive后页面样式突然失效而烦恼吗?自从Math…...

实时体积云渲染进阶:Perlin与Worley噪声的混合艺术

1. 理解体积云渲染的基础噪声 在实时体积云渲染中,噪声算法扮演着关键角色。就像画家需要不同的笔触来表现云层的质感,我们需要Perlin和Worley这两种基础噪声来构建云的形态。这两种噪声各有特点,理解它们的差异是混合使用的前提。 Perlin噪声…...

PLECS C-Script实战:手把手教你用代码生成三相SVPWM调制波(附完整代码)

PLECS C-Script实战:手把手教你用代码生成三相SVPWM调制波(附完整代码) 在电力电子领域,空间矢量脉宽调制(SVPWM)技术因其优异的电压利用率和平滑的输出波形,已成为三相逆变器控制的核心算法。但…...

GitHub进阶玩法全解析,零基础可快速上手进阶高手,轻松解决各类常见难题下(补充版)

9. GitHub Pages与Webhooks:扩展你的能力边界9.1 GitHub Pages不只是静态网站是的,大家都知道它能托管静态网站。但高级用法包括:自定义域名和HTTPS:完全免费,在仓库设置里绑定自己的域名就行,GitHub会自动…...

Swift-All全流程体验:快速上手文本生成与多模态模型

Swift-All全流程体验:快速上手文本生成与多模态模型 1. 认识Swift-All:一站式大模型工具箱 1.1 什么是Swift-All? Swift-All是魔搭社区推出的大模型与多模态模型全流程开发框架。它最大的特点是支持600文本大模型和300多模态模型的训练、推…...

告别Keil单调调试:用Ozone + J-Link可视化你的FreeRTOS任务状态(附工程配置避坑点)

告别Keil单调调试:用Ozone J-Link可视化你的FreeRTOS任务状态(附工程配置避坑点) 嵌入式开发中,调试环节往往占据大量时间成本。当项目复杂度上升到RTOS层面时,传统的Keil调试界面显得力不从心——开发者需要反复切换…...

告别目标检测框!用ALBEF和ViT-BERT轻松搞定多模态图文匹配(附代码实战)

无需目标检测框的跨模态革命:ALBEF实战图文匹配新范式 当我在去年尝试构建一个电商图文检索系统时,最头疼的不是模型调参,而是处理那些密密麻麻的目标检测框标注——每个商品都要精确标注位置和属性,团队为此投入了三周时间却只完…...

COMSOL增材制造多层多道模拟:附赠价值2k+学习资源及模型视频

comsol增材制造多层多道模拟,同时附赠价值2k以前学习 的 模型和一些视频增材制造的热应力变形和层间熔合质量是工程师的噩梦。去年调试某航天零件3D打印工艺时,我连续烧了三个钛合金基板才意识到传统试错法已经过时——直到在COMSOL里重构了整个多层沉积…...

斯坦福CS146S十周课程:从LLM基础到Multi-Agent

2025 年秋季,斯坦福计算机系出现了一门排课火爆的新课 —— CS146S: The Modern Software Developer(现代软件开发者)。这门课由 Mihail Eric 主讲,他是斯坦福校友,曾在 Amazon Alexa 担任技术主管,创办过 …...

一款即插即用的西门子PLC测试工具,全面支持S7200、SMART 1200、1500、300...

西门子PLC测试工具,支持S7200,SMART 1200 1500 300等各种PLC,到手即用,。搞自动化的小伙伴们有没有遇到过PLC调试效率低的问题?今天要安利的这个西门子全家桶测试工具,简直就是程序员的物理外挂。从老掉牙的…...

吐血整理:零基础学深度学习需要学哪些框架?PyTorch 和 TensorFlow 选哪个?

吐血整理:零基础学深度学习需要学哪些框架?PyTorch 和 TensorFlow 选哪个? 标签:#深度学习、#pytorch、#tensorflow、#计算机视觉、#人工智能、#python、#机器学习### 一、深度学习入门必学框架有哪些?分别用来做什么&…...

NarratoAI:视频解说自动化难题的智能化破解方案

NarratoAI:视频解说自动化难题的智能化破解方案 【免费下载链接】NarratoAI 利用AI大模型,一键解说并剪辑视频; Using AI models to automatically provide commentary and edit videos with a single click. 项目地址: https://gitcode.co…...

OpCore-Simplify:黑苹果配置的革命性自动化工具,让复杂变简单

OpCore-Simplify:黑苹果配置的革命性自动化工具,让复杂变简单 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为繁琐的Ope…...

豆包、元宝、difyapi返回的数据,vue上解析显示,保留原有的样式

这个问题本质上是:第三方 LLM API(豆包 / 元宝 / Dify)返回的 Markdown / 结构化文本,如何在 Vue 中正确解析并尽量保留原始样式。下面我用「通用思路 Vue3 实战代码」一步步说明。一、先搞清楚:它们返回的是什么&…...