C# 基于AE的GIS二次开发 空间分析 缓冲区分析(Buffer) 相交(Intersect) 联合(Union)

调用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!!!!!!!!!!!

 

最终效果:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章