Merging lakes split on YT border
Turned out to be quite involved, but now have an automated solution.
How to automatically merge polygons sharing a common boundary, keeping all attributes from class “A” features?
Interactively I would do this in an edit session by:
- selecting all objects of Name “One”,
- Editor toolbar >> Merge,
- choose Class “A” to be the parent/master feature.
Repeat for features of Name “Two”, “Three”, …
Dissolve solution from How to combine adjacent polygons sharing similar trait into single polygon? doesn’t work because we need to keep other attributes which differ. In other words:
- Dissolve/merge touching polygons where geometry [Name] is identical
- Keep attributes from polygon with [Class] A (if multiple Class A’s, ok to just keep first one)
- Discard attributes from other features
Dissolve does work, just not on it’s own. Spatial Join as well, but it too is insufficient on it’s own. I had explored and rejected both of these earlier because of of losing wanted attributes altogether (Dissolve) or resulting nulls in the attributes I need to keep (Spatial Join). With @Richard’s answer we’re reoriented properly. The solution:
- Dissolve on the common field, Name. We lose all other attributes but that’s ok as it’s only the geometry we’ll keep from this step.
- Collect the attributes we want and make them portable with Make Feature Layer (or a Definition Query or interactive selection or …) and Feature to Points. Make sure to select INSIDE so the points are always inside the polygons.
- Transfer the attributes from the points to the empty polygons with Spatial Join, use Match Option CLOSEST. One to one and One to Many don’t seem to differ for the data I’m working with.
Expressed in arcpy:
# original feature class: border_lakes # final feature class: dissolved_border_lakes_with_attributes # all others can be discarded (tip: use "in_memory" workspace) arcpy.Dissolve_management(in_features="border_lakes", out_feature_class="dissolved_border_lakes", dissolve_field="Name", statistics_fields="", multi_part="MULTI_PART", unsplit_lines="DISSOLVE_LINES") arcpy.MakeFeatureLayer_management(in_features="border_lakes", out_layer="selected_border_lakes", where_clause="Class LIKE 'A'") arcpy.FeatureToPoint_management(in_features="selected_border_lakes", out_feature_class="attribute_points", point_location="INSIDE") arcpy.SpatialJoin_analysis(target_features="dissolved_border_lakes", join_features="attribute_points", out_feature_class="dissolved_border_lakes_with_attributes", join_operation="JOIN_ONE_TO_ONE", join_type="KEEP_ALL", field_mapping="", match_option="CLOSEST", search_radius="", distance_field_name="")
Notes
Spatial Join in step 3 is where I went wrong at first and ended up with null attributes or other unwanted combinations. I was choosing HAVE_THEIR_CENTER_IN and WITHIN. It was the interactive Spatial Join from the ArcMap table of contents, with it’s different wording from the geoprocessing tool, that gave me the final clue.
I suspect it possible to use spatial join without using the point file intermediary, but wasn’t successful with our data. Having something that works is good enough for now; I’ll leave further optimization for others.