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:
OID | Territory1 | Territory2 | Territory3 | Territory4 | Territory5 | etc..... |
1 | ||||||
2 | Response | |||||
3 | ||||||
4 | Response | Response |
Territory layer:
OID | FIELD_NAME |
1 | Territory2 |
2 | Territory3 |
3 | Territory4 |
4 | Territory5 |
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).
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.
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():
Nice catch. I've changed that. Unfortunately still getting the same results.
or
if row[0] not in ["", " ", None]:
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.
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.
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.