/// <summary> /// operation solve trace /// </summary> /// <returns>solve trace</returns> public override JsonObject Solve() { try { if ((this.edgeFlags.Length == 0) && (this.junctionFlags.Length == 0)) { string message = "No input valid flags found"; if (this.flagNotFound.Count == 0) { throw new GeometricNetworkException(message); } else { JsonObject error = (new ObjectError(message)).ToJsonObject(); error.AddArray("flagsNotFound", Helper.GetListJsonObjects(this.flagNotFound)); if (this.barrierNotFound.Count > 0) { error.AddArray("barriersNotFound", Helper.GetListJsonObjects(this.barrierNotFound)); } return(error); } } ITraceFlowSolverGEN traceFlowSolver = new TraceFlowSolverClass() as ITraceFlowSolverGEN; INetSolver netSolver = traceFlowSolver as INetSolver; INetwork network = this.geometricNetwork.Network; netSolver.SourceNetwork = network; // flag origin this.SetFlagsOrigin(ref traceFlowSolver); // barrier this.SetBarriers(ref traceFlowSolver); // set disabled layers foreach (int i in this.DisableLayers) { netSolver.DisableElementClass(i); } // set weight this.SetWeights(ref traceFlowSolver); if ((this.TraceSolverType != TraceSolverType.FindCircuits) && (this.TraceSolverType != TraceSolverType.FindCommonAncestors)) { // The TraceIndeterminateFlow property affects the trace results of trace solvers whose FlowMethod parameter is esriFMUpstream or esriFMDownstream if ((this.FlowMethod == esriFlowMethod.esriFMDownstream) || (this.FlowMethod == esriFlowMethod.esriFMUpstream)) { traceFlowSolver.TraceIndeterminateFlow = this.TraceIndeterminateFlow; } } IEnumNetEID junctionEIDs = null; IEnumNetEID edgeEIDs = null; object totalCost; int count; object[] segmentCosts; JsonObject objectJson = new JsonObject(); switch (this.TraceSolverType) { case TraceSolverType.FindAccumulation: traceFlowSolver.FindAccumulation(this.FlowMethod, this.FlowElements, out junctionEIDs, out edgeEIDs, out totalCost); objectJson.AddDouble("totalCost", (double)totalCost); break; case TraceSolverType.FindCircuits: traceFlowSolver.FindCircuits(this.FlowElements, out junctionEIDs, out edgeEIDs); break; case TraceSolverType.FindCommonAncestors: traceFlowSolver.FindCommonAncestors(this.FlowElements, out junctionEIDs, out edgeEIDs); break; case TraceSolverType.FindFlowElements: traceFlowSolver.FindFlowElements(this.FlowMethod, this.FlowElements, out junctionEIDs, out edgeEIDs); break; case TraceSolverType.FindFlowEndElements: traceFlowSolver.FindFlowEndElements(this.FlowMethod, this.FlowElements, out junctionEIDs, out edgeEIDs); break; case TraceSolverType.FindFlowUnreachedElements: traceFlowSolver.FindFlowUnreachedElements(this.FlowMethod, this.FlowElements, out junctionEIDs, out edgeEIDs); break; case TraceSolverType.FindPath: count = Math.Max(this.junctionFlags.Length, this.edgeFlags.Length); if (count < 2) { throw new GeometricNetworkException("Edge or junction found < 2!"); } --count; segmentCosts = new object[count]; traceFlowSolver.FindPath(this.FlowMethod, this.ShortestPathObjFn, out junctionEIDs, out edgeEIDs, count, ref segmentCosts); objectJson.AddArray("segmentCosts", segmentCosts); break; case TraceSolverType.FindSource: count = this.junctionFlags.Length + this.edgeFlags.Length; segmentCosts = new object[count]; traceFlowSolver.FindSource(this.FlowMethod, this.ShortestPathObjFn, out junctionEIDs, out edgeEIDs, count, ref segmentCosts); objectJson.AddArray("segmentCosts", segmentCosts); break; case TraceSolverType.FindLongest: // get end junctions in upstream IEnumNetEID junctionEIDsFindLongest = null; IEnumNetEID edgeEIDsFindLongest = null; traceFlowSolver.FindFlowEndElements(esriFlowMethod.esriFMUpstream, esriFlowElements.esriFEJunctions, out junctionEIDsFindLongest, out edgeEIDsFindLongest); int? eidLongest = null; double eidLongestLenght = double.MinValue; if (junctionEIDsFindLongest.Count > 0) { double eidLongestLenghtCurrent = double.NaN; for (int i = 0; i < junctionEIDsFindLongest.Count; i++) { int netEIDCurrent = junctionEIDsFindLongest.Next(); object[] segmentLenghts = new object[1]; IEnumNetEID junctionEIDsLongest = null; IEnumNetEID edgeEIDsLongest = null; INetFlag netFlag = new JunctionFlagClass(); INetElements netElements = this.geometricNetwork.Network as INetElements; int featureClassID, featureID, subID; netElements.QueryIDs(netEIDCurrent, esriElementType.esriETJunction, out featureClassID, out featureID, out subID); netFlag.UserClassID = featureClassID; netFlag.UserID = featureID; netFlag.UserSubID = subID; IJunctionFlag[] junctionFlags = new IJunctionFlag[] { this.junctionFlags[0], netFlag as IJunctionFlag }; traceFlowSolver.PutJunctionOrigins(ref junctionFlags); traceFlowSolver.FindPath(esriFlowMethod.esriFMUpstream, esriShortestPathObjFn.esriSPObjFnMinMax, out junctionEIDsLongest, out edgeEIDsLongest, 1, ref segmentLenghts); if (segmentLenghts[0] != null) { eidLongestLenghtCurrent = Convert.ToDouble(segmentLenghts[0]); if (eidLongestLenghtCurrent > eidLongestLenght) { eidLongestLenght = eidLongestLenghtCurrent; eidLongest = netEIDCurrent; edgeEIDs = edgeEIDsLongest; junctionEIDs = junctionEIDsLongest; } } } } else { throw new GeometricNetworkException("Junction end not found!"); } if (eidLongest.HasValue) { objectJson.AddDouble("totalCost", eidLongestLenght); } else { throw new GeometricNetworkException("EID longest not found!"); } break; default: throw new GeometricNetworkException("Trace solver type not found"); } this.SetResults(ref objectJson, edgeEIDs, junctionEIDs); objectJson.AddArray("flagsNotFound", Helper.GetListJsonObjects(this.flagNotFound)); objectJson.AddArray("barriersNotFound", Helper.GetListJsonObjects(this.barrierNotFound)); return(objectJson); } catch (Exception e) { return((new ObjectError(e.Message)).ToJsonObject()); } }