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