so this is to check if any annotation overlaps and if it does it rotates one by 90 degrees
this just loops through the features and works fine
with arcpy.da.UpdateCursor(fc, ["objectid", "FeatureID","Angle" ,"SHAPE@", "SHAPE@X", "SHAPE@Y","LEGACY_TABLE_NAME"],"objectid in (4007789,4007788,4007787,4007786,4007791,4007790)") as Cur:
for row in Cur:
# read in the data
print row[0]
SA_Filter = "OBJECTID = {0}".format(row[0])
try:
arcpy.management.SelectLayerByAttribute(fc, "NEW_SELECTION", SA_Filter)
annocount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(annocount[0])
if int(annocount[0]) == 1:
print "selected one anno"
arcpy.management.SelectLayerByLocation(fc, "INTERSECT", fc, "", "NEW_SELECTION")
tmpcount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(tmpcount[0])
if int(tmpcount[0]) >= 2 and int(tmpcount[0]) < 74:
print "more than 1"
row[2] = float(row[2]) + 90
except:
print "Error"
but when i add in a simple update to a text field it fails
with arcpy.da.UpdateCursor(fc, ["objectid", "FeatureID","Angle" ,"SHAPE@", "SHAPE@X", "SHAPE@Y","LEGACY_TABLE_NAME"],"objectid in (4007789,4007788,4007787,4007786,4007791,4007790)") as Cur:
for row in Cur:
# read in the data
print row[0]
SA_Filter = "OBJECTID = {0}".format(row[0])
try:
arcpy.management.SelectLayerByAttribute(fc, "NEW_SELECTION", SA_Filter)
annocount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(annocount[0])
if int(annocount[0]) == 1:
print "selected one anno"
arcpy.management.SelectLayerByLocation(fc, "INTERSECT", fc, "", "NEW_SELECTION")
tmpcount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(tmpcount[0])
if int(tmpcount[0]) >= 2 and int(tmpcount[0]) < 74:
print "more than 1"
row[2] = float(row[2]) + 90
row[6] = "updated"
Cur.updateRow(row)
except:
print "Error"
Hey @StuartMoore
In your try except error, can you add a message that prints the error inside? It may be more descriptive and point out which part is causing an issue.
except Exception as e:
print(f"Error with message: {e}")
From the surface, it's slightly difficult to see what's going on, especially since the error is saying the select by attribute is causing the issue. I would also print SA_Filter to see what it's printing.
Cody
this is what i get:
i think the issue is with this line as it works in terms of selecting the features by their objectid and also the select by location part.
Cur.updateRow(row)
i'm running this in Desktop 10.2.1 on a versioned dataset. i'm very confident that it was working yesterday but today its being a pain...
i've used similar update cursors and its worked but this time after the first feature it seems to loose connection with the database as the features disappear from the map and this pops up:
I think the issue lies with the fact that you are using an update cursor as a search cursor. I would create a search cursor to get object ids and evaluate their position and information with that. Then when I run into a feature that needs to be turned create an update cursor with a where clause that updates that object id.
thanks i tried that and it still failed, i even recreated the data and re-ran it incase the data had been corupted
with arcpy.da.SearchCursor(fc, ["objectid", "FeatureID","Angle" ,"SHAPE@", "SHAPE@X", "SHAPE@Y","LEGACY_TABLE_NAME"],"objectid in (4011345,4011328,4011327,4011326,4011325,4011324,4011323,4011346)") as Cur:
for row in Cur:
# read in the data
print row[0]
SA_Filter = "OBJECTID = {0}".format(row[0])
print SA_Filter
try:
arcpy.management.SelectLayerByAttribute(fc, "NEW_SELECTION", SA_Filter)
annocount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(annocount[0])
if int(annocount[0]) == 1:
print "selected one anno"
arcpy.management.SelectLayerByLocation(fc, "INTERSECT", fc, "", "NEW_SELECTION")
tmpcount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(tmpcount[0])
if int(tmpcount[0]) >= 2 and int(tmpcount[0]) < 74:
print "more than 1"
with arcpy.da.UpdateCursor(fc, ["objectid", "FeatureID","Angle" ,"SHAPE@", "SHAPE@X", "SHAPE@Y","LEGACY_TABLE_NAME"],"objectid = {0}".format(row[0])) as UPDCur:
for upd in UPDCur:
print "entered Update cursot"
upd[2] = float(upd[2]) + 90
upd[6] = "te22st"
UPDCur.updateRow(upd)
except Exception as e:
print "Error with message: {0}".format(e)
but oddly if i reconcile my session and refresh the map it has updated the first one
i'm thinking the issue is the arcfm session side
i change it to use the field calculator instead of the update cursor, it works but the downside is its significantly slower 😔
with arcpy.da.SearchCursor(fc, ["objectid", "FeatureID","Angle" ,"SHAPE@", "SHAPE@X", "SHAPE@Y","LEGACY_TABLE_NAME"],"objectid in (4011345,4011328,4011327,4011326,4011325,4011324,4011323,4011346)") as Cur:
for row in Cur:
# read in the data
print row[0]
SA_Filter = "OBJECTID = {0}".format(row[0])
print SA_Filter
try:
arcpy.management.SelectLayerByAttribute(fc, "NEW_SELECTION", SA_Filter)
annocount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(annocount[0])
if int(annocount[0]) == 1:
print "selected one anno"
arcpy.management.SelectLayerByLocation(fc, "INTERSECT", fc, "", "NEW_SELECTION")
tmpcount = arcpy.management.GetCount(fc)
print "tmp count: {0}".format(tmpcount[0])
if int(tmpcount[0]) >= 2 and int(tmpcount[0]) < 74:
print "more than 1"
arcpy.management.SelectLayerByAttribute(fc, "NEW_SELECTION", SA_Filter)
arcpy.CalculateField_management(fc, "Angle",
"!ANGLE!+90",
"PYTHON_9.3")
except Exception as e:
print "Error with message: {0}".format(e)
I understand your frustration I just wrote a piece of code that was going to take 60+ days....
It is weird that the OBJECTID exists but returns an invalid expression, it is almost like the fc variable is being rewritten to equal a different map layer and that why the expression fails
Nesting Cursors is generally pretty bad, but it can be useful when you want the spatial query to be done in SQL instead of iterating the whole dataset for each feature in python:
import arcpy
from arcpy.da import SearchCursor, UpdateCursor, Editor
import os
def rotate_annotations(feature_class: os.PathLike, *, angle_field: str = 'Angle') -> None:
field_names = ('OID@', 'SHAPE@', angle_field)
with UpdateCursor(feature_class, field_names) as upd_cursor:
for row in upd_cursor:
oid, shape, angle = row
intersecting_features = \
[
feature
for feature in SearchCursor(feature_class, field_names, spatial_filter=shape)
if feature[0] != oid
]
if intersecting_features:
angle += 90.0
upd_cursor.updateRow([oid, shape, angle])
return
if __name__ == '__main__':
fc = r"path\to\your\feature_class"
wsp = arcpy.Describe(fc).workspace.catalogPath
with Editor(wsp) as edit:
try:
rotate_annotations(fc)
except Exception as e:
print(e)
edit.stopEditing(False)
I also threw the operation in an Editor session, which should prevent locks. Also since the rotation code is now a function call, you can call it multiple times on the data if you want to continue rotating annotations that entered a collision after the initial rotation was applied.