I'm cleaning up a (very) messy shapefile in QGIS/Grass.

I now have several large polygons with numerous (100s) of small rings.

Is there a quick and easy way to remove/ fill all these small rings. Selecting and deleting each one manually is not feasible.

  • do you mean small polygons instead of small rings? – dmci Dec 10 '12 at 14:03
  • They are empty spaces, so rings – Andy Harvey Dec 10 '12 at 14:34
  • have you tried using v.clean tool=rmarea thresh=... – dmci Dec 10 '12 at 16:03
  • Thanks dcmi, yes I have tried rmarea but it does not seem to be working. Can you confirm, should this work on rings, or only on slivers between polygons. Perhaps I am using the tool incorrectly? – Andy Harvey Dec 10 '12 at 16:22
  • what type is shapefile polygon or linestring ? – simplexio Jan 10 '13 at 9:40

If you need to fill small "donut holes" you might try the buffer-out/buffer-in trick. You create a buffer of your polygons just large enough to fill the holes. Then buffer that polygon layer again with the same value but negative (i.e. buffer inside). The problem with this method is that is does change the outer boundary slightly. If the holes are small, this might not make too much of a difference. (From what you describe as "rings", they seem to empty areas, not part of the surrounding polygon, so v.clean tool=rmarea won't work)

  • thanks micha, thats what i thought RE v.clean.rmarea. The buffer idea is a good one, but I don't think will work in this case. Some of the rings are relatively large, and I need to keep the outer boundary's position. Looks like manual delete is the only way to go....? – Andy Harvey Dec 11 '12 at 8:21
  • Andy, consider also the threshold parameter for the tools to pick only those of interest. And see also v.edit which also supports to spatially constrain operations. Eventually, consider to use GRASS 7 for that which has even more topological tools. – markusN Feb 9 '13 at 9:24

I am assuming that these small rings are "donut holes", or gaps within the polygon (and am mostly writing this for better search result hits, as the title is a bit ambiguous to me).

My solution to this using GRASS GIS is as follows:

# (optional before starting: clean features
v.clean in=original_import out=original_map tool=bpol,rmdup
v.build map=original_map

# 1. Add centroids to the holes
v.centroids in=original_map out=map_with_centroids
# 2. Drop the current table and and one that includes the 
#    areas that now have centroids and a value column that
#    you will use to dissolve the areas
v.db.droptable map=map_with_centroids -f
v.db.addtable map=map_with_centroids columns='value INT'
# 3. Update this "value" column with the same value everywhere
v.db.update map=map_with_centroids col=value value=1
# 4. Now combine the areas by dissolving them together
v.dissolve in=map_with_centroids out=map_noholes column=value

If you rename "original import" to your input map name and "map_noholes" to your desired output map name, you should be able to just copy/paste this block.


The following solution is feasible only if you have a limited, manageable number of large polygons. First save each polygon as a separate, single-feature shapefile. Then for each one, do the following.

Use the MMQGIS plugin to export the feature set as .csv nodes, then open the 'temp_nodes.csv' in a spreadsheet. Sort the data by the 'shapeid' column. Delete all rows whose 'shapeid' value does not contain the text string 'ring' (these should be sorted together). Save your csv file (maybe 'save as ...').

Then you use MMQGIS again, this time importing your .csv node file as polygons. This will be a layer that contains only the rings from the original polygon. Then make a very small distance buffer, maybe 0.05m, small enough distance to be sure none of the buffer polygons extend beyond the exterior boundary of your large polygon. Select and copy all the buffer features, and paste them into the layer with the single large feature. This is now no longer single-feature, because it has the original polygon plus separate polygons for each ring. So then, select all features in the set, and merge them. Remove the csv and buffer layers and delete all the source files, which are now redundant.

Repeat the steps for each of your single-feature layers. Once finished with all these feature sets, then you can copy and paste or otherwise rejoin them into a single feature set with all the rings filled.


There is new QGIS tool now that works fine!

new QGIS tool

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.