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

 

最終效果:

 

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