v.clean(1grass)

πŸ’– v.clean πŸ’–

okay so bestie, we are reading the v.clean page out of the GRASS User's Manual, and honestly? it's the glow-up your crusty, tangled vector map has been praying for 🫢✨


🌸 NAME 🌸

v.clean β€” Toolset for cleaning topology of vector map.

✨ KEYWORDS ✨

vector, topology, geometry, snapping

πŸ‘‘ SYNOPSIS πŸ‘‘

v.clean
v.clean --help
v.clean [-bc] input=name  [layer=string]   [type=string[,string,...]]
output=name  [error=name]  tool=string[,string,...]
[threshold=float[,float,...]]   [--overwrite]  [--help]  [--verbose]
[--quiet]  [--ui]

πŸŽ€ Flags πŸŽ€

  • -b β€” do not build topology for the output vector, bestie. we're skipping that step πŸ’…
  • -c β€” combine tools with their recommended follow-up tools (the module does the chaining for you, iconic)
  • --overwrite β€” let the output files just bulldoze existing files and take their place
  • --help β€” print the usage summary
  • --verbose β€” verbose module output, i.e. it tells you everything
  • --quiet β€” quiet module output, i.e. it tells you nothing
  • --ui β€” force launching the GUI dialog

πŸ¦‹ Parameters πŸ¦‹

  • input=name [required] β€” Name of input vector map. Or data source for direct OGR access.
  • layer=string β€” Layer number or name ('-1' for all layers). A single vector map can be connected to multiple database tables, and this number determines which table to use. When used with direct OGR access, this is the layer name. Default: -1
  • type=string[,string,...] β€” Input feature type. Options: point, line, boundary, centroid, area, face, kernel. Default: point,line,boundary,centroid,area,face,kernel
  • output=name [required] β€” Name for output vector map.
  • error=name β€” Name of output map where errors are written.
  • tool=string[,string,...] [required] β€” Cleaning tool. Options:
    • break β€” break lines at each intersection
    • snap β€” snap lines to vertex in threshold
    • rmdangle β€” remove dangles, threshold ignored if < 0
    • chdangle β€” change the type of boundary dangle to line, threshold ignored if < 0, input line type is ignored
    • rmbridge β€” remove bridges connecting area and island or 2 islands
    • chbridge β€” change the type of bridges connecting area and island or 2 islands from boundary to line
    • rmdupl β€” remove duplicate geometry features (pay attention to categories!)
    • rmdac β€” remove duplicate area centroids (type option ignored)
    • bpol β€” break (topologically clean) polygons (imported from non topological format, like ShapeFile). Boundaries are broken on each point shared between 2 and more polygons where angles of segments are different
    • prune β€” remove vertices in threshold from lines and boundaries, boundary is pruned only if topology is not damaged (new intersection, changed attachment of centroid), first and last segment of the boundary is never changed
    • rmarea β€” remove small areas, the longest boundary with adjacent area is removed
    • rmline β€” remove all lines or boundaries of zero length, threshold is ignored
    • rmsa β€” remove small angles between lines at nodes
  • threshold=float[,float,...] β€” One value for each tool; for threshold units, see each tool. Default: 0.0[,0.0,...]

πŸ’œ DESCRIPTION πŸ’œ

So v.clean lets you automatically fix the topology of vector maps, no manual untangling required 🧚 You can list several tools and they'll run sequentially, one after the other β€” and when you do that, the threshold parameter also needs several values listed accordingly, one per tool. An error map is optionally written too, and it stores the erroneous geometries so you can go stare at what went wrong πŸ™ˆ

🧡 Break lines/boundaries

tool=break

The break tool breaks lines/boundaries at intersections, and it also breaks lines/boundaries that form a collapsed loop. For example, 0.0;1.0;0.0 gets broken at 1.0.

Threshold does not apply (it is ignored), so use an arbitrary value (e.g., 0) if v.clean is run with several tools.

✨ Hint, bestie: breaking lines should be followed by removing duplicates, e.g. v.clean ... tool=break,rmdupl. And if the -c flag is used with v.clean ... tool=break, the duplicates are automatically removed for you. no thoughts, just -c. πŸ’…

🫧 Remove duplicate geometry features

tool=rmdupl

The rmdupl tool removes geometry features with identical coordinates. Categories are merged. If a point and a centroid have identical coordinates, one of them will be removed if both points and centroids are selected with v.clean ... type=point,centroid. The same applies for lines and boundaries.

Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0) if v.clean is run with several tools.

The rmdupl tool should be used after breaking lines and breaking polygons.

πŸ“ Remove dangles or change boundary dangles to type line

tool=rmdangle and tool=chdangle

A line/boundary counts as a dangle if no other line of the given type is on at least one end node. If a dangle is formed by several lines, that whole string of lines is taken as one dangle and the line lengths are summarized. The rmdangle tool deletes a dangle if the (combined) length is shorter than thresh, or if thresh < 0. And if the combined length is larger than thresh, nothing gets deleted. sorry bestie, rules are rules.

Threshold has to be given as maximum line/boundary length in map units; for latitude-longitude projects it's in degrees. Dangles shorter than thresh are removed sequentially. All dangles will be removed if thresh < 0.

With thresh < 0, only closed loops and lines connecting loops will remain. This is useful to remove all incorrect boundaries after other cleaning operations with thres < 0. Areas can then be successfully built. πŸŽ‰

To preferentially remove shortest dangles first, a first pass with a small thresh value can be followed by subsequent passes with higher thresh values. And you can do that as one single v.clean job β€” just list the tool several times and define a list of increasing thresh values. multi-tasking queen πŸ‘‘

The chdangle tool is similar to the rmdangle tool, but it works only on boundaries and changes dangling boundaries to lines instead of removing them.

🌈 Remove or change bridges connecting an area and an island or two islands

tool=rmbridge and tool=chbridge

A bridge is an area type connection of an island (polygon in a polygon) to the outer polygon. This is topologically incorrect (but OGC Simple Features allow it, smh). The rmbridge tool removes bridges and the chbridge tool changes bridges to type line:

    +-------------+             +-------------+   +-------------+
    |            P|  P: polygon |            P|   |            P|
    |    +---+    |  I: island  |    +---+    |   |    +---+    |
    |    | I |    |  B: bridge  |    | I |    |   |    | I |    |
    |    |   |    |  L: line    |    |   |    |   |    |   |    |
    |    +-+-+    |             |    +---+    |   |    +-.-+    |
    |      |      |             |             |   |      .      |
    |      | B    |             |             |   |      . L    |
    |      |      |             |             |   |      .      |
    +------+------+             +-------------+   +-------------+

Islands and areas must be already clean, i.e. without dangles or small angles, e.g. v.clean ... type=boundary tool=rmdangle,rmsa,break,rmdupl,rmbridge thresh=-1,0,0,0,0.

Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0) if v.clean is run with several tools.

πŸŽ€ Snap lines to vertex in threshold

tool=snap

The snap tool snaps vertices to another vertex not farther away than thresh. If there is no other vertex within thresh, no snapping will be done. The type option can have a strong influence on the result. And listen β€” a too large threshold combined with type=boundary can severely damage area topology, beyond repair. not a vibe, be careful 😭

Threshold gives maximum distance to another vertex in map units, for latitude-longitude projects in degrees.

Snapped boundaries may need to be cleaned with break,rmdupl,rmsa. If the -c flag is used with v.clean tool=snap, the sequence of break,rmdupl,rmsa is automatically repeated after snapping until no more small angles are left. Additional cleaning with e.g. tool=rmdangle may be necessary.

πŸ’€ Remove duplicate area centroids

tool=rmdac

The rmdac tool removes duplicate area centroids that can result from deleting boundaries.

Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0) if v.clean is run with several tools.

🌟 Break (topologically clean) areas (imported from a non topological format like ShapeFile)

tool=bpol

The bpol tool breaks boundaries on each point shared between 2 and more areas where angles of boundary segments are different, and on all boundary nodes (start and end points of each boundary). The bpol tool behaves similar to break for boundaries, but it does not break collapsed loops. Also it's faster than the break tool, but it needs more memory. tradeoffs, bestie πŸ’…

Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0) if v.clean is run with several tools.

The bpol tool should be followed by rmdupl. If the -c flag is used with v.clean ... tool=bpol, duplicates are automatically removed.

πŸ¦‹ Remove vertices in threshold from lines and boundaries

tool=prune

The prune tool simplifies lines and boundaries by removing vertices according to threshold. This tool preserves area topology β€” areas are never deleted and centroid attachment is never changed. v.generalize offers much more functionality for line simplification, but it does not preserve area topology. pick your fighter.

🧚 Remove small areas

tool=rmarea

The rmarea tool removes all areas <= thresh. The longest boundary with an adjacent area is removed, or all boundaries if there is no adjacent area. Area categories are not combined when a small area is merged with a larger area.

🌸 Heads up: Threshold must always be in square meters, also for latitude-longitude projects or projects with units other than meters. always. square meters. periodt.

πŸ‘‘ Remove all lines or boundaries of zero length

tool=rmline

The rmline tool removes all lines or boundaries of zero length that may have resulted from other cleaning operations. Zero length boundaries are redundant and do not influence area topology. gone. deleted. iconic.

Threshold does not apply (it is ignored), use an arbitrary value (e.g., 0) if v.clean is run with several tools.

🫢 Remove small angles between lines at nodes

tool=rmsa

The rmsa tool only concerns angles which are so small that the calculated angle is 0. The following figure should help demonstrate what the tool does.

Threshold does not apply, use dummy value if v.clean is run with several tools.

tool=rmsa

The rmsa tool should be followed by break,rmdupl. And the rmsa tool followed by break,rmdupl may need to be run more than once to remove all small angles. If the -c flag is used with v.clean ... tool=rmsa, the sequence of rmsa,break,rmdupl is automatically repeated until no more small angles are left. the module just keeps going until it's clean, we love a determined queen ✨


πŸ’… NOTES πŸ’…

Good news: you do not have to run v.build on the output vector, unless the -b flag was used. And heads up, the -b flag affects only the output vector β€” topology is always built for the error vector.


✨ EXAMPLES ✨

Okay bestie, this is the part where it all comes together 🫢 real commands, real maps, real slay.


πŸŽ€ Snap lines to vertex in threshold πŸŽ€

Classic snap moment. One tool, one threshold, done:

v.clean input=testmap output=cleanmap tool=snap threshold=1

πŸ” Inspecting the topological errors visually πŸ”

Not one but two icons can scoop up the topological errors into a vector map β€” v.build and v.clean both eat that:

v.build -e map=imported error=build_errors
v.clean -c input=imported output=clean error=cleaning_errors tool=snap,rmdangle,rmbridge,chbridge,bpol,prune threshold=5

Then you can vibe check those vector maps right alongside the original data using this little display command set πŸ’…:

d.vect map=imported color=26:26:26 fill_color=77:77:77 width=5
d.vect map=build_errors color=255:33:36 fill_color=none width=5 icon=basic/point size=30
d.vect map=cleaning_errors color=255:33:36 fill_color=none width=5 icon=basic/point size=30

Figure: Topological errors detected in the original data (left) and cleaned data (right). side-by-side glow-up, honestly ✨


🌸 Cleaning OGR imported data (Simple Feature data) such as SHAPE file 🌸

So when you import areas with v.in.ogr -c (that's the no cleaning mode, bestie, zero scrubbing), you lowkey need to run v.clean after to get the map into a topologically valid structure β€” we're talking removal of duplicate collinear lines and all that chaos. The tools you want for this glow-up are bpol and rmdupl:

v.clean input=areamap output=areamap_clean tool=bpol,rmdupl type=boundary

🌈 Extracting intersection points of vector lines 🌈

Want the crossing points? We get the crossing points. Intersection points are written to the 'points' map:

v.clean input=lines1 output=lines2 err=points tool=break type=line

⭐ Break lines ⭐

v.clean will break the lines wherever they cross, and it creates a new node if one is needed. Iconic behaviour honestly. Example:

v.in.ascii -n out=crossed_lines format=standard << EOF
L 2
 0 5
 10 5
L 2
 5 0
 5 10
EOF
v.clean in=crossed_lines out=crossed_lines_brk \
        error=intersection tool=break type=line

πŸ’€ Remove all lines of zero length πŸ’€

Look at this lil zero-length line just existing for no reason 😭 watch:

v.out.ascii zero format=standard
L  2 1
 -819832.09065589 -987825.2187231
 -806227.28362601 -971104.80702988
 1     1
L  2 1
 -799165.24638913 -972974.16982788
 -799165.24638913 -972974.16982788
 1     2
v.clean input=zero output=zero_clean tool=rmline type=line
v.out.ascii zero_clean format=standard
L  2 1
 -819832.09065589 -987825.2187231
 -806227.28362601 -971104.80702988
 1     1

Hmm notice anything? πŸ‘€ v.clean type=boundary would remove nothing. That line is staying, bestie. Type matters.


πŸ”₯ Repeatedly remove dangling lines up to 50m length πŸ”₯

Yes you can absolutely stack the same tool multiple times with escalating thresholds β€” it's giving layers:

v.clean input=testmap output=cleanmap type=line \
        tool=rmdangle,rmdangle,rmdangle,rmdangle threshold=5,10,20,50

πŸ¦‹ SEE ALSO πŸ¦‹

v.info, v.build, g.gui.vdigit, v.edit, v.fill.holes, v.generalize

(go read those next, they're the rest of the friend group fr fr πŸ’œ)


πŸ‘‘ AUTHORS πŸ‘‘

  • David Gerdes, U.S. Army Construction Engineering Research Laboratory
  • Radim Blazek, ITC-irst, Trento, Italy
  • Martin Landa, FBK-irst (formerly ITC-irst), Trento, Italy

🌟 SOURCE CODE 🌟

Available at: v.clean source code (history)

Latest change: Friday Apr 17 01:04:26 2026 in commit: 32a143358df26b2e518b03c7e0d79541e8d1e5b1

Main index | Vector index | Topics index | Keywords index | Graphical index | Full index

Β© 2003-2026 GRASS Development Team, GRASS 8.5.0 Reference Manual


okay that's the whole page bestie, you're officially a v.clean expert now πŸ’…βœ¨ this was brought to you by the GRASS 8.5.0 reference manual, latest touch on Friday Apr 17 01:04:26 2026 β€” go clean some topology, you got this πŸ«ΆπŸŽ€
πŸ“¦ where this page comes from