基于网络数据集的最短路径
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于网络数据集的最短路径
/a/1486719/
在网络找了很久还是没有找到关于网络数据集最短路径分析,全是基于几何网络的,昨天参照AE的ClosestFacilitySolver实例和网上网友发布的在内存建立图层的方法完成了网络数据集的最短路径分析,功能还是比较粗糙,对于高手应该很简单,但是对于刚接触AE的朋友也算是抛砖引玉了。
贴出主要函数:
//打开网络数据集
public INetworkDataset OpenNetworkDataset(IWorkspace networkDatasetWorkspace, System.String networkDatasetName, System.String featureDatasetName)
{
if (networkDatasetWorkspace == null || networkDatasetName == "" || featureDatasetName == null)
{
return null;
}
IDatasetContainer3 datasetContainer3 = null;
switch (networkDatasetWorkspace.Type)
{
case ESRI.ArcGIS.Geodatabase.esriWorkspaceType.esriFileSystemWorkspace:
// Shapefile or SDC network dataset workspace
IWorkspaceExtensionManager workspaceExtensionManager = networkDatasetWorkspace as ESRI.ArcGIS.Geodatabase.IWorkspaceExtensionManager; // Dynamic Cast
ESRI.ArcGIS.esriSystem.UID networkID = new ESRI.ArcGIS.esriSystem.UIDClass();
networkID.Value = "workDatasetWorkspaceExtension";
ESRI.ArcGIS.Geodatabase.IWorkspaceExtension workspaceExtension = workspaceExtensionManager.FindExtension(networkID);
datasetContainer3 = workspaceExtension as IDatasetContainer3; // Dynamic Cast
break;
case ESRI.ArcGIS.Geodatabase.esriWorkspaceType.esriLocalDatabaseWorkspace:
// Personal Geodatabase or File Geodatabase network dataset workspace
case ESRI.ArcGIS.Geodatabase.esriWorkspaceType.esriRemoteDatabaseWorkspace:
// SDE Geodatabase network dataset workspace
ESRI.ArcGIS.Geodatabase.IFeatureWorkspace featureWorkspace = networkDatasetWorkspace as ESRI.ArcGIS.Geodatabase.IFeatureWorkspace; // Dynamic Cast
featureDataset = featureWorkspace.OpenFeatureDataset(featureDatasetName);
ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtensionContainer featureDatasetExtensionContainer = featureDataset as ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtensionContainer; // Dynamic Cast
ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtension featureDatasetExtension = featureDatasetExtensionContainer.FindExtension(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset);
datasetContainer3 = featureDatasetExtension as ESRI.ArcGIS.Geodatabase.IDatasetContainer3; // Dynamic Cast
break;
}
if (datasetContainer3 == null)
return null;
ESRI.ArcGIS.Geodatabase.IDataset dataset = datasetContainer3.get_DatasetByName(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset, networkDatasetName);
return dataset as ESRI.ArcGIS.Geodatabase.INetworkDataset; // Dynamic Cast
}
//创建网络分析上下文
public INAContext CreateSolverContext(INetworkDataset networkDataset)
{
IDENetworkDataset deNDS = GetDENetworkDataset(networkDataset);
INASolver naSolver;
naSolver = new NARouteSolver();
INAContextEdit contextEdit = naSolver.CreateContext(deNDS, ) as INAContextEdit;
contextEdit.Bind(networkDataset, new GPMessagesClass());
return contextEdit as INAContext;
}
//得到创建网络分析上下文所需的IDENetworkDataset类型参数
public 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;
}
///
/// 在内存中创建图层
///
/// 数据集名称(所建图层名称)
/// 别名
/// 空间参考
/// 几何类型
/// 属性字段集合
///
public static 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 th
at 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;
_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();
= 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;
}
//Create fileds
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.Ar
cGIS.Geodatabase.FieldClass();
// create a user defined text field
ESRI.ArcGIS.Geodatabase.IFieldEdit fieldEdit = (ESRI.ArcGIS.Geodatabase.IFieldEdit)field; // Explicit Cast
// setup field properties
_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;
}
//Get Spatial Reference from Dataset
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
}
}
//在要素类创建要素
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();
}
}
//************************************************************
//根据点图层在网络拓扑图层上确定用户要查找最优路径所用经历的点
//************************************************************
public void LoadNANetworkLocations(string strNAClassName, IFeatureClass inputFC, double snapTolerance)
{
INAClass naClass;
INamedSet classes;
classes = m_NAContext.NAClasses;
naClass = classes.get_ItemByName(strNAClassName) as INAClass;
// delete existing Locations except if that a barriers
naClass.DeleteAllRows();
// Create a NAClassLoader and set the snap tolerance (meters unit)
INAClassLoader classLoader = new NAClassLoader();
classLoader.Locator = m_NAContext.Locator;
if (snapTolerance > 0) classLoader.Locator.SnapTolerance = snapTolerance;
classLoader.NAClass = naClass;
//Create field map to automatically map fields from input class to naclass
INAClassFieldMap fieldMap;
fieldMap = new NAClassFieldMap();
fieldMap.CreateMapping(naClass.ClassDefinition, inputFC.Fields);
classLoader.FieldMap = fieldMap;
//Load Network Locations
int rowsIn = 0;
int rowsLocated = 0;
IFeatureCursor featureCursor = inputFC.Search(null, true);
classLoader.Load((ICursor)featureCursor, null, ref rowsIn, ref rowsLocated);
//Message all of the network analysis agents that the analysis context has changed
((INAContextEdit)m_NAContext).ContextChanged();
}
//*********************************************************************************
// Set Solver Settings设置阻抗属性等
//*********************************************************************************
public void SetSolverSettings()
{
//Set Route specific Settings
INASolver naSolver = m_NAContext.Solver;
INARouteSolver cfSolver = naSolver as INARouteSolver;
/*if (txtCutOff.Text.Length > 0 && IsNumeric(txtCutOff.Text.Trim()))
cfSolver.DefaultCutoff = txtCutOff.Text;
else
cfSolver.DefaultCutoff = null;
if (txtTargetFacility.Text.Length > 0 && IsNumeric(txtTargetFacility.Text))
cfSolver.DefaultTargetFacilityCount = int.Parse(txtTargetFacility.Text);
else
cfSolver.DefaultTargetFacilityCount = 1;*/
cfSolver.OutputLines = esriNAOutputLineType.esriNAOutputLineTrueShapeWithMeasure;
cfSolver.CreateTraversalResult =true ;
eTimeWindows = false;
cfSolver.FindBestSequence = false;
cfSolver.PreserveFirstStop = false;
cfSolver.PreserveLastStop
= false;
// Set generic solver settings设置Solver属性,设置路径分析阻抗属性
// Set the impedance attribute
INASolverSettings naSolverSettings;
naSolverSettings = naSolver as INASolverSettings;
naSolverSettings.ImpedanceAttributeName = cboCostAttribute.Text;
// Set the OneWay Restriction if necessary设置单行限制
IStringArray restrictions;
restrictions = naSolverSettings.RestrictionAttributeNames;
restrictions.RemoveAll();
if (chkUseRestriction.Checked)
restrictions.Add("oneway");
naSolverSettings.RestrictionAttributeNames = restrictions;
//Restrict UTurns限制U型转向限制
naSolverSettings.RestrictUTurns = esriNetworkForwardStarBacktrack.esriNFSBNoBacktrack;
naSolverSettings.IgnoreInvalidLocations = true;
// Set the Hierachy attribute设置层次属性
eHierarchy = chkUseHierarchy.Checked;
if (eHierarchy)
{
naSolverSettings.HierarchyAttributeName = "hierarchy";
naSolverSettings.HierarchyLevelCount = 3;
naSolverSettings.set_MaxValueForHierarchy(1, 1);
naSolverSettings.set_NumTransitionToHierarchy(1, 9);
naSolverSettings.set_MaxValueForHierarchy(2, 2);
naSolverSettings.set_NumTransitionToHierarchy(2, 9);
}
// Do not forget to update the context after you set your impedance
naSolver.UpdateContext(m_NAContext, GetDENetworkDataset(m_workDataset), new GPMessagesClass());
}
//*********************************************************************************
// Solve the problem 进行最短路径分析
//*********************************************************************************
public string Solve(INAContext naContext, IGPMessages gpMessages)
{
string errStr = "";
try
{
//Solving the Problem
errStr = "Error when solving";
bool isPartialSolution = naContext.Solver.Solve(naContext, gpMessages, null);
if (!isPartialSolution)
errStr = "OK";
else
errStr = "Partial Solution";
}
catch (Exception e)
{
errStr += " Error Description " + e.Message;
}
return errStr;
}