00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <grass/gis.h>
00022 #include <grass/Vect.h>
00023
00024
00025 int
00026 dig_Wr_spindx_head ( GVFILE * fp,
00027 struct Plus_head *ptr)
00028 {
00029 unsigned char buf[5];
00030 long length = 42;
00031
00032 dig_rewind (fp);
00033 dig_set_cur_port (&(ptr->spidx_port));
00034
00035
00036 buf[0] = GV_SIDX_VER_MAJOR;
00037 buf[1] = GV_SIDX_VER_MINOR;
00038 buf[2] = GV_SIDX_EARLIEST_MAJOR;
00039 buf[3] = GV_SIDX_EARLIEST_MINOR;
00040 buf[4] = ptr->spidx_port.byte_order;
00041 if (0 >= dig__fwrite_port_C (buf, 5, fp)) return (-1);
00042
00043
00044 if (0 >= dig__fwrite_port_L ( &length, 1, fp)) return (0);
00045
00046
00047 buf[0] = ptr->spidx_with_z;
00048 if (0 >= dig__fwrite_port_C (buf, 1, fp)) return (-1);
00049
00050
00051 if (0 >= dig__fwrite_port_L (&(ptr->Node_spidx_offset), 1, fp)) return (-1);
00052 if (0 >= dig__fwrite_port_L (&(ptr->Edge_spidx_offset), 1, fp)) return (-1);
00053 if (0 >= dig__fwrite_port_L (&(ptr->Line_spidx_offset), 1, fp)) return (-1);
00054 if (0 >= dig__fwrite_port_L (&(ptr->Area_spidx_offset), 1, fp)) return (-1);
00055 if (0 >= dig__fwrite_port_L (&(ptr->Isle_spidx_offset), 1, fp)) return (-1);
00056 if (0 >= dig__fwrite_port_L (&(ptr->Volume_spidx_offset), 1, fp)) return (-1);
00057 if (0 >= dig__fwrite_port_L (&(ptr->Hole_spidx_offset), 1, fp)) return (-1);
00058
00059 G_debug (3, "spidx offset node = %d line = %d, area = %d isle = %d", ptr->Node_spidx_offset,
00060 ptr->Line_spidx_offset, ptr->Area_spidx_offset, ptr->Isle_spidx_offset);
00061
00062
00063 if (0 >= dig__fwrite_port_L (&(ptr->coor_size), 1, fp)) return (-1);
00064
00065 G_debug (2, "spidx body offset %d", dig_ftell( fp) );
00066
00067 return (0);
00068 }
00069
00070
00071 int
00072 dig_Rd_spindx_head ( GVFILE * fp,
00073 struct Plus_head *ptr)
00074 {
00075 unsigned char buf[5];
00076 int byte_order;
00077 long coor_size;
00078
00079 dig_rewind (fp);
00080
00081
00082 if (0 >= dig__fread_port_C (buf, 5, fp)) return (-1);
00083 ptr->spidx_Version_Major = buf[0];
00084 ptr->spidx_Version_Minor = buf[1];
00085 ptr->spidx_Back_Major = buf[2];
00086 ptr->spidx_Back_Minor = buf[3];
00087 byte_order = buf[4];
00088
00089 G_debug (2, "Sidx header: file version %d.%d , supported from GRASS version %d.%d",
00090 ptr->spidx_Version_Major, ptr->spidx_Version_Minor,
00091 ptr->spidx_Back_Major, ptr->spidx_Back_Minor );
00092
00093 G_debug (2, " byte order %d", byte_order );
00094
00095
00096 if ( ptr->spidx_Version_Major > GV_SIDX_VER_MAJOR || ptr->spidx_Version_Minor > GV_SIDX_VER_MINOR ) {
00097
00098
00099 if ( ptr->spidx_Back_Major > GV_SIDX_VER_MAJOR || ptr->spidx_Back_Minor > GV_SIDX_VER_MINOR ) {
00100
00101 G_fatal_error ( "Spatial index format version %d.%d is not supported by this release."
00102 " Try to rebuild topology or upgrade GRASS.",
00103 ptr->spidx_Version_Major, ptr->spidx_Version_Minor);
00104 return (-1);
00105 }
00106
00107 G_warning ( "Your GRASS version does not fully support spatial index format %d.%d of the vector."
00108 " Consider to rebuild topology or upgrade GRASS.",
00109 ptr->spidx_Version_Major, ptr->spidx_Version_Minor );
00110 }
00111
00112 dig_init_portable ( &(ptr->spidx_port), byte_order);
00113 dig_set_cur_port ( &(ptr->spidx_port) );
00114
00115
00116 if (0 >= dig__fread_port_L (&(ptr->spidx_head_size), 1, fp)) return (-1);
00117 G_debug (2, " header size %d", ptr->spidx_head_size );
00118
00119
00120 if (0 >= dig__fread_port_C (buf, 1, fp)) return (-1);
00121 ptr->spidx_with_z = buf[0];
00122 G_debug (2, " with_z %d", ptr->spidx_with_z );
00123
00124
00125 if (0 >= dig__fread_port_L (&(ptr->Node_spidx_offset), 1, fp)) return (-1);
00126 if (0 >= dig__fread_port_L (&(ptr->Edge_spidx_offset), 1, fp)) return (-1);
00127 if (0 >= dig__fread_port_L (&(ptr->Line_spidx_offset), 1, fp)) return (-1);
00128 if (0 >= dig__fread_port_L (&(ptr->Area_spidx_offset), 1, fp)) return (-1);
00129 if (0 >= dig__fread_port_L (&(ptr->Isle_spidx_offset), 1, fp)) return (-1);
00130 if (0 >= dig__fread_port_L (&(ptr->Volume_spidx_offset), 1, fp)) return (-1);
00131 if (0 >= dig__fread_port_L (&(ptr->Hole_spidx_offset), 1, fp)) return (-1);
00132
00133
00134 if (0 >= dig__fread_port_L (&coor_size, 1, fp)) return (-1);
00135 G_debug (2, " coor size %d", coor_size );
00136
00137 dig_fseek ( fp, ptr->spidx_head_size, SEEK_SET );
00138
00139 return (0);
00140 }
00141
00142 int rtree_dump_node( FILE *fp, struct Node *n, int with_z);
00143
00144
00145 int rtree_dump_branch( FILE *fp, struct Branch *b, int with_z, int level)
00146 {
00147 struct Rect *r;
00148
00149 r = &(b->rect);
00150
00151 if ( level == 0 )
00152 fprintf ( fp, " id = %d ", (int)b->child);
00153
00154 fprintf ( fp, " %f %f %f %f %f %f\n", r->boundary[0], r->boundary[1], r->boundary[2],
00155 r->boundary[3], r->boundary[4], r->boundary[5]);
00156
00157 if ( level > 0 ) {
00158 rtree_dump_node( fp, b->child, with_z);
00159 }
00160 return 0;
00161 }
00162
00163
00164 int rtree_dump_node( FILE *fp, struct Node *n, int with_z)
00165 {
00166 int i, nn;
00167
00168 fprintf (fp, "Node level=%d count=%d\n", n->level, n->count );
00169
00170 if ( n->level > 0 ) nn = NODECARD; else nn = LEAFCARD;
00171
00172 for (i = 0; i < nn; i++) {
00173 if ( n->branch[i].child ) {
00174 fprintf (fp, " Branch %d", i );
00175 rtree_dump_branch( fp, &n->branch[i], with_z, n->level );
00176 }
00177 }
00178
00179 return 0;
00180 }
00181
00182 int rtree_write_node( GVFILE *fp, struct Node *n, int with_z);
00183
00184
00185 int rtree_write_branch( GVFILE *fp, struct Branch *b, int with_z, int level)
00186 {
00187 struct Rect *r;
00188 int i;
00189
00190 r = &(b->rect);
00191
00192
00193 if ( with_z ) {
00194 if (0 >= dig__fwrite_port_D (&(r->boundary[0]), 6, fp)) return (-1);
00195 } else {
00196 if (0 >= dig__fwrite_port_D (&(r->boundary[0]), 2, fp)) return (-1);
00197 if (0 >= dig__fwrite_port_D (&(r->boundary[3]), 2, fp)) return (-1);
00198 }
00199 if ( level == 0 ) {
00200 i = (int) b->child;
00201 if (0 >= dig__fwrite_port_I ( &i, 1, fp)) return (-1);
00202 } else {
00203 rtree_write_node( fp, b->child, with_z);
00204 }
00205 return 0;
00206 }
00207
00208
00209 int rtree_write_node( GVFILE *fp, struct Node *n, int with_z)
00210 {
00211 int i, nn;
00212
00213
00214 if (0 >= dig__fwrite_port_I ( &(n->level), 1, fp)) return (-1);
00215
00216
00217 if (0 >= dig__fwrite_port_I ( &(n->count), 1, fp)) return (-1);
00218
00219 if ( n->level > 0 ) nn = NODECARD; else nn = LEAFCARD;
00220 for ( i = 0; i < nn; i++) {
00221 if ( n->branch[i].child ) {
00222 rtree_write_branch( fp, &n->branch[i], with_z, n->level );
00223 }
00224 }
00225
00226 return 0;
00227 }
00228
00229 int rtree_read_node( GVFILE *fp, struct Node *n, int with_z);
00230
00231
00232 int rtree_read_branch( GVFILE *fp, struct Branch *b, int with_z, int level)
00233 {
00234 struct Rect *r;
00235 int i;
00236
00237 G_debug (3, "rtree_read_branch()");
00238
00239 r = &(b->rect);
00240
00241
00242 if ( with_z ) {
00243 if (0 >= dig__fread_port_D (&(r->boundary[0]), 6, fp)) return (-1);
00244 } else {
00245 if (0 >= dig__fread_port_D (&(r->boundary[0]), 2, fp)) return (-1);
00246 if (0 >= dig__fread_port_D (&(r->boundary[3]), 2, fp)) return (-1);
00247 r->boundary[2] = 0;
00248 r->boundary[5] = 0;
00249 }
00250
00251 if ( level == 0 ) {
00252 if (0 >= dig__fread_port_I ( &i, 1, fp)) return (-1);
00253 b->child = (struct Node *) i;
00254 } else {
00255
00256 b->child = RTreeNewNode();
00257 rtree_read_node( fp, b->child, with_z);
00258 }
00259 return 0;
00260 }
00261
00262
00263 int rtree_read_node( GVFILE *fp, struct Node *n, int with_z)
00264 {
00265 int level, count, i;
00266
00267 G_debug (3, "rtree_read_node()");
00268
00269
00270 if (0 >= dig__fread_port_I ( &level, 1, fp)) return (-1);
00271 n->level = level;
00272
00273
00274 if (0 >= dig__fread_port_I ( &count, 1, fp)) return (-1);
00275 n->count = count;
00276
00277 for (i=0; i<count; i++) {
00278 if ( 0 > rtree_read_branch( fp, &n->branch[i], with_z, level ) ) return (-1);
00279 }
00280
00281 return 0;
00282 }
00283
00284
00285 int
00286 dig_write_spidx ( GVFILE * fp, struct Plus_head *Plus)
00287 {
00288 dig_set_cur_port(&(Plus->spidx_port));
00289 dig_rewind (fp);
00290
00291 dig_Wr_spindx_head ( fp, Plus );
00292
00293 Plus->Node_spidx_offset = dig_ftell ( fp );
00294 rtree_write_node( fp, Plus->Node_spidx, Plus->with_z);
00295
00296 Plus->Line_spidx_offset = dig_ftell ( fp );
00297 rtree_write_node( fp, Plus->Line_spidx, Plus->with_z);
00298
00299 Plus->Area_spidx_offset = dig_ftell ( fp );
00300 rtree_write_node( fp, Plus->Area_spidx, Plus->with_z);
00301
00302 Plus->Isle_spidx_offset = dig_ftell ( fp );
00303 rtree_write_node( fp, Plus->Isle_spidx, Plus->with_z);
00304
00305 dig_rewind (fp);
00306 dig_Wr_spindx_head ( fp, Plus );
00307
00308 return 0;
00309 }
00310
00311
00312 int
00313 dig_read_spidx ( GVFILE * fp, struct Plus_head *Plus)
00314 {
00315 G_debug (1, "dig_read_spindx()");
00316
00317
00318 dig_spidx_init ( Plus);
00319
00320 dig_rewind (fp);
00321 dig_Rd_spindx_head ( fp, Plus);
00322 dig_set_cur_port(&(Plus->spidx_port));
00323
00324 dig_fseek ( fp, Plus->Node_spidx_offset, 0);
00325 rtree_read_node( fp, Plus->Node_spidx, Plus->with_z);
00326
00327 dig_fseek ( fp, Plus->Line_spidx_offset, 0);
00328 rtree_read_node( fp, Plus->Line_spidx, Plus->with_z);
00329
00330 dig_fseek ( fp, Plus->Area_spidx_offset, 0);
00331 rtree_read_node( fp, Plus->Area_spidx, Plus->with_z);
00332
00333 dig_fseek ( fp, Plus->Isle_spidx_offset, 0);
00334 rtree_read_node( fp, Plus->Isle_spidx, Plus->with_z);
00335
00336 return 0;
00337 }
00338
00339
00340 int
00341 dig_dump_spidx ( FILE * fp, struct Plus_head *Plus)
00342 {
00343
00344 fprintf ( fp, "Nodes\n");
00345 rtree_dump_node( fp, Plus->Node_spidx, Plus->with_z);
00346
00347 fprintf ( fp, "Lines\n");
00348 rtree_dump_node( fp, Plus->Line_spidx, Plus->with_z);
00349
00350 fprintf ( fp, "Areas\n");
00351 rtree_dump_node( fp, Plus->Area_spidx, Plus->with_z);
00352
00353 fprintf ( fp, "Isles\n");
00354 rtree_dump_node( fp, Plus->Isle_spidx, Plus->with_z);
00355
00356 return 0;
00357 }
00358