v.fill.holes(1)

πŸ’– v.fill.holes β€” the GRASS GIS User's Manual glow-up πŸ’–

okay bestie, welcome to the v.fill.holes(1) page, straight outta the GRASS GIS User's Manual. this one's a lil vector geometry baddie and honestly? she eats. let's get into it 🫢


✨ NAME ✨

v.fill.holes β€” fill holes in areas by keeping only outer boundaries

πŸŽ€ KEYWORDS πŸŽ€

vector, geometry, fill, exterior, ring, perimeter

πŸ¦‹ SYNOPSIS πŸ¦‹

v.fill.holes
v.fill.holes --help
v.fill.holes input=name  [layer=string]   [cats=range]
[where=sql_query]  output=name  [--overwrite]  [--help]  [--verbose]
[--quiet]  [--ui]

🌸 Flags 🌸

  • --overwrite β€” allow output files to just steamroll over existing files, no questions asked
  • --help β€” print the usage summary, iykyk
  • --verbose β€” verbose module output, she's chatty
  • --quiet β€” quiet module output, she's not
  • --ui β€” force launching the GUI dialog, for the visual learners

πŸ’… Parameters πŸ’…

  • input=name [required] β€” name of the input vector map. or, plot twist, a data source for direct OGR access
  • layer=string β€” layer number or name. vector features can carry category values in different layers, and this number decides which layer we're using. when you're doing direct OGR access, this is the layer name instead. Default: 1
  • cats=range β€” category values. Example: 1,3,7-9,13
  • where=sql_query β€” WHERE conditions of SQL statement, without the ’where’ keyword. Example: income < 1000 and population >= 10000
  • output=name [required] β€” name for output vector map

🌈 DESCRIPTION 🌈

so v.fill.holes fills the empty spaces inside areas. specifically, it keeps the areas that have centroids, while areas without centroids β€” which typically represent holes β€” get removed. periodt. πŸ—‘οΈ

v.fill.holes goes over every area in a vector map and preserves only the outer boundaries of each area, yeeting the inner boundaries that are considered holes. those holes become part of the area that contained them, and no boundaries of those holes are kept. not one. πŸ’€

Figure: Holes inside areas are removed. (a) Original areas with holes and (b) the same areas but with holes filled.

now, in the case where areas have empty space in between them β€” like, there are holes in the overall coverage but not in the areas themselves β€” v.fill.holes can't assign that empty space to either of the areas, because it genuinely does not know which area that space should belong to. πŸ™ˆ if that space needs filling, the fix is to merge the areas around the empty space into one by dissolving their common boundaries. that turns the empty space into a hole inside one single area, which is giving... one area with a hole. problem solved, slay. ✨

Figure: Empty space in between two areas does not belong to either area, so it is filled only after the boundaries between areas are dissolved, i.e., areas merged into one. (a) Original areas with space in between, (b) one area with a hole after dissolving the common boundary, and (c) hole filled.

🧚 Topology 🧚

strictly speaking β€” and bestie, we are being strict β€” in the GRASS topological model, an area is a closed boundary (or a series of connected closed boundaries) which may have a centroid. if it has a centroid, it gets rendered as a filled area in displays, and that's what everyone usually means by "area" from the user's perspective. those are the areas where v.fill.holes preserves the associated outer boundary (or boundaries). πŸ‘‘

other closed boundaries β€” the ones without a centroid β€” are not carried over to the output. and all other features get removed too, points and lines included. bye bye. πŸ‘‹

πŸ’œ Attributes πŸ’œ

if a specific layer is selected, attributes for that layer are preserved for the areas, based on the category or categories associated with each area. by default, layer number 1 is the one selected.

but if there are attribute tables hanging out with other layers, or attributes tied to categories of features other than areas with centroids β€” that attribute data does not get carried over to the output, same way the corresponding geometries don't. no cap. 🚫


πŸ“ EXAMPLE πŸ“

the lakes vector map in the North Carolina sample dataset represents islands inside lakes as areas distinguished by attributes. to show off v.fill.holes, we're first gonna extract only the lakes, which creates holes exactly where the islands used to be. then we fill those holes back in so we get the whole perimeter of the lakes, islands included. 🏞️

remove the islands by extracting everything else (results in holes):

v.extract input=lakes where="FTYPE != ’ROCK/ISLAND’" output=lakes_only

remove the holes:

v.fill.holes input=lakes_only output=lakes_filled
Figure: The filled lake (blue) and borders of the original lakes with islands removed (light blue). Figure shows a smaller area in the north of the data extent.

πŸ‘€ SEE ALSO πŸ‘€

  • v.dissolve for removing common boundaries based on attributes
  • v.clean for removing topological issues
  • r.fillnulls for filling empty spaces in raster maps using interpolation
  • r.fill.stats for filling empty spaces in raster maps using statistics

πŸ‘‘ AUTHOR πŸ‘‘

Vaclav Petras, NCSU Center for Geospatial Analytics, GeoForAll Lab


⭐ SOURCE CODE ⭐

available at: v.fill.holes source code (history)

accessed: Saturday Jan 17 05:41:20 2026

main index | vector index | topics index | keywords index | graphical index | full index

Β© 2003-2025 GRASS Development Team, GRASS GIS 8.4.2 Reference Manual


and that's the whole page, bestie πŸ’– huge shoutout to GRASS 8.4.2 and to v.fill.holes(1) for being the moment. go fill some holes, you got this πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from