GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
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 SPDX-FileCopyrightText: 2007-2008 GRASS Development Team
7 SPDX-License-Identifier: GPL-2.0-or-later
8
9 \author Martin Landa <landa.martin gmail.com>
10 */
11
12#include <math.h>
13#include <grass/glocale.h>
14#include <grass/vedit.h>
15
16static int select_by_query(struct Map_info *, int, int, double, int,
17 struct line_pnts *, struct line_cats *);
18
19static int merge_lists(struct ilist *alist, struct ilist *blist);
20
21/*!
22 \brief Select primitives by query (based on geometry properties)
23
24 Currently supported:
25 - QUERY_LENGTH, select all lines longer than threshold (or shorter if
26 threshold is < 0)
27 - QUERY_DANGLE, select all dangles longer than threshold (or shorter if
28 threshold is < 0)
29
30 Perform global query if <i>List</i> is empty otherwise query only
31 selected vector objects.
32
33 \param Map pointer to Map_info
34 \param type feature type
35 \param layer layer number (unused)
36 \param thresh threshold value (< 0 for 'shorter', > 0 for 'longer')
37 \param query query (length, dangle, ...)
38 \param[in,out] List list of selected features
39
40 \return number of selected primitives
41 */
42int Vedit_select_by_query(struct Map_info *Map, int type, int layer G_UNUSED,
43 double thresh, int query, struct ilist *List)
44{
45 int num, line, i;
46 double thresh_tmp;
47 struct line_pnts *Points;
48 struct line_cats *Cats;
49 struct ilist *List_query;
50
51 Points = Vect_new_line_struct();
53
54 if (List->n_values == 0) {
56 }
57 else {
59 }
60
61 switch (query) {
62 case QUERY_LENGTH: {
63 if (List->n_values == 0) {
64 /* query all vector objects in vector map */
66 for (line = 1; line <= num; line++) {
67 if (select_by_query(Map, line, type, thresh, query, Points,
68 Cats))
70 }
71 }
72 else {
73 for (i = 0; i < List->n_values; i++) {
74 line = List->value[i];
75 if (select_by_query(Map, line, type, thresh, query, Points,
76 Cats)) {
78 }
79 }
80 }
81 break;
82 }
83 case QUERY_DANGLE: {
84 struct ilist *List_dangle;
85
88
89 /* select dangles shorter than 'thresh_tmp' */
91
92 if (thresh <= 0.0) { /* shorter than */
93 for (i = 0; i < List_dangle->n_values; i++) {
95 }
96 }
97 else { /* longer than */
98 for (i = 1; i <= Vect_get_num_lines(Map); i++) {
101 }
102 }
103
105 break;
106 }
107 default:
108 break;
109 }
110
111 if (List != List_query) {
112 merge_lists(List, List_query);
114 }
115
116 G_debug(3, "Vedit_select_by_query(): %d lines selected (by query %d)",
117 List->n_values, query);
118
121
122 return List->n_values;
123}
124
125/*!
126 \brief Query selected primitive
127
128 \return 1 line test positive
129 \return 0 line test negative
130 \return -1 on error (line is dead)
131 */
132int select_by_query(struct Map_info *Map, int line, int type, double thresh,
133 int query, struct line_pnts *Points, struct line_cats *Cats)
134{
135 int ltype;
136 double length;
137 int i, cat_curr;
138 int node1, node2, node; /* nodes */
139 int nnode1, nnode2; /* number of line in node */
140 double nx, ny, nz; /* node coordinates */
141 struct ilist *exclude, *found; /* line id of nearest lines */
142 struct line_cats *Cats_curr;
143
144 if (!Vect_line_alive(Map, line))
145 return -1;
146
147 ltype = Vect_read_line(Map, Points, Cats, line);
148
149 if (!(ltype & type))
150 return -1;
151
152 if (query == QUERY_LENGTH) {
153 length = Vect_line_length(Points);
154 if (thresh <= 0.0) { /* shorter then */
155 if (length <= fabs(thresh))
156 return 1;
157 }
158 else { /* longer then */
159 if (length > thresh)
160 return 1;
161 }
162 }
163 else if (query == QUERY_DANGLE) {
164 /*
165 this code is currently replaced by Vect_select_dangle()
166 not used by v.edit
167 */
168 int layer, cat;
169
170 layer = 1;
171 Vect_cat_get(Cats, layer, &cat); /* get first category from layer */
172 if (!(type & GV_LINES))
173 return -1;
174 /* check if line is dangle */
175
177
178 node = -1;
181
182 if ((nnode1 == 4 && nnode2 == 1) || (nnode1 == 1 && nnode2 == 4)) {
183 if (nnode1 == 4)
184 node = node1;
185 else
186 node = node2;
187 }
188
189 /* no dangle ? */
190 if (node == -1)
191 return -1;
192
193 length = Vect_line_length(Points);
194 if (thresh <= 0.0) { /* shorter then */
195 if (length > fabs(thresh))
196 return -1;
197 }
198 else { /* longer then */
199 if (length <= thresh)
200 return -1;
201 }
202
203 /* at least one of the lines need to have same category number */
206
207 Vect_get_node_coor(Map, node, &nx, &ny, &nz);
208
211 found);
212
214
215 for (i = 0; i < found->n_values; i++) {
216 Vect_read_line(Map, NULL, Cats_curr, found->value[i]);
217 if (Vect_cat_get(Cats_curr, layer, &cat_curr) > -1) {
218 if (cat == cat_curr)
219 return 1;
220 }
221 }
222
226 }
227 else {
228 /* this shouldn't happen */
229 G_fatal_error("Vedit_select_by_query(): %s", _("Unknown query tool"));
230 }
231
232 return 0;
233}
234
235/*!
236 \brief Merge two lists, i.e. store only duplicate items
237
238 \param[in,out] alist list to be merged
239 \param blist list used for merging
240
241 \return result number of items
242 */
243int merge_lists(struct ilist *alist, struct ilist *blist)
244{
245 int i;
246
247 struct ilist *list_del;
248
250
251 for (i = 0; i < alist->n_values; i++) {
252 if (!Vect_val_in_list(blist, alist->value[i]))
253 Vect_list_append(list_del, alist->value[i]);
254 }
255
257
259
260 return alist->n_values;
261}
#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:75
int Vect_get_line_nodes(struct Map_info *, int, int *, int *)
Get line nodes.
Definition level_two.c:302
int Vect_get_node_coor(struct Map_info *, int, double *, double *, double *)
Get node coordinates.
Definition level_two.c:272
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
double Vect_line_length(const struct line_pnts *)
Calculate line length, 3D-length in case of 3D vector line.
Definition line.c:573
void Vect_select_dangles(struct Map_info *, int, double, struct ilist *)
Select dangles from vector map.
Definition dangles.c:96
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:379
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:43
#define GV_LINES
#define WITHOUT_Z
2D/3D vector data
#define G_UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:43
#define _(str)
Definition glocale.h:10
Vector map info.
List of integers.
Definition gis.h:712
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