11

I have a polygon vector layer representing the area inundated in a flood. The layer has been produced in a such a way that some of the areas are composed of multiple smaller touching polygons (see screenshot below, labelled "original data").

I would like to dissolve the polygons where they touch. If I use the dissolve geoprocessing tool in QGIS's fTools, which uses the GEOS library, I get some unexpected results (see "dissolve with QGIS fTools"). It seems that GEOS doesn't use a threshold in determining if polygons are touching, as mentioned in these issues:

http://trac.osgeo.org/qgis/ticket/3126

http://trac.osgeo.org/qgis/ticket/3184

http://hub.qgis.org/issues/2806

The same approach in ArcGIS gives the expected result (see "dissolve with ArcGIS 10.1").

Apparently this is a "feature" of GEOS, rather than a bug. Is there any way to fix the data I have to produce the expected result? A minor loss of precision (a few cm?) could be acceptable for me. Ideally the solution would be something I could write into a QGIS plugin, as a pre-processing step.

Related question (with no answers): How to set tolerance value of Geoprocessing tool in QGIS?

Link to sample data as a shapefile: https://www.dropbox.com/s/c8ns7wwfv289ad0/sample.zip

dissolve polygons v.dissolve

  • A workaround would be to first grow and then shrink the fTools-dissolved polygon (by buffering first with a positive and then with a negative buffer). – Jake Sep 16 '13 at 13:51
  • I did try this, but I end up with other problems (e.g. i.stack.imgur.com/LnFJy.png). Here, the blue area is created when I buffer/dissolve/neg-buffer, where it shouldn't be. This isn't too much better than the original problem. I can't see how I can recover the original "sharp" corner. – Snorfalorpagus Sep 16 '13 at 14:03
14

In this case, it looks like you need to help the dissolve tool along by fixing the topology first. Here's how you can do this in GRASS.

When you load the shapefile, this is how GRASS sees it:

Each cross marks an area. You can see that there are some crosses on the boundary lines: These are the sliver polygons caused by the slight offset between the boundary lines.

  1. Remove the sliver polygons formed by the gaps between the real polygons:

    v.clean input=sample output=tempA --o tool=rmarea thresh=0.001
    
  2. Snap the boundary lines:

    v.clean input=tempA output=tempB --o tool=snap thresh=0.001
    
  3. Break the boundary lines at the new intersections:

    v.clean input=tempB output=tempA --o tool=break thresh=0.001
    
  4. Remove the now duplicate boundary lines:

    v.clean input=tempA output=tempB --o tool=rmdupl thresh=0.001
    
  5. Dissolve the polygons

    v.dissolve input=tempB output=cleaned --o column=ID
    

Et voilà:

  • Thanks @Jake. This is a very clear answer. Unfortunately when I try to apply the process to my entire dataset (covering 2500km2), I get an error from the snap tool "ERROR: G_realloc: unable to allocate 144720024 bytes of memory at snap.c:186". I guess I'm going to have to break it down into smaller chunks. That should be OK though, as I'm already breaking it down into 0.25km2 squares to speed up intersections / spatial indexing (this is the "ID" field in the sample data). – Snorfalorpagus Sep 17 '13 at 13:08
7

Use GRASS GIS command v.dissolve (in Sextante plugin -> GRASS Commands -> Vector)

If I quickly reproduce you example: enter image description here

The result with v.dissolve:

enter image description here

Explanation

The problem is easy to understand. A shapefile has no topology, if two areas shared a common border that border would be digitized two times and also stored in duplicate.

You see this clearly when you try to edit the shapefile:

enter image description here

GRASS GIS (as ArcGIS) is a topological gis. When you import the shapefile in GRASS, the resulting layer has a topology: the common border between two areas exists once and is shared.

enter image description here

For this reason, when you want to dissolve a shapefile (dissolve two boundaries) you might encounter problems (in QGIS, GvSIG, OpenJUMP, or the old ArcView 3.x), see ArcUserI:Understanding Topology and Shapefiles.

In GRASS, v.dissolve is designed to dissolve common boundaries between areas with the same category number

  • 1
    My guess is that this is a numeric problem, and I wonder if your pretty good copy of the OP's geometry, would capture the same numeric properties? – Chau Sep 17 '13 at 6:31
  • @Chau: v.dissolve has a tolerance parameter, which addresses the OP's problem. – Jake Sep 17 '13 at 6:54
  • That detail should be incorporated into the above answer, thanks for clarifying :) – Chau Sep 17 '13 at 7:12
  • I've added a link to the original data as a shapefile in the question. When I use v.dissolve it does seem to work, except that it "fills" the little square in the middle of the features. i.stack.imgur.com/AA59l.png – Snorfalorpagus Sep 17 '13 at 8:10
  • 1
    I propose an explanation – gene Sep 17 '13 at 18:18

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.