GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
Loading...
Searching...
No Matches
sindex.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/sindex.c
3
4 \brief Vector library - select vector features
5
6 Higher level functions for reading/writing/manipulating vectors.
7
8 SPDX-FileCopyrightText: 2001-2011 GRASS Development Team
9 SPDX-License-Identifier: GPL-2.0-or-later
10
11 \author Radim Blazek, Markus Metz
12 */
13
14#include <stdlib.h>
15#include <grass/vector.h>
16
17/*!
18 \brief Select lines with bounding boxes by box.
19
20 Select lines whose boxes overlap specified box!!! It means that
21 selected line may or may not overlap the box.
22
23 \param Map vector map
24 \param Box bounding box
25 \param type line type
26 \param[out] list output list, must be initialized
27
28 \return number of lines
29 */
31 int type, struct boxlist *list)
32{
33 int i, line, nlines, ntypes, mtype;
34 struct Plus_head *plus;
35 struct P_line *Line;
36 static struct boxlist *LocList = NULL;
37
38 G_debug(3, "Vect_select_lines_by_box()");
39 G_debug(3, " Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
40 Box->E, Box->W, Box->T, Box->B);
41 plus = &(Map->plus);
42
44
45 ntypes = mtype = 0;
46 /* count the number of different primitives in Map */
47 if (plus->n_plines != 0) {
48 ntypes++;
49 mtype |= GV_POINT;
50 }
51 if (plus->n_llines != 0) {
52 ntypes++;
53 mtype |= GV_LINE;
54 }
55 if (plus->n_blines != 0) {
56 ntypes++;
58 }
59 if (plus->n_clines != 0) {
60 ntypes++;
62 }
63 if (plus->n_flines != 0) {
64 ntypes++;
65 mtype |= GV_FACE;
66 }
67 if (plus->n_klines != 0) {
68 ntypes++;
70 }
71
72 if (ntypes == 1) {
73 /* there is only one type in Map */
74 if (mtype & type)
75 return dig_select_lines(plus, Box, list);
76 return 0;
77 }
78
79 if (ntypes == 0)
80 /* empty vector */
81 return 0;
82
83 if (!LocList) {
84 LocList = (struct boxlist *)G_malloc(sizeof(struct boxlist));
86 }
87
88 nlines = dig_select_lines(plus, Box, LocList);
89 G_debug(3, " %d lines selected (all types)", nlines);
90
91 /* Remove lines of not requested types */
92 for (i = 0; i < nlines; i++) {
93 line = LocList->id[i];
94 if (plus->Line[line] == NULL)
95 continue; /* Should not happen */
96 Line = plus->Line[line];
97 if (!(Line->type & type))
98 continue;
99 dig_boxlist_add(list, line, &LocList->box[i]);
100 }
101
102 G_debug(3, " %d lines of requested type", list->n_values);
103
104 return list->n_values;
105}
106
107/*!
108 \brief Select areas with bounding boxes by box.
109
110 Select areas whose boxes overlap specified box!!!
111 It means that selected area may or may not overlap the box.
112
113 \param Map vector map
114 \param Box bounding box
115 \param[out] output list, must be initialized
116
117 \return number of areas
118 */
120 struct boxlist *list)
121{
122 int i;
123 static int debug_level = -1;
124
125 if (debug_level == -1) {
126 const char *dstr = G_getenv_nofatal("DEBUG");
127
128 if (dstr != NULL)
129 debug_level = atoi(dstr);
130 else
131 debug_level = 0;
132 }
133
134 G_debug(3, "Vect_select_areas_by_box()");
135 G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
136 Box->E, Box->W, Box->T, Box->B);
137
138 dig_select_areas(&(Map->plus), Box, list);
139 G_debug(3, " %d areas selected", list->n_values);
140 /* avoid loop when not debugging */
141 if (debug_level > 2) {
142 for (i = 0; i < list->n_values; i++) {
143 G_debug(3, " area = %d pointer to area structure = %p",
144 list->id[i], (void *)Map->plus.Area[list->id[i]]);
145 }
146 }
147
148 return list->n_values;
149}
150
151/*!
152 \brief Select isles with bounding boxes by box.
153
154 Select isles whose boxes overlap specified box!!!
155 It means that selected isle may or may not overlap the box.
156
157 \param Map vector map
158 \param Box bounding box
159 \param[out] list output list, must be initialized
160
161 \return number of isles
162 */
164 struct boxlist *list)
165{
166 G_debug(3, "Vect_select_isles_by_box()");
167 G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
168 Box->E, Box->W, Box->T, Box->B);
169
170 dig_select_isles(&(Map->plus), Box, list);
171 G_debug(3, " %d isles selected", list->n_values);
172
173 return list->n_values;
174}
175
176/*!
177 \brief Select nodes by box.
178
179 \param Map vector map
180 \param Box bounding box
181 \param[out] list output list, must be initialized
182
183 \return number of nodes
184 */
186 struct ilist *list)
187{
188 struct Plus_head *plus;
189
190 G_debug(3, "Vect_select_nodes_by_box()");
191 G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
192 Box->E, Box->W, Box->T, Box->B);
193
194 plus = &(Map->plus);
195
197
198 dig_select_nodes(plus, Box, list);
199 G_debug(3, " %d nodes selected", list->n_values);
200
201 return list->n_values;
202}
203
204/*!
205 \brief Select lines by Polygon with optional isles.
206
207 Polygons should be closed, i.e. first and last points must be identical.
208
209 \param Map vector map
210 \param Polygon outer ring
211 \param nisles number of islands or 0
212 \param Isles array of islands or NULL
213 \param type line type
214 \param[out] list output list, must be initialised
215
216 \return number of lines
217 */
219 struct line_pnts *Polygon, int nisles,
220 struct line_pnts **Isles, int type,
221 struct ilist *List)
222{
223 int i;
224 struct bound_box box;
225 static struct line_pnts *LPoints = NULL;
226 static struct boxlist *LocList = NULL;
227
228 /* TODO: this function was not tested with isles */
229 G_debug(3, "Vect_select_lines_by_polygon() nisles = %d", nisles);
230
232 if (!LPoints)
234 if (!LocList) {
236 }
237
238 /* Select first all lines by box */
241 box.B = -PORT_DOUBLE_MAX;
243 G_debug(3, " %d lines selected by box", LocList->n_values);
244
245 /* Check all lines if intersect the polygon */
246 for (i = 0; i < LocList->n_values; i++) {
247 int j, line, intersect = 0;
248
249 line = LocList->id[i];
250 /* Read line points */
252
253 /* Check if any of line vertices is within polygon */
254 for (j = 0; j < LPoints->n_points; j++) {
255 if (Vect_point_in_poly(LPoints->x[j], LPoints->y[j], Polygon) >=
256 1) { /* inside polygon */
257 int k, inisle = 0;
258
259 for (k = 0; k < nisles; k++) {
260 if (Vect_point_in_poly(LPoints->x[j], LPoints->y[j],
261 Isles[k]) >= 1) { /* in isle */
262 inisle = 1;
263 break;
264 }
265 }
266
267 if (!inisle) { /* inside polygon, outside isles -> select */
268 intersect = 1;
269 break;
270 }
271 }
272 }
273 if (intersect) {
274 Vect_list_append(List, line);
275 continue;
276 }
277
278 /* Check intersections of the line with area/isles boundary */
279 /* Outer boundary */
281 Vect_list_append(List, line);
282 continue;
283 }
284
285 /* Islands */
286 for (j = 0; j < nisles; j++) {
288 intersect = 1;
289 break;
290 }
291 }
292 if (intersect) {
293 Vect_list_append(List, line);
294 }
295 }
296
297 G_debug(4, " %d lines selected by polygon", List->n_values);
298
299 return List->n_values;
300}
301
302/*!
303 \brief Select areas by Polygon with optional isles.
304
305 Polygons should be closed, i.e. first and last points must be identical.
306
307 \param Map vector map
308 \param Polygon outer ring
309 \param nisles number of islands or 0
310 \param Isles array of islands or NULL
311 \param[out] list output list, must be initialised
312
313 \return number of areas
314 */
316 struct line_pnts *Polygon, int nisles,
317 struct line_pnts **Isles, struct ilist *List)
318{
319 int i, area;
320 static struct ilist *BoundList = NULL;
321
322 /* TODO: this function was not tested with isles */
323 G_debug(3, "Vect_select_areas_by_polygon() nisles = %d", nisles);
324
326 if (!BoundList)
328
329 /* Select boundaries by polygon */
331 BoundList);
332
333 /* Add areas on left/right side of selected boundaries */
334 for (i = 0; i < BoundList->n_values; i++) {
335 int line, left, right;
336
337 line = BoundList->value[i];
338
339 Vect_get_line_areas(Map, line, &left, &right);
340 G_debug(4, "boundary = %d left = %d right = %d", line, left, right);
341
342 if (left > 0) {
343 Vect_list_append(List, left);
344 }
345 else if (left < 0) { /* island */
346 area = Vect_get_isle_area(Map, abs(left));
347 G_debug(4, " left island -> area = %d", area);
348 if (area > 0)
349 Vect_list_append(List, area);
350 }
351
352 if (right > 0) {
353 Vect_list_append(List, right);
354 }
355 else if (right < 0) { /* island */
356 area = Vect_get_isle_area(Map, abs(right));
357 G_debug(4, " right island -> area = %d", area);
358 if (area > 0)
359 Vect_list_append(List, area);
360 }
361 }
362
363 /* But the Polygon may be completely inside the area (only one), in that
364 * case we find the area by one polygon point and add it to the list */
365 area = Vect_find_area(Map, Polygon->x[0], Polygon->y[0]);
366 if (area > 0)
367 Vect_list_append(List, area);
368
369 G_debug(3, " %d areas selected by polygon", List->n_values);
370
371 return List->n_values;
372}
#define NULL
Definition ccmath.h:32
const char * G_getenv_nofatal(const char *)
Get environment variable.
Definition env.c:403
#define G_malloc(n)
Definition defs/gis.h:136
int G_debug(int, const char *,...) __attribute__((format(printf
int Vect_reset_boxlist(struct boxlist *)
Reset boxlist structure.
struct boxlist * Vect_new_boxlist(int)
Creates and initializes a struct boxlist.
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_line_check_intersection(struct line_pnts *, struct line_pnts *, int)
Check if 2 lines intersect.
int Vect_point_in_poly(double, double, const struct line_pnts *)
Determines if a point (X,Y) is inside a polygon.
Definition Vlib/poly.c:977
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
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
int Vect_reset_list(struct ilist *)
Reset ilist structure.
int Vect_find_area(struct Map_info *, double, double)
Find the nearest area.
int Vect_get_isle_area(struct Map_info *, int)
Returns area id for isle.
#define GV_CENTROID
#define GV_LINE
#define GV_POINT
Feature types used in memory on run time (may change)
#define GV_BOUNDARY
#define GV_FACE
#define PORT_DOUBLE_MAX
Limits for portable types.
Definition dig_defines.h:66
#define GV_KERNEL
int dig_init_boxlist(struct boxlist *, int)
int dig_select_isles(struct Plus_head *, const struct bound_box *, struct boxlist *)
Select isles with boxes by box.
Definition spindex.c:969
int dig_select_lines(struct Plus_head *, const struct bound_box *, struct boxlist *)
Select lines with boxes by box.
Definition spindex.c:757
int dig_select_areas(struct Plus_head *, const struct bound_box *, struct boxlist *)
Select areas with boxes by box.
Definition spindex.c:873
int dig_boxlist_add(struct boxlist *, int, const struct bound_box *)
int dig_select_nodes(struct Plus_head *, const struct bound_box *, struct ilist *)
Select nodes by bbox.
Definition spindex.c:666
int dig_line_box(const struct line_pnts *, struct bound_box *)
float Box[8][3]
Vertices for box.
Definition gsd_objs.c:1451
int Vect_select_lines_by_box(struct Map_info *Map, const struct bound_box *Box, int type, struct boxlist *list)
Select lines with bounding boxes by box.
Definition sindex.c:30
int Vect_select_areas_by_box(struct Map_info *Map, const struct bound_box *Box, struct boxlist *list)
Select areas with bounding boxes by box.
Definition sindex.c:119
int Vect_select_lines_by_polygon(struct Map_info *Map, struct line_pnts *Polygon, int nisles, struct line_pnts **Isles, int type, struct ilist *List)
Select lines by Polygon with optional isles.
Definition sindex.c:218
int Vect_select_areas_by_polygon(struct Map_info *Map, struct line_pnts *Polygon, int nisles, struct line_pnts **Isles, struct ilist *List)
Select areas by Polygon with optional isles.
Definition sindex.c:315
int Vect_select_nodes_by_box(struct Map_info *Map, const struct bound_box *Box, struct ilist *list)
Select nodes by box.
Definition sindex.c:185
int Vect_select_isles_by_box(struct Map_info *Map, const struct bound_box *Box, struct boxlist *list)
Select isles with bounding boxes by box.
Definition sindex.c:163
Vector map info.
Vector geometry.
char type
Line type.
Basic topology-related info.
plus_t n_klines
Current number of kernels.
struct P_line ** Line
Array of vector geometries.
plus_t n_plines
Current number of points.
plus_t n_blines
Current number of boundaries.
plus_t n_clines
Current number of centroids.
plus_t n_flines
Current number of faces.
plus_t n_llines
Current number of lines.
Bounding box.
Definition dig_structs.h:62
List of bounding boxes with id.
struct bound_box * box
Array of bounding boxes.
List of integers.
Definition gis.h:712
Feature geometry info - coordinates.
Definition manage.h:4