CustomUpstreamTraceTaskCSharp.cs
// Copyright 2012 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.ADF.CATIDs; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.EditorExt; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.NetworkAnalysis; namespace CustomUpstreamTraceTask { [Guid("f759ebca-dcd0-4ddd-be5a-aed8408447e5")] [ClassInterface(ClassInterfaceType.None)] [ProgId("CustomUpstreamTraceTask.CustomUpstreamTraceTaskCSharp")] public sealed class CustomUpstreamTraceTaskCSharp : ITraceTask, ITraceTaskResults { #region COM Registration Function(s) [ComRegisterFunction()] [ComVisible(false)] static void RegisterFunction(Type registerType) { // Required for ArcGIS Component Category Registrar support ArcGISCategoryRegistration(registerType); // // TODO: Add any COM registration code here // } [ComUnregisterFunction()] [ComVisible(false)] static void UnregisterFunction(Type registerType) { // Required for ArcGIS Component Category Registrar support ArcGISCategoryUnregistration(registerType); // // TODO: Add any COM unregistration code here // } #region ArcGIS Component Category Registrar generated code /// <summary> /// Required method for ArcGIS Component Category registration - /// Do not modify the contents of this method with the code editor. /// </summary> private static void ArcGISCategoryRegistration(Type registerType) { string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID); UtilityNetworkTasks.Register(regKey); } /// <summary> /// Required method for ArcGIS Component Category unregistration - /// Do not modify the contents of this method with the code editor. /// </summary> private static void ArcGISCategoryUnregistration(Type registerType) { string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID); UtilityNetworkTasks.Unregister(regKey); } #endregion #endregion private IUtilityNetworkAnalysisExt m_utilNetExt; private IEnumNetEID m_resultJunctions; private IEnumNetEID m_resultEdges; bool ITraceTask.EnableSolve { get { // if there are no networks loaded, then the Solve button is disabled INetworkAnalysisExt nax = m_utilNetExt as INetworkAnalysisExt; if (nax.NetworkCount == 0) return false; // if there is at least one flag on the network, // then enable the Solve button INetworkAnalysisExtFlags naxFlags = m_utilNetExt as INetworkAnalysisExtFlags; if (naxFlags.EdgeFlagCount == 0 && naxFlags.JunctionFlagCount == 0) return false; else return true; } } string ITraceTask.Name { get { return "Custom Upstream Trace"; } } void ITraceTask.OnCreate(IUtilityNetworkAnalysisExt utilityNetworkAnalysis) { m_utilNetExt = utilityNetworkAnalysis; } void ITraceTask.OnTraceExecution() { // prepare the network solver ITraceFlowSolverGEN tfs = UTIL_coreTraceSetup(); if (tfs == null) return; // perform the trace task IEnumNetEID resultJuncs, resultEdges; ITraceTasks traceTasks = m_utilNetExt as ITraceTasks; esriFlowElements flowElements = traceTasks.TraceFlowElements; if (traceTasks.TraceEnds) // find the features stopping the trace tfs.FindFlowEndElements(esriFlowMethod.esriFMUpstream, flowElements, out resultJuncs, out resultEdges); else // return the traced features tfs.FindFlowElements(esriFlowMethod.esriFMUpstream, flowElements, out resultJuncs, out resultEdges); // copy the results to the class level INetworkAnalysisExt nax = m_utilNetExt as INetworkAnalysisExt; if (resultJuncs == null) { // junctions were not returned -- create an empty enumeration IEnumNetEIDBuilder eidBuilder = new EnumNetEIDArrayClass(); eidBuilder.Network = nax.CurrentNetwork.Network; eidBuilder.ElementType = esriElementType.esriETJunction; m_resultJunctions = eidBuilder as IEnumNetEID; } else { m_resultJunctions = resultJuncs; } if (resultEdges == null) { // edges were not returned -- create an empty enumeration IEnumNetEIDBuilder eidBuilder = new EnumNetEIDArrayClass(); eidBuilder.Network = nax.CurrentNetwork.Network; eidBuilder.ElementType = esriElementType.esriETEdge; m_resultEdges = eidBuilder as IEnumNetEID; } else { m_resultEdges = resultEdges; } // update the extension with the results INetworkAnalysisExtResults naxResults = m_utilNetExt as INetworkAnalysisExtResults; naxResults.ClearResults(); // first remove the old results if (naxResults.ResultsAsSelection) naxResults.CreateSelection(resultJuncs, resultEdges); else { naxResults.SetResults(resultJuncs, resultEdges); } } IEnumNetEID ITraceTaskResults.ResultEdges { get { return m_resultEdges; } } IEnumNetEID ITraceTaskResults.ResultJunctions { get { return m_resultJunctions; } } public ITraceFlowSolverGEN UTIL_coreTraceSetup() { // get the current network's logical network INetworkAnalysisExt nax = m_utilNetExt as INetworkAnalysisExt; INetwork net = nax.CurrentNetwork.Network; // create a new TraceFlowSolver object and // set the source network for the solve ITraceFlowSolverGEN tfs = new TraceFlowSolverClass() as ITraceFlowSolverGEN; INetSolver netSolver = tfs as INetSolver; netSolver.SourceNetwork = net; // get the barriers for the network, using the element barriers and // selection barriers that have been added using the user interface INetworkAnalysisExtBarriers naxBarriers = m_utilNetExt as INetworkAnalysisExtBarriers; INetElementBarriers juncElemBarriers, edgeElemBarriers; naxBarriers.CreateElementBarriers(out juncElemBarriers, out edgeElemBarriers); ISelectionSetBarriers selSetBarriers; naxBarriers.CreateSelectionBarriers(out selSetBarriers); netSolver.set_ElementBarriers(esriElementType.esriETJunction, juncElemBarriers); netSolver.set_ElementBarriers(esriElementType.esriETEdge, edgeElemBarriers); netSolver.SelectionSetBarriers = selSetBarriers; // set up the disabled layers for the network solver // for each feature layer belonging to this network, determine if it is // enabled or disabled; if it's disabled, then notify the network solver for (int i = 0; i < nax.FeatureLayerCount; i++) { IFeatureLayer featureLayer = nax.get_FeatureLayer(i); if (naxBarriers.GetDisabledLayer(featureLayer)) netSolver.DisableElementClass(featureLayer.FeatureClass.FeatureClassID); } INetworkAnalysisExtWeightFilter naxWeightFilter = m_utilNetExt as INetworkAnalysisExtWeightFilter; INetSolverWeightsGEN netSolverWeights = netSolver as INetSolverWeightsGEN; INetSchema netSchema = net as INetSchema; // create the junction weight filter int juncFilterRangeCount = naxWeightFilter.get_FilterRangeCount(esriElementType.esriETJunction); if (juncFilterRangeCount > 0) { INetWeight netWeight = netSchema.get_WeightByName(naxWeightFilter.JunctionWeightFilterName); netSolverWeights.JunctionFilterWeight = netWeight; esriWeightFilterType juncWeightFilterType; bool juncApplyNotOperator; naxWeightFilter.GetFilterType(esriElementType.esriETJunction, out juncWeightFilterType, out juncApplyNotOperator); netSolverWeights.SetFilterType(esriElementType.esriETJunction, juncWeightFilterType, juncApplyNotOperator); object[] juncFromValues = new object[juncFilterRangeCount]; object[] juncToValues = new object[juncFilterRangeCount]; for (int i = 0; i < juncFilterRangeCount; i++) { naxWeightFilter.GetFilterRange(esriElementType.esriETJunction, i, out juncFromValues[i], out juncToValues[i]); } netSolverWeights.SetFilterRanges(esriElementType.esriETJunction, ref juncFromValues, ref juncToValues); } // create the edge weight filters int edgeFilterRangeCount = naxWeightFilter.get_FilterRangeCount(esriElementType.esriETEdge); if (edgeFilterRangeCount > 0) { INetWeight fromToNetWeight = netSchema.get_WeightByName(naxWeightFilter.FromToEdgeWeightFilterName); netSolverWeights.FromToEdgeFilterWeight = fromToNetWeight; INetWeight toFromNetWeight = netSchema.get_WeightByName(naxWeightFilter.ToFromEdgeWeightFilterName); netSolverWeights.ToFromEdgeFilterWeight = toFromNetWeight; esriWeightFilterType edgeWeightFilterType; bool edgeApplyNotOperator; naxWeightFilter.GetFilterType(esriElementType.esriETEdge, out edgeWeightFilterType, out edgeApplyNotOperator); netSolverWeights.SetFilterType(esriElementType.esriETEdge, edgeWeightFilterType, edgeApplyNotOperator); object[] edgeFromValues = new object[edgeFilterRangeCount]; object[] edgeToValues = new object[edgeFilterRangeCount]; for (int i = 0; i < edgeFilterRangeCount; i++) { naxWeightFilter.GetFilterRange(esriElementType.esriETEdge, i, out edgeFromValues[i], out edgeToValues[i]); } netSolverWeights.SetFilterRanges(esriElementType.esriETEdge, ref edgeFromValues, ref edgeToValues); } INetworkAnalysisExtFlags naxFlags = m_utilNetExt as INetworkAnalysisExtFlags; // assign the edge flags to the network solver int edgeFlagCount = naxFlags.EdgeFlagCount; if (edgeFlagCount > 0) { IEdgeFlag[] edgeFlags = new IEdgeFlag[edgeFlagCount]; for (int i = 0; i < edgeFlagCount; i++) { IEdgeFlagDisplay edgeFlagDisplay = naxFlags.get_EdgeFlag(i); IFlagDisplay flagDisplay = edgeFlagDisplay as IFlagDisplay; IEdgeFlag edgeFlag = new EdgeFlagClass(); edgeFlag.Position = Convert.ToSingle(edgeFlagDisplay.Percentage); INetFlag netFlag = edgeFlag as INetFlag; netFlag.UserClassID = flagDisplay.FeatureClassID; netFlag.UserID = flagDisplay.FID; netFlag.UserSubID = flagDisplay.SubID; edgeFlags[i] = edgeFlag; } tfs.PutEdgeOrigins(ref edgeFlags); } // assign the junction flags to the network solver int juncFlagCount = naxFlags.JunctionFlagCount; if (juncFlagCount > 0) { IJunctionFlag[] juncFlags = new IJunctionFlag[juncFlagCount]; for (int i = 0; i < juncFlagCount; i++) { IJunctionFlagDisplay juncFlagDisplay = naxFlags.get_JunctionFlag(i); IFlagDisplay flagDisplay = juncFlagDisplay as IFlagDisplay; IJunctionFlag juncFlag = new JunctionFlagClass(); INetFlag netFlag = juncFlag as INetFlag; netFlag.UserClassID = flagDisplay.FeatureClassID; netFlag.UserID = flagDisplay.FID; netFlag.UserSubID = flagDisplay.SubID; juncFlags[i] = juncFlag; } tfs.PutJunctionOrigins(ref juncFlags); } // set the option for tracing on indeterminate flow ITraceTasks traceTasks = m_utilNetExt as ITraceTasks; tfs.TraceIndeterminateFlow = traceTasks.TraceIndeterminateFlow; return tfs; } } }