You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							404 lines
						
					
					
						
							17 KiB
						
					
					
				
			
		
		
	
	
							404 lines
						
					
					
						
							17 KiB
						
					
					
				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; } | 
						|
        /// <summary> | 
						|
        /// IGeometry转WKT | 
						|
        /// </summary> | 
						|
        /// <param name="geometry"></param> | 
						|
        /// <returns></returns> | 
						|
        public static string ConvertIGeoemtryToWKT(IGeometry geometry) | 
						|
        { | 
						|
            return ConvertWKBToWKT(ConvertGeometryToWKB(geometry)); | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// IGeometry转WKB | 
						|
        /// </summary> | 
						|
        /// <param name="geometry"></param> | 
						|
        /// <returns></returns> | 
						|
        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; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// WKT转IGeometry | 
						|
        /// </summary> | 
						|
        /// <param name="wkt"></param> | 
						|
        /// <returns></returns> | 
						|
        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; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// WKB转WKT | 
						|
        /// </summary> | 
						|
        /// <param name="wkb"></param> | 
						|
        /// <returns></returns> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// WKT转WKB | 
						|
        /// </summary> | 
						|
        /// <param name="wkt"></param> | 
						|
        /// <returns></returns> | 
						|
        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); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// WKB转IGeometry | 
						|
        /// </summary> | 
						|
        /// <param name="wkb"></param> | 
						|
        /// <returns></returns> | 
						|
        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); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// JSON图图形转IGeometry | 
						|
        /// </summary> | 
						|
        /// <param name="jsonGeometry">图形串</param> | 
						|
        /// <param name="geometryType">图形类型:点,线、面</param> | 
						|
        /// <param name="wkid">输出图形坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形</param> | 
						|
        /// <param name="isGeograhicCoordinateSystem">是地理坐标参考</param> | 
						|
        /// <returns></returns> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// JSON图图形转IGeometry | 
						|
        /// </summary> | 
						|
        /// <param name="jsonGeometry">图形串</param> | 
						|
        /// <param name="geometryType">图形类型:点,线、面</param> | 
						|
        /// <param name="wkid">输出图形坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形</param> | 
						|
        /// <param name="isGeograhicCoordinateSystem">是地理坐标参考</param> | 
						|
        /// <returns></returns> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// IGeometry转JSON字符串 | 
						|
        /// </summary> | 
						|
        /// <param name="geometry">待转换图形</param> | 
						|
        /// <param name="wkid">坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形</param> | 
						|
        /// <param name="isGeograhicCoordinateSystem">是地理坐标参考</param> | 
						|
        /// <returns></returns> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
 | 
						|
        /// <summary> | 
						|
        /// IGeometry转JSON字符串:坐标参考wkid,4490 | 
						|
        /// </summary> | 
						|
        /// <param name="geometry">待转换图形</param> | 
						|
        /// <returns></returns> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 根据坐标WKID创建地理坐标参考 | 
						|
        /// </summary> | 
						|
        /// <param name="WKID">WKID</param> | 
						|
        /// <param name="pTolerance">容差</param> | 
						|
        /// <returns></returns> | 
						|
        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); | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
    } | 
						|
}
 | 
						|
 |