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