NetTopologySuite配合NetTopologySuite.IO.ShapeFile是C#中读取Shapefile最稳妥方案,需同时提供.shp、.shx、.dbf三文件,注意编码、坐标顺序(X/Y即经度/纬度)及手动处理坐标系转换。

用 NetTopologySuite 读取 .shp 文件最稳妥
直接手写解析 Shapefile 是不现实的——它由 .shp、.shx、.dbf 三个二进制/混合格式文件组成,且坐标系、几何类型、字段编码(如 GBK/UTF-8)都需手动处理。目前 C# 生态中,NetTopologySuite 配合 NetTopologySuite.IO.ShapeFile 是最成熟、维护活跃的选择,支持读取点/线/面及属性,也兼容常见投影(如 WGS84、Web Mercator)。
安装方式:
dotnet add package NetTopologySuite
dotnet add package NetTopologySuite.IO.ShapeFile
读取时必须同时提供 .shp + .shx + .dbf 三个文件
Shapefile 是“文件集合”,缺一不可:.shp 存几何,.shx 是索引(加速随机访问),.dbf 存属性表。只传 .shp 路径会抛 System.IO.FileNotFoundException 或静默跳过属性。
- 确保三个文件同名同目录,例如:
roads.shp、roads.shx、roads.dbf - 路径传入时只需指定
.shp文件名,库会自动拼出其他两个:new ShapefileDataReader(@"C:\data\roads.shp") - 如果
.dbf编码不是默认 ANSI(如中文环境常用 GBK),需显式指定:new ShapefileDataReader(path, new DbfColumnDescriptor { Encoding = Encoding.GetEncoding("GBK") })
Geometry 类型和坐标顺序容易反
Shapefile 规范中,坐标是 (X, Y) 即 (经度, 纬度),但很多 GIS 工具(包括部分 QGIS 导出)可能误存为 (Y, X)。NetTopologySuite 默认按规范解析,若发现多边形方向错乱、点明显偏移,优先检查原始数据坐标顺序。
- 读出的
Geometry对象,其Coordinate数组第一个是X,第二个是Y;不要直接当成Latitude, Longitude去用 - 用
geometry.Coordinates[0].X取经度,geometry.Coordinates[0].Y取纬度 - 若确认源数据是
(lat, lng)存储,需在读取后批量交换:coord.X ↔ coord.Y
没有内置坐标系转换,WKT/Proj 字符串得自己配
ShapefileDataReader 会尝试从 .prj 文件读 EPSG 或 WKT,但不自动做坐标变换。如果你拿到的是 UTM 坐标或地方坐标系,而需要转 WGS84 经纬度,必须额外引入 ProjNet4GeoAPI 或调用外部 PROJ 库。
常见情况:.prj 内容是 PROJCS["CGCS2000_3_Degree_GK_Zone_35", ...],此时 reader.Projection 会返回 WKT 字符串,但不会自动转点——你得用 ProjNet 构建 CoordinateTransformation 实例再逐点转换。
真正麻烦的不是读取,而是确认原始数据到底用什么坐标系、有没有 .prj、.prj 是否准确——这三个问题比代码本身更常卡住进度。










