• 以Network Dataset(网络数据集)方式实现的最短路径分析


     

    转自原文 以Network Dataset(网络数据集)方式实现的最短路径分析

    构建网络有两种方式,分别是网络数据集NetworkDataset和几何网络Geometric Network,这个网络结构数据的创建直接在Catalog中实现创建,进行最短路径分析,为了直接使用ArcGIS提供的功能,我选用的是NetworkDataset,主要记录下考虑单双行的最短路径的设计与实现(理想状态,不考虑转弯等要素)。
    (A)对数据编辑的要求有一下几点:
    (1) 添加属性字段,名称为Oneway,类型Text,默认值为空。

    (2) 道路数据电子矢量化
    (3) 对于单行线、禁行以及无限制通行方向道路属性值设置的要求:
    由东往西或由北往南通行的单行路段,Oneway字段值设为:FT
    由西往东或由南往北通行的单行路段,Oneway字段值设为:TF
    禁止通行的路段,Oneway字段值为:N
    双向通行的路段,Oneway字段值为:空字符
    (B)路径分析的思路分为一下几步:
    (1)读取shp文件和网络数据集数据
    (2)创建网络分析上下文对象INAContext和网络分析对象INASolver(==IRouteNASolver)
    (3)加载位置点图层,创建网络位置
    (4)设置Solver参数(输出、容限值等)
    (5)进行分析
    (6)显示路线及结果信息
    PS:对于道路走向不是正南正北,或者很难分辨是东西向还是南北向的,Oneway字段的赋值情况,还没有琢磨出万无一失的方法,有高人熟悉的,请指点。
    (C)代码实现部分:
    //初始化地图、网络数据集
            private void Initial()
            {
                this.axMapControl1.ActiveView.Clear();
                axMapControl1.ActiveView.Refresh();

                pFeatureWorkspace = OpenWorkspace(ConfigurationManager.ConnectionStrings["MdbPath"].ToString()) as IFeatureWorkspace;
                pNetworkDataset = OpenNetworkDataset_Other(pFeatureWorkspace as IWorkspace, "TestNet_ND", "TestNet");

                pNAContext = CreateNAContext(pNetworkDataset);

                pInputFC = pFeatureWorkspace.OpenFeatureClass("stop");

                pVertexFC = pFeatureWorkspace.OpenFeatureClass("TestNet_ND_Junctions");

                IFeatureLayer pVertexFL = new FeatureLayerClass();
                pVertexFL.FeatureClass = pFeatureWorkspace.OpenFeatureClass("TestNet_ND_Junctions");
                pVertexFL.Name = pVertexFL.FeatureClass.AliasName;
                axMapControl1.AddLayer(pVertexFL, 0);

                IFeatureLayer pRoadFL = new FeatureLayerClass();
                pRoadFL.FeatureClass = pFeatureWorkspace.OpenFeatureClass("道路中心线");
                pRoadFL.Name = pRoadFL.FeatureClass.AliasName;
                axMapControl1.AddLayer(pRoadFL,0);

                ILayer pLayer;
                INetworkLayer pNetworkLayer = new NetworkLayerClass();
                pNetworkLayer.NetworkDataset = pNetworkDataset;
                pLayer = pNetworkLayer as ILayer;
                pLayer.Name = "Network Dataset";
                axMapControl1.AddLayer(pLayer, 0);

                //Create a Network Analysis Layer and add to ArcMap
                INALayer naLayer = pNAContext.Solver.CreateLayer(pNAContext);
                pLayer = naLayer as ILayer;
                pLayer.Name = pNAContext.Solver.DisplayName;
                axMapControl1.AddLayer(pLayer, 0);

                pActiveView = axMapControl1.ActiveView;
                pMap = pActiveView.FocusMap;
                pGraphicsContainer = pMap as IGraphicsContainer;
            }

            //打开工作空间
            private IWorkspace OpenWorkspace(string strMDBName)
            {
                IWorkspaceFactory pWorkspaceFactory = new AccessWorkspaceFactoryClass();
                return pWorkspaceFactory.OpenFromFile(strMDBName, 0);
            }

            //打开网络数据集
            private INetworkDataset OpenNetworkDataset(IWorkspace workspace,string strNDName)
            {
                IWorkspaceExtensionManager pWorkspaceExtensionManager;
                IWorkspaceExtension pWorkspaceExtension;
                IDatasetContainer2 pDatasetContainer2;

                pWorkspaceExtensionManager = workspace as IWorkspaceExtensionManager;
                int iCount = pWorkspaceExtensionManager.ExtensionCount;
                for (int i = 0; i < iCount; i++)
                {
                    pWorkspaceExtension = pWorkspaceExtensionManager.get_Extension(i);
                    if(pWorkspaceExtension.Name.Equals("Network Dataset"))
                    {
                        pDatasetContainer2=pWorkspaceExtension as IDatasetContainer2;
                        return pDatasetContainer2.get_DatasetByName(esriDatasetType.esriDTNetworkDataset, strNDName) as INetworkDataset;
                    }               
                }
                return null;

            }

            private INetworkDataset OpenNetworkDataset_Other(IWorkspace workspace, string strNDName,string strRoadFeatureDataset)
            {
                IDatasetContainer3 pDatasetContainer3;
                IFeatureWorkspace pFeatureWorkspace = workspace as IFeatureWorkspace;
                pFeatureDataset = pFeatureWorkspace.OpenFeatureDataset(strRoadFeatureDataset);
                IFeatureDatasetExtensionContainer pFeatureDatasetExtensionContainer = pFeatureDataset as IFeatureDatasetExtensionContainer;
                IFeatureDatasetExtension pFeatureDatasetExtension = pFeatureDatasetExtensionContainer.FindExtension(esriDatasetType.esriDTNetworkDataset);
                pDatasetContainer3 = pFeatureDatasetExtension as IDatasetContainer3;

                if (pDatasetContainer3 == null)
                    return null;
                IDataset pDataset = pDatasetContainer3.get_DatasetByName(esriDatasetType.esriDTNetworkDataset, strNDName);
                return pDataset as INetworkDataset;
            }

            //创建网络分析上下文
            private INAContext CreateNAContext(INetworkDataset networkDataset)
            {
                IDENetworkDataset pDENetworkDataset = GetDENetworkDataset(networkDataset);
                INASolver pNASolver = new NARouteSolverClass();
                INAContextEdit pNAContextEdit = pNASolver.CreateContext(pDENetworkDataset, pNASolver.Name) as INAContextEdit;
                pNAContextEdit.Bind(networkDataset,new GPMessagesClass());
                return pNAContextEdit as INAContext;
            }

    //根据点图层确定最短路径所用经历的点
            private void LoadNANetWorkLocations(string strNAClassName, IFeatureClass inputFC, double dSnapTolerance)
            {
                INAClass pNAClass;
                INamedSet pNamedSet;
                pNamedSet = pNAContext.NAClasses;
                pNAClass = pNamedSet.get_ItemByName(strNAClassName) as INAClass;

                //删除已存在的位置点
                pNAClass.DeleteAllRows();

                //创建NAClassLoader,设置捕捉容限值
                INAClassLoader pNAClassLoader = new NAClassLoaderClass();
                pNAClassLoader.Locator = pNAContext.Locator;
                if (dSnapTolerance > 0)
                    pNAClassLoader.Locator.SnapTolerance = dSnapTolerance;
                pNAClassLoader.NAClass = pNAClass;

                //字段匹配
                INAClassFieldMap pNAClassFieldMap = new NAClassFieldMapClass();
                pNAClassFieldMap.CreateMapping(pNAClass.ClassDefinition, inputFC.Fields);
                pNAClassLoader.FieldMap = pNAClassFieldMap;

                //pNAClassFieldMap.set_MappedField("OBJECTID", "OBJECTID");
                //pNAClassLoader.FieldMap = pNAClassFieldMap;

                //加载网络位置点数据
                int iRows=0;
                int iRowsLocated=0;
                IFeatureCursor pFeatureCursor = pInputFC.Search(null, true);
                pNAClassLoader.Load((ICursor)pFeatureCursor, null, ref iRows, ref iRowsLocated);
                ((INAContextEdit)pNAContext).ContextChanged();
            }


           private void SetSolverSettings()
            {
                //Set Route specific Settings
                INASolver naSolver = pNAContext.Solver;
                INARouteSolver cfSolver = naSolver as INARouteSolver;
                cfSolver.OutputLines = esriNAOutputLineType.esriNAOutputLineTrueShapeWithMeasure;
                // Set generic solver settings
                // Set the impedance attribute
                INASolverSettings naSolverSettings;
                naSolverSettings = naSolver as INASolverSettings;
                // Set the On

    eWay Restriction if necessary
                IStringArray restrictions;
                restrictions = naSolverSettings.RestrictionAttributeNames;
                restrictions.RemoveAll();
                restrictions.Add("oneway");
                naSolverSettings.RestrictionAttributeNames = restrictions;
                ////Restrict UTurns
                //naSolverSettings.RestrictUTurns = esriNetworkForwardStarBacktrack.esriNFSBNoBacktrack;
                //naSolverSettings.IgnoreInvalidLocations = true;
                // Do not forget to update the context after you set your impedance
                naSolver.UpdateContext(pNAContext, GetDENetworkDataset(pNAContext.NetworkDataset), new GPMessagesClass());
            }

              //路径分析
                 private void btnSolver_Click(object sender, EventArgs e)
                {
                    this.Cursor = Cursors.WaitCursor;
                    lstOutput.Items.Clear();
                    lstOutput.Items.Add("分析中...");
                    LoadNANetWorkLocations("Stops", pInputFC, 80);
                    IGPMessages gpMessages = new GPMessagesClass();
                    INASolver naSolver = pNAContext.Solver;
                    SetSolverSettings();
                    pNAContext.Solver.Solve(pNAContext, gpMessages, new CancelTrackerClass());

                    if (gpMessages != null)
                    {
                        for (int i = 0; i < gpMessages.Count; i++)
                        {
                            switch (gpMessages.GetMessage(i).Type)
                            {

                                case esriGPMessageType.esriGPMessageTypeError:
                                    lstOutput.Items.Add("错误 " + gpMessages.GetMessage(i).ErrorCode.ToString() + " " + gpMessages.GetMessage(i).Description);
                                    break;
                                case esriGPMessageType.esriGPMessageTypeWarning:
                                    lstOutput.Items.Add("警告 " + gpMessages.GetMessage(i).Description);
                                    break;
                                default:
                                    lstOutput.Items.Add("信息 " + gpMessages.GetMessage(i).Description);
                                    break;
                            }
                        }
                    }

                    axMapControl1.Refresh();
                    lstOutput.Items.Add("Successful");
                    this.Cursor = Cursors.Default;
                 }
    (D)上下效果图

  • 相关阅读:
    eclipse报错:发现了以元素 'd:skin' 开头的无效内容。此处不应含有子元素
    深入解析_Android的自定义布局
    RSA算法加密解密
    android版本
    TabHost+RadioGroup搭建基础布局
    android横竖屏控制
    一大波静态方法
    有时候
    简单的dialog菜单
    mongodb学习(三)——函数使用的小技巧
  • 原文地址:https://www.cnblogs.com/arxive/p/6262427.html
Copyright © 2020-2023  润新知