天天看點

以Network Dataset(網絡資料集)方式實作的最短路徑分析

建構網絡有兩種方式,分别是網絡資料集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;

            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);

                            default:

                                lstOutput.Items.Add("資訊 " + gpMessages.GetMessage(i).Description);

                        }

                    }

                }

                axMapControl1.Refresh();

                lstOutput.Items.Add("Successful");

                this.Cursor = Cursors.Default;

             }

(D)上下效果圖

以Network Dataset(網絡資料集)方式實作的最短路徑分析

沒有整理與歸納的知識,一文不值!高度概括與梳理的知識,才是自己真正的知識與技能。 永遠不要讓自己的自由、好奇、充滿創造力的想法被現實的架構所束縛,讓創造力自由成長吧! 多花時間,關心他(她)人,正如别人所關心你的。理想的騰飛與實作,沒有别人的支援與幫助,是萬萬不能的。

    本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/arxive/p/6262427.html,如需轉載請自行聯系原作者

繼續閱讀