Arcpy: Using Update cursor to find errors in data entry.

605
6
11-17-2022 04:28 PM
Server
by
New Contributor III

Hello,

I currently have an arc online tool that allows users to enter data for polygons based on their overlap with a larger territory layer. Unfortunately due to the nature of web app builder, the user is also able to enter values into a corresponding territory field (in the polygon layer), even if there is no overlap. Because of this issue, I am writing a tool that checks for these errors. Unfortunately I keep running into an issue. 

The two datasets look like this: 

Polygon layer:

OIDTerritory1Territory2Territory3Territory4Territory5etc.....
1      
2   Response  
3      
4 ResponseResponse   

 

Territory layer:

OIDFIELD_NAME
1Territory2
2Territory3
3Territory4
4Territory5
etc...etc...

 

Essentially I want to select an individual territory (from the FIELD_NAME field), intersect it with the polygon layer, reverse the selection (so all polygons that are not within the territory are selected) and then test to see if that specific territory field within the polygon layer has any values in it. If it does, then there is an error and I want that to be displayed in an error field with the number of errors. 

Currently, my code seems to just be adding 1, regardless of any data that is incorrect/correct in the dataset. Keep in mind I have a break statement in my code, so after one iteration it stops (for testing). 

Server_1-1668730925218.png

 

Any Ideas?

 

Here is my code (ive changed the dataset names etc): 

 

 

 

 

def check_errors():
    
    env.workspace = gdb_name
    print ('--------------------------------------')
    print("check_errors()")
    
    arcpy.management.AddField('polygon_areas', "OVERLAP_ERROR", "LONG")

    #create layers
    polygon_layer = arcpy.MakeFeatureLayer_management('polygon_areas', 'polygon_layer')
    territory_layer = arcpy.MakeFeatureLayer_management('territory', 'territory_layer')
    print("layers created!")
    
    overlap_error_count = 0
    overlap_error_field = ["OVERLAP_ERROR"]
    
    
    #clear error field:
    update_cur = arcpy.da.UpdateCursor(polygon_layer, overlap_error_field)
    for row in update_cur:
        row[0] = 0
        update_cur.updateRow(row)
    print ('    Cleared error field') 
    
    
    
    #-------------------------------------------------------------------------------------------------------------------------------
    
    territory_fields = [
    'Territory1','Territory1','Territory1','Territory1','Territory1','Territory1','Territory1','Territory1','Territory1', 'Territory1'
    ]
    
    #cycle through each field that corresponds to territory name, check for errors
    for name in territory_fields:

        print("Currently Processing: " + name)
        print(datetime.datetime.now())
        
        #select a territory, intersect with the polygons, and select all polygons that fall outside of the territory
        #do any rows have values within the territories field? Should be empty
        arcpy.SelectLayerByAttribute_management('territory_layer', 'NEW_SELECTION', "FIELD_NAME = '" + name + "'")
        arcpy.SelectLayerByLocation_management('polygon_layer', 'INTERSECT', 'territory_layer', "", "", "INVERT")
        
        
        #look at the territory field, add a 1 to the error field if there exists data within the territory field
        update_cur = arcpy.da.UpdateCursor("polygon_layer", [name] + overlap_error_field)  
        for row in update_cur:
            
           
            if row[0] != "" or None or " ":
                
                row[1] += 1
            
                update_cur.updateRow(row)            
        
        
    print ('overlap errors calculated')
        
    arcpy.CopyFeatures_management('polygon_layer', 'Polygon_features')

 

 

 

 

 

 

Thanks in advance! Im pulling my hair out with this one. 

0 Kudos
6 Replies
Brian_Wilson
Occasional Contributor III

Quick scan, line 50 jumped out at me. It's wrong. 

I think you probably meant

 

            if row[0] != "" and row[0] != None and row[0] != " ":

 

There are probably other ways to do that, maybe this ? The first part tests for row[0] having something in it and the second part will strip off any number of spaces from the start and end of the string. So it matches "    1   " and " 1" for example

if row[0] and row[0].strip():

 

 

0 Kudos
Server
by
New Contributor III

Nice catch. I've changed that. Unfortunately still getting the same results. 

Server_0-1668732673763.png

 

0 Kudos
DanPatterson
MVP Esteemed Contributor

or

 

if row[0] not in ["", " ", None]:

 


... sort of retired...
0 Kudos
by Anonymous User
Not applicable

Any reason you are using the same field in the territory_fields list?

territory_fields = [
    'Territory1','Territory1','Territory1','Territory1','Territory1','Territory1','Territory1','Territory1','Territory1', 'Territory1'
    ]

 

Maybe output the selections to a feautureclass so you can see what your code is doing and maybe that will show you where the 1 is coming from.

0 Kudos
Brian_Wilson
Occasional Contributor III

Try putting "del row, update_cur" below the update loop, and, what's that "break" doing on line 55?

"Del" will force the objects to be released so if anything is buffered for some reason it will be flushed.

But that break... won't it terminate the outer for loop? so you're only going through that loop once? Huh.

0 Kudos
Server
by
New Contributor III

Hi Brian, the break is simply there to stop the loop at one iteration (one territory). Its just for testing (I stated in the blurb above). I can see how its confusing though. Ill edit my submission for clarity. Ill give the "Del" a shot. 

0 Kudos