spindex_rw.c

Go to the documentation of this file.
00001 /*
00002 * $Id: spindex_rw.c,v 1.5 2006/02/09 03:08:58 glynn Exp $
00003 *
00004 ****************************************************************************
00005 *
00006 * MODULE:       Vector library 
00007 *               
00008 * AUTHOR(S):    Radim Blazek.
00009 *
00010 * PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
00011 *
00012 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00013 *
00014 *               This program is free software under the GNU General Public
00015 *               License (>=v2). Read the file COPYING that comes with GRASS
00016 *               for details.
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   /* bytes 1 - 5 */
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   /* bytes 6 - 9 : header size */
00044   if (0 >= dig__fwrite_port_L ( &length, 1, fp)) return (0);
00045   
00046   /* byte 10 : dimension 2D or 3D */
00047   buf[0] = ptr->spidx_with_z; 
00048   if (0 >= dig__fwrite_port_C (buf, 1, fp)) return (-1);
00049  
00050   /* bytes 11 - 38 : Offsets */
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   /* bytes 39 - 42 : Offsets */
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   /* bytes 1 - 5 */
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   /* check version numbers */
00096   if ( ptr->spidx_Version_Major > GV_SIDX_VER_MAJOR || ptr->spidx_Version_Minor > GV_SIDX_VER_MINOR ) {
00097       /* The file was created by GRASS library with higher version than this one */
00098       
00099       if ( ptr->spidx_Back_Major > GV_SIDX_VER_MAJOR || ptr->spidx_Back_Minor > GV_SIDX_VER_MINOR ) {
00100           /* This version of GRASS lib is lower than the oldest which can read this format */
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   /* bytes 6 - 9 : header size */
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   /* byte 10 : dimension 2D or 3D */ 
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   /* bytes 11 - 38 : Offsets */
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   /* bytes 39 - 42 : Offsets */
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 /* Dump RTree branch to file */
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 /* Dump RTree node to file */
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 /* Write RTree branch to file */
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     /* rectangle */
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 ) { /* write data (element id) */
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 /* Write RTree node to file */
00209 int rtree_write_node( GVFILE *fp, struct Node *n, int with_z)
00210 {
00211     int i, nn;
00212 
00213     /* level ( 0 = leaf, data ) */
00214     if (0 >= dig__fwrite_port_I ( &(n->level), 1, fp)) return (-1);
00215 
00216     /* count */
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 /* Read RTree branch from file */
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     /* rectangle */
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 ) { /* read data (element id) */
00252         if (0 >= dig__fread_port_I ( &i, 1, fp)) return (-1);
00253         b->child = (struct Node *) i;
00254     } else {
00255         /* create new node */
00256         b->child = RTreeNewNode();
00257         rtree_read_node( fp, b->child, with_z);
00258     }
00259     return 0;
00260 }
00261 
00262 /* Read RTree node to file */
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     /* level ( 0 = leaf, data ) */
00270     if (0 >= dig__fread_port_I ( &level, 1, fp)) return (-1);
00271     n->level = level;
00272 
00273     /* count */
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 /* Write spatial index */
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 ); /* rewrite with offsets */
00307 
00308     return 0; 
00309 }
00310 
00311 /* Read spatial index file */
00312 int
00313 dig_read_spidx ( GVFILE * fp, struct Plus_head *Plus)
00314 {
00315     G_debug (1, "dig_read_spindx()");
00316 
00317     /* TODO: free old tree */
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 /* Dump spatial index */
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 

Generated on Sun Apr 6 17:32:44 2008 for GRASS by  doxygen 1.5.5