I have a script that is supposed to replace the geometry of a polygon with a new polygon constructed by reading some of its fields (minX, minY, maxX, maxY).
I can do this with traditional arcpy, but I'm running into issues when trying to do it with the arcgis module.
Specifically, I either get no edits to the geometry if I include a spatial reference OR I get a "read-only" error if I include the spatial reference.
The documentation does not have any examples of actually updating geometry the way that you can update attributes.
Does anyone have any pointers? Thanks
# Get inspectbl as arcgis Featureset
inspectFL = arcgis.features.FeatureLayer(inspectbl,
gis=portal)
inspectFS = inspectFL.query(where=where_clause)
spatref = inspectFS.spatial_reference
for insp in inspectFS:
# Convert arcgis.feature geometry into
# arcpy Geometry.
lowleft = [insp.attributes["mapminx"],
insp.attributes["mapminy"]]
upleft = [insp.attributes["mapminx"],
insp.attributes["mapmaxy"]]
upright = [insp.attributes["mapmaxx"],
insp.attributes["mapmaxy"]]
lowright =[insp.attributes["mapmaxx"], insp.attributes["mapminy"]]
corners = [lowleft, upleft, upright, lowright]
geo = arcgis.geometry.Polygon(corners, spatial_reference=spatref)
geo = arcgis.geometry.Geometry({"rings":corners,
"spatial_reference": {"wkid":spatref}})
insp.set_value(field_name="shape",
value= geo)
inspectFL.edit_features(updates=inspectFS,
use_global_ids=True)
Solved! Go to Solution.
Ok, so as it turns out, it was not an issue of the final point, although I've added that just in case.
The actual issue was that I was not nesting the coordinates deep enough.
The "rings" needs to be a list of lists of coordinate pairs, like:
[[[x1,y1], [x2,y2]]]
I had it as
[[x1,y1, [x2, y2]]
Final working is
# Get inspectbl as arcgis Featureset
inspectFL = arcgis.features.FeatureLayer(inspectbl,
gis=portal)
inspectFS = inspectFL.query(where=where_clause)
spatref = inspectFS.spatial_reference
for insp in inspectFS:
# Convert arcgis.feature geometry into
# arcgis.geometry.Geometry.
lowleft = [insp.attributes["mapminx"],
insp.attributes["mapminy"]]
upleft = [insp.attributes["mapminx"],
insp.attributes["mapmaxy"]]
upright = [insp.attributes["mapmaxx"],
insp.attributes["mapmaxy"]]
lowright =[insp.attributes["mapmaxx"], insp.attributes["mapminy"]]
corners = [[lowleft, upleft, upright, lowright, lowleft]]
geo = arcgis.geometry.Geometry({"rings":corners,
"spatial_reference":
{"wkid":spatref}})
insp.set_value(field_name="shape",
value= geo)
x = inspectFL.edit_features(updates=inspectFS,
use_global_ids=True)
Thanks everyone
Might be worth using the as_dict instance method and from_dict class method to create a new feature with matching attributes instead of editing the original object. Heavy handed but if it works, it works!
I might be mistaken about this, but I don't think your polygons are valid. I'm pretty sure the first point needs to be repeated as the last point to close it out, like this:
corners = [lowleft, upleft, upright, lowright, lowleft]
That's an interesting thought and I'll check it out, but it works with only four points in normal arcpy
with arcpy.da.UpdateCursor(inspectbl,
['SHAPE@', "mapminx", "mapminy",
"mapmaxx", "mapmaxy", "OID@"],
where_clause= where_clause) as cursor:
for row in cursor:
lowleft = arcpy.Point(row[1], row[2])
upleft = arcpy.Point(row[1], row[4])
upright = arcpy.Point(row[3], row[4])
lowright = arcpy.Point(row[3], row[2])
corners = arcpy.Array([lowleft, upleft, upright, lowright])
row[0] = arcpy.Geometry("polygon", corners)
cursor.updateRow(row)so I'm not certain that's it
Ok, so as it turns out, it was not an issue of the final point, although I've added that just in case.
The actual issue was that I was not nesting the coordinates deep enough.
The "rings" needs to be a list of lists of coordinate pairs, like:
[[[x1,y1], [x2,y2]]]
I had it as
[[x1,y1, [x2, y2]]
Final working is
# Get inspectbl as arcgis Featureset
inspectFL = arcgis.features.FeatureLayer(inspectbl,
gis=portal)
inspectFS = inspectFL.query(where=where_clause)
spatref = inspectFS.spatial_reference
for insp in inspectFS:
# Convert arcgis.feature geometry into
# arcgis.geometry.Geometry.
lowleft = [insp.attributes["mapminx"],
insp.attributes["mapminy"]]
upleft = [insp.attributes["mapminx"],
insp.attributes["mapmaxy"]]
upright = [insp.attributes["mapmaxx"],
insp.attributes["mapmaxy"]]
lowright =[insp.attributes["mapmaxx"], insp.attributes["mapminy"]]
corners = [[lowleft, upleft, upright, lowright, lowleft]]
geo = arcgis.geometry.Geometry({"rings":corners,
"spatial_reference":
{"wkid":spatref}})
insp.set_value(field_name="shape",
value= geo)
x = inspectFL.edit_features(updates=inspectFS,
use_global_ids=True)
Thanks everyone