本文来自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
时间: 2024-10-28 07:36:43