GRASS 8 Programmer's Manual 8.6.0dev(2026)-f6f2c534ea
Loading...
Searching...
No Matches
vector/vedit/select.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/vedit/select.c
3
4 \brief Vedit library - select primitives by query
5
6 (C) 2007-2008 by the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10
11 \author Martin Landa <landa.martin gmail.com>
12 */
13
14#include <math.h>
15#include <grass/glocale.h>
16#include <grass/vedit.h>
17
18static int select_by_query(struct Map_info *, int, int, double, int,
19 struct line_pnts *, struct line_cats *);
20
21static int merge_lists(struct ilist *alist, struct ilist *blist);
22
23/*!
24 \brief Select primitives by query (based on geometry properties)
25
26 Currently supported:
27 - QUERY_LENGTH, select all lines longer than threshold (or shorter if
28 threshold is < 0)
29 - QUERY_DANGLE, select all dangles longer than threshold (or shorter if
30 threshold is < 0)
31
32 Perform global query if <i>List</i> is empty otherwise query only
33 selected vector objects.
34
35 \param Map pointer to Map_info
36 \param type feature type
37 \param layer layer number (unused)
38 \param thresh threshold value (< 0 for 'shorter', > 0 for 'longer')
39 \param query query (length, dangle, ...)
40 \param[in,out] List list of selected features
41
42 \return number of selected primitives
43 */
44int Vedit_select_by_query(struct Map_info *Map, int type, int layer UNUSED,
45 double thresh, int query, struct ilist *List)
46{
47 int num, line, i;
48 double thresh_tmp;
49 struct line_pnts *Points;
50 struct line_cats *Cats;
51 struct ilist *List_query;
52
53 Points = Vect_new_line_struct();
55
56 if (List->n_values == 0) {
58 }
59 else {
61 }
62
63 switch (query) {
64 case QUERY_LENGTH: {
65 if (List->n_values == 0) {
66 /* query all vector objects in vector map */
68 for (line = 1; line <= num; line++) {
69 if (select_by_query(Map, line, type, thresh, query, Points,
70 Cats))
72 }
73 }
74 else {
75 for (i = 0; i < List->n_values; i++) {
76 line = List->value[i];
77 if (select_by_query(Map, line, type, thresh, query, Points,
78 Cats)) {
80 }
81 }
82 }
83 break;
84 }
85 case QUERY_DANGLE: {
86 struct ilist *List_dangle;
87
90
91 /* select dangles shorter than 'thresh_tmp' */
93
94 if (thresh <= 0.0) { /* shorter than */
95 for (i = 0; i < List_dangle->n_values; i++) {
97 }
98 }
99 else { /* longer than */
100 for (i = 1; i <= Vect_get_num_lines(Map); i++) {
103 }
104 }
105
107 break;
108 }
109 default:
110 break;
111 }
112
113 if (List != List_query) {
114 merge_lists(List, List_query);
116 }
117
118 G_debug(3, "Vedit_select_by_query(): %d lines selected (by query %d)",
119 List->n_values, query);
120
123
124 return List->n_values;
125}
126
127/*!
128 \brief Query selected primitive
129
130 \return 1 line test positive
131 \return 0 line test negative
132 \return -1 on error (line is dead)
133 */
134int select_by_query(struct Map_info *Map, int line, int type, double thresh,
135 int query, struct line_pnts *Points, struct line_cats *Cats)
136{
137 int ltype;
138 double length;
139 int i, cat_curr;
140 int node1, node2, node; /* nodes */
141 int nnode1, nnode2; /* number of line in node */
142 double nx, ny, nz; /* node coordinates */
143 struct ilist *exclude, *found; /* line id of nearest lines */
144 struct line_cats *Cats_curr;
145
146 if (!Vect_line_alive(Map, line))
147 return -1;
148
149 ltype = Vect_read_line(Map, Points, Cats, line);
150
151 if (!(ltype & type))
152 return -1;
153
154 if (query == QUERY_LENGTH) {
155 length = Vect_line_length(Points);
156 if (thresh <= 0.0) { /* shorter then */
157 if (length <= fabs(thresh))
158 return 1;
159 }
160 else { /* longer then */
161 if (length > thresh)
162 return 1;
163 }
164 }
165 else if (query == QUERY_DANGLE) {
166 /*
167 this code is currently replaced by Vect_select_dangle()
168 not used by v.edit
169 */
170 int layer, cat;
171
172 layer = 1;
173 Vect_cat_get(Cats, layer, &cat); /* get first category from layer */
174 if (!(type & GV_LINES))
175 return -1;
176 /* check if line is dangle */
177
179
180 node = -1;
183
184 if ((nnode1 == 4 && nnode2 == 1) || (nnode1 == 1 && nnode2 == 4)) {
185 if (nnode1 == 4)
186 node = node1;
187 else
188 node = node2;
189 }
190
191 /* no dangle ? */
192 if (node == -1)
193 return -1;
194
195 length = Vect_line_length(Points);
196 if (thresh <= 0.0) { /* shorter then */
197 if (length > fabs(thresh))
198 return -1;
199 }
200 else { /* longer then */
201 if (length <= thresh)
202 return -1;
203 }
204
205 /* at least one of the lines need to have same category number */
208
209 Vect_get_node_coor(Map, node, &nx, &ny, &nz);
210
213 found);
214
216
217 for (i = 0; i < found->n_values; i++) {
218 Vect_read_line(Map, NULL, Cats_curr, found->value[i]);
219 if (Vect_cat_get(Cats_curr, layer, &cat_curr) > -1) {
220 if (cat == cat_curr)
221 return 1;
222 }
223 }
224
228 }
229 else {
230 /* this shouldn't happen */
231 G_fatal_error("Vedit_select_by_query(): %s", _("Unknown query tool"));
232 }
233
234 return 0;
235}
236
237/*!
238 \brief Merge two lists, i.e. store only duplicate items
239
240 \param[in,out] alist list to be merged
241 \param blist list used for merging
242
243 \return result number of items
244 */
245int merge_lists(struct ilist *alist, struct ilist *blist)
246{
247 int i;
248
249 struct ilist *list_del;
250
252
253 for (i = 0; i < alist->n_values; i++) {
254 if (!Vect_val_in_list(blist, alist->value[i]))
255 Vect_list_append(list_del, alist->value[i]);
256 }
257
259
261
262 return alist->n_values;
263}
#define NULL
Definition ccmath.h:32
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition line.c:77
int Vect_get_line_nodes(struct Map_info *, int, int *, int *)
Get line nodes.
Definition level_two.c:304
int Vect_get_node_coor(struct Map_info *, int, double *, double *, double *)
Get node coordinates.
Definition level_two.c:274
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition level_two.c:75
double Vect_line_length(const struct line_pnts *)
Calculate line length, 3D-length in case of 3D vector line.
Definition line.c:575
void Vect_select_dangles(struct Map_info *, int, double, struct ilist *)
Select dangles from vector map.
Definition dangles.c:98
int Vect_cat_get(const struct line_cats *, int, int *)
Get first found category of given field.
int Vect_find_line_list(struct Map_info *, double, double, double, int, double, int, const struct ilist *, struct ilist *)
Find the nearest line(s).
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
int Vect_list_delete_list(struct ilist *, const struct ilist *)
Delete list from existing list.
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
int Vect_val_in_list(const struct ilist *, int)
Find a given item in the list.
int Vect_get_node_n_lines(struct Map_info *, int)
Get number of lines for node.
Definition level_two.c:381
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:45
#define GV_LINES
#define WITHOUT_Z
2D/3D vector data
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:46
#define _(str)
Definition glocale.h:10
Vector map info.
List of integers.
Definition gis.h:715
Feature category info.
int * cat
Array of categories.
Feature geometry info - coordinates.
int Vedit_select_by_query(struct Map_info *Map, int type, int layer, double thresh, int query, struct ilist *List)
Select primitives by query (based on geometry properties)
#define QUERY_LENGTH
Definition vedit.h:12
#define QUERY_DANGLE
Definition vedit.h:13