建構網絡有兩種方式,分别是網絡資料集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;
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)上下效果圖
沒有整理與歸納的知識,一文不值!高度概括與梳理的知識,才是自己真正的知識與技能。 永遠不要讓自己的自由、好奇、充滿創造力的想法被現實的架構所束縛,讓創造力自由成長吧! 多花時間,關心他(她)人,正如别人所關心你的。理想的騰飛與實作,沒有别人的支援與幫助,是萬萬不能的。
本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/arxive/p/6262427.html,如需轉載請自行聯系原作者