NetworkAnalysis


Supported with:
  • Engine
  • ArcGIS for Desktop Basic
  • ArcGIS for Desktop Standard
  • ArcGIS for Desktop Advanced
  • Server
Library dependencies: System, SystemUI, Geometry, GraphicsCore, Display, Server, Output, Geodatabase, GISClient, DataSourcesFile, DataSourcesGDB, DataSourcesOleDB, DataSourcesRaster, DataSourcesNetCDF, GeoDatabaseDistributed, GeoDatabaseExtensions, Carto

Additional library information: Contents, Object Model Diagram

The NetworkAnalysis library provides objects for populating a geodatabase with network data and objects to analyze the network when it is loaded in the geodatabase. In addition, this library contains helper objects used for converting between the geometric network features and the logical network elements.
Developers can utilize this library to support custom network tracing. This library is meant to work with utility networks such as gas lines, electricity supply lines, and so on.

See the following sections for more information about this namespace:

NetworkLoader object

The NetworkLoader coclass allows you to specify input parameters for the name and type of network, the feature classes to be included, the feature classes to be used as sources and sinks, and the weights you want to employ. These parameters are specified up front through the object, then the LoadNetwork method is executed to generate the geometric network and its logical network.
When you execute the LoadNetwork method, a logical network is generated based on the feature classes you specify. An enabled/disabled field is added to the table for each feature class to keep track of whether flow can go through each individual feature. A domain is also created with the values of enabled and disabled. This domain is automatically assigned to the created field within each feature class.
The INetworkLoader and INetworkLoader2 interfaces let you set the parameters for building a geometric network out of a set of feature classes within the same dataset. Use these interfaces to define and generate your geometric network.
The INetworkLoaderProps interface allows you to see the default field names that will be added to each feature class and the name of the domain. In addition, default field and domain names can be returned for the ancillary role (feature classes that contain sources or sinks).

Solver objects

Two solver objects are contained in this library. Both objects are used together to perform network analysis. The NetSolver object prepares the solver environment with the necessary weights and filters, while the TraceFlowSolver object sets the flags and performs the analysis through the network.
NetSolver
The NetSolver object sets the table for the trace methods in the TraceFlowSolver class. Through this object, you can specify the network you're working on, disable entire network classes, specify individual barriers, and define weights. The derived TraceFlowSolver class can then be used to run a trace on the defined problem.
The INetSolver interface specifies barriers and disabled classes. This interface is key when you need to limit your traces based on the exclusion of entire classes or individual elements. This interface offers the following three ways to set barriers for the purpose of limiting traces:
  • The DisableElementClass method stops traces at every instance of the specified class. For example, if you have a gas pipe that has burst and you need to identify all valves to shut off, you would use this method to set barriers at every valve in the network.
  • The ElementBarriers property lets you specify an INetElementBarriers object that contains individual elements to use as barriers. These could be barriers composed of closed street segments, bridges that are out, or individual electric switches that have been opened.
  • The SelectionSetBarriers property is similar to the ElementBarriers property. It allows you to specify an ISelectionSetBarriers object to use as a barrier in your trace-solving routine. SelectionSetBarriers are meant to be barriers based on a selected set of elements, such as 8-inch pipes or six-lane highways.
The following code example uses the ElementBarriers property to set barriers based on a set of identified elements:
[C#]
void SetEdgeBarrier(INetwork network, IFeatureClass featClass, int edgeOID1, int
    edgeOID2)
{
    //Create the NetElementBarriers object.
    INetElementBarriersGEN netEdgeBarriers = new NetElementBarriersClass()as
        INetElementBarriersGEN;
    int[] oidArray = new int[2];
    oidArray[0] = edgeOID1;
    oidArray[1] = edgeOID2;
    netEdgeBarriers.Network = network;
    netEdgeBarriers.ElementType = esriETEdge;
    netEdgeBarriers.SetBarriers(featClass.FeatureClassID, oidArray);

    //Set the edge barrier in TraceFlowSolver.
    ITraceFlowSolverGEN traceFlowSolver = new TraceFlowSolverClass()as
        ITraceFlowSolverGEN;
    INetSolver netSolver = traceFlowSolver as INetSolver;
    netSolver.SourceNetwork = network;
    netSolver.ElementBarriers(esriETEdge) = netEdgeBarriers;
}
[VB.NET]
Sub SetEdgeBarrier(network As INetwork, featClass As IFeatureClass, edgeOID1 As Integer, edgeOID2 As Integer)
    'Create the NetElementBarriers object.
    Dim netEdgeBarriers As INetElementBarriersGEN = New NetElementBarriers
    Dim oidArray(0 To 1) As Integer
    oidArray(0) = edgeOID1
    oidArray(1) = edgeOID2
    netEdgeBarriers.Network = network
    netEdgeBarriers.ElementType = esriETEdge
    netEdgeBarriers.SetBarriers(featClass.FeatureClassID, oidArray)
    
    'Set the edge barrier in TraceFlowSolver.
    Dim traceFlowSolver As ITraceFlowSolverGEN = New TraceFlowSolver
    Dim netSolver As INetSolver = CType(traceFlowSolver, INetSolver)
    netSolver.SourceNetwork = network
    netSolver.ElementBarriers(esriETEdge) = netEdgeBarriers
End Sub
The INetSolverWeights interface specifies the weights to use during trace-solving procedures. For a description of how weights are used, see the NetWeight coclass documentation. This interface allows you to specify junction and edge weights and also set the filters to be used in conjunction with the weights. The filters specify the attribute values or ranges to use when tracing. For instance, a cathodic protection trace might be done by tracing on steel pipe, so the weight filter would indicate to trace only on the value representing steel pipe.
Filter weights (FromToEdgeFilterWeight, ToFromEdgeFilterWeight, and JunctionFilterWeight) are used to explicitly specify the type of feature on which you want to trace. FromToEdgeFilterWeight, FromToEdgeWeight, ToFromEdgeFilterWeight, and ToFromEdgeWeight get their from- and to-direction based on the digitized direction of the edge.
The following code example sets filter weights on edges and junctions. The edge weight is Material, and the filter is being set to not trace on values of 1. The junction weight is Fitting_Type, and the filter is being set to not trace on values of 8.
[C#]
void SetFilterWeights(INetwork network)
{
    int[] range = new int[1];

    //Establish the trace flow solver.
    ITraceFlowSolverGEN traceFlowSolver = new TraceFlowSolverClass()as
        ITraceFlowSolverGEN;
    INetSolver netSolver = traceFlowSolver as INetSolver;
    netSolver.SourceNetwork = network;

    //Add the weights.
    INetSchema netSchema = network as INetSchema;
    INetSolverWeightsGEN netSolverWeights = netSolverWeights as INetSolverWeightsGEN;

    INetWeight netWeight = netSchema.WeightByName("Material");
    netSolverWeights.FromToEdgeFilterWeight = netWeight;
    netSolverWeights.ToFromEdgeFilterWeight = netWeight;
    netSolverWeights.SetFilterType(esriETEdge, esriWFRange, true);
    range[0] = 1;
    netSolverWeights.SetFilterRanges(esriETEdge, range, range);

    netWeight = netSchema.WeightByName("Fitting_Type");
    netSolverWeights.JunctionFilterWeight = netWeight;
    netSolverWeights.SetFilterType(esriETJunction, esriWFRange, true);
    range[0] = 8;
    netSolverWeights.SetFilterRanges(esriETJunction, range, range);
}
[VB.NET]
Sub SetFilterWeights(network As INetwork)
    Dim range(0) As Integer
    
    'Establish the trace flow solver.
    Dim traceFlowSolver As ITraceFlowSolverGEN = New TraceFlowSolver
    Dim netSolver As INetSolver = CType(traceFlowSolver, INetSolver)
    netSolver.SourceNetwork = network
    
    'Add the weights.
    Dim netSchema As INetSchema = CType(network, INetSchema)
    Dim netSolverWeights As INetSolverWeightsGEN = CType(netSolverWeights, INetSolverWeightsGEN)
    
    Dim netWeight As INetWeight = netSchema.WeightByName("Material")
    netSolverWeights.FromToEdgeFilterWeight = netWeight
    netSolverWeights.ToFromEdgeFilterWeight = netWeight
    netSolverWeights.SetFilterType(esriETEdge, esriWFRange, True)
    range(0) = 1
    netSolverWeights.SetFilterRanges(esriETEdge, range, range)
    
    netWeight = netSchema.WeightByName("Fitting_Type")
    netSolverWeights.JunctionFilterWeight = netWeight
    netSolverWeights.SetFilterType(esriETJunction, esriWFRange, True)
    range(0) = 8
    netSolverWeights.SetFilterRanges(esriETJunction, range, range)
End Sub
TraceFlowSolver
The TraceFlowSolver object contains a set of traces developed by ESRI for use with custom code. You can also generate your own trace routines using the ForwardStar object.
The ITraceFlowSolver interface lets you specify junction and edge origins, then execute one of the trace methods. These trace methods allow you to perform the majority of required tracing tasks; traces not included with these interfaces need to be constructed via the ForwardStar object.
The ITraceFlowSolver2 interface adds trace solvers to the TraceFlowSolver object. It can be used in a similar way as the ITraceFlowSolver interface. Many of the traces require that flow direction be established on the network. You can set flow direction through the IUtilityNetwork interface.
There are four basic trace algorithms that can be used to solve a variety of trace-flow problems. These methods are accessible from the Utility Network Analyst toolbar to create the nine trace tasks available there, and they can also be used to create an unlimited number of new tasks.
  • FindCircuits (sometimes known as find loops) finds elements that can be reached from more than one direction. This method is important for such things as electrical networks, where electricity traveling in both directions on an edge can cause problems.
  • FindCommonAncestors finds the common elements in an upstream trace from more than one location. This method helps determine potential pollution sources based on sites where contaminants have been discovered or identify potential outage locations when multiple customers have reported that their service is out.
  • FindFlowElements and FindFlowEndElements perform the same type of analysis. The only difference is that FindFlowEndElements returns only the termination elements of the trace. These methods are probably the most important trace methods because they solve problems, such as what is upstream from this location, what is downstream, what is connected, and so on. By applying further constraints (such as disabling classes), these methods can perform additional analysis, such as shutoff modeling.
  • FindPath determines the optimal path between two or more flags. The flags are routed in order beginning with the first flag entered and ending with the last. By default, the optimal path is based on the number of elements traversed, with optimal being the least number of elements. Define weights on the network to base the optimal path on length of segments, travel time, or some other parameter.

NetFlag objects

The NetFlag abstract class has two classes that are derived from it: EdgeFlag and JunctionFlag. The purpose of the class is to specify the starting points (flags) of traces and path-finding routines. When a flag is created, it is necessary to specify whether that flag is on an edge or a junction. The PutEdgeOrigins and PutJunctionOrigins methods on ITraceFlowSolver include the flags in the current trace.
The INetFlag interface is the only interface on the NetFlag object. This interface allows set and retrieve access on the individual properties of the element being used as a flag. Use this interface to specify the user class and ID of the element. UserSubID specifies the index of the particular element you want to use as a flag within a complex junction or edge feature.
EdgeFlag
An EdgeFlag object is a type of NetFlag object. The EdgeFlag object specifies the starting point of a trace or path algorithm. As the name implies, the flag (or starting point) must be on an edge feature. This object creates a flag that is associated with an edge feature.
The IEdgeFlag interface is the only interface on the EdgeFlag object. This interface provides access to the flag properties unique to an edge. Use this interface to specify the position of the flag on the edge and whether the flag is to be used for flow in both directions along the edge. The Position property specifies the percentage location of the flag down the edge beginning at the from point.
JunctionFlag
A JunctionFlag object is a type of NetFlag object. The JunctionFlag object specifies the starting point (flag) of a trace or path algorithm. As the name implies, the flag must be on a junction feature.
The IJunctionFlag interface is the only interface on the JunctionFlag object. This interface has no properties or methods but serves as a way to identify what type of flag you have. For instance, if an object supports IJunctionFlag, then you know you have a JunctionFlag object.

FlagDisplay objects

The FlagDisplay abstract class supports two coclasses, JunctionFlagDisplay and EdgeFlagDisplay, for the tracking of flags set through the Utility Network Analyst toolbar. The purpose of the class is to monitor flags set through the toolbar and make sure they are correctly displayed when the map is redrawn. Flags are used by the network toolbar as starting points for traces.
The IFlagDisplay interface provides access to the properties of flags set through the Utility Network Analyst toolbar. These properties include the feature class, ID, and SubID (if a complex network feature) of the feature on which the flag was placed, as well as the symbol used to draw the flag. The SubID must be specified, even for noncomplex network features. You can look up any network element’s ID by calling INetElements.QueryIDs and passing in its element identification (EID).
The ClientClassID and ClientFID properties are specifically for developer use. These properties are not used by the core ArcGIS software in any way.
Geometry returns a point object representing the location of the flag.
JunctionFlagDisplay
The JunctionFlagDisplay coclass is a type of FlagDisplay that supports flags placed on junction elements through the network toolbar. At any time, there can be zero or more JunctionFlagDisplay objects associated with the toolbar.
The IJunctionFlagDisplay interface has no properties or methods but can be used to determine if the FlagDisplay object is a JunctionFlagDisplay object.
EdgeFlagDisplay
The EdgeFlagDisplay coclass is a type of FlagDisplay that supports flags placed on edge elements through the Utility Network Analyst toolbar. At any time, there can be zero or more EdgeFlagDisplay objects associated with the toolbar.
The IEdgeFlagDisplay interface allows you to determine if the FlagDisplay object is of type EdgeFlagDisplay. The only property on the interface (Percentage) returns the position of the flag on the edge measured as a percentage from the digitized from end of the feature.
The following code example demonstrates how to take the edge flags set within the Network toolbar and pass them to a TraceFlowSolver object:
[C#]
void FlagDisplay(INetworkAnalysisExtFlags flags, ITraceFlowSolverGEN traceSolver)
{
    IEdgeFlag[] edgeFlags = new IEdgeFlag[flags.EdgeFlagCount];
    IFlagDisplay edgeFlagDisplay;
    INetFlag edgeFlag;
    for (int i = 0; i < flags.EdgeFlagCount; i++)
    {
        edgeFlagDisplay = flags.EdgeFlag(i);
        edgeFlag = New EdgeFlagClass()as INetFlag;
        edgeFlag.UserID = edgeFlagDisplay.FID;
        edgeFlag.UserClassID = edgeFlagDisplay.FeatureClassID;
        edgeFlag.Label = "Edge";
        edgeFlags[i] = edgeFlag;
    }
    traceSolver.PutEdgeOrigins(edgeFlags);
}
[VB.NET]
Sub FlagDisplay(flags As INetworkAnalysisExtFlags, traceSolver As ITraceFlowSolverGEN)
    Dim edgeFlags() As IEdgeFlag, edgeFlagDisplay As IFlagDisplay
    Dim edgeFlag As INetFlag, i As Integer
    ReDim edgeFlags(0 To flags.EdgeFlagCount - 1)
    For i = 0 To flags.EdgeFlagCount - 1
        edgeFlagDisplay = flags.EdgeFlag(i)
        edgeFlag = New EdgeFlag
        edgeFlag.UserID = edgeFlagDisplay.FID
        edgeFlag.UserClassID = edgeFlagDisplay.FeatureClassID
        edgeFlag.Label = "Edge"
        edgeFlags(i) = edgeFlag
    Next i
    traceSolver.PutEdgeOrigins(edgeFlags)
End Sub

Barrier objects

There are two barrier objects contained in this library. These objects specify to the NetSolver object those network elements through which the trace and path tasks cannot pass.
NetElementBarriers
There are two ways the NetElementBarriers coclass can be created. You can either create the object directly and set the barriers manually, or you can generate the object through INetworkAnalysisExtBarriers.CreateElementBarriers. When this object is generated through CreateElementBarriers, the resulting barrier elements are based on what was set by the user through the toolbar.
The INetElementBarriers interface is used to set the type of element (edge or junction) contained within the class and to set the barriers.
SetBarriers specifies which network features are to be used as barriers. If a network feature is a complex edge, then all elements of that feature are added to the barrier.
The INetElementBarriers2 interface allows barrier elements to be added without it acting on the entire complex feature.
SetBarriersByEID allows barriers to be specified by their EID. This option saves you from performing a query on the element to determine the feature class ID and feature ID.
SelectionSetBarriers
The SelectionSetBarriers coclass is similar to NetElementBarriers but can contain both junction and edge elements. When creating your own custom trace tool, you can create a SelectionSetBarriers object or generate one through INetworkAnalysisExtBarriers.CreateSelectionBarriers. The resulting class can then be applied during the analysis process through the NetSolver object.
SelectionSetBarriers offers an additional advantage over NetElementBarriers in that the Not method can be used to specify that elements not within the class act as barriers.
The ISelectionSetBarriers interface allows new barriers to be added to the set through the Add method but also offers the Not method to specify that elements not currently within the set (instead of what is within the set) serve as barriers.

Helper objects

The network analysis helper objects assist in the conversion between the domain of network elements and the domain of geometry and features. For example, the PointToEID object can convert a map coordinate to a flag position along the network, while the EIDHelper object can convert the numerous EIDs returned by the trace solver to geometry that can be displayed on the map.
PointToEID
The PointToEID object finds the nearest network element to a given point in a geometric network.
The IPointToEID interface is used to find the EID and point location of the nearest edge or junction element in a geometric network to a given point. In the case of finding the nearest edge element, the position of the point along the edge is also returned. This position is measured as a percentage from the digitized from end of the edge. The resulting EID is from the specified geometric network and corresponds to a feature from one of the layers in the specified source map.
SnapTolerance is in the map units of the specified SourceMap.
The following code example can be used to place a junction flag on the nearest junction feature to the given (x,y) map coordinate:
[C#]
void PlaceJunctionFlag(double x, double y, IMap map, INetworkAnalysisExt
    networkAnalysisExt, ISymbol flagSymbol)
{
    IPoint point = new PointClass()as IPoint;
    point.X = x;
    point.Y = y;
    int EID;
    IPoint outPoint;
    IPointToEID pointToEID = new PointToEIDClass()as IPointToEID;
    pointToEID.GeometricNetwork = networkAnalysisExt.CurrentNetwork;
    pointToEID.SourceMap = map;
    pointToEID.SnapTolerance = 10; //Set a snap tolerance of 10 map units.
    pointToEID.GetNearestJunction(point, out EID, out outPoint);

    INetElements netElements = networkAnalysisExt.CurrentNetwork.Network as
        INetElements;
    int FCID, FID, subID;
    pNetElements.QueryIDs(EID, esriETJunction, out FCID, out FID, out subID);
    IJunctionFlagDisplay junctionFlagDisplay = new JunctionFlagDisplayClass()as
        IJunctionFlagDisplay;
    IFlagDisplay flagDisplay = junctionFlagDisplay as IFlagDisplay;
    flagDisplay.FeatureClassID = FCID;
    flagDisplay.FID = FID;
    flagDisplay.SubID = subID;
    flagDisplay.Geometry = outPoint as IGeometry;
    flagDisplay.Symbol = flagSymbol;

    INetworkAnalysisExtFlags networkAnalysisExtFlags = networkAnalysisExt as
        INetworkAnalysisExtFlags;
    networkAnalysisExtFlags.AddJunctionFlag(junctionFlagDisplay);
}
[VB.NET]
Sub PlaceJunctionFlag(x As Double, y As Double, map As IMap, _
                      networkAnalysisExt As INetworkAnalysisExt, flagSymbol As ISymbol)
    Dim point As IPoint = New Point
    point.X = x
    point.Y = y
    Dim EID As Integer
    Dim outPoint As IPoint
    Dim pointToEID As IPointToEID = New PointToEID
    With pointToEID
        .GeometricNetwork = networkAnalysisExt.CurrentNetwork
        .SourceMap = map
        .SnapTolerance = 10 'Set a snap tolerance of 10 map units.
        .GetNearestJunction(point, EID, outPoint)
    End With
    
    Dim netElements As INetElements = CType(networkAnalysisExt.CurrentNetwork.Network, INetElements)
    Dim FCID As Integer, FID As Integer, subID As Integer
    pNetElements.QueryIDs(EID, esriETJunction, FCID, FID, subID)
    Dim junctionFlagDisplay As IJunctionFlagDisplay = New JunctionFlagDisplay
    Dim flagDisplay As IFlagDisplay = CType(junctionFlagDisplay, IFlagDisplay)
    With flagDisplay
        .FeatureClassID = FCID
        .FID = FID
        .SubID = subID
        .Geometry = CType(outPoint, IGeometry)
        .Symbol = flagSymbol
    End With
    Dim networkAnalysisExtFlags As INetworkAnalysisExtFlags = CType(networkAnalysisExt, INetworkAnalysisExtFlags)
    networkAnalysisExtFlags.AddJunctionFlag(junctionFlagDisplay)
End Sub
EIDHelper
The EIDHelper coclass allows you to quickly query information on the features corresponding to a given set of network EIDs. This object is important because it provides the ability to efficiently query the geometry and field values for these features and return them in a single cursor.
As an example of when this object would be used, consider an upstream trace operation. The trace operation is performed on the network with results being the elements that are traversed. The EIDHelper coclass is necessary to take this set of elements and determine the actual features that were traversed. The features could then be listed as part of a report or simply highlighted.
The IEIDHelper interface lets you set the parameters for retrieving the geometry and features. The settings are specified up front through this interface, then the CreateEnumEIDInfo method is executed to generate a cursor containing the geometry and feature objects. You have the option of returning only geometry objects, only feature objects, or both.
Feature objects that are returned in the cursor are meant only for querying attribute values from the features and not for editing the features. These feature objects contain only those fields specified using the AddField method. For optimization purposes, if no calls are made to AddField before calling the CreateEnumEIDInfo method, the feature objects returned contain only the object identification (OID) and Shape fields.
Use the DisplayEnvelope property to limit the number of feature and geometry objects returned in the cursor. Only those objects whose geometry lies within the specified DisplayEnvelope are returned. If the DisplayEnvelope is set to Nothing, then all features, geometries, or both corresponding to the EIDs are returned, regardless of their spatial position.
PartialComplex specifies whether only the subgeometries of the individual elements of a complex feature are returned. When this property is false, the geometry for the entire complex feature is returned whether or not each element is in the input set of EIDs (assuming at least one element of the complex feature is in the input set).