Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
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)

share|improve this answer
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

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.

My method is to use the MMQGIS plugin to export the feature set as .csv nodes, then open the .csv in a spreadsheet, and do a custom filter for shape_id cells containing the string 'ring'. You can then place a flag, such as integer 1, into the fourth column, so it is entered only into the filtered rows. Then, take off the filter, and order all four columns by your flag column, largest-to-smallest so the 1's are at the top. Then select, copy, and paste the first three columns of only the flagged rows into a new workbook, and save as .csv.

Then you use MMQGIS again, this time importing your new .csv node file as polygons. This will be a layer that contains only the rings from the original polygon, so you can then easily copy and paste all these features into the relevant single-feature layer. 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.

Once finished with all the feature sets, then you can copy and paste or otherwise rejoin them into a single feature set with all the rings filled.

share|improve this answer

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

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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