GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-7413740dd8
plus.c
Go to the documentation of this file.
1 /**
2  * \file plus.c
3  *
4  * \brief Vector library - update topo structure (lower level functions)
5  *
6  * Lower level functions for reading/writing/manipulating vectors.
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 CERL (probably Dave Gerdes), Radim Blazek
12  *
13  * \date 2001-2006
14  */
15 
16 #include <sys/types.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <grass/vector.h>
21 #include <grass/glocale.h>
22 
23 /*!
24  * \brief Initialize Plus_head structure
25  *
26  * \param[in,out] Plus pointer to Plus_head structure
27  *
28  * \return 1
29  */
30 int dig_init_plus(struct Plus_head *Plus)
31 {
32 
33  G_debug(3, "dig_init_plus()");
34 
35  G_zero(Plus, sizeof(struct Plus_head));
36 
37  Plus->built = GV_BUILD_NONE;
38 
39  dig_spidx_init(Plus);
40  dig_cidx_init(Plus);
41 
42  return 1;
43 }
44 
45 /*!
46  * \brief Free Plus->Node structure
47  *
48  * \param[in] Plus pointer to Plus_head structure
49  */
50 void dig_free_plus_nodes(struct Plus_head *Plus)
51 {
52  int i;
53  struct P_node *Node;
54 
55  G_debug(2, "dig_free_plus_nodes()");
56 
57  /* Nodes */
58  if (Plus->Node) { /* it may be that header only is loaded */
59  for (i = 1; i <= Plus->n_nodes; i++) {
60  Node = Plus->Node[i];
61  if (Node == NULL)
62  continue;
63 
64  dig_free_node(Node);
65  }
66  G_free(Plus->Node);
67  }
68  Plus->Node = NULL;
69  Plus->n_nodes = 0;
70  Plus->alloc_nodes = 0;
71 }
72 
73 /*!
74  * \brief Free Plus->Line structure
75  *
76  * \param[in] Plus pointer to Plus_head structure
77  */
78 void dig_free_plus_lines(struct Plus_head *Plus)
79 {
80  int i;
81  struct P_line *Line;
82 
83  G_debug(2, "dig_free_plus_lines()");
84 
85  /* Lines */
86  if (Plus->Line) { /* it may be that header only is loaded */
87  for (i = 1; i <= Plus->n_lines; i++) {
88  Line = Plus->Line[i];
89  if (Line == NULL)
90  continue;
91 
92  dig_free_line(Line);
93  }
94  G_free(Plus->Line);
95  }
96 
97  Plus->Line = NULL;
98  Plus->n_lines = 0;
99  Plus->alloc_lines = 0;
100 
101  Plus->n_plines = 0;
102  Plus->n_llines = 0;
103  Plus->n_blines = 0;
104  Plus->n_clines = 0;
105  Plus->n_flines = 0;
106  Plus->n_klines = 0;
107 }
108 
109 /*!
110  * \brief Free Plus->Area structure
111  *
112  * \param[in] Plus pointer to Plus_head structure
113  */
114 void dig_free_plus_areas(struct Plus_head *Plus)
115 {
116  int i;
117  struct P_area *Area;
118 
119  G_debug(2, "dig_free_plus_areas()");
120 
121  /* Areas */
122  if (Plus->Area) { /* it may be that header only is loaded */
123  for (i = 1; i <= Plus->n_areas; i++) {
124  Area = Plus->Area[i];
125  if (Area == NULL)
126  continue;
127 
128  dig_free_area(Area);
129  }
130  G_free(Plus->Area);
131  }
132  Plus->Area = NULL;
133  Plus->n_areas = 0;
134  Plus->alloc_areas = 0;
135 }
136 
137 /*!
138  * \brief Free Plus->Isle structure
139  *
140  * \param[in] Plus pointer to Plus_head structure
141  */
142 void dig_free_plus_isles(struct Plus_head *Plus)
143 {
144  int i;
145  struct P_isle *Isle;
146 
147  G_debug(2, "dig_free_plus_isles()");
148 
149  /* Isles */
150  if (Plus->Isle) { /* it may be that header only is loaded */
151  for (i = 1; i <= Plus->n_isles; i++) {
152  Isle = Plus->Isle[i];
153  if (Isle == NULL)
154  continue;
155 
156  dig_free_isle(Isle);
157  }
158  G_free(Plus->Isle);
159  }
160 
161  Plus->Isle = NULL;
162  Plus->n_isles = 0;
163  Plus->alloc_isles = 0;
164 }
165 
166 /*!
167  * \brief Free Plus structure.
168  *
169  * Structure is not inited and dig_init_plus() should follow.
170  *
171  * \param[in] Plus pointer to Plus_head structure
172  */
173 void dig_free_plus(struct Plus_head *Plus)
174 {
175  G_debug(2, "dig_free_plus()");
176  dig_free_plus_nodes(Plus);
177  dig_free_plus_lines(Plus);
178  dig_free_plus_areas(Plus);
179  dig_free_plus_isles(Plus);
180 
181  dig_spidx_free(Plus);
182  dig_cidx_free(Plus);
183 }
184 
185 /*!
186  * \brief Reads topo file to topo structure.
187  *
188  * \param[in,out] Plus pointer to Plus_head structure
189  * \param[in] plus topo file
190  * \param[in] head_only read only head
191  *
192  * \return 1 on success
193  * \return 0 on error
194  */
195 int dig_load_plus(struct Plus_head *Plus, struct gvfile *plus, int head_only)
196 {
197  int i;
198 
199  G_debug(1, "dig_load_plus()");
200  /* TODO
201  if (do_checks)
202  dig_do_file_checks (map, map->plus_file, map->digit_file);
203  */
204 
205  /* free and init old */
206  dig_free_plus(Plus);
207  dig_init_plus(Plus);
208 
209  /* Now let's begin reading the Plus file nodes, lines, areas and isles */
210 
211  if (dig_Rd_Plus_head(plus, Plus) == -1)
212  return 0;
213 
214  if (head_only)
215  return 1;
216 
217  dig_set_cur_port(&(Plus->port));
218 
219  /* Nodes */
220  if (dig_fseek(plus, Plus->Node_offset, 0) == -1)
221  G_fatal_error(_("Unable read topology for nodes"));
222 
223  dig_alloc_nodes(Plus, Plus->n_nodes);
224  for (i = 1; i <= Plus->n_nodes; i++) {
225  if (dig_Rd_P_node(Plus, i, plus) == -1)
226  G_fatal_error(_("Unable to read topology for node %d"), i);
227  }
228 
229  /* Lines */
230  if (dig_fseek(plus, Plus->Line_offset, 0) == -1)
231  G_fatal_error(_("Unable read topology for lines"));
232 
233  dig_alloc_lines(Plus, Plus->n_lines);
234  for (i = 1; i <= Plus->n_lines; i++) {
235  if (dig_Rd_P_line(Plus, i, plus) == -1)
236  G_fatal_error(_("Unable to read topology for line %d"), i);
237  }
238 
239  /* Areas */
240  if (dig_fseek(plus, Plus->Area_offset, 0) == -1)
241  G_fatal_error(_("Unable to read topo for areas"));
242 
243  dig_alloc_areas(Plus, Plus->n_areas);
244  for (i = 1; i <= Plus->n_areas; i++) {
245  if (dig_Rd_P_area(Plus, i, plus) == -1)
246  G_fatal_error(_("Unable read topology for area %d"), i);
247  }
248 
249  /* Isles */
250  if (dig_fseek(plus, Plus->Isle_offset, 0) == -1)
251  G_fatal_error(_("Unable to read topology for isles"));
252 
253  dig_alloc_isles(Plus, Plus->n_isles);
254  for (i = 1; i <= Plus->n_isles; i++) {
255  if (dig_Rd_P_isle(Plus, i, plus) == -1)
256  G_fatal_error(_("Unable to read topology for isle %d"), i);
257  }
258 
259  return (1);
260 }
261 
262 /*!
263  * \brief Writes topo structure to topo file
264  *
265  * \param[in,out] fp_plus topo file
266  * \param[in] Plus pointer to Plus_head structure
267  *
268  * \return 0 on success
269  * \return -1 on error
270  */
271 int dig_write_plus_file(struct gvfile *fp_plus, struct Plus_head *Plus)
272 {
273 
274  dig_set_cur_port(&(Plus->port));
275  dig_rewind(fp_plus);
276 
277  if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
278  G_warning(_("Unable to write head to plus file"));
279  return (-1);
280  }
281 
282  if (dig_write_nodes(fp_plus, Plus) < 0) {
283  G_warning(_("Unable to write nodes to plus file"));
284  return (-1);
285  }
286 
287  if (dig_write_lines(fp_plus, Plus) < 0) {
288  G_warning(_("Unable to write lines to plus file"));
289  return (-1);
290  }
291 
292  if (dig_write_areas(fp_plus, Plus) < 0) {
293  G_warning(_("Unable to write areas to plus file"));
294  return (-1);
295  }
296 
297  if (dig_write_isles(fp_plus, Plus) < 0) {
298  G_warning(_("Unable to write isles to plus file"));
299  return (-1);
300  }
301 
302  dig_rewind(fp_plus);
303  if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
304  G_warning(_("Unable to write head to plus file"));
305  return (-1);
306  }
307 
308  dig_fflush(fp_plus);
309  return (0);
310 } /* write_plus_file() */
311 
312 /*!
313  * \brief Writes topo structure (nodes) to topo file
314  *
315  * \param[in,out] plus topo file
316  * \param[in] Plus pointer to Plus_head structure
317  *
318  * \return 0 on success
319  * \return -1 on error
320  */
321 int dig_write_nodes(struct gvfile *plus, struct Plus_head *Plus)
322 {
323  int i;
324 
325  Plus->Node_offset = dig_ftell(plus);
326 
327  for (i = 1; i <= Plus->n_nodes; i++) {
328  if (dig_Wr_P_node(Plus, i, plus) < 0)
329  return (-1);
330  }
331 
332  return (0);
333 } /* write_nodes() */
334 
335 /*!
336  * \brief Writes topo structure (lines) to topo file
337  *
338  * \param[in,out] plus topo file
339  * \param[in] Plus pointer to Plus_head structure
340  *
341  * \return 0 on success
342  * \return -1 on error
343  */
344 int dig_write_lines(struct gvfile *plus, struct Plus_head *Plus)
345 {
346  int i;
347 
348  Plus->Line_offset = dig_ftell(plus);
349 
350  for (i = 1; i <= Plus->n_lines; i++) {
351  if (dig_Wr_P_line(Plus, i, plus) < 0)
352  return (-1);
353  }
354 
355  return (0);
356 
357 } /* write_line() */
358 
359 /*!
360  * \brief Writes topo structure (areas) to topo file
361  *
362  * \param[in,out] plus topo file
363  * \param[in] Plus pointer to Plus_head structure
364  *
365  * \return 0 on success
366  * \return -1 on error
367  */
368 int dig_write_areas(struct gvfile *plus, struct Plus_head *Plus)
369 {
370  int i;
371 
372  Plus->Area_offset = dig_ftell(plus);
373 
374  for (i = 1; i <= Plus->n_areas; i++) {
375  if (dig_Wr_P_area(Plus, i, plus) < 0)
376  return (-1);
377  }
378 
379  return (0);
380 
381 } /* write_areas() */
382 
383 /*!
384  * \brief Writes topo structure (isles) to topo file
385  *
386  * \param[in,out] plus topo file
387  * \param[in] Plus pointer to Plus_head structure
388  *
389  * \return 0 on success
390  * \return -1 on error
391  */
392 int dig_write_isles(struct gvfile *plus, struct Plus_head *Plus)
393 {
394  int i;
395 
396  Plus->Isle_offset = dig_ftell(plus);
397 
398  for (i = 1; i <= Plus->n_isles; i++) {
399  if (dig_Wr_P_isle(Plus, i, plus) < 0)
400  return (-1);
401  }
402 
403  return (0);
404 
405 } /* write_isles() */
#define NULL
Definition: ccmath.h:32
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
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
#define GV_BUILD_NONE
Topology levels - nothing to build.
Definition: dig_defines.h:123
void dig_free_line(struct P_line *)
Free line structure.
Definition: struct_alloc.c:177
void dig_free_node(struct P_node *)
Free node structure.
Definition: struct_alloc.c:48
int dig_alloc_nodes(struct Plus_head *, int)
Reallocate array of pointers to nodes.
Definition: struct_alloc.c:105
int dig_Rd_P_area(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:333
int dig_alloc_areas(struct Plus_head *, int)
Reallocate array of pointers to areas.
Definition: struct_alloc.c:218
off_t dig_ftell(struct gvfile *file)
Get struct gvfile position.
Definition: file.c:36
int dig_alloc_isles(struct Plus_head *, int)
Reallocate array of pointers to isles.
Definition: struct_alloc.c:243
int dig_Wr_Plus_head(struct gvfile *, struct Plus_head *)
Write Plus_head to file.
Definition: plus_struct.c:673
int dig_Wr_P_area(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:380
int dig_Rd_P_isle(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:418
int dig_set_cur_port(struct Port_info *)
Set current Port_info structure.
Definition: portable.c:996
void dig_cidx_free(struct Plus_head *)
Definition: diglib/cindex.c:44
int dig_Rd_P_line(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:149
void dig_rewind(struct gvfile *file)
Rewind file position.
Definition: file.c:87
int dig_Wr_P_node(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:104
int dig_Rd_Plus_head(struct gvfile *, struct Plus_head *)
Read Plus_head from file.
Definition: plus_struct.c:493
int dig_cidx_init(struct Plus_head *)
Initialize Plus_head structure (cidx)
Definition: diglib/cindex.c:29
int dig_Wr_P_line(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:242
int dig_Rd_P_node(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:52
int dig_fseek(struct gvfile *file, off_t offset, int whence)
Set struct gvfile position.
Definition: file.c:60
void dig_free_area(struct P_area *)
Free area structure.
Definition: struct_alloc.c:284
int dig_alloc_lines(struct Plus_head *, int)
Reallocate array of pointers to lines.
Definition: struct_alloc.c:193
int dig_fflush(struct gvfile *file)
Flush struct gvfile.
Definition: file.c:104
void dig_spidx_free(struct Plus_head *)
Free spatial index (nodes, lines, areas, isles)
Definition: spindex.c:235
int dig_Wr_P_isle(struct Plus_head *, int i, struct gvfile *)
Definition: plus_struct.c:454
void dig_free_isle(struct P_isle *)
Free isle structure.
Definition: struct_alloc.c:319
int dig_spidx_init(struct Plus_head *)
Initit spatial index (nodes, lines, areas, isles)
Definition: spindex.c:35
#define _(str)
Definition: glocale.h:10
void dig_free_plus(struct Plus_head *Plus)
Free Plus structure.
Definition: plus.c:173
int dig_write_plus_file(struct gvfile *fp_plus, struct Plus_head *Plus)
Writes topo structure to topo file.
Definition: plus.c:271
int dig_write_areas(struct gvfile *plus, struct Plus_head *Plus)
Writes topo structure (areas) to topo file.
Definition: plus.c:368
int dig_init_plus(struct Plus_head *Plus)
Initialize Plus_head structure.
Definition: plus.c:30
void dig_free_plus_areas(struct Plus_head *Plus)
Free Plus->Area structure.
Definition: plus.c:114
void dig_free_plus_nodes(struct Plus_head *Plus)
Free Plus->Node structure.
Definition: plus.c:50
int dig_write_nodes(struct gvfile *plus, struct Plus_head *Plus)
Writes topo structure (nodes) to topo file.
Definition: plus.c:321
int dig_load_plus(struct Plus_head *Plus, struct gvfile *plus, int head_only)
Reads topo file to topo structure.
Definition: plus.c:195
void dig_free_plus_lines(struct Plus_head *Plus)
Free Plus->Line structure.
Definition: plus.c:78
void dig_free_plus_isles(struct Plus_head *Plus)
Free Plus->Isle structure.
Definition: plus.c:142
int dig_write_isles(struct gvfile *plus, struct Plus_head *Plus)
Writes topo structure (isles) to topo file.
Definition: plus.c:392
int dig_write_lines(struct gvfile *plus, struct Plus_head *Plus)
Writes topo structure (lines) to topo file.
Definition: plus.c:344
Area (topology) info.
Definition: dig_structs.h:1583
Isle (topology) info.
Definition: dig_structs.h:1623
Vector geometry.
Definition: dig_structs.h:1553
Topological feature - node.
Definition: dig_structs.h:1433
Basic topology-related info.
Definition: dig_structs.h:769
plus_t n_klines
Current number of kernels.
Definition: dig_structs.h:906
plus_t alloc_lines
Number of allocated lines.
Definition: dig_structs.h:970
off_t Isle_offset
Offset of array of isles in topo file.
Definition: dig_structs.h:1021
off_t Node_offset
Offset of array of nodes in topo file.
Definition: dig_structs.h:1005
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
off_t Area_offset
Offset of array of areas in topo file.
Definition: dig_structs.h:1017
plus_t n_nodes
Current number of topological features derived from vector geometries.
Definition: dig_structs.h:923
plus_t alloc_areas
Number of allocated areas.
Definition: dig_structs.h:976
plus_t n_blines
Current number of boundaries.
Definition: dig_structs.h:894
struct P_area ** Area
Array of areas.
Definition: dig_structs.h:875
plus_t alloc_isles
Number of allocated isles.
Definition: dig_structs.h:982
plus_t n_clines
Current number of centroids.
Definition: dig_structs.h:898
plus_t alloc_nodes
Number of allocated nodes.
Definition: dig_structs.h:958
plus_t n_isles
Current number of isles.
Definition: dig_structs.h:939
struct P_isle ** Isle
Array of isles.
Definition: dig_structs.h:879
struct P_node ** Node
Array of nodes.
Definition: dig_structs.h:867
struct Port_info port
Portability information.
Definition: dig_structs.h:829
plus_t n_areas
Current number of areas.
Definition: dig_structs.h:935
int built
Highest level of topology currently available.
Definition: dig_structs.h:857
plus_t n_flines
Current number of faces.
Definition: dig_structs.h:902
off_t Line_offset
Offset of array of vector geometries in topo file.
Definition: dig_structs.h:1013
plus_t n_llines
Current number of lines.
Definition: dig_structs.h:890
File definition.
Definition: dig_structs.h:94