ArcGIS二次开发基础教程(13):网络分析之最近设施分析

ArcGIS二次开发基础教程(13):网络分析之最近设施分析

最近设施分析

		/// <summary>
        /// Geodatabase function: open work space
        /// </summary>
        /// <param name="strGDBName">Input file name</param>
        /// <returns>Workspace</returns>
        public IWorkspace OpenWorkspace(string strMDBName)
        {
            // As Workspace Factories are Singleton objects, they must be instantiated with the Activator
            var workspaceFactory = System.Activator.CreateInstance(System.Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory")) as ESRI.ArcGIS.Geodatabase.IWorkspaceFactory;
            if (!System.IO.File.Exists(strMDBName))
            {
                MessageBox.Show("The workspace: " + strMDBName + " does not exist", "Workspace Error");
                return null;
            }

            IWorkspace workspace = null;
            try
            {
                workspace = workspaceFactory.OpenFromFile(strMDBName, 0);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Opening workspace failed: " + ex.Message, "Workspace Error");
            }

            return workspace;
        }

		/// <summary>
        /// Geodatabase function: open network dataset
        /// </summary>
        /// <param name="workspace">Input workspace</param>
        /// <param name="strNDSName">Input network dataset name</param>
        /// <returns>NetworkDataset</returns>
        public INetworkDataset OpenNetworkDataset(IWorkspace workspace, string featureDatasetName, string strNDSName)
        {
            // Obtain the dataset container from the workspace
            var featureWorkspace = workspace as IFeatureWorkspace;
            ESRI.ArcGIS.Geodatabase.IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(featureDatasetName);
            var featureDatasetExtensionContainer = featureDataset as ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtensionContainer;
            ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtension featureDatasetExtension = featureDatasetExtensionContainer.FindExtension(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset);
            var datasetContainer3 = featureDatasetExtension as ESRI.ArcGIS.Geodatabase.IDatasetContainer3;

            // Use the container to open the network dataset.
            ESRI.ArcGIS.Geodatabase.IDataset dataset = datasetContainer3.get_DatasetByName(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset, strNDSName);
            return dataset as ESRI.ArcGIS.Geodatabase.INetworkDataset;
        }

 		/// <summary>
        /// Geodatabase function: get network dataset
        /// </summary>
        /// <param name="networkDataset">Input network dataset</param>
        /// <returns>DE network dataset</returns>    
        public IDENetworkDataset GetDENetworkDataset(INetworkDataset networkDataset)
        {
            // Cast from the network dataset to the DatasetComponent
            IDatasetComponent dsComponent = networkDataset as IDatasetComponent;

            // Get the data element
            return dsComponent.DataElement as IDENetworkDataset;
        }

 		/// <summary>
        /// Create NASolver and NAContext
        /// </summary>
        /// <param name="networkDataset">Input network dataset</param>
        private void CreateSolverContext(INetworkDataset networkDataset)
        {
            if (networkDataset == null) return;

            //Get the Data Element
            IDENetworkDataset deNDS = GetDENetworkDataset(networkDataset);

            INASolver naSolver = new NAClosestFacilitySolverClass();
            f_NAContext = naSolver.CreateContext(deNDS, naSolver.Name);
            ((INAContextEdit)f_NAContext).Bind(networkDataset, new GPMessagesClass());
        }

        /// <summary>
        /// Create a layer for the network dataset and add it to the map
        /// </summary>
        private void AddNetworkDatasetLayerToMap(INetworkDataset networkDataset)
        {
            INetworkLayer networkLayer = new NetworkLayerClass();
            networkLayer.NetworkDataset = networkDataset;
            ILayer layer = networkLayer as ILayer;
            layer.Name = "CF_ND";
            axMapControl1.AddLayer(layer);
        }

        /// <summary>
        /// Create a layer from the context and add it to the map
        /// </summary>
        private void AddNetworkAnalysisLayerToMap()
        {
            ILayer layer = f_NAContext.Solver.CreateLayer(f_NAContext) as ILayer;
            layer.Name = f_NAContext.Solver.DisplayName;
            axMapControl1.AddLayer(layer);
        }

		private INAContext f_NAContext;//网络分析上下文
        private IFeatureClass incidentsFeatureClass;//事故点
        private IFeatureClass facilitiesFeatureClass;//设施点
        private IGraphicsContainer gra;
        private IActiveView act;
        private bool CFNA = false;//分析准备
        private int incidentsCount = 0;//事故点
        private int facilitiesCount = 0;//设施点
        private void 打开网络数据集ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            IFeatureWorkspace featureWorkspace = null;
            INetworkDataset networkDataset1 = null;
            openFileDialog1.Title = "打开网络数据集";
            openFileDialog1.Filter = "Peronal GeoDatabase(*.mdb)|*.mdb";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    // Open Geodatabase and network dataset
                    IWorkspace workspace = OpenWorkspace(openFileDialog1.FileName);
                    networkDataset1 = OpenNetworkDataset(workspace, "CF", "CF_ND");
                    featureWorkspace = workspace as IFeatureWorkspace;
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show("Unable to open dataset. Error Message: " + ex.Message);
                    this.Close();
                    return;
                }
                //创建网络上下文
                CreateSolverContext(networkDataset1);
                //从工作空间获得用来存储输入点的要素类
                incidentsFeatureClass = featureWorkspace.OpenFeatureClass("incidents");
                facilitiesFeatureClass = featureWorkspace.OpenFeatureClass("facilities");
                //获得道路和节点图层
                IFeatureClass road = featureWorkspace.OpenFeatureClass("road");
                IFeatureClass junctions = featureWorkspace.OpenFeatureClass("CF_ND_Junctions");
                //把以上四个图层全部添加进地图
                IFeatureLayer layer1 = new FeatureLayerClass();
                IFeatureClass class1 = incidentsFeatureClass;
                layer1.FeatureClass = class1;
                layer1.Name = class1.AliasName;
                axMapControl1.AddLayer(layer1);
                IFeatureLayer layer2 = new FeatureLayerClass();
                IFeatureClass class2 = facilitiesFeatureClass;
                layer2.FeatureClass = class2;
                layer2.Name = class2.AliasName;
                axMapControl1.AddLayer(layer2);
                IFeatureLayer layer3 = new FeatureLayerClass();
                layer3.FeatureClass = road;
                layer3.Name = road.AliasName;
                axMapControl1.AddLayer(layer3);
                IFeatureLayer layer4 = new FeatureLayerClass();
                layer4.FeatureClass = junctions;
                layer4.Name = junctions.AliasName;
                axMapControl1.AddLayer(layer4);
                //添加网络数据集图层和网络分析图层
                AddNetworkDatasetLayerToMap(networkDataset1);
                AddNetworkAnalysisLayerToMap();
                gra = axMapControl1.ActiveView.FocusMap as IGraphicsContainer;
                act = axMapControl1.ActiveView;
                axMapControl1.Refresh();
            }
        }

private void 分析准备ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            CFNA = true;
            //清除输入设施点
            ITable table = facilitiesFeatureClass as ITable;
            table.DeleteSearchedRows(null);
            //清除输入事故点
            ITable table2 = incidentsFeatureClass as ITable;
            table2.DeleteSearchedRows(null);
            //清除网络分析图层设施点
            INAClass class1 = f_NAContext.NAClasses.get_ItemByName("Facilities") as INAClass;
            ITable table3 = class1 as ITable;
            table3.DeleteSearchedRows(null);
            //清除网络分析图层事故点
            INAClass class2 = f_NAContext.NAClasses.get_ItemByName("Incidents") as INAClass;
            ITable table4 = class2 as ITable;
            table4.DeleteSearchedRows(null);
            //清楚路线
            INAClass class3 = f_NAContext.NAClasses.get_ItemByName("CFRoutes") as INAClass;
            ITable table5 = class3 as ITable;
            table5.DeleteSearchedRows(null);
            //清除障碍
            INAClass class4 = f_NAContext.NAClasses.get_ItemByName("Barriers") as INAClass;
            ITable table6 = class4 as ITable;
            table6.DeleteSearchedRows(null);
            //点号清零
            facilitiesCount = 0;
            incidentsCount = 0;
            //元素清零
            gra.DeleteAllElements();
            act.Refresh();
            //提醒
            MessageBox.Show("可开始选择点");
        }

        private void ChooseIncidents(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            if (CFNA == true)//如果分析准备好了就添加要素点
            {
                IPoint pt = new PointClass();
                pt = act.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                IFeature feature = incidentsFeatureClass.CreateFeature();
                feature.Shape = pt;
                feature.Store();
                incidentsCount++;

                //在地图上显示当前站点数目
                ITextElement textElement = new TextElementClass();
                ITextSymbol ts = new TextSymbolClass();
                IRgbColor color = new RgbColorClass();
                color.RGB = 38;
                ts.Color = color;
                textElement.Symbol = ts;
                textElement.Text = incidentsCount.ToString();
                IElement ele = textElement as IElement;
                ele.Geometry = pt;
                gra.AddElement(ele, 0);
                act.Refresh();
            }
        }

        private void ChooseFacilities(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            if (CFNA == true)
            {
                IPoint pt = new PointClass();
                pt = act.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                IFeature feature = facilitiesFeatureClass.CreateFeature();
                feature.Shape = pt;
                feature.Store();
                facilitiesCount++;

                ITextElement textElement = new TextElementClass();
                ITextSymbol ts = new TextSymbolClass();
                IRgbColor color = new RgbColorClass();
                color.RGB = 196;
                ts.Color = color;
                textElement.Symbol = ts;
                textElement.Text = facilitiesCount.ToString();
                IElement ele = textElement as IElement;
                ele.Geometry = pt;
                gra.AddElement(ele, 0);
                act.Refresh();
            }
        }

        /// <summary>
        /// Set solver settings
        /// </summary>
        /// <param name="strNAClassName">NAClass name</param>
        /// <param name="inputFC">Input feature class</param>
        public void LoadNANetworkLocations(string strNAClassName, IFeatureClass inputFC)
        {
            INamedSet classes = f_NAContext.NAClasses;
            INAClass naClass = classes.get_ItemByName(strNAClassName) as INAClass;

            // delete existing Locations except if that a barriers
            naClass.DeleteAllRows();

            // Create a NAClassLoader and set the snap tolerance (meters unit)
            INAClassLoader classLoader = new NAClassLoader();
            classLoader.Locator = f_NAContext.Locator;
            ((INALocator3)classLoader.Locator).MaxSnapTolerance = 80;
            classLoader.NAClass = naClass;

            //Create field map to automatically map fields from input class to NAClass
            INAClassFieldMap fieldMap = new NAClassFieldMapClass();
            fieldMap.CreateMapping(naClass.ClassDefinition, inputFC.Fields);
            classLoader.FieldMap = fieldMap;

            // Avoid loading network locations onto non-traversable portions of elements
            INALocator3 locator = f_NAContext.Locator as INALocator3;
            locator.ExcludeRestrictedElements = true;
            locator.CacheRestrictedElements(f_NAContext);

            //Load Network Locations
            int rowsIn = 0;
            int rowsLocated = 0;
            IFeatureCursor featureCursor = inputFC.Search(null, true);
            classLoader.Load((ICursor)featureCursor, null, ref rowsIn, ref rowsLocated);

            //Message all of the network analysis agents that the analysis context has changed
            ((INAContextEdit)f_NAContext).ContextChanged();
        }

        private void 实施分析ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            IGPMessages messages = new GPMessagesClass();
            //加载站点  设施点和事故点
            LoadNANetworkLocations("Incidents", incidentsFeatureClass);
            LoadNANetworkLocations("Facilities", facilitiesFeatureClass);
            f_NAContext.Solver.Solve(f_NAContext, messages, null);
            //每次实施分析后把输入要素清空
            ITable table = incidentsFeatureClass as ITable;
            table.DeleteSearchedRows(null);
            ITable table2 = facilitiesFeatureClass as ITable;
            table.DeleteSearchedRows(null);
            axMapControl1.Refresh();
        }

还可以将分析结果以文本形式显示出来

		//需要一个ListBox控件
		/// <summary>
        /// Display analysis results in the list box
        /// </summary>
        public void DisplayOutput()
    {
            ITable table = m_NAContext.NAClasses.get_ItemByName(OUTPUTCLASSNAME) as ITable;
      if (table == null)
      {
                lstOutput.Items.Add("Impossible to get the " + OUTPUTCLASSNAME + " table");
      }
      lstOutput.Items.Add("Number facilities found " + table.RowCount(null).ToString());
      lstOutput.Items.Add("");
      if (table.RowCount(null) > 0)
      {
        lstOutput.Items.Add("IncidentID, FacilityID,FacilityRank,Total_Length" );
        double total_impedance;
        long incidentID;
        long facilityID;
        long facilityRank;
        ICursor cursor;
        IRow row;

        cursor = table.Search(null, false);
        row = cursor.NextRow();
        while (row != null)
        {
          incidentID = long.Parse(row.get_Value(table.FindField("IncidentID")).ToString());
          facilityID = long.Parse(row.get_Value(table.FindField("FacilityID")).ToString());
          facilityRank = long.Parse(row.get_Value(table.FindField("FacilityRank")).ToString());
          total_impedance = double.Parse(row.get_Value(table.FindField("Total_Length")).ToString());
          lstOutput.Items.Add(incidentID.ToString() + ",\t" + facilityID.ToString() +
            ",\t" + facilityRank.ToString() + ",\t" + total_impedance.ToString("F2"));

          row = cursor.NextRow();
        }
      }

历届GIS应用技能大赛开发题答案点这里,尚在不定期更新中

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值