4

In QGIS 3.16. I have a layer of 1000+ polygons, many of which are adjacent (touching, overlapping, or one completely inside another). If all of the adjacent polygons are merged, I will end up with between 100 and 200 (larger) polygons.

I would like to accomplish this in a way that preserves all of the attributes for all polygons, for example:

  1. For polygons being merged: values for attribute X are concatenated for the resulting polygon. (Example: For attribute 'status', Polygon A has value "IC" and Polygon B has value "NC". If these two polygons merge into Polygon AB, I would like the corresponding value of attribute 'status' to be "IC, NC".)

  2. For polygons not being merged (i.e. isolated ones without an adjacent neighbor) there is no change to their attributes.

This seems like a fairly common task that it should be possible to accomplish, but my searches have been fruitless thus far.

I'd like to stay within QGIS if possible (I have never used PostGIS before). If your answer involves SQL or Python, please consider that I am learning these now but an absolute beginner, so I will not understand code without context.

6

Using only QGIS, you can achieve this as follows:

  1. Dissolve all polygons

  2. Apply Multipart to singleparts to the dissolved polygons: you get one feature for each connected group of polygons.

  3. On the orginal layer, create a new field named grouped that adds a unique identifier for the group of polygons each of the original polygon features is part of. Use this expression in the field calculator: array_first (overlay_intersects( 'singleparts', $id)) where singleparts is the name of the layer created in step 2.

  4. Use Menu Processing / Toolbox / Aggregate with the original polygon layer as input to dissolve all features based on the group field created in step 3.

Screenshot: see original adjacent polygons (touching, overlapping, within another), labeled with their value for the status attribute and the group as calculated in step 3. The Aggregate dialog shows Group by expression that based on this grouped attribute, the polygons are dissolved. Below, you can choose how each attribute will be aggregated: for status, select concatenate and make sure the field length (second last column) is long enough (in my case, 10 was too short, I manually had to change it: I set the value to 100). enter image description here

Result: three single features, labeled with the (concatenated) status attribute: enter image description here

12
  • Babel, you are being extraordinarily helpful to me this/last week and I appreciate it very much. Thanks! I understand the principle of what you're suggesting, but my attempts to implement step #3 are yielding a column with all NULL values. (Strangely, the field calculator seems to be getting values as the output preview shows a number in brackets...) The same behavior occurs: 1) whether the simpleparts layer (with my name) is temporary or saved to a .shp; 2) whether I use $id or a field "id" that I created in that .shp; 3) whether the new 'grouped' field is type Integer or String. – pete May 11 at 14:04
  • Sorry, you're right: the output of overlay_intersects() is an array. To get the number, you must add an array_first () function. I changed my anser accordingly. – Babel May 11 at 14:08
  • This worked for the ID (step 3)! Unfortunately the polygon groups do not exactly match the features created during step 2: in some cases a polygon is in one group for the 'singleparts' layer, and another group in the 'grouped' field in the original layer. I can't upload an image in the comment but the cases I'm seeing of this are where two polygons appear to be touching at exactly one vertex (and are also touching other polygons); the smaller of the two polygons is inconsistently grouped. – pete May 11 at 14:47
  • You can edit your original question to upload a screenshot (if you than copy the link in edit mode and paste it to comments, to can avoid publishing the image there). I'm not quite sure how the problem looks and how you want to have it resolved. I added two polygons that touche other polygons at exactlyy one vertiex, see: i.stack.imgur.com/gQ31S.png – Babel May 11 at 15:03
  • 1
    I think I have solved my above issue via the following method: from the original layer, create a buffer layer of distance 0,01m; then use that buffer layer for the rest of your sequence. The polygons that touch at a single node are subsequently grouped together, which was not the case before. If anyone has further suggestions, feel free to share them. Otherwise, thanks again Babel! – pete May 11 at 15:04

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.