10

I inherited a line shapefile in ArcMap that is used to represent a road network. The problem is that the road network is pretty large and it is impossible for me to:

  1. Tell if the end of each line (road segments) is "connected" to either an edge, vertex, or the end of another line (road segment); and
  2. Tell if the entire road network is "connected" - i.e., can I trace a route from any point on the road network to any other point on the road network?

Is there a way to accomplish this in ArcMap? That is, is there a function that will allow me to highlight line segments that do no connect to other line segments, or something similar that would allow me to answer the two questions above?

4 Answers 4

16

Yes, but sort of. ArcGis no longer has line-node topology that enables the user to tell how many arcs (lines) are connected at their ends (nodes).

To check is one thing, but how about to fix instead? If you open the feature class in ArcMap and then use planarize lines (give a tolerance) and the lines will be snapped and split at intersection - saves a lot of work. If you don't want to split the lines then consider the tool Integrate but be careful to use a very small tolerance, it will snap the ends together but can make the lines also snap together. Before using Integrate keep a backup as it can destroy your data!

Now, to find disconnected ends use Feature Vertices to Points to get the end points and then Collect Events which will give you a feature class with the number of end points present, at this stage any event of 1 is suspect so you will need to separate these out.

To work out if it should be connected is the next task, use Generate Near Table (again with a suitable tolerance) and option of closest = ALL using the events with a count of 1 against the original lines, then using Summary Statistics you can find for each point the count of records using the IN_FID as a case field and NEAR_FID as a statistics field with a statistic type of "COUNT".

To make like easier extract from the near table the records with a distance greater than 0 using Table Select. Each event will find the line that generated it but the distance will be 0, if it is attached properly to another line (at a vertex) the distance will also be 0, so now any event that has a record remaining in the near table is possibly disjoint but these will need to be viewed manually.

2
  • 4
    "Feature Vertice to Point" has an option to output Dangle Points. I think this will simplify your workflow.
    – klewis
    Aug 5, 2014 at 13:39
  • Wow @klewis, when did that appear? It certainly wasn't there in 9.3. Well spotted! Aug 5, 2014 at 21:52
5

Another approach is to use MAP topology. I knocked this bit of VBA code up that would identify dangling edges. If you see dangling edges within the network rather than the expected ends of the network then there must be a disconnect.

Example of selecting up dangling edges

The code relies on you having VBA installed, being in edit mode and have added the polyline layer to the map topology.

Public Sub SelectDanglingPolylines()
 ' Description: Takes a polyline dataset and select all dangling polylines.
 '
 ' Requirements: You need to be in edit mode and have added the layer to a MAP TOPOLOGY,
 ' also polyline layer must be first in TOC.
 '
 ' Limitations: Large datasets take a long time to build the cache and may even fail.
 '
 ' Author: Duncan Hornby
 ' Created: 11/12/2011
 '

 ' Get map and then first layer, must be of polyline type
 Dim pMXDocument As IMxDocument
 Set pMXDocument = ThisDocument
 Dim pMap As IMap
 Set pMap = pMXDocument.FocusMap
 Dim pLayer As ILayer
 Set pLayer = pMap.Layer(0)
 Dim pFeatureLayer As IFeatureLayer
 Set pFeatureLayer = pLayer
 Dim pFeatureClass As IFeatureClass
 Set pFeatureClass = pFeatureLayer.FeatureClass
 If pFeatureClass.ShapeType <> esriGeometryPolyline Then
     MsgBox "This code works only with polylines!", vbExclamation, "Wrong data type at layer 0"
     Exit Sub
 End If

 ' Get editor and topology extension
 Dim pEditor As IEditor
 Dim pID As New UID
 Dim pTopologyExtension As ITopologyExtension
 Dim pTEID As New UID
 pID = "esriEditor.editor"
 Set pEditor = Application.FindExtensionByCLSID(pID)
 pTEID = "esriEditorExt.TopologyExtension"
 Set pTopologyExtension = Application.FindExtensionByCLSID(pTEID)
 If pTopologyExtension.CurrentTopology Is Nothing Then Exit Sub

 ' Get a MAP topology not a geodatabase topology
 Dim pMapTopology As IMapTopology
 If TypeOf pTopologyExtension.CurrentTopology Is IMapTopology Then
     Set pMapTopology = pTopologyExtension.MapTopology
 Else
     ' Not a Map Topology
     Exit Sub
 End If

 ' This is the colection that FID are added to
 Dim aColl As New Collection

 ' Build cache
 Application.StatusBar.Message(0) = "Building MAP TOPOLOGY cache, this can take a long time on large datasets..."
 DoEvents
 Dim pGeoDataset As IGeoDataset
 Set pGeoDataset = pFeatureClass
 Dim pEnvelope As IEnvelope
 Set pEnvelope = pGeoDataset.Extent
 pMapTopology.Cache.Build pEnvelope, False

 ' Identify dangling nodes and add polyline FID to collection
 Application.StatusBar.Message(0) = "Identifying dangling nodes..."
 DoEvents
 Dim pEnumTopologyParent As IEnumTopologyParent
 Dim pTopologyNode As ITopologyNode
 Dim pEnumTopologyNode As IEnumTopologyNode
 Set pEnumTopologyNode = pMapTopology.Cache.Nodes
 pEnumTopologyNode.Reset
 Set pTopologyNode = pEnumTopologyNode.Next
 While Not pTopologyNode Is Nothing
 If pTopologyNode.Degree = 1 Then
     ' As this has 1 degree it has only 1 parent polyline
     Set pEnumTopologyParent = pTopologyNode.Parents
     pEnumTopologyParent.Reset
     aColl.Add (pEnumTopologyParent.Next.m_FID) 'Adds polyline FID to collection
 End If
 Set pTopologyNode = pEnumTopologyNode.Next
 Wend

 ' Use collection to select polylines
 Application.StatusBar.Message(0) = "Selecting polylines..."
 DoEvents
 Dim pFeatureSelection As IFeatureSelection
 Set pFeatureSelection = pFeatureLayer
 Dim X As Variant
 For Each X In aColl
     pFeatureSelection.SelectionSet.Add CLng(X)
 Next
 pMXDocument.ActiveView.PartialRefresh esriViewGeoSelection, Nothing, pEnvelope
 Application.StatusBar.Message(0) = ""
 DoEvents
End Sub
2
  • I like that code, if you don't mind I'll copy a few bits of that; The benefit of doing it this way is that it's live and as errors are fixed they will dissapear, the bad part is if a line is dangling then it is shown - whether one end is connected or the line is completely disconnected. May I suggest that you change the code do display the node "valence" (how many connected lines) or just the dangle nodes (that's my workstation coming out again!)... that would be awesome... but only if the OP has VBA/VB.net capability. Aug 5, 2014 at 21:50
  • 1
    One could tweak the code and get edges that have valency of 1 at both ends to find a completely disconnected line, or variations like a 1 at 1 end and a 2 at the other, depends on the network I guess?
    – Hornbydd
    Aug 5, 2014 at 22:12
2

This is an old post, but I think the simplest solution is to:

  1. Dissolve your polyline feature
  2. Use Feature Vertices To Points with Dangle option
  3. Join By Spatial Location the original polyline feature to the resulting points layer. Use the "Intersected by it" option.

The result will have a "Count" field for each line in your layer. if the Count is greater than 1, the line isn't "connected" to the rest of the lines.

Conceptually: Step 2 here creates points at vertices with a single connected edge (one line "going in", zero "going out"). Since each line within the "connected" network will have at most 1 such vertex, any line with more than 1 isn't part of the network and is therefore not "connected".

2
  • This method produces many false positives. Say a road leads to a T junction. The top part of the T will have two dangling vertices. If you take the features with a count of two and then intersect them again with the road network, the ones not touching are islands.
    – woot
    Apr 14, 2017 at 8:35
  • Actually, the second intersect I wrote about above only finds isolated roads. It would not find out if the network has multiple parts
    – woot
    Apr 14, 2017 at 8:46
1

Here is a method I came up with, with the help of some friends, using Model Builder and Gephi. Step 1 ArcModel creating table of links/edges (adding nodes at every line overlap if desired) Step 2 Gephi import of links/edges then adding component IDs Step 3 ArcModel adds component IDs back to original line

Step1screenshot Step 1 Takes all the input features splits them at intersections to ensure a network node is present and creates a table to be imported into Gephi. Here are the steps: Process: Feature To Line (can take multiple inputs) Process: Multipart To Singlepart Process: Repair Geometry Process: Add Start End coords (Add Geometry attributes) Process: Add Field "Source" Process: Add Field "Target" Process: Calculate "Source"(as startX & startY) Process: Calculate "Target" (as end X & endY) Process: Delete fields (cleansup extra fields to avoid confusion) Process: GDB Table to CSV

Step2Gephi_Screenshot Step 2 Gephi process( free download) -import CSV output with Source and Target named node fields as Links -Run Calculated Components as Undirected (under Statistic tools) -Export CSV from Data Laboratory for Nodes (include node ID and component ID)

Step 3: Takes Gephi output and adds component/network attribute to original lines Process: Table to Table(ingest Gephi output into Geodatabase to structure unique objectIDs) Process: Join Field (Source node values joined with Gephi output to populate component number to lines) Symbolize by component

Cleanup after this point will likely be a manual process of examining where the disconnects are occurring along the lines and if the disconnect is a valid real-world separation or just a data flaw.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.