Check records with one another within a polyline.shp then update if they intersect another record or not

4644
3
01-20-2015 03:24 AM
GisWombat
New Contributor

Aim

 

To compare records within a polyline shapefile. If a record intersects, touches or crosses another record it updates the intsctCHK field with a “Y” value otherwise it updates it with a “N” value (meaning that it doesn’t touch, cross or intersect another record at all). The intsctCHK field will be used to create an error report further down the script.

 

My Attempt

 

I used two search cursors to compare each record with one another. If the record touches, intersects, or crosses another record it will be placed into an intersection array, if not into a non intersection array. Then I will update the intsctCHK field with another loop to see whether or not the record is in the intersection array.

 

ArcGIS 10.1 (advanced license / ArcInfo), Python (Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32)

 

     inShapefile1 = polylineShapefile
     inShapefile2 = polylineShapefile
     checkField1 = "SHAPE@"       

     checkField2 = "SHAPE@"

     updateField = " intsctCHK "

     intersectCount = 0

   

    # List of records that do not cross / touch / intersect another record

    polylineNonIntersectList = []

    # List of records that cross / touch / intersect other record/s

    polylineIntersectList = []

                  

    cursorA = arcpy.da.SearchCursor(inShapefile1, [checkField1])

    for rowA in cursorA:

        if rowA[0]:

            cursorB = arcpy.da.SearchCursor(inShapefile2, [checkField2])

            rowB = cursorB.next()

            for rowB in cursorB:

                if rowB[0]:

                    # Proceed if the row doesn't equal itself in the other cursor loop

                    if (rowA[0] != rowB[0]):

                        if (rowA[0].touches(rowB[0]) == True):
                            polylineIntersectList.append (rowA[0])

                            break

                        elif (rowA[0].crosses(rowB[0]) == True):

                            polylineIntersectList.append (rowA[0])

                            break

                        elif (rowA[0].intersect((rowB[0]),2) == True):

                            polylineIntersectList.append (rowA[0])

                            break

                        else:

                            polylineNonIntersectList.append (rowA[0])

    del cursorA

    del cursorB

  

    cursorC = arcpy.da.UpdateCursor (inShapefile1, [checkField1, updateField])

    for row in cursorC:

        if row[0]:

            #check if value in polylineListIntersect list (i.e. it intersects another record)

            if row[0] in polylineIntersectList:

                row[1] = "Y"

                intersectCount += 1

            else:

                row[1] = "N"

            cursorC.updateRow(row)

    del cursorC

 

Result

 

The program executes, however it does not work properly as it updates all records with a “N” value in the intsctCHK field and intersectCount still equals 0.

 

I am relatively new to python and wish to improve my python skills, so took it upon myself to give it a try. Also, I have attempted to use Select By Location and Spatial Join but have not been successful. If any of you guys could give advice/tips it would be of great help. Thank you in advance. 

0 Kudos
3 Replies
JakeSkinner
Esri Esteemed Contributor

Hi Gis Wombat,

Here is an example on how you can check to see if any of the polylines crosses or touches another line.  The code selects the first row using an UpdateCursor and then iterates through all the other features using a SearchCursor.  If it crosses or touches another line, it will update the intsctCHK field with "Y".  There is a second UpdateCursor used to then populate the empty or NULL values with a "N".  A second UpdateCursor is used instead of an 'else' statement because the instctCHK field will be incorrectly updated to "N" when it comes across a polyline that it does not touch/cross, when it in fact touches/crosses a different polyline.

with arcpy.da.UpdateCursor(fc, ["SHAPE@", "intsctCHK"]) as cursor:
    for row in cursor:
        with arcpy.da.SearchCursor(fc, ["SHAPE@"]) as cursor2:
            for row2 in cursor2:
                if row[0].crosses(row2[0]) or row[0].touches(row2[0]):
                    row[1] = "Y"               
                cursor.updateRow(row)

del cursor, cursor2

with arcpy.da.UpdateCursor(fc, ["intsctCHK"]) as cursor:
    for row in cursor:
        if row[0] != "Y":
            row[0] = "N"
            cursor.updateRow(row)

del cursor
0 Kudos
GisWombat
New Contributor

Hi Jake Bryson,

Can't thank you enough for assisting me with the python code. It works really well and executes perfectly. Please see below my final python code.

I was having troubles with the .contains, .within, and .equals functions because when a record in the first loop matches with itself in the second loop it updates that record with a "Y" in the intsctCHK field. Meaning all records will have a "Y" in the intsctCHK field. In my case all 4000+ polyline records had an updated "Y".

So I decided to create a check to make sure the record doesn't match itself during the process by applying another IF statement and using the polyline FID as another check.

  1. fc = polylineShapefile
  2. intersectCount = 0
  3. #   contains(second_geometry) geometry contains the other geometry.
  4. #   crosses(second_geometry) geometries intersect in a geometry of lesser dimension.  
  5. #   equals(second_geometry) geometries are of the same type and define the same set of points in the plane.  
  6. #   overlaps(second_geometry) geometries has the same dimension as one of the input geometries.  
  7. #   touches(second_geometry) boundaries of the geometries intersect.  
  8. #   within(second_geometry) geometry is contained within another geometry.  
  9. with arcpy.da.UpdateCursor(fc, ["FID","SHAPE@", "intersect"]) as cursor:
  10.    for row in cursor:
  11.        with arcpy.da.SearchCursor(fc, ["FID","SHAPE@"]) as cursor2:
  12.            for row2 in cursor2:
  13.                # Check to make sure the record doesn't match itself with the second loop
  14.                if row[0] != row2[0] and row[1] != row2[1]:
  15.                    if row[1].crosses(row2[1]) or row[1].touches(row2[1]) or row[1].overlaps(row2[1]) or row[1].within(row2[1]) or row[1].equals(row2[1]) or row[1].contains(row2[1]):
  16.                        row[2] = "Y"
  17.                        intersectCount += 1
  18.            cursor.updateRow(row)
  19. del cursor, cursor2
  20. with arcpy.da.UpdateCursor(fc, ["intersect"]) as cursor:
  21.    for row in cursor:
  22.        if row[0] != "Y":
  23.            row[0] = "N"
  24.            cursor.updateRow(row)
  25. del cursor
  26. print "*** "+str(intersectCount)+" polyline intersect errors. ***"

Thanks again, really appreciate it.

0 Kudos
GisWombat
New Contributor
  1. fc = polylineShapefile 
  2. intersectCount = 0
  3. #   contains(second_geometry) geometry contains the other geometry.
  4. #   crosses(second_geometry) geometries intersect in a geometry of lesser dimension.
  5. #   equals(second_geometry) geometries are of the same type and define the same set of points in the plane.
  6. #   overlaps(second_geometry) geometries has the same dimension as one of the input geometries.
  7. #   touches(second_geometry) boundaries of the geometries intersect. 
  8. #   within(second_geometry) geometry is contained within another geometry.  
  9. with arcpy.da.UpdateCursor(fc, ["FID","SHAPE@", "intersect"]) as cursor: 
  10.     for row in cursor:
  11.         with arcpy.da.SearchCursor(fc, ["FID","SHAPE@"]) as cursor2: 
  12.             for row2 in cursor2:
  13.                 if row[0] != row2[0] and row[1] != row2[1]:
  14.                     if row[1].crosses(row2[1]) or row[1].touches(row2[1]) or row[1].overlaps(row2[1]) or row[1].within(row2[1]) or row[1].equals(row2[1]) or row[1].contains(row2[1]):
  15.                         row[2] = "Y"
  16.                         intersectCount += 1
  17.         cursor.updateRow(row)
  18. del cursor, cursor2
  19. with arcpy.da.UpdateCursor(fc, ["intersect"]) as cursor:
  20.     for row in cursor:
  21.         if row[0] != "Y": 
  22.             row[0] = "N"
  23.             cursor.updateRow(row) 
  24. del cursor 

0 Kudos