cindex_rw.c

Go to the documentation of this file.
00001 /****************************************************************************
00002 *
00003 * MODULE:       Vector library 
00004 *               
00005 * AUTHOR(S):    Radim Blazek.
00006 *
00007 * PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
00008 *
00009 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00010 *
00011 *               This program is free software under the GNU General Public
00012 *               License (>=v2). Read the file COPYING that comes with GRASS
00013 *               for details.
00014 *
00015 *****************************************************************************/
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <grass/gis.h>
00019 #include <grass/Vect.h>
00020 
00021 int 
00022 dig_write_cidx_head ( GVFILE * fp, struct Plus_head *plus)
00023 {
00024     int i;
00025     unsigned char buf[5];
00026     long length = 9;
00027 
00028     G_debug (3, "dig_write_cidx_head()" );
00029 
00030     dig_rewind (fp);
00031     dig_set_cur_port (&(plus->cidx_port));
00032 
00033     /* Head of header */
00034     /* bytes 1 - 5 */
00035     buf[0] = GV_CIDX_VER_MAJOR;
00036     buf[1] = GV_CIDX_VER_MINOR;
00037     buf[2] = GV_CIDX_EARLIEST_MAJOR;
00038     buf[3] = GV_CIDX_EARLIEST_MINOR;
00039     buf[4] = plus->cidx_port.byte_order;
00040     if (0 >= dig__fwrite_port_C (buf, 5, fp)) return (-1);
00041 
00042     /* bytes 6 - 9 : header size */
00043     if (0 >= dig__fwrite_port_L ( &length, 1, fp)) return (0);
00044 
00045     /* Body of header - info about all fields */
00046     /* Number of fields */
00047     if (0 >= dig__fwrite_port_I ( &(plus->n_cidx), 1, fp)) return (-1);
00048 
00049     for ( i = 0; i < plus->n_cidx; i++ ) {
00050         int t;
00051         struct Cat_index *ci;
00052 
00053         ci = &(plus->cidx[i]);
00054     
00055         G_debug (3, "cidx %d head offset: %d", i, dig_ftell( fp) );
00056 
00057         /* Field number */
00058         if (0 >= dig__fwrite_port_I ( &(ci->field), 1, fp)) return (-1);
00059 
00060         /* Number of categories */
00061         if (0 >= dig__fwrite_port_I ( &(ci->n_cats), 1, fp)) return (-1);
00062         
00063         /* Number of unique categories */
00064         if (0 >= dig__fwrite_port_I ( &(ci->n_ucats), 1, fp)) return (-1);
00065 
00066         /* Number of types */
00067         if (0 >= dig__fwrite_port_I ( &(ci->n_types), 1, fp)) return (-1);
00068 
00069         /* Types */
00070         for ( t = 0; t < ci->n_types; t++ ) {
00071             int wtype;
00072             
00073             /* type */
00074             wtype = dig_type_to_store ( ci->type[t][0] );
00075             if (0 >= dig__fwrite_port_I ( &wtype, 1, fp)) return (-1);
00076 
00077             /* number of items */
00078             if (0 >= dig__fwrite_port_I ( &(ci->type[t][1]), 1, fp)) return (-1);
00079 
00080         }
00081 
00082         /* Offset */
00083         if (0 >= dig__fwrite_port_L ( &(ci->offset), 1, fp)) return (0);
00084         G_debug (3, "cidx %d offset: %d", i, ci->offset);
00085     }
00086 
00087     G_debug (3, "cidx body offset %d", dig_ftell( fp) );
00088 
00089     return (0);
00090 }
00091 
00092 /* return: 0 OK, -1 error */
00093 int 
00094 dig_read_cidx_head (   GVFILE * fp, struct Plus_head *plus)
00095 {
00096     unsigned char buf[5];
00097     int i, byte_order;
00098 
00099     dig_rewind (fp);
00100 
00101     /* bytes 1 - 5 */
00102     if (0 >= dig__fread_port_C (buf, 5, fp))  return (-1);
00103     plus->cidx_Version_Major = buf[0];
00104     plus->cidx_Version_Minor = buf[1];
00105     plus->cidx_Back_Major    = buf[2];
00106     plus->cidx_Back_Minor    = buf[3];
00107     byte_order               = buf[4];
00108 
00109     G_debug (3, "Cidx header: file version %d.%d , supported from GRASS version %d.%d", 
00110                 plus->cidx_Version_Major, plus->cidx_Version_Minor,
00111                 plus->cidx_Back_Major, plus->cidx_Back_Minor );
00112 
00113     G_debug (3, "  byte order %d", byte_order );
00114 
00115     /* check version numbers */
00116     if ( plus->cidx_Version_Major > GV_CIDX_VER_MAJOR || plus->cidx_Version_Minor > GV_CIDX_VER_MINOR ) {
00117       /* The file was created by GRASS library with higher version than this one */
00118 
00119         if ( plus->cidx_Back_Major > GV_CIDX_VER_MAJOR || plus->cidx_Back_Minor > GV_CIDX_VER_MINOR ) {
00120           /* This version of GRASS lib is lower than the oldest which can read this format */     
00121           G_fatal_error ( "Category index format version %d.%d is not supported by this release."
00122                           " Try to rebuild topology or upgrade GRASS.", 
00123                            plus->cidx_Version_Major, plus->cidx_Version_Minor);
00124           return (-1);
00125       }
00126 
00127       G_warning ( "Your GRASS version does not fully support category index format %d.%d of the vector."
00128                   " Consider to rebuild topology or upgrade GRASS.",
00129                       plus->cidx_Version_Major, plus->cidx_Version_Minor );
00130     }
00131 
00132     dig_init_portable ( &(plus->cidx_port), byte_order);
00133     dig_set_cur_port ( &(plus->cidx_port) );
00134 
00135     /* bytes 6 - 9 : header size */
00136     if (0 >= dig__fread_port_L (&(plus->cidx_head_size), 1, fp)) return (-1);
00137     G_debug (3, "  header size %d", plus->cidx_head_size );
00138 
00139     /* Body of header - info about all fields */
00140     /* Number of fields */
00141     if (0 >= dig__fread_port_I ( &(plus->n_cidx), 1, fp)) return (-1);
00142     
00143     /* alloc space */
00144     plus->a_cidx = plus->n_cidx;
00145     plus->cidx = (struct Cat_index*) G_malloc(  plus->a_cidx * sizeof( struct Cat_index ) );
00146 
00147     for ( i = 0; i < plus->n_cidx; i++ ) {
00148         int t;
00149         struct Cat_index *ci;
00150 
00151         ci = &(plus->cidx[i]);
00152         ci->cat = NULL;
00153         ci->a_cats = 0;
00154 
00155         /* Field number */
00156         if (0 >= dig__fread_port_I ( &(ci->field), 1, fp)) return (-1);
00157 
00158         /* Number of categories */
00159         if (0 >= dig__fread_port_I ( &(ci->n_cats), 1, fp)) return (-1);
00160         
00161         /* Number of unique categories */
00162         if (0 >= dig__fread_port_I ( &(ci->n_ucats), 1, fp)) return (-1);
00163 
00164         /* Number of types */
00165         if (0 >= dig__fread_port_I ( &(ci->n_types), 1, fp)) return (-1);
00166 
00167         /* Types */
00168         for ( t = 0; t < ci->n_types; t++ ) {
00169             int rtype;
00170             
00171             /* type */
00172             if (0 >= dig__fread_port_I ( &rtype, 1, fp)) return (-1);
00173             ci->type[t][0] = dig_type_from_store ( rtype );
00174 
00175             /* number of items */
00176             if (0 >= dig__fread_port_I ( &(ci->type[t][1]), 1, fp)) return (-1);
00177         }
00178 
00179         /* Offset */
00180         if (0 >= dig__fread_port_L ( &(ci->offset), 1, fp)) return (0);
00181     }
00182 
00183     if ( dig_fseek ( fp, plus->cidx_head_size, SEEK_SET ) == -1 ) return (-1);
00184 
00185     return (0);
00186 }
00187 
00188 /* Write spatial index */
00189 int
00190 dig_write_cidx ( GVFILE * fp, struct Plus_head *plus)
00191 {
00192     int i;
00193 
00194     dig_set_cur_port(&(plus->cidx_port));
00195     dig_rewind (fp);
00196 
00197     dig_write_cidx_head ( fp, plus );
00198 
00199     /* Write category-type-id for each field */ 
00200     for ( i = 0; i < plus->n_cidx; i++ ) {
00201         int j;
00202         struct Cat_index *ci;
00203 
00204         ci = &(plus->cidx[i]);
00205         ci->offset = dig_ftell ( fp );
00206 
00207         /* convert type  */
00208         for ( j = 0; j < ci->n_cats; j++ )
00209             ci->cat[j][1] = dig_type_to_store ( ci->cat[j][1] );
00210         
00211         if (0 >= dig__fwrite_port_I ( (int *)ci->cat, 3 * ci->n_cats, fp)) return (-1);
00212 
00213         /* Return back */
00214         for ( j = 0; j < ci->n_cats; j++ )
00215             ci->cat[j][1] = dig_type_from_store ( ci->cat[j][1] );
00216     }
00217 
00218     dig_write_cidx_head ( fp, plus ); /* rewrite with offsets */
00219 
00220     return 0; 
00221 }
00222 
00223 /* Read spatial index file 
00224  * returns 0 - OK
00225  *         1 - error
00226  */
00227 int
00228 dig_read_cidx ( GVFILE * fp, struct Plus_head *plus, int head_only)
00229 {
00230     int i;
00231 
00232     G_debug (3, "dig_read_cidx()");
00233 
00234     dig_cidx_init ( plus);
00235 
00236     dig_rewind (fp);
00237     if ( dig_read_cidx_head ( fp, plus) == -1 ) {
00238         G_debug (3, "Cannot read cidx head");
00239         return 1;
00240     }
00241 
00242     if ( head_only ) {
00243         plus->cidx_up_to_date = 1; /* OK ?*/
00244         return 0;
00245     }
00246     
00247     dig_set_cur_port(&(plus->cidx_port));
00248 
00249     /* Read category-type-id for each field */ 
00250     for ( i = 0; i < plus->n_cidx; i++ ) {
00251         int j;
00252         struct Cat_index *ci;
00253 
00254         ci = &(plus->cidx[i]);
00255         ci->a_cats = ci->n_cats;
00256         ci->cat = G_malloc ( ci->a_cats * 3 * sizeof(int) );
00257 
00258         if ( dig_fseek ( fp, ci->offset, 0) == -1 ) return 1;
00259         
00260         if (0 >= dig__fread_port_I ( (int *)ci->cat, 3 * ci->n_cats, fp)) return 1;
00261 
00262         /* convert type  */
00263         for ( j = 0; j < ci->n_cats; j++ )
00264             ci->cat[j][1] = dig_type_from_store ( ci->cat[j][1] );
00265     }
00266 
00267 
00268     plus->cidx_up_to_date = 1;
00269          
00270     return 0; 
00271 }
00272 

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