/*! * \brief Writes the null value to the N_array_2d struct at position col, row * * The null value will be automatically set to the array data type (CELL, FCELL or DCELL). * * \param data N_array_2d * * \param col int * \param row int * \return void * */ void N_put_array_2d_value_null(N_array_2d * data, int col, int row) { G_debug(6, "N_put_array_2d_value_null: put null value to array pos [%i][%i]", col, row); if (data->offset == 0) { if (data->type == CELL_TYPE && data->cell_array != NULL) { Rast_set_c_null_value((void *) &(data-> cell_array[row * data->cols_intern + col]), 1); } else if (data->type == FCELL_TYPE && data->fcell_array != NULL) { Rast_set_f_null_value((void *) &(data-> fcell_array[row * data->cols_intern + col]), 1); } else if (data->type == DCELL_TYPE && data->dcell_array != NULL) { Rast_set_d_null_value((void *) &(data-> dcell_array[row * data->cols_intern + col]), 1); } } else { if (data->type == CELL_TYPE && data->cell_array != NULL) { Rast_set_c_null_value((void *) &(data-> cell_array[(row + data->offset) * data->cols_intern + col + data->offset]), 1); } else if (data->type == FCELL_TYPE && data->fcell_array != NULL) { Rast_set_f_null_value((void *) &(data-> fcell_array[(row + data->offset) * data->cols_intern + col + data->offset]), 1); } else if (data->type == DCELL_TYPE && data->dcell_array != NULL) { Rast_set_d_null_value((void *) &(data-> dcell_array[(row + data->offset) * data->cols_intern + col + data->offset]), 1); } } return; }
static void write_row_int(png_bytep p) { unsigned int x, c; channel *ch; for (x = 0; x < width; x++) for (c = 0; c < 6; c++) { ch = &channels[c]; if (ch->active) ch->buf[x] = (CELL) get_png_val(&p, bit_depth); } if (channels[C_A].active && ialpha > 0) for (c = 0; c < 6; c++) { ch = &channels[c]; if (c != C_A && ch->active) for (x = 0; x < width; x++) if (channels[C_A].buf[x] <= ialpha) Rast_set_c_null_value(&ch->buf[x], 1); } for (c = 0; c < 6; c++) { ch = &channels[c]; if (ch->active) Rast_put_c_row(ch->fd, ch->buf); } }
static void do_reclass_int(int fd, void *cell, int null_is_zero) { struct fileinfo *fcb = &R__.fileinfo[fd]; CELL *c = cell; CELL *reclass_table = fcb->reclass.table; CELL min = fcb->reclass.min; CELL max = fcb->reclass.max; int i; for (i = 0; i < R__.rd_window.cols; i++) { if (Rast_is_c_null_value(&c[i])) { if (null_is_zero) c[i] = 0; continue; } if (c[i] < min || c[i] > max) { if (null_is_zero) c[i] = 0; else Rast_set_c_null_value(&c[i], 1); continue; } c[i] = reclass_table[c[i] - min]; if (null_is_zero && Rast_is_c_null_value(&c[i])) c[i] = 0; } }
/*! * \brief Get range min and max * * The mininum and maximum CELL values are extracted from the * <i>range</i> structure. * * If the range structure has no defined min/max (first!=0) there will * not be a valid range. In this case the min and max returned must be * the NULL-value. * * \param range pointer to Range structure which holds range info * \param[out] min minimum value * \param[out] max maximum value */ void Rast_get_range_min_max(const struct Range *range, CELL * min, CELL * max) { if (range->first_time) { Rast_set_c_null_value(min, 1); Rast_set_c_null_value(max, 1); } else { if (Rast_is_c_null_value(&(range->min))) Rast_set_c_null_value(min, 1); else *min = range->min; if (Rast_is_c_null_value(&(range->max))) Rast_set_c_null_value(max, 1); else *max = range->max; } }
int find_pourpts(void) { int row, col; double easting, northing, stream_length; CELL old_elev, basin_num, no_basin, curr_basin; WAT_ALT wa; ASP_FLAG af; char is_swale; ocs_alloced = 2 * bas_thres; ocs = (OC_STACK *)G_malloc(ocs_alloced * sizeof(OC_STACK)); basin_num = 0; Rast_set_c_null_value(&no_basin, 1); stream_length = old_elev = 0; for (row = 0; row < nrows; row++) { G_percent(row, nrows, 1); northing = window.north - (row + .5) * window.ns_res; for (col = 0; col < ncols; col++) { seg_get(&aspflag, (char *)&af, row, col); cseg_get(&bas, &curr_basin, row, col); if (curr_basin == 0) cseg_put(&bas, &no_basin, row, col); cseg_get(&haf, &curr_basin, row, col); if (curr_basin == 0) cseg_put(&haf, &no_basin, row, col); is_swale = FLAG_GET(af.flag, SWALEFLAG); if (af.asp <= 0 && is_swale > 0) { basin_num += 2; if (arm_flag) { easting = window.west + (col + .5) * window.ew_res; fprintf(fp, "%5d drains into %5d at %3d %3d %.3f %.3f", (int)basin_num, 0, row, col, easting, northing); if (col == 0 || col == ncols - 1) { stream_length = .5 * window.ew_res; } else if (row == 0 || row == nrows - 1) { stream_length = .5 * window.ns_res; } else { stream_length = 0.0; } seg_get(&watalt, (char *) &wa, row, col); old_elev = wa.ele; } basin_num = def_basin(row, col, basin_num, stream_length, old_elev); } } } G_percent(nrows, nrows, 1); /* finish it */ n_basins = basin_num; G_free(ocs); return 0; }
void new_stats(const char *name, struct Reclass *reclass) { struct Histogram histo, histo2; struct Range range; CELL cat, cat2; int i; CELL min, max; min = reclass->min; max = reclass->max; /* read histogram for original file */ G_suppress_warnings(1); i = Rast_read_histogram(reclass->name, reclass->mapset, &histo); G_suppress_warnings(0); if (i <= 0) return; /* compute data rage for reclass */ Rast_init_range(&range); for (i = 0; i < histo.num; i++) { cat = histo.list[i].cat; if (cat < min || cat > max) continue; cat2 = reclass->table[cat - min]; Rast_update_range(cat2, &range); } Rast_write_range(name, &range); /* now generate a histogram from the original */ /* allocate histogram list */ histo2.num += range.max - range.min + 1; histo2.list = (LIST *) G_calloc(histo2.num, sizeof(LIST)); /* set all counts to 0 */ i = 0; for (cat = range.min; cat <= range.max; cat++) { histo2.list[i].cat = cat; histo2.list[i++].count = 0; } /* go thru original histogram and add into histo2 */ for (i = 0; i < histo.num; i++) { cat = histo.list[i].cat; if (cat < min || cat > max) Rast_set_c_null_value(&cat, 1); else cat2 = reclass->table[cat - min]; if (!Rast_is_c_null_value(&cat)) histo2.list[cat2 - range.min].count += histo.list[i].count; } Rast_write_histogram(name, &histo2); }
int shape_index(int fd, char **par, area_des ad, double *result) { double area; struct Cell_head hd; CELL complete_value; double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; int mask_fd = -1, null_count = 0; int i = 0, k = 0; int *mask_buf; Rast_set_c_null_value(&complete_value, 1); Rast_get_cellhd(ad->raster, "", &hd); /* open mask if needed */ if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return 0; mask_buf = malloc(ad->cl * sizeof(int)); for (i = 0; i < ad->rl; i++) { if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) return 0; for (k = 0; k < ad->cl; k++) { if (mask_buf[k] == 0) { null_count++; } } } } /*calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); area = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (ad->rl * ad->cl - null_count); *result = area; return 1; }
static void set_to_null(struct RASTER_MAP_PTR *buf, int col) { switch (buf->type) { case CELL_TYPE: Rast_set_c_null_value(&(buf->data.c[col]), 1); break; case FCELL_TYPE: Rast_set_f_null_value(&(buf->data.f[col]), 1); break; case DCELL_TYPE: Rast_set_d_null_value(&(buf->data.d[col]), 1); break; } }
static void convert_and_write_di(int fd, const void *vbuf) { const DCELL *buf = vbuf; struct fileinfo *fcb = &R__.fileinfo[fd]; CELL *p = (CELL *) fcb->data; int i; for (i = 0; i < fcb->cellhd.cols; i++) if (Rast_is_d_null_value(&buf[i])) Rast_set_c_null_value(&p[i], 1); else p[i] = (CELL) buf[i]; Rast_put_c_row(fd, p); }
static void gdal_values_int(int fd, const unsigned char *data, const COLUMN_MAPPING * cmap, int nbytes, CELL * cell, int n) { struct fileinfo *fcb = &R__.fileinfo[fd]; const unsigned char *d; COLUMN_MAPPING cmapold = 0; int i; for (i = 0; i < n; i++) { if (!cmap[i]) { cell[i] = 0; continue; } if (cmap[i] == cmapold) { cell[i] = cell[i - 1]; continue; } d = data + (cmap[i] - 1) * nbytes; switch (fcb->gdal->type) { case GDT_Byte: cell[i] = *(GByte *) d; break; case GDT_Int16: cell[i] = *(GInt16 *) d; break; case GDT_UInt16: cell[i] = *(GUInt16 *) d; break; case GDT_Int32: cell[i] = *(GInt32 *) d; break; case GDT_UInt32: cell[i] = *(GUInt32 *) d; break; default: /* shouldn't happen */ Rast_set_c_null_value(&cell[i], 1); break; } cmapold = cmap[i]; } }
int main(int argc, char **argv) { IO rasters[] = { /* rasters stores output buffers */ {"dem",YES,"Input dem","input",UNKNOWN,-1,NULL}, /* WARNING: this one map is input */ {"forms",NO,"Most common geomorphic forms","patterns",CELL_TYPE,-1,NULL}, {"ternary",NO,"code of ternary patterns","patterns",CELL_TYPE,-1,NULL}, {"positive",NO,"code of binary positive patterns","patterns",CELL_TYPE,-1,NULL}, {"negative",NO,"code of binary negative patterns","patterns",CELL_TYPE,-1,NULL}, {"intensity",NO,"rasters containing mean relative elevation of the form","geometry",FCELL_TYPE,-1,NULL}, {"exposition",NO,"rasters containing maximum difference between extend and central cell","geometry",FCELL_TYPE,-1,NULL}, {"range",NO,"rasters containing difference between max and min elevation of the form extend","geometry",FCELL_TYPE,-1,NULL}, {"variance",NO,"rasters containing variance of form boundary","geometry",FCELL_TYPE,-1,NULL}, {"elongation",NO,"rasters containing local elongation","geometry",FCELL_TYPE,-1,NULL}, {"azimuth",NO,"rasters containing local azimuth of the elongation","geometry",FCELL_TYPE,-1,NULL}, {"extend",NO,"rasters containing local extend (area) of the form","geometry",FCELL_TYPE,-1,NULL}, {"width",NO,"rasters containing local width of the form","geometry",FCELL_TYPE,-1,NULL} }; /* adding more maps change IOSIZE macro */ CATCOLORS ccolors[CNT]={ /* colors and cats for forms */ {ZERO, 0, 0, 0, "forms"}, {FL, 220, 220, 220, "flat"}, {PK, 56, 0, 0, "summit"}, {RI, 200, 0, 0, "ridge"}, {SH, 255, 80, 20, "shoulder"}, {CV, 250, 210, 60, "spur"}, {SL, 255, 255, 60, "slope"}, {CN, 180, 230, 20, "hollow"}, {FS, 60, 250, 150, "footslope"}, {VL, 0, 0, 255, "valley"}, {PT, 0, 0, 56, "depression"}, {__, 255, 0, 255, "ERROR"}}; struct GModule *module; struct Option *opt_input, *opt_output[io_size], *par_search_radius, *par_skip_radius, *par_flat_treshold, *par_flat_distance; struct Flag *flag_units, *flag_extended; struct History history; int i,j, n; int meters=0, multires=0, extended=0; /* flags */ int row,cur_row,col,radius; int pattern_size; double max_resolution; char prefix[20]; G_gisinit(argv[0]); { /* interface parameters */ module = G_define_module(); module->description = _("Calculate geomorphons (terrain forms)and associated geometry using machine vision approach"); G_add_keyword("Geomorphons"); G_add_keyword("Terrain patterns"); G_add_keyword("Machine vision geomorphometry"); opt_input = G_define_standard_option(G_OPT_R_INPUT); opt_input->key = rasters[0].name; opt_input->required = rasters[0].required; opt_input->description = _(rasters[0].description); for (i=1;i<io_size;++i) { /* WARNING: loop starts from one, zero is for input */ opt_output[i] = G_define_standard_option(G_OPT_R_OUTPUT); opt_output[i]->key = rasters[i].name; opt_output[i]->required = NO; opt_output[i]->description = _(rasters[i].description); opt_output[i]->guisection = _(rasters[i].gui); } par_search_radius = G_define_option(); par_search_radius->key = "search"; par_search_radius->type = TYPE_INTEGER; par_search_radius->answer = "3"; par_search_radius->required = YES; par_search_radius->description = _("Outer search radius"); par_skip_radius = G_define_option(); par_skip_radius->key = "skip"; par_skip_radius->type = TYPE_INTEGER; par_skip_radius->answer = "0"; par_skip_radius->required = YES; par_skip_radius->description = _("Inner search radius"); par_flat_treshold = G_define_option(); par_flat_treshold->key = "flat"; par_flat_treshold->type = TYPE_DOUBLE; par_flat_treshold->answer = "1"; par_flat_treshold->required = YES; par_flat_treshold->description = _("Flatenss treshold (degrees)"); par_flat_distance = G_define_option(); par_flat_distance->key = "dist"; par_flat_distance->type = TYPE_DOUBLE; par_flat_distance->answer = "0"; par_flat_distance->required = YES; par_flat_distance->description = _("Flatenss distance, zero for none"); flag_units = G_define_flag(); flag_units->key = 'm'; flag_units->description = _("Use meters to define search units (default is cells)"); flag_extended = G_define_flag(); flag_extended->key = 'e'; flag_extended->description = _("Use extended form correction"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); } { /* calculate parameters */ int num_outputs=0; double search_radius, skip_radius, start_radius, step_radius; double ns_resolution; for (i=1;i<io_size;++i) /* check for outputs */ if(opt_output[i]->answer) { if (G_legal_filename(opt_output[i]->answer) < 0) G_fatal_error(_("<%s> is an illegal file name"), opt_output[i]->answer); num_outputs++; } if(!num_outputs && !multires) G_fatal_error(_("At least one output is required")); meters=(flag_units->answer != 0); extended=(flag_extended->answer != 0); nrows = Rast_window_rows(); ncols = Rast_window_cols(); Rast_get_window(&window); G_begin_distance_calculations(); if(G_projection()==PROJECTION_LL) { /* for LL max_res should be NS */ ns_resolution=G_distance(0,Rast_row_to_northing(0, &window),0,Rast_row_to_northing(1, &window)); max_resolution=ns_resolution; } else { max_resolution=MAX(window.ns_res,window.ew_res); /* max_resolution MORE meters per cell */ } G_message("NSRES, %f", ns_resolution); cell_res=max_resolution; /* this parameter is global */ /* search distance */ search_radius=atof(par_search_radius->answer); search_cells=meters?(int)(search_radius/max_resolution):search_radius; if(search_cells<1) G_fatal_error(_("Search radius size must cover at least 1 cell")); row_radius_size=meters?ceil(search_radius/max_resolution):search_radius; row_buffer_size=row_radius_size*2+1; search_distance=(meters)?search_radius:max_resolution*search_cells; /* skip distance */ skip_radius=atof(par_skip_radius->answer); skip_cells=meters?(int)(skip_radius/max_resolution):skip_radius; if(skip_cells>=search_cells) G_fatal_error(_("Skip radius size must be at least 1 cell lower than radius")); skip_distance=(meters)?skip_radius:ns_resolution*skip_cells; /* flatness parameters */ flat_threshold=atof(par_flat_treshold->answer); if(flat_threshold<=0.) G_fatal_error(_("Flatenss treshold must be grater than 0")); flat_threshold=DEGREE2RAD(flat_threshold); flat_distance=atof(par_flat_distance->answer); flat_distance=(meters)?flat_distance:ns_resolution*flat_distance; flat_threshold_height=tan(flat_threshold)*flat_distance; if((flat_distance>0&&flat_distance<=skip_distance)||flat_distance>=search_distance) { G_warning(_("Flatenss distance should be between skip and search radius. Otherwise ignored")); flat_distance=0; } if (search_distance<10*cell_res) extended=0; /* print information about distances */ G_message("Search distance m: %f, cells: %d", search_distance, search_cells); G_message("Skip distance m: %f, cells: %d", skip_distance, skip_cells); G_message("Flat threshold distance m: %f, height: %f",flat_distance, flat_threshold_height); G_message("%s version",(extended)?"extended":"basic"); } /* generate global ternary codes */ for(i=0;i<6561;++i) global_ternary_codes[i]=ternary_rotate(i); /* open DEM */ strcpy(elevation.elevname,opt_input->answer); open_map(&elevation); PATTERN* pattern; PATTERN patterns[4]; void* pointer_buf; int formA, formB, formC; double search_dist=search_distance; double skip_dist=skip_distance; double flat_dist=flat_distance; double area_of_octagon=4*(search_distance*search_distance)*sin(DEGREE2RAD(45.)); cell_step=1; /* prepare outputs */ for (i=1;i<io_size;++i) if(opt_output[i]->answer) { rasters[i].fd=Rast_open_new(opt_output[i]->answer,rasters[i].out_data_type); rasters[i].buffer=Rast_allocate_buf(rasters[i].out_data_type); } /* main loop */ for(row=0;row<nrows;++row) { G_percent(row, nrows, 2); cur_row = (row < row_radius_size)?row: ((row >= nrows-row_radius_size-1) ? row_buffer_size - (nrows-row-1) : row_radius_size); if(row>(row_radius_size) && row<nrows-(row_radius_size+1)) shift_buffers(row); for (col=0;col<ncols;++col) { /* on borders forms ussualy are innatural. */ if(row<(skip_cells+1) || row>nrows-(skip_cells+2) || col<(skip_cells+1) || col>ncols-(skip_cells+2) || Rast_is_f_null_value(&elevation.elev[cur_row][col])) { /* set outputs to NULL and do nothing if source value is null or border*/ for (i=1;i<io_size;++i) if(opt_output[i]->answer) { pointer_buf=rasters[i].buffer; switch (rasters[i].out_data_type) { case CELL_TYPE: Rast_set_c_null_value(&((CELL*)pointer_buf)[col],1); break; case FCELL_TYPE: Rast_set_f_null_value(&((FCELL*)pointer_buf)[col],1); break; case DCELL_TYPE: Rast_set_d_null_value(&((DCELL*)pointer_buf)[col],1); break; default: G_fatal_error(_("Unknown output data type")); } } continue; } /* end null value */ { int cur_form, small_form; search_distance=search_dist; skip_distance=skip_dist; flat_distance=flat_dist; pattern_size=calc_pattern(&patterns[0],row,cur_row,col); pattern=&patterns[0]; cur_form=determine_form(pattern->num_negatives,pattern->num_positives); /* correction of forms */ if(extended) { /* 1) remove extensive innatural forms: ridges, peaks, shoulders and footslopes */ if((cur_form==4||cur_form==8||cur_form==2||cur_form==3)) { search_distance=(search_dist/4.<4*max_resolution)? 4*max_resolution : search_dist/4.; skip_distance=0; flat_distance=0; pattern_size=calc_pattern(&patterns[1],row,cur_row,col); pattern=&patterns[1]; small_form=determine_form(pattern->num_negatives,pattern->num_positives); if(cur_form==4||cur_form==8) cur_form=(small_form==1)? 1 : cur_form; if(cur_form==2||cur_form==3) cur_form=small_form; } } /* end of correction */ pattern=&patterns[0]; if(opt_output[o_forms]->answer) ((CELL*)rasters[o_forms].buffer)[col]=cur_form; } if(opt_output[o_ternary]->answer) ((CELL*)rasters[o_ternary].buffer)[col]=determine_ternary(pattern->pattern); if(opt_output[o_positive]->answer) ((CELL*)rasters[o_positive].buffer)[col]=pattern->num_positives;//rotate(pattern->positives); if(opt_output[o_negative]->answer) ((CELL*)rasters[o_negative].buffer)[col]=pattern->num_negatives;//rotate(pattern->negatives); if(opt_output[o_intensity]->answer) ((FCELL*)rasters[o_intensity].buffer)[col]=intensity(pattern->elevation,pattern_size); if(opt_output[o_exposition]->answer) ((FCELL*)rasters[o_exposition].buffer)[col]=exposition(pattern->elevation); if(opt_output[o_range]->answer) ((FCELL*)rasters[o_range].buffer)[col]=range(pattern->elevation); if(opt_output[o_variance]->answer) ((FCELL*)rasters[o_variance].buffer)[col]=variance(pattern->elevation, pattern_size); // used only for next four shape functions if(opt_output[o_elongation]->answer ||opt_output[o_azimuth]->answer|| opt_output[o_extend]->answer || opt_output[o_width]->answer) { float azimuth,elongation,width; radial2cartesian(pattern); shape(pattern, pattern_size,&azimuth,&elongation,&width); if(opt_output[o_azimuth]->answer) ((FCELL*)rasters[o_azimuth].buffer)[col]=azimuth; if(opt_output[o_elongation]->answer) ((FCELL*)rasters[o_elongation].buffer)[col]=elongation; if(opt_output[o_width]->answer) ((FCELL*)rasters[o_width].buffer)[col]=width; } if(opt_output[o_extend]->answer) ((FCELL*)rasters[o_extend].buffer)[col]=extends(pattern, pattern_size)/area_of_octagon; } /* end for col */ /* write existing outputs */ for (i=1;i<io_size;++i) if(opt_output[i]->answer) Rast_put_row(rasters[i].fd, rasters[i].buffer, rasters[i].out_data_type); } G_percent(row, nrows, 2); /* end main loop */ /* finish and close */ free_map(elevation.elev, row_buffer_size+1); for (i=1;i<io_size;++i) if(opt_output[i]->answer) { G_free(rasters[i].buffer); Rast_close(rasters[i].fd); Rast_short_history(opt_output[i]->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(opt_output[i]->answer, &history); } if(opt_output[o_forms]->answer) write_form_cat_colors(opt_output[o_forms]->answer,ccolors); if(opt_output[o_intensity]->answer) write_contrast_colors(opt_output[o_intensity]->answer); if(opt_output[o_exposition]->answer) write_contrast_colors(opt_output[o_exposition]->answer); if(opt_output[o_range]->answer) write_contrast_colors(opt_output[o_range]->answer); G_message("Done!"); exit(EXIT_SUCCESS); }
int calculate(int fd, struct area_entry *ad, double *result) { CELL *buf, *buf_sup, *buf_null; CELL corrCell, precCell, supCell; long npatch, area; long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp; struct pst *pst; long nalloc, incr; int i, j, k; int connected; int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked; struct Cell_head hd; Rast_get_window(&hd); buf_null = Rast_allocate_c_buf(); Rast_set_c_null_value(buf_null, Rast_window_cols()); buf_sup = buf_null; /* initialize patch ids */ pid_corr = G_malloc(Rast_window_cols() * sizeof(long)); pid_sup = G_malloc(Rast_window_cols() * sizeof(long)); for (j = 0; j < Rast_window_cols(); j++) { pid_corr[j] = 0; pid_sup[j] = 0; } /* open mask if needed */ mask_fd = -1; mask_buf = mask_sup = NULL; masked = FALSE; if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return RLI_ERRORE; mask_buf = G_malloc(ad->cl * sizeof(int)); if (mask_buf == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } mask_sup = G_malloc(ad->cl * sizeof(int)); if (mask_sup == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } for (j = 0; j < ad->cl; j++) mask_buf[j] = 0; masked = TRUE; } /* calculate number of patches */ npatch = 0; area = 0; pid = 0; /* patch size and type */ incr = 1024; if (incr > ad->rl) incr = ad->rl; if (incr > ad->cl) incr = ad->cl; if (incr < 2) incr = 2; nalloc = incr; pst = G_malloc(nalloc * sizeof(struct pst)); for (k = 0; k < nalloc; k++) { pst[k].count = 0; } for (i = 0; i < ad->rl; i++) { buf = RLI_get_cell_raster_row(fd, i + ad->y, ad); if (i > 0) { buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad); } if (masked) { mask_tmp = mask_sup; mask_sup = mask_buf; mask_buf = mask_tmp; if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) return 0; } ltmp = pid_sup; pid_sup = pid_corr; pid_corr = ltmp; Rast_set_c_null_value(&precCell, 1); connected = 0; for (j = 0; j < ad->cl; j++) { pid_corr[j + ad->x] = 0; corrCell = buf[j + ad->x]; if (masked && (mask_buf[j] == 0)) { Rast_set_c_null_value(&corrCell, 1); } if (Rast_is_c_null_value(&corrCell)) { connected = 0; precCell = corrCell; continue; } area++; supCell = buf_sup[j + ad->x]; if (masked && (mask_sup[j] == 0)) { Rast_set_c_null_value(&supCell, 1); } if (!Rast_is_c_null_value(&precCell) && corrCell == precCell) { pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x]; connected = 1; pst[pid_corr[j + ad->x]].count++; } else { connected = 0; } if (!Rast_is_c_null_value(&supCell) && corrCell == supCell) { if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) { /* connect or merge */ /* after r.clump */ if (connected) { npatch--; if (npatch == 0) { G_fatal_error("npatch == 0 at row %d, col %d", i, j); } } old_pid = pid_corr[j + ad->x]; new_pid = pid_sup[j + ad->x]; pid_corr[j + ad->x] = new_pid; if (old_pid > 0) { /* merge */ /* update left side of the current row */ for (k = 0; k < j; k++) { if (pid_corr[k + ad->x] == old_pid) pid_corr[k + ad->x] = new_pid; } /* update right side of the previous row */ for (k = j + 1; k < ad->cl; k++) { if (pid_sup[k + ad->x] == old_pid) pid_sup[k + ad->x] = new_pid; } pst[new_pid].count += pst[old_pid].count; pst[old_pid].count = 0; if (old_pid == pid) pid--; } else { pst[new_pid].count++; } } connected = 1; } if (!connected) { /* start new patch */ npatch++; pid++; pid_corr[j + ad->x] = pid; if (pid >= nalloc) { pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst)); for (k = nalloc; k < pid + incr; k++) pst[k].count = 0; nalloc = pid + incr; } pst[pid].count = 1; pst[pid].type.t = CELL_TYPE; pst[pid].type.val.c = corrCell; } precCell = corrCell; } } if (npatch > 0) { double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; double area_p; double cell_size_m; double min, max; /* calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows); /* get min and max patch size */ min = 1.0 / 0.0; /* inf */ max = -1.0 / 0.0; /* -inf */ for (old_pid = 1; old_pid <= pid; old_pid++) { if (pst[old_pid].count > 0) { area_p = cell_size_m * pst[old_pid].count / 10000; if (min > area_p) min = area_p; if (max < area_p) max = area_p; } } *result = max - min; } else Rast_set_d_null_value(result, 1); if (masked) { close(mask_fd); G_free(mask_buf); G_free(mask_sup); } G_free(buf_null); G_free(pid_corr); G_free(pid_sup); G_free(pst); return RLI_OK; }
int seg_stream_geometry(SEGMENT *streams, SEGMENT *dirs) { int i, s, d; /* s - streams index; d - direction */ int done = 1; int r, c; int next_r, next_c; int prev_r, prev_c; int cur_stream, next_stream, dirs_cell; float cur_northing, cur_easting; float next_northing, next_easting; float init_northing, init_easting; double cur_length = 0.; double cur_accum_length = 0.; STREAM *SA = stream_attributes; /* for better code readability */ struct Cell_head window; G_get_window(&window); G_message(_("Finding longest streams...")); G_begin_distance_calculations(); for (s = 0; s < init_num; ++s) { /* main loop on springs */ G_percent(s, init_num, 2); r = (int)init_cells[s] / ncols; c = (int)init_cells[s] % ncols; Segment_get(streams, &cur_stream, r, c); cur_length = 0; done = 1; SA[cur_stream].init = init_cells[s]; /* stored as index */ init_northing = window.north - (r + .5) * window.ns_res; init_easting = window.west + (c + .5) * window.ew_res; while (done) { cur_northing = window.north - (r + .5) * window.ns_res; cur_easting = window.west + (c + .5) * window.ew_res; Segment_get(dirs, &dirs_cell, r, c); d = abs(dirs_cell); next_r = NR(d); next_c = NC(d); if (NOT_IN_REGION(d)) Rast_set_c_null_value(&next_stream, 1); else Segment_get(streams, &next_stream, next_r, next_c); if (d < 1 || NOT_IN_REGION(d) || !next_stream) { cur_length = (window.ns_res + window.ew_res) / 2; SA[cur_stream].accum_length += cur_length; SA[cur_stream].length += cur_length; SA[cur_stream].stright = G_distance(cur_easting, cur_northing, init_easting, init_northing); SA[cur_stream].outlet = (r * ncols + c); /* add outlet to sorting */ break; } next_northing = window.north - (next_r + .5) * window.ns_res; next_easting = window.west + (next_c + .5) * window.ew_res; cur_length = G_distance(next_easting, next_northing, cur_easting, cur_northing); SA[cur_stream].accum_length += cur_length; SA[cur_stream].length += cur_length; prev_r = r; prev_c = c; r = next_r; c = next_c; if (next_stream != cur_stream) { SA[cur_stream].stright = G_distance(next_easting, next_northing, init_easting, init_northing); init_northing = cur_northing; init_easting = cur_easting; SA[cur_stream].outlet = (prev_r * ncols + prev_c); cur_stream = next_stream; cur_accum_length = 0; SA[cur_stream].init = (r * ncols + c); for (i = 0; i < SA[cur_stream].trib_num; ++i) { if (SA[SA[cur_stream].trib[i]].accum_length == 0) { done = 0; cur_accum_length = 0; break; /* do not pass accum */ } if (SA[SA[cur_stream].trib[i]].accum_length > cur_accum_length) cur_accum_length = SA[SA[cur_stream].trib[i]].accum_length; } /* end for i */ SA[cur_stream].accum_length = cur_accum_length; } /* end if */ } /* end while */ } /* end for s */ G_percent(1, 1, 1); return 0; }
void rgb2his(CELL * rowbuffer[3], int columns) { int sample; /* sample indicator */ double red; /* the red band output */ double green; /* the green band output */ double blue; /* the blue band output */ double scaler; /* red value */ double scaleg; /* green value */ double scaleb; /* blue value */ double high; /* maximum red, green, blue */ double low; /* minimum red, green, blue */ double intens; /* intensity */ double sat; /* saturation */ double hue = 0.0L; /* hue */ for (sample = 0; sample < columns; sample++) { if (Rast_is_c_null_value(&rowbuffer[0][sample]) || Rast_is_c_null_value(&rowbuffer[1][sample]) || Rast_is_c_null_value(&rowbuffer[2][sample])) { Rast_set_c_null_value(&rowbuffer[0][sample], 1); Rast_set_c_null_value(&rowbuffer[1][sample], 1); Rast_set_c_null_value(&rowbuffer[2][sample], 1); continue; } scaler = (double)rowbuffer[0][sample]; scaler /= 255.0; scaleg = (double)rowbuffer[1][sample]; scaleg /= 255.0; scaleb = (double)rowbuffer[2][sample]; scaleb /= 255.0; high = scaler; if (scaleg > high) high = scaleg; if (scaleb > high) high = scaleb; low = scaler; if (scaleg < low) low = scaleg; if (scaleb < low) low = scaleb; /* calculate the lightness (intensity) */ intens = ((high + low) / 2.0); /* if min = max the achromatic case R=G=B */ if (high == low) { sat = 0.0; /* hue = -1.0; */ hue = 0.0; rowbuffer[0][sample] = (unsigned char)hue; rowbuffer[1][sample] = (unsigned char)(intens * 255.); rowbuffer[2][sample] = (unsigned char)(sat * 255.); } /* else chromatic case */ else if (high != low) { if (intens <= 0.5) sat = (high - low) / (high + low); else /* sat = (high-low)/(2 - (high-low)); */ sat = (high - low) / (2 - high - low); red = (high - scaler) / (high - low); green = (high - scaleg) / (high - low); blue = (high - scaleb) / (high - low); /* resulting color between yellow and magenta */ if (scaler == high) hue = blue - green; /* resulting color between cyan and yellow */ else if (scaleg == high) hue = 2 + red - blue; /* resulting color between magenta and cyan */ else if (scaleb == high) hue = 4 + green - red; /* convert to degrees */ hue *= 60.0; /* make nonnegative */ if (hue < 0.0) hue += 360.0; /* set the HIS output values */ rowbuffer[0][sample] = (unsigned char)(255.0 * hue / 360.0 + 0.5); rowbuffer[1][sample] = (unsigned char)(intens * 255. + 0.5); rowbuffer[2][sample] = (unsigned char)(sat * 255. + 0.5); } } }
int main( int argc, char **argv ) { char *name = nullptr; struct Option *map; struct Cell_head window; G_gisinit( argv[0] ); G_define_module(); map = G_define_standard_option( G_OPT_R_OUTPUT ); if ( G_parser( argc, argv ) ) exit( EXIT_FAILURE ); name = map->answer; #ifdef Q_OS_WIN _setmode( _fileno( stdin ), _O_BINARY ); _setmode( _fileno( stdout ), _O_BINARY ); //setvbuf( stdin, NULL, _IONBF, BUFSIZ ); // setting _IONBF on stdout works on windows correctly, data written immediately even without fflush(stdout) //setvbuf( stdout, NULL, _IONBF, BUFSIZ ); #endif QgsGrassDataFile stdinFile; stdinFile.open( stdin ); QDataStream stdinStream( &stdinFile ); QFile stdoutFile; stdoutFile.open( stdout, QIODevice::WriteOnly | QIODevice::Unbuffered ); QDataStream stdoutStream( &stdoutFile ); qint32 proj, zone; stdinStream >> proj >> zone; QgsRectangle extent; qint32 rows, cols; stdinStream >> extent >> cols >> rows; checkStream( stdinStream ); QString err = QgsGrass::setRegion( &window, extent, rows, cols ); if ( !err.isEmpty() ) { G_fatal_error( "Cannot set region: %s", err.toUtf8().constData() ); } window.proj = ( int ) proj; window.zone = ( int ) zone; G_set_window( &window ); Qgis::DataType qgis_type; qint32 type; stdinStream >> type; checkStream( stdinStream ); qgis_type = ( Qgis::DataType )type; RASTER_MAP_TYPE grass_type; switch ( qgis_type ) { case Qgis::Int32: grass_type = CELL_TYPE; break; case Qgis::Float32: grass_type = FCELL_TYPE; break; case Qgis::Float64: grass_type = DCELL_TYPE; break; default: G_fatal_error( "QGIS data type %d not supported", qgis_type ); return 1; } cf = Rast_open_new( name, grass_type ); if ( cf < 0 ) { G_fatal_error( "Unable to create raster map <%s>", name ); return 1; } void *buf = Rast_allocate_buf( grass_type ); int expectedSize = cols * QgsRasterBlock::typeSize( qgis_type ); bool isCanceled = false; QByteArray byteArray; for ( int row = 0; row < rows; row++ ) { stdinStream >> isCanceled; checkStream( stdinStream ); if ( isCanceled ) { break; } double noDataValue; stdinStream >> noDataValue; stdinStream >> byteArray; checkStream( stdinStream ); if ( byteArray.size() != expectedSize ) { G_fatal_error( "Wrong byte array size, expected %d bytes, got %d, row %d / %d", expectedSize, byteArray.size(), row, rows ); return 1; } qint32 *cell = nullptr; float *fcell = nullptr; double *dcell = nullptr; if ( grass_type == CELL_TYPE ) cell = ( qint32 * ) byteArray.data(); else if ( grass_type == FCELL_TYPE ) fcell = ( float * ) byteArray.data(); else if ( grass_type == DCELL_TYPE ) dcell = ( double * ) byteArray.data(); void *ptr = buf; for ( int col = 0; col < cols; col++ ) { if ( grass_type == CELL_TYPE ) { if ( ( CELL )cell[col] == ( CELL )noDataValue ) { Rast_set_c_null_value( ( CELL * )ptr, 1 ); } else { Rast_set_c_value( ptr, ( CELL )( cell[col] ), grass_type ); } } else if ( grass_type == FCELL_TYPE ) { if ( ( FCELL )fcell[col] == ( FCELL )noDataValue ) { Rast_set_f_null_value( ( FCELL * )ptr, 1 ); } else { Rast_set_f_value( ptr, ( FCELL )( fcell[col] ), grass_type ); } } else if ( grass_type == DCELL_TYPE ) { if ( ( DCELL )dcell[col] == ( DCELL )noDataValue ) { Rast_set_d_null_value( ( DCELL * )ptr, 1 ); } else { Rast_set_d_value( ptr, ( DCELL )dcell[col], grass_type ); } } ptr = G_incr_void_ptr( ptr, Rast_cell_size( grass_type ) ); } Rast_put_row( cf, buf, grass_type ); #ifndef Q_OS_WIN // Because stdin is somewhere buffered on Windows (not clear if in QProcess or by Windows) // we cannot in QgsGrassImport wait for this because it hangs. Setting _IONBF on stdin does not help // and there is no flush() on QProcess. // OTOH, smaller stdin buffer is probably blocking QgsGrassImport so that the import can be canceled immediately. stdoutStream << ( bool )true; // row written stdoutFile.flush(); #endif } if ( isCanceled ) { Rast_unopen( cf ); } else { Rast_close( cf ); struct History history; Rast_short_history( name, "raster", &history ); Rast_command_history( &history ); Rast_write_history( name, &history ); } exit( EXIT_SUCCESS ); }
int init_vars(int argc, char *argv[]) { int r, c; int ele_fd, wat_fd, fd = -1; int seg_rows, seg_cols, num_cseg_total, num_open_segs, num_open_array_segs; double memory_divisor, heap_mem, seg_factor, disk_space; /* int page_block, num_cseg; */ int max_bytes; CELL *buf, alt_value, *alt_value_buf, block_value; char asp_value; DCELL wat_value; DCELL dvalue; WAT_ALT wa, *wabuf; ASP_FLAG af, af_nbr, *afbuf; char MASK_flag; void *elebuf, *ptr, *watbuf, *watptr; int ele_map_type, wat_map_type; size_t ele_size, wat_size; int ct_dir, r_nbr, c_nbr; G_gisinit(argv[0]); /* input */ ele_flag = pit_flag = run_flag = ril_flag = 0; /* output */ wat_flag = asp_flag = bas_flag = seg_flag = haf_flag = tci_flag = 0; bas_thres = 0; /* shed, unused */ arm_flag = dis_flag = 0; /* RUSLE */ ob_flag = st_flag = sl_flag = sg_flag = ls_flag = er_flag = 0; nxt_avail_pt = 0; /* dep_flag = 0; */ max_length = d_zero = 0.0; d_one = 1.0; ril_value = -1.0; /* dep_slope = 0.0; */ max_bytes = 0; sides = 8; mfd = 1; c_fac = 5; abs_acc = 0; ele_scale = 1; segs_mb = 300; /* scan options */ for (r = 1; r < argc; r++) { if (sscanf(argv[r], "elevation=%s", ele_name) == 1) ele_flag++; else if (sscanf(argv[r], "accumulation=%s", wat_name) == 1) wat_flag++; else if (sscanf(argv[r], "tci=%s", tci_name) == 1) tci_flag++; else if (sscanf(argv[r], "drainage=%s", asp_name) == 1) asp_flag++; else if (sscanf(argv[r], "depression=%s", pit_name) == 1) pit_flag++; else if (sscanf(argv[r], "threshold=%d", &bas_thres) == 1) ; else if (sscanf(argv[r], "max_slope_length=%lf", &max_length) == 1) ; else if (sscanf(argv[r], "basin=%s", bas_name) == 1) bas_flag++; else if (sscanf(argv[r], "stream=%s", seg_name) == 1) seg_flag++; else if (sscanf(argv[r], "half_basin=%s", haf_name) == 1) haf_flag++; else if (sscanf(argv[r], "flow=%s", run_name) == 1) run_flag++; else if (sscanf(argv[r], "ar=%s", arm_name) == 1) arm_flag++; /* slope length else if (sscanf(argv[r], "slope_length=%s", sl_name) == 1) sl_flag++; */ else if (sscanf(argv[r], "slope_steepness=%s", sg_name) == 1) sg_flag++; else if (sscanf(argv[r], "length_slope=%s", ls_name) == 1) ls_flag++; else if (sscanf(argv[r], "blocking=%s", ob_name) == 1) ob_flag++; else if (sscanf(argv[r], "memory=%lf", &segs_mb) == 1) ; else if (sscanf(argv[r], "disturbed_land=%s", ril_name) == 1) { if (sscanf(ril_name, "%lf", &ril_value) == 0) { ril_value = -1.0; ril_flag++; } } /* slope deposition else if (sscanf (argv[r], "sd=%[^\n]", dep_name) == 1) dep_flag++; */ else if (sscanf(argv[r], "-%d", &sides) == 1) { if (sides != 4) usage(argv[0]); } else if (sscanf(argv[r], "convergence=%d", &c_fac) == 1) ; else if (strcmp(argv[r], "-s") == 0) mfd = 0; else if (strcmp(argv[r], "-a") == 0) abs_acc = 1; else usage(argv[0]); } /* check options */ if (mfd == 1 && (c_fac < 1 || c_fac > 10)) { G_fatal_error("Convergence factor must be between 1 and 10."); } if ((ele_flag != 1) || ((arm_flag == 1) && ((bas_thres <= 0) || ((haf_flag != 1) && (bas_flag != 1)))) || ((bas_thres <= 0) && ((bas_flag == 1) || (seg_flag == 1) || (haf_flag == 1) || (sl_flag == 1) || (sg_flag == 1) || (ls_flag == 1))) ) usage(argv[0]); tot_parts = 4; if (sl_flag || sg_flag || ls_flag) er_flag = 1; /* do RUSLE */ if (er_flag) tot_parts++; /* define basins */ if (seg_flag || bas_flag || haf_flag) tot_parts++; G_message(_n("SECTION 1 beginning: Initiating Variables. %d section total.", "SECTION 1 beginning: Initiating Variables. %d sections total.", tot_parts), tot_parts); this_mapset = G_mapset(); /* for sd factor if (dep_flag) { if (sscanf (dep_name, "%lf", &dep_slope) != 1) { dep_flag = -1; } } */ G_get_set_window(&window); nrows = Rast_window_rows(); ncols = Rast_window_cols(); if (max_length <= d_zero) max_length = 10 * nrows * window.ns_res + 10 * ncols * window.ew_res; if (window.ew_res < window.ns_res) half_res = .5 * window.ew_res; else half_res = .5 * window.ns_res; diag = sqrt(window.ew_res * window.ew_res + window.ns_res * window.ns_res); if (sides == 4) diag *= 0.5; /* Segment rows and cols: 64 */ seg_rows = SROW; seg_cols = SCOL; /* seg_factor * <size in bytes> = segment size in KB */ seg_factor = seg_rows * seg_rows / 1024.; if (segs_mb < 3.0) { segs_mb = 3; G_warning(_("Maximum memory to be used was smaller than 3 MB," " set to 3 MB.")); } /* balance segment files */ /* elevation + accumulation: * 2 */ memory_divisor = sizeof(WAT_ALT) * 2; disk_space = sizeof(WAT_ALT); /* aspect and flags: * 4 */ memory_divisor += sizeof(ASP_FLAG) * 4; disk_space += sizeof(ASP_FLAG); /* astar_points: / 16 */ /* ideally only a few but large segments */ memory_divisor += sizeof(POINT) / 16.; disk_space += sizeof(POINT); /* heap points: / 4 */ memory_divisor += sizeof(HEAP_PNT) / 4.; disk_space += sizeof(HEAP_PNT); /* TCI: as is */ if (tci_flag) { memory_divisor += sizeof(double); disk_space += sizeof(double); } /* RUSLE */ if (er_flag) { /* r_h */ memory_divisor += 4; disk_space += 4; /* s_l */ memory_divisor += 8; disk_space += 8; /* s_g */ if (sg_flag) { memory_divisor += 8; disk_space += 8; } /* l_s */ if (ls_flag) { memory_divisor += 8; disk_space += 8; } /* ril */ if (ril_flag) { memory_divisor += 8; disk_space += 8; } } /* KB -> MB */ memory_divisor = memory_divisor * seg_factor / 1024.; disk_space = disk_space * seg_factor / 1024.; num_open_segs = segs_mb / memory_divisor; heap_mem = num_open_segs * seg_factor * sizeof(HEAP_PNT) / (4. * 1024.); G_debug(1, "segs MB: %.0f", segs_mb); G_debug(1, "region rows: %d", nrows); G_debug(1, "seg rows: %d", seg_rows); G_debug(1, "region cols: %d", ncols); G_debug(1, "seg cols: %d", seg_cols); num_cseg_total = nrows / SROW + 1; G_debug(1, " row segments:\t%d", num_cseg_total); num_cseg_total = ncols / SCOL + 1; G_debug(1, "column segments:\t%d", num_cseg_total); num_cseg_total = (ncols / seg_cols + 1) * (nrows / seg_rows + 1); G_debug(1, " total segments:\t%d", num_cseg_total); G_debug(1, " open segments:\t%d", num_open_segs); /* nonsense to have more segments open than exist */ if (num_open_segs > num_cseg_total) num_open_segs = num_cseg_total; G_debug(1, " open segments after adjusting:\t%d", num_open_segs); disk_space *= num_cseg_total; if (disk_space < 1024.0) G_verbose_message(_("Will need up to %.2f MB of disk space"), disk_space); else G_verbose_message(_("Will need up to %.2f GB (%.0f MB) of disk space"), disk_space / 1024.0, disk_space); if (er_flag) { cseg_open(&r_h, seg_rows, seg_cols, num_open_segs); cseg_read_cell(&r_h, ele_name, ""); } /* read elevation input and mark NULL/masked cells */ /* scattered access: alt, watalt, bitflags, asp */ seg_open(&watalt, nrows, ncols, seg_rows, seg_cols, num_open_segs * 2, sizeof(WAT_ALT)); seg_open(&aspflag, nrows, ncols, seg_rows, seg_cols, num_open_segs * 4, sizeof(ASP_FLAG)); if (tci_flag) dseg_open(&tci, seg_rows, seg_cols, num_open_segs); /* open elevation input */ ele_fd = Rast_open_old(ele_name, ""); ele_map_type = Rast_get_map_type(ele_fd); ele_size = Rast_cell_size(ele_map_type); elebuf = Rast_allocate_buf(ele_map_type); afbuf = G_malloc(ncols * sizeof(ASP_FLAG)); if (ele_map_type == FCELL_TYPE || ele_map_type == DCELL_TYPE) ele_scale = 1000; /* should be enough to do the trick */ /* initial flow accumulation */ if (run_flag) { wat_fd = Rast_open_old(run_name, ""); wat_map_type = Rast_get_map_type(ele_fd); wat_size = Rast_cell_size(ele_map_type); watbuf = Rast_allocate_buf(ele_map_type); } else { watbuf = watptr = NULL; wat_fd = wat_size = wat_map_type = -1; } wabuf = G_malloc(ncols * sizeof(WAT_ALT)); alt_value_buf = Rast_allocate_buf(CELL_TYPE); /* read elevation input and mark NULL/masked cells */ G_message("SECTION 1a: Mark masked and NULL cells"); MASK_flag = 0; do_points = (GW_LARGE_INT) nrows * ncols; for (r = 0; r < nrows; r++) { G_percent(r, nrows, 1); Rast_get_row(ele_fd, elebuf, r, ele_map_type); ptr = elebuf; if (run_flag) { Rast_get_row(wat_fd, watbuf, r, wat_map_type); watptr = watbuf; } for (c = 0; c < ncols; c++) { afbuf[c].flag = 0; afbuf[c].asp = 0; /* check for masked and NULL cells */ if (Rast_is_null_value(ptr, ele_map_type)) { FLAG_SET(afbuf[c].flag, NULLFLAG); FLAG_SET(afbuf[c].flag, INLISTFLAG); FLAG_SET(afbuf[c].flag, WORKEDFLAG); Rast_set_c_null_value(&alt_value, 1); /* flow accumulation */ Rast_set_d_null_value(&wat_value, 1); do_points--; } else { if (ele_map_type == CELL_TYPE) { alt_value = *((CELL *)ptr); } else if (ele_map_type == FCELL_TYPE) { dvalue = *((FCELL *)ptr); dvalue *= ele_scale; alt_value = ele_round(dvalue); } else if (ele_map_type == DCELL_TYPE) { dvalue = *((DCELL *)ptr); dvalue *= ele_scale; alt_value = ele_round(dvalue); } /* flow accumulation */ if (run_flag) { if (Rast_is_null_value(watptr, wat_map_type)) { wat_value = 0; /* ok ? */ } else { if (wat_map_type == CELL_TYPE) { wat_value = *((CELL *)watptr); } else if (wat_map_type == FCELL_TYPE) { wat_value = *((FCELL *)watptr); } else if (wat_map_type == DCELL_TYPE) { wat_value = *((DCELL *)watptr); } } } else { wat_value = 1; } } wabuf[c].wat = wat_value; wabuf[c].ele = alt_value; alt_value_buf[c] = alt_value; ptr = G_incr_void_ptr(ptr, ele_size); if (run_flag) { watptr = G_incr_void_ptr(watptr, wat_size); } } seg_put_row(&watalt, (char *) wabuf, r); seg_put_row(&aspflag, (char *)afbuf, r); if (er_flag) { cseg_put_row(&r_h, alt_value_buf, r); } } G_percent(nrows, nrows, 1); /* finish it */ Rast_close(ele_fd); G_free(wabuf); G_free(afbuf); if (run_flag) { Rast_close(wat_fd); G_free(watbuf); } MASK_flag = (do_points < nrows * ncols); /* do RUSLE */ if (er_flag) { if (ob_flag) { fd = Rast_open_old(ob_name, ""); buf = Rast_allocate_c_buf(); for (r = 0; r < nrows; r++) { G_percent(r, nrows, 1); Rast_get_c_row(fd, buf, r); for (c = 0; c < ncols; c++) { block_value = buf[c]; if (!Rast_is_c_null_value(&block_value) && block_value) { seg_get(&aspflag, (char *)&af, r, c); FLAG_SET(af.flag, RUSLEBLOCKFLAG); seg_put(&aspflag, (char *)&af, r, c); } } } G_percent(nrows, nrows, 1); /* finish it */ Rast_close(fd); G_free(buf); } if (ril_flag) { dseg_open(&ril, seg_rows, seg_cols, num_open_segs); dseg_read_cell(&ril, ril_name, ""); } /* dseg_open(&slp, SROW, SCOL, num_open_segs); */ dseg_open(&s_l, seg_rows, seg_cols, num_open_segs); if (sg_flag) dseg_open(&s_g, seg_rows, seg_cols, num_open_segs); if (ls_flag) dseg_open(&l_s, seg_rows, seg_cols, num_open_segs); } G_debug(1, "open segments for A* points"); /* columns per segment */ seg_cols = seg_rows * seg_rows; num_cseg_total = do_points / seg_cols; if (do_points % seg_cols > 0) num_cseg_total++; /* no need to have more segments open than exist */ num_open_array_segs = num_open_segs / 16.; if (num_open_array_segs > num_cseg_total) num_open_array_segs = num_cseg_total; if (num_open_array_segs < 1) num_open_array_segs = 1; seg_open(&astar_pts, 1, do_points, 1, seg_cols, num_open_array_segs, sizeof(POINT)); /* one-based d-ary search_heap with astar_pts */ G_debug(1, "open segments for A* search heap"); G_debug(1, "heap memory %.2f MB", heap_mem); /* columns per segment */ /* larger is faster */ seg_cols = seg_rows * seg_rows; num_cseg_total = do_points / seg_cols; if (do_points % seg_cols > 0) num_cseg_total++; /* no need to have more segments open than exist */ num_open_array_segs = (1 << 20) * heap_mem / (seg_cols * sizeof(HEAP_PNT)); if (num_open_array_segs > num_cseg_total) num_open_array_segs = num_cseg_total; if (num_open_array_segs < 2) num_open_array_segs = 2; G_debug(1, "A* search heap open segments %d, total %d", num_open_array_segs, num_cseg_total); /* the search heap will not hold more than 5% of all points at any given time ? */ /* chances are good that the heap will fit into one large segment */ seg_open(&search_heap, 1, do_points + 1, 1, seg_cols, num_open_array_segs, sizeof(HEAP_PNT)); G_message(_("SECTION 1b: Determining Offmap Flow.")); /* heap is empty */ heap_size = 0; if (pit_flag) { buf = Rast_allocate_c_buf(); fd = Rast_open_old(pit_name, ""); } else buf = NULL; first_astar = first_cum = -1; for (r = 0; r < nrows; r++) { G_percent(r, nrows, 1); if (pit_flag) Rast_get_c_row(fd, buf, r); for (c = 0; c < ncols; c++) { seg_get(&aspflag, (char *)&af, r, c); if (!FLAG_GET(af.flag, NULLFLAG)) { if (er_flag) dseg_put(&s_l, &half_res, r, c); asp_value = af.asp; if (r == 0 || c == 0 || r == nrows - 1 || c == ncols - 1) { /* dseg_get(&wat, &wat_value, r, c); */ seg_get(&watalt, (char *)&wa, r, c); wat_value = wa.wat; if (wat_value > 0) { wat_value = -wat_value; /* dseg_put(&wat, &wat_value, r, c); */ wa.wat = wat_value; seg_put(&watalt, (char *)&wa, r, c); } if (r == 0) asp_value = -2; else if (c == 0) asp_value = -4; else if (r == nrows - 1) asp_value = -6; else if (c == ncols - 1) asp_value = -8; /* cseg_get(&alt, &alt_value, r, c); */ alt_value = wa.ele; add_pt(r, c, alt_value); FLAG_SET(af.flag, INLISTFLAG); FLAG_SET(af.flag, EDGEFLAG); af.asp = asp_value; seg_put(&aspflag, (char *)&af, r, c); } else { seg_get(&watalt, (char *)&wa, r, c); for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; seg_get(&aspflag, (char *)&af_nbr, r_nbr, c_nbr); if (FLAG_GET(af_nbr.flag, NULLFLAG)) { af.asp = -1 * drain[r - r_nbr + 1][c - c_nbr + 1]; add_pt(r, c, wa.ele); FLAG_SET(af.flag, INLISTFLAG); FLAG_SET(af.flag, EDGEFLAG); seg_put(&aspflag, (char *)&af, r, c); wat_value = wa.wat; if (wat_value > 0) { wa.wat = -wat_value; seg_put(&watalt, (char *)&wa, r, c); } break; } } } /* real depression ? */ if (pit_flag && asp_value == 0) { if (!Rast_is_c_null_value(&buf[c]) && buf[c] != 0) { seg_get(&watalt, (char *)&wa, r, c); add_pt(r, c, wa.ele); FLAG_SET(af.flag, INLISTFLAG); FLAG_SET(af.flag, EDGEFLAG); seg_put(&aspflag, (char *)&af, r, c); wat_value = wa.wat; if (wat_value > 0) { wa.wat = -wat_value; seg_put(&watalt, (char *)&wa, r, c); } } } } /* end non-NULL cell */ } /* end column */ } G_percent(r, nrows, 1); /* finish it */ return 0; }
int calculate(int fd, area_des ad, struct Cell_head hd, double *result) { CELL *buf; CELL *buf_sup; CELL corrCell; CELL precCell; CELL supCell; int i, j; int mask_fd = -1, *mask_buf; int ris = 0; int masked = FALSE; long npatch = 0; long tot = 0; long zero = 0; long uno = 1; long idCorr = 0; long lastId = 0; long doppi = 0; long *mask_patch_sup; long *mask_patch_corr; double indice = 0; double area = 0; /*if all cells are null area=0 */ double areaCorrect = 0; double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; avlID_tree albero = NULL; avlID_table *array; /* open mask if needed */ if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return RLI_ERRORE; mask_buf = G_malloc(ad->cl * sizeof(int)); if (mask_buf == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } masked = TRUE; } mask_patch_sup = G_malloc(ad->cl * sizeof(long)); if (mask_patch_sup == NULL) { G_fatal_error("malloc mask_patch_sup failed"); return RLI_ERRORE; } mask_patch_corr = G_malloc(ad->cl * sizeof(long)); if (mask_patch_corr == NULL) { G_fatal_error("malloc mask_patch_corr failed"); return RLI_ERRORE; } buf_sup = Rast_allocate_c_buf(); if (buf_sup == NULL) { G_fatal_error("malloc buf_sup failed"); return RLI_ERRORE; } buf = Rast_allocate_c_buf(); if (buf == NULL) { G_fatal_error("malloc buf failed"); return RLI_ERRORE; } Rast_set_c_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */ for (i = 0; i < ad->cl; i++) { mask_patch_sup[i] = 0; mask_patch_corr[i] = 0; } /*for each raster row */ for (j = 0; j < ad->rl; j++) { if (j > 0) { buf_sup = RLI_get_cell_raster_row(fd, j - 1 + ad->y, ad); } buf = RLI_get_cell_raster_row(fd, j + ad->y, ad); if (masked) { if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) { G_fatal_error("mask read failed"); return RLI_ERRORE; } } Rast_set_c_null_value(&precCell, 1); for (i = 0; i < ad->cl; i++) { /*for each cell in the row */ corrCell = buf[i + ad->x]; if ((masked) && (mask_buf[i + ad->x] == 0)) { Rast_set_c_null_value(&corrCell, 1); } /*valid cell */ if (!(Rast_is_null_value(&corrCell, CELL_TYPE))) { area++; if (i > 0) precCell = buf[i - 1 + ad->x]; if (j == 0) Rast_set_c_null_value(&supCell, 1); else supCell = buf_sup[i + ad->x]; if (corrCell != precCell) { if (corrCell != supCell) { /*new patch */ if (idCorr == 0) { /*first patch */ lastId = 1; idCorr = 1; mask_patch_corr[i] = idCorr; } else { /*not first patch */ /* put in the tree previous values */ if (albero == NULL) { albero = avlID_make(idCorr, uno); if (albero == NULL) { G_fatal_error("avlID_make error"); return RLI_ERRORE; } npatch++; } else { /* tree not null */ ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error ("avlID_add unknown error"); return RLI_ERRORE; } } } lastId++; idCorr = lastId; mask_patch_corr[i] = idCorr; } } else { /*current cell and upper cell are equal */ if ((corrCell == precCell) && (mask_patch_sup[i] != mask_patch_corr[i - 1])) { long r = 0; long del = mask_patch_sup[i]; r = avlID_sub(&albero, del); if (r == 0) { G_fatal_error("avlID_sub error"); return RLI_ERRORE; } /*Remove one patch because it makes part of a patch already found */ ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avlID_add unknown error"); return RLI_ERRORE; } } r = i; while (i < ad->cl) { if (mask_patch_sup[r] == del) { mask_patch_sup[r] = idCorr; } else { r = ad->cl + 1; } } } if (albero == NULL) { albero = avlID_make(idCorr, uno); if (albero == NULL) { G_fatal_error("avlID_make error"); return RLI_ERRORE; } npatch++; } else { /* tree not null */ ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avlID_add unknown error"); return RLI_ERRORE; } } } idCorr = mask_patch_sup[i]; mask_patch_corr[i] = idCorr; } } else { /*current cell and previous cell are equal */ if ((corrCell == supCell) && (mask_patch_sup[i] != mask_patch_corr[i - 1])) { int l; mask_patch_corr[i] = mask_patch_sup[i]; l = i - 1; while (l >= 0) { if (mask_patch_corr[l] == idCorr) { mask_patch_corr[l] = mask_patch_sup[i]; l--; } else { l = (-1); } } lastId--; idCorr = mask_patch_sup[i]; } else { mask_patch_corr[i] = idCorr; } } } else { /*cell not to consider or cell is null */ mask_patch_corr[i] = 0; } } mask_patch_sup = mask_patch_corr; } if (area != 0) { if (albero == NULL) { albero = avlID_make(idCorr, uno); if (albero == NULL) { G_fatal_error("avlID_make error"); return RLI_ERRORE; } npatch++; } else { ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avlID_add unknown error"); return RLI_ERRORE; } } } array = G_malloc(npatch * sizeof(avlID_tableRow)); if (array == NULL) { G_fatal_error("malloc array failed"); return RLI_ERRORE; } tot = avlID_to_array(albero, zero, array); if (tot != npatch) { G_warning ("avlID_to_array unaspected value. the result could be wrong"); return RLI_ERRORE; } for (i = 0; i < npatch; i++) { if (array[i]->tot == 0) doppi++; } npatch = npatch - doppi; /*calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area); indice = areaCorrect / npatch; G_free(array); } else indice = (double)(0); *result = indice; if (masked) G_free(mask_buf); G_free(mask_patch_corr); G_free(buf_sup); return RLI_OK; }
int open_files(struct globals *globals) { struct Ref Ref; /* group reference list */ int *in_fd, bounds_fd, is_null; int n, row, col, srows, scols, inlen, outlen, nseg; DCELL **inbuf; /* buffers to store lines from each of the imagery group rasters */ CELL *boundsbuf, bounds_val; int have_bounds = 0; CELL s, id; struct Range range; /* min/max values of bounds map */ struct FPRange *fp_range; /* min/max values of each input raster */ DCELL *min, *max; struct ngbr_stats Ri, Rk; /*allocate memory for flags */ globals->null_flag = flag_create(globals->nrows, globals->ncols); globals->candidate_flag = flag_create(globals->nrows, globals->ncols); flag_clear_all(globals->null_flag); flag_clear_all(globals->candidate_flag); G_debug(1, "Checking image group..."); /* ****** open the input rasters ******* */ if (!I_get_group_ref(globals->image_group, &Ref)) G_fatal_error(_("Group <%s> not found in the current mapset"), globals->image_group); if (Ref.nfiles <= 0) G_fatal_error(_("Group <%s> contains no raster maps"), globals->image_group); /* Read Imagery Group */ in_fd = G_malloc(Ref.nfiles * sizeof(int)); inbuf = (DCELL **) G_malloc(Ref.nfiles * sizeof(DCELL *)); fp_range = G_malloc(Ref.nfiles * sizeof(struct FPRange)); min = G_malloc(Ref.nfiles * sizeof(DCELL)); max = G_malloc(Ref.nfiles * sizeof(DCELL)); G_debug(1, "Opening input rasters..."); for (n = 0; n < Ref.nfiles; n++) { inbuf[n] = Rast_allocate_d_buf(); in_fd[n] = Rast_open_old(Ref.file[n].name, Ref.file[n].mapset); } /* Get min/max values of each input raster for scaling */ globals->max_diff = 0.; globals->nbands = Ref.nfiles; for (n = 0; n < Ref.nfiles; n++) { /* returns -1 on error, 2 on empty range, quitting either way. */ if (Rast_read_fp_range(Ref.file[n].name, Ref.file[n].mapset, &fp_range[n]) != 1) G_fatal_error(_("No min/max found in raster map <%s>"), Ref.file[n].name); Rast_get_fp_range_min_max(&(fp_range[n]), &min[n], &max[n]); G_debug(1, "Range for layer %d: min = %f, max = %f", n, min[n], max[n]); } if (globals->weighted == FALSE) globals->max_diff = Ref.nfiles; else { /* max difference with selected similarity method */ Ri.mean = max; Rk.mean = min; globals->max_diff = 1; globals->max_diff = (*globals->calculate_similarity) (&Ri, &Rk, globals); } /* ********** find out file segmentation size ************ */ G_debug(1, "Calculate temp file sizes..."); /* size of each element to be stored */ inlen = sizeof(DCELL) * Ref.nfiles; outlen = sizeof(CELL); G_debug(1, "data element size, in: %d , out: %d ", inlen, outlen); globals->datasize = sizeof(double) * globals->nbands; /* count non-null cells */ globals->notnullcells = (long)globals->nrows * globals->ncols; for (row = 0; row < globals->nrows; row++) { for (n = 0; n < Ref.nfiles; n++) { Rast_get_d_row(in_fd[n], inbuf[n], row); } for (col = 0; col < globals->ncols; col++) { is_null = 0; /*Assume there is data */ for (n = 0; n < Ref.nfiles; n++) { if (Rast_is_d_null_value(&inbuf[n][col])) { is_null = 1; } } if (is_null) { globals->notnullcells--; FLAG_SET(globals->null_flag, row, col); } } } G_verbose_message(_("Non-NULL cells: %ld"), globals->notnullcells); if (globals->notnullcells < 2) G_fatal_error(_("Insufficient number of non-NULL cells in current region")); /* segment lib segment size */ srows = 64; scols = 64; nseg = manage_memory(srows, scols, globals); /* create segment structures */ if (Segment_open (&globals->bands_seg, G_tempfile(), globals->nrows, globals->ncols, srows, scols, inlen, nseg) != 1) G_fatal_error("Unable to create input temporary files"); if (Segment_open (&globals->rid_seg, G_tempfile(), globals->nrows, globals->ncols, srows, scols, outlen, nseg * 2) != 1) G_fatal_error("Unable to create input temporary files"); /* load input bands to segment structure */ if (Ref.nfiles > 1) G_message(_("Loading input bands...")); else G_message(_("Loading input band...")); globals->bands_val = (double *)G_malloc(inlen); globals->second_val = (double *)G_malloc(inlen); /* initial segment ID */ s = 1; globals->row_min = globals->nrows; globals->row_max = 0; globals->col_min = globals->ncols; globals->col_max = 0; for (row = 0; row < globals->nrows; row++) { G_percent(row, globals->nrows, 4); for (n = 0; n < Ref.nfiles; n++) { Rast_get_d_row(in_fd[n], inbuf[n], row); } for (col = 0; col < globals->ncols; col++) { is_null = 0; /*Assume there is data */ for (n = 0; n < Ref.nfiles; n++) { globals->bands_val[n] = inbuf[n][col]; if (Rast_is_d_null_value(&inbuf[n][col])) { is_null = 1; } else { if (globals->weighted == FALSE) /* scaled version */ globals->bands_val[n] = (inbuf[n][col] - min[n]) / (max[n] - min[n]); } } if (Segment_put(&globals->bands_seg, (void *)globals->bands_val, row, col) != 1) G_fatal_error(_("Unable to write to temporary file")); if (!is_null) { if (!globals->seeds) { /* sequentially number all cells with a unique segment ID */ id = s; s++; } /* get min/max row/col to narrow the processing window */ if (globals->row_min > row) globals->row_min = row; if (globals->row_max < row) globals->row_max = row; if (globals->col_min > col) globals->col_min = col; if (globals->col_max < col) globals->col_max = col; } else { /* all input bands NULL */ Rast_set_c_null_value(&id, 1); FLAG_SET(globals->null_flag, row, col); } if (!globals->seeds || is_null) { if (Segment_put(&globals->rid_seg, (void *)&id, row, col) != 1) G_fatal_error(_("Unable to write to temporary file")); } } } G_percent(1, 1, 1); G_debug(1, "nrows: %d, min row: %d, max row %d", globals->nrows, globals->row_min, globals->row_max); G_debug(1, "ncols: %d, min col: %d, max col %d", globals->ncols, globals->col_min, globals->col_max); globals->row_max++; globals->col_max++; globals->ncells = (long)(globals->row_max - globals->row_min) * (globals->col_max - globals->col_min); /* bounds/constraints */ Rast_set_c_null_value(&globals->upper_bound, 1); Rast_set_c_null_value(&globals->lower_bound, 1); if (globals->bounds_map != NULL) { if (Segment_open (&globals->bounds_seg, G_tempfile(), globals->nrows, globals->ncols, srows, scols, sizeof(CELL), nseg) != TRUE) G_fatal_error("Unable to create bounds temporary files"); if (Rast_read_range(globals->bounds_map, globals->bounds_mapset, &range) != 1) G_fatal_error(_("No min/max found in raster map <%s>"), globals->bounds_map); Rast_get_range_min_max(&range, &globals->upper_bound, &globals->lower_bound); if (Rast_is_c_null_value(&globals->upper_bound) || Rast_is_c_null_value(&globals->lower_bound)) { G_fatal_error(_("No min/max found in raster map <%s>"), globals->bounds_map); } bounds_fd = Rast_open_old(globals->bounds_map, globals->bounds_mapset); boundsbuf = Rast_allocate_c_buf(); for (row = 0; row < globals->nrows; row++) { Rast_get_c_row(bounds_fd, boundsbuf, row); for (col = 0; col < globals->ncols; col++) { bounds_val = boundsbuf[col]; if (FLAG_GET(globals->null_flag, row, col)) { Rast_set_c_null_value(&bounds_val, 1); } else { if (!Rast_is_c_null_value(&bounds_val)) { have_bounds = 1; if (globals->lower_bound > bounds_val) globals->lower_bound = bounds_val; if (globals->upper_bound < bounds_val) globals->upper_bound = bounds_val; } } if (Segment_put(&globals->bounds_seg, &bounds_val, row, col) != 1) G_fatal_error(_("Unable to write to temporary file")); } } Rast_close(bounds_fd); G_free(boundsbuf); if (!have_bounds) { G_warning(_("There are no boundary constraints in '%s'"), globals->bounds_map); Rast_set_c_null_value(&globals->upper_bound, 1); Rast_set_c_null_value(&globals->lower_bound, 1); Segment_close(&globals->bounds_seg); globals->bounds_map = NULL; globals->bounds_mapset = NULL; } } else { G_debug(1, "no boundary constraint supplied."); } /* other info */ globals->candidate_count = 0; /* counter for remaining candidate pixels */ /* Free memory */ for (n = 0; n < Ref.nfiles; n++) { G_free(inbuf[n]); Rast_close(in_fd[n]); } globals->rs.sum = G_malloc(globals->datasize); globals->rs.mean = G_malloc(globals->datasize); globals->reg_tree = rgtree_create(globals->nbands, globals->datasize); globals->n_regions = s - 1; if (globals->seeds) { load_seeds(globals, srows, scols, nseg); } G_debug(1, "Number of initial regions: %d", globals->n_regions); G_free(inbuf); G_free(in_fd); G_free(fp_range); G_free(min); G_free(max); return TRUE; }
int main(int argc, char **argv) { struct GModule *module; struct Option *opt_out; struct Option *opt_lev; struct Flag *flg_d; struct Flag *flg_c; int dither; char *out_name; int out_file; CELL *out_array; struct Colors out_colors; int levels; int atrow, atcol; struct Cell_head window; unsigned char *dummy, *nulls; int i, j; struct History history; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("composite")); G_add_keyword("RGB"); module->description = _("Combines red, green and blue raster maps into " "a single composite raster map."); for (i = 0; i < 3; i++) { struct Option *opt; char buff[80]; B[i].opt_name = opt = G_define_standard_option(G_OPT_R_INPUT); sprintf(buff, "%s", color_names[i]); opt->key = G_store(buff); opt->answer = NULL; sprintf(buff, _("Name of raster map to be used for <%s>"), color_names[i]); opt->description = G_store(buff); } opt_lev = G_define_option(); opt_lev->key = "levels"; opt_lev->type = TYPE_INTEGER; opt_lev->required = NO; opt_lev->options = "1-256"; opt_lev->answer = "32"; opt_lev->description = _("Number of levels to be used for each component"); opt_lev->guisection = _("Levels"); for (i = 0; i < 3; i++) { struct Option *opt; char buff[80]; B[i].opt_levels = opt = G_define_option(); sprintf(buff, "lev_%s", color_names[i]); opt->key = G_store(buff); opt->type = TYPE_INTEGER; opt->required = NO; opt->options = "1-256"; sprintf(buff, _("Number of levels to be used for <%s>"), color_names[i]); opt->description = G_store(buff); opt->guisection = _("Levels"); } opt_out = G_define_standard_option(G_OPT_R_OUTPUT); flg_d = G_define_flag(); flg_d->key = 'd'; flg_d->description = _("Dither"); flg_c = G_define_flag(); flg_c->key = 'c'; flg_c->description = _("Use closest color"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); levels = atoi(opt_lev->answer); dither = flg_d->answer; closest = flg_c->answer; /* read in current window */ G_get_window(&window); dummy = G_malloc(window.cols); nulls = G_malloc(window.cols); for (i = 0; i < 3; i++) { struct band *b = &B[i]; /* Get name of layer to be used */ b->name = b->opt_name->answer; /* Make sure map is available */ b->file = Rast_open_old(b->name, ""); b->type = Rast_get_map_type(b->file); b->size = Rast_cell_size(b->type); /* Reading color lookup table */ if (Rast_read_colors(b->name, "", &b->colors) == -1) G_fatal_error(_("Unable to read color file of raster map <%s>"), b->name); for (j = 0; j < 3; j++) b->array[j] = (i == j) ? G_malloc(window.cols) : dummy; b->levels = b->opt_levels->answer ? atoi(b->opt_levels->answer) : levels; b->maxlev = b->levels - 1; b->offset = 128 / b->maxlev; if (dither) for (j = 0; j < 2; j++) b->floyd[j] = G_calloc(window.cols + 2, sizeof(short)); } /* open output files */ out_name = opt_out->answer; out_file = Rast_open_c_new(out_name); out_array = Rast_allocate_c_buf(); /* Make color table */ make_color_cube(&out_colors); G_message(_("Writing raster map <%s>..."), out_name); for (atrow = 0; atrow < window.rows; atrow++) { G_percent(atrow, window.rows, 2); for (i = 0; i < 3; i++) { struct band *b = &B[i]; Rast_get_row_colors(b->file, atrow, &b->colors, b->array[0], b->array[1], b->array[2], nulls); if (dither) { short *tmp = b->floyd[0]; b->floyd[0] = b->floyd[1]; for (atcol = 0; atcol < window.cols + 2; atcol++) tmp[atcol] = 0; b->floyd[1] = tmp; } } for (atcol = 0; atcol < window.cols; atcol++) { int val[3]; if (nulls[atcol]) { Rast_set_c_null_value(&out_array[atcol], 1); continue; } for (i = 0; i < 3; i++) { struct band *b = &B[i]; int v = b->array[i][atcol]; if (dither) { int r, w, d; v += b->floyd[0][atcol + 1] / 16; v = (v < 0) ? 0 : (v > 255) ? 255 : v; r = quantize(i, v); w = r * 255 / b->maxlev; d = v - w; b->floyd[0][atcol + 2] += 7 * d; b->floyd[1][atcol + 0] += 3 * d; b->floyd[1][atcol + 1] += 5 * d; b->floyd[1][atcol + 2] += 1 * d; val[i] = r; } else val[i] = quantize(i, v); } out_array[atcol] = (CELL) (val[2] * B[1].levels + val[1]) * B[0].levels + val[0]; } Rast_put_row(out_file, out_array, CELL_TYPE); } G_percent(window.rows, window.rows, 1); /* Close the input files */ for (i = 0; i < 3; i++) Rast_close(B[i].file); /* Close the output file */ Rast_close(out_file); Rast_write_colors(out_name, G_mapset(), &out_colors); Rast_short_history(out_name, "raster", &history); Rast_command_history(&history); Rast_write_history(out_name, &history); G_done_msg(_("Raster map <%s> created."), out_name); exit(EXIT_SUCCESS); }
int close_maps(char *stream_rast, char *stream_vect, char *dir_rast) { int stream_fd, dir_fd, r, c, i; CELL *cell_buf1, *cell_buf2; struct History history; CELL stream_id; ASP_FLAG af; /* cheating... */ stream_fd = dir_fd = -1; cell_buf1 = cell_buf2 = NULL; G_message(_("Writing output raster maps...")); /* write requested output rasters */ if (stream_rast) { stream_fd = Rast_open_new(stream_rast, CELL_TYPE); cell_buf1 = Rast_allocate_c_buf(); } if (dir_rast) { dir_fd = Rast_open_new(dir_rast, CELL_TYPE); cell_buf2 = Rast_allocate_c_buf(); } for (r = 0; r < nrows; r++) { G_percent(r, nrows, 2); if (stream_rast) Rast_set_c_null_value(cell_buf1, ncols); /* reset row to all NULL */ if (dir_rast) Rast_set_c_null_value(cell_buf2, ncols); /* reset row to all NULL */ for (c = 0; c < ncols; c++) { if (stream_rast) { cseg_get(&stream, &stream_id, r, c); if (stream_id) cell_buf1[c] = stream_id; } if (dir_rast) { seg_get(&aspflag, (char *)&af, r, c); if (!FLAG_GET(af.flag, NULLFLAG)) { cell_buf2[c] = af.asp; } } } if (stream_rast) Rast_put_row(stream_fd, cell_buf1, CELL_TYPE); if (dir_rast) Rast_put_row(dir_fd, cell_buf2, CELL_TYPE); } G_percent(nrows, nrows, 2); /* finish it */ if (stream_rast) { Rast_close(stream_fd); G_free(cell_buf1); Rast_short_history(stream_rast, "raster", &history); Rast_command_history(&history); Rast_write_history(stream_rast, &history); } if (dir_rast) { struct Colors colors; Rast_close(dir_fd); G_free(cell_buf2); Rast_short_history(dir_rast, "raster", &history); Rast_command_history(&history); Rast_write_history(dir_rast, &history); Rast_init_colors(&colors); Rast_make_aspect_colors(&colors, -8, 8); Rast_write_colors(dir_rast, G_mapset(), &colors); } /* close stream vector */ if (stream_vect) { if (close_streamvect(stream_vect) < 0) G_fatal_error(_("Unable to write vector map <%s>"), stream_vect); } /* rearranging desk chairs on the Titanic... */ G_free(outlets); /* free stream nodes */ for (i = 1; i <= n_stream_nodes; i++) { if (stream_node[i].n_alloc > 0) { G_free(stream_node[i].trib); } } G_free(stream_node); return 1; }
int open_file(char *name) { int cell_file, buf_len; int i, row; CELL *buf; /* open raster map */ cell_file = Rast_open_old(name, ""); if (Rast_get_map_type(cell_file) != CELL_TYPE) { Rast_close(cell_file); G_fatal_error(_("Input raster must be of type CELL.")); } n_rows = Rast_window_rows(); n_cols = Rast_window_cols(); G_message(_("File %s -- %d rows X %d columns"), name, n_rows, n_cols); n_cols += (PAD << 1); /* copy raster map into our read/write file */ work_file_name = G_tempfile(); /* create the file and then open it for read and write */ close(creat(work_file_name, 0666)); if ((work_file = open(work_file_name, 2)) < 0) { unlink(work_file_name); G_fatal_error(_("%s: Unable to create temporary file <%s> -- errno = %d"), error_prefix, work_file_name, errno); } buf_len = n_cols * sizeof(CELL); buf = (CELL *) G_malloc(buf_len); Rast_set_c_null_value(buf, n_cols); for (i = 0; i < PAD; i++) { if (write(work_file, buf, buf_len) != buf_len) { unlink(work_file_name); G_fatal_error(_("%s: Error writing temporary file"), error_prefix); } } for (row = 0; row < n_rows; row++) { Rast_get_c_row(cell_file, buf + PAD, row); if (write(work_file, buf, buf_len) != buf_len) { unlink(work_file_name); G_fatal_error(_("%s: Error writing temporary file"), error_prefix); } } Rast_set_c_null_value(buf, n_cols); for (i = 0; i < PAD; i++) { if (write(work_file, buf, buf_len) != buf_len) { unlink(work_file_name); G_fatal_error(_("%s: Error writing temporary file"), error_prefix); } } n_rows += (PAD << 1); G_free(buf); Rast_close(cell_file); Rowio_setup(&row_io, work_file, MAX_ROW, n_cols * sizeof(CELL), read_row, write_row); return 0; }
/*! * \brief Initialize range structure * * Initializes the <i>range</i> structure for updates by * Rast_update_range() and Rast_row_update_range(). * * Must set a flag in the range structure that indicates that no * min/max have been defined - probably a <tt>"first"</tt> boolean * flag. * * \param range pointer to Range structure which holds range info */ void Rast_init_range(struct Range *range) { Rast_set_c_null_value(&(range->min), 1); Rast_set_c_null_value(&(range->max), 1); range->first_time = 1; }
int main(int argc, char **argv) { unsigned char *hue_n, *hue_r, *hue_g, *hue_b; unsigned char *int_n, *int_r; unsigned char *sat_n, *sat_r; unsigned char *dummy; CELL *r_array, *g_array, *b_array; char *name_h, *name_i, *name_s; int intensity; int saturation; int atrow, atcol; int hue_file; int int_file = 0; int int_used; int sat_file = 0; int sat_used; char *name_r, *name_g, *name_b; int r_file = 0; int r_used; int g_file = 0; int g_used; int b_file = 0; int b_used; struct Cell_head window; struct Colors hue_colors; struct Colors int_colors; struct Colors sat_colors; struct Colors gray_colors; struct History history; struct GModule *module; struct Option *opt_h, *opt_i, *opt_s; struct Option *opt_r, *opt_g, *opt_b; struct Flag *nulldraw; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("color transformation")); G_add_keyword(_("RGB")); G_add_keyword(_("HIS")); module->description = _("Generates red, green and blue raster map layers " "combining hue, intensity and saturation (HIS) " "values from user-specified input raster map layers."); opt_h = G_define_option(); opt_h->key = "h_map"; opt_h->type = TYPE_STRING; opt_h->required = YES; opt_h->gisprompt = "old,cell,raster"; opt_h->description = _("Name of layer to be used for HUE"); opt_i = G_define_option(); opt_i->key = "i_map"; opt_i->type = TYPE_STRING; opt_i->required = NO; opt_i->gisprompt = "old,cell,raster"; opt_i->description = _("Name of layer to be used for INTENSITY"); opt_s = G_define_option(); opt_s->key = "s_map"; opt_s->type = TYPE_STRING; opt_s->required = NO; opt_s->gisprompt = "old,cell,raster"; opt_s->description = _("Name of layer to be used for SATURATION"); opt_r = G_define_option(); opt_r->key = "r_map"; opt_r->type = TYPE_STRING; opt_r->required = YES; opt_r->gisprompt = "new,cell,raster"; opt_r->description = _("Name of output layer to be used for RED"); opt_g = G_define_option(); opt_g->key = "g_map"; opt_g->type = TYPE_STRING; opt_g->required = YES; opt_g->gisprompt = "new,cell,raster"; opt_g->description = _("Name of output layer to be used for GREEN"); opt_b = G_define_option(); opt_b->key = "b_map"; opt_b->type = TYPE_STRING; opt_b->required = YES; opt_b->gisprompt = "new,cell,raster"; opt_b->description = _("Name of output layer to be used for BLUE"); nulldraw = G_define_flag(); nulldraw->key = 'n'; nulldraw->description = _("Respect NULL values while drawing"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* read in current window */ G_get_window(&window); /* Get name of layer to be used for hue */ name_h = opt_h->answer; /* Make sure map is available */ hue_file = Rast_open_old(name_h, ""); hue_r = G_malloc(window.cols); hue_g = G_malloc(window.cols); hue_b = G_malloc(window.cols); hue_n = G_malloc(window.cols); dummy = G_malloc(window.cols); /* Reading color lookup table */ if (Rast_read_colors(name_h, "", &hue_colors) == -1) G_fatal_error(_("Color file for <%s> not available"), name_h); int_used = 0; if (opt_i->answer != NULL) { /* Get name of layer to be used for intensity */ name_i = opt_i->answer; int_used = 1; /* Make sure map is available */ int_file = Rast_open_old(name_i, ""); int_r = G_malloc(window.cols); int_n = G_malloc(window.cols); /* Reading color lookup table */ if (Rast_read_colors(name_i, "", &int_colors) == -1) G_fatal_error(_("Color file for <%s> not available"), name_i); } sat_used = 0; if (opt_s->answer != NULL) { /* Get name of layer to be used for saturation */ name_s = opt_s->answer; sat_used = 1; /* Make sure map is available */ sat_file = Rast_open_old(name_s, ""); sat_r = G_malloc(window.cols); sat_n = G_malloc(window.cols); /* Reading color lookup table */ if (Rast_read_colors(name_s, "", &sat_colors) == -1) G_fatal_error(_("Color file for <%s> not available"), name_s); } r_used = 0; if (opt_r->answer != NULL) { name_r = opt_r->answer; r_file = Rast_open_c_new(name_r); r_used = 1; } g_used = 0; if (opt_g->answer != NULL) { name_g = opt_g->answer; g_file = Rast_open_c_new(name_g); g_used = 1; } b_used = 0; if (opt_b->answer != NULL) { name_b = opt_b->answer; b_file = Rast_open_c_new(name_b); b_used = 1; } r_array = Rast_allocate_c_buf(); g_array = Rast_allocate_c_buf(); b_array = Rast_allocate_c_buf(); /* Make color table */ make_gray_scale(&gray_colors); /* Now do the work */ intensity = 255; /* default is to not change intensity */ saturation = 255; /* default is to not change saturation */ for (atrow = 0; atrow < window.rows; atrow++) { G_percent(atrow, window.rows, 2); Rast_get_row_colors(hue_file, atrow, &hue_colors, hue_r, hue_g, hue_b, hue_n); if (int_used) Rast_get_row_colors(int_file, atrow, &int_colors, int_r, dummy, dummy, int_n); if (sat_used) Rast_get_row_colors(sat_file, atrow, &sat_colors, sat_r, dummy, dummy, sat_n); for (atcol = 0; atcol < window.cols; atcol++) { if (nulldraw->answer) { if (hue_n[atcol] || (int_used && int_n[atcol]) || (sat_used && sat_n[atcol])) { Rast_set_c_null_value(&r_array[atcol], 1); Rast_set_c_null_value(&g_array[atcol], 1); Rast_set_c_null_value(&b_array[atcol], 1); continue; } } if (int_used) intensity = int_r[atcol]; if (sat_used) saturation = sat_r[atcol]; HIS_to_RGB(hue_r[atcol], hue_g[atcol], hue_b[atcol], intensity, saturation, &r_array[atcol], &g_array[atcol], &b_array[atcol]); } if (r_used) Rast_put_row(r_file, r_array, CELL_TYPE); if (g_used) Rast_put_row(g_file, g_array, CELL_TYPE); if (b_used) Rast_put_row(b_file, b_array, CELL_TYPE); } G_percent(window.rows, window.rows, 5); /* Close the cell files */ Rast_close(hue_file); if (int_used) Rast_close(int_file); if (sat_used) Rast_close(sat_file); if (r_used) { Rast_close(r_file); Rast_write_colors(name_r, G_mapset(), &gray_colors); Rast_short_history(name_r, "raster", &history); Rast_command_history(&history); Rast_write_history(name_r, &history); Rast_put_cell_title(name_r, "Red extracted from HIS"); } if (g_used) { Rast_close(g_file); Rast_write_colors(name_g, G_mapset(), &gray_colors); Rast_short_history(name_g, "raster", &history); Rast_command_history(&history); Rast_write_history(name_g, &history); Rast_put_cell_title(name_g, "Green extracted from HIS"); } if (b_used) { Rast_close(b_file); Rast_write_colors(name_b, G_mapset(), &gray_colors); Rast_short_history(name_b, "raster", &history); Rast_command_history(&history); Rast_write_history(name_b, &history); Rast_put_cell_title(name_b, "Blue extracted from HIS"); } return EXIT_SUCCESS; }
int bar(struct stat_list *dist_stats, /* list of distribution statistics */ struct Colors *colors) { struct stat_node *ptr; int draw = YES; long int bar_height; /* height, in pixels, of a histogram bar */ CELL bar_color; /* color/category number of a histogram bar */ DCELL dmax, range_dmin, range_dmax, dmin, dval; long int max_tics; /* maximum tics allowed on an axis */ long int xoffset; /* offset for x-axis */ long int yoffset; /* offset for y-axis */ long int stat_start; long int stat_finis; int text_height; int text_width; long int i, j; long int num_cats = 0; long int num_stats = 0; long int tic_every; /* spacing, in units of category value, of tics */ long int tic_unit; double t, b, l, r; double tt, tb, tl, tr; double x_line[3]; /* for border of histogram */ double y_line[3]; double x_box[5]; /* for histogram bar coordinates */ double y_box[5]; double height, width; double xscale; /* scaling factors */ double yscale; char xlabel[1024]; char ylabel[1024]; char txt[1024]; char tic_name[80]; /* get coordinates of current screen window */ D_get_src(&t, &b, &l, &r); /* create axis lines, to be drawn later */ height = b - t; width = r - l; x_line[0] = x_line[1] = l + (ORIGIN_X * width); x_line[2] = l + (XAXIS_END * width); y_line[0] = b - (YAXIS_END * height); y_line[1] = y_line[2] = b - (ORIGIN_Y * height); /* figure scaling factors and offsets */ num_cats = dist_stats->maxcat - dist_stats->mincat + 1; if (nodata) { num_cats++; dist_stats->mincat--; } xscale = ((x_line[2] - x_line[1]) / ((double)num_cats)); yscale = ((y_line[1] - y_line[0])) / dist_stats->maxstat; if (num_cats >= x_line[2] - x_line[1]) xoffset = (long int)x_line[1]; else xoffset = (long int)x_line[0] + 0.5 * xscale; /* boxes need extra space */ yoffset = (double)(y_line[1]); /* figure tic_every and tic_units for the x-axis of the bar-chart. * tic_every tells how often to place a tic-number. tic_unit tells * the unit to use in expressing tic-numbers. */ if (xscale < XTIC_DIST) { max_tics = (x_line[2] - x_line[1]) / XTIC_DIST; if (nodata) max_tics--; i = 0; if (is_fp) { Rast_get_fp_range_min_max(&fp_range, &range_dmin, &range_dmax); if (Rast_is_d_null_value(&range_dmin) || Rast_is_d_null_value(&range_dmax)) G_fatal_error("Floating point data range is empty"); if ((range_dmax - range_dmin) < 1.0) tics[i].every = 5; if ((range_dmax - range_dmin) < 110) tics[i].every = 20; /* dirrty hack */ while ((range_dmax - range_dmin) / tics[i].every > max_tics) i++; } else { while ((num_cats / tics[i].every) > max_tics) i++; } tic_every = tics[i].every; tic_unit = tics[i].unit; strcpy(tic_name, tics[i].name); } else { if (is_fp && !cat_ranges) { Rast_get_fp_range_min_max(&fp_range, &range_dmin, &range_dmax); if (Rast_is_d_null_value(&range_dmin) || Rast_is_d_null_value(&range_dmax)) G_fatal_error("Floating point data range is empty"); } tic_every = 1; tic_unit = 1; } /* X-AXIS LOOP * * loop through category range, drawing a pie-slice and a * legend bar on each iteration evenly divisible, a tic-mark * on those evenly divisible by tic_unit, and a tic_mark * number on those evenly divisible by tic_every * */ ptr = dist_stats->ptr; for (i = dist_stats->mincat; i <= dist_stats->maxcat; i++) { if (!ptr) break; draw = NO; /* figure bar color and height * * the cat number determines the color, the corresponding stat, * determines the bar height. if a stat cannot be found for the * cat, then it doesn't drow anything, before it used to draw the * box of size 0 in black. Later when the option to provide the * background color will be added , we might still draw a box in * this color. */ if (nodata && i == dist_stats->mincat) { if (dist_stats->null_stat == 0 && xscale > 1) draw = NO; else { draw = YES; Rast_set_c_null_value(&bar_color, 1); bar_height = (yoffset - yscale * (double)dist_stats->null_stat); } } else if (ptr->cat == i) { /* AH-HA!! found the stat */ if (ptr->stat == 0 && xscale > 1) draw = NO; else { draw = YES; bar_color = ptr->cat; bar_height = (yoffset - yscale * (double)ptr->stat); } if (ptr->next != NULL) ptr = ptr->next; } else { /* we have to look for the stat */ /* loop until we find it, or pass where it should be */ while (ptr->cat < i && ptr->next != NULL) ptr = ptr->next; if (ptr->cat == i) { /* AH-HA!! found the stat */ if (ptr->stat == 0 && xscale > 1) draw = NO; else { draw = YES; bar_color = ptr->cat; bar_height = (yoffset - yscale * (double)ptr->stat); } if (ptr->next != NULL) ptr = ptr->next; } else { /* stat cannot be found */ if (xscale > 1) { draw = NO; #ifdef notdef draw = YES; bar_color = D_translate_color("black"); bar_height = yoffset; /* zero */ #endif } else draw = NO; } } /* draw the bar */ if (draw == YES) { if (xscale != 1) { /* draw the bar as a box */ if (!Rast_is_c_null_value(&bar_color) && is_fp) { if (cat_ranges) Rast_get_ith_d_cat(&cats, bar_color, &dmin, &dmax); else { dmin = range_dmin + i * (range_dmax - range_dmin) / nsteps; dmax = range_dmin + (i + 1) * (range_dmax - range_dmin) / nsteps; } if (dmin != dmax) { for (j = 0; j < xscale; j++) { dval = dmin + j * (dmax - dmin) / xscale; D_d_color(dval, colors); x_box[0] = x_box[1] = xoffset + ((i - dist_stats->mincat) * xscale - 0.5 * xscale + j); x_box[2] = x_box[3] = xoffset + ((i - dist_stats->mincat) * xscale - 0.5 * xscale + j + 1); y_box[0] = y_box[3] = yoffset; y_box[1] = y_box[2] = bar_height; D_polygon_abs(x_box, y_box, 4); } } else { /* 1-color bar */ D_d_color(dmin, colors); x_box[0] = x_box[1] = xoffset + ((i - dist_stats->mincat) * xscale - 0.5 * xscale); x_box[2] = x_box[3] = xoffset + ((i - dist_stats->mincat) * xscale + 0.5 * xscale); y_box[0] = y_box[3] = yoffset; y_box[1] = y_box[2] = bar_height; D_polygon_abs(x_box, y_box, 4); } } /* fp */ else { /* 1-color bar for int data or null */ D_color((CELL) bar_color, colors); x_box[0] = x_box[1] = xoffset + ((i - dist_stats->mincat) * xscale - 0.5 * xscale); x_box[2] = x_box[3] = xoffset + ((i - dist_stats->mincat) * xscale + 0.5 * xscale); y_box[0] = y_box[3] = yoffset; y_box[1] = y_box[2] = bar_height; D_polygon_abs(x_box, y_box, 4); } } else { /* draw the bar as a line */ if (is_fp) { if (cat_ranges) Rast_get_ith_d_cat(&cats, bar_color, &dmin, &dmax); else { dmin = range_dmin + i * (range_dmax - range_dmin) / nsteps; dmax = range_dmin + (i + 1) * (range_dmax - range_dmin) / nsteps; } D_d_color(dmin, colors); } else D_color((CELL) bar_color, colors); x_box[0] = x_box[1] = xoffset + (i - dist_stats->mincat) * xscale; y_box[0] = yoffset; y_box[1] = bar_height; D_line_abs(x_box[0], y_box[0], x_box[1], y_box[1]); } } /* draw x-axis tic-marks and numbers */ /* draw tick for null and for numbers at every tic step except when there is null, don't draw tic for mincat+1 */ if (((rem((long int)i, tic_every) == 0L) || ((i == dist_stats->mincat) && nodata)) && !(nodata && i == dist_stats->mincat + 1)) { /* draw a numbered tic-mark */ D_use_color(color); D_begin(); D_move_abs(xoffset + (i - dist_stats->mincat) * xscale - 0.5 * xscale, b - ORIGIN_Y * (b - t)); D_cont_rel(0, BIG_TIC * (b - t)); D_end(); D_stroke(); if (nodata && i == dist_stats->mincat) sprintf(txt, "null"); else if (is_fp) { dmin = range_dmin + i * (range_dmax - range_dmin) / nsteps; if ((tic_every * (range_dmax - range_dmin) / nsteps) < 1.0) sprintf(txt, "%.2f", dmin / (double)tic_unit); else sprintf(txt, "%d", (int)(dmin / (double)tic_unit)); } else sprintf(txt, "%d", (int)(i / tic_unit)); text_height = (b - t) * TEXT_HEIGHT; text_width = (r - l) * TEXT_WIDTH; D_text_size(text_width, text_height); D_get_text_box(txt, &tt, &tb, &tl, &tr); while ((tr - tl) > XTIC_DIST) { text_width *= 0.75; text_height *= 0.75; D_text_size(text_width, text_height); D_get_text_box(txt, &tt, &tb, &tl, &tr); } D_pos_abs(xoffset + (i - dist_stats->mincat) * xscale - 0.5 * xscale - (tr - tl) / 2, b - XNUMS_Y * (b - t)); D_text(txt); } else if (rem(i, tic_unit) == 0.0) { /* draw a tic-mark */ D_use_color(color); D_begin(); D_move_abs(xoffset + (i - dist_stats->mincat) * xscale - 0.5 * xscale, b - ORIGIN_Y * (b - t)); D_cont_rel(0, SMALL_TIC * (b - t)); D_end(); D_stroke(); } } /* draw the x-axis label */ if (tic_unit != 1) sprintf(xlabel, "X-AXIS: Cell Values %s", tic_name); else sprintf(xlabel, "X-AXIS: Cell Values"); text_height = (b - t) * TEXT_HEIGHT; text_width = (r - l) * TEXT_WIDTH; D_text_size(text_width, text_height); D_get_text_box(xlabel, &tt, &tb, &tl, &tr); D_pos_abs(l + (r - l) / 2 - (tr - tl) / 2, b - LABEL_1 * (b - t)); D_use_color(color); D_text(xlabel); /* DRAW Y-AXIS TIC-MARKS AND NUMBERS * * first, figure tic_every and tic_units for the x-axis of the bar-chart. * tic_every tells how often to place a tic-number. tic_unit tells * the unit to use in expressing tic-numbers. */ max_tics = (long)((y_line[1] - y_line[0]) / YTIC_DIST); if (dist_stats->maxstat == dist_stats->minstat) dist_stats->minstat = 0; /* LOOKS FUNNY TO ME */ num_stats = dist_stats->maxstat - dist_stats->minstat; i = 0; while ((num_stats / tics[i].every) > max_tics) i++; tic_every = tics[i].every; tic_unit = tics[i].unit; strcpy(tic_name, tics[i].name); stat_start = tic_unit * ((long)(dist_stats->minstat / tic_unit)); stat_finis = tic_unit * ((long)(dist_stats->maxstat / tic_unit)); /* Y-AXIS LOOP * */ for (i = stat_start; i <= stat_finis; i += tic_unit) { if (rem(i, tic_every) == (float)0) { /* draw a tic-mark */ D_begin(); D_move_abs(x_line[0], yoffset - yscale * i); D_cont_rel((-(r - l) * BIG_TIC), 0); D_end(); D_stroke(); /* draw a tic-mark number */ sprintf(txt, "%d", (int)(i / tic_unit)); text_height = (b - t) * TEXT_HEIGHT; text_width = (r - l) * TEXT_WIDTH; D_text_size(text_width, text_height); D_get_text_box(txt, &tt, &tb, &tl, &tr); while ((tt - tb) > YTIC_DIST) { text_width *= 0.75; text_height *= 0.75; D_text_size(text_width, text_height); D_get_text_box(txt, &tt, &tb, &tl, &tr); } D_pos_abs(l + (r - l) * YNUMS_X - (tr - tl) / 2, yoffset - (yscale * i + 0.5 * (tt - tb))); D_text(txt); } else if (rem(i, tic_unit) == 0.0) { /* draw a tic-mark */ D_begin(); D_move_abs(x_line[0], yoffset - yscale * i); D_cont_rel(-(r - l) * SMALL_TIC, 0); D_end(); D_stroke(); } } /* draw the y-axis label */ if (tic_unit != 1) { if (type == COUNT) sprintf(ylabel, "Y-AXIS: Number of cells %s", tic_name); else sprintf(ylabel, "Y-AXIS: Area %s sq. meters", tic_name); } else { if (type == COUNT) sprintf(ylabel, "Y-AXIS: Number of cells"); else sprintf(ylabel, "Y-AXIS: Area"); } text_height = (b - t) * TEXT_HEIGHT; text_width = (r - l) * TEXT_WIDTH; D_text_size(text_width, text_height); D_get_text_box(ylabel, &tt, &tb, &tl, &tr); D_pos_abs(l + (r - l) / 2 - (tr - tl) / 2, b - LABEL_2 * (b - t)); D_use_color(color); D_text(ylabel); /* draw x and y axis lines */ D_use_color(color); D_polyline_abs(x_line, y_line, 3); return 0; }
static int load_seeds(struct globals *globals, int srows, int scols, int nseg) { int row, col; SEGMENT seeds_seg; CELL *seeds_buf, seeds_val; int seeds_fd; int spos, sneg, have_seeds; struct rc Ri; G_debug(1, "load_seeds()"); G_message(_("Loading seeds from raster map <%s>..."), globals->seeds); if (Segment_open (&seeds_seg, G_tempfile(), globals->nrows, globals->ncols, srows, scols, sizeof(CELL), nseg) != TRUE) G_fatal_error("Unable to create bounds temporary files"); seeds_fd = Rast_open_old(globals->seeds, ""); seeds_buf = Rast_allocate_c_buf(); have_seeds = 0; /* load seeds map to segment structure */ for (row = 0; row < globals->nrows; row++) { Rast_get_c_row(seeds_fd, seeds_buf, row); for (col = 0; col < globals->ncols; col++) { if (FLAG_GET(globals->null_flag, row, col)) { Rast_set_c_null_value(&seeds_val, 1); } else { seeds_val = seeds_buf[col]; if (!Rast_is_c_null_value(&seeds_val)) have_seeds = 1; } if (Segment_put(&seeds_seg, &seeds_val, row, col) != 1) G_fatal_error(_("Unable to write to temporary file")); } } if (!have_seeds) { G_warning(_("No seeds found in '%s'!"), globals->seeds); G_free(seeds_buf); Rast_close(seeds_fd); Segment_close(&seeds_seg); return 0; } spos = 1; sneg = -1; /* convert seeds to regions */ G_debug(1, "convert seeds to regions"); Rast_set_c_null_value(&seeds_val, 1); for (row = 0; row < globals->nrows; row++) { Rast_get_c_row(seeds_fd, seeds_buf, row); for (col = 0; col < globals->ncols; col++) { if (!(FLAG_GET(globals->null_flag, row, col)) && !(FLAG_GET(globals->candidate_flag, row, col))) { if (Rast_is_c_null_value(&(seeds_buf[col]))) { if (Segment_put(&globals->rid_seg, &sneg, row, col) != 1) G_fatal_error(_("Unable to write to temporary file")); sneg--; globals->n_regions--; } else { Ri.row = row; Ri.col = col; read_seed(globals, &seeds_seg, &Ri, spos); spos++; } } } } G_free(seeds_buf); Rast_close(seeds_fd); Segment_close(&seeds_seg); globals->n_regions = spos - 1; flag_clear_all(globals->candidate_flag); return 1; }
int main(int argc, char **argv) { char *map_name; int color; int lines; int cols; struct FPRange fp_range; struct Colors colors; double ratio; DCELL dmin, dmax, dval; int cats_num; int cur_dot_row, cur_dot_col; int dots_per_line, dots_per_col; int atcat; int white, black; int atcol, atline; int count, offset; double t, b, l, r; int fp, new_colr; double x_box[5], y_box[5]; struct GModule *module; struct Option *opt1, *opt2, *opt3, *opt4; struct Flag *skip_null; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("raster")); module->description = _("Displays the color table associated with a raster map layer."); opt1 = G_define_standard_option(G_OPT_R_MAP); opt1->description = _("Name of raster map whose color table is to be displayed"); opt2 = G_define_option(); opt2->key = "color"; opt2->type = TYPE_STRING; opt2->answer = DEFAULT_BG_COLOR; opt2->gisprompt = "old_color,color,color"; opt2->description = _("Color of lines separating the colors of the color table"); opt3 = G_define_option(); opt3->key = "lines"; opt3->type = TYPE_INTEGER; opt3->options = "1-1000"; opt3->description = _("Number of lines to appear in the color table"); opt4 = G_define_option(); opt4->key = "cols"; opt4->type = TYPE_INTEGER; opt4->options = "1-1000"; opt4->description = _("Number of columns to appear in the color table"); skip_null = G_define_flag(); skip_null->key = 'n'; skip_null->description = _("Don't draw a collar showing the NULL color in FP maps"); /* Check command line */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); map_name = opt1->answer; fp = Rast_map_is_fp(map_name, ""); if (opt2->answer != NULL) { new_colr = D_translate_color(opt2->answer); color = new_colr; } if (fp) lines = 1; else lines = 0; if (opt3->answer != NULL) { if (fp) G_warning(_("<%s> is floating-point; " "ignoring [lines] and drawing continuous color ramp"), map_name); else sscanf(opt3->answer, "%d", &lines); } if (fp) cols = 1; else cols = 0; if (opt4->answer) { if (fp) G_warning(_("<%s> is floating-point; " "ignoring [cols] and drawing continuous color ramp"), map_name); else sscanf(opt4->answer, "%d", &cols); } /* Make sure map is available */ if (Rast_read_colors(map_name, "", &colors) == -1) G_fatal_error(_("Color file for <%s> not available"), map_name); if (Rast_read_fp_range(map_name, "", &fp_range) == -1) G_fatal_error(_("Range file for <%s> not available"), map_name); if (D_open_driver() != 0) G_fatal_error(_("No graphics device selected. " "Use d.mon to select graphics device.")); D_setup_unity(0); D_get_src(&t, &b, &l, &r); Rast_get_fp_range_min_max(&fp_range, &dmin, &dmax); if (Rast_is_d_null_value(&dmin) || Rast_is_d_null_value(&dmax)) G_fatal_error(_("Data range is empty")); cats_num = (int)dmax - (int)dmin + 1; if (lines <= 0 && cols <= 0) { double dx, dy; dy = (double)(b - t); dx = (double)(r - l); ratio = dy / dx; cols = 1 + sqrt((dmax - dmin + 1.) / ratio); lines = 1 + cats_num / cols; } else if (lines > 0 && cols <= 0) { cols = 1 + cats_num / lines; } else if (cols > 0 && lines <= 0) { lines = 1 + cats_num / cols; } /* otherwise, accept without complaint what the user requests * It is possible that the number of lines and cols is not * sufficient for the number of categories. */ dots_per_line = (b - t) / lines; dots_per_col = (r - l) / cols; x_box[0] = 0; y_box[0] = 0; x_box[1] = 0; y_box[1] = (6 - dots_per_line); x_box[2] = (dots_per_col - 6); y_box[2] = 0; x_box[3] = 0; y_box[3] = (dots_per_line - 6); x_box[4] = (6 - dots_per_col); y_box[4] = 0; white = D_translate_color("white"); black = D_translate_color("black"); Rast_set_c_null_value(&atcat, 1); if (!fp) { for (atcol = 0; atcol < cols; atcol++) { cur_dot_row = t; cur_dot_col = l + atcol * dots_per_col; count = 0; for (atline = 0; atline < lines; atline++) { cur_dot_row += dots_per_line; /* Draw outer border box */ D_use_color(color); D_begin(); D_move_abs(cur_dot_col + 2, (cur_dot_row - 1)); D_cont_rel(0, (2 - dots_per_line)); D_cont_rel((dots_per_col - 2), 0); D_cont_rel(0, (dots_per_line - 2)); D_cont_rel((2 - dots_per_col), 0); D_end(); D_stroke(); /* Draw black box */ D_use_color(black); D_begin(); D_move_abs(cur_dot_col + 3, (cur_dot_row - 2)); D_cont_rel(0, (4 - dots_per_line)); D_cont_rel((dots_per_col - 4), 0); D_cont_rel(0, (dots_per_line - 4)); D_cont_rel((4 - dots_per_col), 0); D_end(); D_stroke(); /* Color box */ D_color((CELL) atcat, &colors); D_pos_abs(cur_dot_col + 4, (cur_dot_row - 3)); D_polygon_rel(x_box, y_box, 5); count++; /* first cat number is null value */ if (count == 1) atcat = (int)dmin; else if (++atcat > (int)dmax) break; } if (atcat > (int)dmax) break; } /* col loop */ } /* int map */ else { /*** draw continuous color ramp for fp map ***/ cur_dot_row = t + dots_per_line; cur_dot_col = l; /* Draw outer border box */ D_use_color(color); D_begin(); D_move_abs(cur_dot_col + 1, (cur_dot_row - 1)); D_cont_rel(0, (2 - dots_per_line)); D_cont_rel((dots_per_col - 2), 0); D_cont_rel(0, (dots_per_line - 2)); D_cont_rel((2 - dots_per_col), 0); D_end(); D_stroke(); /* Draw black box */ D_use_color(black); D_begin(); D_move_abs(cur_dot_col + 2, (cur_dot_row - 2)); D_cont_rel(0, (4 - dots_per_line)); D_cont_rel((dots_per_col - 4), 0); D_cont_rel(0, (dots_per_line - 4)); D_cont_rel((4 - dots_per_col), 0); D_end(); D_stroke(); /* Color ramp box */ /* get separate color for each pixel */ /* fisrt 5 pixels draw null color */ y_box[1] = -1; y_box[3] = 1; x_box[2] = (dots_per_col - 6); x_box[4] = (6 - dots_per_col); G_debug(1, "dots_per_line: %d dmin=%.2f dmax=%.2f", dots_per_line, dmin, dmax); if (skip_null->answer) offset = 1; else offset = 4; for (r = 0; r < dots_per_line - 6; r++) { if ((r <= 4) && !skip_null->answer) Rast_set_d_null_value(&dval, 1); else dval = dmin + r*(dmax - dmin) / (dots_per_line - 6 - offset); D_d_color(dval, &colors); D_pos_abs(cur_dot_col + 3, (cur_dot_row - 3) - r); D_polygon_rel(x_box, y_box, 5); } } D_save_command(G_recreate_command()); D_close_driver(); exit(EXIT_SUCCESS); }
void filter_holes(Gfile * out) { int row, col, nrows, ncols; void *arast, *brast, *crast; int i, pixel[9], cold, warm, shadow, nulo, lim; Gfile tmp; nrows = Rast_window_rows(); ncols = Rast_window_cols(); if (nrows < 3 || ncols < 3) return; /* Open to read */ if ((out->fd = Rast_open_old(out->name, "")) < 0) G_fatal_error(_("Unable to open raster map <%s>"), out->name); arast = Rast_allocate_buf(CELL_TYPE); brast = Rast_allocate_buf(CELL_TYPE); crast = Rast_allocate_buf(CELL_TYPE); /* Open to write */ sprintf(tmp.name, "_%d.BBB", getpid()); tmp.rast = Rast_allocate_buf(CELL_TYPE); if ((tmp.fd = Rast_open_new(tmp.name, CELL_TYPE)) < 0) G_fatal_error(_("Unable to create raster map <%s>"), tmp.name); G_important_message(_("Filling small holes in clouds...")); /* Se puede acelerar creandolos nulos y luego arast = brast brast = crast y cargando crast solamente G_set_f_null_value(cell[2], ncols); */ for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); /* Read row values */ if (row != 0) { Rast_get_c_row(out->fd, arast, row - 1); } Rast_get_c_row(out->fd, brast, row); if (row != (nrows - 1)) { Rast_get_c_row(out->fd, crast, row + 1); } /* Analysis of all pixels */ for (col = 0; col < ncols; col++) { pixel[0] = pval(brast, col); if (pixel[0] == 0) { if (row == 0) { pixel[1] = -1; pixel[2] = -1; pixel[3] = -1; if (col == 0) { pixel[4] = -1; pixel[5] = pval(brast, col + 1); pixel[6] = -1; pixel[7] = pval(crast, col); pixel[8] = pval(crast, col + 1); } else if (col != (ncols - 1)) { pixel[4] = pval(brast, col - 1); pixel[5] = pval(brast, col + 1); pixel[6] = pval(crast, col - 1); pixel[7] = pval(crast, col); pixel[8] = pval(crast, col + 1); } else { pixel[4] = pval(brast, col - 1); pixel[5] = -1; pixel[6] = pval(crast, col - 1); pixel[7] = pval(crast, col); pixel[8] = -1; } } else if (row != (nrows - 1)) { if (col == 0) { pixel[1] = -1; pixel[2] = pval(arast, col); pixel[3] = pval(arast, col + 1); pixel[4] = -1; pixel[5] = pval(brast, col + 1); pixel[6] = -1; pixel[7] = pval(crast, col); pixel[8] = pval(crast, col + 1); } else if (col != (ncols - 1)) { pixel[1] = pval(arast, col - 1); pixel[2] = pval(arast, col); pixel[3] = pval(arast, col + 1); pixel[4] = pval(brast, col - 1); pixel[5] = pval(brast, col + 1); pixel[6] = pval(crast, col - 1); pixel[7] = pval(crast, col); pixel[8] = pval(crast, col + 1); } else { pixel[1] = pval(arast, col - 1); pixel[2] = pval(arast, col); pixel[3] = -1; pixel[4] = pval(brast, col - 1); pixel[5] = -1; pixel[6] = pval(crast, col - 1); pixel[7] = pval(crast, col); pixel[8] = -1; } } else { pixel[6] = -1; pixel[7] = -1; pixel[8] = -1; if (col == 0) { pixel[1] = -1; pixel[2] = pval(arast, col); pixel[3] = pval(arast, col + 1); pixel[4] = -1; pixel[5] = pval(brast, col + 1); } else if (col != (ncols - 1)) { pixel[1] = pval(arast, col - 1); pixel[2] = pval(arast, col); pixel[3] = pval(arast, col + 1); pixel[4] = pval(brast, col - 1); pixel[5] = pval(brast, col + 1); } else { pixel[1] = pval(arast, col - 1); pixel[2] = pval(arast, col); pixel[3] = -1; pixel[4] = pval(brast, col - 1); pixel[5] = -1; } } cold = warm = shadow = nulo = 0; for (i = 1; i < 9; i++) { switch (pixel[i]) { case IS_COLD_CLOUD: cold++; break; case IS_WARM_CLOUD: warm++; break; case IS_SHADOW: shadow++; break; default: nulo++; break; } } lim = (int)(cold + warm + shadow + nulo) / 2; /* Entra pixel[0] = 0 */ if (nulo < lim) { if (shadow >= (cold + warm)) pixel[0] = IS_SHADOW; else pixel[0] = (warm > cold) ? IS_WARM_CLOUD : IS_COLD_CLOUD; } } if (pixel[0] != 0) { ((CELL *) tmp.rast)[col] = pixel[0]; } else { Rast_set_c_null_value((CELL *) tmp.rast + col, 1); } } Rast_put_row(tmp.fd, tmp.rast, CELL_TYPE); } G_percent(1, 1, 1); G_free(arast); G_free(brast); G_free(crast); Rast_close(out->fd); G_free(tmp.rast); Rast_close(tmp.fd); G_remove("cats", out->name); G_remove("cell", out->name); G_remove("cellhd", out->name); G_remove("cell_misc", out->name); G_remove("hist", out->name); G_rename("cats", tmp.name, out->name); G_rename("cell", tmp.name, out->name); G_rename("cellhd", tmp.name, out->name); G_rename("cell_misc", tmp.name, out->name); G_rename("hist", tmp.name, out->name); return; }
CELL clump(int in_fd, int out_fd, int diag, int print) { register int col; register int n; CELL NEW, OLD; CELL *temp_cell, *temp_clump; CELL *prev_in, *cur_in, *out_cell; CELL *prev_clump, *cur_clump; CELL X, LEFT; CELL *index, *renumber; CELL label; int nrows, ncols; int row; int len; int nalloc; long cur_time; char *cname; int cfd, csize; CELL cat; nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* allocate clump index */ nalloc = INCR; index = (CELL *) G_malloc(nalloc * sizeof(CELL)); index[0] = 0; renumber = NULL; /* allocate CELL buffers two columns larger than current window */ len = (ncols + 2) * sizeof(CELL); prev_in = (CELL *) G_malloc(len); cur_in = (CELL *) G_malloc(len); prev_clump = (CELL *) G_malloc(len); cur_clump = (CELL *) G_malloc(len); out_cell = (CELL *) G_malloc(len); /* temp file for initial clump IDs */ cname = G_tempfile(); if ((cfd = open(cname, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) G_fatal_error(_("Unable to open temp file")); csize = ncols * sizeof(CELL); time(&cur_time); /* fake a previous row which is all NULL */ Rast_set_c_null_value(prev_in, ncols + 2); /* set left and right edge to NULL */ Rast_set_c_null_value(&cur_in[0], 1); Rast_set_c_null_value(&cur_in[ncols + 1], 1); /* initialize clump labels */ G_zero(cur_clump, len); G_zero(prev_clump, len); label = 0; /**************************************************** * PASS 1 * * pass thru the input, create initial clump labels * ****************************************************/ G_message(_("Pass 1 of 2...")); for (row = 0; row < nrows; row++) { Rast_get_c_row(in_fd, cur_in + 1, row); G_percent(row, nrows, 4); Rast_set_c_null_value(&X, 1); for (col = 1; col <= ncols; col++) { LEFT = X; X = cur_in[col]; if (Rast_is_c_null_value(&X)) { /* don't clump NULL data */ cur_clump[col] = 0; continue; } /* * if the cell value is different to the left and above * (diagonal: and above left and above right) * then we must start a new clump * * this new clump may eventually collide with another * clump and will have to be merged */ /* try to connect the current cell to an existing clump */ OLD = NEW = 0; /* same clump as to the left */ if (X == LEFT) { OLD = cur_clump[col] = cur_clump[col - 1]; } if (diag) { /* check above right, center, left, in that order */ n = 2; temp_clump = prev_clump + col + 1; temp_cell = prev_in + col + 1; do { if (X == *temp_cell) { cur_clump[col] = *temp_clump; if (OLD == 0) { OLD = *temp_clump; } else { NEW = *temp_clump; break; } } temp_cell--; temp_clump--; } while (n-- > 0); } else { /* check above */ if (X == prev_in[col]) { temp_clump = prev_clump + col; cur_clump[col] = *temp_clump; if (OLD == 0) { OLD = *temp_clump; } else { NEW = *temp_clump; } } } if (NEW == 0 || OLD == NEW) { /* ok */ if (OLD == 0) { /* start a new clump */ label++; cur_clump[col] = label; if (label >= nalloc) { nalloc += INCR; index = (CELL *) G_realloc(index, nalloc * sizeof(CELL)); } index[label] = label; } continue; } /* conflict! preserve NEW clump ID and change OLD clump ID. * Must go back to the left in the current row and to the right * in the previous row to change all the clump values as well. */ /* left of the current row from 1 to col - 1 */ temp_clump = cur_clump; n = col - 1; while (n-- > 0) { temp_clump++; /* skip left edge */ if (*temp_clump == OLD) *temp_clump = NEW; } /* right of previous row from col + 1 to ncols */ temp_clump = prev_clump; temp_clump += col; n = ncols - col; while (n-- > 0) { temp_clump++; /* skip col */ if (*temp_clump == OLD) *temp_clump = NEW; } /* modify the OLD index */ index[OLD] = NEW; } /* write initial clump IDs */ /* this works also with writing out cur_clump, but only * prev_clump is complete and will not change any more */ if (row > 0) { if (write(cfd, prev_clump + 1, csize) != csize) G_fatal_error(_("Unable to write to temp file")); } /* switch the buffers so that the current buffer becomes the previous */ temp_cell = cur_in; cur_in = prev_in; prev_in = temp_cell; temp_clump = cur_clump; cur_clump = prev_clump; prev_clump = temp_clump; } /* write last row with initial clump IDs */ if (write(cfd, prev_clump + 1, csize) != csize) G_fatal_error(_("Unable to write to temp file")); G_percent(1, 1, 1); /* generate a renumbering scheme */ G_message(_("Generating renumbering scheme...")); G_debug(1, "%d initial labels", label); /* allocate final clump ID */ renumber = (CELL *) G_malloc((label + 1) * sizeof(CELL)); renumber[0] = 0; cat = 1; G_percent(0, label, 1); for (n = 1; n <= label; n++) { G_percent(n, label, 1); OLD = n; NEW = index[n]; if (OLD != NEW) { renumber[n] = 0; /* find valid clump ID */ while (OLD != NEW) { OLD = NEW; NEW = index[OLD]; } index[n] = NEW; } else /* set final clump id */ renumber[n] = cat++; } /* rewind temp file */ lseek(cfd, 0, SEEK_SET); if (print) { fprintf(stdout, "clumps=%d\n", cat - 1); } else { /**************************************************** * PASS 2 * * apply renumbering scheme to initial clump labels * ****************************************************/ /* the input raster is no longer needed, * using instead the temp file with initial clump labels */ G_message(_("Pass 2 of 2...")); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 4); if (read(cfd, cur_clump, csize) != csize) G_fatal_error(_("Unable to read from temp file")); temp_clump = cur_clump; temp_cell = out_cell; for (col = 0; col < ncols; col++) { *temp_cell = renumber[index[*temp_clump]]; if (*temp_cell == 0) Rast_set_c_null_value(temp_cell, 1); temp_clump++; temp_cell++; } Rast_put_row(out_fd, out_cell, CELL_TYPE); } G_percent(1, 1, 1); } close(cfd); unlink(cname); print_time(&cur_time); return 0; }
double calculate(area_des ad, int fd, char **par, double *result) { CELL *buf; CELL corrCell; CELL precCell; int i, j; int mask_fd = -1, *mask_buf; int ris = 0; int masked = FALSE; int a = 0; /* a=0 if all cells are null */ long m = 0; long tot = 0; long zero = 0; long totCorr = 0; double indice = 0; double somma = 0; double p = 0; double area = 0; double t; avl_tree albero = NULL; AVL_table *array; generic_cell uc; uc.t = CELL_TYPE; /* open mask if needed */ if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return RLI_ERRORE; mask_buf = G_malloc(ad->cl * sizeof(int)); if (mask_buf == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } masked = TRUE; } Rast_set_c_null_value(&precCell, 1); for (j = 0; j < ad->rl; j++) { /* for each row */ if (masked) { if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) { G_fatal_error("mask read failed"); return RLI_ERRORE; } } buf = RLI_get_cell_raster_row(fd, j + ad->y, ad); for (i = 0; i < ad->cl; i++) { /* for each cell in the row */ area++; corrCell = buf[i + ad->x]; if ((masked) && (mask_buf[i + ad->x] == 0)) { Rast_set_c_null_value(&corrCell, 1); area--; } if (!(Rast_is_null_value(&corrCell, uc.t))) { a = 1; if (Rast_is_null_value(&precCell, uc.t)) { precCell = corrCell; } if (corrCell != precCell) { if (albero == NULL) { uc.val.c = precCell; albero = avl_make(uc, totCorr); if (albero == NULL) { G_fatal_error("avl_make error"); return RLI_ERRORE; } else m++; } else { uc.val.c = precCell; ris = avl_add(&albero, uc, totCorr); switch (ris) { case AVL_ERR: { G_fatal_error("avl_add error"); return RLI_ERRORE; } case AVL_ADD: { m++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avl_make unknown error"); return RLI_ERRORE; } } } totCorr = 1; } /* endif not equal cells */ else { /*equal cells */ totCorr++; } precCell = corrCell; } } } /*last closing */ if (a != 0) { if (albero == NULL) { uc.val.c = precCell; albero = avl_make(uc, totCorr); if (albero == NULL) { G_fatal_error("avl_make error"); return RLI_ERRORE; } m++; } else { uc.val.c = precCell; ris = avl_add(&albero, uc, totCorr); switch (ris) { case AVL_ERR: { G_fatal_error("avl_add error"); return RLI_ERRORE; } case AVL_ADD: { m++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avl_add unknown error"); return RLI_ERRORE; } } } } array = G_malloc(m * sizeof(AVL_tableRow)); if (array == NULL) { G_fatal_error("malloc array failed"); return RLI_ERRORE; } tot = avl_to_array(albero, zero, array); if (tot != m) { G_warning("avl_to_array unaspected value. the result could be wrong"); return RLI_ERRORE; } char *sval; sval = par[0]; double alpha_double; alpha_double = (double)atof(sval); /* claculate index summary */ for (i = 0; i < m; i++) { t = (double)(array[i]->tot); p = t / area; G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double)); somma = somma + pow(p, alpha_double); } indice = (1 / (1 - alpha_double)) * log(somma); if (isnan(indice) || isinf(indice)) { indice = -1; } G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice); *result = indice; G_free(array); if (masked) G_free(mask_buf); return RLI_OK; }
int close_array_seg(void) { struct Colors colors; int incr, max, red, green, blue, rd, gr, bl, flag; int c, r, map_fd; CELL *cellrow, value; CELL *theseg; RAMSEG thesegseg; cellrow = Rast_allocate_c_buf(); if (seg_flag || bas_flag || haf_flag) { if (seg_flag) { theseg = bas; thesegseg = bas_seg; } else if (bas_flag) { theseg = bas; thesegseg = bas_seg; } else { theseg = haf; thesegseg = haf_seg; } max = n_basins; G_debug(1, "%d basins created", max); Rast_init_colors(&colors); if (max > 0) Rast_make_random_colors(&colors, 1, max); else { G_warning(_("No basins were created. Verify threshold and region settings.")); Rast_make_random_colors(&colors, 1, 2); } if (max < 1000 && max > 0) { Rast_set_c_color((CELL) 0, 0, 0, 0, &colors); r = 1; incr = 0; while (incr >= 0) { G_percent(r, max, 2); for (gr = 130 + incr; gr <= 255; gr += 20) { for (rd = 90 + incr; rd <= 255; rd += 30) { for (bl = 90 + incr; bl <= 255; bl += 40) { flag = 1; while (flag) { Rast_get_c_color(&r, &red, &green, &blue, &colors); /* if existing rule is too dark then append a new rule to override it */ if ((blue * .11 + red * .30 + green * .59) < 100) { Rast_set_c_color(r, rd, gr, bl, &colors); flag = 0; } if (++r > max) { gr = rd = bl = 300; flag = 0; incr = -1; } } } } } if (incr >= 0) { incr += 15; if (incr > 120) incr = 7; } } G_percent(r - 1, max, 3); /* finish it */ } else G_debug(1, "Too many subbasins to reasonably check for color brightness"); /* using the existing stack of while/for/for/for/while loops ... */ } /* stream segments map */ if (seg_flag) { map_fd = Rast_open_c_new(seg_name); for (r = 0; r < nrows; r++) { Rast_set_c_null_value(cellrow, ncols); /* reset row to all NULL */ for (c = 0; c < ncols; c++) { value = FLAG_GET(swale, r, c); if (value) cellrow[c] = bas[SEG_INDEX(bas_seg, r, c)]; } Rast_put_row(map_fd, cellrow, CELL_TYPE); } Rast_close(map_fd); Rast_write_colors(seg_name, this_mapset, &colors); } /* basins map */ if (bas_flag) { map_fd = Rast_open_c_new(bas_name); for (r = 0; r < nrows; r++) { for (c = 0; c < ncols; c++) { cellrow[c] = bas[SEG_INDEX(bas_seg, r, c)]; if (cellrow[c] == 0) Rast_set_c_null_value(cellrow + c, 1); } Rast_put_row(map_fd, cellrow, CELL_TYPE); } Rast_close(map_fd); Rast_write_colors(bas_name, this_mapset, &colors); } /* half_basins map */ if (haf_flag) { map_fd = Rast_open_c_new(haf_name); for (r = 0; r < nrows; r++) { for (c = 0; c < ncols; c++) { cellrow[c] = haf[SEG_INDEX(haf_seg, r, c)]; if (cellrow[c] == 0) Rast_set_c_null_value(cellrow + c, 1); } Rast_put_row(map_fd, cellrow, CELL_TYPE); } Rast_close(map_fd); Rast_write_colors(haf_name, this_mapset, &colors); } if (seg_flag || bas_flag || haf_flag) Rast_free_colors(&colors); G_free(haf); G_free(bas); G_free(cellrow); if (arm_flag) fclose(fp); close_maps(); return 0; }