I am trying to update the geometry of a point layer based on values in another table. I originally collected a large set of manhole locations and attributes using a submeter GNSS receiver. Requirements for the project changed and we ended up having to go back out and survey them with an RTK GNSS receiver for higher accuracy. I already have my feature class with attachments and attributes (including an Asset_ID field) for the submeter resolution data. I have a .csv and a shapefile of the RTK resolution data (with a Name field that matches the Asset_ID field from my submeter dataset). How can I go about moving all of my submeter data to the positions of the RTK data set, and maintain my attachments and attributes, without manually updating the geometry of each feature in the advanced editing toolbar, or manually snapping them to the features in the RTK shapefile. I am running 10.6 Advanced with most extensions (i.e. spatial analyst, 3D analyst, Geostatistical analyst, etc.)
P.S.: I have already done a join based on the Name/Asset_ID fields and populated 3 fields in my Submeter dataset (POINT_X, POINT_Y, and POINT_Z) with the coordinates from the RTK dataset, so I guess I could update based on those fields instead of an external dataset/table
I have this exact same problem. Did you ever figure out a way to do it?
My situation is very similar.
I have two address point layers with the same data, but different point locations. It sounds similar to your updating structure locations issue. There is a common field between the two layers. I have several thousand points that need updated, so a manual effort would be a poor use of time.
@JamesJordan, @DanAllen , @DerekHunt1
I'm pretty late to the party, but maybe it still helps...
This sounds like a job for Python, not Arcade.
Open the Python window:
Edit this code, paste it in the Python window and execute it (make sure you don't have selections in the layers!).
geometry_layer_name = "name_of_the_layer_with_the_right_geometry"
attribute_layer_name = "name_of_the_layer_with_attributes_and_wrong_geometry"
common_field = "name_of_the_common_field"
# this will change the geometry of the second layer's underlying data, so back it up!
active_map = arcpy.mp.ArcGISProject("current").activeMap
geometry_layer = active_map.listLayers(geometry_layer_name)[0]
attribute_layer = active_map.listLayers(attribute_layer_name)[0]
# read the correct geometries and save them in a dictionary
# {common_field_value: shape}
cursor = arcpy.da.SearchCursor(geometry_layer, [common_field, "SHAPE@"])
shapes = dict([row for row in cursor])
# loop through the second layer and update the geometries
with arcpy.da.UpdateCursor(attribute_layer, [common_field, "SHAPE@"]) as cursor:
for row in cursor:
try:
new_shape = shapes[row[0]]
cursor.updateRow([row[0], new_shape])
except KeyError:
print("No new geometry found for feature with {} = {}".format(common_field, row[0]))
Huge Kudos! This worked flawlessly!
Hi Johannes,
Thank you for the script. It does indeed work great. Would you be kind enough to edit the script to print the list of only the features that had their geometry changed?
Cheers,
Richard
geometry_layer_name = "name_of_the_layer_with_the_right_geometry"
attribute_layer_name = "name_of_the_layer_with_attributes_and_wrong_geometry"
common_field = "name_of_the_common_field"
# this will change the geometry of the second layer's underlying data, so back it up!
active_map = arcpy.mp.ArcGISProject("current").activeMap
geometry_layer = active_map.listLayers(geometry_layer_name)[0]
attribute_layer = active_map.listLayers(attribute_layer_name)[0]
# read the correct geometries and save them in a dictionary
# {common_field_value: shape}
cursor = arcpy.da.SearchCursor(geometry_layer, [common_field, "SHAPE@"])
shapes = dict([row for row in cursor])
# loop through the second layer and update the geometries
updated_features = []
with arcpy.da.UpdateCursor(attribute_layer, [common_field, "SHAPE@"]) as cursor:
for row in cursor:
try:
new_shape = shapes[row[0]]
# only update if the geometry is different, fill the updated_features list
if not new_shape.equals(row[1]):
cursor.updateRow([row[0], new_shape])
updated_features.append(row[0])
except KeyError:
print("No new geometry found for feature with {} = {}".format(common_field, row[0]))
# build an SQL query of the updated_features, depending on whether common_field is a text field or not
if updated_features and isinstance(updated_features[0], str):
sql = "{} IN ('{}')".format(common_field, "', '".join(updated_features))
else:
sql = "{} IN ({})".format(common_field, ", ".join([str(uf) for uf in updated_features]))
# print the SQL query
print("Updated the geometry of {} features:\n{}".format(len(updated_features), sql))
So I'm able to run the script but I keep ending with "No new geometry found for feature with__" and then it list my common field. Any ideas on what I need to change?
That means the script doesn't find the corresponding values in the geometry update table.