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
Answer
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.
Remove the sliver polygons formed by the gaps between the real polygons:
v.clean input=sample output=tempA --o tool=rmarea thresh=0.001
Snap the boundary lines:
v.clean input=tempA output=tempB --o tool=snap thresh=0.001
Break the boundary lines at the new intersections:
v.clean input=tempB output=tempA --o tool=break thresh=0.001
Remove the now duplicate boundary lines:
v.clean input=tempA output=tempB --o tool=rmdupl thresh=0.001
Dissolve the polygons
v.dissolve input=tempB output=cleaned --o column=ID
Et voilĂ :
No comments:
Post a Comment