调用GP工具实现空间分析的;
需引用命名空间:
using ESRI.ArcGIS.AnalysisTools;//添加引用 在Arcgis10.2\DeveloperKit10.2\DotNet\ToolBoxes
using ESRI.ArcGIS.Geoprocessor;//添加引用 在Arcgis10.2\DeveloperKit10.2\DotNet\
下面用到的几个方法:
//辅助私有方法
///
/// 获取指定名称的矢量图层对象
///
///
///
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里
///
/// 单个缓冲区分析
///
/// map控件
/// 文件名
/// 缓冲半径
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());
}
}
联合:
///
/// 两个的图层联合
///
/// map控件
/// 文件名称
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 这个的赋值只能两个.(后面有改进,实现多个图层联合)
相交:
///
/// 图层相交
///
///
/// 叠加的图层名
/// 文件名
/// 缓冲半径
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 生成唯一渲染色带
///
/// 唯一值渲染图层
///
/// 矢量图层
/// 唯一值字段
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;
}
///
/// 获取默认符号
///
///
///
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;
}
///
/// 构建色带
///
///
///
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;
}
///
/// 辅助将.NET颜色转换为AE颜色
///
///
///
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;
}
///
/// 构建色带
///
/// 色带个数
///
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
}
要点!!!!!!!!!!
///
/// 返回缓冲shp的路径
///
///
///
/// 缓冲半径分级的值
/// 返回路径 路径默认bin debug里
private static List Buffer(IMapControlDefault mapControl, string name, double[] distances)
{
List path=new List();
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;
}
}
///
/// 大于两个的图层联合
///
///
///
/// 返回路径 相对路径 最终联合图层是Union.shp
public static string Union(IMapControlDefault mapControl, string name, double[] distances)
{
List pathBuffer = new List();
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;
}
}
///
/// 图层相交
///
///
/// 叠加的图层名
/// 文件名
/// 缓冲半径
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!!!!!!!!!!!
最终效果: