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