GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
spindex_rw.c
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * MODULE: Vector library
5  *
6  * AUTHOR(S): Radim Blazek.
7  *
8  * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
9  *
10  * COPYRIGHT: (C) 2001 by the GRASS Development Team
11  *
12  * This program is free software under the GNU General Public
13  * License (>=v2). Read the file COPYING that comes with GRASS
14  * for details.
15  *
16  *****************************************************************************/
17 #include <stdlib.h>
18 #include <string.h>
19 #include <grass/gis.h>
20 #include <grass/Vect.h>
21 #include <grass/version.h>
22 
23 
24 int dig_Wr_spindx_head(GVFILE * fp, struct Plus_head *ptr)
25 {
26  unsigned char buf[5];
27  long length = 42;
28 
29  dig_rewind(fp);
30  dig_set_cur_port(&(ptr->spidx_port));
31 
32  /* bytes 1 - 5 */
33  buf[0] = GV_SIDX_VER_MAJOR;
34  buf[1] = GV_SIDX_VER_MINOR;
35  buf[2] = GV_SIDX_EARLIEST_MAJOR;
36  buf[3] = GV_SIDX_EARLIEST_MINOR;
37  buf[4] = ptr->spidx_port.byte_order;
38  if (0 >= dig__fwrite_port_C(buf, 5, fp))
39  return (-1);
40 
41  /* bytes 6 - 9 : header size */
42  if (0 >= dig__fwrite_port_L(&length, 1, fp))
43  return (0);
44 
45  /* byte 10 : dimension 2D or 3D */
46  buf[0] = ptr->spidx_with_z;
47  if (0 >= dig__fwrite_port_C(buf, 1, fp))
48  return (-1);
49 
50  /* bytes 11 - 38 : Offsets */
51  if (0 >= dig__fwrite_port_L(&(ptr->Node_spidx_offset), 1, fp))
52  return (-1);
53  if (0 >= dig__fwrite_port_L(&(ptr->Edge_spidx_offset), 1, fp))
54  return (-1);
55  if (0 >= dig__fwrite_port_L(&(ptr->Line_spidx_offset), 1, fp))
56  return (-1);
57  if (0 >= dig__fwrite_port_L(&(ptr->Area_spidx_offset), 1, fp))
58  return (-1);
59  if (0 >= dig__fwrite_port_L(&(ptr->Isle_spidx_offset), 1, fp))
60  return (-1);
61  if (0 >= dig__fwrite_port_L(&(ptr->Volume_spidx_offset), 1, fp))
62  return (-1);
63  if (0 >= dig__fwrite_port_L(&(ptr->Hole_spidx_offset), 1, fp))
64  return (-1);
65 
66  G_debug(3, "spidx offset node = %ld line = %ld, area = %ld isle = %ld",
67  ptr->Node_spidx_offset, ptr->Line_spidx_offset,
68  ptr->Area_spidx_offset, ptr->Isle_spidx_offset);
69 
70  /* bytes 39 - 42 : Offsets */
71  if (0 >= dig__fwrite_port_L(&(ptr->coor_size), 1, fp))
72  return (-1);
73 
74  G_debug(2, "spidx body offset %ld", dig_ftell(fp));
75 
76  return (0);
77 }
78 
79 
80 int dig_Rd_spindx_head(GVFILE * fp, struct Plus_head *ptr)
81 {
82  unsigned char buf[5];
83  int byte_order;
84  long coor_size;
85 
86  dig_rewind(fp);
87 
88  /* bytes 1 - 5 */
89  if (0 >= dig__fread_port_C(buf, 5, fp))
90  return (-1);
91  ptr->spidx_Version_Major = buf[0];
92  ptr->spidx_Version_Minor = buf[1];
93  ptr->spidx_Back_Major = buf[2];
94  ptr->spidx_Back_Minor = buf[3];
95  byte_order = buf[4];
96 
97  G_debug(2,
98  "Sidx header: file version %d.%d , supported from GRASS version %d.%d",
99  ptr->spidx_Version_Major, ptr->spidx_Version_Minor,
100  ptr->spidx_Back_Major, ptr->spidx_Back_Minor);
101 
102  G_debug(2, " byte order %d", byte_order);
103 
104  /* check version numbers */
105  if (ptr->spidx_Version_Major > GV_SIDX_VER_MAJOR ||
106  ptr->spidx_Version_Minor > GV_SIDX_VER_MINOR) {
107  /* The file was created by GRASS library with higher version than this one */
108 
109  if (ptr->spidx_Back_Major > GV_SIDX_VER_MAJOR ||
110  ptr->spidx_Back_Minor > GV_SIDX_VER_MINOR) {
111  /* This version of GRASS lib is lower than the oldest which can read this format */
112  G_debug(1, "Spatial index format version %d.%d",
113  ptr->spidx_Version_Major, ptr->spidx_Version_Minor);
115  ("This version of GRASS (%d.%d) is too old to read this spatial index format."
116  " Try to rebuild topology or upgrade GRASS to at least version %d.",
117  GRASS_VERSION_MAJOR, GRASS_VERSION_MINOR, GRASS_VERSION_MAJOR + 1);
118  return (-1);
119  }
120 
121  G_warning
122  ("Your GRASS version does not fully support spatial index format %d.%d of the vector."
123  " Consider to rebuild topology or upgrade GRASS.",
124  ptr->spidx_Version_Major, ptr->spidx_Version_Minor);
125  }
126 
127  dig_init_portable(&(ptr->spidx_port), byte_order);
128  dig_set_cur_port(&(ptr->spidx_port));
129 
130  /* bytes 6 - 9 : header size */
131  if (0 >= dig__fread_port_L(&(ptr->spidx_head_size), 1, fp))
132  return (-1);
133  G_debug(2, " header size %ld", ptr->spidx_head_size);
134 
135  /* byte 10 : dimension 2D or 3D */
136  if (0 >= dig__fread_port_C(buf, 1, fp))
137  return (-1);
138  ptr->spidx_with_z = buf[0];
139  G_debug(2, " with_z %d", ptr->spidx_with_z);
140 
141  /* bytes 11 - 38 : Offsets */
142  if (0 >= dig__fread_port_L(&(ptr->Node_spidx_offset), 1, fp))
143  return (-1);
144  if (0 >= dig__fread_port_L(&(ptr->Edge_spidx_offset), 1, fp))
145  return (-1);
146  if (0 >= dig__fread_port_L(&(ptr->Line_spidx_offset), 1, fp))
147  return (-1);
148  if (0 >= dig__fread_port_L(&(ptr->Area_spidx_offset), 1, fp))
149  return (-1);
150  if (0 >= dig__fread_port_L(&(ptr->Isle_spidx_offset), 1, fp))
151  return (-1);
152  if (0 >= dig__fread_port_L(&(ptr->Volume_spidx_offset), 1, fp))
153  return (-1);
154  if (0 >= dig__fread_port_L(&(ptr->Hole_spidx_offset), 1, fp))
155  return (-1);
156 
157  /* bytes 39 - 42 : Offsets */
158  if (0 >= dig__fread_port_L(&coor_size, 1, fp))
159  return (-1);
160  G_debug(2, " coor size %ld", coor_size);
161 
162  dig_fseek(fp, ptr->spidx_head_size, SEEK_SET);
163 
164  return (0);
165 }
166 
167 int rtree_dump_node(FILE * fp, struct Node *n, int with_z);
168 
169 /* Dump RTree branch to file */
170 int rtree_dump_branch(FILE * fp, struct Branch *b, int with_z, int level)
171 {
172  struct Rect *r;
173 
174  r = &(b->rect);
175 
176  if (level == 0)
177  fprintf(fp, " id = %d ", (int)b->child);
178 
179  fprintf(fp, " %f %f %f %f %f %f\n", r->boundary[0], r->boundary[1],
180  r->boundary[2], r->boundary[3], r->boundary[4], r->boundary[5]);
181 
182  if (level > 0) {
183  rtree_dump_node(fp, b->child, with_z);
184  }
185  return 0;
186 }
187 
188 /* Dump RTree node to file */
189 int rtree_dump_node(FILE * fp, struct Node *n, int with_z)
190 {
191  int i, nn;
192 
193  fprintf(fp, "Node level=%d count=%d\n", n->level, n->count);
194 
195  if (n->level > 0)
196  nn = NODECARD;
197  else
198  nn = LEAFCARD;
199 
200  for (i = 0; i < nn; i++) {
201  if (n->branch[i].child) {
202  fprintf(fp, " Branch %d", i);
203  rtree_dump_branch(fp, &n->branch[i], with_z, n->level);
204  }
205  }
206 
207  return 0;
208 }
209 
210 int rtree_write_node(GVFILE * fp, struct Node *n, int with_z);
211 
212 /* Write RTree branch to file */
213 int rtree_write_branch(GVFILE * fp, struct Branch *b, int with_z, int level)
214 {
215  struct Rect *r;
216  int i;
217 
218  r = &(b->rect);
219 
220  /* rectangle */
221  if (with_z) {
222  if (0 >= dig__fwrite_port_D(&(r->boundary[0]), 6, fp))
223  return (-1);
224  }
225  else {
226  if (0 >= dig__fwrite_port_D(&(r->boundary[0]), 2, fp))
227  return (-1);
228  if (0 >= dig__fwrite_port_D(&(r->boundary[3]), 2, fp))
229  return (-1);
230  }
231  if (level == 0) { /* write data (element id) */
232  i = (int)b->child;
233  if (0 >= dig__fwrite_port_I(&i, 1, fp))
234  return (-1);
235  }
236  else {
237  rtree_write_node(fp, b->child, with_z);
238  }
239  return 0;
240 }
241 
242 /* Write RTree node to file */
243 int rtree_write_node(GVFILE * fp, struct Node *n, int with_z)
244 {
245  int i, nn;
246 
247  /* level ( 0 = leaf, data ) */
248  if (0 >= dig__fwrite_port_I(&(n->level), 1, fp))
249  return (-1);
250 
251  /* count */
252  if (0 >= dig__fwrite_port_I(&(n->count), 1, fp))
253  return (-1);
254 
255  if (n->level > 0)
256  nn = NODECARD;
257  else
258  nn = LEAFCARD;
259  for (i = 0; i < nn; i++) {
260  if (n->branch[i].child) {
261  rtree_write_branch(fp, &n->branch[i], with_z, n->level);
262  }
263  }
264 
265  return 0;
266 }
267 
268 int rtree_read_node(GVFILE * fp, struct Node *n, int with_z);
269 
270 /* Read RTree branch from file */
271 int rtree_read_branch(GVFILE * fp, struct Branch *b, int with_z, int level)
272 {
273  struct Rect *r;
274  int i;
275 
276  G_debug(3, "rtree_read_branch()");
277 
278  r = &(b->rect);
279 
280  /* rectangle */
281  if (with_z) {
282  if (0 >= dig__fread_port_D(&(r->boundary[0]), 6, fp))
283  return (-1);
284  }
285  else {
286  if (0 >= dig__fread_port_D(&(r->boundary[0]), 2, fp))
287  return (-1);
288  if (0 >= dig__fread_port_D(&(r->boundary[3]), 2, fp))
289  return (-1);
290  r->boundary[2] = 0;
291  r->boundary[5] = 0;
292  }
293 
294  if (level == 0) { /* read data (element id) */
295  if (0 >= dig__fread_port_I(&i, 1, fp))
296  return (-1);
297  b->child = (struct Node *)i;
298  }
299  else {
300  /* create new node */
301  b->child = RTreeNewNode();
302  rtree_read_node(fp, b->child, with_z);
303  }
304  return 0;
305 }
306 
307 /* Read RTree node to file */
308 int rtree_read_node(GVFILE * fp, struct Node *n, int with_z)
309 {
310  int level, count, i;
311 
312  G_debug(3, "rtree_read_node()");
313 
314  /* level ( 0 = leaf, data ) */
315  if (0 >= dig__fread_port_I(&level, 1, fp))
316  return (-1);
317  n->level = level;
318 
319  /* count */
320  if (0 >= dig__fread_port_I(&count, 1, fp))
321  return (-1);
322  n->count = count;
323 
324  for (i = 0; i < count; i++) {
325  if (0 > rtree_read_branch(fp, &n->branch[i], with_z, level))
326  return (-1);
327  }
328 
329  return 0;
330 }
331 
332 /* Write spatial index */
333 int dig_write_spidx(GVFILE * fp, struct Plus_head *Plus)
334 {
335  dig_set_cur_port(&(Plus->spidx_port));
336  dig_rewind(fp);
337 
338  dig_Wr_spindx_head(fp, Plus);
339 
340  Plus->Node_spidx_offset = dig_ftell(fp);
341  rtree_write_node(fp, Plus->Node_spidx, Plus->with_z);
342 
343  Plus->Line_spidx_offset = dig_ftell(fp);
344  rtree_write_node(fp, Plus->Line_spidx, Plus->with_z);
345 
346  Plus->Area_spidx_offset = dig_ftell(fp);
347  rtree_write_node(fp, Plus->Area_spidx, Plus->with_z);
348 
349  Plus->Isle_spidx_offset = dig_ftell(fp);
350  rtree_write_node(fp, Plus->Isle_spidx, Plus->with_z);
351 
352  dig_rewind(fp);
353  dig_Wr_spindx_head(fp, Plus); /* rewrite with offsets */
354 
355  return 0;
356 }
357 
358 /* Read spatial index file */
359 int dig_read_spidx(GVFILE * fp, struct Plus_head *Plus)
360 {
361  G_debug(1, "dig_read_spindx()");
362 
363  /* TODO: free old tree */
364  dig_spidx_init(Plus);
365 
366  dig_rewind(fp);
367  dig_Rd_spindx_head(fp, Plus);
368  dig_set_cur_port(&(Plus->spidx_port));
369 
370  dig_fseek(fp, Plus->Node_spidx_offset, 0);
371  rtree_read_node(fp, Plus->Node_spidx, Plus->with_z);
372 
373  dig_fseek(fp, Plus->Line_spidx_offset, 0);
374  rtree_read_node(fp, Plus->Line_spidx, Plus->with_z);
375 
376  dig_fseek(fp, Plus->Area_spidx_offset, 0);
377  rtree_read_node(fp, Plus->Area_spidx, Plus->with_z);
378 
379  dig_fseek(fp, Plus->Isle_spidx_offset, 0);
380  rtree_read_node(fp, Plus->Isle_spidx, Plus->with_z);
381 
382  return 0;
383 }
384 
385 /* Dump spatial index */
386 int dig_dump_spidx(FILE * fp, struct Plus_head *Plus)
387 {
388 
389  fprintf(fp, "Nodes\n");
390  rtree_dump_node(fp, Plus->Node_spidx, Plus->with_z);
391 
392  fprintf(fp, "Lines\n");
393  rtree_dump_node(fp, Plus->Line_spidx, Plus->with_z);
394 
395  fprintf(fp, "Areas\n");
396  rtree_dump_node(fp, Plus->Area_spidx, Plus->with_z);
397 
398  fprintf(fp, "Isles\n");
399  rtree_dump_node(fp, Plus->Isle_spidx, Plus->with_z);
400 
401  return 0;
402 }
int rtree_read_branch(GVFILE *fp, struct Branch *b, int with_z, int level)
Definition: spindex_rw.c:271
RectReal boundary[NUMSIDES]
Definition: index.h:42
int dig_dump_spidx(FILE *fp, struct Plus_head *Plus)
Definition: spindex_rw.c:386
float b
Definition: named_colr.c:8
int rtree_write_node(GVFILE *fp, struct Node *n, int with_z)
Definition: spindex_rw.c:243
int dig_set_cur_port(struct Port_info *port)
Definition: portable.c:640
struct Node * child
Definition: index.h:50
int dig_Wr_spindx_head(GVFILE *fp, struct Plus_head *ptr)
Definition: spindex_rw.c:24
struct Rect rect
Definition: index.h:49
float r
Definition: named_colr.c:8
int dig_spidx_init(struct Plus_head *Plus)
Initit spatial index (nodes, lines, areas, isles)
Definition: spindex.c:31
Definition: index.h:56
int dig__fwrite_port_D(double *buf, int cnt, GVFILE *fp)
Definition: portable.c:370
int count
int rtree_write_branch(GVFILE *fp, struct Branch *b, int with_z, int level)
Definition: spindex_rw.c:213
void dig_init_portable(struct Port_info *port, int byte_order)
Definition: portable.c:568
int dig__fread_port_L(long *buf, int cnt, GVFILE *fp)
Definition: portable.c:137
Definition: index.h:47
int dig__fwrite_port_I(int *buf, int cnt, GVFILE *fp)
Definition: portable.c:465
struct Node * RTreeNewNode(void)
Definition: node.c:44
int dig_fseek(GVFILE *file, long offset, int whence)
Set GVFILE position.
Definition: file.c:60
int dig_Rd_spindx_head(GVFILE *fp, struct Plus_head *ptr)
Definition: spindex_rw.c:80
int dig_read_spidx(GVFILE *fp, struct Plus_head *Plus)
Definition: spindex_rw.c:359
int dig__fwrite_port_L(long *buf, int cnt, GVFILE *fp)
Definition: portable.c:422
int
Definition: g3dcolor.c:48
int dig__fread_port_D(double *buf, int cnt, GVFILE *fp)
Definition: portable.c:75
if(!YY_CURRENT_BUFFER)
Definition: lex.yy.c:799
int dig_write_spidx(GVFILE *fp, struct Plus_head *Plus)
Definition: spindex_rw.c:333
int LEAFCARD
Definition: card.c:22
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int dig__fread_port_C(char *buf, int cnt, GVFILE *fp)
Definition: portable.c:347
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int count
Definition: index.h:58
int rtree_dump_node(FILE *fp, struct Node *n, int with_z)
Definition: spindex_rw.c:189
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
void dig_rewind(GVFILE *file)
Rewind GVFILE position.
Definition: file.c:85
int NODECARD
Definition: card.c:21
int level
Definition: index.h:59
int dig__fwrite_port_C(char *buf, int cnt, GVFILE *fp)
Definition: portable.c:558
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int rtree_read_node(GVFILE *fp, struct Node *n, int with_z)
Definition: spindex_rw.c:308
Definition: index.h:40
long dig_ftell(GVFILE *file)
Get GVFILE position.
Definition: file.c:36
int n
Definition: dataquad.c:291
struct Branch branch[MAXCARD]
Definition: index.h:60
int dig__fread_port_I(int *buf, int cnt, GVFILE *fp)
Definition: portable.c:207
int rtree_dump_branch(FILE *fp, struct Branch *b, int with_z, int level)
Definition: spindex_rw.c:170