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:

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

Before and after example

Annotated table, what to keep and discard

  • To do this I would use Polygon Neighbors first to create a table from which to look up which polygons are neighbors and then to run a cursor through the feature class updating variable values as you wish as well as one to flag whether it should be dissolved as a final step. – PolyGeo Dec 10 '15 at 19:46
  • If you have networkx module I can post solution that uses it – FelixIP Dec 10 '15 at 22:15

I would create two copies of the layer for this feature class. In one layer I would select everything. In the other layer I would select just the polygons with a Class of "A". I would use Spatial Join using the layer with all features selected as the target and the layer with just Class A features as the Join layer. I would use the keep all target features option and the One to One option.

The output will have duplicate fields, Select all records where the Name and Name_1 fields contain the same values. This will be the set of all the features that touched a Class A feature and had a matching Name value. Calculate the Class field of the Target to be "A". Calculate over the Code_1 and waterDefinition_1 fields into the Code and waterDefinition fields to set these values to match the value of the touching Class A feature.

Now you can Dissolve all of the features and use all of the target fields as Dissolve fields (Not the fields ending in _1) to preserve the unique attribute cases. Uncheck the Create Multi-part feature option. If a feature was not touched by a Class A feature it will have its original attributes. Merge of these features would only occur if they were touching features that had the same attribute values that are not Class A attributes. However, all features that touched a Class A feature will now be merged together and have the Class A attributes.

  • +1 However I'd first exported B that don't share a boundary with A first and delete all of the attributes in remaining B. Not sure this will work if there is ABB polygons in 1 'row' – FelixIP Dec 10 '15 at 22:00
  • Exporting the B polygons avoids two B polygons dissolving together when they had the exact same attributes, so that is fine. No need to void the attributes of the remaining B polygons. The Spatial Join would have Null in all of the join fields when a Class A polygon does not touch a Class B polygon. There is a possible worry if two same Case Class A polygons with an attribute difference touch the same Class B polygon, but do not touch each other, since only one of the Class A polygons would dissolve with the Class B polygon. A second iteration of the process would eliminate that set. – Richard Fairhurst Dec 10 '15 at 22:34
  • Spatial Join is key. I had explored and rejected this earlier because of resulting nulls in the attributes I wanted to keep (wrong Match Option) . With your encouragement to look at it again I found something that works, and discovered a simplification of your method too! More coming when I get my notes in better shape. – matt wilkie Dec 11 '15 at 18:53

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:

  1. 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.

  2. 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.

  3. 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.

Model diagram

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)

    dissolve_field="Name", statistics_fields="", 

    where_clause="Class LIKE 'A'")




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.

Interactive Spatial Join dialog

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.