GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
Loading...
Searching...
No Matches
bridges.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/bridges.c
3
4 \brief Vector library - clean geometry (bridges)
5
6 Higher level functions for reading/writing/manipulating vectors.
7
8 SPDX-FileCopyrightText: 2001-2009 GRASS Development Team
9 SPDX-License-Identifier: GPL-2.0-or-later
10
11 \author Radim Blazek
12 */
13
14#include <stdlib.h>
15#include <grass/vector.h>
16#include <grass/rbtree.h>
17#include <grass/glocale.h>
18
19static int cmp_int(const void *a, const void *b)
20{
21 const int *ai = a;
22 const int *bi = b;
23
24 return (*ai < *bi ? -1 : (*ai > *bi));
25}
26
27static void remove_bridges(struct Map_info *Map, int chtype,
28 struct Map_info *Err, int *lrm, int *brm);
29
30/*!
31 \brief Remove bridges from vector map.
32
33 Remove bridges (type boundary) connecting areas to islands or 2
34 islands. Islands and areas must be already clean, i.e. without
35 dangles. Bridge may be formed by more lines. Optionally deleted
36 bridges are written to error map. Input map must be opened on
37 level 2 for update at least on level GV_BUILD_BASE
38
39 \param Map input map where bridges are deleted
40 \param Err vector map where deleted bridges are written or NULL
41 \param lines_removed number of lines removed
42 \param bridges_removed Err number of bridges removed
43 */
46{
47 remove_bridges(Map, 0, Err, lines_removed, bridges_removed);
48}
49
50/*!
51 \brief Change type of bridges in vector map.
52
53 Change the type of bridges (type boundary) connecting areas to
54 islands or 2 islands. Islands and areas must be already clean,
55 i.e. without dangles. Bridge may be formed by more lines.
56 Optionally changed bridges are written to error map. Input map
57 must be opened on level 2 for update at least on level
58 GV_BUILD_BASE.
59
60 \param Map input map where bridges are changed
61 \param Err vector map where changed bridges are written or NULL
62 \param lines_changed number of lines changed
63 \param bridges_changed Err number of bridges changed
64 */
67{
68 remove_bridges(Map, 1, Err, lines_changed, bridges_changed);
69}
70
71/*
72 Called by Vect_remove_bridges() and Vect_chtype_bridges():
73 chtype = 0 -> works like Vect_remove_bridges()
74 chtype = 1 -> works like Vect_chtype_bridges()
75
76 Algorithm: Go thorough all lines,
77 if both sides of the line have left and side 0 (candidate) do this check:
78 follow adjacent lines in one direction (nearest to the right at the end
79 node), if we reach this line again without dangle in the way, but with this
80 line traversed from other side it is a bridge.
81
82 List of all lines in chain is created during the cycle.
83 */
84void remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err,
85 int *lrm, int *brm)
86{
87 int type, nlines, line, *bline;
88 int left, right, node1, node2, current_line, next_line, abs_line;
89 int bridges_removed = 0; /* number of removed bridges */
90 int lines_removed = 0; /* number of lines removed */
91 struct Plus_head *Plus;
92 struct line_pnts *Points;
93 struct line_cats *Cats;
95 struct RB_TRAV trav;
96
97 int dangle, other_side;
98
99 Plus = &(Map->plus);
100
101 Points = Vect_new_line_struct();
103
104 CycleTree = rbtree_create(cmp_int, sizeof(int));
105 BridgeTree = rbtree_create(cmp_int, sizeof(int));
106
107 nlines = Vect_get_num_lines(Map);
108
109 G_debug(1, "nlines = %d", nlines);
110
111 for (line = 1; line <= nlines; line++) {
112 G_percent(line, nlines, 1);
113 if (!Vect_line_alive(Map, line))
114 continue;
115
116 type = Vect_read_line(Map, NULL, NULL, line);
117 if (!(type & GV_BOUNDARY))
118 continue;
119
120 Vect_get_line_areas(Map, line, &left, &right);
121
122 if (left != 0 || right != 0)
123 continue; /* Cannot be bridge */
124
125 G_debug(2, "line %d - bridge candidate", line);
126
128
129 if (abs(node1) == abs(node2))
130 continue; /* either zero length or loop -> cannot be a bridge */
131
132 current_line = -line; /* we start with negative (go forward, node2 ) */
133
134 G_debug(3, "current line: %d", line);
135 dangle = 0;
136 other_side = 0;
139
140 while (1) {
143 abs_line = abs(next_line);
144
145 /* Add this line to the list */
146 if (rbtree_find(CycleTree, (void *)&abs_line)) {
147 if (!rbtree_find(BridgeTree, (void *)&abs_line)) {
149 }
150 }
151 else {
153 }
154
155 if (abs(next_line) == abs(current_line)) {
156 G_debug(4, " dangle -> no bridge");
157 dangle = 1;
158 break;
159 }
160 if (abs(next_line) == line) { /* start line reached */
161 /* which side */
162 if (next_line < 0) { /* other side (connected by node 2) */
163 G_debug(5, " other side reached");
164 other_side = 1;
165 }
166 else { /* start side */
167 break;
168 }
169 }
170
171 current_line = -next_line; /* change the sign to look at the next
172 node in following cycle */
173 }
174
175 if (!dangle && other_side) {
176 G_debug(3, " line %d is part of bridge chain", line);
177
179 /* for (i = 0; i < BridgeList->n_values; i++) { */
180 while ((bline = rbtree_traverse(&trav))) {
181 Vect_read_line(Map, Points, Cats, *bline);
182
183 if (Err) {
185 }
186
187 if (!chtype)
189 else
191
193 }
195 }
196 }
197
202
203 if (lrm)
205 if (brm)
207
208 G_verbose_message(_("Removed lines: %d"), lines_removed);
209 G_verbose_message(_("Removed bridges: %d"), bridges_removed);
210}
void Vect_chtype_bridges(struct Map_info *Map, struct Map_info *Err, int *lines_changed, int *bridges_changed)
Change type of bridges in vector map.
Definition bridges.c:65
void Vect_remove_bridges(struct Map_info *Map, struct Map_info *Err, int *lines_removed, int *bridges_removed)
Remove bridges from vector map.
Definition bridges.c:44
#define NULL
Definition ccmath.h:32
void G_percent(long, long, int)
Print percent complete messages.
Definition percent.c:59
void void G_verbose_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
int rbtree_insert(struct RB_TREE *, void *)
Definition rbtree.c:71
int rbtree_init_trav(struct RB_TRAV *, struct RB_TREE *)
Definition rbtree.c:262
void rbtree_clear(struct RB_TREE *)
Definition rbtree.c:488
struct RB_TREE * rbtree_create(rb_compare_fn *, size_t)
Definition rbtree.c:47
void * rbtree_find(struct RB_TREE *, const void *)
Definition rbtree.c:241
void * rbtree_traverse(struct RB_TRAV *)
Definition rbtree.c:279
void rbtree_destroy(struct RB_TREE *)
Definition rbtree.c:518
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition line.c:75
off_t Vect_rewrite_line(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites existing feature (topological level required)
int Vect_get_line_nodes(struct Map_info *, int, int *, int *)
Get line nodes.
Definition level_two.c:302
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition level_two.c:73
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
int Vect_delete_line(struct Map_info *, off_t)
Delete existing feature (topological level required)
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
int Vect_get_line_areas(struct Map_info *, int, int *, int *)
Get area id on the left and right side of the boundary.
Definition level_two.c:345
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:43
#define GV_LINE
#define GV_BOUNDARY
#define GV_RIGHT
int dig_angle_next_line(struct Plus_head *, plus_t, int, int, float *)
Find line number of next angle to follow a line.
Definition plus_area.c:474
#define _(str)
Definition glocale.h:10
double b
Definition r_raster.c:37
Vector map info.
Basic topology-related info.
Feature category info.
Feature geometry info - coordinates.