/**************************************************************** * main.c * * This is the main program for line-of-sight analysis. * It takes a digital elevation map and identifies all * the grid cells that are visible from a user specified * observer location. Other input parameters to the * program include the height of the observer above the * ground, a map marking areas of interest in which the * analysis is desired, and a maximum range for the line * of sight. * ****************************************************************/ #include #include #include #include #include #define MAIN #include #include #include "cmd_line.h" #include "point.h" #include "local_proto.h" #define COLOR_SHIFT 155.0 #define COLOR_MAX 255.0 #define SEARCH_PT_INCLINATION SEARCH_PT->inclination #define NEXT_SEARCH_PT SEARCH_PT->next struct Cell_head window; /* database window */ int main (int argc, char *argv[]) { int row_viewpt,col_viewpt,nrows,ncols,a,b,row,patt_flag; int segment_no,flip,xmax,ymax,sign_on_y,sign_on_x; int submatrix_rows,submatrix_cols,lenth_data_item; int patt=0,in_fd,out_fd,patt_fd=0; double old, new; double slope_1,slope_2,max_vert_angle=0.0,color_factor; char *old_mapset,*patt_mapset=NULL; FCELL *value; char *search_mapset, *current_mapset; char *in_name, *out_name, *patt_name=NULL; struct Categories cats; struct Cell_head cellhd_elev, cellhd_patt; extern struct Cell_head window; FCELL *cell, data, viewpt_elev; SEGMENT seg_in, seg_out, seg_patt; struct point *heads[16],*SEARCH_PT; struct GModule *module; struct Option *opt1,*opt2,*opt3,*opt5,*opt6,*opt7; G_gisinit (argv[0]); module = G_define_module(); module->keywords = _("raster"); module->description = _("Line-of-sight raster analysis program."); /* Define the different options */ opt1 = G_define_option() ; opt1->key = "input"; opt1->type = TYPE_STRING; opt1->required = YES; opt1->gisprompt = "old,cell,raster" ; opt1->description= _("Raster map containing elevation data") ; opt7 = G_define_option() ; opt7->key = "output"; opt7->type = TYPE_STRING; opt7->required = YES; opt7->gisprompt = "new,cell,raster" ; opt7->description= _("Raster map name for storing results"); opt3 = G_define_option() ; opt3->key = "coordinate"; opt3->type = TYPE_STRING; opt3->required = YES; opt3->key_desc = "x,y"; opt3->description= _("Coordinate identifying the viewing location"); opt2 = G_define_option() ; opt2->key = "patt_map"; opt2->type = TYPE_STRING; opt2->required = NO; opt2->description= _("Binary (1/0) raster map"); opt2->gisprompt = "old,cell,raster" ; opt5 = G_define_option() ; opt5->key = "obs_elev"; opt5->type = TYPE_DOUBLE; opt5->required = NO; opt5->answer = "1.75"; opt5->description= _("Height of the viewing location"); opt6 = G_define_option() ; opt6->key = "max_dist"; opt6->type = TYPE_DOUBLE; opt6->required = NO; opt6->answer = "1000"; opt6->options = "0-99999" ; opt6->description= _("Max distance from the viewing point (meters)") ; if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_scan_easting (opt3->answers[0], &east, G_projection()) ; G_scan_northing (opt3->answers[1], &north, G_projection()) ; sscanf (opt5->answer, "%lf", &obs_elev); sscanf (opt6->answer, "%lf", &max_dist); elev_layer = opt1->answer; patt_layer = opt2->answer; out_layer = opt7->answer; G_get_window (&window); current_mapset= G_mapset(); /* set flag to indicate presence of areas of interest */ if(patt_layer == NULL) patt_flag=0; else patt_flag=1; if ((G_projection() == PROJECTION_LL)) G_fatal_error( _("Lat/Long support is not (yet) implemented for this module.")); /* check if specified observer location inside window */ if(eastwindow.east || north>window.north || north4 && segment_no<13) sign_on_x= -1; else sign_on_x=1; /* calc slopes for bounding rays of a segment */ if(segment_no==1 || segment_no==4 || segment_no==5 || segment_no==8 || segment_no==9 || segment_no==12 || segment_no==13 || segment_no==16) { slope_1= 0.0; slope_2= 0.5; } else { slope_1= 0.5; slope_2= 1.0; } if(segment_no==1 || segment_no==2 || segment_no==7 || segment_no==8 || segment_no==9 || segment_no==10 || segment_no==15 || segment_no==16) flip = 0; else flip = 1; /* calculate max and min 'x' and 'y' */ a= ((ncols-1)*(sign_on_x+1)/2 - sign_on_x * col_viewpt); b= (1-sign_on_y)/2*(nrows-1) + sign_on_y*row_viewpt; if(flip==0){ xmax=a; ymax=b; } else { xmax=b; ymax=a; } /* perform analysis for every segment */ heads[segment_no-1]= segment(segment_no,xmax,ymax, slope_1,slope_2,flip,sign_on_y,sign_on_x, viewpt_elev,&seg_in,&seg_out,&seg_patt, row_viewpt,col_viewpt,patt_flag); } /* end of for-loop over segments */ /* loop over all segment lists to find maximum vertical */ /* angle of any point when viewed from observer location*/ for(segment_no=1; segment_no <= 16; segment_no++) { SEARCH_PT = heads[segment_no-1]; while(SEARCH_PT != NULL) { if(fabs(SEARCH_PT_INCLINATION) > max_vert_angle) max_vert_angle = fabs(SEARCH_PT_INCLINATION); SEARCH_PT = NEXT_SEARCH_PT; } } /* calculate factor to be multiplied to every vertical */ /* angle for suitable color variation on output map */ color_factor = decide_color_range(max_vert_angle*57.3, COLOR_SHIFT,COLOR_MAX); color_factor = 1.0; /* to give true angle? */ /* mark visible points for all segments on outputmap */ for(segment_no=1; segment_no <= 16; segment_no++) { mark_visible_points(heads[segment_no-1],&seg_out, row_viewpt,col_viewpt,color_factor,COLOR_SHIFT); } /* mark viewpt on output map */ data = 180; value = &data; segment_put(&seg_out,value,row_viewpt,col_viewpt); /* write pending updates by segment_put() to outputmap */ segment_flush(&seg_out); /* convert output submatrices to full cell overlay */ for(row=0; row< nrows; row++) { int col ; segment_get_row(&seg_out,cell,row); for (col=0; col < ncols; col++) if (cell[col] == 1) G_set_null_value(&cell[col], 1, FCELL_TYPE); if(G_put_raster_row(new, cell, FCELL_TYPE) < 0) exit(1); } segment_release(&seg_in); /* release memory */ segment_release(&seg_out); if(patt_flag == 1) segment_release(&seg_patt); close(in_fd); /* close all files */ close(out_fd); unlink (in_name); /* remove temp files as well */ unlink (out_name); G_close_cell(old); G_close_cell(new); if(patt_flag == 1) { close(patt_fd); G_close_cell(patt); } /* create category file for output map */ G_read_cats (out_layer, current_mapset, &cats); G_set_cats_fmt ("$1 degree$?s", 1.0, 0.0, 0.0, 0.0, &cats); G_write_cats (out_layer, &cats); exit(EXIT_SUCCESS); }