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