使用NetTopologySuite.IO.Esri从WKT创建Shapefile失败求助
问题
尝试使用NetTopologySuite.IO.Esri从WKT创建Shapefile时,抛出以下错误:
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'NetTopologySuite.Geometries.Polygon' to type 'NetTopologySuite.Geometries.MultiPolygon'.
at NetTopologySuite.IO.Esri.Shapefiles.Writers.ShapefileWriter1.Write(IFeature feature) at NetTopologySuite.IO.Esri.Shapefiles.Writers.ShapefileWriter.Write(IEnumerable1 features)
at NetTopologySuite.IO.Esri.Shapefile.WriteAllFeatures(IEnumerable`1 features, String shpPath, Encoding encoding, String projection)
调试追踪代码后发现,在Shapefile.cs第185行,代码通过var shapeType = features.FindNonEmptyGeometry().GetShapeType();获取几何类型,当前场景中该代码始终返回**PolygonZM**。
已尝试搜索NetTopologySuite create shp,但未找到针对NetTopologySuite.IO.Esri的解决方案;仅找到使用NetTopologySuite.IO.Shapefile创建Shapefile的方法,但该库已停止更新。
以下是测试代码:
using System.Text; using NetTopologySuite.Features; using NetTopologySuite.IO; using NetTopologySuite.IO.Esri; var features = new List<Feature>(); var wktReader = new WKTReader(); // 尝试过EPSG:4326和EPSG:3826的WKT,均无效 var geometry = wktReader.Read($"POLYGON((229884.458362927 2698919.1790506,229878.266318657 2698913.05244554,229872.637726088 2698914.0245398,229870.132848978 2698912.76299454,229868.585854503 2698911.60799823,229862.417875893 2698913.56799102,229859.466886255 2698913.2179918,229854.168905161 2698909.4280045,229832.918531065 2698900.75121021,229826.266555421 2698903.87487001,229815.242942057 2698911.30138916,229814.158096991 2698912.0322406,229802.736136414 2698917.5934203,229787.107090625 2698922.43900198,229770.41744862 2698926.49898628,229758.597689508 2698931.31876844,229754.622568952 2698933.63004125,229756.82934315 2698935.98290305,229758.154520219 2698937.39368305,229761.467578897 2698937.10864875,229772.427440716 2698935.38875568,229785.926793536 2698934.84915899,229801.796838123 2698933.66916467,229811.707603543 2698932.67086896,229818.576179578 2698931.9792722,229834.383317175 2698930.1646309,229840.615502711 2698929.44918301,229859.255237777 2698926.54949485,229875.612191821 2698922.46243583,229879.34506797 2698921.52971422,229884.458362927 2698919.1790506))"); // 也试过这个写法,同样无效 // var geometry = wktReader.Read(wkt) as Polygon; var attributes = new AttributesTable { { "Date", new DateTime(2022, 1, 1) }, { "Content", $"I am No. 1" } }; var feature = new Feature(geometry, attributes); features.Add(feature); Shapefile.WriteAllFeatures(features, @"C:\Users\user\Downloads\test.shp");
解决思路
方案1:将单个Polygon包装为MultiPolygon
错误核心是自动推断几何类型时,内部默认按MultiPolygon处理,但实际传入的是单个Polygon。手动将Polygon包装为MultiPolygon即可:
var polygon = wktReader.Read(wkt) as Polygon; var multiPolygon = new MultiPolygon(new[] { polygon }); var feature = new Feature(multiPolygon, attributes);
方案2:显式指定ShapefileWriter的几何类型
避开自动推断的问题,手动创建指定几何类型的ShapefileWriter,替代WriteAllFeatures快捷方法:
using (var writer = new ShapefileWriter<Polygon>(@"C:\Users\user\Downloads\test.shp")) { writer.Write(feature); }
注意泛型参数需和传入Feature的几何类型严格一致。
方案3:调整WKTReader的几何工厂配置
错误中返回PolygonZM,说明读取的几何包含Z/M维度。如果不需要这些维度,可配置几何工厂禁用:
var geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); // 指定坐标系,不启用Z/M维度 var wktReader = new WKTReader(geometryFactory);
这样读取的Polygon为普通类型,避免类型转换异常。
内容的提问来源于stack exchange,提问作者anthea.wu14

