ArcEngine 地圖導航 查詢路徑 經緯度座標導航 最優路徑分析
阿新 • • 發佈:2019-01-30
本文來自CSDN部落格,轉載請標明出處 http//blog.csdn.net/zdb330906531
需求:根據經緯度座標,取得兩個起點與終點,顯示最優路徑實現導航。
參考官方例子後,我在arcMap上已實現效果,要求改為程式碼實現。
實現思路:1、建立路徑 2、新增位置 3、求解
程式碼如下:
① 建立路徑
呼叫方法:public INAContext CreateSolverContext(INetworkDataset networkDataset) { IDENetworkDataset deNDS = GetDENetworkDataset(networkDataset); INASolver naSolver = new NARouteSolver();//路徑(NAClosestFacilitySolver 最近設施) INAContextEdit contextEdit = naSolver.CreateContext(deNDS, naSolver.Name) as INAContextEdit; contextEdit.Bind(networkDataset, new GPMessagesClass()); return contextEdit as INAContext; } public IDENetworkDataset GetDENetworkDataset(INetworkDataset networkDataset) { IDatasetComponent dsComponent = networkDataset as IDatasetComponent; return dsComponent.DataElement as IDENetworkDataset; }
ILayer ilayer = MapLayerHelper.GetLayerByName(axMapControl1.Map, "道路_ND");
INetworkDataset networkDataset = (ilayer as INetworkLayer).NetworkDataset;//網路資料集
INAContext m_NAContext = CreateSolverContext(networkDataset);
② 新增位置
/// <summary> /// 在記憶體中建立圖層 /// </summary> /// <param name="DataSetName">資料集名稱(所建圖層名稱)</param> /// <param name="AliaseName">別名</param> /// <param name="SpatialRef">空間參考</param> /// <param name="GeometryType">幾何型別</param> /// <param name="PropertyFields">屬性欄位集合</param> /// <returns>IfeatureLayer</returns> public static IFeatureLayer CreateFeatureLayerInMemeory(string DataSetName, string AliaseName, ISpatialReference SpatialRef, esriGeometryType GeometryType, IFields PropertyFields) { ESRI.ArcGIS.Geodatabase.IWorkspaceFactory workspaceFactory = new ESRI.ArcGIS.DataSourcesGDB.InMemoryWorkspaceFactoryClass(); ESRI.ArcGIS.Geodatabase.IWorkspaceName workspaceName = workspaceFactory.Create("", "MyWorkspace", null, 0); ESRI.ArcGIS.esriSystem.IName name = (IName)workspaceName; ESRI.ArcGIS.Geodatabase.IWorkspace inmemWor = (IWorkspace)name.Open(); IField oField = new FieldClass(); IFields oFields = new FieldsClass(); IFieldsEdit oFieldsEdit = null; IFieldEdit oFieldEdit = null; IFeatureClass oFeatureClass = null; IFeatureLayer oFeatureLayer = null; try { oFieldsEdit = oFields as IFieldsEdit; oFieldEdit = oField as IFieldEdit; if (PropertyFields != null) { for (int i = 0; i < PropertyFields.FieldCount; i++) { oFieldsEdit.AddField(PropertyFields.get_Field(i)); } } IGeometryDef geometryDef = new GeometryDefClass(); IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef; geometryDefEdit.AvgNumPoints_2 = 5; geometryDefEdit.GeometryType_2 = GeometryType; geometryDefEdit.GridCount_2 = 1; geometryDefEdit.HasM_2 = false; geometryDefEdit.HasZ_2 = false; geometryDefEdit.SpatialReference_2 = SpatialRef; oFieldEdit.Name_2 = "SHAPE"; oFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry; oFieldEdit.GeometryDef_2 = geometryDef; oFieldEdit.IsNullable_2 = true; oFieldEdit.Required_2 = true; oFieldsEdit.AddField(oField); oFeatureClass = (inmemWor as IFeatureWorkspace).CreateFeatureClass(DataSetName, oFields, null, null, esriFeatureType.esriFTSimple, "SHAPE", ""); (oFeatureClass as IDataset).BrowseName = DataSetName; oFeatureLayer = new FeatureLayerClass(); oFeatureLayer.Name = AliaseName; oFeatureLayer.FeatureClass = oFeatureClass; } catch {} finally { System.Runtime.InteropServices.Marshal.ReleaseComObject(oField); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFields); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldsEdit); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldEdit); System.Runtime.InteropServices.Marshal.ReleaseComObject(name); System.Runtime.InteropServices.Marshal.ReleaseComObject(workspaceFactory); System.Runtime.InteropServices.Marshal.ReleaseComObject(workspaceName); System.Runtime.InteropServices.Marshal.ReleaseComObject(inmemWor); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFeatureClass); GC.Collect(); } return oFeatureLayer; }
INAClassLoader classLoader = new NAClassLoader(); classLoader.Locator = m_NAContext.Locator; classLoader.Locator.SnapTolerance = 100; classLoader.NAClass = m_NAContext.NAClasses.get_ItemByName("Stops") as INAClass; //新增起點與終點位置 string[] startCoordinate = textBox1.Text.Split(','); string[] endCoordinate = textBox2.Text.Split(','); double x1 = SpatialReferenceHelper.ConvertDegreesToDigital(startCoordinate[0]); double y1 = SpatialReferenceHelper.ConvertDegreesToDigital(startCoordinate[1]); double x2 = SpatialReferenceHelper.ConvertDegreesToDigital(endCoordinate[0]); double y2 = SpatialReferenceHelper.ConvertDegreesToDigital(endCoordinate[1]); IPoint startPoint = new PointClass(); startPoint.PutCoords(x1, y1); startPoint.SpatialReference = LocateHelper.GeoCoordinateSystem; startPoint.Project(mainForm.MapForm.axMapControl1.SpatialReference); IPoint endPoint = new PointClass(); endPoint.PutCoords(x2, y2); endPoint.SpatialReference = LocateHelper.GeoCoordinateSystem; endPoint.Project(mainForm.MapForm.axMapControl1.SpatialReference); IFeatureLayer featurelayer = MapApi.CreateFeatureLayerInMemeory("點圖層", "點圖層", LocateHelper.GeoCoordinateSystem, esriGeometryType.esriGeometryPoint, null); IFeature feature = featurelayer.FeatureClass.CreateFeature(); feature.Shape = startPoint; feature.Store(); feature = featurelayer.FeatureClass.CreateFeature(); feature.Shape = endPoint; feature.Store();
③ 求解(這裡建議 try catch 一下)
int rowsIn = 0, rowsLocated = 0;
IFeatureCursor featureCursor = featurelayer.FeatureClass.Search(null, true);
classLoader.Load((ICursor)featureCursor, null, ref rowsIn, ref rowsLocated);
((INAContextEdit)m_NAContext).ContextChanged();
IGPMessages gpMessages = new GPMessagesClass();
m_NAContext.Solver.Solve(m_NAContext, gpMessages, null); //求解
好了,進行到這裡的時候就能看到導航效果了。附圖一張
遇到的問題:由於不存在 Network Analyst 許可,操作失敗。
參考官方例子 ClosestFacilitySolver 重新授權即可
參考資料:
http://resources.arcgis.com/zh-cn/help/main/10.1/index.html#//00470000005w000000
http://download.csdn.net/download/PMC_520/766131
http://blog.csdn.net/chanyinhelv/article/details/15498845