【原】ArcEngine中最短路径的实现(二)
最短路径分析属于ArcGIS的网络分析范畴。而ArcGIS的网络分析分为两类,分别是基于几何网络和网络数据集的网络分析。它们都可以实现最短路径功能...
上次介绍了用几何网络实现的“最短路径”,这次用网络数据集实现真正的最短路径功能,跟上次一样,先处理下数据。
1、先打开ArcCatalog,连接到目标文件夹,假定该文件下有一个名为road的道路图层。
2、在road图层上右键新建一个网络数据集,并按照其默认设置直至完成。
3、打开该地图的工作空间,把刚才新建的网络数据集添加工作空间中。
4、在网络分析菜单中选择新建最近设施点。
这时在工作空间里,可以看到多了一个名为“Closest Facility”的图层。它下面还有4个子图层,名字分别为“Facilities”,“Incidents”,“Barriers”,“Routes”。“Facilities”就是设施点图层,也就是目的点,“Incidents”的意思就是出发点,“Barriers”是障碍点,意思就是地图某条道路附近有一个障碍点,如果障碍点与道路距离在容限范围内,则表示此道路不通,“Routes”就是最终的结果。这样我们编程实现最短路径的思路就出现了:
1、添加出发点。
2、添加目的点。
3、生成最优路径,获取结果。
这里的添加出发点或者目的点,是往“Facilities”或“Incidents”图层上添加元素。获取结果也是从“Routes”中获取Polyline。往“Facilities”或“Incidents”图层上添加元素用到的主要方法是INALocator的QueryLocationByPoint函数,生成路径主要接口是INASolver和它的Solve方法。获取结果是按属性查找,因为“Routes”类其实就是一个图层类,只不过只是存在于内存。
1
CMapControlDefault m_map;2
IPointCollectionPtr m_ipPointCollection;3

4
ILayerPtr ipLayer = m_map.GetLayer(0); // 网络数据集5
INALayerPtr ipNaLayer = ipLayer;6
if (NULL == ipNaLayer)7

{8
return;9
}10
11
INAContextPtr ipNaContext;12
HRESULT hr = ipNaLayer->get_Context(&ipNaContext);13
INAClassLoaderPtr ipNAClassLoader(CLSID_NAClassLoader);14
INALocatorPtr ipNALocator = NULL;15
hr = ipNaContext->get_Locator(&ipNALocator);16
ipNALocator->put_SnapToleranceUnits(esriMeters);17
ipNALocator->put_SnapTolerance(200);18
ipNaContext;19
hr = ipNAClassLoader->putref_Locator(ipNALocator);20
21
INamedSetPtr ipNamedSet = NULL;22
ipNaContext->get_NAClasses(&ipNamedSet);23
24
CString szName = "Facilities";25
BSTR bstrName = szName.AllocSysString();26
INAClassPtr ipNAFacilitiesClass = NULL;27
hr = ipNamedSet->get_ItemByName(bstrName, (IUnknown**)&ipNAFacilitiesClass);28
szName = "Incidents";29
bstrName = szName.AllocSysString();30
INAClassPtr ipNAIncidentsClass = NULL;31
hr = ipNamedSet->get_ItemByName(bstrName, (IUnknown**)&ipNAIncidentsClass);32
szName = "CFRoutes";33
bstrName = szName.AllocSysString();34
INAClassPtr ipNARoutesClass = NULL;35
hr = ipNamedSet->get_ItemByName(bstrName, (IUnknown**)&ipNARoutesClass);36
37
INALocationPtr ipNALocation1(CLSID_NALocation);38
INALocationPtr ipNALocation2(CLSID_NALocation);39
ipNAClassLoader->get_Locator(&ipNALocator);40
IPointPtr ipBeginPoint(CLSID_Point);41
m_ipPointCollection->get_Point(0, &ipBeginPoint);42
IPointPtr ipEndPoint(CLSID_Point);43
m_ipPointCollection->get_Point(1, &ipEndPoint);44
IPointPtr ipPoint1(CLSID_Point);45
IPointPtr ipPoint2(CLSID_Point);46
double dbLVal = 0.0;47
ipNALocator->QueryLocationByPoint(ipBeginPoint, &ipNALocation1, &ipPoint1, &dbLVal);48
ipNALocator->QueryLocationByPoint(ipEndPoint, &ipNALocation2, &ipPoint2, &dbLVal);49
50
INALocationObjectPtr ipNALocationObject = NULL;51
IFeatureClassPtr ipFeatureClass = ipNAIncidentsClass;52
IFeaturePtr ipFeature = NULL;53
ipFeatureClass->CreateFeature(&ipFeature);54
IRowSubtypesPtr ipRowSubtypes = ipFeature;55
ipRowSubtypes->InitDefaultValues();56
ipFeature->putref_Shape(ipBeginPoint);57
ITablePtr ipTable = NULL;58
ipFeature->get_Table(&ipTable);59
long nIndex = 0;60
szName = "Sequence";61
bstrName = szName.AllocSysString();62
ipTable->FindField(bstrName, &nIndex);63
VARIANT var_int;64
var_int.intVal = 1;65
var_int.vt = VT_INT;66
ipFeature->put_Value(nIndex, var_int);67
szName = "Name";68
bstrName = szName.AllocSysString();69
ipTable->FindField(bstrName, &nIndex);70
ipFeature->put_Value(nIndex, COleVariant("Start Point"));71
ipNALocationObject = ipFeature;72
ipNALocationObject->put_NALocation(ipNALocation1);73
ipFeature->Store();74
IFieldsPtr ipFields(CLSID_Fields);75
hr = ipTable->get_Fields(&ipFields);76
long nFieldCount = 0;77
hr = ipFields->get_FieldCount(&nFieldCount);78
for (int k = 0; k < nFieldCount; k++)79

{80
IFieldPtr ipField(CLSID_Field);81
ipFields->get_Field(k, &ipField);82
BSTR bstrFieldName;83
ipField->get_Name(&bstrFieldName);84
CString szFieldName = bstrFieldName;85
}86
87
ipFeatureClass = ipNAFacilitiesClass;88
ipFeatureClass->CreateFeature(&ipFeature);89
ipRowSubtypes = ipFeature;90
ipRowSubtypes->InitDefaultValues();91
ipFeature->putref_Shape(ipEndPoint);92
ipTable = NULL;93
ipFeature->get_Table(&ipTable);94
nIndex = 0;95
szName = "Sequence";96
bstrName = szName.AllocSysString();97
ipTable->FindField(bstrName, &nIndex);98
var_int.intVal = 2;99
ipFeature->put_Value(nIndex, var_int);100
szName = "Name";101
bstrName = szName.AllocSysString();102
ipTable->FindField(bstrName, &nIndex);103
ipFeature->put_Value(nIndex, COleVariant("End Point"));104
ipNALocationObject = ipFeature;105
ipNALocationObject->put_NALocation(ipNALocation2);106
ipFeature->Store();107
108
INAClosestFacilitySolverPtr ipNACFSolver = NULL;109
INASolverPtr ipNASolver = NULL;110
ipNaContext->get_Solver(&ipNASolver);111
112
IGPMessagesPtr ipGPM(CLSID_GPMessages);113
ITrackCancelPtr ipTrackCancel(CLSID_TrackCancel);114
VARIANT_BOOL bIsPartialSolution;115
ipNASolver->Solve(ipNaContext, ipGPM, ipTrackCancel, &bIsPartialSolution);116
117
szName = "CFRoutes";118
bstrName = szName.AllocSysString();119
ipNARoutesClass = NULL;120
hr = ipNamedSet->get_ItemByName(bstrName, (IUnknown**)&ipNARoutesClass);121
122
IFeatureClassPtr ipFeatureClassRoutes = ipNARoutesClass;123
IFeatureCursorPtr ipFCursor = NULL;124
IQueryFilterPtr ipQueryFilter(CLSID_QueryFilter);125
CString szQueryFilter("ObjectID > 0");126
BSTR bstr_QueryFilter = szQueryFilter.AllocSysString();127
ipQueryFilter->put_WhereClause(bstr_QueryFilter);128
VARIANT_BOOL bCycle = VARIANT_FALSE;129
try130

{131
ipFeatureClassRoutes->Search(ipQueryFilter, bCycle, &ipFCursor);132
}133
catch (CException* e)134

{135
CString szErrorMsg;136
e->GetErrorMessage(szErrorMsg.GetBuffer(MAX_PATH), MAX_PATH);137
szErrorMsg.ReleaseBuffer();138
e->Delete();139
szErrorMsg += "\n";140
OutputDebugStr(szErrorMsg);141
}142
catch (
)143

{144
OutputDebugStr("An Unknowned Exception Occurred!\n");145
}146
147
IFeaturePtr ipLineFeature = NULL;148
hr = ipFCursor->NextFeature(&ipLineFeature);149
while (ipLineFeature != NULL)150

{151
IGeometryPtr ipGeometry = NULL;152
IPolylinePtr ipPolyLine = NULL;153
ipLineFeature->get_Shape(&ipGeometry);154
esriGeometryType type;155
ipGeometry->get_GeometryType(&type);156
if (type == esriGeometryPolyline)157

{158
ipPolyLine = ipGeometry;159
AddPolyline(ipPolyLine, 4);160
}161
hr = ipFCursor->NextFeature(&ipLineFeature);162
}163
IActiveViewPtr ipActiveView = NULL;164
ipActiveView = m_map.GetActiveView();165
ipActiveView->Refresh();

浙公网安备 33010602011771号