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); |
|
} |
|
} |
|
} |
|
} |
|
}
|
|
|