基於Arcgis GP工具的大部分的功能,都在這裏面了
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.Geoprocessor;
using AG.GH.Utility.Common;
using ESRI.ArcGIS.SpatialAnalystTools;
using AG.GH.Utility.Common.Sub;
using ESRI.ArcGIS.DataSourcesRaster;
using System.Data;
using System.Linq;
using ESRI.ArcGIS.ConversionTools;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.DataSourcesFile;
using System.Text.RegularExpressions;
using ESRI.ArcGIS.SpatialAnalyst;
using ESRI.ArcGIS.GeoAnalyst;
using AG.GH.Utility.Tools.Sub;
using AG.COM.SDM.Utility;
using AG.GH.Utility.Data;
using ESRI.ArcGIS.DataManagementTools;
using System.IO;
namespace AG.GH.Utility.Tools
{
/// <summary>
/// 2018年9月26日 對部分代碼添加region管理-蔡周峻
/// 2018年10月15日20:58:33 ShowGPFileMessage
/// 2018年10月18日10:53:20 陳彪,新建虛函數ClassifyRaster
/// </summary>
public interface IGeoAnalysis
{
#region 屬性
ITrackCancel TrackCancel { set; }
IGeoProcessorEvents GPEvents { set; }
#endregion
#region 裁剪
void ClipFeature(IFeatureClass inputFeatures, IPolygon clip, IFeatureClass outputClass, string sClause);
IFeatureClass ClipFeature(IFeatureClass inputFeatures, IPolygon clip, string sClause);
IFeatureClass ClipFeature(IFeatureClass inputFeatures, List<IPolygon> clipGeometrys, string sClause);
IFeatureClass ClipFeature(IFeatureClass inputFeatures, IGeometryArray clipGeometrys, string sClause);
IFeatureClass ClipFeature(IFeatureClass inputFeatures, IFeatureClass clipFeatures, IQueryFilter inputFilter, IQueryFilter clipFilter);
IFeatureClass ClipFeature(object inputFeatures, object clipFeatures, double tolerance);
#endregion
#region 擦除
void Erase(IFeatureClass inputFeatures, IPolygon erase, string sClause);
IFeatureClass Erase(IFeatureClass inputFeatures, IFeatureClass eraseFeatures, string outputClass);
IFeatureClass Erase(IFeatureClass inputFeatures, IFeatureClass eraseFeatures, string outputClass, IQueryFilter inputFilter, IQueryFilter eraseFilter);
IFeatureClass EraseWithArcInfo
(object inputFeatures, object eraseFeatures, string outputClass, double tolerance);
#endregion
#region 聯合
IFeatureClass Union(object[] inputObjects, JoinAttributesType joinType);
IFeatureClass Union(IFeatureClass inputFeatures, IFeatureClass unionFeatures);
IFeatureClass Union(IFeatureClass inputFeatures, IFeatureClass unionFeatures, IQueryFilter inputFilter, IQueryFilter unionFilter);
#endregion
#region 求相交
IFeatureClass Intersect(object[] inputObjects,JoinAttributesType joinType, string outputType, double tolerance);
IFeatureClass Intersect(IFeatureClass inputFeatures, IFeatureClass intersecFeatures);
IFeatureClass Intersect(IFeatureLayer inputFeatures, IFeatureLayer intersecFeatures);
IFeatureClass Intersect(IFeatureClass inputFeatures, IFeatureClass intersectFeatures, IQueryFilter inputFilter, IQueryFilter intersectFilter);
#endregion
#region 求緩衝
IFeatureClass Buffer(IFeatureClass inputFeatures, IQueryFilter inputFilter, double radius, bool dissolve);
#endregion
/// <summary>
/// 交集取反
/// </summary>
/// <param name="inputFeatures"></param>
/// <param name="update_features"></param>
/// <param name="outputClass"></param>
/// <param name="joinType"></param>
/// <returns></returns>
IFeatureClass SymDiffWithArcInfo(object inputFeatures, object update_features, string outputClass, JoinAttributesType joinType);
IFeatureClass IdentityWithArcInfo(object inputFeatures, object identityFeatures, string outputClass, JoinAttributesType joinType);
void Release();
#region 輸出路徑設置
void SetClipResultPathRandomName();
void SetUnionResultPathRandomName();
void SetBufferResultPathRandomName();
void SetIntersectResultPathRandomName();
string SetRasterResultPathPathRandomName();
#endregion
}
public class GeoAnalysis : EnvironmentClass, IGeoAnalysis, IDebug, IEnvironment
{
private ITrackCancel m_TrackCancel = null;
private TrackCancelClass2 m_cancelHandler = null;
private IGeoTopology m_GeoTopology = null;
private IFeaturesCopy m_FeaturesCopy = null;
private Geoprocessor m_GP = null;
private IGeoProcessorEvents m_GPEvents = null;
private ESRI.ArcGIS.AnalysisTools.Intersect m_IntersectTool = null;
private ESRI.ArcGIS.AnalysisTools.Buffer m_BufferTool = null;
private ESRI.ArcGIS.AnalysisTools.Erase m_EraseTool = null;
#region 屬性
public ITrackCancel TrackCancel
{
set
{
m_TrackCancel = value;
}
}
/// <summary>
/// 裁剪的數據路徑
/// </summary>
public string ClipResultPath
{
get;
set;
}
/// <summary>
/// 聯合的數據路徑
/// </summary>
public string UnionResultPath
{
get;
set;
}
/// <summary>
/// 緩衝分析的數據保存路徑
/// </summary>
public string BufferResultPath
{
get;
set;
}
/// <summary>
/// 相交計算得到的結果的保存路徑
/// </summary>
public string IntersectResultPath
{
get;
set;
}
/// <summary>
/// 柵格計算得到的結果的保持的路徑
/// </summary>
public string RasterResultPath
{
get;
set;
}
public IGeoProcessorEvents GPEvents
{
set
{
if (m_GPEvents != null)
m_GP.UnRegisterGeoProcessorEvents(m_GPEvents);
if (value != null)
m_GP.RegisterGeoProcessorEvents(value);
m_GPEvents = value;
}
}
#endregion
#region 構造函數
public GeoAnalysis(bool initializeGPTool=true)
{
if (initializeGPTool)
{
m_GP = new Geoprocessor();
m_FeaturesCopy = new FeaturesCopyClass();
}
ClipResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Clip";
UnionResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Uinon";
BufferResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Buffer";
IntersectResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Intersect";
RasterResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Raster";
}
public GeoAnalysis(ITrackCancel trackCancel, IGeoProcessorEvents gpEvents)
: this()
{
m_TrackCancel = trackCancel;
if (gpEvents != null)
m_GP.RegisterGeoProcessorEvents(gpEvents);
m_GPEvents = gpEvents;
}
public GeoAnalysis(TrackCancelClass2 trackCancel)
: this(trackCancel, trackCancel.Progressor as IGeoProcessorEvents)
{
m_cancelHandler = trackCancel;
}
#endregion
#region IGeoAnalysis 成員
public void Release()
{
m_GP = null;
m_IntersectTool = null;
}
public void Erase(IFeatureClass inputFeatures, IPolygon erase, string sClause)
{
if (m_GeoTopology == null)
{
m_GeoTopology = new GeoTopology();
(m_GeoTopology as IDebug).ThrowException = true;
}
IFeatureCursor pFeatureCursor = null;
try
{
ISpatialFilter pSpatialFilter = new SpatialFilterClass();
pSpatialFilter.Geometry = erase;
pSpatialFilter.GeometryField = inputFeatures.ShapeFieldName;
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
pSpatialFilter.WhereClause = String.IsNullOrEmpty(sClause) ? "" : sClause;
if (inputFeatures.ShapeType == esriGeometryType.esriGeometryPoint)
{
(inputFeatures as ITable).DeleteSearchedRows(pSpatialFilter);
return;
}
IFeature pFeature = null;
pFeatureCursor = inputFeatures.Search(pSpatialFilter, false);
while ((pFeature = pFeatureCursor.NextFeature()) != null)
{
IGeometry source = pFeature.ShapeCopy;
IGeometry output = m_GeoTopology.Erase(source, erase);
if (output == null || output.IsEmpty)
{
pFeature.Delete();
}
else
{
pFeature.Shape = output;
pFeature.Store();
}
if (source != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(source);
}
}
catch (Exception err)
{
if (m_throwException)
throw err;
}
finally
{
if (pFeatureCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
}
}
public IFeatureClass Erase(IFeatureClass inputFeatures, IFeatureClass eraseFeatures, string outputClass)
{
return Erase(inputFeatures, eraseFeatures, outputClass, null, null);
}
public IFeatureClass Erase(IFeatureClass inputFeatures, IFeatureClass eraseFeatures, string outputClass, IQueryFilter inputFilter, IQueryFilter eraseFilter)
{
IFeatureCursor pFeatureCursor = null;
try
{
if (eraseFeatures.ShapeType != esriGeometryType.esriGeometryPolygon)
throw new Exception("eraseFeatures要素類必須爲Polygon");
IGeometryDef geometryDef = CommonUtils.CloneGeometryDef(inputFeatures, this.ZFlag, this.MFlag);
IFeatureClass outputFeaturs = WSExt.CreateSimpleClassFromPath(outputClass, inputFeatures.Fields, geometryDef, base.m_overwriteOutput);
IEnumInvalidObject pEnumInvalidObject = m_FeaturesCopy.PasteObjects(inputFeatures, outputFeaturs, inputFilter);
if (pEnumInvalidObject != null && pEnumInvalidObject.Next() != null)
throw new Exception("複製要素出錯,存在錯誤的對象");
IFeature pFeature = null;
pFeatureCursor = eraseFeatures.Search(eraseFilter, true);
while ((pFeature = pFeatureCursor.NextFeature()) != null)
{
IPolygon pPolygon = pFeature.ShapeCopy as IPolygon;
if (pPolygon == null || pPolygon.IsEmpty) continue;
Erase(outputFeaturs, pPolygon, "");
}
return outputFeaturs;
}
catch (Exception err)
{
if (m_throwException)
throw err;
return null;
}
finally
{
if (pFeatureCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
}
}
public IFeatureClass EraseWithArcInfo(object inputFeatures, object eraseFeatures, string outputClass, double tolerance)
{
SetGPEnvironment();
try
{
if (m_EraseTool == null) m_EraseTool = new ESRI.ArcGIS.AnalysisTools.Erase();
m_EraseTool.in_features = inputFeatures;
m_EraseTool.erase_features = eraseFeatures;
m_EraseTool.out_feature_class = outputClass;
if (tolerance > 0.0)
{
m_EraseTool.cluster_tolerance = tolerance;
}
IGeoProcessorResult gpResult =
m_GP.Execute(m_EraseTool as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err) { LogGPMessage(); if (m_throwException) throw err; return null; }
}
public IFeatureClass IdentityWithArcInfo(object inputFeatures, object identityFeatures, string outputClass, JoinAttributesType joinType)
{
SetGPEnvironment();
try
{
ESRI.ArcGIS.AnalysisTools.Identity tIdentity = null;
tIdentity = new ESRI.ArcGIS.AnalysisTools.Identity();
tIdentity.in_features = inputFeatures;
tIdentity.identity_features = identityFeatures;
tIdentity.out_feature_class = outputClass;
tIdentity.join_attributes = joinType.ToString();
IGeoProcessorResult gpResult =
m_GP.Execute(tIdentity as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err) { LogGPMessage(); if (m_throwException) throw err; return null; }
}
public IFeatureClass SymDiffWithArcInfo(object inputFeatures, object update_features, string outputClass, JoinAttributesType joinType)
{
SetGPEnvironment();
try
{
ESRI.ArcGIS.AnalysisTools.SymDiff tSymDiff = null;
tSymDiff = new ESRI.ArcGIS.AnalysisTools.SymDiff();
tSymDiff.in_features = inputFeatures;
tSymDiff.update_features = update_features;
tSymDiff.out_feature_class = outputClass;
tSymDiff.join_attributes = joinType.ToString();
IGeoProcessorResult gpResult =
m_GP.Execute(tSymDiff as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err) { LogGPMessage(); if (m_throwException) throw err; return null; }
}
void JoinAttributes(string preFix, IFields inputFields, IRow identityRow, IRowBuffer pRowBuffer)
{
try
{
for (int i = 0; i < identityRow.Fields.FieldCount; i++)
{
IField pField = identityRow.Fields.get_Field(i);
if (pField.Type == esriFieldType.esriFieldTypeGeometry
|| pField.Type == esriFieldType.esriFieldTypeOID
|| pField.Name.ToUpper().Contains("SHAPE_")
|| pField.Name.ToUpper().Contains("SHAPE.")) continue;
int checkIndex = inputFields.FindField(pField.Name);
string sFieldName = checkIndex > -1 ? preFix + pField.Name : pField.Name;
int index = pRowBuffer.Fields.FindField(sFieldName);
IField pBufferField = pRowBuffer.Fields.get_Field(index);
if (pBufferField.Type != pField.Type || pBufferField.Editable == false) continue;
object value = identityRow.get_Value(i);
if (value == null) continue;
pRowBuffer.set_Value(index, value);
}
}
catch (Exception err) { }
}
#endregion
#region 疊加分析-相交(Intersect)
public IFeatureClass Intersect(IFeatureLayer inputFeatures, IFeatureLayer intersecFeatures)
{
return this.Intersect(inputFeatures.FeatureClass, intersecFeatures.FeatureClass);
}
public IFeatureClass Intersect(object[] inputObjects, JoinAttributesType joinType, string outputType, double tolerance)
{
SetGPEnvironment();
try
{
IGpValueTableObject gpValueTable = new GpValueTableObjectClass();
gpValueTable.SetColumns(2);
object row = null;
object rank = null;
for (int i = 0; i < inputObjects.Length; i++)
{
object value = inputObjects[i];
rank = i + 1;
if (value is IFeatureClass)
{
row = ApplyQueryFilter(value as IFeatureClass, null);
}
else
{
row = value;
}
gpValueTable.AddRow(ref row);
gpValueTable.SetValue(i, 1, ref rank);
}
if (m_IntersectTool == null) m_IntersectTool = new ESRI.ArcGIS.AnalysisTools.Intersect();
m_IntersectTool.in_features = gpValueTable;
m_IntersectTool.join_attributes = joinType.ToString();
m_IntersectTool.out_feature_class = IntersectResultPath;
m_IntersectTool.output_type = outputType;
if (tolerance > 0.0)
{
m_IntersectTool.cluster_tolerance = tolerance;
}
IGeoProcessorResult gpResult =
m_GP.Execute(m_IntersectTool as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err)
{
var gpError = LogGPMessage();
throw new Exception(gpError);
}
}
public IFeatureClass Intersect(IFeatureClass inputFeatures, IFeatureClass intersectFeatures)
{
return Intersect(inputFeatures, intersectFeatures, null, null);
}
public IFeatureClass Intersect(IFeatureClass inputFeatures, IFeatureClass intersectFeatures, IQueryFilter inputFilter, IQueryFilter intersectFilter)
{
var row1 = ApplyQueryFilter(inputFeatures, inputFilter);
var row2 = ApplyQueryFilter(intersectFeatures, intersectFilter);
return Intersect(new object[] { row1, row2 }, JoinAttributesType.ALL, "INPUT", 0.0);
}
#endregion
#region 疊加分析-聯合(Union)
public IFeatureClass Union(object[] inputObjects, JoinAttributesType joinType)
{
SetGPEnvironment();
try
{
IGpValueTableObject gpValueTable = new GpValueTableObjectClass();
gpValueTable.SetColumns(2);
object row = null;
object rank = null;
for (int i = 0; i < inputObjects.Length; i++)
{
object value = inputObjects[i];
rank = i + 1;
if (value is IFeatureClass)
{
row = ApplyQueryFilter(value as IFeatureClass, null);
}
else
{
row = value;
}
gpValueTable.AddRow(ref row);
gpValueTable.SetValue(i, 1, ref rank);
}
var m_UnionTool = new ESRI.ArcGIS.AnalysisTools.Union();
m_UnionTool.in_features = gpValueTable;
m_UnionTool.join_attributes = joinType.ToString();
m_UnionTool.out_feature_class = UnionResultPath;
var gpResult =m_GP.Execute(m_UnionTool as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err) { LogGPMessage(); if (m_throwException) throw err; return null; }
}
public IFeatureClass Union(IFeatureClass inputFeatures, IFeatureClass unionFeatures)
{
return Union(inputFeatures, unionFeatures, null, null);
}
public IFeatureClass Union(IFeatureClass inputFeatures, IFeatureClass unionFeatures, IQueryFilter inputFilter, IQueryFilter unionFilter)
{
object row1 = ApplyQueryFilter(inputFeatures, inputFilter);
object row2 = ApplyQueryFilter(unionFeatures, unionFilter);
return Union(new object[] { row1, row2 }, JoinAttributesType.ALL);
}
#endregion
#region 裁剪(Clip)
public void ClipFeature(IFeatureClass inputFeatures, IPolygon clip, IFeatureClass outputFeatures, string whereClause)
{
if (m_GeoTopology == null)
{
m_GeoTopology = new GeoTopology();
(m_GeoTopology as IDebug).ThrowException = true;
}
IWorkspaceEdit wsEdit = null;
IFeatureCursor inputCursor = null;
IFeatureCursor outputCursor = null;
try
{
bool isPointClass = inputFeatures.ShapeType == esriGeometryType.esriGeometryPoint;
ISpatialFilter pSpatialFilter = new SpatialFilterClass();
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
pSpatialFilter.GeometryField = inputFeatures.ShapeFieldName;
pSpatialFilter.WhereClause = String.IsNullOrEmpty(whereClause) ? "" : whereClause;
pSpatialFilter.Geometry = clip;
if (m_cancelHandler != null)
{
m_cancelHandler.SetCircleRun(inputFeatures.FeatureCount(pSpatialFilter));
m_cancelHandler.SetWaitingMessage("Clip運算....");
}
clip.SpatialReference = (inputFeatures as IGeoDataset).SpatialReference;
inputCursor = inputFeatures.Search(pSpatialFilter, true);
wsEdit = (outputFeatures as IDataset).Workspace as IWorkspaceEdit;
wsEdit.StartEditing(true);
wsEdit.StartEditOperation();
outputCursor = outputFeatures.Insert(true);
int shapeIndex = outputFeatures.Fields.FindField(outputFeatures.ShapeFieldName);
IGeometryDef geometryDef = outputFeatures.Fields.get_Field(shapeIndex).GeometryDef;
bool hasZ = geometryDef.HasZ;
bool hasM = geometryDef.HasM;
int indexZ = inputCursor.FindField("ELEV");
int count = 0;
IGeometry outGeometry = null;
IFeature sourceFeature = null;
IFeatureBuffer targetFeature = null;
while ((sourceFeature = inputCursor.NextFeature()) != null)
{
if (m_TrackCancel != null && !m_TrackCancel.Continue()) break;
IGeometry inGeometry = sourceFeature.ShapeCopy;
if (inGeometry == null || inGeometry.IsEmpty) continue;
targetFeature = outputFeatures.CreateFeatureBuffer();
//包含判斷,提升效率
IRelationalOperator pRelationalOp = inGeometry as IRelationalOperator;
if (clip.SpatialReference != inGeometry.SpatialReference)
{
clip.SpatialReference = inGeometry.SpatialReference;
}
if (pRelationalOp.Within(clip))
{
outGeometry = inGeometry;
}
else
{
outGeometry = isPointClass ? inGeometry : m_GeoTopology.Interset(inGeometry, clip);
}
// IGeometry outGeometry = isPointClass ? inGeometry : m_GeoTopology.Interset(inGeometry, clip);
if (outGeometry == null || outGeometry.IsEmpty)
continue;
m_FeaturesCopy.CopyPropertry(sourceFeature as IRow, targetFeature as IRowBuffer, false);
if (!hasZ && m_ZFlag == FlagEnum.Disabled)
{
m_GeoTopology.DropZ(outGeometry);
}
if (m_MFlag == FlagEnum.Disabled)
{
m_GeoTopology.DropM(outGeometry);
}
if (hasZ)
{
IZAware pZAware = outGeometry as IZAware;
pZAware.ZAware = true;
if (outGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
{
double z = 0.0;
if (indexZ > -1)
{
object oZ = sourceFeature.get_Value(indexZ);
if (oZ != null && !DBNull.Value.Equals(oZ))
{
string sZ = oZ.ToString();
double.TryParse(sZ, out z);
}
}
(outGeometry as IPoint).Z = z;
}
else
{
IZ2 pZ = outGeometry as IZ2;
pZ.SetConstantZ(0);
}
}
targetFeature.Shape = outGeometry;
outputCursor.InsertFeature(targetFeature);
count++;
if (count == 2000)
{
outputCursor.Flush();
count = 0;
}
if (m_cancelHandler != null)
m_cancelHandler.StepCircle();
if (inGeometry != null)
CommonUtils.CloseObject(inGeometry);
}
if (count > 0)
{
outputCursor.Flush();
}
wsEdit.StopEditOperation();
wsEdit.StopEditing(true);
}
catch (Exception err)
{
if (wsEdit != null && wsEdit.IsBeingEdited())
{
wsEdit.AbortEditOperation();
wsEdit.StopEditing(false);
}
if (m_throwException)
throw err;
}
finally
{
if (inputCursor != null)
CommonUtils.CloseObject(inputCursor);
if (outputCursor != null)
CommonUtils.CloseObject(outputCursor);
}
}
public IFeatureClass ClipFeature(IFeatureClass inputFeature, IPolygon clip, string whereClause)
{
IFeatureClass outputFeatures = null;
try
{
IGeometryDef geometryDef = CommonUtils.CloneGeometryDef(inputFeature, this.ZFlag, this.MFlag);
outputFeatures = WSExt.CreateSimpleClassFromPath(ClipResultPath, inputFeature.Fields, geometryDef, m_overwriteOutput);
ClipFeature(inputFeature, clip, outputFeatures, whereClause);
}
catch (Exception err)
{
if (m_throwException)
throw err;
}
return outputFeatures;
}
public IFeatureClass ClipFeature(IFeatureClass inputFeatures, List<IPolygon> clipGeometrys, string whereClause)
{
IFeatureClass outputFeaures = ClipFeature(inputFeatures, clipGeometrys[0], whereClause);
for (int i = 1; i < clipGeometrys.Count; i++)
{
ClipFeature(inputFeatures, clipGeometrys[i], outputFeaures, whereClause);
}
return outputFeaures;
}
public IFeatureClass ClipFeature(IFeatureClass inputFeatures, IGeometryArray clipGeometrys, string whereClause)
{
if (clipGeometrys == null || clipGeometrys.Count < 1)
return null;
IFeatureClass outputFeaures = ClipFeature(inputFeatures, clipGeometrys.get_Element(0) as IPolygon, whereClause);
for (int i = 1; i < clipGeometrys.Count; i++)
{
ClipFeature(inputFeatures, clipGeometrys.get_Element(i) as IPolygon, outputFeaures, whereClause);
}
return outputFeaures;
}
public IFeatureClass ClipFeature(IFeatureClass inputFeatures, IFeatureClass clipFeatures, IQueryFilter inputFilter, IQueryFilter clipFilter)
{
object in_Features = ApplyQueryFilter(inputFeatures, inputFilter);
object clip_Features = ApplyQueryFilter(clipFeatures, clipFilter);
return ClipFeature(in_Features, clip_Features, 0.001);
}
public IFeatureClass ClipFeature(object inputFeatures, object clipFeatures, double tolerance)
{
SetGPEnvironment();
try
{
var m_ClipTool = new ESRI.ArcGIS.AnalysisTools.Clip();
m_ClipTool.in_features = inputFeatures;
m_ClipTool.clip_features = clipFeatures;
m_ClipTool.out_feature_class = ClipResultPath;
if (tolerance > 0.0)
{
m_ClipTool.cluster_tolerance = tolerance;
}
IGeoProcessorResult gpResult =
m_GP.Execute(m_ClipTool as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err)
{
LogGPMessage();
if (m_throwException)
throw err;
return null;
}
}
#endregion
#region 緩衝(Buffer)
public IFeatureClass Buffer(IFeatureClass inputFeatures, IQueryFilter inputFilter, double radius, bool dissolve)
{
SetGPEnvironment();
try
{
if (m_BufferTool == null)
m_BufferTool = new ESRI.ArcGIS.AnalysisTools.Buffer();
m_BufferTool.in_features = ApplyQueryFilter(inputFeatures, inputFilter);
m_BufferTool.out_feature_class = BufferResultPath;
m_BufferTool.dissolve_option = dissolve ? "ALL" : "NONE";
m_BufferTool.buffer_distance_or_field = radius + " Meters";
IGeoProcessorResult gpResult =
m_GP.Execute(m_BufferTool as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err)
{
LogGPMessage();
if (m_throwException)
throw err;
return null;
}
}
/// <summary>
/// 空間數據的緩衝分析
/// </summary>
/// <param name="inputFeatures"></param>
/// <param name="inputFilter"></param>
/// <param name="radiusWithUnit">Meters</param>
/// <param name="dissolveOption">ALL NONE LIST</param>
/// <returns></returns>
public IFeatureClass Buffer(IFeatureClass inputFeatures, IQueryFilter inputFilter, string radiusWithUnit, string dissolveOption = "ALL")
{
SetGPEnvironment();
try
{
if (m_BufferTool == null)
m_BufferTool = new ESRI.ArcGIS.AnalysisTools.Buffer();
m_BufferTool.in_features = ApplyQueryFilter(inputFeatures, inputFilter);
m_BufferTool.out_feature_class = BufferResultPath;
m_BufferTool.dissolve_option = dissolveOption;
m_BufferTool.buffer_distance_or_field = radiusWithUnit;
IGeoProcessorResult gpResult =
m_GP.Execute(m_BufferTool as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err)
{
LogGPMessage();
if (m_throwException)
throw err;
return null;
}
}
#endregion
#region 分割(Slice)
/// <summary>
/// 分割, 即將待重分類的柵格數據的值域進行n等分
/// 每一段的柵格像元值, 由舊值從小到大變爲1、2、3...的順序自然數值
/// </summary>
/// <param name="layer">待重分類的柵格圖層</param>
/// <param name="sliceNum">待分割的段數,默認5段</param>
/// <param name="type">分割類型,默認等間距分割</param>
/// <returns></returns>
public IRasterLayer Slice(IRasterLayer layer, int sliceNum, esriGeoAnalysisSliceEnum type = esriGeoAnalysisSliceEnum.esriGeoAnalysisSliceEqualInterval)
{
IReclassOp reclassOp = new RasterReclassOpClass();
IRasterAnalysisEnvironment rasterAnalysisEnvironment = reclassOp as IRasterAnalysisEnvironment;
rasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, (layer.Raster as IGeoDataset).Extent, null);
rasterAnalysisEnvironment.OutSpatialReference = (layer.Raster as IGeoDataset).SpatialReference;
IRaster rasterResult = reclassOp.Slice(layer.Raster as IGeoDataset, type, sliceNum) as IRaster;
IRasterLayer rlyr = new RasterLayerClass();
rlyr.CreateFromRaster(rasterResult);
return rlyr;
}
/// <summary>
/// 分割, 即將待重分類的柵格數據的值域進行n等分
/// 每一段的柵格像元值, 由舊值從小到大變爲1、2、3...的順序自然數值
/// </summary>
/// <param name="inputRaster">待重分類的IRaster</param>
/// <param name="sliceNum">待分割的段數,默認5段</param>
/// <param name="type">分割類型,默認等間距分割</param>
/// <returns></returns>
public IRasterLayer Slice(IRaster inputRaster, int sliceNum, esriGeoAnalysisSliceEnum type = esriGeoAnalysisSliceEnum.esriGeoAnalysisSliceEqualInterval)
{
IReclassOp reclassOp = new RasterReclassOpClass();
// 環境設置
IRasterAnalysisEnvironment rasterAnalysisEnvironment = reclassOp as IRasterAnalysisEnvironment;
rasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, (inputRaster as IGeoDataset).Extent, null);
rasterAnalysisEnvironment.OutSpatialReference = (inputRaster as IGeoDataset).SpatialReference;
IRaster rasterResult = reclassOp.Slice(inputRaster as IGeoDataset, type, sliceNum) as IRaster;
IRasterLayer rlyr = new RasterLayerClass();
rlyr.CreateFromRaster(rasterResult);
return rlyr;
}
#endregion
#region 空間連接
public IFeatureClass SpatialJoins(IFeatureClass inputFeatures, IFeatureClass joinsFeatures, SpatialJoinOperation operation)
{
return SpatialJoins(inputFeatures, joinsFeatures, operation, MatchOption.INTERSECT);
}
public IFeatureClass SpatialJoins(IFeatureClass inputFeatures, IFeatureClass joinsFeatures, SpatialJoinOperation operation,MatchOption type)
{
SetGPEnvironment();
try
{
var m_SpatialJoinsTool = new ESRI.ArcGIS.AnalysisTools.SpatialJoin();
m_SpatialJoinsTool.target_features = inputFeatures;
m_SpatialJoinsTool.join_features = joinsFeatures;
m_SpatialJoinsTool.join_operation = operation.ToString();
m_SpatialJoinsTool.match_option = type.ToString();
var gpResult = m_GP.Execute(m_SpatialJoinsTool as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch(Exception err)
{
LogGPMessage(); if (m_throwException) throw err; return null;
}
}
#endregion
#region 地圖代數
/// <summary>
/// 傳入RasterLayer列表,傳入表達式,計算結果
/// </summary>
/// <param name="param">IRasterLayer列表</param>
/// <param name="expression">表達式</param>
/// <returns>返回計算結果柵格圖層</returns>
public IRasterLayer RasterCalculator(List<IRasterLayer> param, string expression, IFeatureLayer maskLayer = null)
{
// 使用IMapAlgebraOp
IMapAlgebraOp mapAlgebraOp = new RasterMapAlgebraOpClass();
for (int i = 1; i <= param.Count; i++)
{
// 綁定柵格數據與名稱
mapAlgebraOp.BindRaster(
param[i - 1].Raster as IGeoDataset,
"raster" + i.ToString());
}
if (maskLayer != null)
{
IRasterAnalysisEnvironment rasterAnalysisEnvironment = mapAlgebraOp as IRasterAnalysisEnvironment;
rasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, (maskLayer as IGeoDataset).Extent, null);
rasterAnalysisEnvironment.Mask = maskLayer.FeatureClass as IGeoDataset;
}
// 創建並返回柵格圖層
IRasterLayer rasterLayer = new RasterLayerClass();
rasterLayer.CreateFromRaster(mapAlgebraOp.Execute(expression) as IRaster);
return rasterLayer;
}
public IRasterLayer RasterCalculator(List<IRasterLayer> param, RasterConditionCreator expression)
{
return RasterCalculator(param, expression.Result);
}
#endregion
#region 柵格-相減
/// <summary>
/// 保存的路徑默認是RasterResultPath
/// </summary>
/// <param name="baseMapLayer"></param>
/// <param name="toCutLayer"></param>
/// <param name="radio"></param>
public bool RasterSubtract(RasterLayer baseMapLayer, RasterLayer toCutLayer, double radio)
{
try
{
SetGPEnvironment();
RasterCalculator RC = new RasterCalculator();
RC.expression = "\"" + baseMapLayer.FilePath +
"\" - Con(IsNull(\"" + toCutLayer.FilePath + "\"),0,1)*" + radio;
GDBHelper gdbHelper = new GDBHelper(RasterResultPath, true);
gdbHelper.DeleteRasterLayer();
gdbHelper.Close();
RC.output_raster = RasterResultPath;
m_GP.Execute(RC, null);
return true;
}
catch (Exception ex)
{
object sev = null;
string str2=m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
/// <summary>
/// 柵格計算器,在這裏會刪掉原來的數據
/// </summary>
/// <param name="baseMapLayer">用於定義範圍</param>
/// <param name="toCutLayers"></param>
/// <param name="radios"></param>
/// <returns></returns>
public bool RasterCalculatorExcutor(IRasterLayer baseMapLayer, string expression)
{
try
{
SetGPEnvironment();
DeleteExistRasterLayer(RasterResultPath);
RasterCalculator RC = new RasterCalculator();
RC.expression = expression;
RC.output_raster = RasterResultPath;
m_GP.Execute(RC, null);
return true;
}
catch (Exception ex)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
/// <summary>
/// 這個是單值的
/// </summary>
/// <param name="baseMapLayer"></param>
/// <param name="toCutLayers">要裁剪的圖層</param>
/// <param name="radios">圖層約減的比例</param>
/// <returns></returns>
public string GetRasterSubtractExpression(RasterLayer baseMapLayer, List<RasterLayer> toCutLayers, List<double> radios)
{
string expression = "\"" + baseMapLayer.FilePath + "\"";
for (var i = 0; i < toCutLayers.Count; i++)
{
expression += "- Con(IsNull(\"" + toCutLayers[i].FilePath + "\"),0,1)*" + radios[i];
}
return expression;
}
/// <summary>
/// radioStep的值是從大到小,比如15,8,2
/// raidoValue是對應的,比如0.4,0.6,0.8
/// 也就是>15的值是0.4
/// 最後的值是1
/// </summary>
/// <param name="toCutLayer"></param>
/// <param name="radioStep"></param>
/// <param name="raidoValue"></param>
/// <param name="globalRadio"></param>
/// <returns></returns>
public string GetRasterSubtractExpression(RasterLayer toCutLayer, double[] radioStep, double[] raidoValue, double globalRadio,bool reverseValue=false,string nullValueExpress="0")
{
StringBuilder sb=new StringBuilder();
sb.Append("Con(IsNull(\"" + toCutLayer.FilePath + "\")," + nullValueExpress + ",");
for (var i = 0; i < radioStep.Length; i++)
{
sb.Append("Con(\"" + toCutLayer.FilePath + "\">" + radioStep[i] + "," + (reverseValue == false ? raidoValue[i] : 1 - raidoValue[i]) + ",");
if (i == radioStep.Length - 1)
sb.Append(reverseValue == false ? "1" : "0");
}
for (var i = 0; i < radioStep.Length; i++)
{
sb.Append(")");
}
sb.Append("*" + globalRadio);
sb.Append(")");
return sb.ToString();
}
/// <summary>
/// 獲得減的算法。
/// </summary>
/// <param name="toCutLayer"></param>
/// <param name="globalRadio"></param>
/// <param name="reverseValue"></param>
/// <param name="nullValueExpress"></param>
/// <returns></returns>
public string GetRasterSubtractExpression(RasterLayer toCutLayer, double globalRadio, bool reverseValue = false, string nullValueExpress = "0")
{
StringBuilder sb = new StringBuilder();
sb.Append("Con(IsNull(\"" + toCutLayer.FilePath + "\")," + nullValueExpress + ",");
if (reverseValue == false)
sb.Append("\"" + toCutLayer.FilePath + "\"");
else
sb.Append("(100-\"" + toCutLayer.FilePath + "\")");
sb.Append(")*" + globalRadio);
return sb.ToString();
}
/// <summary>
/// 獲得分級的表達式
/// </summary>
/// <param name="toCutLayer"></param>
/// <param name="radioStep"></param>
/// <param name="raidoValue"></param>
/// <param name="reverseValue"></param>
/// <returns></returns>
public string GetRasterClassifyExpression(RasterLayer toCutLayer, double[] radioStep, double[] raidoValue, bool reverseValue = false)
{
return GetRasterClassifyExpression(toCutLayer.FilePath, radioStep, raidoValue, reverseValue);
}
/// <summary>
/// 獲得分級的表達式
/// </summary>
/// <param name="toCutLayer"></param>
/// <param name="radioStep"></param>
/// <param name="raidoValue"></param>
/// <param name="reverseValue"></param>
/// <returns></returns>
public string GetRasterClassifyExpression(string layerFilePath, double[] radioStep, double[] raidoValue, bool reverseValue=false)
{
StringBuilder sb = new StringBuilder();
for (var i = 0; i < radioStep.Length; i++)
{
sb.Append("Con(\"" + layerFilePath + "\">" + radioStep[i] + "," + (reverseValue == false ? raidoValue[i] : 1 - raidoValue[i]) + ",");
if (i == radioStep.Length - 1)
sb.Append(reverseValue == false ? raidoValue[raidoValue.Length - 1] : raidoValue[0]);
}
for (var i = 0; i < radioStep.Length; i++)
{
sb.Append(")");
}
return sb.ToString();
}
/// <summary>
/// 二值切割
/// </summary>
/// <param name="layerFilePath"></param>
/// <param name="splitValue"></param>
/// <param name="bigValueExpression"></param>
/// <param name="lessValueExpression"></param>
/// <returns></returns>
public string GetRasterClassifyExpression(string layerFilePath, double splitValue, string bigValueExpression,string lessValueExpression)
{
StringBuilder sb = new StringBuilder();
sb.Append("Con(\"" + layerFilePath + "\">" + splitValue + "," + bigValueExpression + ","+lessValueExpression+")");
return sb.ToString();
}
/// <summary>
/// 空非空切割
/// </summary>
/// <param name="layerFilePath"></param>
/// <param name="notNullExpression"></param>
/// <param name="nulExpression"></param>
/// <returns></returns>
public string GetRasterNotNullExpression(string layerFilePath, string notNullExpression, string nulExpression)
{
StringBuilder sb = new StringBuilder();
sb.Append("Con(IsNull(\"" + layerFilePath + "\")" + "," + nulExpression + "," + notNullExpression + ")");
return sb.ToString();
}
#endregion
#region 柵格-裁剪
/// <summary>
/// 用要素圖層裁剪柵格圖層
/// </summary>
/// <param name="rasterLayer"></param>
/// <param name="featureLayer"></param>
/// <param name="outPutPath"></param>
/// <returns></returns>
public IRasterLayer RasterClip(IRasterLayer rasterLayer, IFeatureLayer featureLayer, string outPutPath)
{
m_GP.OverwriteOutput = true;
IEnvelope envelope = (featureLayer.FeatureClass as IGeoDataset).Extent;
var rectangle = envelope.XMin + " " + envelope.YMin + " " + envelope.XMax + " " + envelope.YMax;
Clip clip = new Clip();
clip.in_raster = rasterLayer;
clip.rectangle = rectangle;
clip.out_raster = outPutPath;
clip.in_template_dataset = featureLayer;
clip.clipping_geometry = "ClippingGeometry";
clip.maintain_clipping_extent = "MAINTAIN_EXTENT";
m_GP.Execute(clip, this.m_cancelHandler);
IRasterLayer resultLayer = RasterHelper.GetRasterLayer(outPutPath);
return resultLayer;
}
#endregion
#region 柵格-數據運算
/// <summary>
/// 乘冪運算
/// </summary>
/// <param name="rasterLayer">需要計算的柵格圖層</param>
/// <param name="index">底數</param>
/// <returns></returns>
public IRasterLayer CaculatorPow(IRasterLayer rasterLayer, double index)
{
IMathOp mathOp = new RasterMathOpsClass();
var geoDataset = mathOp.Power(rasterLayer.Raster as IGeoDataset, index);
IRasterLayer layer = new RasterLayerClass();
layer.CreateFromRaster(geoDataset as IRaster);
return layer;
}
public IRasterLayer Abs(IRasterLayer rasterLayer)
{
IMathOp mathOp = new RasterMathOpsClass();
var geoDataset = mathOp.Abs(rasterLayer.Raster as IGeoDataset);
IRasterLayer layer = new RasterLayerClass();
layer.CreateFromRaster(geoDataset as IRaster);
return layer;
}
/// <summary>
/// 條件判斷Nodata柵格,是Nodata返回1,不是則返回0
/// </summary>
/// <param name="rasterLayer"></param>
/// <returns></returns>
public IRasterLayer GetNullRaster(IRasterLayer rasterLayer)
{
ILogicalOp logicalOp = new RasterMathOpsClass();
IGeoDataset geoDataset = logicalOp.IsNull(rasterLayer.Raster as IGeoDataset);
IRasterLayer resultlayer = new RasterLayerClass();
resultlayer.CreateFromRaster(geoDataset as IRaster);
return resultlayer;
}
#endregion
#region 柵格-矢量轉柵格
public string Rasterify(IFeatureLayer featureLayer, string value_field, string outpath, string cell_assignment, string priority_field, double cellsize, bool useFeatureToRaster = false)
{
SetGPEnvironment();
m_GP.OverwriteOutput = true;
if (useFeatureToRaster)
{
try
{
var gp = new FeatureToRaster();
gp.in_features = featureLayer.FeatureClass;
gp.out_raster = outpath;
gp.field = value_field;
gp.cell_size = cellsize;
DeleteExistRasterLayer(outpath);
var result = m_GP.Execute(gp, this.m_cancelHandler);
return outpath;
}
catch (Exception ex)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
else
{
try
{
var gp = new PolygonToRaster();
gp.in_features = featureLayer;
gp.value_field = value_field;
gp.out_rasterdataset = outpath;
gp.cell_assignment = cell_assignment;
gp.priority_field = priority_field;
gp.cellsize = cellsize;
DeleteExistRasterLayer(outpath);
var result = m_GP.Execute(gp, this.m_cancelHandler);
return outpath;
}
catch (Exception ex)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
}
/// <summary>
/// 使用原生接口進行柵格化
/// </summary>
/// <param name="featureLayer">要素圖層</param>
/// <param name="valueField">柵格化字段名稱</param>
/// <param name="outputRasterFolderPath">輸出tif文件全路徑</param>
/// <param name="cellSize">可選參數|與座標系有關。像元分辨率,默認30</param>
/// <returns></returns>
public IRasterLayer Rasterify(IFeatureLayer featureLayer, string valueField, double cellSize = 30)
{
IConversionOp conversionOp = new RasterConversionOpClass();
IFeatureClassDescriptor descriptor = new FeatureClassDescriptorClass();
descriptor.Create(featureLayer.FeatureClass, null, valueField);
IGeoDataset geoDataset = descriptor as IGeoDataset;
IWorkspaceFactory factoryClass = new RasterWorkspaceFactoryClass();
string outputRasterFolderPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\" + "Rasterify\\";
if(Directory.Exists(outputRasterFolderPath)==false)
{
Directory.CreateDirectory(outputRasterFolderPath);
}
IWorkspace workspace = factoryClass.OpenFromFile(outputRasterFolderPath, 0);
IRasterAnalysisEnvironment rasterAnalysisEnvironment = conversionOp as IRasterAnalysisEnvironment;
rasterAnalysisEnvironment.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, cellSize);
rasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, geoDataset.Extent, null);
string fileName = featureLayer.Name + "柵格";
int index = 0;
while (true)
{
if (File.Exists(System.IO.Path.Combine(outputRasterFolderPath, fileName+".tif")))
{
fileName = featureLayer.Name + "柵格" + (index++);
}
else
{
break;
}
}
IRasterDataset resultDataset = conversionOp.ToRasterDataset(geoDataset, "TIFF", workspace, fileName);
IRasterLayer resultLayer = new RasterLayerClass();
resultLayer.CreateFromDataset(resultDataset);
return resultLayer;
}
#endregion
#region 柵格-重分類
private string ClassifyRasterWithRamap(string rasterLayerPath, string remap, string resultPath = null,string fieldName = "VALUE")
{
try
{
resultPath = resultPath == null ? RasterResultPath + "_reclassify" : resultPath;
DeleteExistRasterLayer(resultPath);
Reclassify reclassify = new Reclassify(rasterLayerPath, "", null, null);
reclassify.missing_values = "NODATA";
reclassify.out_raster = resultPath;
reclassify.reclass_field = fieldName;
if(string.IsNullOrEmpty(remap)==false)
reclassify.remap = remap;
var result = m_GP.Execute(reclassify, m_TrackCancel);
return resultPath;
}
catch (Exception ex)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
public string ClassifyRaster(IRasterLayer rasterLayer, int classCount = 5, bool trimZero = true, string resultPath = null)
{
double max, min;
CommonUtils.GetRasterHelper().GetRasterMinMaxValue(rasterLayer, out max, out min);
string remap = "";
if (trimZero)
{
remap = min + " 0 0";
double step = max / (classCount - 1);
for (var i = 1; i < classCount; i++)
{
remap += ";";
remap += (step * (i - 1)) + " " + (step * i) + " " + i;
}
}
else
{
double step = (max - min) / classCount;
for (var i = 0; i < classCount; i++)
{
if (i != 0)
remap += ";";
remap += (step * i + min) + " " + (step * (i + 1) + min) + " " + i;
}
}
return ClassifyRasterWithRamap(rasterLayer.FilePath, remap, resultPath);
}
public string ClassifyRaster(string rasterLayerPath, int classCount = 5, bool trimZero = true, string resultPath = null)
{
var rasterLayer = GDBHelper.GetRasterLayer(rasterLayerPath, true);
return ClassifyRaster(rasterLayer, classCount, trimZero, resultPath);
}
/// <summary>
/// rasterLayerPath 柵格的路徑
/// fieldsMatch=[{"草地":30},{"林地":50}]
/// </summary>
/// <param name="rasterLayerPath"></param>
/// <param name="fieldsMatch"></param>
/// <param name="resultPath"></param>
/// <returns></returns>
public string ClassifyRaster(string rasterLayerPath, Dictionary<string, int> fieldsMatch, string resultPath = null,string fieldName="VALUE")
{
StringBuilder sb = new StringBuilder();
foreach (string key in fieldsMatch.Keys)
{
if (sb.Length != 0)
sb.Append(";");
sb.Append(key + " " + fieldsMatch[key]);
}
return ClassifyRasterWithRamap(rasterLayerPath, sb.ToString(), resultPath, fieldName);
}
/// <summary>
///
/// </summary>
/// <param name="outpath"></param>
/// <param name="p1"></param>
/// <param name="p2"></param>
public string ClassifyRaster(string rasterLayerPath, string remap, string resultPath = null, string fieldName = "VALUE")
{
return ClassifyRasterWithRamap(rasterLayerPath, remap, resultPath, fieldName);
}
#endregion
#region 柵格-重分類-原生接口
/// <summary>
/// 重分類方法
/// </summary>
/// <param name="layer"></param>
/// <param name="reclassifySubRanges"></param>
public IRasterLayer ReclassifyByRemap(IRasterLayer layer, List<ReclassifySubRange> reclassifySubRanges)
{
double statisticsMinimum;
double statisticsMaximum;
Common.CommonUtils.GetRasterHelper().GetRasterMinMaxValue(layer.Raster, out statisticsMinimum, out statisticsMaximum);
INumberRemap numberRemap = new NumberRemapClass();
IRasterLayer resultLayer = new RasterLayerClass();
if (statisticsMinimum > reclassifySubRanges[0].StartValue || statisticsMaximum < reclassifySubRanges[reclassifySubRanges.Count].EndValue)
{
// 重新調整重分類子範圍列表
int newStartSubRangeIndex = 0;
int newEndSubRangeIndex = reclassifySubRanges.Count;
for (int i = 0; i < reclassifySubRanges.Count; i++)
{
if (statisticsMinimum < reclassifySubRanges[i].StartValue)
{
newStartSubRangeIndex = i - 1;
break;
}
else
continue;
}
for (int i = 0; i < reclassifySubRanges.Count; i++)
{
if (statisticsMaximum < reclassifySubRanges[i].EndValue)
{
newEndSubRangeIndex = i;
break;
}
else
continue;
}
List<ReclassifySubRange> newReclassifySubRange = reclassifySubRanges.GetRange(newStartSubRangeIndex, newEndSubRangeIndex - newStartSubRangeIndex + 1);
for (int i = 0; i < newReclassifySubRange.Count; i++)
{
numberRemap.MapRange(newReclassifySubRange[i].StartValue, newReclassifySubRange[i].EndValue, newReclassifySubRange[i].ReclassifyValue);
}
IReclassOp reclassOp = new RasterReclassOpClass();
IRaster resultRaster = reclassOp.ReclassByRemap(layer as IGeoDataset, numberRemap as IRemap, false) as IRaster;
resultLayer.CreateFromRaster(resultRaster);
}
else
{
for (int i = 0; i < reclassifySubRanges.Count; i++)
{
numberRemap.MapRange(reclassifySubRanges[i].StartValue, reclassifySubRanges[i].EndValue, reclassifySubRanges[i].ReclassifyValue);
}
IReclassOp reclassOp = new RasterReclassOpClass();
IRaster resultRaster = reclassOp.ReclassByRemap(layer.Raster as IGeoDataset, numberRemap as IRemap, false) as IRaster;
resultLayer.CreateFromRaster(resultRaster);
}
return resultLayer;
}
#endregion
#region 柵格-由要素圖層裁剪
/// <summary>
/// 由要素圖層裁剪柵格[未測試]
/// </summary>
public IRasterLayer ClipByFeatureLayer(IRasterLayer inputLayer, IFeatureLayer maskLayer, string outputRasterPath)
{
if (maskLayer == null)
{
return inputLayer;
}
SetGPEnvironment();
m_GP.OverwriteOutput = true;
ExtractByMask extract = new ExtractByMask() {
in_mask_data = maskLayer, in_raster = inputLayer, out_raster = outputRasterPath
};
m_GP.Execute(extract, this.m_cancelHandler);
IRasterLayer resultLayer = RasterHelper.GetRasterLayer(outputRasterPath);
return resultLayer;
}
#endregion
#region 柵格-求空間並集
/// <summary>
/// 獲得並集的表達式
/// </summary>
/// <param name="layer1Expression"></param>
/// <param name="layer2Expression"></param>
/// <returns></returns>
public string GetRasterUnionExpression(string layer1Expression,string layer2Expression)
{
string exrepssion = "Con((" + layer1Expression + "+" + layer2Expression + ")>0,1,0)";
return exrepssion;
}
#endregion
#region 柵格-局域統計-求和
public string BlockStatisticsRaster(string rasterFilePath, string neighborhoodMeth = "RECTANGLE", int width = 3, string statisticsType = "SUM", string resultPath=null)
{
try
{
SetGPEnvironment();
resultPath = resultPath == null ? RasterResultPath + "_blockSts" : resultPath;
BlockStatistics bs = new BlockStatistics(rasterFilePath, resultPath);
bs.neighborhood = neighborhoodMeth + " " + width + " " + width + " CELL";
bs.statistics_type = statisticsType;
m_GP.Execute(bs, this.m_TrackCancel);
return resultPath;
}
catch (Exception err)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
public IRasterLayer ComputeFocalStatistics(IRasterLayer param, esriGeoAnalysisStatisticsEnum type, int nbrSize = 3)
{
IRasterNeighborhood nbrhood = new RasterNeighborhoodClass();
if (nbrSize == 3)
nbrhood.SetDefault();
else
nbrhood.SetRectangle((double)nbrSize, (double)nbrSize, esriGeoAnalysisUnitsEnum.esriUnitsCells);
IRasterLayer result = new RasterLayerClass();
result.CreateFromRaster(new RasterNeighborhoodOpClass().FocalStatistics(param.Raster as IGeoDataset, type, nbrhood, true) as IRaster);
return result;
}
#endregion
#region 柵格-直方圖統計
/// <summary>
/// 根據區域生成統計表
/// </summary>
/// <param name="in_zone_Layer">包含區域的圖層</param>
/// <param name="in_value_raster">要統計的柵格</param>
/// <param name="zoneField">要統計的區域字段</param>
/// <param name="tableName"></param>
/// <returns></returns>
public DataTable ZonalHistogram(IFeatureLayer in_zone_Layer, IRasterLayer in_value_raster, string zoneField, string GDBPath,string tableName)
{
m_GP.OverwriteOutput = true;
ZonalHistogram zonalHistogram = new ZonalHistogram();
zonalHistogram.in_zone_data = in_zone_Layer;
zonalHistogram.zone_field = zoneField;
zonalHistogram.in_value_raster = in_value_raster;
zonalHistogram.out_table = GDBPath + "\\" + tableName;
m_GP.Execute(zonalHistogram, null);
var gdbHelper = new GDBHelper(GDBPath);
gdbHelper.Open();
IFeatureWorkspace featureWorkspace = gdbHelper.WorkSpace;
ITable table = featureWorkspace.OpenTable(tableName);
DataTable dataTable = MyDataConverter.ConvertToDataTable(table);
gdbHelper.Close();
return dataTable;
}
#endregion
#region 柵格-分區統計
/// <summary>
/// 按區域統計柵格信息
/// </summary>
/// <param name="in_zone_Layer"></param>
/// <param name="in_value_raster"></param>
/// <param name="zoneField"></param>
/// <param name="GDBPath"></param>
/// <param name="tableName"></param>
/// <returns></returns>
public DataTable ZonalStatisticsAsTable(IFeatureLayer in_zone_Layer, IRasterLayer in_value_raster, string zoneField, string GDBPath, string tableName)
{
m_GP.OverwriteOutput = true;
ZonalStatisticsAsTable zonalStatistics = new ZonalStatisticsAsTable();
zonalStatistics.in_zone_data = in_zone_Layer;
zonalStatistics.zone_field = zoneField;
zonalStatistics.in_value_raster = in_value_raster;
zonalStatistics.out_table = GDBPath + "\\"+tableName;
m_GP.Execute(zonalStatistics, m_TrackCancel);
var gdbHelper = new GDBHelper(GDBPath);
gdbHelper.Open();
IFeatureWorkspace featureWorkspace = gdbHelper.WorkSpace;
ITable table = featureWorkspace.OpenTable(tableName);
DataTable dataTable = MyDataConverter.ConvertToDataTable(table);
gdbHelper.Close();
return dataTable;
}
#endregion
#region 柵格-求衆數
public IRasterLayer ComputerCellStatistics(string rasterLayerDir,List<string> rasterLayerNames,string resultFileName,string statisticsType="MAJORITY")
{
try
{
m_GP.OverwriteOutput = true;
m_GP.SetEnvironmentValue("workspace", rasterLayerDir);
m_GP.SetEnvironmentValue("extent", System.IO.Path.Combine(rasterLayerDir, rasterLayerNames[0]));
m_GP.SetEnvironmentValue("cellsize", 30);
var cellStatistics = new CellStatistics();
cellStatistics.in_rasters_or_constants = String.Join(";", rasterLayerNames.ToArray());
cellStatistics.out_raster = resultFileName;
cellStatistics.statistics_type = statisticsType;
cellStatistics.ignore_nodata = "DATA";
m_GP.RegisterGeoProcessorEvents(this.m_TrackCancel.Progressor as IGeoProcessorEvents);
m_GP.Execute(cellStatistics, this.m_TrackCancel);
var layer = RasterHelper.GetRasterLayer((string)(cellStatistics.out_raster));
return layer;
}
catch (Exception)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
#endregion
#region 柵格-填窪
public void Fill(RasterLayer baseMapLayer,double z=double.Epsilon)
{
try
{
SetGPEnvironment();
ESRI.ArcGIS.SpatialAnalystTools.Fill fill = new Fill();
fill.in_surface_raster = baseMapLayer;
fill.out_surface_raster = RasterResultPath;
if (z > double.Epsilon)
fill.z_limit = z;
m_GP.Execute(fill, null);
}
catch (Exception ex)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
#endregion
#region 柵格-坡向
/// <summary>
/// 柵格/DEM轉坡向圖
/// </summary>
public void RasterGetAspect(IRasterLayer baseMapLayer, bool autoSetRender = false)
{
try
{
if (m_cancelHandler != null)
{
m_cancelHandler.SetWaitingMessage("正在計算坡向...");
}
SetGPEnvironment();
var tAspect = new Aspect();
tAspect.in_raster = baseMapLayer;
tAspect.out_raster = RasterResultPath;
m_GP.Execute(tAspect, null);
}
catch (Exception)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
#endregion
#region 柵格-坡度
/// <summary>
/// 柵格/DEM轉坡度圖
/// </summary>
public void ComputeSlope(IRasterLayer baseMapLayer,string saveFileName, string measurement="DEGREE",float zFactorScale=1)
{
try
{
if (m_cancelHandler != null)
{
m_cancelHandler.SetWaitingMessage("正在計算坡度...");
}
SetGPEnvironment();
ESRI.ArcGIS.SpatialAnalystTools.Slope tSlope = new Slope();
tSlope.in_raster = baseMapLayer;
tSlope.out_raster = saveFileName;
tSlope.output_measurement = measurement;
tSlope.z_factor = zFactorScale;
m_GP.Execute(tSlope, null);
}
catch (Exception)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
public void ComputeSlope(IRasterLayer baseMapLayer, string saveFileName, bool isDegree, float zFactorScale = 1)
{
ComputeSlope(baseMapLayer, saveFileName, isDegree ? "DEGREE" : "PERCENT_RISE", zFactorScale);
}
#endregion
#region 柵格-距離
public IRasterLayer ComputeEucDistance(IRasterLayer roadLayer,string file)
{
try
{
var compute = new ESRI.ArcGIS.SpatialAnalystTools.EucDistance();
compute.in_source_data = roadLayer;
compute.out_distance_raster = file;
m_GP.Execute(compute, this.m_cancelHandler);
IRasterLayer layer = new RasterLayerClass();
layer.CreateFromFilePath(file);
return layer;
}
catch (Exception)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
#endregion
#region 柵格-整型
/// <summary>
/// 柵格轉整型(柵格的值是浮點型時無法轉出面)
/// </summary>
public void RasterValueToInt(object pInputRaster)
{
try
{
if (m_cancelHandler != null)
{
m_cancelHandler.SetWaitingMessage("浮點型柵格轉爲整形...");
}
SetGPEnvironment();
ESRI.ArcGIS.SpatialAnalystTools.Int tInt = new Int();
tInt.in_raster_or_constant = pInputRaster;
tInt.out_raster = RasterResultPath;
m_GP.Execute(tInt, null);
}
catch (Exception)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
#endregion
#region 柵格-轉面
/// <summary>
/// 柵格轉要素面
/// </summary>
public IFeatureClass RasterConvertFeaPolygon(IRasterLayer baseMapLayer)
{
try
{
SetGPEnvironment();
if (m_cancelHandler != null)
{
m_cancelHandler.SetWaitingMessage("柵格轉要素面...");
}
ESRI.ArcGIS.ConversionTools.RasterToPolygon tRasterToPolygon = new RasterToPolygon();
tRasterToPolygon.in_raster = baseMapLayer;
tRasterToPolygon.raster_field = "VALUE";
tRasterToPolygon.out_polygon_features = RasterResultPath;
tRasterToPolygon.simplify = "SIMPLIFY";
IGeoProcessorResult gpResult =
m_GP.Execute(tRasterToPolygon as IGPProcess, m_TrackCancel) as IGeoProcessorResult;
return DecodeResultClass(gpResult);
}
catch (Exception err) { LogGPMessage(); if (m_throwException) throw err; return null; }
}
#endregion
#region 插值-IDW
/// <summary>
/// 反距離權重(IDW)插值 不檢查要素類及其他數據的質量,請在調用前做好異常處理
/// </summary>
/// <param name="layer">待插值的點要素圖層</param>
/// <param name="regionLayer">插值範圍區域圖層</param>
/// <param name="interpolationFieldName">待插值字段</param>
/// <param name="power">可選參數|反距離的階數,默認2階,1~12階可選</param>
/// <param name="cellSize">可選參數|插值結果柵格的像元分辨率, 默認30</param>
/// <param name="searchRadiusPointCount">可選參數|插值時搜索的半徑點數, 默認12個</param>
public IRasterLayer IDW(IFeatureLayer layer, IFeatureLayer regionLayer,string interpolationFieldName,int power = 2,float cellSize = 30,int searchRadiusPointCount = 12)
{
return IDW(layer.FeatureClass, regionLayer, interpolationFieldName, power, cellSize, searchRadiusPointCount);
}
public IRasterLayer IDW(IFeatureClass featureClass, IFeatureLayer regionLayer, string interpolationFieldName, int power = 2, float cellSize = 30, int searchRadiusPointCount = 12)
{
IInterpolationOp _interpolationOp = new RasterInterpolationOpClass();
// 設置要素類描述對象
IFeatureClassDescriptor featureClassDescriptor = new FeatureClassDescriptorClass();
featureClassDescriptor.Create(featureClass, null, interpolationFieldName);
// 設置搜索半徑點數
IRasterRadius rasterRadius = new RasterRadiusClass();
rasterRadius.SetVariable(searchRadiusPointCount, null);
// 設置柵格分析環境
IRasterAnalysisEnvironment rasterAnalysisEnvironment = _interpolationOp as IRasterAnalysisEnvironment;
rasterAnalysisEnvironment.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, cellSize as object);
rasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, (regionLayer.FeatureClass as IGeoDataset).Extent as object, null);
rasterAnalysisEnvironment.Mask = regionLayer.FeatureClass as IGeoDataset;
// 執行分析
IGeoDataset geoDataset = _interpolationOp.IDW(featureClassDescriptor as IGeoDataset, power, rasterRadius, null);
IRasterLayer resultLayer = new RasterLayerClass();
resultLayer.CreateFromRaster(geoDataset as IRaster);
return resultLayer;
}
#endregion
#region 插值-趨勢面
/// <summary>
/// 趨勢面插值 默認使用最鄰近插值,階數默認4階
/// </summary>
/// <param name="layer">待插值要素圖層</param>
/// <param name="regionLayer">插值範圍圖層</param>
/// <param name="interpolationFieldName">待插值的字段名</param>
/// <param name="trendType">可選參數|迴歸方法, 默認執行多項式迴歸</param>
/// <param name="order">可選參數|階數,1~12階可選,默認3階,越高越平滑但是耗時越長</param>
/// <param name="cellSize">可選參數|插值結果柵格的像元分辨率, 默認30</param>
public IRasterLayer Trend(IFeatureLayer layer,IFeatureLayer regionLayer,string interpolationFieldName,esriGeoAnalysisTrendEnum trendType= esriGeoAnalysisTrendEnum.esriGeoAnalysisLinearTrend,int order = 4,double cellSize = 30)
{
IInterpolationOp _interpolationOp = new RasterInterpolationOpClass();
// 設置要素類描述對象
IFeatureClassDescriptor featureClassDescriptor = new FeatureClassDescriptorClass();
featureClassDescriptor.Create(layer.FeatureClass, null, interpolationFieldName);
// 設置柵格分析環境
IRasterAnalysisEnvironment rasterAnalysisEnvironment = _interpolationOp as IRasterAnalysisEnvironment;
rasterAnalysisEnvironment.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, cellSize as object);
rasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, (regionLayer.FeatureClass as IGeoDataset).Extent as object, null);
rasterAnalysisEnvironment.Mask = regionLayer.FeatureClass as IGeoDataset;
IRaster result = _interpolationOp.Trend(
featureClassDescriptor as IGeoDataset,
trendType, order) as IRaster;
IRasterLayer resultLayer = new RasterLayerClass();
resultLayer.CreateFromRaster(result);
return resultLayer;
}
#endregion
#region 選擇對象
private FeatureLayerClass ApplyQueryFilter(IFeatureClass pFeatureClass, IQueryFilter pQueryFilter)
{
FeatureLayerClass pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.Name = pFeatureClass.AliasName;
pFeatureLayer.FeatureClass = pFeatureClass;
if (pQueryFilter != null)
{
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
}
return pFeatureLayer;
}
#endregion
#region 複製圖層
/// <summary>
/// 通過原路徑複製圖層到目標路徑
/// </summary>
/// <param name="sourceLayerPath"></param>
/// <param name="targetLayerPath"></param>
public bool CopyLayer(string sourceLayerPath,string targetLayerPath)
{
SetGPEnvironment();
try
{
if (!ReleaseLock(sourceLayerPath))
{
MessageBox.Show("嘗試關閉資源鎖定時異常");
return false;
}
else
{
var copyLayerTool = new ESRI.ArcGIS.DataManagementTools.Copy(sourceLayerPath, targetLayerPath);
m_GP.Execute(copyLayerTool, m_TrackCancel);
return true;
}
}
catch (Exception err)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
#endregion
#region 刪除圖層
public bool DeleteLayer(string targetLayerPath)
{
SetGPEnvironment();
try
{
if (!ReleaseLock(targetLayerPath))
{
return false;
}
else
{
var deleteLayer = new ESRI.ArcGIS.DataManagementTools.Delete(targetLayerPath);
m_GP.Execute(deleteLayer, m_TrackCancel);
return true;
}
}
catch (Exception)
{
object sev = null;
string str2 = m_GP.GetMessages(ref sev);
throw new Exception(str2);
}
}
#endregion
#region 設置GP的環境變量
/// <summary>
/// 設置GP的環境變量
/// </summary>
private void SetGPEnvironment()
{
object obj = null;
if (m_GP == null) return;
m_GP.ClearMessages();
m_GP.OverwriteOutput = base.OverwriteOutput;
obj = m_GP.GetEnvironmentValue("OutputZFlag");
m_GP.SetEnvironmentValue("OutputZFlag", base.ZFlag.ToString());
obj = m_GP.GetEnvironmentValue("OutputMFlag");
m_GP.SetEnvironmentValue("OutputMFlag", base.MFlag.ToString());
}
/// <summary>
/// 設置GP工具的分析範圍
/// </summary>
/// <param name="layer"></param>
public void SetGPEnvironment(IRasterLayer layer)
{
SetGPEnvironment();
m_GP.SetEnvironmentValue("Extent", layer.FilePath);
}
/// <summary>
/// 設置GP工具的工作環境
/// </summary>
/// <param name="filePath"></param>
public void SetGPWorkspace(string filePath)
{
m_GP.SetEnvironmentValue("workspace", filePath);
}
/// <summary>
/// 設置研究的範圍
/// </summary>
/// <param name="layerExtent"></param>
public void SetGPMask(IRasterLayer layer)
{
m_GP.SetEnvironmentValue("Mask", layer.FilePath);
}
private void DeleteExistRasterLayer(string filePath)
{
GDBHelper gdbHelper = new GDBHelper(filePath, true);
gdbHelper.DeleteRasterLayer();
gdbHelper.Close();
}
/// <summary>
/// 顯示GP的消息
/// </summary>
/// <param name="gp"></param>
/// <param name="showMessageBox"></param>
/// <returns></returns>
public static string ShowGPFileMessage(Geoprocessor gp,bool showMessageBox=true)
{
object sev = null;
string str2 = gp.GetMessages(ref sev);
if (showMessageBox)
{
if(str2!=null)
MessageBox.Show(str2);
else
MessageBox.Show("處理出錯.ESRI沒有告訴我原因,沒人知道");
}
return str2;
}
#endregion
#region 其他
private static int m_cellNo = 0;
public void SetClipResultPathRandomName()
{
string randomName = DateTime.Now.ToString("hhmmss") + (m_cellNo++);
ClipResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\CATemp_Clip" + randomName;
}
public void SetUnionResultPathRandomName()
{
string randomName = DateTime.Now.ToString("hhmmss") + (m_cellNo++);
UnionResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Uinon" + randomName;
}
public void SetBufferResultPathRandomName()
{
string randomName = DateTime.Now.ToString("hhmmss") + (m_cellNo++);
BufferResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Buffer" + randomName;
}
public void SetIntersectResultPathRandomName()
{
string randomName = DateTime.Now.ToString("hhmmss") + (m_cellNo++);
IntersectResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Intersect" + randomName;
}
/// <summary>
/// 設置柵格的隨機名稱
/// </summary>
/// <returns></returns>
public string SetRasterResultPathPathRandomName()
{
string randomName = DateTime.Now.ToString("HHmmss") + (m_cellNo++);
RasterResultPath = AG.COM.SDM.Utility.CommonConstString.STR_TempPath + "\\CATemp.gdb\\Raster" + randomName;
return RasterResultPath;
}
void ExampleUsingValueTables(Geoprocessor GP)
{
// Create a value table with two columns.
IGpValueTableObject vtobject = new GpValueTableObjectClass();
vtobject.SetColumns(2);
// Iterate the enumeration of feature classes and add them to the value table.
// In this case, the inputs and ranks are being set for Intersect.
GP.SetEnvironmentValue("workspace", @"C:\GP\PortlandOR.gdb");
IGpEnumList fcColl = GP.ListFeatureClasses("*", "POLYLINE", "");
string inputfeatures = fcColl.Next();
object row = "";
while (inputfeatures != "")
{
if (inputfeatures == "streets")
{
row = inputfeatures + " 1";
vtobject.AddRow(ref row);
}
else
{
row = inputfeatures + " 2";
vtobject.AddRow(ref row);
}
inputfeatures = fcColl.Next();
}
IVariantArray pVarArray = new VarArrayClass();
pVarArray.Add(vtobject);
pVarArray.Add("C:\\Gp\\PortlandOR.gdb\\streets_bike");
// Execute the Intersect tool.
GP.Execute("intersect_analysis", pVarArray, null);
}
private string LogGPMessage()
{
StringBuilder builder = new StringBuilder();
if (m_GP != null)
{
for (int i = 0; i < m_GP.MessageCount; i++)
{
builder.Append(m_GP.GetMessage(i));
}
m_GP.ClearMessages();
}
return builder.ToString();
}
IFeatureClass DecodeResultClass(IGeoProcessorResult gpResult)
{
IQueryFilter pQueryFilter = null;
IFeatureClass pFeatureClass = null;
IGPUtilities gpUtilities = new GPUtilitiesClass();
gpUtilities.DecodeFeatureLayer(gpResult.GetOutput(0), out pFeatureClass, out pQueryFilter);
return pFeatureClass;
}
ILayer DecodeResultILayer(IGeoProcessorResult gpResult)
{
ILayer layer = null;
IGPUtilities gpUtilities = new GPUtilitiesClass();
if (gpUtilities.Exists(gpResult.GetOutput(0)))
layer = gpUtilities.DecodeLayer(gpResult.GetOutput(0));
return layer;
}
#endregion
#region 釋放
/// <summary>
/// 釋放方案鎖
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private bool ReleaseLock(string path)
{
IWorkspaceFactory2 ipWsFactory = null;
IWorkspaceFactoryLockControl ipWsFactoryLock = null;
IWorkspace ipWorkspace = null;
string layername = string.Empty;
string fileworkspace = string.Empty;
try
{
bool isscuceed= AnalysisPath(path, ref fileworkspace, ref layername);
if (isscuceed == false) return false;
string extension = System.IO.Path.GetExtension(fileworkspace);
switch (extension)
{
case ".gdb":
ipWsFactory = new FileGDBWorkspaceFactoryClass();
break;
case ".shp":
ipWsFactory = new ShapefileWorkspaceFactoryClass();
break;
case ".mdb":
ipWsFactory = new AccessWorkspaceFactoryClass();
break;
default:
break;
}
//獲取資源鎖定
ipWsFactoryLock = (IWorkspaceFactoryLockControl)ipWsFactory;
if (ipWsFactoryLock.SchemaLockingEnabled)
{
ipWsFactoryLock.DisableSchemaLocking();
}
String strConn = "DATABASE=" + fileworkspace;
ipWorkspace = ipWsFactory.OpenFromString(strConn, 0);
ReleaseLayer(ipWorkspace, layername);
return true;
}
catch
{
return false;
}
finally
{
CommonUtils.CloseComObject(ipWorkspace);
CommonUtils.CloseComObject(ipWsFactory);
CommonUtils.CloseComObject(ipWsFactoryLock);
}
}
private bool AnalysisPath(string path,ref string workSpacePath,ref string layerName)
{
try
{
if (String.IsNullOrEmpty(path))
return false;
if (Regex.Match(path, @"\S*.shp").ToString() != "")
{
workSpacePath = Regex.Match(path, @"\S*.shp").ToString();
layerName = path.Substring(path.LastIndexOf("\\") + 1);
layerName = layerName.Replace(".shp","");
}
else if (Regex.Match(path, @"\S*.gdb").ToString() != "")
{
workSpacePath = Regex.Match(path, @"\S*.gdb").ToString();
layerName = path.Substring(path.LastIndexOf("\\") + 1);
}
else if (Regex.Match(path, @"\S*.mdb").ToString() != "")
{
workSpacePath = Regex.Match(path, @"\S*.mdb").ToString();
layerName = path.Substring(path.LastIndexOf("\\") + 1);
}
return true;
}
catch (Exception)
{
return false;
}
}
private bool ReleaseLayer(IWorkspace ipWorkSpace,string layerName)
{
if (ReleaseIFeatureClass(ipWorkSpace, layerName))
{
return true;
}
else if (ReleaseIRaster(ipWorkSpace, layerName))
{
return true;
}
else
{
return false;
}
}
private bool ReleaseIFeatureClass(IWorkspace ipWorkspace, string layerName)
{
//如果是矢量數據
IFeatureWorkspace featureWorkSpace = null;
IFeatureClass pFeatureClass = null;
try
{
featureWorkSpace = ipWorkspace as IFeatureWorkspace;
pFeatureClass = featureWorkSpace.OpenFeatureClass(layerName);
return true;
}
catch (Exception)
{
return false;
}
finally
{
CommonUtils.CloseComObject(pFeatureClass);
CommonUtils.CloseComObject(featureWorkSpace);
}
}
private bool ReleaseIRaster(IWorkspace ipWorkSpace, string layerName)
{
//如果是柵格數據
IRasterWorkspace pRasterWorkspace = null;
IRasterDataset pRasterDataset = null;
try
{
pRasterWorkspace = ipWorkSpace as IRasterWorkspace;
pRasterDataset = pRasterWorkspace.OpenRasterDataset(layerName);
return true;
}
catch (Exception)
{
return false;
}
finally
{
CommonUtils.CloseComObject(pRasterDataset);
CommonUtils.CloseComObject(pRasterWorkspace);
}
}
#endregion
}
public interface IGeoTopology
{
void DropZ(IGeometry geo);
void DropM(IGeometry geo);
IGeometry Union(IGeometry source, IGeometry other);
IGeometry Union<T>(List<T> lst) where T : IGeometry;
IGeometry Union(IGeometryArray geoArray);
IGeometry Union(IEnumGeometry geoEnum);
IGeometry Erase(IGeometry source, IGeometry byother);
IGeometry Interset(IGeometry source, IGeometry other);
IGeometry SymmetricDifference(IGeometry source, IGeometry other);
void Simplify(IGeometry target);
}
public class GeoTopology : EnvironmentClass, IGeoTopology
{
void Prepare(IGeometry source, IGeometry other, ref IGeometry pClone1, ref IGeometry pClone2)
{
pClone1 = (source as IClone).Clone() as IGeometry;
pClone2 = (other as IClone).Clone() as IGeometry;
if (pClone1.SpatialReference != pClone2.SpatialReference)
{
if (pClone1.SpatialReference == null
|| String.IsNullOrEmpty(pClone1.SpatialReference.Name)
|| pClone1.SpatialReference.Name.ToUpper().Contains("UNKNOW"))
{
pClone1.SpatialReference = pClone2.SpatialReference;
}
else
{
pClone2.SpatialReference = pClone1.SpatialReference;
}
}
ITopologicalOperator2 pToplogicalOperator1 = pClone1 as ITopologicalOperator2;
pToplogicalOperator1.IsKnownSimple_2 = false;
try
{
pToplogicalOperator1.Simplify();
}
catch { }
pClone1.SnapToSpatialReference();
ITopologicalOperator2 pToplogicalOperator2 = pClone2 as ITopologicalOperator2;
pToplogicalOperator2.IsKnownSimple_2 = false;
pToplogicalOperator2.Simplify();
pClone2.SnapToSpatialReference();
}
#region IGeoTopology 成員
public void DropZ(IGeometry geo)
{
IZAware pZAware = geo as IZAware;
if (pZAware == null) return;
if (pZAware.ZAware)
{
pZAware.DropZs();
pZAware.ZAware = false;
}
}
public void DropM(IGeometry geo)
{
IMAware pMAware = geo as IMAware;
if (pMAware == null) return;
if (pMAware.MAware)
{
pMAware.DropMs();
pMAware.MAware = false;
}
}
public IGeometry Union(IGeometry source, IGeometry other)
{
IGeometry pClone1 = null;
IGeometry pClone2 = null;
IGeometry output = null;
try
{
Prepare(source, other, ref pClone1, ref pClone2);
ITopologicalOperator2 pToplogicalOperator1 = pClone1 as ITopologicalOperator2;
output = pToplogicalOperator1.Union(pClone2);
}
catch (Exception err) { output = null; if (m_throwException) throw err; }
finally
{
if (pClone1 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone1);
if (pClone2 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone2);
}
return output;
}
public IGeometry Union<T>(List<T> lst) where T : IGeometry
{
try
{
if (lst == null || lst.Count < 1) return null;
if (lst.Count == 1) return lst[0];
object missing = Type.Missing;
ITopologicalOperator2 temp = null;
IGeometryCollection geoEnum = new GeometryBagClass();
for (int i = 0; i < lst.Count; i++)
{
temp = lst[i] as ITopologicalOperator2;
if (!temp.IsKnownSimple) temp.Simplify();
geoEnum.AddGeometry(temp as IGeometry, ref missing, ref missing);
}
return Union(geoEnum as IEnumGeometry);
}
catch (Exception err) { if (m_throwException) throw err; return null; }
}
public IGeometry Union(IGeometryArray geoArray)
{
try
{
if (geoArray == null || geoArray.Count < 1) return null;
if (geoArray.Count == 1) return geoArray.get_Element(0);
object missing = Type.Missing;
ITopologicalOperator2 temp = null;
IGeometryCollection geoEnum = new GeometryBagClass();
for (int i = 0; i < geoArray.Count; i++)
{
temp = geoArray.get_Element(i) as ITopologicalOperator2;
if (!temp.IsKnownSimple) temp.Simplify(); //確保每個圖形Simple化(假如Polygon的面積爲負,則返回永遠是Empty圖形)
geoEnum.AddGeometry(temp as IGeometry, ref missing, ref missing);
}
return Union(geoEnum as IEnumGeometry);
}
catch (Exception err) { if (m_throwException) throw err; return null; }
}
public IGeometry Union(IEnumGeometry geoEnum)
{
try
{
if (geoEnum == null || geoEnum.Count < 1) return null;
IGeometry geo = null;
geoEnum.Reset();
IGeometry src = geoEnum.Next();
geoEnum.Reset();
if (geoEnum.Count == 1) return src;
switch (src.GeometryType)
{
case esriGeometryType.esriGeometryPolygon:
geo = new PolygonClass();
break;
case esriGeometryType.esriGeometryPolyline:
geo = new PolylineClass();
break;
case esriGeometryType.esriGeometryPoint:
geo = new PointClass();
break;
default:
throw new Exception("不支持類型" + src.GeometryType.ToString());
}
ITopologicalOperator2 unionTopo = geo as ITopologicalOperator2;
unionTopo.ConstructUnion(geoEnum as IEnumGeometry);
return geo;
}
catch (Exception err) { if (m_throwException) throw err; return null; }
}
public IGeometry Erase(IGeometry source, IGeometry byother)
{
IGeometry pClone1 = null;
IGeometry pClone2 = null;
IGeometry output = null;
try
{
Prepare(source, byother, ref pClone1, ref pClone2);
ITopologicalOperator2 pToplogicalOperator1 = pClone1 as ITopologicalOperator2;
output = pToplogicalOperator1.Difference(pClone2);
}
catch (Exception err) { output = null; if (m_throwException) throw err; }
finally
{
if (pClone1 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone1);
if (pClone2 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone2);
}
return output;
}
public IGeometry Interset(IGeometry source, IGeometry other)
{
IGeometry pClone1 = null;
IGeometry pClone2 = null;
IGeometry output = null;
try
{
Prepare(source, other, ref pClone1, ref pClone2);
ITopologicalOperator2 pToplogicalOperator1 = pClone1 as ITopologicalOperator2;
int dimension = Math.Min((int)pClone1.Dimension, (int)pClone2.Dimension);
output = pToplogicalOperator1.Intersect(pClone2, (esriGeometryDimension)dimension);
}
catch (Exception err) { output = null; if (m_throwException) throw err; }
finally
{
if (pClone1 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone1);
if (pClone2 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone2);
}
return output;
}
public IGeometry SymmetricDifference(IGeometry source, IGeometry other)
{
IGeometry pClone1 = null;
IGeometry pClone2 = null;
IGeometry output = null;
try
{
Prepare(source, other, ref pClone1, ref pClone2);
ITopologicalOperator2 pToplogicalOperator1 = pClone1 as ITopologicalOperator2;
output = pToplogicalOperator1.SymmetricDifference(pClone2);
}
catch (Exception err) { output = null; if (m_throwException) throw err; }
finally
{
if (pClone1 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone1);
if (pClone2 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pClone2);
}
return output;
}
public void Simplify(IGeometry target)
{
/*拓撲簡單化
* 點:無操作;
* 多點:去除重複點
* 線:Planarize操作,在交點處打斷,去除重複的
* 面:去除重複,生成島洞
* 詳請見幫助文件
**/
if (target == null || target.IsEmpty) return;
ITopologicalOperator2 pTopologicalOperator = target as ITopologicalOperator2;
if (pTopologicalOperator == null) return;
pTopologicalOperator.IsKnownSimple_2 = false;
pTopologicalOperator.Simplify();
}
#endregion
}
public enum JoinAttributesType
{
NO_FID,
ONLY_FID,
ALL
}
public enum SpatialJoinOperation
{
JOIN_ONE_TO_ONE,
JOIN_ONE_TO_MANY
}
public enum MatchOption
{
INTERSECT,
CONTAINS,
WITHIN
}
public interface IProgressStyleSetup
{
ProgressBarStyle BarStyle { get; set; }
}
public interface IEnumInvalidDataset
{
void Reset();
IInvalidDatasetInfo Next();
}
public interface IClassNameChecker
{
/// <summary>
/// 目標工作空間
/// </summary>
IWorkspace ValidateWorkspace { set; }
/// <summary>
/// 重寫要素類
/// </summary>
/// <param name="cName"></param>
/// <returns></returns>
bool Overwrite(string cName);
/// <summary>
/// 檢查名稱是否已存在
/// </summary>
/// <param name="cName"></param>
/// <returns></returns>
bool NameIsExist(string cName);
/// <summary>
/// 驗證名稱字符是否符合
/// </summary>
/// <param name="cName"></param>
/// <param name="fixedName"></param>
/// <param name="errMsg"></param>
/// <returns></returns>
bool Validate(string cName, out string fixedName, out string errMsg);
/// <summary>
/// 自動修正名稱
/// </summary>
/// <param name="cName"></param>
/// <returns></returns>
string AutoRevise(string cName);
/// <summary>
/// 自動修正名稱
/// </summary>
/// <param name="names"></param>
/// <returns></returns>
string[] AutoRevise(string[] names);
}
public class InvalidDatasetInfoClass : IInvalidDatasetInfo
{
private IEnumInvalidObject m_EnumInvalidObject = null;
private string m_ErrorDescription = "";
private string m_InvalidName = "";
#region 構造函數
public InvalidDatasetInfoClass(string err, string name)
{
m_ErrorDescription = err;
m_InvalidName = name;
}
public InvalidDatasetInfoClass
(string err, string name, IEnumInvalidObject pEnumInvalidObject)
: this(err, name)
{
m_EnumInvalidObject = pEnumInvalidObject;
}
#endregion
#region IInvalidDataInfo 成員
public string ErrorDescription
{
get { return m_ErrorDescription; }
}
public string InvalidName
{
get { return m_InvalidName; }
}
public IEnumInvalidObject EnumInvalidObject
{
get { return m_EnumInvalidObject; }
}
#endregion
}
public class ClassNameChecker : IClassNameChecker
{
private IWorkspace m_ValidateWS = null;
#region IClassNameChecker 成員
public IWorkspace ValidateWorkspace
{
set { m_ValidateWS = value; }
}
public bool Overwrite(string cName)
{
if (m_ValidateWS == null) return false;
try
{
if (NameIsExist(cName))
{
IFeatureClass pFeatureClass = (m_ValidateWS as IFeatureWorkspace).OpenFeatureClass(cName);
(pFeatureClass as IDataset).Delete();
}
return true;
}
catch (Exception err) { throw new Exception("覆蓋要素類錯誤", err); }
}
public bool NameIsExist(string cName)
{
if (m_ValidateWS == null || String.IsNullOrEmpty(cName)) return false;
try
{
return (m_ValidateWS as IFeatureWorkspace).OpenFeatureClass(cName) != null;
}
catch { return false; }
//return (m_ValidateWS as IWorkspace2).get_NameExists (esriDatasetType .esriDTFeatureClass ,cName );
}
public string AutoRevise(string cName)
{
if (m_ValidateWS == null || String.IsNullOrEmpty(cName)) return null;
try
{
string errMsg = "";
string fixedName = "";
Validate(cName, out fixedName, out errMsg);
int count = 0;
string temp = fixedName;
while (NameIsExist(temp))
{
count++;
temp = fixedName + "_" + count;
}
return temp;
}
catch (Exception err) { throw new Exception("自動修正要素類名稱錯誤", err); }
}
public string[] AutoRevise(string[] names)
{
if (names == null || names.Length < 1) return null;
string[] outnames = new string[names.Length];
for (int i = 0; i < names.Length; i++)
{
outnames[i] = AutoRevise(names[i]);
}
return outnames;
}
public bool Validate(string cName, out string fixedName, out string errMsg)
{
fixedName = ""; errMsg = "";
if (m_ValidateWS == null || String.IsNullOrEmpty(cName)) return false;
IFieldChecker pFieldChecker = new FieldCheckerClass();
pFieldChecker.ValidateWorkspace = m_ValidateWS;
int errType = pFieldChecker.ValidateTableName(cName, out fixedName);
switch (errType)
{
case 1:
errMsg = "Table name is a SQL reserved word.";
break;
case 2:
errMsg = "Table name contains an Invalid Character.";
break;
case 4:
errMsg = "Table name has an invalid starting character.";
break;
default:
errMsg = "";
break;
}
return errType == 0;
}
#endregion
}
public class InvalidObjectInfoClass : IInvalidObjectInfo
{
private string m_ErrorDescription = "";
private int m_InvalidObjectID = -1;
#region 構造函數
public InvalidObjectInfoClass(string err, int id)
{
m_ErrorDescription = err;
m_InvalidObjectID = id;
}
#endregion
#region IInvalidObjectInfo 成員
public string ErrorDescription
{
get { return m_ErrorDescription; }
}
public int InvalidObjectID
{
get { return m_InvalidObjectID; }
}
#endregion
}
}