C# GeoJSON文件读写 C#如何处理和可视化地理空间JSON数据

5次阅读

geometry 总是 NULL 是因为 geojson.net 的 geometry.load 只解析纯几何对象,不支持顶层为 featurecollection 的完整文件;应改用 featurecollection.load 后遍历 features 获取 geometry。

C# GeoJSON文件读写 C#如何处理和可视化地理空间JSON数据

Geojson.Net 读取 .geojson 文件时,为什么 Geometry 总是 null

因为 GeoJSON 规范要求顶层必须是 FeatureCollectionFeature 或几何对象之一,而 GeoJSON.NetGeometry.Load 只认纯几何(如 { "type": "Point", ... }),不处理带 features 数组的完整文件。

  • 正确做法:用 FeatureCollection.Load 读整个文件,再遍历 Features 获取每个 Feature.Geometry
  • 常见错误:直接对完整 GeoJSON 文件调用 Geometry.Load → 抛出 JsonReaderException 或返回 null
  • 注意字段名大小写:FeatureCollection 的属性是 Features(首字母大写),不是 features;若原始 JSON 是小写,需配合 JsonSerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() }

写入 GeoJSON 时,Feature.Properties 里的中文或嵌套对象丢失怎么办?

GeoJSON.Net 默认用 Newtonsoft.Json 序列化 Properties,但它的 IDictionary<String Object></string>泛型支持弱,遇到 DateTime、自定义类或未标记 [JsonObject] 的类型会跳过或转成空对象。

  • 安全写法:把所有值先转成基础类型(stringintdoublebool)或 JToken,再塞进 Properties
  • 避免直接塞 new { Name = "杭州", Code = 3301 } —— 匿名类型在序列化时可能被忽略
  • 若必须存复杂结构,手动用 JObject.FromObject(...) 转一次再赋值给 Properties["meta"]

在 WinForms/wpf 中显示 GeoJSON 点线面,为什么 MapControl 加载后啥也不画?

绝大多数 .NET 地图控件(如 DotSpatialThinkGeomicrosoft.Maps 封装)不原生支持 GeoJSON 字符串,需要先转换为对应 SDK 的几何类型(如 DotSpatial.Topology.GeometryMicrosoft.Maps.MapControl.WPF.locationCollection)。

  • 点(Point)→ 提取 Coordinates 数组,转成 LocationCoordinate
  • 线(LineString)→ 把 Coordinates 每项转 Location,再构造成 LocationCollectionLineString
  • 面(Polygon)→ 注意外环和内环顺序,DotSpatial 要求外环逆时针、内环顺时针,否则渲染为空
  • 别忘了坐标系:GeoJSON 默认是 WGS84(EPSG:4326),若地图底图用 Web Mercator(EPSG:3857),得做投影转换,否则位置严重偏移

System.Text.Json 替换 Newtonsoft.Json 后,GeoJSON.Net 序列化失败

GeoJSON.Net 目前(v1.0.35)仍强依赖 Newtonsoft.Json,其 IGeometryIFeature 接口的序列化逻辑写死在 JsonConverter 里,System.Text.Json 无法识别这些自定义转换器。

  • 硬切不可行:哪怕你用 JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()),也无法覆盖 Geometry 类型的序列化行为
  • 折中方案:保留 Newtonsoft.Json 专用于 GeoJSON 部分,其他业务逻辑用 System.Text.Json,二者共存无冲突
  • 如果项目已禁用 Newtonsoft.Json,只能改用 NetTopologySuite.IO.GeoJSON(它支持 System.Text.Json 且 API 更现代,但需手动映射 FeatureIGeometry

GeoJSON 的坐标顺序(经度在前)、FeatureCollection 必须有 Features 数组、以及 WGS84 坐标系假设,这三点在调试时最容易被当成“数据有问题”而反复折腾。

text=ZqhQzanResources