构建网络有两种方式,分别是网络数据集NetworkDataset和几何网络Geometric Network,这个网络结构数据的创建直接在Catalog中实现创建,进行最短路径分析,为了直接使用ArcGIS提供的功能,我选用的是NetworkDataset,主要记录下考虑单双行的最短路径的设计与实现(理想状态,不考虑转弯等要素)。

(A)对数据编辑的要求有一下几点:

(1) 添加属性字段,名称为Oneway,类型Text,默认值为空。

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

(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)上下效果图

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

 


你们的评论、反馈,及对你们有所用,是我整理材料和博文写作的最大的鼓励和唯一动力。欢迎讨论和关注!

没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。