GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-7413740dd8
level_two.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/level_two.c
3 
4  \brief Vector library - topology level functions
5 
6  (C) 2001-2009, 2011-2012 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 Original author CERL, probably Dave Gerdes or Mike Higgins.
12  \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
13  \author Update to GRASS 7 by Martin Landa <landa.martin gmail.com>
14  */
15 
16 #include <stdlib.h>
17 #include <grass/vector.h>
18 #include <grass/glocale.h>
19 
20 static void check_level(struct Map_info *Map)
21 {
22  if (Map->level < 2)
23  G_fatal_error(_("Vector map <%s> is not open at topological level"),
24  Vect_get_full_name(Map));
25 }
26 
27 /*!
28  \brief Get number of nodes in vector map
29 
30  \param Map pointer to Map_info struct
31 
32  \return number of nodes
33  */
35 {
36  return (Map->plus.n_nodes);
37 }
38 
39 /*!
40  \brief Get number of primitives in vector map
41 
42  \param Map pointer to Map_info struct
43  \param type feature type
44 
45  \return number of primitives
46  */
47 plus_t Vect_get_num_primitives(struct Map_info *Map, int type)
48 {
49  plus_t num = 0;
50 
51  if (type & GV_POINT)
52  num += Map->plus.n_plines;
53  if (type & GV_LINE)
54  num += Map->plus.n_llines;
55  if (type & GV_BOUNDARY)
56  num += Map->plus.n_blines;
57  if (type & GV_CENTROID)
58  num += Map->plus.n_clines;
59  if (type & GV_FACE)
60  num += Map->plus.n_flines;
61  if (type & GV_KERNEL)
62  num += Map->plus.n_klines;
63 
64  return num;
65 }
66 
67 /*!
68  \brief Fetch number of features (points, lines, boundaries, centroids) in
69  vector map
70 
71  \param Map pointer to Map_info struct
72 
73  \return number of features
74  */
76 {
77  return (Map->plus.n_lines);
78 }
79 
80 /*!
81  \brief Get number of areas in vector map
82 
83  \param Map pointer to Map_info struct
84 
85  \return number of areas
86  */
88 {
89  return (Map->plus.n_areas);
90 }
91 
92 /*!
93  \brief Fetch number of kernels in vector map
94 
95  \param Map pointer to Map_info struct
96 
97  \return number of kernels
98  */
100 {
101  return (Map->plus.n_klines);
102 }
103 
104 /*!
105  \brief Get number of faces in vector map
106 
107  \param Map pointer to Map_info struct
108 
109  \return number of faces
110  */
112 {
113  return (Map->plus.n_flines);
114 }
115 
116 /*!
117  \brief Fetch number of volumes in vector map
118 
119  \param Map pointer to Map_info struct
120 
121  \return number of volumes
122  */
124 {
125  return (Map->plus.n_volumes);
126 }
127 
128 /*!
129  \brief Get number of islands in vector map
130 
131  \param Map pointer to Map_info struct
132 
133  \return number of islands
134  */
136 {
137  return (Map->plus.n_isles);
138 }
139 
140 /*!
141  \brief Fetch number of holes in vector map
142 
143  \param Map pointer to Map_info struct
144 
145  \return number of holes
146  */
148 {
149  return (Map->plus.n_holes);
150 }
151 
152 /*!
153  \brief Get number of defined dblinks
154 
155  \param Map pointer to Map_info struct
156 
157  \return number of dblinks
158  */
160 {
161  /* available on level 1 ? */
162  return (Map->dblnk->n_fields);
163 }
164 
165 /*!
166  \brief Get number of updated features
167 
168  Note: Vect_set_updated() must be called to maintain list of updated
169  features
170 
171  \param Map pointer to Map_info struct
172 
173  \return number of updated features
174  */
176 {
177  return (Map->plus.uplist.n_uplines);
178 }
179 
180 /*!
181  \brief Get updated line by index
182 
183  Note: Vect_set_updated() must be called to maintain list of updated
184  features
185 
186  \param Map pointer to Map_info struct
187  \param idx index
188 
189  \return updated line
190  */
191 int Vect_get_updated_line(struct Map_info *Map, int idx)
192 {
193  return (Map->plus.uplist.uplines[idx]);
194 }
195 
196 /*!
197  \brief Get updated line offset by index
198 
199  Note: Vect_set_updated() must be called to maintain list of updated
200  features
201 
202  \param Map pointer to Map_info struct
203  \param idx index
204 
205  \return updated line
206  */
207 off_t Vect_get_updated_line_offset(struct Map_info *Map, int idx)
208 {
209  return (Map->plus.uplist.uplines_offset[idx]);
210 }
211 
212 /*!
213  \brief Get number of updated nodes
214 
215  \param Map pointer to Map_info struct
216 
217  \return number of updated nodes
218  */
220 {
221  return (Map->plus.uplist.n_upnodes);
222 }
223 
224 /*!
225  \brief Get updated (modified) node by index
226 
227  Note: Vect_set_updated() must be called to maintain list of updated
228  features
229 
230  Negative id:
231  - if Node[id] is not NULL then the node was added
232  - if Node[id] is NULL then the node was deleted
233  Positive id:
234  - node was updated
235 
236  \param Map pointer to Map_info struct
237  \param idx index
238 
239  \return id of modified node
240  */
241 int Vect_get_updated_node(struct Map_info *Map, int idx)
242 {
243  return (Map->plus.uplist.upnodes[idx]);
244 }
245 
246 /*!
247  \brief Get line type
248 
249  \param Map pointer to Map_info struct
250  \param line line id
251 
252  \return line type
253  */
254 int Vect_get_line_type(struct Map_info *Map, int line)
255 {
256  check_level(Map);
257 
258  if (!Vect_line_alive(Map, line))
259  return 0;
260 
261  return (Map->plus.Line[line]->type);
262 }
263 
264 /*!
265  \brief Get node coordinates
266 
267  \param Map pointer to Map_info struct
268  \param num node id (starts at 1)
269  \param[out] x,y,z coordinates values (for 2D coordinates z is NULL)
270 
271  \return 0 on success
272  \return -1 on error
273  */
274 int Vect_get_node_coor(struct Map_info *Map, int num, double *x, double *y,
275  double *z)
276 {
277  struct P_node *Node;
278 
279  if (num < 1 || num > Map->plus.n_nodes) {
280  G_warning(_("Invalid node id: %d"), num);
281  return -1;
282  }
283 
284  Node = Map->plus.Node[num];
285  *x = Node->x;
286  *y = Node->y;
287 
288  if (z != NULL)
289  *z = Node->z;
290 
291  return 0;
292 }
293 
294 /*!
295  \brief Get line nodes
296 
297  \param Map pointer to Map_info struct
298  \param line line id
299  \param n1 (start node), n2 (end node) ids of line nodes (or NULL)
300 
301  \return 1
302  */
303 int Vect_get_line_nodes(struct Map_info *Map, int line, int *n1, int *n2)
304 {
305  char type;
306 
307  check_level(Map);
308 
309  type = Vect_get_line_type(Map, line);
310 
311  if (!(type & GV_LINES))
312  G_fatal_error(_("Nodes not available for line %d"), line);
313 
314  if (type == GV_LINE) {
315  struct P_topo_l *topo = (struct P_topo_l *)Map->plus.Line[line]->topo;
316 
317  if (n1 != NULL)
318  *n1 = topo->N1;
319  if (n2 != NULL)
320  *n2 = topo->N2;
321  }
322  else if (type == GV_BOUNDARY) {
323  struct P_topo_b *topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
324 
325  if (n1 != NULL)
326  *n1 = topo->N1;
327  if (n2 != NULL)
328  *n2 = topo->N2;
329  }
330 
331  return 1;
332 }
333 
334 /*!
335  \brief Get area id on the left and right side of the boundary
336 
337  Negative area id indicates an isle.
338 
339  \param Map pointer to Map_info struct
340  \param line line id
341  \param[out] left,right area id on the left and right side
342 
343  \return 1 on success
344  \return -1 on failure (topology not available, line is not a boundary)
345  */
346 int Vect_get_line_areas(struct Map_info *Map, int line, int *left, int *right)
347 {
348  struct P_topo_b *topo;
349 
350  check_level(Map);
351 
352  if (!Map->plus.Line[line]->topo) {
353  G_warning(_("Areas not available for line %d"), line);
354  return -1;
355  }
356 
357  if (Vect_get_line_type(Map, line) != GV_BOUNDARY) {
358  G_warning(_("Line %d is not a boundary"), line);
359  return -1;
360  }
361 
362  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
363  if (left != NULL)
364  *left = topo->left;
365 
366  if (right != NULL)
367  *right = topo->right;
368 
369  return 1;
370 }
371 
372 /*!
373  \brief Get number of lines for node
374 
375  \param Map pointer to Map_info struct
376  \param node node id
377 
378  \return numbers of lines
379  */
380 int Vect_get_node_n_lines(struct Map_info *Map, int node)
381 {
382  check_level(Map);
383 
384  return (Map->plus.Node[node]->n_lines);
385 }
386 
387 /*!
388  \brief Get line id for node line index
389 
390  \param Map pointer to Map_info struct
391  \param node node id
392  \param line line index (range: 0 - Vect_get_node_n_lines())
393 
394  \return line id
395  */
396 int Vect_get_node_line(struct Map_info *Map, int node, int line)
397 {
398  check_level(Map);
399 
400  return (Map->plus.Node[node]->lines[line]);
401 }
402 
403 /*!
404  \brief Angle of segment of the line connected to the node
405 
406  \param Map pointer to Map_info struct
407  \param node node number
408  \param line line index (range: 0 - Vect_get_node_n_lines())
409 
410  \return angle of segment of the line connected to the node
411  */
412 float Vect_get_node_line_angle(struct Map_info *Map, int node, int line)
413 {
414  check_level(Map);
415 
416  return (Map->plus.Node[node]->angles[line]);
417 }
418 
419 /*!
420  \brief Get area id the centroid is within
421 
422  \param Map pointer to Map_info struct
423  \param centroid centroid id
424 
425  \return area id the centroid is within
426  \return 0 for not in area
427  \return negative id if centroid is duplicated in the area
428  */
429 int Vect_get_centroid_area(struct Map_info *Map, int centroid)
430 {
431  struct P_topo_c *topo;
432 
433  check_level(Map);
434 
435  if (Map->plus.Line[centroid]->type != GV_CENTROID)
436  return 0;
437 
438  topo = (struct P_topo_c *)Map->plus.Line[centroid]->topo;
439  if (!topo)
440  G_fatal_error(_("Topology info not available for feature %d"),
441  centroid);
442 
443  return (topo->area);
444 }
445 
446 /*!
447  \brief Enable/disable maintenance of list of updated lines/nodes
448 
449  See Plus_head.uplist for details.
450 
451  \param Map pointer to Map_info struct
452  \param enable TRUE/FALSE to enable/disable
453  */
454 void Vect_set_updated(struct Map_info *Map, int enable)
455 {
456  G_debug(1, "Vect_set_updated(): name = '%s' enabled = %d", Map->name,
457  enable);
458 
459  check_level(Map);
460 
461  Map->plus.uplist.do_uplist = enable != 0 ? TRUE : FALSE;
462 }
463 
464 /*!
465  \brief Reset list of updated lines/nodes
466 
467  \param Map pointer to Map_info struct
468  */
469 void Vect_reset_updated(struct Map_info *Map)
470 {
471  struct Plus_head *Plus;
472 
473  check_level(Map);
474 
475  Plus = &(Map->plus);
478 }
#define NULL
Definition: ccmath.h:32
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
#define GV_CENTROID
Definition: dig_defines.h:186
#define GV_LINE
Definition: dig_defines.h:184
#define GV_POINT
Feature types used in memory on run time (may change)
Definition: dig_defines.h:183
#define GV_LINES
Definition: dig_defines.h:193
#define GV_BOUNDARY
Definition: dig_defines.h:185
#define GV_FACE
Definition: dig_defines.h:187
#define GV_KERNEL
Definition: dig_defines.h:188
void dig_node_reset_updated(struct Plus_head *)
Reset number of updated nodes.
void dig_line_reset_updated(struct Plus_head *)
Reset number of updated lines.
int plus_t
plus_t size
Definition: dig_structs.h:41
#define TRUE
Definition: gis.h:79
#define FALSE
Definition: gis.h:83
#define _(str)
Definition: glocale.h:10
plus_t Vect_get_num_faces(struct Map_info *Map)
Get number of faces in vector map.
Definition: level_two.c:111
plus_t Vect_get_num_primitives(struct Map_info *Map, int type)
Get number of primitives in vector map.
Definition: level_two.c:47
void Vect_reset_updated(struct Map_info *Map)
Reset list of updated lines/nodes.
Definition: level_two.c:469
void Vect_set_updated(struct Map_info *Map, int enable)
Enable/disable maintenance of list of updated lines/nodes.
Definition: level_two.c:454
plus_t Vect_get_num_kernels(struct Map_info *Map)
Fetch number of kernels in vector map.
Definition: level_two.c:99
int Vect_get_node_line(struct Map_info *Map, int node, int line)
Get line id for node line index.
Definition: level_two.c:396
int Vect_get_node_n_lines(struct Map_info *Map, int node)
Get number of lines for node.
Definition: level_two.c:380
plus_t Vect_get_num_nodes(struct Map_info *Map)
Get number of nodes in vector map.
Definition: level_two.c:34
plus_t Vect_get_num_lines(struct Map_info *Map)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:75
int Vect_get_num_updated_nodes(struct Map_info *Map)
Get number of updated nodes.
Definition: level_two.c:219
int Vect_get_centroid_area(struct Map_info *Map, int centroid)
Get area id the centroid is within.
Definition: level_two.c:429
int Vect_get_updated_node(struct Map_info *Map, int idx)
Get updated (modified) node by index.
Definition: level_two.c:241
plus_t Vect_get_num_areas(struct Map_info *Map)
Get number of areas in vector map.
Definition: level_two.c:87
plus_t Vect_get_num_volumes(struct Map_info *Map)
Fetch number of volumes in vector map.
Definition: level_two.c:123
int Vect_get_updated_line(struct Map_info *Map, int idx)
Get updated line by index.
Definition: level_two.c:191
off_t Vect_get_updated_line_offset(struct Map_info *Map, int idx)
Get updated line offset by index.
Definition: level_two.c:207
plus_t Vect_get_num_holes(struct Map_info *Map)
Fetch number of holes in vector map.
Definition: level_two.c:147
int Vect_get_line_nodes(struct Map_info *Map, int line, int *n1, int *n2)
Get line nodes.
Definition: level_two.c:303
int Vect_get_line_type(struct Map_info *Map, int line)
Get line type.
Definition: level_two.c:254
int Vect_get_num_updated_lines(struct Map_info *Map)
Get number of updated features.
Definition: level_two.c:175
int Vect_get_num_dblinks(struct Map_info *Map)
Get number of defined dblinks.
Definition: level_two.c:159
float Vect_get_node_line_angle(struct Map_info *Map, int node, int line)
Angle of segment of the line connected to the node.
Definition: level_two.c:412
int Vect_get_node_coor(struct Map_info *Map, int num, double *x, double *y, double *z)
Get node coordinates.
Definition: level_two.c:274
int Vect_get_line_areas(struct Map_info *Map, int line, int *left, int *right)
Get area id on the left and right side of the boundary.
Definition: level_two.c:346
plus_t Vect_get_num_islands(struct Map_info *Map)
Get number of islands in vector map.
Definition: level_two.c:135
if(!(yy_init))
Definition: sqlp.yy.c:775
Vector map info.
Definition: dig_structs.h:1243
int level
Topology level.
Definition: dig_structs.h:1297
char * name
Map name (for 4.0)
Definition: dig_structs.h:1316
struct dblinks * dblnk
Array of DB links.
Definition: dig_structs.h:1265
struct Plus_head plus
Plus info (topology, version, ...)
Definition: dig_structs.h:1270
char type
Line type.
Definition: dig_structs.h:1564
void * topo
Topology info.
Definition: dig_structs.h:1577
Topological feature - node.
Definition: dig_structs.h:1433
double x
X coordinate.
Definition: dig_structs.h:1437
plus_t n_lines
Number of attached lines (size of lines, angle)
Definition: dig_structs.h:1456
float * angles
List of angles of connected lines.
Definition: dig_structs.h:1472
plus_t * lines
List of connected lines.
Definition: dig_structs.h:1463
double z
Z coordinate (used only for 3D data)
Definition: dig_structs.h:1445
double y
Y coordinate.
Definition: dig_structs.h:1441
Boundary topology.
Definition: dig_structs.h:1492
plus_t left
Area number to the left, negative for isle.
Definition: dig_structs.h:1504
plus_t N1
Start node.
Definition: dig_structs.h:1496
plus_t N2
End node.
Definition: dig_structs.h:1500
plus_t right
Area number to the right, negative for isle.
Definition: dig_structs.h:1508
Centroid topology.
Definition: dig_structs.h:1514
plus_t area
Area number, negative for duplicate centroid.
Definition: dig_structs.h:1518
Line topology.
Definition: dig_structs.h:1478
plus_t N1
Start node.
Definition: dig_structs.h:1482
plus_t N2
End node.
Definition: dig_structs.h:1486
Basic topology-related info.
Definition: dig_structs.h:769
int do_uplist
Indicates if the list of updated features is maintained.
Definition: dig_structs.h:1161
plus_t n_klines
Current number of kernels.
Definition: dig_structs.h:906
struct P_line ** Line
Array of vector geometries.
Definition: dig_structs.h:871
plus_t n_lines
Current number of lines.
Definition: dig_structs.h:931
plus_t n_plines
Current number of points.
Definition: dig_structs.h:886
plus_t n_nodes
Current number of topological features derived from vector geometries.
Definition: dig_structs.h:923
plus_t n_volumes
Current number of volumes.
Definition: dig_structs.h:947
int n_upnodes
number of updated nodes
Definition: dig_structs.h:1197
int * upnodes
Array of updated nodes.
Definition: dig_structs.h:1189
plus_t n_blines
Current number of boundaries.
Definition: dig_structs.h:894
plus_t n_clines
Current number of centroids.
Definition: dig_structs.h:898
plus_t n_isles
Current number of isles.
Definition: dig_structs.h:939
int * uplines
Array of updated lines.
Definition: dig_structs.h:1171
plus_t n_holes
Current number of holes.
Definition: dig_structs.h:951
struct Plus_head::@10 uplist
List of updated lines/nodes.
off_t * uplines_offset
Array of updated lines - offset.
Definition: dig_structs.h:1177
int n_uplines
Number of updated lines.
Definition: dig_structs.h:1185
struct P_node ** Node
Array of nodes.
Definition: dig_structs.h:867
plus_t n_areas
Current number of areas.
Definition: dig_structs.h:935
plus_t n_flines
Current number of faces.
Definition: dig_structs.h:902
plus_t n_llines
Current number of lines.
Definition: dig_structs.h:890
#define x