調用GP工具實現空間分析的;
需引用命名空間:
using ESRI.ArcGIS.AnalysisTools;//添加引用 在Arcgis10.2\DeveloperKit10.2\DotNet\ToolBoxes
using ESRI.ArcGIS.Geoprocessor;//添加引用 在Arcgis10.2\DeveloperKit10.2\DotNet\
下面用到的幾個方法:
//輔助私有方法
/// <summary>
/// 獲取指定名稱的矢量圖層對象
/// </summary>
/// <param name="layerName"></param>
/// <returns></returns>
private static IFeatureLayer getFeatureLayer(IMapControlDefault mapControl,string layerName)
{
ILayer layer;
IGeoFeatureLayer featureLayer;
for (int i = 0; i < mapControl.LayerCount; i++)
{
layer = mapControl.get_Layer(i);
if (layer != null && layer.Name == layerName)
{
featureLayer = layer as IGeoFeatureLayer;
return featureLayer;
}
}
return null;
}
//獲取指定路徑下得shp要素
public static IFeatureLayer GetLayerFromPathShp(string path)
{
try
{
IWorkspaceFactory workspcFac = new ShapefileWorkspaceFactoryClass();
IFeatureWorkspace featureWorkspace;
int index = path.LastIndexOf("\\");
//獲得文件路徑
string filePath = path.Substring(0, index);
//獲得文件名
string fileName = path.Substring(index + 1);
IFeatureLayer featureLayer = new FeatureLayerClass();
//打開路徑
featureWorkspace = workspcFac.OpenFromFile(filePath, 0) as IFeatureWorkspace;
//打開類要素
featureLayer.FeatureClass = featureWorkspace.OpenFeatureClass(fileName);
return featureLayer;
}
catch(Exception ex)
{
MessageBoxEX.Show("提示","指定路徑shp獲取失敗!"+ex);
return null;
}
}
緩衝區分析:
static string appPath = Environment.CurrentDirectory + "\\shp\\";//路徑 默認存debug裏
/// <summary>
/// 單個緩衝區分析
/// </summary>
/// <param name="mapControl">map控件</param>
/// <param name="name">文件名</param>
/// <param name="distances">緩衝半徑</param>
public static void Buffer(IMapControlDefault mapControl,string distances,string name)
{
string outPath = appPath+ ""+ name + distances + "_Buffer.shp";
IFeatureLayer featureLayer = getFeatureLayer(mapControl, "颱風路徑");
Geoprocessor gp = new Geoprocessor(); //初始化Geoprocessor
gp.OverwriteOutput = true; //允許運算結果覆蓋現有文件
try
{
ESRI.ArcGIS.AnalysisTools.Buffer pBuffer = new ESRI.ArcGIS.AnalysisTools.Buffer(); //定義Buffer工具
pBuffer.in_features = featureLayer; //輸入對象,既可是IFeatureLayer對象,也可是完整文件路徑如“D://data.shp”
pBuffer.out_feature_class = outPath; //輸出對象,一般是包含輸出文件名的完整文件路徑
//設置緩衝區的大小,即可是帶單位的具體數值,如0.1 Decimal Degrees;也可是輸入圖層中的某個字段,如“BufferLeng”
pBuffer.buffer_distance_or_field = "" + distances + " Kilometers"; //緩衝區參數
pBuffer.dissolve_option = "NONE"; //支持融合緩衝區重疊交叉部分
gp.Execute(pBuffer, null); //執行緩衝區分析
//添加結果到窗口
string pFolder = System.IO.Path.GetDirectoryName(outPath); //得到字符串中文件夾位置
string pFileName = System.IO.Path.GetFileName(outPath); //得到字符串中文件名字
mapControl.AddShapeFile(pFolder, pFileName); //往地圖控件裏添加文件
mapControl.ActiveView.Refresh(); //激活窗口刷新
}
catch (Exception ex)
{
MessageBoxEX.Show("警告", "緩衝分析失敗!" + ex.ToString());
}
}
聯合:
/// <summary>
/// 兩個的圖層聯合
/// </summary>
/// <param name="mapControl">map控件</param>
/// <param name="name">文件名稱</param>
public static void Union(IMapControlDefault mapControl,string name)
{
object sev = null;
string outPath = appPath+""+name+"_Union.shp";
//創建地理處理
IBasicGeoprocessor pBGeop = new BasicGeoprocessorClass();
//TODO:
//pBGeop.Union();
Geoprocessor pGp = new Geoprocessor();
pGp.OverwriteOutput = true; //允許運算結果覆蓋現有文件,可無
try
{
IFeatureLayer featureLayer = getFeatureLayer(mapControl, "颱風路徑");
//使用AE中自帶的緩衝區分析工具
Union union = new Union();
union.in_features = "H:\\Windows\\文檔\\ArcGIS\\艾雲尼.shp;H:\\Windows\\文檔\\ArcGIS\\艾雲尼5.shp;";
union.out_feature_class = outPath;//輸出路徑
union.join_attributes = "ALL";//連接屬性
union.gaps = "GAPS";
pGp.Execute(union, null); //執行
//添加結果到窗口
string pFolder = System.IO.Path.GetDirectoryName(outPath); //得到字符串中文件夾位置
string pFileName = System.IO.Path.GetFileName(outPath); //得到字符串中文件名字
mapControl.AddShapeFile(pFolder, pFileName); //往地圖控件裏添加文件
mapControl.ActiveView.Refresh(); //激活窗口刷新
}
catch
{
MessageBox.Show(pGp.GetMessages(ref sev));
}
}
受許可影響,輸入圖層只能兩個疊加,不然會報異常錯誤!!!!!!!!!!!!!!!!!!!!!!! 調試很久才發現..........
就是 union.in_features 這個的賦值只能兩個.(後面有改進,實現多個圖層聯合)
相交:
/// <summary>
/// 圖層相交
/// </summary>
/// <param name="mapControl"></param>
/// <param name="layerName">疊加的圖層名</param>
/// <param name="name">文件名</param>
/// <param name="distances">緩衝半徑</param>
public static void Intersect(IMapControlDefault mapControl,string layerName, string name, double[] distances)
{
Geoprocessor pGp = new Geoprocessor();
object sev = null;
string outPath = appPath + "Intersect.shp";//輸出路徑
try
{
IFeatureLayer featureLayer = getFeatureLayer(mapControl, layerName);//選取圖層
string str = Union(mapControl, name, distances);//默認分級緩衝區圖層
GpValueTableObjectClass pObject = new GpValueTableObjectClass();
object p1 = featureLayer as object;//一個輸入是獲取的圖層
object p2 = str as object;//一個輸入直接路徑獲取的圖層
pObject.SetColumns(2);
pObject.AddRow(ref p1);
pObject.AddRow(ref p2);
pGp.OverwriteOutput = true; //允許運算結果覆蓋現有文件
Intersect intsect = new Intersect();
intsect.in_features = pObject;
intsect.out_feature_class = outPath;
intsect.join_attributes = "ALL";
pGp.Execute(intsect, null); //執行
//添加結果到窗口
string pFolder = System.IO.Path.GetDirectoryName(outPath); //得到字符串中文件夾位置
string pFileName = System.IO.Path.GetFileName(outPath); //得到字符串中文件名字
mapControl.AddShapeFile(pFolder, pFileName); //往地圖控件裏添加文件
UniqueValueRender(mapControl, "Intersect", "FID_Union");//着色
mapControl.ActiveView.Refresh(); //激活窗口刷新
}
catch (Exception ex)
{
MessageBoxEX.Show("警告", "圖層相交失敗!"+ pGp.GetMessages(ref sev));
}
}
以上三個方法實現一個簡單的,分級緩衝區分析並分級着色,
大致步驟:先得到各個緩衝半徑下的緩衝區圖層→各個緩衝區圖層進行聯合(多個圖層聯合實現)→聯合圖層和想要的圖層進行相交
最後大致如圖(基於線要素緩衝的 其他要素應該也可以,沒嘗試過):
上代碼:
後面要用到的唯一值渲染色帶
#region 生成唯一渲染色帶
/// <summary>
/// 唯一值渲染圖層
/// </summary>
/// <param name="pFeatureLayer">矢量圖層</param>
/// <param name="pUniqueFieldName">唯一值字段</param>
public static void UniqueValueRender(IMapControlDefault mapControl,string layerName, string pUniqueFieldName)
{
IFeatureLayer pFeatureLayer = getFeatureLayer(mapControl, layerName);//獲取要素圖層
IGeoFeatureLayer pGeoLayer = pFeatureLayer as IGeoFeatureLayer;
if (pGeoLayer == null) return;
ITable pTable = pGeoLayer.FeatureClass as ITable;//得到屬性表
ICursor pCursor;
IQueryFilter pQueryFilter = new QueryFilter();//查詢
pQueryFilter.AddField(pUniqueFieldName);
pCursor = pTable.Search(pQueryFilter, true);//獲取字段
IEnumerator pEnumreator;
//獲取字段中各要素屬性唯一值
IDataStatistics pDataStatistics = new DataStatisticsClass();
pDataStatistics.Field = pUniqueFieldName;//獲取統計字段
pDataStatistics.Cursor = pCursor;
pEnumreator = pDataStatistics.UniqueValues;
int fieldcount = pDataStatistics.UniqueValueCount;//唯一值個數,以此確定顏色帶範圍
IUniqueValueRenderer pUniqueValueR = new UniqueValueRendererClass();
pUniqueValueR.FieldCount = 1;//單值渲染
pUniqueValueR.set_Field(0, pUniqueFieldName);//渲染字段
IEnumColors pEnumColor = GetColorRgb(fieldcount).Colors;
pEnumColor.Reset();
while (pEnumreator.MoveNext())
{
string value = pEnumreator.Current.ToString();
if (value != null)
{
IColor pColor = pEnumColor.Next();
ISymbol pSymbol = GetDefaultSymbol(pFeatureLayer.FeatureClass.ShapeType, pColor);//獲取默認符號
pUniqueValueR.AddValue(value, pUniqueFieldName, pSymbol);
}
}
pGeoLayer.Renderer = pUniqueValueR as IFeatureRenderer;
}
public static void UniqueValueRender(string path, string pUniqueFieldName)
{
IFeatureLayer pFeatureLayer = GetLayerFromPathShp(path);
IGeoFeatureLayer pGeoLayer = pFeatureLayer as IGeoFeatureLayer;
if (pGeoLayer == null) return;
ITable pTable = pGeoLayer.FeatureClass as ITable;
ICursor pCursor;
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.AddField(pUniqueFieldName);
pCursor = pTable.Search(pQueryFilter, true);//獲取字段
IEnumerator pEnumreator;
//獲取字段中各要素屬性唯一值
IDataStatistics pDataStatistics = new DataStatisticsClass();
pDataStatistics.Field = pUniqueFieldName;//獲取統計字段
pDataStatistics.Cursor = pCursor;
pEnumreator = pDataStatistics.UniqueValues;
int fieldcount = pDataStatistics.UniqueValueCount;//唯一值個數,以此確定顏色帶範圍
IUniqueValueRenderer pUniqueValueR = new UniqueValueRendererClass();
pUniqueValueR.FieldCount = 1;//單值渲染
pUniqueValueR.set_Field(0, pUniqueFieldName);//渲染字段
IEnumColors pEnumColor = GetColorRgb(fieldcount).Colors;
pEnumColor.Reset();
while (pEnumreator.MoveNext())
{
string value = pEnumreator.Current.ToString();
if (value != null)
{
IColor pColor = pEnumColor.Next();
ISymbol pSymbol = GetDefaultSymbol(pFeatureLayer.FeatureClass.ShapeType, pColor);
pUniqueValueR.AddValue(value, pUniqueFieldName, pSymbol);
}
}
pGeoLayer.Renderer = pUniqueValueR as IFeatureRenderer;
}
/// <summary>
/// 獲取默認符號
/// </summary>
/// <param name="geometryType"></param>
/// <returns></returns>
private static ISymbol GetDefaultSymbol(esriGeometryType geometryType, IColor pColor)
{
ISymbol pSymbol = null;
switch (geometryType)
{
case esriGeometryType.esriGeometryLine:
case esriGeometryType.esriGeometryPolyline:
ISimpleLineSymbol pLineSymbol = new SimpleLineSymbolClass();
pLineSymbol.Color = pColor as IColor;
pLineSymbol.Width = 3;
pLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
pSymbol = pLineSymbol as ISymbol;
break;
case esriGeometryType.esriGeometryPoint:
ISimpleMarkerSymbol pMarkerSymbol = new SimpleMarkerSymbolClass();
pMarkerSymbol.Color = pColor as IColor;
pMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
pSymbol = pMarkerSymbol as ISymbol;
break;
case esriGeometryType.esriGeometryPolygon:
ISimpleFillSymbol pFillSymbol = new SimpleFillSymbolClass();
pFillSymbol.Color = pColor as IColor;
pFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
pSymbol = pFillSymbol as ISymbol;
break;
}
return pSymbol;
}
/// <summary>
/// 構建色帶
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
private static IRandomColorRamp GetColorRamp(int size)
{
IRandomColorRamp pRandomColorRamp = new RandomColorRampClass();
pRandomColorRamp.StartHue = 0;
pRandomColorRamp.EndHue = 60;
pRandomColorRamp.MaxSaturation = 100;
pRandomColorRamp.MinSaturation = 100;
pRandomColorRamp.MaxValue = 100;
pRandomColorRamp.MinValue = 100;
pRandomColorRamp.Size = size;
bool ok = true;
pRandomColorRamp.CreateRamp(out ok);
return pRandomColorRamp;
}
/// <summary>
/// 輔助將.NET顏色轉換爲AE顏色
/// </summary>
/// <param name="pColor"></param>
/// <returns></returns>
private static IColor ConvertNETColorToAEColor(Color pColor)
{
IRgbColor rgbColor = new RgbColorClass();
rgbColor.Red = pColor.R;
rgbColor.Blue = pColor.B;
rgbColor.Green = pColor.G;
return rgbColor as IColor;
}
/// <summary>
/// 構建色帶
/// </summary>
/// <param name="size">色帶個數</param>
/// <returns></returns>
private static IAlgorithmicColorRamp GetColorRgb(int size)
{
IColor fromColor = null, toColor = null;
fromColor = ConvertNETColorToAEColor(Color.Yellow);//起始顏色
toColor = ConvertNETColorToAEColor(Color.Red);//終止顏色
IAlgorithmicColorRamp algCR = new AlgorithmicColorRampClass();
algCR.Size = size;//生成渲染個數
bool nFlag;
//設置色帶生成算法
algCR.Algorithm = esriColorRampAlgorithm.esriLabLChAlgorithm;
algCR.FromColor = fromColor; algCR.ToColor = toColor;
algCR.CreateRamp(out nFlag);
return algCR;
}
#endregion
}
要點!!!!!!!!!!
/// <summary>
/// 返回緩衝shp的路徑
/// </summary>
/// <param name="mapControl"></param>
/// <param name="name"></param>
/// <param name="distances">緩衝半徑分級的值</param>
/// <returns>返回路徑 路徑默認bin debug裏 </returns>
private static List<string> Buffer(IMapControlDefault mapControl, string name, double[] distances)
{
List<string> path=new List<string>();
string outPath = appPath;
IFeatureLayer featureLayer = getFeatureLayer(mapControl, "颱風路徑");//本人默認了此圖層的要素進行緩衝區分析,可根據需要自行修改
Geoprocessor gp = new Geoprocessor(); //初始化Geoprocessor
try
{
for (int i = 0; i < distances.Length; i++)
{
gp.OverwriteOutput = true; //允許運算結果覆蓋現有文件
ESRI.ArcGIS.AnalysisTools.Buffer pBuffer = new ESRI.ArcGIS.AnalysisTools.Buffer(); //定義Buffer工具
pBuffer.in_features = featureLayer; //輸入對象,既可是IFeatureLayer對象,也可是完整文件路徑如“D://data.shp”
string shpName = name + "" + distances[i].ToString().Trim() + "Buffer.shp";
pBuffer.out_feature_class = outPath + shpName; //輸出對象,一般是包含輸出文件名的完整文件路徑
//設置緩衝區的大小,即可是帶單位的具體數值,如0.1 Decimal Degrees;也可是輸入圖層中的某個字段,如“BufferLeng”
pBuffer.buffer_distance_or_field = "" + distances[i].ToString().Trim() + " Kilometers"; //緩衝區參數
pBuffer.dissolve_option = "NONE"; //支持融合緩衝區重疊交叉部分 NONE
gp.Execute(pBuffer, null); //執行緩衝區分析
path.Add(outPath + shpName);
}
return path;
}
catch (Exception ex)
{
// Print geoprocessing execution error messages.
MessageBoxEX.Show("警告", "緩衝分析失敗!" + ex.ToString());
return path;
}
}
/// <summary>
/// 大於兩個的圖層聯合
/// </summary>
/// <param name="mapControl"></param>
/// <param name="distances"></param>
/// <param name="name">返回路徑 相對路徑 最終聯合圖層是Union.shp</param>
public static string Union(IMapControlDefault mapControl, string name, double[] distances)
{
List<string> pathBuffer = new List<string>();
Geoprocessor pGp = new Geoprocessor();
string outPath = appPath;
try
{
IFeatureLayer featureLayer = getFeatureLayer(mapControl, "颱風路徑");
string inputPath;
pathBuffer = Buffer(mapControl, name, distances);
for (int i = 0; i < pathBuffer.Count - 1; i++)
{
if (i == 0)
{
inputPath = "" + pathBuffer[i] + ";" + pathBuffer[i + 1] + ";";
outPath = appPath + "Union" + i + ".shp";
}
else if (i == pathBuffer.Count - 2)
{
inputPath = "" + outPath + ";" + pathBuffer[i + 1] + ";";
outPath = appPath + "Union.shp";
}
else
{
inputPath = "" + outPath + ";" + pathBuffer[i + 1] + ";";
outPath = appPath + "Union" + i + ".shp";
}
pGp.OverwriteOutput = true; //允許運算結果覆蓋現有文件,可無
//使用AE中自帶的緩衝區分析工具
Union union = new Union();
union.in_features = inputPath;
union.out_feature_class = outPath;//輸出路徑
union.join_attributes = "ONLY_FID";//連接屬性 NO_FID ONLY_FID
union.gaps = "GAPS";
pGp.Execute(union, null); //執行
}
//string pFolder = System.IO.Path.GetDirectoryName(outPath); //得到字符串中文件夾位置
//string pFileName = System.IO.Path.GetFileName(outPath); //得到字符串中文件名字
//mapControl.AddShapeFile(pFolder, pFileName); //往地圖控件裏添加文件
//mapControl.ActiveView.Refresh(); //激活窗口刷新
return outPath;
}
catch (Exception ex)
{
MessageBoxEX.Show("警告", "聯合分析失敗!" );
return null;
}
}
/// <summary>
/// 圖層相交
/// </summary>
/// <param name="mapControl"></param>
/// <param name="layerName">疊加的圖層名</param>
/// <param name="name">文件名</param>
/// <param name="distances">緩衝半徑</param>
public static void Intersect(IMapControlDefault mapControl,string layerName, string name, double[] distances)
{
Geoprocessor pGp = new Geoprocessor();
object sev = null;
string outPath = appPath + "Intersect.shp";
try
{
IFeatureLayer featureLayer = getFeatureLayer(mapControl, layerName);//選取圖層
string str = Union(mapControl, name, distances);//默認分級緩衝區圖層
GpValueTableObjectClass pObject = new GpValueTableObjectClass();
object p1 = featureLayer as object;
object p2 = str as object;
pObject.SetColumns(2);
pObject.AddRow(ref p1);
pObject.AddRow(ref p2);
pGp.OverwriteOutput = true; //允許運算結果覆蓋現有文件
Intersect intsect = new Intersect();
intsect.in_features = pObject;
intsect.out_feature_class = outPath;
intsect.join_attributes = "ALL";
pGp.Execute(intsect, null); //執行
//添加結果到窗口
string pFolder = System.IO.Path.GetDirectoryName(outPath); //得到字符串中文件夾位置
string pFileName = System.IO.Path.GetFileName(outPath); //得到字符串中文件名字
mapControl.AddShapeFile(pFolder, pFileName); //往地圖控件裏添加文件
UniqueValueRender(mapControl, "Intersect", "FID_Union");//着色
mapControl.ActiveView.Refresh(); //激活窗口刷新
}
catch (Exception ex)
{
MessageBoxEX.Show("警告", "圖層相交失敗!"+ pGp.GetMessages(ref sev));//pGp.GetMessages(ref sev)將GP工具裏報的錯誤顯示出來
}
}
OVER!!!!!!!!!!!
最終效果: