年度变更建库软件5.0版本
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.

304 lines
12 KiB

6 months ago
using ESRI.ArcGIS.Geometry;
using NetTopologySuite.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Kingo.RuleCheck.CheckHelper
{
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));
}
/// <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;
}
}
public static string GeometryToJsonString(ESRI.ArcGIS.Geometry.IGeometry geometry)
{
ESRI.ArcGIS.esriSystem.IJSONWriter jsonWriter = new ESRI.ArcGIS.esriSystem.JSONWriterClass();
jsonWriter.WriteToString();
ESRI.ArcGIS.Geometry.JSONConverterGeometryClass jsonCon = new ESRI.ArcGIS.Geometry.JSONConverterGeometryClass();
jsonCon.WriteGeometry(jsonWriter, null, geometry, false);
return Encoding.UTF8.GetString(jsonWriter.GetStringBuffer());
}
/// <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)
{
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("转换后图形为空!");
}
ESRI.ArcGIS.Geometry.ITopologicalOperator topological = geometry as ESRI.ArcGIS.Geometry.ITopologicalOperator;
if (!topological.IsSimple)
{
topological.Simplify();
}
ISpatialReference spatialReference = null;
if (isGeograhicCoordinateSystem)
{
spatialReference = CreateGeographicCoordinateSystem(wkid);
}
else
{
spatialReference = CreateProjectedCoordinateSystem(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>
/// 修复几何错误
/// </summary>
/// <param name="geometry">几何对象</param>
public static void SimplifyGeometry(ESRI.ArcGIS.Geometry.IGeometry geometry)
{
if (geometry is ESRI.ArcGIS.Geometry.ITopologicalOperator2 topoOp)
{
topoOp.IsKnownSimple_2 = false; //设为false
if (!topoOp.IsSimple)
{
switch (geometry.GeometryType)
{
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint:
{
topoOp.Simplify();
}
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
{
((ESRI.ArcGIS.Geometry.IPolygon4)geometry).SimplifyPreserveFromTo();
}
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
{
if (geometry is ESRI.ArcGIS.Geometry.IPolyline6 polyline6)
{
polyline6.SimplifyNonPlanar();
}
else
{
((ESRI.ArcGIS.Geometry.IPolyline5)geometry).SimplifyNetwork();
}
}
break;
}
}
}
}
/// <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 ConverJsonToIGeoemtryWithoutSimple(string jsonGeometry, esriGeometryType geometryType = esriGeometryType.esriGeometryPolygon, int wkid = 4490, bool isGeograhicCoordinateSystem = 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("转换后图形为空!");
}
ISpatialReference spatialReference = null;
if (isGeograhicCoordinateSystem)
{
spatialReference = CreateGeographicCoordinateSystem(wkid);
}
else
{
spatialReference = CreateProjectedCoordinateSystem(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>
/// 根据坐标WKID创建地理坐标参考
/// </summary>
/// <param name="WKID">WKID</param>
/// <returns></returns>
private static IGeographicCoordinateSystem CreateGeographicCoordinateSystem(int WKID)
{
try
{
ISpatialReferenceFactory2 pSpatialRefFac = new SpatialReferenceEnvironmentClass();
return pSpatialRefFac.CreateGeographicCoordinateSystem(WKID);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 根据WKID创建投影坐标参考
/// </summary>
/// <param name="wkid"></param>
/// <returns></returns>
public static IProjectedCoordinateSystem CreateProjectedCoordinateSystem(int wkid)
{
//创建一个要素集创建一个投影
ISpatialReferenceFactory pSpatialRefFac = new SpatialReferenceEnvironmentClass();
return pSpatialRefFac.CreateProjectedCoordinateSystem(wkid);
}
}
}