/**********************************************************************/ /* */ /* This is the main program for tracing out the shortest path(s) */ /* based on the raster map showing back path cells from which the*/ /* cumulative costs were determined. */ /* */ /**********************************************************************/ #include #include #include #include #include #include #define MAIN #include "stash.h" #include #include "local_proto.h" char *value; int nrows, ncols; SEGMENT in_row_seg, in_col_seg, out_seg; int main(int argc, char **argv) { int n, verbose = 1, backrow, backcol, col, row, len, flag, srows, scols, backrow_fd, backcol_fd, path_fd, in_row_fd, in_col_fd, out_fd; char *current_mapset, *search_mapset, *path_mapset, *backrow_mapset, *backcol_mapset, *in_row_file, *in_col_file, *out_file; CELL *cell; POINT *PRES_PT, *PRESENT_PT, *OLD_PT; struct Cell_head window; double east, north; struct Option *opt1, *opt2, *opt3, *opt4; struct Flag *flag1; struct GModule *module; G_gisinit (argv[0]); /* Set description */ module = G_define_module(); module->keywords = _("raster"); module->description = _("Recursively traces the least cost path backwards to " "cells from which the cumulative cost was determined."); opt1 = G_define_option() ; opt1->key = "x_input" ; opt1->type = TYPE_STRING ; opt1->required = YES ; opt1->gisprompt = "old,cell,raster" ; opt1->description= _("Name of raster map containing back-path easting information"); opt2 = G_define_option() ; opt2->key = "y_input" ; opt2->type = TYPE_STRING ; opt2->required = YES ; opt2->gisprompt = "old,cell,raster" ; opt2->description= _("Name of raster map containing back-path norhting information"); opt3 = G_define_option() ; opt3->key = "coordinate" ; opt3->type = TYPE_STRING ; opt3->multiple = YES; opt3->key_desc = "x,y" ; opt3->description= _("The map E and N grid coordinates of starting points"); opt4 = G_define_option() ; opt4->key = "output" ; opt4->type = TYPE_STRING ; opt4->required = YES ; opt4->gisprompt = "new,cell,raster" ; opt4->description= _("Name of spread path raster map") ; flag1 = G_define_flag(); flag1->key = 'v'; flag1->description = _("Run verbosly"); /* Do command line parsing */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); current_mapset = G_mapset(); in_row_file = G_tempfile(); in_col_file = G_tempfile(); out_file = G_tempfile(); /* Get database window parameters */ if(G_get_window (&window) < 0) G_fatal_error("can't read current window parameters"); verbose = flag1->answer; /* Check if backrow layer exists in data base */ search_mapset = ""; strcpy(backrow_layer, opt2->answer); strcpy(backcol_layer, opt1->answer); backrow_mapset = G_find_cell (backrow_layer, search_mapset); backcol_mapset = G_find_cell (backcol_layer, search_mapset); if (backrow_mapset == NULL) G_fatal_error("%s - not found", backrow_layer); if (backcol_mapset == NULL) G_fatal_error("%s - not found", backcol_layer); search_mapset = ""; strcpy (path_layer, opt4->answer); path_mapset = G_find_cell (path_layer, search_mapset); /* find number of rows and cols in window */ nrows = G_window_rows(); ncols = G_window_cols(); cell = G_allocate_cell_buf(); /* Open back cell layers for reading */ backrow_fd = G_open_cell_old(backrow_layer, backrow_mapset); if (backrow_fd < 0) G_fatal_error("%s - can't open raster file", backrow_layer); backcol_fd = G_open_cell_old(backcol_layer, backcol_mapset); if (backcol_fd < 0) G_fatal_error("%s - can't open raster file", backcol_layer); /* Parameters for map submatrices */ len = sizeof(CELL); srows = nrows/4 + 1; scols = ncols/4 + 1; if (verbose) G_message("\nReading the input map -%s- and -%s- and creating some temporary files...", backrow_layer, backcol_layer); /* Create segmented files for back cell and output layers */ in_row_fd = creat(in_row_file,0666); segment_format(in_row_fd, nrows, ncols, srows, scols, len); close(in_row_fd); in_col_fd = creat(in_col_file,0666); segment_format(in_col_fd, nrows, ncols, srows, scols, len); close(in_col_fd); out_fd = creat(out_file,0666); segment_format(out_fd, nrows, ncols, srows, scols, len); close(out_fd); /* Open initialize and segment all files */ in_row_fd = open(in_row_file,2); segment_init(&in_row_seg,in_row_fd,4); in_col_fd = open(in_col_file,2); segment_init(&in_col_seg,in_col_fd,4); out_fd = open(out_file,2); segment_init(&out_seg,out_fd,4); /* Write the back cell layers in the segmented files, and * Change UTM coordinates to ROWs and COLUMNs */ for( row=0 ; row 0) cell[col] = (window.north - cell[col])/window.ns_res/* - 0.5*/; else cell[col] = -1; segment_put_row(&in_row_seg, cell, row); if( G_get_map_row(backcol_fd, cell, row)<0) G_fatal_error("unable to get map row %d", row); for (col=0; col 0) cell[col] = (cell[col] - window.west)/window.ew_res/* - 0.5*/; segment_put_row(&in_col_seg, cell, row); } /* Convert easting and northing from the command line to row and col */ if (opt3->answer) { for(n=0; opt3->answers[n] != NULL; n+=2) { G_scan_easting (opt3->answers[n ], &east, G_projection()) ; G_scan_northing (opt3->answers[n+1], &north, G_projection()) ; row = (window.north - north) / window.ns_res; col = (east - window.west) / window.ew_res; /* ignore pt outside window */ if(east < window.west || east > window.east || north < window.south || north > window.north) { fprintf(stderr,"Warning, ignoring point outside window: \n") ; fprintf(stderr," %.4f,%.4f\n", east, north) ; continue ; } value = (char *) &backrow; segment_get (&in_row_seg, value, row, col); /* ignore pt in no-data area */ if(backrow < 0) { fprintf(stderr,"Warning, ignoring point in NO-DATA area : \n") ; fprintf(stderr," %.4f,%.4f\n", east, north) ; continue ; } value = (char *)&backcol; segment_get (&in_col_seg, value, row, col); insert (&PRESENT_PT, row, col, backrow, backcol); } } /* Set flag according to input */ if (path_mapset != NULL) { if (head_start_pt == NULL) /*output layer exists and start pts are not given on cmd line*/ flag = 1; /* output layer exists and starting pts are given on cmd line*/ else flag = 2; } else flag = 3; /* output layer does not previously exist */ /* Check if specified output layer name is legal */ if (flag == 3) { if (G_legal_filename (path_layer) < 0) G_fatal_error("%s - illegal name", path_layer); } /* If the output layer containing the starting positions*/ /* create a linked list of of them */ if (flag == 1) { path_fd = G_open_cell_old (path_layer, path_mapset); if (path_fd < 0) G_fatal_error("%s -can't open raster file", path_layer); /* Search for the marked starting pts and make list */ for(row = 0; row < nrows; row++) { if(G_get_map_row(path_fd,cell,row) < 0) G_fatal_error("unable to get map row %d", row); for(col = 0; col < ncols; col++) { if(cell[col] > 0) { value = (char *)&backrow; segment_get (&in_row_seg, value, row, col); /* ignore pt in no-data area */ if(backrow < 0) { fprintf(stderr,"Warning, ignoring point in NO-DATA area : \n") ; fprintf(stderr," %.4f,%.4f\n", window.west + window.ew_res*(col + 0.5), window.north - window.ns_res*(row + 0.5)) ; continue ; } value = (char *)&backcol; segment_get (&in_col_seg, value, row, col); insert (&PRESENT_PT, row, col, backrow, backcol); } } /* loop over cols */ } /* loop over rows */ G_close_cell(path_fd); } /* loop over the starting points to find the least cost paths */ if (verbose) G_message("\nFinding the least cost paths ..."); PRES_PT = head_start_pt; while(PRES_PT != NULL) { path_finder (PRES_PT->row, PRES_PT->col, PRES_PT->backrow, PRES_PT->backcol); OLD_PT = PRES_PT; PRES_PT = NEXT_PT; G_free (OLD_PT); } /* Write pending updates by segment_put() to outputmap */ segment_flush(&out_seg); if (verbose) G_message("\nWriting the output map -%s-...", path_layer); path_fd = G_open_cell_new(path_layer); for ( row=0 ; row