arcgis Engine C# 最短路径分析实现部分关键代码。

时间:2015-1-30    作者:悬浮的青春    分类: gis二次开发


不废话了。下面直接贴代码。有兴趣的自己看吧。看看有没有你想要的。

 public void Initial(IFeatureWorkspace workspace)
        {
            axMapControl1.ClearLayers();
            pFeatureWorkspace = workspace;
            pNetworkDataset = OpenNetworkDataset_Other(pFeatureWorkspace as IWorkspace, "XX_ND", "XX");

            pNAContext = CreateNAContext(pNetworkDataset);
           

            pVertexFC = pFeatureWorkspace.OpenFeatureClass("XX_ND_Junctions");

            IFeatureLayer pVertexFL = new FeatureLayerClass();
            pVertexFL.FeatureClass = pFeatureWorkspace.OpenFeatureClass("XX_ND_Junctions");
            pVertexFL.Name = pVertexFL.FeatureClass.AliasName;
            axMapControl1.AddLayer(pVertexFL, 0);

            IFeatureLayer pRoadFL = new FeatureLayerClass();
            pRoadFL.FeatureClass = pFeatureWorkspace.OpenFeatureClass("ROA_NATROAD");
            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 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 NARouteSolver();
            INAContextEdit pNAContextEdit = pNASolver.CreateContext(pDENetworkDataset, pNASolver.Name) as INAContextEdit;
            pNAContextEdit.Bind(networkDataset, new GPMessagesClass());
            return pNAContextEdit as INAContext;
        }


 //得到创建网络分析上下文所需的IDENetworkDataset类型参数 
        private IDENetworkDataset GetDENetworkDataset(INetworkDataset networkDataset)
        {
            //QI from the Network Dataset to the DatasetComponent
            IDatasetComponent dsComponent;
            dsComponent = networkDataset as IDatasetComponent;
            //Get the Data Element
            return dsComponent.DataElement as IDENetworkDataset;
        }

        //根据点图层确定最短路径所用经历的点
        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 NAClassLoader();
            pNAClassLoader.Locator = pNAContext.Locator;
            if (dSnapTolerance > 0)
                pNAClassLoader.Locator.SnapTolerance = dSnapTolerance;
            pNAClassLoader.NAClass = pNAClass;

            //字段匹配
            INAClassFieldMap pNAClassFieldMap = new NAClassFieldMap();
            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 = inputFC.Search(null, true);
            pNAClassLoader.Load((ICursor)pFeatureCursor, null, ref iRows, ref iRowsLocated);
            ((INAContextEdit)pNAContext).ContextChanged();
        }



 public void Solve(IPointCollection m_ipPoints)
        {
            try
            {
                ISpatialReference SR = GetSpatialReferenceFromDataset(pNetworkDataset as IDataset);
                IFields fields = CreateFields();
                IFeatureLayer stoplayer = CreateFeatureLayerInmemeory("stop", "起止点", SR, esriGeometryType.esriGeometryPoint, fields);


                CreateFeature(stoplayer.FeatureClass, m_ipPoints);



                //
                LoadNANetWorkLocations("Stops", stoplayer.FeatureClass, Convert.ToDouble(ConfigurationManager.AppSettings.Get("RAnalystSnap").ToString()));
                IGPMessages gpMessages = new GPMessagesClass();
                INASolver naSolver = pNAContext.Solver;
                //INAClosestFacilitySolver nasolver=pNAContext.s
                //SetSolverSettings();可以默认设置。如果想设置开启此方法
                try
                {
                    pNAContext.Solver.Solve(pNAContext, gpMessages, new CancelTrackerClass());

                }
                catch
                {
                    MessageBox.Show("无路径分析结果", "提示"); return;
                }
                if (gpMessages != null)
                {
                }

                axMapControl1.Refresh();

                this.Cursor = Cursors.Default;

                IFeatureClass resultdata = pNAContext.Result.NAContext.NAClasses.get_ItemByName("Routes") as IFeatureClass;
                //Route或者路径。主要是汉化的问题。
                //这里就得到结果了。得到之后随便你怎么处理。我是导出来了。

//导出方法。


 ExportFeature(resultdata);
            }
            catch
            {

            }
        }

 #region 创建路径点图层
        /// <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 IFeatureLayer CreateFeatureLayerInmemeory(string DataSetName, string AliaseName, ISpatialReference SpatialRef, esriGeometryType GeometryType, IFields PropertyFields)
        {
            IWorkspaceFactory workspaceFactory = new 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;

                for (int i = 0; i < PropertyFields.FieldCount; i++)
                {
                    oFieldsEdit.AddField(PropertyFields.get_Field(i));
                }

                //IGeometryDef Interface Provides access to members that return information about the geometry definition
                IGeometryDef geometryDef = new GeometryDefClass();
                //IGeometryDefEdit Provides access to members that modify the geometry definition
                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 FeatureLayer();
                oFeatureLayer.Name = AliaseName;
                oFeatureLayer.FeatureClass = oFeatureClass;
            }
            catch
            {
            }
            finally
            {
                try
                {
                    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);
                }
                catch { }

                GC.Collect();
            }
            return oFeatureLayer;
        }
        /// <summary>
        /// 创建fields
        /// </summary>
        /// <returns></returns>
        public IFields CreateFields()
        {
            IFields fields = new FieldsClass();
            // create the fields using the required fields method
            IObjectClassDescription objectClassDescription = new ObjectClassDescriptionClass();
            fields = objectClassDescription.RequiredFields;
            ESRI.ArcGIS.Geodatabase.IFieldsEdit fieldsEdit = (ESRI.ArcGIS.Geodatabase.IFieldsEdit)fields; // Explicit Cast
            ESRI.ArcGIS.Geodatabase.IField field = new ESRI.ArcGIS.Geodatabase.FieldClass();

            // create a user defined text field
            ESRI.ArcGIS.Geodatabase.IFieldEdit fieldEdit = (ESRI.ArcGIS.Geodatabase.IFieldEdit)field; // Explicit Cast

            // setup field properties
            fieldEdit.Name_2 = "SampleField";
            fieldEdit.Type_2 = ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeString;
            fieldEdit.IsNullable_2 = true;
            fieldEdit.AliasName_2 = "Sample Field Column";
            fieldEdit.DefaultValue_2 = "test";
            fieldEdit.Editable_2 = true;
            fieldEdit.Length_2 = 100;

            // add field to field collection
            fieldsEdit.AddField(field);
            fields = (ESRI.ArcGIS.Geodatabase.IFields)fieldsEdit; // Explicit Cast
            return fields;
            //}
            //return null;
        }
        /// <summary>
        /// 获取dataset的空间参考
        /// </summary>
        /// <param name="dataset"></param>
        /// <returns></returns>
        public ISpatialReference GetSpatialReferenceFromDataset(IDataset dataset)
        {
            //If the dataset supports IGeoDataset
            if (dataset is IGeoDataset)
            {
                //then grab the spatial reference information and return it.
                IGeoDataset geoDataset = (IGeoDataset)dataset;
                return geoDataset.SpatialReference;
            }
            else
            {
                return null; //otherwise return null
            }
        }
        /// <summary>
        /// 在featureclass 中添加 点集
        /// </summary>
        /// <param name="featureClass"></param>
        /// <param name="PointCollection"></param>
        public void CreateFeature(IFeatureClass featureClass, IPointCollection PointCollection)
        {
            // Ensure the feature class contains points.
            if (featureClass.ShapeType != esriGeometryType.esriGeometryPoint)
            {
                return;
            }

            // Build the feature.
            for (int i = 0; i < PointCollection.PointCount; i++)
            {
                IFeature feature = featureClass.CreateFeature();
                feature.Shape = PointCollection.get_Point(i);


                // Apply the appropriate subtype to the feature.
                ISubtypes subtypes = (ISubtypes)featureClass;
                IRowSubtypes rowSubtypes = (IRowSubtypes)feature;
                if (subtypes.HasSubtype)
                {
                    // In this example, the value of 3 represents the Cross subtype.
                    rowSubtypes.SubtypeCode = 3;
                }

                // Initialize any default values the feature has.
                rowSubtypes.InitDefaultValues();

                // Update the value on a string field that indicates who installed the feature.
                //int contractorFieldIndex = featureClass.FindField("CONTRACTOR");
                //feature.set_Value(contractorFieldIndex, "K Johnston");

                // Commit the new feature to the geodatabase.
                feature.Store();
            }
        }

  /// <summary>
        /// 导出路径
        /// </summary>
        /// <param name="apFeatureClass"></param>
        public void ExportFeature(IFeatureClass apFeatureClass)
        {

            if (apFeatureClass == null)
            {

                MessageBox.Show("分析出错,请检查路径分析结果", "系统提示");
                return;

            }

            string ExportFileShortName = "最短路径";
            string ExportFilePath = Application.StartupPath;

            //设置导出要素类的参数
            IFeatureClassName pOutFeatureClassName = new FeatureClassNameClass();
            IDataset pOutDataset = (IDataset)apFeatureClass;
            pOutFeatureClassName = (IFeatureClassName)pOutDataset.FullName;
            //创建一个输出shp文件的工作空间
            IWorkspaceFactory pShpWorkspaceFactory = new ShapefileWorkspaceFactory();
            IWorkspaceName pInWorkspaceName = new WorkspaceNameClass();
            pInWorkspaceName = pShpWorkspaceFactory.Create(ExportFilePath, FilePath, null, 0);

            //创建一个要素集合
            IFeatureDatasetName pInFeatureDatasetName = null;
            //创建一个要素类
            IFeatureClassName pInFeatureClassName = new FeatureClassNameClass();
            IDatasetName pInDatasetClassName;
            pInDatasetClassName = (IDatasetName)pInFeatureClassName;
            pInDatasetClassName.Name = ExportFileShortName;//作为输出参数
            pInDatasetClassName.WorkspaceName = pInWorkspaceName;
            //通过FIELDCHECKER检查字段的合法性,为输出SHP获得字段集合
            long iCounter;
            IFields pOutFields, pInFields;
            IFieldChecker pFieldChecker;
            IField pGeoField;
            IEnumFieldError pEnumFieldError = null;
            pInFields = apFeatureClass.Fields;
            pFieldChecker = new FieldChecker();
            pFieldChecker.Validate(pInFields, out pEnumFieldError, out pOutFields);
            //通过循环查找几何字段
            pGeoField = null;
            for (iCounter = 0; iCounter < pOutFields.FieldCount; iCounter++)
            {
                if (pOutFields.get_Field((int)iCounter).Type == esriFieldType.esriFieldTypeGeometry)
                {
                    pGeoField = pOutFields.get_Field((int)iCounter);
                    break;
                }
            }
            //得到几何字段的几何定义
            IGeometryDef pOutGeometryDef;
            IGeometryDefEdit pOutGeometryDefEdit;
            pOutGeometryDef = pGeoField.GeometryDef;
            //设置几何字段的空间参考和网格
            pOutGeometryDefEdit = (IGeometryDefEdit)pOutGeometryDef;
            pOutGeometryDefEdit.GridCount_2 = 1;
            pOutGeometryDefEdit.set_GridSize(0, 1500000);
            try
            {
                //开始导入
                IFeatureDataConverter pShpToClsConverter = new FeatureDataConverterClass();
                pShpToClsConverter.ConvertFeatureClass(pOutFeatureClassName, null, pInFeatureDatasetName, pInFeatureClassName, pOutGeometryDef, pOutFields, "", 1000, 0);
                Console.WriteLine("导出成功");



标签: arcgis二次开发

WRITTEN BY

avatar


评论:

ZXX 2020-03-18 01:35
你好,我现在已经分析出了最短路径,但是我想提取出路径所经过的所有结点,请问该怎么弄啊?
悬浮的青春 2020-04-27 09:43
@ZXX:你看下分析后的结果吧。里面其实就有的。
GIS 2019-12-06 10:20
你好,有二三维联动的代码没
悬浮的青春 2019-12-26 10:35
@GIS:你好。有和skyline联动的代码。有写部分文章。
gis 2019-07-12 15:28
请问如何找出行驶路径啊?
悬浮的青春 2019-07-22 16:54
@gis:IFeatureClass resultdata = pNAContext.Result.NAContext.NAClasses.get_ItemByName("Routes") as IFeatureClass;
                //Route或者路径。主要是汉化的问题。
                //这里就得到结果了。得到之后随便你怎么处理。我是导出来了。
lamp 2015-12-31 10:54
亲,我只想要实现输入两个点,求他们之间在路网上的最短路径的距离长度。这个怎么求?
悬浮的青春 2016-01-05 16:20
@lamp:最短路径求出之后,最短路径的属性里面有这个路径的长度。
悬浮的青春 2016-01-05 16:24
@lamp:路径的长度单位就是地图的单位。