00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <stdarg.h>
00021 #include <grass/glocale.h>
00022 #include <grass/gis.h>
00023 #include <grass/Vect.h>
00024
00025
00026 #ifndef HAVE_OGR
00027 static int format () { G_fatal_error ("Requested format is not compiled in this version"); return 0; }
00028 #endif
00029
00030 static int (*Build_array[]) () =
00031 {
00032 Vect_build_nat
00033 #ifdef HAVE_OGR
00034 , Vect_build_ogr
00035 #else
00036 , format
00037 #endif
00038 };
00039
00040 FILE *Msgout = NULL;
00041
00042
00043 int prnmsg ( char *msg, ...) {
00044 char buffer[1000];
00045 va_list ap;
00046
00047 if ( Msgout != NULL ) {
00048 va_start(ap,msg);
00049 vsprintf(buffer,msg,ap);
00050 va_end(ap);
00051 fprintf (Msgout, "%s", buffer);
00052 fflush (Msgout);
00053 }
00054
00055 return 1;
00056 }
00057
00064 int
00065 Vect_build ( struct Map_info *Map, FILE *msgout )
00066 {
00067 return Vect_build_partial ( Map, GV_BUILD_ALL, msgout );
00068 }
00069
00070
00077 int
00078 Vect_get_built ( struct Map_info *Map )
00079 {
00080 return ( Map->plus.built );
00081 }
00082
00117 int
00118 Vect_build_partial ( struct Map_info *Map, int build, FILE *msgout )
00119 {
00120 struct Plus_head *plus ;
00121 int ret;
00122
00123 G_debug (3, "Vect_build(): build = %d", build);
00124 Msgout = msgout;
00125
00126
00127
00128 Map->level = 1;
00129 Map->support_updated = 1;
00130
00131 Map->plus.Spidx_built = 1;
00132
00133 plus = &(Map->plus);
00134 prnmsg ( _("Building topology ...\n") );
00135 plus->with_z = Map->head.with_z;
00136 plus->spidx_with_z = Map->head.with_z;
00137
00138 if ( build == GV_BUILD_ALL ) {
00139 dig_cidx_free(plus);
00140 dig_cidx_init(plus);
00141 }
00142
00143 ret = ( (*Build_array[Map->format]) (Map, build, msgout) );
00144
00145 if ( ret == 0 ) { return 0; }
00146
00147 prnmsg (_("Topology was built.\n"));
00148
00149 Map->level = LEVEL_2;
00150 plus->mode = GV_MODE_WRITE;
00151
00152 if ( build == GV_BUILD_ALL ) {
00153 plus->cidx_up_to_date = 1;
00154 dig_cidx_sort ( plus );
00155 }
00156
00157
00158
00159 prnmsg (_("Number of nodes : %d\n"), plus->n_nodes);
00160 prnmsg (_("Number of primitives: %d\n"), plus->n_lines);
00161 prnmsg (_("Number of points : %d\n"), plus->n_plines);
00162 prnmsg (_("Number of lines : %d\n"), plus->n_llines);
00163 prnmsg (_("Number of boundaries: %d\n"), plus->n_blines);
00164 prnmsg (_("Number of centroids : %d\n"), plus->n_clines);
00165
00166 if ( plus->n_flines > 0 )
00167 prnmsg (_("Number of faces : %d\n"), plus->n_flines);
00168
00169 if ( plus->n_klines > 0 )
00170 prnmsg (_("Number of kernels : %d\n"), plus->n_klines);
00171
00172 if ( plus->built >= GV_BUILD_AREAS ) {
00173 int line, nlines, area, nareas, err_boundaries, err_centr_out, err_centr_dupl, err_nocentr;
00174 P_LINE *Line;
00175 struct Plus_head *Plus;
00176
00177
00178 Plus = &(Map->plus);
00179 nlines = Vect_get_num_lines (Map);
00180 err_boundaries = err_centr_out = err_centr_dupl = 0;
00181 for ( line = 1; line <= nlines; line++ ){
00182 Line = Plus->Line[line];
00183 if ( !Line ) continue;
00184 if ( Line->type == GV_BOUNDARY && ( Line->left == 0 || Line->right == 0 ) ) {
00185 G_debug ( 3, "line = %d left = %d right = %d", line, Line->left, Line->right);
00186 err_boundaries++;
00187 }
00188 if ( Line->type == GV_CENTROID ) {
00189 if ( Line->left == 0 )
00190 err_centr_out++;
00191 else if ( Line->left < 0 )
00192 err_centr_dupl++;
00193 }
00194 }
00195
00196 err_nocentr = 0;
00197 nareas = Vect_get_num_areas (Map);
00198 for ( area = 1; area <= nareas; area++ ){
00199 if ( !Vect_area_alive(Map, area ) ) continue;
00200 line = Vect_get_area_centroid ( Map, area );
00201 if ( line == 0 )
00202 err_nocentr++;
00203 }
00204
00205 prnmsg (_("Number of areas : %d\n"), plus->n_areas);
00206 prnmsg (_("Number of isles : %d\n"), plus->n_isles);
00207
00208 if ( err_boundaries )
00209 prnmsg (_("Number of incorrect boundaries : %d\n"), err_boundaries);
00210
00211 if ( err_centr_out )
00212 prnmsg (_("Number of centroids outside area : %d\n"), err_centr_out);
00213
00214 if ( err_centr_dupl )
00215 prnmsg (_("Number of duplicate centroids : %d\n"), err_centr_dupl);
00216
00217 if ( err_nocentr )
00218 prnmsg (_("Number of areas without centroid : %d\n"), err_nocentr);
00219
00220 } else {
00221 prnmsg (_("Number of areas : -\n"));
00222 prnmsg (_("Number of isles : -\n"));
00223 }
00224 return 1;
00225 }
00226
00233 int
00234 Vect_save_topo ( struct Map_info *Map )
00235 {
00236 struct Plus_head *plus ;
00237 char fname[1024], buf[1024];
00238 GVFILE fp;
00239
00240 G_debug (1, "Vect_save_topo()");
00241
00242 plus = &(Map->plus);
00243
00244
00245 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00246 G__file_name (fname, buf, GV_TOPO_ELEMENT, Map->mapset);
00247 G_debug (1, "Open topo: %s", fname);
00248 dig_file_init ( &fp );
00249 fp.file = fopen( fname, "w");
00250 if ( fp.file == NULL) {
00251 G_warning(_("Can't open topo file for write: %s\n"), fname);
00252 return 0;
00253 }
00254
00255
00256 dig_init_portable ( &(plus->port), dig__byte_order_out ());
00257
00258 if ( 0 > dig_write_plus_file (&fp, plus) ) {
00259 G_warning (_("Error writing out topo file.\n"));
00260 return 0;
00261 }
00262
00263 fclose( fp.file );
00264
00265 return 1;
00266 }
00267
00274 int
00275 Vect_topo_dump ( struct Map_info *Map, FILE *out )
00276 {
00277 int i, j, line, isle;
00278 P_NODE *Node;
00279 P_LINE *Line;
00280 P_AREA *Area;
00281 P_ISLE *Isle;
00282 BOUND_BOX box;
00283 struct Plus_head *plus;
00284
00285 plus = &(Map->plus);
00286
00287 fprintf (out, "---------- TOPOLOGY DUMP ----------\n" );
00288
00289
00290 Vect_box_copy ( &box, &(plus->box) );
00291 fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", box.N, box.S,
00292 box.E, box.W, box.T, box.B);
00293
00294
00295 fprintf (out, "Nodes (%d nodes, alive + dead ):\n", plus->n_nodes );
00296 for (i = 1; i <= plus->n_nodes; i++) {
00297 if ( plus->Node[i] == NULL ) { continue; }
00298 Node = plus->Node[i];
00299 fprintf (out, "node = %d, n_lines = %d, xy = %f, %f\n", i, Node->n_lines,
00300 Node->x, Node->y );
00301 for (j = 0; j < Node->n_lines; j++) {
00302 line = Node->lines[j];
00303 Line = plus->Line[abs(line)];
00304 fprintf (out, " line = %3d, type = %d, angle = %f\n", line, Line->type, Node->angles[j] );
00305 }
00306 }
00307
00308
00309 fprintf (out, "Lines (%d lines, alive + dead ):\n", plus->n_lines );
00310 for (i = 1; i <= plus->n_lines; i++) {
00311 if ( plus->Line[i] == NULL ) { continue; }
00312 Line = plus->Line[i];
00313 fprintf (out, "line = %d, type = %d, offset = %ld n1 = %d, n2 = %d, "
00314 "left/area = %d, right = %d\n",
00315 i, Line->type, Line->offset, Line->N1, Line->N2,
00316 Line->left, Line->right);
00317 fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Line->N, Line->S,
00318 Line->E, Line->W, Line->T, Line->B);
00319 }
00320
00321
00322 fprintf (out, "Areas (%d areas, alive + dead ):\n", plus->n_areas );
00323 for (i = 1; i <= plus->n_areas; i++) {
00324 if ( plus->Area[i] == NULL ) { continue; }
00325 Area = plus->Area[i];
00326
00327 fprintf (out, "area = %d, n_lines = %d, n_isles = %d centroid = %d\n",
00328 i, Area->n_lines, Area->n_isles, Area->centroid );
00329
00330 fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Area->N, Area->S,
00331 Area->E, Area->W, Area->T, Area->B);
00332
00333 for (j = 0; j < Area->n_lines; j++) {
00334 line = Area->lines[j];
00335 Line = plus->Line[abs(line)];
00336 fprintf (out, " line = %3d\n", line );
00337 }
00338 for (j = 0; j < Area->n_isles; j++) {
00339 isle = Area->isles[j];
00340 fprintf (out, " isle = %3d\n", isle );
00341 }
00342 }
00343
00344
00345 fprintf (out, "Islands (%d islands, alive + dead ):\n", plus->n_isles );
00346 for (i = 1; i <= plus->n_isles; i++) {
00347 if ( plus->Isle[i] == NULL ) { continue; }
00348 Isle = plus->Isle[i];
00349
00350 fprintf (out, "isle = %d, n_lines = %d area = %d\n", i, Isle->n_lines,
00351 Isle->area );
00352
00353 fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Isle->N, Isle->S,
00354 Isle->E, Isle->W, Isle->T, Isle->B);
00355
00356 for (j = 0; j < Isle->n_lines; j++) {
00357 line = Isle->lines[j];
00358 Line = plus->Line[abs(line)];
00359 fprintf (out, " line = %3d\n", line );
00360 }
00361 }
00362
00363 return 1;
00364 }
00365
00372 int
00373 Vect_save_spatial_index ( struct Map_info *Map )
00374 {
00375 struct Plus_head *plus ;
00376 char fname[1024], buf[1024];
00377 GVFILE fp;
00378
00379 G_debug (1, "Vect_save_spatial_index()");
00380
00381 plus = &(Map->plus);
00382
00383
00384 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00385 G__file_name (fname, buf, GV_SIDX_ELEMENT, Map->mapset);
00386 G_debug (1, "Open sidx: %s", fname);
00387 dig_file_init ( &fp );
00388 fp.file = fopen( fname, "w");
00389 if ( fp.file == NULL) {
00390 G_warning(_("Can't open spatial index file for write: %s\n"), fname);
00391 return 0;
00392 }
00393
00394
00395 dig_init_portable ( &(plus->spidx_port), dig__byte_order_out ());
00396
00397 if ( 0 > dig_write_spidx (&fp, plus) ) {
00398 G_warning (_("Error writing out spatial index file.\n"));
00399 return 0;
00400 }
00401
00402 fclose( fp.file );
00403
00404 return 1;
00405 }
00406
00413 int
00414 Vect_spatial_index_dump ( struct Map_info *Map, FILE *out )
00415 {
00416 if ( !(Map->plus.Spidx_built) ) {
00417 Vect_build_sidx_from_topo ( Map, NULL );
00418 }
00419
00420 fprintf (out, "---------- SPATIAL INDEX DUMP ----------\n" );
00421
00422 dig_dump_spidx ( out, &(Map->plus) );
00423
00424 return 1;
00425 }
00426