Arcengine Shortest Path Analysis (source code)
Using system;
Using ESRI. ArcGIS. CARTO;
Using ESRI. ArcGIS. geometry;
Using ESRI. ArcGIS. Geodatabase;
Using ESRI. ArcGIS. networkanalysis;
Namespace giseditor
{
/// <Summary>
/// Shortest Path Analysis
/// </Summary>
Public class clspathfinder
{
Private igeometricnetwork m_ipgeometricnetwork;
Private IMAP m_ipmap;
Private ipointcollection m_ippoints;
Private ipointtoeid m_ippointtoeid;
Private double m_dblpathcost = 0;
Private ienumneteid m_ipenumneteid_junctions;
Private ienumneteid m_ipenumneteid_edges;
Private ipolympus m_ippolyline;
# Region Public Function
// Return and set the current map
Public IMAP setorgetmap
{
Set {m_ipmap = value ;}
Get {return m_ipmap ;}
}
// Open the network workspace of the geometric Dataset
Public void openfeaturedatasetnetwork (ifeaturedataset featuredataset)
{
Closeworkspace ();
If (! Initializenetworkandmap (featuredataset ))
Console. writeline ("Network opening error ");
}
// Set of Input Points
Public ipointcollection stoppoints
{
Set {m_ippoints = value ;}
Get {return m_ippoints ;}
}
// Path cost
Public double pathcost
{
Get {return m_dblpathcost ;}
}
// Returns the ry of the path.
Public ipolyline pathpolyline ()
{
Ieidinfo ipeidinfo;
Igeometry ipgeometry;
If (m_ippolyline! = NULL) return m_ippolyline;
M_ippolyline = new polylineclass ();
Igeometrycollection ipnewgeometrycoll = m_ippolyline as igeometrycollection;
Ispatialreference ipspatialreference = m_ipmap.spatialreference;
Ieidhelper ipeidhelper = new eidhelperclass ();
Ipeidhelper. geometricnetwork = m_ipgeometricnetwork;
Ipeidhelper. outputspatialreference = ipspatialreference;
Ipeidhelper. returngeometries = true;
Ienumeidinfo ipenumeidinfo = ipeidhelper. createenumeidinfo (m_ipenumneteid_edges );
Int COUNT = ipenumeidinfo. count;
Ipenumeidinfo. Reset ();
For (INT I = 0; I <count; I ++)
{
Ipeidinfo = ipenumeidinfo. Next ();
Ipgeometry = ipeidinfo. geometry;
Ipnewgeometrycoll. addgeometrycollection (ipgeometry as igeometrycollection );
}
Return m_ippolyline;
}
// Solution path
Public void solvepath (string weightname)
{
Try
{
Int intedgeuserclassid;
Int intedgeuserid;
Int intedgeusersubid;
Int intedgeid;
Ipoint ipfoundedgepoint;
Double dbledgepercent;
/* The second parameter of the putedgeorigins method must be an iedgeflag array,
* In code in other languages such as VB, you only need to pass the first element of the array of this type, that is
* Yes, but the mechanism in C # is different and the following changes need to be made: Use
* Itraceflowsolvergen replaces itraceflowsolver
*/
Itraceflowsolvergen iptraceflowsolver = new traceflowsolverclass () as itraceflowsolvergen;
Inetsolver ipnetsolver = iptraceflowsolver as inetsolver;
Inetwork ipnetwork = m_ipgeometricnetwork.network;
Ipnetsolver. sourcenetwork = ipnetwork;
Inetelements ipnetelements = ipnetwork as inetelements;
Int intcount = m_ippoints.pointcount;
// Define an edge flag Array
Iedgeflag [] pedgeflaglist = new edgeflagclass [intcount];
For (INT I = 0; I <intcount; I ++)
{
Inetflag ipnetflag = new edgeflagclass () as inetflag;
Ipoint ipedgepoint = m_ippoints.get_point (I );
// Find the nearest edge of the Input Point
M_ippointtoeid.getnearestedge (ipedgepoint, out intedgeid, out ipfoundedgepoint, out dbledgepercent );
Ipnetelements. queryids (intedgeid, esrielementtype. esrietedge, out intedgeuserclassid, out intedgeuserid, out intedgeusersubid );
Ipnetflag. userclassid = intedgeuserclassid;
Ipnetflag. userid = intedgeuserid;
Ipnetflag. usersubid = intedgeusersubid;
Iedgeflag ptemp = (iedgeflag) (ipnetflag as iedgeflag );
Pedgeflaglist [I] = ptemp;
}
Iptraceflowsolver. putedgeorigins (ref pedgeflaglist );
Inetschema ipnetschema = ipnetwork as inetschema;
Inetweight ipnetweight = ipnetschema. get_weightbyname (weightname );
Inetsolverweights ipnetsolverweights = iptraceflowsolver as inetsolverweights;
Ipnetsolverweights. fromtoedgeweight = ipnetweight; // start Edge Weight
Ipnetsolverweights. tofromedgeweight = ipnetweight; // terminate Edge Weight
Object [] Vares = new object [intCount-1];
// Obtain the set of edge and intersection through findpath
Iptraceflowsolver. findpath (esriflowmethod. esrifmconnected,
Esrishortestpathobjfn. esrispobjfnminsum,
Out m_ipenumneteid_junations, out m_ipenumneteid_edges, intCount-1, ref Vares );
// Calculate the element cost
M_dblpathcost = 0;
For (INT I = 0; I <Vares. length; I ++)
{
Double m_va = (double) Vares [I];
M_dblpathcost = m_dblpathcost + m_va;
}
M_ippolyline = NULL;
}
Catch (exception ex)
{
Console. writeline (ex. Message );
}
}
# Endregion
# Region private function
// Initialize the ry network and map
Private bool initializenetworkandmap (ifeaturedataset featuredataset)
{
Ifeatureclasscontainer ipfeatureclasscontainer;
Ifeatureclass ipfeatureclass;
Igeodataset ipgeodataset;
Ilayer iPlayer;
Ifeaturelayer ipfeaturelayer;
Ienvelope ipenvelope, ipmaxenvelope;
Double dblsearchtol;
Inetworkcollection ipnetworkcollection = featuredataset as inetworkcollection;
Int COUNT = ipnetworkcollection. geometricnetworkcount;
// Obtain the first geometric network workspace
M_ipgeometricnetwork = ipnetworkcollection. get_geometricnetwork (0 );
Inetwork ipnetwork = m_ipgeometricnetwork.network;
If (m_ipmap! = NULL)
{
M_ipmap = new mapclass ();
Ipfeatureclasscontainer = m_ipgeometricnetwork as ifeatureclasscontainer;
Count = ipfeatureclasscontainer. classcount;
For (INT I = 0; I <count; I ++)
{
Ipfeatureclass = ipfeatureclasscontainer. get_class (I );
Ipfeaturelayer = new featurelayerclass ();
Ipfeaturelayer. featureclass = ipfeatureclass;
M_ipmap.addlayer (ipfeaturelayer );
}
}
Count = m_ipmap.layercount;
Ipmaxenvelope = new envelopeclass ();
For (INT I = 0; I <count; I ++)
{
IPlayer = m_ipmap.get_layer (I );
Ipfeaturelayer = iPlayer as ifeaturelayer;
Ipgeodataset = ipfeaturelayer as igeodataset;
Ipenvelope = ipgeodataset. extent;
Ipmaxenvelope. Union (ipenvelope );
}
M_ippointtoeid = new pointtoeidclass ();
M_ippointtoeid.sourcemap = m_ipmap;
M_ippointtoeid.geometricnetwork = m_ipgeometricnetwork;
Double dblwidth = ipmaxenvelope. width;
Double dblheight = ipmaxenvelope. height;
If (dblwidth> dblheight)
Dblsearchtol = dblwidth/100;
Else
Dblsearchtol = dblheight/100;
M_ippointtoeid.snaptolerance = dblsearchtol;
Return true;
}
// Close the Workspace
Private void closeworkspace ()
{
M_ipgeometricnetwork = NULL;
M_ippoints = NULL;
M_ippointtoeid = NULL;
M_ipenumneteid_junctions = NULL;
M_ipenumneteid_edges = NULL;
M_ippolyline = NULL;
}
# Endregion
}
}
Note:
The order in which the class is called:
Clspathfinder m_ippathfinder;
If (m_ippathfinder = NULL) // open the geometric network workspace
{
M_ippathfinder = new clspathfinder ();
Ipmap = This. m_activeview.focusmap;
IPlayer = ipmap. get_layer (0 );
Ipfeaturelayer = iPlayer as ifeaturelayer;
Ipfdb = ipfeaturelayer. featureclass. featuredataset;
M_ippathfinder.setorgetmap = ipmap;
M_ippathfinder.openfeaturedatasetnetwork (ipfdb );
}
Private void viewmap_onmousedown (Object sender, ESRI. ArcGIS. mapcontrol. imapcontrolevents2_onmousedownevent e) // obtain the point entered by the mouse on the map
{
Ipoint ipnew;
If (m_ippoints = NULL)
{
M_ippoints = new multipointclass ();
M_ippathfinder.stoppoints = m_ippoints;
}
Ipnew = viewmap. activeview. screendisplay. displaytransformation. tomappoint (E. X, E. y );
Object o = type. missing;
M_ippoints.addpoint (ipnew, ref o, ref O );
}
M_ippathfinder.solvepath ("weight"); // parse the path first
Ipolympus ippolyresult = m_ippathfinder.pathpolyline (); // returns the shortest path.