Identifying Self closing loop in multipart features

1546
7
01-31-2020 02:15 AM
RiyasDeen2
New Contributor

I have been stuck with this problem for well over 2 days, I think it's time to shout for help!, Attached data for reference. The other feature does't visually look like a self closing loop, but it is. The raw data has two features with same ID overlapping each other, which could cause a self closing loop.

What I'm trying to do:
We are looking at migrating to Roads and Highways to manage our Linear road data. We have well defined calibration points for few important roads but no calibration points for local roads. I'm trying to auto create calibration points using Generate Calibration Points tool. It worked fine for a small dataset. When I tried to run it on a larger dataset ArcGIS Pro crashed on me.

I could potentially replace this tool by creating end points and adding length of the feature as calibration points, but apparently this tool handle Loops and Lollipops

Investigation So Far:

I dug deeper and isolated two offending features which were causing ArcGIS Pro  to crash. I deleted these two features and ran the tool again it worked fine. When I ran it for 2 isolated features ArcGIS Pro crashed again. Both these features have one thing in common, they are multi-part feature and one of the part is a self closing loop

Multi-part loop

What I want:

These two features are part of a feature class of well over a million roads. I want to be able to identify these features using python or a GP tool, we can't do this manually. The raw data comes from a third party and we can't control the data quality. Or, somehow make this work with ArcGIS Pro. I have tested in both v 2.3.3 and 2.4.3, same behavior.

What I can't do:

I can't convert this to single part features, mainly to do with some business rules down stream, this would be my last ditch option, I know it'll work if I make it single part feature. I'm trying to avoid it.

I can't manually identify the feature, delete it and run the tool again. This is a small component of a bigger ETL pipeline, I want the process fully automated.

Hopefully ESRI will fix this bug in ArcGIS Pro, until then I would appreciate some suggestions on how to tackle this.

Thanks!!

Tags (1)
0 Kudos
7 Replies
DanPatterson_Retired
MVP Emeritus

Doesn't leave much other than scripting and checking out each shape

Polyline—ArcPy classes | ArcGIS Desktop 

pseudo... p is a polyline's SHAPE@

if p.partCount > 0:

    first = p.getPart(0) 

    second = p.getPart(1)

    if (first.firstPoint == second.firstPoint) or (first.firstPoint == second.lastPoint) :

        ... do something ....

If there are only 2 parts and an equality check is carried out with tolerance

JohannesBierer
Occasional Contributor III

Maybe it is helpful to create a point feature class of firstPoint == lastPoint places? You could try this script?

import arcpy

arcpy.env.overwriteOutput = True

inFc = r"Yourpath...\Problem Data.gdb\problem_road_isolated" 
inFcS = r"Yourpath...\Problem Data.gdb\problem_road_isolated_single"

outPoint = r"Yourpath...\Problem Data.gdb\\ClosedRing"

arcpy.MultipartToSinglepart_management(inFc, inFcS)

CoordList = list()
  
with arcpy.da.SearchCursor (inFcS, "SHAPE@") as sCurs:
            for geom, in sCurs:
                for i in range(geom.partCount):
                    part = geom.getPart(i)
                       
                    if geom.lastPoint.X == geom.firstPoint.X:
                      
                        CoordList.append("{}; {}".format(geom.lastPoint.X, geom.lastPoint.Y))
                            
pt = arcpy.Point()
ptGeoms = []

spatial_reference = arcpy.SpatialReference(3111)

for p in CoordList:

    coord = p.split(";")
    
    pt.X = coord[0]
    print(coord[0])
    pt.Y = coord[1]
    print(coord[1])
    ptGeoms.append(arcpy.PointGeometry(pt, spatial_reference))

arcpy.CopyFeatures_management(ptGeoms, outPoint)
arcpy.AddXY_management(outPoint)
DanPatterson_Retired
MVP Emeritus

Johannes Bierer‌you also need to compare the first and second part's first and last coordinates as well.

Comparing the first and last point of a part, is only 'part' of the solution, if you follow.

JohannesBierer
Occasional Contributor III

There's as well a identation error at line 14.

I thought with line 15 I could do a for loop through each part of the geometrie?

0 Kudos
DanLee
by Esri Regular Contributor
Esri Regular Contributor

For the two features you provide, the following can help identify them:
1. Run Feature To Polygon tool on the input Lines (roads). Say the output is tmpPolys.
2. If tmpPolygs contains polygons, run Near tool on the Lines and Near Features should be tmpPolys; set search distance to be 0 or very small. The Lines with loops (singlepart or in multipart) will have polygon IDs in Near_FID field.


However, if your roads have multiple features that may form polygons (closed road block), then the above won't work. You can try the following:
1. Run Feature Vertices To Points with BOTH_ENDS option on roads data. Say output is bothEnds. For your sample data, you get 8 points - each part of the features gets two endpoints.
2. Run Find Identical on bothEnds; check Shape and ORIG_FID under Field(s); check "Output only duplicate records". You should get 4 records, say in output bothEndsDups.
3. Join Field on bothEnds, OBJECTID (as join field), with bothEndsDups, IN_FID (as join field), to transfer IN_FID to bothEnds.
4. Select IN_FID >0 from bothEnds.
5. Run Join Field on the original roads data, OBJECT ID as join field; to join bothEnds with ORIG_FID as join field, to transfer IN_FID. Now your roads (lines) with values in IN_FID are the ones with loops.
Would any of the above work for you?

0 Kudos
DanLee
by Esri Regular Contributor
Esri Regular Contributor

For the two features you provide, the following can help identify them:

1. Run Feature To Polygon tool on the input Lines (roads). Say the output is tmpPolys.

2. If tmpPolygs contains polygons, run Near tool on the Lines and Near Features should be tmpPolys; set search distance to be 0 or very small. The Lines with loops (singlepart or in multipart) will have polygon IDs in Near_FID field.

However, if your roads have multiple features that may form polygons (closed road block), then the above won't work. You can try the following:

1. Run Feature Vertices To Points with BOTH_ENDS option on roads data. Say output is bothEnds. For your sample data, you get 8 points - each part of the features gets two endpoints.

2. Run Find Identical on bothEnds; check Shape and ORIG_FID under Field(s); check "Output only duplicate records". You should get 4 records, say in output bothEndsDups.

3. Join Field on bothEnds, OBJECTID (as join field), with bothEndsDups, IN_FID (as join field), to transfer IN_FID to bothEnds.

4. Select IN_FID >0 from bothEnds.

5. Run Join Field on the original roads data, OBJECT ID as join field; to join bothEnds with ORIG_FID as join field, to transfer IN_FID. Now your roads (lines) with values in IN_FID are the ones with loops.

Would any of the above work for you?

0 Kudos
by Anonymous User
Not applicable

@RiyasDeen2  this crash should have been fixed in the Generate Calibration Points tool in ArcGIS Pro 2.5 and upwards. Could you check and verify.

However, do note that we only just implemented full support for complex shapes (loops, lollipops, alphas, branches, etc) and gapped routes having complex components in Roads and Highways, in ArcGIS Pro 2.7. This includes the LRS data loading tools, LRS editing, event behaviors, etc. Before 2.7, some of the tools might work (like Generate Calibration Points) for a few shapes, but it's not guaranteed throughout the R&H stack.

0 Kudos