using ESRI.ArcGIS.Geometry; using KGIS.Framework.AE; using NetTopologySuite.IO; using System; using System.Text; namespace Kingo.PluginServiceInterface { public static class GeometryConvertHelper { public static IGeometryFactory3 GeometryFactory3 { get; set; } /// /// IGeometry转WKT /// /// /// public static string ConvertIGeoemtryToWKT(IGeometry geometry) { return ConvertWKBToWKT(ConvertGeometryToWKB(geometry)); } /// /// IGeometry转WKB /// /// /// public static byte[] ConvertGeometryToWKB(IGeometry geometry) { //IWkb wkb = geometry as IWkb; ITopologicalOperator oper = geometry as ITopologicalOperator; oper.Simplify(); if (GeometryFactory3 == null) { GeometryFactory3 = new GeometryEnvironment() as IGeometryFactory3; } byte[] b = GeometryFactory3.CreateWkbVariantFromGeometry(geometry) as byte[]; return b; } /// /// WKT转IGeometry /// /// /// public static IGeometry ConvertWKTToIGeometry(string wkt) { //return ConvertWKBToIGeometry(ConvertWKTToWKB(wkt)); IGeometry geometry = null; try { geometry = ConvertWKBToIGeometry(ConvertWKTToWKB(wkt)); IPolygon polygon = geometry as IPolygon; if (polygon == null) { IPolyline line = geometry as IPolyline; return line; } IArea area = geometry as IArea; if (!polygon.IsEmpty && area != null && area.Area < 0) { polygon.ReverseOrientation(); } else { geometry = ConvertWKBToIGeometry(ConvertWKTToWKB(wkt)); } } catch (Exception ex) { throw new Exception("WKT转IGeometry异常:" + ex.Message); } return geometry; } /// /// WKB转WKT /// /// /// public static string ConvertWKBToWKT(byte[] wkb) { try { WKTWriter writer = new WKTWriter(); WKBReader reader = new WKBReader(); return writer.Write(reader.Read(wkb)); } catch (Exception ex) { return ex.Message; } } /// /// WKT转WKB /// /// /// public static byte[] ConvertWKTToWKB(string wkt) { try { WKBWriter writer = new WKBWriter(); WKTReader reader = new WKTReader(); return writer.Write(reader.Read(wkt)); } catch (Exception ex) { throw new Exception("WKT格式转WKB异常:" + ex.Message); } } /// /// WKB转IGeometry /// /// /// public static IGeometry ConvertWKBToIGeometry(byte[] wkb) { IGeometry geom; try { int countin = wkb.GetLength(0); if (GeometryFactory3 == null) { GeometryFactory3 = new GeometryEnvironment() as IGeometryFactory3; } GeometryFactory3.CreateGeometryFromWkbVariant(wkb, out geom, out countin); return geom; } catch (Exception ex) { throw new Exception("WKB格式转IGeometry异常:" + ex.Message); } } /// /// JSON图图形转IGeometry /// /// 图形串 /// 图形类型:点,线、面 /// 输出图形坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形 /// 是地理坐标参考 /// public static IGeometry ConverJsonToIGeoemtry(string jsonGeometry, esriGeometryType geometryType = esriGeometryType.esriGeometryPolygon, int wkid = 4490, bool isGeograhicCoordinateSystem = true, bool isSimplify = true) { try { using (ESRI.ArcGIS.ADF.ComReleaser comReleaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.esriSystem.IJSONReader reader = new ESRI.ArcGIS.esriSystem.JSONReaderClass(); comReleaser.ManageLifetime(reader); reader.ReadFromString(jsonGeometry); ESRI.ArcGIS.Geometry.JSONConverterGeometryClass jsonConverter = new JSONConverterGeometryClass(); comReleaser.ManageLifetime(jsonConverter); IGeometry geometry = jsonConverter.ReadGeometry(reader, geometryType, false, false); if (geometry == null || geometry.IsEmpty) { throw new Exception("转换后图形为空!"); } //此处发现湖南抽取过来的图形Simplify之后图形变化较大,会删除节点,所以湖南暂时不执行图形简化操作 //四川单图斑边界套合检查返回的部分不套合图形Simplify之后会导致图形为空 if (!KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("ArearName").Equals("43") && isSimplify) { ESRI.ArcGIS.Geometry.ITopologicalOperator topological = geometry as ESRI.ArcGIS.Geometry.ITopologicalOperator; if (!topological.IsSimple) { topological.Simplify(); } } //IPointCollection geometryCollection = geometry as IPointCollection; //int count = geometryCollection.PointCount; //ESRI.ArcGIS.Geometry.ITopologicalOperator3 topological = geometry as ESRI.ArcGIS.Geometry.ITopologicalOperator3; //esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK; //bool b = topological.get_IsSimpleEx(out reason); //if (!b) //{ // topological.Simplify(); //} //geometryCollection = geometry as IPointCollection; //count = geometryCollection.PointCount; ISpatialReference spatialReference = null; if (isGeograhicCoordinateSystem) { spatialReference = GeoDBAPI.CreateGeographicCoordinateSystem(wkid); } else { spatialReference = GeoDBAPI.CreteSpatialReference(wkid); } if (wkid > 0) { if (geometry.SpatialReference == null) { geometry.SpatialReference = spatialReference; } else if (wkid != geometry.SpatialReference.FactoryCode) { geometry.Project(spatialReference); } } return geometry; } } catch (Exception ex) { throw ex; } } /// /// JSON图图形转IGeometry /// /// 图形串 /// 图形类型:点,线、面 /// 输出图形坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形 /// 是地理坐标参考 /// public static IGeometry ConverJsonToIGeoemtry(string jsonGeometry, ISpatialReference spatialReference, esriGeometryType geometryType = esriGeometryType.esriGeometryPolygon, bool isSimple = true) { try { using (ESRI.ArcGIS.ADF.ComReleaser comReleaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.esriSystem.IJSONReader reader = new ESRI.ArcGIS.esriSystem.JSONReaderClass(); comReleaser.ManageLifetime(reader); reader.ReadFromString(jsonGeometry); ESRI.ArcGIS.Geometry.JSONConverterGeometryClass jsonConverter = new JSONConverterGeometryClass(); comReleaser.ManageLifetime(jsonConverter); IGeometry geometry = jsonConverter.ReadGeometry(reader, geometryType, false, false); if (geometry == null || geometry.IsEmpty) { throw new Exception("转换后图形为空!"); } if (geometry.SpatialReference == null) { if (spatialReference != null) { double tolerance = (spatialReference as ISpatialReferenceTolerance).XYTolerance; if (tolerance < 0.0001) { geometry.SpatialReference = CreateGeographicCoordinateSystem(4490, 0.0000000001); } else { geometry.SpatialReference = CreateGeographicCoordinateSystem(4490, 0.000000001); } } else { geometry.SpatialReference = CreateGeographicCoordinateSystem(4490, 0.000000001); } } if (spatialReference != null) { geometry.Project(spatialReference); } if (geometryType == esriGeometryType.esriGeometryPolygon) { double area = (geometry as IArea).Area; if (area < 0)//面积小于0说明环的方向不对,坐标点顺序要反转一下 { (geometry as IPolygon).ReverseOrientation(); } } if (isSimple) { ESRI.ArcGIS.Geometry.ITopologicalOperator topological = geometry as ESRI.ArcGIS.Geometry.ITopologicalOperator; if (!topological.IsSimple) { topological.Simplify(); } } return geometry; } } catch (Exception ex) { throw ex; } } /// /// IGeometry转JSON字符串 /// /// 待转换图形 /// 坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形 /// 是地理坐标参考 /// public static string ConverIGometryToJson(IGeometry geometry, int wkid = 4490, bool isGeograhicCoordinateSystem = true) { try { if (geometry == null || geometry.IsEmpty || geometry.SpatialReference == null) { throw new Exception("图形或坐标参考为空,无法转换!"); } if (wkid > 0) { if (isGeograhicCoordinateSystem) { geometry.Project(GeoDBAPI.CreateGeographicCoordinateSystem(wkid)); } else { geometry.Project(GeoDBAPI.CreteSpatialReference(wkid)); } } using (ESRI.ArcGIS.ADF.ComReleaser comReleaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geometry.JSONConverterGeometryClass jsonConverter = new JSONConverterGeometryClass(); comReleaser.ManageLifetime(jsonConverter); ESRI.ArcGIS.esriSystem.IJSONWriter jsonWriter = new ESRI.ArcGIS.esriSystem.JSONWriterClass(); jsonWriter.WriteToString(); comReleaser.ManageLifetime(jsonWriter); jsonConverter.WriteGeometry(jsonWriter, null, geometry, false); return Encoding.UTF8.GetString(jsonWriter.GetStringBuffer()); } } catch (Exception ex) { throw ex; } } /// /// IGeometry转JSON字符串:坐标参考wkid,4490 /// /// 待转换图形 /// public static string ConverIGometryToJson(IGeometry geometry, bool prj4490) { try { if (geometry == null || geometry.IsEmpty || geometry.SpatialReference == null) { throw new Exception("图形或坐标参考为空,无法转换!"); } if (prj4490) { ISpatialReferenceTolerance spatialReferenceTolerance = geometry.SpatialReference as ISpatialReferenceTolerance; if (spatialReferenceTolerance.XYTolerance < 0.0001) { geometry.Project(CreateGeographicCoordinateSystem(4490, 0.0000000001)); } else { geometry.Project(CreateGeographicCoordinateSystem(4490, 0.000000001)); } } using (ESRI.ArcGIS.ADF.ComReleaser comReleaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geometry.JSONConverterGeometryClass jsonConverter = new JSONConverterGeometryClass(); comReleaser.ManageLifetime(jsonConverter); ESRI.ArcGIS.esriSystem.IJSONWriter jsonWriter = new ESRI.ArcGIS.esriSystem.JSONWriterClass(); jsonWriter.WriteToString(); comReleaser.ManageLifetime(jsonWriter); jsonConverter.WriteGeometry(jsonWriter, null, geometry, false); return Encoding.UTF8.GetString(jsonWriter.GetStringBuffer()); } } catch (Exception ex) { throw ex; } } /// /// 根据坐标WKID创建地理坐标参考 /// /// WKID /// 容差 /// public static ISpatialReference CreateGeographicCoordinateSystem(int WKID, double pTolerance) { ISpatialReference pSpatialReference = null; ISpatialReferenceFactory2 pSpatialRefFac = null; try { pSpatialRefFac = new SpatialReferenceEnvironmentClass(); pSpatialReference = pSpatialRefFac.CreateGeographicCoordinateSystem(WKID); (pSpatialReference as ISpatialReferenceResolution).set_XYResolution(true, pTolerance / 10); (pSpatialReference as ISpatialReferenceResolution).set_ZResolution(true, pTolerance / 10); (pSpatialReference as ISpatialReferenceResolution).MResolution = (pTolerance / 10); (pSpatialReference as ISpatialReferenceTolerance).XYTolerance = pTolerance; (pSpatialReference as ISpatialReferenceTolerance).ZTolerance = pTolerance; (pSpatialReference as ISpatialReferenceTolerance).MTolerance = pTolerance; return pSpatialReference; } catch (Exception ex) { throw ex; } finally { if (pSpatialRefFac != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(pSpatialRefFac); } } } } }