|
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. |