用 GeoJSON.Net
读取 .geojson 文件时,为什么 Geometry
总是 null
?
因为 GeoJSON 规范要求顶层必须是
FeatureCollection、
Feature或几何对象之一,而
GeoJSON.Net的
Geometry.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]的类型会跳过或转成空对象。 安全写法:把所有值先转成基础类型(
string、
int、
double、
bool)或
JToken,再塞进
Properties避免直接塞
new { Name = "杭州", Code = 3301 } —— 匿名类型在序列化时可能被忽略
若必须存复杂结构,手动用 JObject.FromObject(...)转一次再赋值给
Properties["meta"]
在 WinForms/WPF 中显示 GeoJSON 点线面,为什么 MapControl
加载后啥也不画?
绝大多数 .NET 地图控件(如
DotSpatial、
ThinkGeo或
Microsoft.Maps封装)不原生支持 GeoJSON 字符串,需要先转换为对应 SDK 的几何类型(如
DotSpatial.Topology.Geometry或
Microsoft.Maps.MapControl.WPF.LocationCollection)。 点(
Point)→ 提取
Coordinates数组,转成
Location或
Coordinate线(
LineString)→ 把
Coordinates每项转
Location,再构造成
LocationCollection或
LineString面(
Polygon)→ 注意外环和内环顺序,
DotSpatial要求外环逆时针、内环顺时针,否则渲染为空 别忘了坐标系:GeoJSON 默认是 WGS84(EPSG:4326),若地图底图用 Web Mercator(EPSG:3857),得做投影转换,否则位置严重偏移
用 System.Text.Json
替换 Newtonsoft.Json
后,GeoJSON.Net
序列化失败
GeoJSON.Net目前(v1.0.35)仍强依赖
Newtonsoft.Json,其
IGeometry和
IFeature接口的序列化逻辑写死在
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 更现代,但需手动映射
Feature到
IGeometry) GeoJSON 的坐标顺序(经度在前)、
FeatureCollection必须有
Features数组、以及 WGS84 坐标系假设,这三点在调试时最容易被当成“数据有问题”而反复折腾。
