ArcGIS Pro 3.4 API Reference Guide
ArcGIS.Core.Data.Topology Namespace / Topology Class / BuildGraph Method
The area of interest for which a topology graph is built. It must be either ArcGIS.Core.Geometry.GeometryType.Envelope or ArcGIS.Core.Geometry.GeometryType.Polygon.
The client callback that receives a TopologyGraph as input for analysis.
Example Version

BuildGraph Method
Creates an in-memory representation of the topologically-integrated features within the current topology for a given area. This method must be called on the MCT. Use QueuedTask.Run.
Syntax
public void BuildGraph( 
   Geometry extent,
   Action<TopologyGraph> callBack
)

Parameters

extent
The area of interest for which a topology graph is built. It must be either ArcGIS.Core.Geometry.GeometryType.Envelope or ArcGIS.Core.Geometry.GeometryType.Polygon.
callBack
The client callback that receives a TopologyGraph as input for analysis.
Exceptions
Remarks
The life time of the TopologyGraph as input for callBack is scoped to that of the client callback itself. Once the flow of execution has returned from the callback, the TopologyGraph object will be disposed. Hence, attempting to use the TopologyGraph outside of this scope will raise a ArcGIS.Core.ObjectDisconnectedException.
Example
ExploreTopologyGraph
public void ExploreTopologyGraph()
{
  using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"C:\TestData\GrandTeton.gdb"))))
  using (Topology topology = geodatabase.OpenDataset<Topology>("Backcountry_Topology"))
  {
    // Build a topology graph using the extent of the topology dataset.

    topology.BuildGraph(topology.GetExtent(), (topologyGraph) =>
    {
      using (Feature campsites12 = GetFeature(geodatabase, "Campsites", 12))
      {
        IReadOnlyList<TopologyNode> topologyNodesViaCampsites12 = topologyGraph.GetNodes(campsites12);

        TopologyNode topologyNodeViaCampsites12 = topologyNodesViaCampsites12[0];

        IReadOnlyList<TopologyEdge> allEdgesConnectedToNodeViaCampsites12 = topologyNodeViaCampsites12.GetEdges();
        IReadOnlyList<TopologyEdge> allEdgesConnectedToNodeViaCampsites12CounterClockwise = topologyNodeViaCampsites12.GetEdges(false);

        System.Diagnostics.Debug.Assert(allEdgesConnectedToNodeViaCampsites12.Count == allEdgesConnectedToNodeViaCampsites12CounterClockwise.Count);

        foreach (TopologyEdge edgeConnectedToNodeViaCampsites12 in allEdgesConnectedToNodeViaCampsites12)
        {
          TopologyNode fromNode = edgeConnectedToNodeViaCampsites12.GetFromNode();
          TopologyNode toNode = edgeConnectedToNodeViaCampsites12.GetToNode();

          bool fromNodeIsTheSameAsTopologyNodeViaCampsites12 = (fromNode == topologyNodeViaCampsites12);
          bool toNodeIsTheSameAsTopologyNodeViaCampsites12 = (toNode == topologyNodeViaCampsites12);

          System.Diagnostics.Debug.Assert(fromNodeIsTheSameAsTopologyNodeViaCampsites12 || toNodeIsTheSameAsTopologyNodeViaCampsites12,
            "The FromNode *or* ToNode of each edge connected to 'topologyNodeViaCampsites12' should be the same as 'topologyNodeViaCampsites12' itself.");

          IReadOnlyList<FeatureInfo> leftParentFeaturesBoundedByEdge = edgeConnectedToNodeViaCampsites12.GetLeftParentFeatures();
          foreach (FeatureInfo featureInfo in leftParentFeaturesBoundedByEdge)
          {
            System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(featureInfo.FeatureClassName));
            System.Diagnostics.Debug.Assert(featureInfo.ObjectID > 0);
            EnsureShapeIsNotEmpty(featureInfo);
          }

          IReadOnlyList<FeatureInfo> leftParentFeaturesNotBoundedByEdge = edgeConnectedToNodeViaCampsites12.GetLeftParentFeatures(false);
          foreach (FeatureInfo featureInfo in leftParentFeaturesNotBoundedByEdge)
          {
            System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(featureInfo.FeatureClassName));
            System.Diagnostics.Debug.Assert(featureInfo.ObjectID > 0);
            EnsureShapeIsNotEmpty(featureInfo);
          }

          IReadOnlyList<FeatureInfo> rightParentFeaturesBoundedByEdge = edgeConnectedToNodeViaCampsites12.GetRightParentFeatures();
          foreach (FeatureInfo featureInfo in rightParentFeaturesBoundedByEdge)
          {
            System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(featureInfo.FeatureClassName));
            System.Diagnostics.Debug.Assert(featureInfo.ObjectID > 0);
            EnsureShapeIsNotEmpty(featureInfo);
          }

          IReadOnlyList<FeatureInfo> rightParentFeaturesNotBoundedByEdge = edgeConnectedToNodeViaCampsites12.GetRightParentFeatures(false);
          foreach (FeatureInfo featureInfo in rightParentFeaturesNotBoundedByEdge)
          {
            System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(featureInfo.FeatureClassName));
            System.Diagnostics.Debug.Assert(featureInfo.ObjectID > 0);
            EnsureShapeIsNotEmpty(featureInfo);
          }
        }
      }
    });
  }
}

private void EnsureShapeIsNotEmpty(FeatureInfo featureInfo)
{
  using (Feature feature = featureInfo.GetFeature())
  {
    System.Diagnostics.Debug.Assert(!feature.GetShape().IsEmpty, "The feature's shape should not be empty.");
  }
}
FindClosestElement
public void FindClosestElement()
{
  using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"C:\TestData\GrandTeton.gdb"))))
  using (Topology topology = geodatabase.OpenDataset<Topology>("Backcountry_Topology"))
  {
    // Build a topology graph using the extent of the topology dataset.

    topology.BuildGraph(topology.GetExtent(), (topologyGraph) =>
    {
      MapPoint queryPointViaCampsites12 = null;

      using (Feature campsites12 = GetFeature(geodatabase, "Campsites", 12))
      {
        queryPointViaCampsites12 = campsites12.GetShape() as MapPoint;
      }

      double searchRadius = 1.0;

      TopologyElement topologyElementViaCampsites12 = 
          topologyGraph.FindClosestElement<TopologyElement>(
                    queryPointViaCampsites12, searchRadius);

      System.Diagnostics.Debug.Assert(
        topologyElementViaCampsites12 != null, "There should be a topology element corresponding to 'queryPointViaCampsites12' within the 'searchRadius' units.");

      IReadOnlyList<FeatureInfo> parentFeatures = topologyElementViaCampsites12.GetParentFeatures();

      Console.WriteLine("The parent features that spawn 'topologyElementViaCampsites12' are:");
      foreach (FeatureInfo parentFeature in parentFeatures)
      {
        Console.WriteLine($"\t{parentFeature.FeatureClassName}; OID: {parentFeature.ObjectID}");
      }

      TopologyNode topologyNodeViaCampsites12 = topologyGraph.FindClosestElement<TopologyNode>(queryPointViaCampsites12, searchRadius);

      if (topologyNodeViaCampsites12 != null)
      {
        // There exists a TopologyNode nearest to the query point within searchRadius units.
      }

      TopologyEdge topologyEdgeViaCampsites12 = topologyGraph.FindClosestElement<TopologyEdge>(queryPointViaCampsites12, searchRadius);

      if (topologyEdgeViaCampsites12 != null)
      {
        // There exists a TopologyEdge nearest to the query point within searchRadius units.
      }
    });
  }
}
Requirements

Target Platforms: Windows 11, Windows 10

ArcGIS Pro version: 3 or higher.
See Also