GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
plus_struct.c
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * MODULE: Vector library
5  *
6  * AUTHOR(S): Dave Gerdes, CERL.
7  * Update to GRASS 5.7 Radim Blazek.
8  *
9  * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
10  *
11  * COPYRIGHT: (C) 2001 by the GRASS Development Team
12  *
13  * This program is free software under the GNU General Public
14  * License (>=v2). Read the file COPYING that comes with GRASS
15  * for details.
16  *
17  *****************************************************************************/
18 #include <string.h>
19 #include <grass/gis.h>
20 #include <grass/Vect.h>
21 
22 /*
23  * Routines for reading and writing Dig+ structures.
24  * return 0 on success, -1 on failure of whatever kind
25  * if you dont want it written out, then dont call these routines
26  * ie check for deleted status before calling a write routine
27  * in as much as it would be nice to hide that code in here,
28  * this is a library routine and we chose to make it dependent on
29  * as few external files as possible
30  */
31 
32 /* These routines assume ptr->alloc_lines is valid
33  * Make sure it is initialized before calling
34  */
35 
36 /*
37  * Internally, my default variables for lines/areas/nodes/isles are type
38  * plus_t which is typedefed as short. This limits the current version
39  * to no more than 32K lines, nodes etc. (excluding points)
40  * All in the name of future expansion, I have converted these values to
41  * longs in the dig_plus data file.
42  *
43  * NOTE: 3.10 changes plus_t to ints.
44  * This assumes that any reasonable machine will use 4 bytes to
45  * store an int. The mapdev code is not guaranteed to work if
46  * plus_t is changed to a type that is larger than an int.
47  */
48 
49 int dig_Rd_P_node(struct Plus_head *Plus, int n, GVFILE * fp)
50 {
51  int cnt, n_edges;
52  P_NODE *ptr;
53 
54  G_debug(3, "dig_Rd_P_node()");
55 
56 
57  if (0 >= dig__fread_port_P(&cnt, 1, fp))
58  return (-1);
59 
60  if (cnt == 0) { /* dead */
61  G_debug(3, " node is dead");
62  Plus->Node[n] = NULL;
63  return 0;
64  }
65 
66  ptr = dig_alloc_node();
67  ptr->n_lines = cnt;
68 
69  if (dig_node_alloc_line(ptr, ptr->n_lines) == -1)
70  return -1;
71 
72  if (ptr->n_lines) {
73  if (0 >= dig__fread_port_P(ptr->lines, ptr->n_lines, fp))
74  return (-1);
75  if (0 >= dig__fread_port_F(ptr->angles, ptr->n_lines, fp))
76  return (-1);
77  }
78 
79  if (Plus->with_z)
80  if (0 >= dig__fread_port_P(&n_edges, 1, fp)) /* reserved for edges */
81  return (-1);
82 
83  /* here will be edges */
84 
85  if (0 >= dig__fread_port_D(&(ptr->x), 1, fp))
86  return (-1);
87  if (0 >= dig__fread_port_D(&(ptr->y), 1, fp))
88  return (-1);
89 
90  if (Plus->with_z) {
91  if (0 >= dig__fread_port_D(&(ptr->z), 1, fp))
92  return (-1);
93  }
94  else
95  ptr->z = 0;
96 
97 
98  Plus->Node[n] = ptr;
99 
100  return (0);
101 }
102 
103 int dig_Wr_P_node(struct Plus_head *Plus, int n, GVFILE * fp)
104 {
105  int i, n_edges = 0;
106  P_NODE *ptr;
107 
108  G_debug(3, "dig_Wr_P_node()");
109  ptr = Plus->Node[n];
110 
111  /* If NULL i.e. dead write just 0 instead of number of lines */
112  if (ptr == NULL) {
113  G_debug(3, " node is dead -> write 0 only");
114  i = 0;
115  if (0 >= dig__fwrite_port_P(&i, 1, fp))
116  return (-1);
117  return 0;
118  }
119 
120  if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
121  return (-1);
122 
123  if (ptr->n_lines) {
124  if (0 >= dig__fwrite_port_P(ptr->lines, ptr->n_lines, fp))
125  return (-1);
126  if (0 >= dig__fwrite_port_F(ptr->angles, ptr->n_lines, fp))
127  return (-1);
128  }
129 
130  if (Plus->with_z)
131  if (0 >= dig__fwrite_port_P(&n_edges, 1, fp)) /* reserved for edges */
132  return (-1);
133 
134  /* here will be edges */
135 
136  if (0 >= dig__fwrite_port_D(&(ptr->x), 1, fp))
137  return (-1);
138  if (0 >= dig__fwrite_port_D(&(ptr->y), 1, fp))
139  return (-1);
140 
141  if (Plus->with_z)
142  if (0 >= dig__fwrite_port_D(&(ptr->z), 1, fp))
143  return (-1);
144 
145  return (0);
146 }
147 
148 int dig_Rd_P_line(struct Plus_head *Plus, int n, GVFILE * fp)
149 {
150  int n_edges, vol;
151  char tp;
152  P_LINE *ptr;
153  P_NODE *Node;
154 
155  G_debug(3, "dig_Rd_P_line()");
156 
157  if (0 >= dig__fread_port_C(&tp, 1, fp))
158  return (-1);
159 
160  if (tp == 0) { /* dead */
161  G_debug(3, " line is dead");
162  Plus->Line[n] = NULL;
163  return 0;
164  }
165 
166  ptr = dig_alloc_line();
167 
168  ptr->type = dig_type_from_store(tp);
169  G_debug(5, " line type %d -> %d", tp, ptr->type);
170 
171  if (0 >= dig__fread_port_L(&(ptr->offset), 1, fp))
172  return (-1);
173 
174  /* First node */
175  if (ptr->type & (GV_POINTS | GV_LINES | GV_KERNEL))
176  if (0 >= dig__fread_port_P(&(ptr->N1), 1, fp))
177  return -1;
178 
179  /* Second node, for points/centroids not needed */
180  if (ptr->type & (GV_LINE | GV_BOUNDARY)) {
181  if (0 >= dig__fread_port_P(&(ptr->N2), 1, fp))
182  return -1;
183  }
184  else if (ptr->type & (GV_POINTS | GV_KERNEL))
185  ptr->N2 = ptr->N1;
186 
187  /* left area for boundary, area for centroid */
188  if (ptr->type & (GV_BOUNDARY | GV_CENTROID))
189  if (0 >= dig__fread_port_P(&(ptr->left), 1, fp))
190  return -1;
191 
192  /* right area */
193  if (ptr->type & GV_BOUNDARY)
194  if (0 >= dig__fread_port_P(&(ptr->right), 1, fp))
195  return -1;
196 
197  if ((ptr->type & GV_FACE) && Plus->with_z) { /* reserved for face edges */
198  if (0 >= dig__fread_port_I(&n_edges, 1, fp))
199  return -1;
200 
201  /* here will be list of edges */
202 
203  /* left / right volume */
204  if (0 >= dig__fread_port_P(&vol, 1, fp))
205  return -1;
206  if (0 >= dig__fread_port_P(&vol, 1, fp))
207  return -1;
208  }
209 
210  if ((ptr->type & GV_KERNEL) && Plus->with_z) /* reserved for kernel (volume number) */
211  if (0 >= dig__fread_port_P(&vol, 1, fp))
212  return -1;
213 
214  /* Bounding box */
215  if (ptr->type & (GV_LINE | GV_BOUNDARY | GV_FACE)) {
216  if (0 >= dig__fread_port_D(&(ptr->N), 1, fp))
217  return -1;
218  if (0 >= dig__fread_port_D(&(ptr->S), 1, fp))
219  return -1;
220  if (0 >= dig__fread_port_D(&(ptr->E), 1, fp))
221  return -1;
222  if (0 >= dig__fread_port_D(&(ptr->W), 1, fp))
223  return -1;
224 
225  if (Plus->with_z) {
226  if (0 >= dig__fread_port_D(&(ptr->T), 1, fp))
227  return -1;
228  if (0 >= dig__fread_port_D(&(ptr->B), 1, fp))
229  return -1;
230  }
231  else {
232  ptr->T = 0.0;
233  ptr->B = 0.0;
234  }
235  }
236  else {
237  Node = Plus->Node[ptr->N1];
238  ptr->N = Node->y;
239  ptr->S = Node->y;
240  ptr->E = Node->x;
241  ptr->W = Node->x;
242  ptr->T = Node->z;
243  ptr->B = Node->z;
244  }
245 
246  Plus->Line[n] = ptr;
247  return (0);
248 }
249 
250 int dig_Wr_P_line(struct Plus_head *Plus, int n, GVFILE * fp)
251 {
252  int n_edges = 0, vol = 0;
253  char ch;
254  P_LINE *ptr;
255 
256  G_debug(4, "dig_Wr_P_line() line = %d", n);
257 
258  ptr = Plus->Line[n];
259 
260  /* If NULL i.e. dead write just 0 instead of type */
261  if (ptr == NULL) {
262  G_debug(3, " line is dead -> write 0 only");
263  ch = 0;
264  if (0 >= dig__fwrite_port_C(&ch, 1, fp))
265  return (-1);
266  return 0;
267  }
268 
269  ch = (char)dig_type_to_store(ptr->type);
270  G_debug(5, " line type %d -> %d", ptr->type, ch);
271  if (0 >= dig__fwrite_port_C(&ch, 1, fp))
272  return (-1);
273  if (0 >= dig__fwrite_port_L(&(ptr->offset), 1, fp))
274  return (-1);
275 
276  /* First node */
277  if (ptr->type & (GV_POINTS | GV_LINES | GV_KERNEL))
278  if (0 >= dig__fwrite_port_P(&(ptr->N1), 1, fp))
279  return (-1);
280 
281  /* Second node, for points/centroids not needed */
282  if (ptr->type & (GV_LINE | GV_BOUNDARY))
283  if (0 >= dig__fwrite_port_P(&(ptr->N2), 1, fp))
284  return (-1);
285 
286  /* left area for boundary, area for centroid */
287  if (ptr->type & (GV_BOUNDARY | GV_CENTROID))
288  if (0 >= dig__fwrite_port_P(&(ptr->left), 1, fp))
289  return (-1);
290 
291  /* right area */
292  if (ptr->type & GV_BOUNDARY)
293  if (0 >= dig__fwrite_port_P(&(ptr->right), 1, fp))
294  return (-1);
295 
296  if ((ptr->type & GV_FACE) && Plus->with_z) { /* reserved for face */
297  if (0 >= dig__fwrite_port_I(&n_edges, 1, fp))
298  return (-1);
299 
300  /* here will be list of edges */
301 
302  /* left / right volume */
303  if (0 >= dig__fwrite_port_P(&vol, 1, fp))
304  return (-1);
305  if (0 >= dig__fwrite_port_P(&vol, 1, fp))
306  return (-1);
307  }
308 
309  if ((ptr->type & GV_KERNEL) && Plus->with_z) /* reserved for kernel (volume number) */
310  if (0 >= dig__fwrite_port_P(&vol, 1, fp))
311  return (-1);
312 
313  /* Bounding box */
314  if (ptr->type & (GV_LINE | GV_BOUNDARY | GV_FACE)) {
315  if (0 >= dig__fwrite_port_D(&(ptr->N), 1, fp))
316  return (-1);
317  if (0 >= dig__fwrite_port_D(&(ptr->S), 1, fp))
318  return (-1);
319  if (0 >= dig__fwrite_port_D(&(ptr->E), 1, fp))
320  return (-1);
321  if (0 >= dig__fwrite_port_D(&(ptr->W), 1, fp))
322  return (-1);
323 
324  if (Plus->with_z) {
325  if (0 >= dig__fwrite_port_D(&(ptr->T), 1, fp))
326  return (-1);
327  if (0 >= dig__fwrite_port_D(&(ptr->B), 1, fp))
328  return (-1);
329  }
330  }
331 
332  return (0);
333 }
334 
335 int dig_Rd_P_area(struct Plus_head *Plus, int n, GVFILE * fp)
336 {
337  int cnt;
338  P_AREA *ptr;
339 
340 #ifdef GDEBUG
341  G_debug(3, "dig_Rd_P_area(): n = %d", n);
342 #endif
343 
344  if (0 >= dig__fread_port_P(&cnt, 1, fp))
345  return (-1);
346 
347  if (cnt == 0) { /* dead */
348  Plus->Area[n] = NULL;
349  return 0;
350  }
351 
352  ptr = dig_alloc_area();
353 
354  /* lines */
355  ptr->n_lines = cnt;
356 
357  if (dig_area_alloc_line(ptr, ptr->n_lines) == -1)
358  return -1;
359 
360  if (ptr->n_lines)
361  if (0 >= dig__fread_port_P(ptr->lines, ptr->n_lines, fp))
362  return -1;
363 
364  /* isles */
365  if (0 >= dig__fread_port_P(&(ptr->n_isles), 1, fp))
366  return -1;
367 
368  if (dig_area_alloc_isle(ptr, ptr->n_isles) == -1)
369  return -1;
370 
371  if (ptr->n_isles)
372  if (0 >= dig__fread_port_P(ptr->isles, ptr->n_isles, fp))
373  return -1;
374 
375  /* centroid */
376  if (0 >= dig__fread_port_P(&(ptr->centroid), 1, fp))
377  return -1;
378 
379  if (0 >= dig__fread_port_D(&(ptr->N), 1, fp))
380  return -1;
381  if (0 >= dig__fread_port_D(&(ptr->S), 1, fp))
382  return -1;
383  if (0 >= dig__fread_port_D(&(ptr->E), 1, fp))
384  return -1;
385  if (0 >= dig__fread_port_D(&(ptr->W), 1, fp))
386  return -1;
387 
388  if (Plus->with_z) {
389  if (0 >= dig__fread_port_D(&(ptr->T), 1, fp))
390  return -1;
391  if (0 >= dig__fread_port_D(&(ptr->B), 1, fp))
392  return -1;
393  }
394  else {
395  ptr->T = 0.0;
396  ptr->B = 0.0;
397  }
398 
399  Plus->Area[n] = ptr;
400 
401  return (0);
402 }
403 
404 int dig_Wr_P_area(struct Plus_head *Plus, int n, GVFILE * fp)
405 {
406  int i;
407  P_AREA *ptr;
408 
409  ptr = Plus->Area[n];
410 
411  /* If NULL i.e. dead write just 0 instead of number of lines */
412  if (ptr == NULL) {
413  i = 0;
414  if (0 >= dig__fwrite_port_P(&i, 1, fp))
415  return (-1);
416  return 0;
417  }
418 
419  /* lines */
420  if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
421  return (-1);
422 
423  if (ptr->n_lines)
424  if (0 >= dig__fwrite_port_P(ptr->lines, ptr->n_lines, fp))
425  return -1;
426 
427  /* isles */
428  if (0 >= dig__fwrite_port_P(&(ptr->n_isles), 1, fp))
429  return (-1);
430 
431  if (ptr->n_isles)
432  if (0 >= dig__fwrite_port_P(ptr->isles, ptr->n_isles, fp))
433  return -1;
434 
435  /* centroid */
436  if (0 >= dig__fwrite_port_P(&(ptr->centroid), 1, fp))
437  return (-1);
438 
439  if (0 >= dig__fwrite_port_D(&(ptr->N), 1, fp))
440  return (-1);
441  if (0 >= dig__fwrite_port_D(&(ptr->S), 1, fp))
442  return (-1);
443  if (0 >= dig__fwrite_port_D(&(ptr->E), 1, fp))
444  return (-1);
445  if (0 >= dig__fwrite_port_D(&(ptr->W), 1, fp))
446  return (-1);
447 
448  if (Plus->with_z) {
449  if (0 >= dig__fwrite_port_D(&(ptr->T), 1, fp))
450  return (-1);
451  if (0 >= dig__fwrite_port_D(&(ptr->B), 1, fp))
452  return (-1);
453  }
454 
455  return (0);
456 }
457 
458 int dig_Rd_P_isle(struct Plus_head *Plus, int n, GVFILE * fp)
459 {
460  int cnt;
461  P_ISLE *ptr;
462 
463 #ifdef GDEBUG
464  G_debug(3, "dig_Rd_P_isle()");
465 #endif
466 
467  if (0 >= dig__fread_port_P(&cnt, 1, fp))
468  return (-1);
469 
470  if (cnt == 0) { /* dead */
471  Plus->Isle[n] = NULL;
472  return 0;
473  }
474 
475  ptr = dig_alloc_isle();
476 
477  /* lines */
478  ptr->n_lines = cnt;
479 
480  if (dig_isle_alloc_line(ptr, ptr->n_lines) == -1)
481  return -1;
482 
483  if (ptr->n_lines)
484  if (0 >= dig__fread_port_P(ptr->lines, ptr->n_lines, fp))
485  return -1;
486 
487  /* area */
488  if (0 >= dig__fread_port_P(&(ptr->area), 1, fp))
489  return -1;
490 
491  if (0 >= dig__fread_port_D(&(ptr->N), 1, fp))
492  return -1;
493  if (0 >= dig__fread_port_D(&(ptr->S), 1, fp))
494  return -1;
495  if (0 >= dig__fread_port_D(&(ptr->E), 1, fp))
496  return -1;
497  if (0 >= dig__fread_port_D(&(ptr->W), 1, fp))
498  return -1;
499 
500  if (Plus->with_z) {
501  if (0 >= dig__fread_port_D(&(ptr->T), 1, fp))
502  return -1;
503  if (0 >= dig__fread_port_D(&(ptr->B), 1, fp))
504  return -1;
505  }
506  else {
507  ptr->T = 0.0;
508  ptr->B = 0.0;
509  }
510 
511  Plus->Isle[n] = ptr;
512 
513  return (0);
514 }
515 
516 int dig_Wr_P_isle(struct Plus_head *Plus, int n, GVFILE * fp)
517 {
518  int i;
519  P_ISLE *ptr;
520 
521  ptr = Plus->Isle[n];
522 
523  /* If NULL i.e. dead write just 0 instead of number of lines */
524  if (ptr == NULL) {
525  i = 0;
526  if (0 >= dig__fwrite_port_P(&i, 1, fp))
527  return (-1);
528  return 0;
529  }
530 
531  /* lines */
532  if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
533  return (-1);
534 
535  if (ptr->n_lines)
536  if (0 >= dig__fwrite_port_P(ptr->lines, ptr->n_lines, fp))
537  return -1;
538 
539  /* area */
540  if (0 >= dig__fwrite_port_P(&(ptr->area), 1, fp))
541  return (-1);
542 
543  if (0 >= dig__fwrite_port_D(&(ptr->N), 1, fp))
544  return (-1);
545  if (0 >= dig__fwrite_port_D(&(ptr->S), 1, fp))
546  return (-1);
547  if (0 >= dig__fwrite_port_D(&(ptr->E), 1, fp))
548  return (-1);
549  if (0 >= dig__fwrite_port_D(&(ptr->W), 1, fp))
550  return (-1);
551 
552  if (Plus->with_z) {
553  if (0 >= dig__fwrite_port_D(&(ptr->T), 1, fp))
554  return (-1);
555  if (0 >= dig__fwrite_port_D(&(ptr->B), 1, fp))
556  return (-1);
557  }
558 
559  return (0);
560 }
561 
562 /*
563  \return -1 error
564  \return 0 OK
565  */
566 int dig_Rd_Plus_head(GVFILE * fp, struct Plus_head *ptr)
567 {
568  unsigned char buf[5];
569  int byte_order;
570 
571  dig_rewind(fp);
572 
573  /* bytes 1 - 5 */
574  if (0 >= dig__fread_port_C(buf, 5, fp))
575  return (-1);
576  ptr->Version_Major = buf[0];
577  ptr->Version_Minor = buf[1];
578  ptr->Back_Major = buf[2];
579  ptr->Back_Minor = buf[3];
580  byte_order = buf[4];
581 
582  G_debug(2,
583  "Topo header: file version %d.%d , supported from GRASS version %d.%d",
584  ptr->Version_Major, ptr->Version_Minor, ptr->Back_Major,
585  ptr->Back_Minor);
586 
587  G_debug(2, " byte order %d", byte_order);
588 
589  /* check version numbers */
590  if (ptr->Version_Major > GV_TOPO_VER_MAJOR ||
591  ptr->Version_Minor > GV_TOPO_VER_MINOR) {
592  /* The file was created by GRASS library with higher version than this one */
593 
594  if (ptr->Back_Major > GV_TOPO_VER_MAJOR ||
595  ptr->Back_Minor > GV_TOPO_VER_MINOR) {
596  /* This version of GRASS lib is lower than the oldest which can read this format */
598  ("Topology format version %d.%d is not supported by this release."
599  " Try to rebuild topology or upgrade GRASS.",
600  ptr->Version_Major, ptr->Version_Minor);
601  return (-1);
602  }
603 
604  G_warning
605  ("Your GRASS version does not fully support topology format %d.%d of the vector."
606  " Consider to rebuild topology or upgrade GRASS.",
607  ptr->Version_Major, ptr->Version_Minor);
608  }
609 
610  dig_init_portable(&(ptr->port), byte_order);
611  dig_set_cur_port(&(ptr->port));
612 
613  /* bytes 6 - 9 : header size */
614  if (0 >= dig__fread_port_L(&(ptr->head_size), 1, fp))
615  return (-1);
616  G_debug(2, " header size %ld", ptr->head_size);
617 
618  /* byte 10 : dimension 2D or 3D */
619  if (0 >= dig__fread_port_C(buf, 1, fp))
620  return (-1);
621  ptr->with_z = buf[0];
622  G_debug(2, " with_z %d", ptr->with_z);
623 
624  /* bytes 11 - 58 : bound box */
625  if (0 >= dig__fread_port_D(&(ptr->box.N), 1, fp))
626  return (-1);
627  if (0 >= dig__fread_port_D(&(ptr->box.S), 1, fp))
628  return (-1);
629  if (0 >= dig__fread_port_D(&(ptr->box.E), 1, fp))
630  return (-1);
631  if (0 >= dig__fread_port_D(&(ptr->box.W), 1, fp))
632  return (-1);
633  if (0 >= dig__fread_port_D(&(ptr->box.T), 1, fp))
634  return (-1);
635  if (0 >= dig__fread_port_D(&(ptr->box.B), 1, fp))
636  return (-1);
637 
638  /* bytes 59 - 86 : number of structures */
639  if (0 >= dig__fread_port_P(&(ptr->n_nodes), 1, fp))
640  return (-1);
641  if (0 >= dig__fread_port_P(&(ptr->n_edges), 1, fp))
642  return (-1);
643  if (0 >= dig__fread_port_P(&(ptr->n_lines), 1, fp))
644  return (-1);
645  if (0 >= dig__fread_port_P(&(ptr->n_areas), 1, fp))
646  return (-1);
647  if (0 >= dig__fread_port_P(&(ptr->n_isles), 1, fp))
648  return (-1);
649  if (0 >= dig__fread_port_P(&(ptr->n_volumes), 1, fp))
650  return (-1);
651  if (0 >= dig__fread_port_P(&(ptr->n_holes), 1, fp))
652  return (-1);
653 
654  /* bytes 87 - 110 : number of line types */
655  if (0 >= dig__fread_port_P(&(ptr->n_plines), 1, fp))
656  return (-1);
657  if (0 >= dig__fread_port_P(&(ptr->n_llines), 1, fp))
658  return (-1);
659  if (0 >= dig__fread_port_P(&(ptr->n_blines), 1, fp))
660  return (-1);
661  if (0 >= dig__fread_port_P(&(ptr->n_clines), 1, fp))
662  return (-1);
663  if (0 >= dig__fread_port_P(&(ptr->n_flines), 1, fp))
664  return (-1);
665  if (0 >= dig__fread_port_P(&(ptr->n_klines), 1, fp))
666  return (-1);
667 
668  /* bytes 111 - 138 : Offset */
669  if (0 >= dig__fread_port_L(&(ptr->Node_offset), 1, fp))
670  return (-1);
671  if (0 >= dig__fread_port_L(&(ptr->Edge_offset), 1, fp))
672  return (-1);
673  if (0 >= dig__fread_port_L(&(ptr->Line_offset), 1, fp))
674  return (-1);
675  if (0 >= dig__fread_port_L(&(ptr->Area_offset), 1, fp))
676  return (-1);
677  if (0 >= dig__fread_port_L(&(ptr->Isle_offset), 1, fp))
678  return (-1);
679  if (0 >= dig__fread_port_L(&(ptr->Volume_offset), 1, fp))
680  return (-1);
681  if (0 >= dig__fread_port_L(&(ptr->Hole_offset), 1, fp))
682  return (-1);
683 
684  /* bytes 139 - 142 : Coor size and time */
685  if (0 >= dig__fread_port_L(&(ptr->coor_size), 1, fp))
686  return (-1);
687 
688  G_debug(2, " coor size %ld", ptr->coor_size);
689 
690  dig_fseek(fp, ptr->head_size, SEEK_SET);
691 
692  return (0);
693 }
694 
695 int dig_Wr_Plus_head(GVFILE * fp, struct Plus_head *ptr)
696 {
697  unsigned char buf[10];
698  long length = 142;
699 
700  dig_rewind(fp);
701  dig_set_cur_port(&(ptr->port));
702 
703  /* bytes 1 - 5 */
704  buf[0] = GV_TOPO_VER_MAJOR;
705  buf[1] = GV_TOPO_VER_MINOR;
706  buf[2] = GV_TOPO_EARLIEST_MAJOR;
707  buf[3] = GV_TOPO_EARLIEST_MINOR;
708  buf[4] = ptr->port.byte_order;
709  if (0 >= dig__fwrite_port_C(buf, 5, fp))
710  return (-1);
711 
712  /* bytes 6 - 9 : header size */
713  if (0 >= dig__fwrite_port_L(&length, 1, fp))
714  return (0);
715 
716  /* byte 10 : dimension 2D or 3D */
717  buf[0] = ptr->with_z;
718  if (0 >= dig__fwrite_port_C(buf, 1, fp))
719  return (0);
720 
721  /* bytes 11 - 58 : bound box */
722  if (0 >= dig__fwrite_port_D(&(ptr->box.N), 1, fp))
723  return (-1);
724  if (0 >= dig__fwrite_port_D(&(ptr->box.S), 1, fp))
725  return (-1);
726  if (0 >= dig__fwrite_port_D(&(ptr->box.E), 1, fp))
727  return (-1);
728  if (0 >= dig__fwrite_port_D(&(ptr->box.W), 1, fp))
729  return (-1);
730  if (0 >= dig__fwrite_port_D(&(ptr->box.T), 1, fp))
731  return (-1);
732  if (0 >= dig__fwrite_port_D(&(ptr->box.B), 1, fp))
733  return (-1);
734 
735  /* bytes 59 - 86 : number of structures */
736  if (0 >= dig__fwrite_port_P(&(ptr->n_nodes), 1, fp))
737  return (-1);
738  if (0 >= dig__fwrite_port_P(&(ptr->n_edges), 1, fp))
739  return (-1);
740  if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
741  return (-1);
742  if (0 >= dig__fwrite_port_P(&(ptr->n_areas), 1, fp))
743  return (-1);
744  if (0 >= dig__fwrite_port_P(&(ptr->n_isles), 1, fp))
745  return (-1);
746  if (0 >= dig__fwrite_port_P(&(ptr->n_volumes), 1, fp))
747  return (-1);
748  if (0 >= dig__fwrite_port_P(&(ptr->n_holes), 1, fp))
749  return (-1);
750 
751  /* bytes 87 - 110 : number of line types */
752  if (0 >= dig__fwrite_port_P(&(ptr->n_plines), 1, fp))
753  return (-1);
754  if (0 >= dig__fwrite_port_P(&(ptr->n_llines), 1, fp))
755  return (-1);
756  if (0 >= dig__fwrite_port_P(&(ptr->n_blines), 1, fp))
757  return (-1);
758  if (0 >= dig__fwrite_port_P(&(ptr->n_clines), 1, fp))
759  return (-1);
760  if (0 >= dig__fwrite_port_P(&(ptr->n_flines), 1, fp))
761  return (-1);
762  if (0 >= dig__fwrite_port_P(&(ptr->n_klines), 1, fp))
763  return (-1);
764 
765  /* bytes 111 - 138 : Offset */
766  if (0 >= dig__fwrite_port_L(&(ptr->Node_offset), 1, fp))
767  return (-1);
768  if (0 >= dig__fwrite_port_L(&(ptr->Edge_offset), 1, fp))
769  return (-1);
770  if (0 >= dig__fwrite_port_L(&(ptr->Line_offset), 1, fp))
771  return (-1);
772  if (0 >= dig__fwrite_port_L(&(ptr->Area_offset), 1, fp))
773  return (-1);
774  if (0 >= dig__fwrite_port_L(&(ptr->Isle_offset), 1, fp))
775  return (-1);
776  if (0 >= dig__fwrite_port_L(&(ptr->Volume_offset), 1, fp))
777  return (-1);
778  if (0 >= dig__fwrite_port_L(&(ptr->Hole_offset), 1, fp))
779  return (-1);
780 
781  /* bytes 139 - 142 : Coor size and time */
782  if (0 >= dig__fwrite_port_L(&(ptr->coor_size), 1, fp))
783  return (-1);
784 
785  G_debug(2, "topo body offset %ld", dig_ftell(fp));
786 
787  return (0);
788 }