GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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(const 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(const 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 vector map
69 
70  \param Map pointer to Map_info struct
71 
72  \return number of features
73  */
75 {
76  return (Map->plus.n_lines);
77 }
78 
79 /*!
80  \brief Get number of areas in vector map
81 
82  \param Map pointer to Map_info struct
83 
84  \return number of areas
85  */
87 {
88  return (Map->plus.n_areas);
89 }
90 
91 /*!
92  \brief Fetch number of kernels in vector map
93 
94  \param Map pointer to Map_info struct
95 
96  \return number of kernels
97  */
99 {
100  return (Map->plus.n_klines);
101 }
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 /*!
118  \brief Fetch number of volumes in vector map
119 
120  \param Map pointer to Map_info struct
121 
122  \return number of volumes
123  */
125 {
126  return (Map->plus.n_volumes);
127 }
128 
129 
130 /*!
131  \brief Get number of islands in vector map
132 
133  \param Map pointer to Map_info struct
134 
135  \return number of islands
136  */
138 {
139  return (Map->plus.n_isles);
140 }
141 
142 
143 /*!
144  \brief Fetch number of holes in vector map
145 
146  \param Map pointer to Map_info struct
147 
148  \return number of holes
149  */
151 {
152  return (Map->plus.n_holes);
153 }
154 
155 
156 /*!
157  \brief Get number of defined dblinks
158 
159  \param Map pointer to Map_info struct
160 
161  \return number of dblinks
162  */
163 int Vect_get_num_dblinks(const struct Map_info *Map)
164 {
165  /* available on level 1 ? */
166  return (Map->dblnk->n_fields);
167 }
168 
169 /*!
170  \brief Get number of updated features
171 
172  Note: Vect_set_updated() must be called to maintain list of updated
173  features
174 
175  \param Map pointer to Map_info struct
176 
177  \return number of updated features
178  */
179 int Vect_get_num_updated_lines(const struct Map_info *Map)
180 {
181  return (Map->plus.uplist.n_uplines);
182 }
183 
184 /*!
185  \brief Get updated line by index
186 
187  Note: Vect_set_updated() must be called to maintain list of updated
188  features
189 
190  \param Map pointer to Map_info struct
191  \param idx index
192 
193  \return updated line
194  */
195 int Vect_get_updated_line(const struct Map_info *Map, int idx)
196 {
197  return (Map->plus.uplist.uplines[idx]);
198 }
199 
200 /*!
201  \brief Get updated line offset by index
202 
203  Note: Vect_set_updated() must be called to maintain list of updated
204  features
205 
206  \param Map pointer to Map_info struct
207  \param idx index
208 
209  \return updated line
210  */
211 off_t Vect_get_updated_line_offset(const struct Map_info *Map, int idx)
212 {
213  return (Map->plus.uplist.uplines_offset[idx]);
214 }
215 
216 /*!
217  \brief Get number of updated nodes
218 
219  \param Map pointer to Map_info struct
220 
221  \return number of updated nodes
222  */
223 int Vect_get_num_updated_nodes(const struct Map_info *Map)
224 {
225  return (Map->plus.uplist.n_upnodes);
226 }
227 
228 /*!
229  \brief Get updated (modified) node by index
230 
231  Note: Vect_set_updated() must be called to maintain list of updated
232  features
233 
234  Negative id:
235  - if Node[id] is not NULL then the node was added
236  - if Node[id] is NULL then the node was deleted
237  Positive id:
238  - node was updated
239 
240  \param Map pointer to Map_info struct
241  \param idx index
242 
243  \return id of modified node
244  */
245 int Vect_get_updated_node(const struct Map_info *Map, int idx)
246 {
247  return (Map->plus.uplist.upnodes[idx]);
248 }
249 
250 /*!
251  \brief Get line type
252 
253  \param Map pointer to Map_info struct
254  \param line line id
255 
256  \return line type
257  */
258 int Vect_get_line_type(const struct Map_info *Map, int line)
259 {
260  check_level(Map);
261 
262  if (!Vect_line_alive(Map, line))
263  return 0;
264 
265  return (Map->plus.Line[line]->type);
266 }
267 
268 /*!
269  \brief Get node coordinates
270 
271  \param Map pointer to Map_info struct
272  \param num node id (starts at 1)
273  \param[out] x,y,z coordinates values (for 2D coordinates z is NULL)
274 
275  \return 0 on success
276  \return -1 on error
277  */
278 int Vect_get_node_coor(const struct Map_info *Map, int num, double *x, double *y,
279  double *z)
280 {
281  struct P_node *Node;
282 
283  if (num < 1 || num > Map->plus.n_nodes) {
284  G_warning(_("Invalid node id: %d"), num);
285  return -1;
286  }
287 
288  Node = Map->plus.Node[num];
289  *x = Node->x;
290  *y = Node->y;
291 
292  if (z != NULL)
293  *z = Node->z;
294 
295  return 0;
296 }
297 
298 /*!
299  \brief Get line nodes
300 
301  \param Map pointer to Map_info struct
302  \param line line id
303  \param n1 (start node), n2 (end node) ids of line nodes (or NULL)
304 
305  \return 1
306  */
307 int Vect_get_line_nodes(const struct Map_info *Map, int line, int *n1, int *n2)
308 {
309  char type;
310 
311  check_level(Map);
312 
313  type = Vect_get_line_type(Map, line);
314 
315  if (!(type & GV_LINES))
316  G_fatal_error(_("Nodes not available for line %d"), line);
317 
318  if (type == GV_LINE) {
319  struct P_topo_l *topo = (struct P_topo_l *)Map->plus.Line[line]->topo;
320 
321  if (n1 != NULL)
322  *n1 = topo->N1;
323  if (n2 != NULL)
324  *n2 = topo->N2;
325  }
326  else if (type == GV_BOUNDARY) {
327  struct P_topo_b *topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
328 
329  if (n1 != NULL)
330  *n1 = topo->N1;
331  if (n2 != NULL)
332  *n2 = topo->N2;
333  }
334 
335  return 1;
336 }
337 
338 /*!
339  \brief Get area id on the left and right side of the boundary
340 
341  Negative area id indicates an isle.
342 
343  \param Map pointer to Map_info struct
344  \param line line id
345  \param[out] left,right area id on the left and right side
346 
347  \return 1 on success
348  \return -1 on failure (topology not available, line is not a boundary)
349  */
350 int Vect_get_line_areas(const struct Map_info *Map, int line, int *left, int *right)
351 {
352  struct P_topo_b *topo;
353 
354  check_level(Map);
355 
356  if (!Map->plus.Line[line]->topo) {
357  G_warning(_("Areas not available for line %d"), line);
358  return -1;
359  }
360 
361  if (Vect_get_line_type(Map, line) != GV_BOUNDARY) {
362  G_warning(_("Line %d is not a boundary"), line);
363  return -1;
364  }
365 
366  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
367  if (left != NULL)
368  *left = topo->left;
369 
370  if (right != NULL)
371  *right = topo->right;
372 
373  return 1;
374 }
375 
376 /*!
377  \brief Get number of lines for node
378 
379  \param Map pointer to Map_info struct
380  \param node node id
381 
382  \return numbers of lines
383  */
384 int Vect_get_node_n_lines(const struct Map_info *Map, int node)
385 {
386  check_level(Map);
387 
388  return (Map->plus.Node[node]->n_lines);
389 
390 }
391 
392 /*!
393  \brief Get line id for node line index
394 
395  \param Map pointer to Map_info struct
396  \param node node id
397  \param line line index (range: 0 - Vect_get_node_n_lines())
398 
399  \return line id
400  */
401 int Vect_get_node_line(const struct Map_info *Map, int node, int line)
402 {
403  check_level(Map);
404 
405  return (Map->plus.Node[node]->lines[line]);
406 }
407 
408 /*!
409  \brief Angle of segment of the line connected to the node
410 
411  \param Map pointer to Map_info struct
412  \param node node number
413  \param line line index (range: 0 - Vect_get_node_n_lines())
414 
415  \return angle of segment of the line connected to the node
416  */
417 float Vect_get_node_line_angle(const struct Map_info *Map, int node, int line)
418 {
419  check_level(Map);
420 
421  return (Map->plus.Node[node]->angles[line]);
422 }
423 
424 /*!
425  \brief Get area id the centroid is within
426 
427  \param Map pointer to Map_info struct
428  \param centroid centroid id
429 
430  \return area id the centroid is within
431  \return 0 for not in area
432  \return negative id if centroid is duplicated in the area
433  */
434 int Vect_get_centroid_area(const struct Map_info *Map, int centroid)
435 {
436  struct P_topo_c *topo;
437 
438  check_level(Map);
439 
440  if (Map->plus.Line[centroid]->type != GV_CENTROID)
441  return 0;
442 
443  topo = (struct P_topo_c *)Map->plus.Line[centroid]->topo;
444  if(!topo)
445  G_fatal_error(_("Topology info not available for feature %d"), centroid);
446 
447  return (topo->area);
448 }
449 
450 /*!
451  \brief Enable/disable maintanance of list of updated lines/nodes
452 
453  See Plus_head.uplist for details.
454 
455  \param Map pointer to Map_info struct
456  \param enable TRUE/FALSE to enable/disable
457 */
458 void Vect_set_updated(struct Map_info *Map, int enable)
459 {
460  G_debug(1, "Vect_set_updated(): name = '%s' enabled = %d", Map->name, enable);
461 
462  check_level(Map);
463 
464  Map->plus.uplist.do_uplist = enable != 0 ? TRUE : FALSE;
465 }
466 
467 /*!
468  \brief Reset list of updated lines/nodes
469 
470  \param Map pointer to Map_info struct
471 */
472 void Vect_reset_updated(struct Map_info *Map)
473 {
474  struct Plus_head *Plus;
475 
476  check_level(Map);
477 
478  Plus = &(Map->plus);
481 }
plus_t Vect_get_num_kernels(const struct Map_info *Map)
Fetch number of kernels in vector map.
Definition: level_two.c:98
int Vect_get_num_updated_nodes(const struct Map_info *Map)
Get number of updated nodes.
Definition: level_two.c:223
#define TRUE
Definition: gis.h:59
plus_t n_areas
Current number of areas.
Definition: dig_structs.h:951
plus_t Vect_get_num_areas(const struct Map_info *Map)
Get number of areas in vector map.
Definition: level_two.c:86
char * name
Map name (for 4.0)
Definition: dig_structs.h:1332
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int plus_t
plus_t size
Definition: dig_structs.h:41
if(!(yy_init))
Definition: sqlp.yy.c:775
plus_t area
Area number, negative for duplicate centroid.
Definition: dig_structs.h:1537
int Vect_get_num_updated_lines(const struct Map_info *Map)
Get number of updated features.
Definition: level_two.c:179
int n_uplines
Number of updated lines.
Definition: dig_structs.h:1201
plus_t n_klines
Current number of kernels.
Definition: dig_structs.h:922
plus_t n_holes
Current number of holes.
Definition: dig_structs.h:967
int Vect_get_node_coor(const struct Map_info *Map, int num, double *x, double *y, double *z)
Get node coordinates.
Definition: level_two.c:278
struct P_line ** Line
Array of vector geometries.
Definition: dig_structs.h:887
int Vect_get_node_n_lines(const struct Map_info *Map, int node)
Get number of lines for node.
Definition: level_two.c:384
plus_t n_plines
Current number of points.
Definition: dig_structs.h:902
plus_t right
Area number to the right, negative for isle.
Definition: dig_structs.h:1526
int * uplines
Array of updated lines.
Definition: dig_structs.h:1187
struct P_node ** Node
Array of nodes.
Definition: dig_structs.h:883
double x
X coordinate.
Definition: dig_structs.h:1453
#define GV_CENTROID
Definition: dig_defines.h:185
plus_t n_lines
Number of attached lines (size of lines, angle)
Definition: dig_structs.h:1472
void Vect_reset_updated(struct Map_info *Map)
Reset list of updated lines/nodes.
Definition: level_two.c:472
plus_t left
Area number to the left, negative for isle.
Definition: dig_structs.h:1522
int Vect_get_num_dblinks(const struct Map_info *Map)
Get number of defined dblinks.
Definition: level_two.c:163
int Vect_get_centroid_area(const struct Map_info *Map, int centroid)
Get area id the centroid is within.
Definition: level_two.c:434
plus_t * lines
List of connected lines.
Definition: dig_structs.h:1479
plus_t n_isles
Current number of isles.
Definition: dig_structs.h:955
plus_t Vect_get_num_volumes(const struct Map_info *Map)
Fetch number of volumes in vector map.
Definition: level_two.c:124
int level
Topology level.
Definition: dig_structs.h:1313
int do_uplist
Indicates if the list of updated features is maintained.
Definition: dig_structs.h:1177
#define NULL
Definition: ccmath.h:32
int Vect_get_updated_node(const struct Map_info *Map, int idx)
Get updated (modified) node by index.
Definition: level_two.c:245
#define x
plus_t N1
Start node.
Definition: dig_structs.h:1514
#define GV_POINT
Feature types used in memory on run time (may change)
Definition: dig_defines.h:182
plus_t N2
End node.
Definition: dig_structs.h:1503
plus_t n_lines
Current number of lines.
Definition: dig_structs.h:947
float Vect_get_node_line_angle(const struct Map_info *Map, int node, int line)
Angle of segment of the line connected to the node.
Definition: level_two.c:417
#define GV_LINE
Definition: dig_defines.h:183
void dig_node_reset_updated(struct Plus_head *)
Reset number of updated nodes.
plus_t N1
Start node.
Definition: dig_structs.h:1499
plus_t Vect_get_num_islands(const struct Map_info *Map)
Get number of islands in vector map.
Definition: level_two.c:137
char type
Line type.
Definition: dig_structs.h:1586
double z
Z coordinate (used only for 3D data)
Definition: dig_structs.h:1461
Centroid topology.
Definition: dig_structs.h:1532
off_t * uplines_offset
Array of updated lines - offset.
Definition: dig_structs.h:1193
#define GV_FACE
Definition: dig_defines.h:186
Basic topology-related info.
Definition: dig_structs.h:784
plus_t Vect_get_num_primitives(const struct Map_info *Map, int type)
Get number of primitives in vector map.
Definition: level_two.c:47
int Vect_get_node_line(const struct Map_info *Map, int node, int line)
Get line id for node line index.
Definition: level_two.c:401
Line topology.
Definition: dig_structs.h:1494
#define FALSE
Definition: gis.h:63
void * topo
Topology info.
Definition: dig_structs.h:1599
int n_upnodes
number of updated nodes
Definition: dig_structs.h:1213
float * angles
List of angles of connected lines.
Definition: dig_structs.h:1488
Boundary topology.
Definition: dig_structs.h:1509
int Vect_get_updated_line(const struct Map_info *Map, int idx)
Get updated line by index.
Definition: level_two.c:195
#define GV_BOUNDARY
Definition: dig_defines.h:184
struct Plus_head plus
Plus info (topology, version, ...)
Definition: dig_structs.h:1286
int Vect_get_line_type(const struct Map_info *Map, int line)
Get line type.
Definition: level_two.c:258
Topological feature - node.
Definition: dig_structs.h:1448
plus_t n_flines
Current number of faces.
Definition: dig_structs.h:918
plus_t Vect_get_num_nodes(const struct Map_info *Map)
Get number of nodes in vector map.
Definition: level_two.c:34
double y
Y coordinate.
Definition: dig_structs.h:1457
Vector map info.
Definition: dig_structs.h:1259
plus_t Vect_get_num_faces(const struct Map_info *Map)
Get number of faces in vector map.
Definition: level_two.c:111
int Vect_get_line_nodes(const struct Map_info *Map, int line, int *n1, int *n2)
Get line nodes.
Definition: level_two.c:307
plus_t n_llines
Current number of lines.
Definition: dig_structs.h:906
struct dblinks * dblnk
Array of DB links.
Definition: dig_structs.h:1281
void Vect_set_updated(struct Map_info *Map, int enable)
Enable/disable maintanance of list of updated lines/nodes.
Definition: level_two.c:458
plus_t Vect_get_num_holes(const struct Map_info *Map)
Fetch number of holes in vector map.
Definition: level_two.c:150
void dig_line_reset_updated(struct Plus_head *)
Reset number of updated lines.
int Vect_get_line_areas(const 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:350
const char * Vect_get_full_name(const struct Map_info *)
Get fully qualified name of vector map.
plus_t Vect_get_num_lines(const struct Map_info *Map)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:74
void G_warning(const char *,...) __attribute__((format(printf
int Vect_line_alive(const struct Map_info *, int)
Check if feature is alive or dead (topological level required)
#define _(str)
Definition: glocale.h:10
plus_t n_clines
Current number of centroids.
Definition: dig_structs.h:914
int * upnodes
Array of updated nodes.
Definition: dig_structs.h:1205
#define GV_LINES
Definition: dig_defines.h:192
struct Plus_head::@10 uplist
List of updated lines/nodes.
plus_t n_blines
Current number of boundaries.
Definition: dig_structs.h:910
plus_t N2
End node.
Definition: dig_structs.h:1518
int G_debug(int, const char *,...) __attribute__((format(printf
#define GV_KERNEL
Definition: dig_defines.h:187
plus_t n_volumes
Current number of volumes.
Definition: dig_structs.h:963
plus_t n_nodes
Current number of topological features derived from vector geometries.
Definition: dig_structs.h:939
off_t Vect_get_updated_line_offset(const struct Map_info *Map, int idx)
Get updated line offset by index.
Definition: level_two.c:211