int main(int argc, char *argv[]) { void *raster, *ptr; /* char *null_row; */ RASTER_MAP_TYPE out_type, map_type; char *outfile; char null_str[80]; char cell_buf[300]; int fd; int row, col; int nrows, ncols, dp; int do_stdout; FILE *fp; double cellsize; struct GModule *module; struct { struct Option *map; struct Option *output; struct Option *dp; struct Option *null; } parm; struct { struct Flag *noheader; struct Flag *singleline; struct Flag *ccenter; } flag; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("export")); module->description = _("Converts a raster map layer into an ESRI ARCGRID file."); /* Define the different options */ parm.map = G_define_standard_option(G_OPT_R_INPUT); parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.output->gisprompt = "new_file,file,output"; parm.output->description = _("Name of an output ARC-GRID map (use out=- for stdout)"); parm.dp = G_define_option(); parm.dp->key = "dp"; parm.dp->type = TYPE_INTEGER; parm.dp->required = NO; parm.dp->answer = "8"; parm.dp->description = _("Number of decimal places"); flag.noheader = G_define_flag(); flag.noheader->key = 'h'; flag.noheader->description = _("Suppress printing of header information"); /* Added to optionally produce a single line output. -- emes -- 12.10.92 */ flag.singleline = G_define_flag(); flag.singleline->key = '1'; flag.singleline->description = _("List one entry per line instead of full row"); /* use cell center in header instead of cell corner */ flag.ccenter = G_define_flag(); flag.ccenter->key = 'c'; flag.ccenter->description = _("Use cell center reference in header instead of cell corner"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); sscanf(parm.dp->answer, "%d", &dp); if (dp > 20 || dp < 0) G_fatal_error("dp has to be from 0 to 20"); outfile = parm.output->answer; if ((strcmp("-", outfile)) == 0) do_stdout = 1; else do_stdout = 0; sprintf(null_str, "-9999"); fd = Rast_open_old(parm.map->answer, ""); map_type = Rast_get_map_type(fd); out_type = map_type; /* null_row = Rast_allocate_null_buf(); */ raster = Rast_allocate_buf(out_type); nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* open arc file for writing */ if (do_stdout) fp = stdout; else if (NULL == (fp = fopen(outfile, "w"))) G_fatal_error(_("Unable to open file <%s>"), outfile); if (!flag.noheader->answer) { struct Cell_head region; char buf[128]; G_get_window(®ion); fprintf(fp, "ncols %d\n", region.cols); fprintf(fp, "nrows %d\n", region.rows); cellsize = fabs(region.east - region.west) / region.cols; if (G_projection() != PROJECTION_LL) { /* Is Projection != LL (3) */ if (!flag.ccenter->answer) { G_format_easting(region.west, buf, region.proj); fprintf(fp, "xllcorner %s\n", buf); G_format_northing(region.south, buf, region.proj); fprintf(fp, "yllcorner %s\n", buf); } else { G_format_easting(region.west + cellsize / 2., buf, region.proj); fprintf(fp, "xllcenter %s\n", buf); G_format_northing(region.south + cellsize / 2., buf, region.proj); fprintf(fp, "yllcenter %s\n", buf); } } else { /* yes, lat/long */ fprintf(fp, "xllcorner %f\n", region.west); fprintf(fp, "yllcorner %f\n", region.south); } fprintf(fp, "cellsize %f\n", cellsize); fprintf(fp, "NODATA_value %s\n", null_str); } for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Rast_get_row(fd, raster, row, out_type); /* Rast_get_null_value_row(fd, null_row, row); */ for (col = 0, ptr = raster; col < ncols; col++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(out_type))) { if (!Rast_is_null_value(ptr, out_type)) { if (out_type == CELL_TYPE) fprintf(fp, "%d", *((CELL *) ptr)); else if (out_type == FCELL_TYPE) { sprintf(cell_buf, "%.*f", dp, *((FCELL *) ptr)); G_trim_decimal(cell_buf); fprintf(fp, "%s", cell_buf); } else if (out_type == DCELL_TYPE) { sprintf(cell_buf, "%.*f", dp, *((DCELL *) ptr)); G_trim_decimal(cell_buf); fprintf(fp, "%s", cell_buf); } } else fprintf(fp, "%s", null_str); if (!flag.singleline->answer) fprintf(fp, " "); else fprintf(fp, "\n"); } if (!flag.singleline->answer) fprintf(fp, "\n"); /* for (col = 0; col < ncols; col++) fprintf (fp,"%d ", null_row[col]); fprintf (fp,"\n"); */ } /* make sure it got to 100% */ G_percent(1, 1, 2); Rast_close(fd); fclose(fp); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int out_fd, base_raster; char *infile, *outmap; int percent; double zrange_min, zrange_max, d_tmp; double irange_min, irange_max; unsigned long estimated_lines; RASTER_MAP_TYPE rtype, base_raster_data_type; struct History history; char title[64]; SEGMENT base_segment; struct PointBinning point_binning; void *base_array; void *raster_row; struct Cell_head region; struct Cell_head input_region; int rows, last_rows, row0, cols; /* scan box size */ int row; /* counters */ int pass, npasses; unsigned long line, line_total; unsigned int counter; unsigned long n_invalid; char buff[BUFFSIZE]; double x, y, z; double intensity; int arr_row, arr_col; unsigned long count, count_total; int point_class; double zscale = 1.0; double iscale = 1.0; double res = 0.0; struct BinIndex bin_index_nodes; bin_index_nodes.num_nodes = 0; bin_index_nodes.max_nodes = 0; bin_index_nodes.nodes = 0; struct GModule *module; struct Option *input_opt, *output_opt, *percent_opt, *type_opt, *filter_opt, *class_opt; struct Option *method_opt, *base_raster_opt; struct Option *zrange_opt, *zscale_opt; struct Option *irange_opt, *iscale_opt; struct Option *trim_opt, *pth_opt, *res_opt; struct Option *file_list_opt; struct Flag *print_flag, *scan_flag, *shell_style, *over_flag, *extents_flag; struct Flag *intens_flag, *intens_import_flag; struct Flag *set_region_flag; struct Flag *base_rast_res_flag; struct Flag *only_valid_flag; /* LAS */ LASReaderH LAS_reader; LASHeaderH LAS_header; LASSRSH LAS_srs; LASPointH LAS_point; int return_filter; const char *projstr; struct Cell_head cellhd, loc_wind; unsigned int n_filtered; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("import")); G_add_keyword(_("LIDAR")); G_add_keyword(_("statistics")); G_add_keyword(_("conversion")); G_add_keyword(_("aggregation")); G_add_keyword(_("binning")); module->description = _("Creates a raster map from LAS LiDAR points using univariate statistics."); input_opt = G_define_standard_option(G_OPT_F_BIN_INPUT); input_opt->required = NO; input_opt->label = _("LAS input file"); input_opt->description = _("LiDAR input files in LAS format (*.las or *.laz)"); input_opt->guisection = _("Input"); output_opt = G_define_standard_option(G_OPT_R_OUTPUT); output_opt->required = NO; output_opt->guisection = _("Output"); file_list_opt = G_define_standard_option(G_OPT_F_INPUT); file_list_opt->key = "file"; file_list_opt->label = _("File containing names of LAS input files"); file_list_opt->description = _("LiDAR input files in LAS format (*.las or *.laz)"); file_list_opt->required = NO; file_list_opt->guisection = _("Input"); method_opt = G_define_option(); method_opt->key = "method"; method_opt->type = TYPE_STRING; method_opt->required = NO; method_opt->description = _("Statistic to use for raster values"); method_opt->options = "n,min,max,range,sum,mean,stddev,variance,coeff_var,median,percentile,skewness,trimmean"; method_opt->answer = "mean"; method_opt->guisection = _("Statistic"); G_asprintf((char **)&(method_opt->descriptions), "n;%s;" "min;%s;" "max;%s;" "range;%s;" "sum;%s;" "mean;%s;" "stddev;%s;" "variance;%s;" "coeff_var;%s;" "median;%s;" "percentile;%s;" "skewness;%s;" "trimmean;%s", _("Number of points in cell"), _("Minimum value of point values in cell"), _("Maximum value of point values in cell"), _("Range of point values in cell"), _("Sum of point values in cell"), _("Mean (average) value of point values in cell"), _("Standard deviation of point values in cell"), _("Variance of point values in cell"), _("Coefficient of variance of point values in cell"), _("Median value of point values in cell"), _("pth (nth) percentile of point values in cell"), _("Skewness of point values in cell"), _("Trimmed mean of point values in cell")); type_opt = G_define_standard_option(G_OPT_R_TYPE); type_opt->required = NO; type_opt->answer = "FCELL"; base_raster_opt = G_define_standard_option(G_OPT_R_INPUT); base_raster_opt->key = "base_raster"; base_raster_opt->required = NO; base_raster_opt->label = _("Subtract raster values from the Z coordinates"); base_raster_opt->description = _("The scale for Z is applied beforehand, the range filter for" " Z afterwards"); base_raster_opt->guisection = _("Transform"); zrange_opt = G_define_option(); zrange_opt->key = "zrange"; zrange_opt->type = TYPE_DOUBLE; zrange_opt->required = NO; zrange_opt->key_desc = "min,max"; zrange_opt->description = _("Filter range for Z data (min,max)"); zrange_opt->guisection = _("Selection"); zscale_opt = G_define_option(); zscale_opt->key = "zscale"; zscale_opt->type = TYPE_DOUBLE; zscale_opt->required = NO; zscale_opt->answer = "1.0"; zscale_opt->description = _("Scale to apply to Z data"); zscale_opt->guisection = _("Transform"); irange_opt = G_define_option(); irange_opt->key = "intensity_range"; irange_opt->type = TYPE_DOUBLE; irange_opt->required = NO; irange_opt->key_desc = "min,max"; irange_opt->description = _("Filter range for intensity values (min,max)"); irange_opt->guisection = _("Selection"); iscale_opt = G_define_option(); iscale_opt->key = "intensity_scale"; iscale_opt->type = TYPE_DOUBLE; iscale_opt->required = NO; iscale_opt->answer = "1.0"; iscale_opt->description = _("Scale to apply to intensity values"); iscale_opt->guisection = _("Transform"); percent_opt = G_define_option(); percent_opt->key = "percent"; percent_opt->type = TYPE_INTEGER; percent_opt->required = NO; percent_opt->answer = "100"; percent_opt->options = "1-100"; percent_opt->description = _("Percent of map to keep in memory"); /* I would prefer to call the following "percentile", but that has too * much namespace overlap with the "percent" option above */ pth_opt = G_define_option(); pth_opt->key = "pth"; pth_opt->type = TYPE_INTEGER; pth_opt->required = NO; pth_opt->options = "1-100"; pth_opt->description = _("pth percentile of the values"); pth_opt->guisection = _("Statistic"); trim_opt = G_define_option(); trim_opt->key = "trim"; trim_opt->type = TYPE_DOUBLE; trim_opt->required = NO; trim_opt->options = "0-50"; trim_opt->label = _("Discard given percentage of the smallest and largest values"); trim_opt->description = _("Discard <trim> percent of the smallest and <trim> percent of the largest observations"); trim_opt->guisection = _("Statistic"); res_opt = G_define_option(); res_opt->key = "resolution"; res_opt->type = TYPE_DOUBLE; res_opt->required = NO; res_opt->description = _("Output raster resolution"); res_opt->guisection = _("Output"); filter_opt = G_define_option(); filter_opt->key = "return_filter"; filter_opt->type = TYPE_STRING; filter_opt->required = NO; filter_opt->label = _("Only import points of selected return type"); filter_opt->description = _("If not specified, all points are imported"); filter_opt->options = "first,last,mid"; filter_opt->guisection = _("Selection"); class_opt = G_define_option(); class_opt->key = "class_filter"; class_opt->type = TYPE_INTEGER; class_opt->multiple = YES; class_opt->required = NO; class_opt->label = _("Only import points of selected class(es)"); class_opt->description = _("Input is comma separated integers. " "If not specified, all points are imported."); class_opt->guisection = _("Selection"); print_flag = G_define_flag(); print_flag->key = 'p'; print_flag->description = _("Print LAS file info and exit"); extents_flag = G_define_flag(); extents_flag->key = 'e'; extents_flag->label = _("Use the extent of the input for the raster extent"); extents_flag->description = _("Set internally computational region extents based on the" " point cloud"); extents_flag->guisection = _("Output"); set_region_flag = G_define_flag(); set_region_flag->key = 'n'; set_region_flag->label = _("Set computation region to match the new raster map"); set_region_flag->description = _("Set computation region to match the 2D extent and resolution" " of the newly created new raster map"); set_region_flag->guisection = _("Output"); over_flag = G_define_flag(); over_flag->key = 'o'; over_flag->label = _("Override projection check (use current location's projection)"); over_flag->description = _("Assume that the dataset has same projection as the current location"); scan_flag = G_define_flag(); scan_flag->key = 's'; scan_flag->description = _("Scan data file for extent then exit"); shell_style = G_define_flag(); shell_style->key = 'g'; shell_style->description = _("In scan mode, print using shell script style"); intens_flag = G_define_flag(); intens_flag->key = 'i'; intens_flag->label = _("Use intensity values rather than Z values"); intens_flag->description = _("Uses intensity values everywhere as if they would be Z" " coordinates"); intens_import_flag = G_define_flag(); intens_import_flag->key = 'j'; intens_import_flag->description = _("Use Z values for filtering, but intensity values for statistics"); base_rast_res_flag = G_define_flag(); base_rast_res_flag->key = 'd'; base_rast_res_flag->label = _("Use base raster resolution instead of computational region"); base_rast_res_flag->description = _("For getting values from base raster, use its actual" " resolution instead of computational region resolution"); only_valid_flag = G_define_flag(); only_valid_flag->key = 'v'; only_valid_flag->label = _("Use only valid points"); only_valid_flag->description = _("Points invalid according to APSRS LAS specification will be" " filtered out"); only_valid_flag->guisection = _("Selection"); G_option_required(input_opt, file_list_opt, NULL); G_option_exclusive(input_opt, file_list_opt, NULL); G_option_required(output_opt, print_flag, scan_flag, shell_style, NULL); G_option_exclusive(intens_flag, intens_import_flag, NULL); G_option_requires(base_rast_res_flag, base_raster_opt, NULL); if (G_parser(argc, argv)) exit(EXIT_FAILURE); int only_valid = FALSE; n_invalid = 0; if (only_valid_flag->answer) only_valid = TRUE; /* we could use rules but this gives more info and allows continuing */ if (set_region_flag->answer && !(extents_flag->answer || res_opt->answer)) { G_warning(_("Flag %c makes sense only with %s option or -%c flag"), set_region_flag->key, res_opt->key, extents_flag->key); /* avoid the call later on */ set_region_flag->answer = '\0'; } struct StringList infiles; if (file_list_opt->answer) { if (access(file_list_opt->answer, F_OK) != 0) G_fatal_error(_("File <%s> does not exist"), file_list_opt->answer); string_list_from_file(&infiles, file_list_opt->answer); } else { string_list_from_one_item(&infiles, input_opt->answer); } /* parse input values */ outmap = output_opt->answer; if (shell_style->answer && !scan_flag->answer) { scan_flag->answer = 1; /* pointer not int, so set = shell_style->answer ? */ } /* check zrange and extent relation */ if (scan_flag->answer || extents_flag->answer) { if (zrange_opt->answer) G_warning(_("zrange will not be taken into account during scan")); } Rast_get_window(®ion); /* G_get_window seems to be unreliable if the location has been changed */ G_get_set_window(&loc_wind); /* TODO: v.in.lidar uses G_get_default_window() */ estimated_lines = 0; int i; for (i = 0; i < infiles.num_items; i++) { infile = infiles.items[i]; /* don't if file not found */ if (access(infile, F_OK) != 0) G_fatal_error(_("Input file <%s> does not exist"), infile); /* Open LAS file*/ LAS_reader = LASReader_Create(infile); if (LAS_reader == NULL) G_fatal_error(_("Unable to open file <%s> as a LiDAR point cloud"), infile); LAS_header = LASReader_GetHeader(LAS_reader); if (LAS_header == NULL) { G_fatal_error(_("Unable to read LAS header of <%s>"), infile); } LAS_srs = LASHeader_GetSRS(LAS_header); /* print info or check projection if we are actually importing */ if (print_flag->answer) { /* print filename when there is more than one file */ if (infiles.num_items > 1) fprintf(stdout, "File: %s\n", infile); /* Print LAS header */ print_lasinfo(LAS_header, LAS_srs); } else { /* report that we are checking more files */ if (i == 1) G_message(_("First file's projection checked," " checking projection of the other files...")); /* Fetch input map projection in GRASS form. */ projstr = LASSRS_GetWKT_CompoundOK(LAS_srs); /* we are printing the non-warning messages only for first file */ projection_check_wkt(cellhd, loc_wind, projstr, over_flag->answer, shell_style->answer || i); /* if there is a problem in some other file, first OK message * is printed but than a warning, this is not ideal but hopefully * not so confusing when importing multiple files */ } if (scan_flag->answer || extents_flag->answer) { /* we assign to the first one (i==0) but update for the rest */ scan_bounds(LAS_reader, shell_style->answer, extents_flag->answer, i, zscale, ®ion); } /* number of estimated point across all files */ /* TODO: this should be ull which won't work with percent report */ estimated_lines += LASHeader_GetPointRecordsCount(LAS_header); /* We are closing all again and we will be opening them later, * so we don't have to worry about limit for open files. */ LASSRS_Destroy(LAS_srs); LASHeader_Destroy(LAS_header); LASReader_Destroy(LAS_reader); } /* if we are not importing, end */ if (print_flag->answer || scan_flag->answer) exit(EXIT_SUCCESS); return_filter = LAS_ALL; if (filter_opt->answer) { if (strcmp(filter_opt->answer, "first") == 0) return_filter = LAS_FIRST; else if (strcmp(filter_opt->answer, "last") == 0) return_filter = LAS_LAST; else if (strcmp(filter_opt->answer, "mid") == 0) return_filter = LAS_MID; else G_fatal_error(_("Unknown filter option <%s>"), filter_opt->answer); } struct ReturnFilter return_filter_struct; return_filter_struct.filter = return_filter; struct ClassFilter class_filter; class_filter_create_from_strings(&class_filter, class_opt->answers); percent = atoi(percent_opt->answer); /* TODO: we already used zscale */ /* TODO: we don't report intensity range */ if (zscale_opt->answer) zscale = atof(zscale_opt->answer); if (iscale_opt->answer) iscale = atof(iscale_opt->answer); /* parse zrange */ if (zrange_opt->answer != NULL) { if (zrange_opt->answers[0] == NULL) G_fatal_error(_("Invalid zrange")); sscanf(zrange_opt->answers[0], "%lf", &zrange_min); sscanf(zrange_opt->answers[1], "%lf", &zrange_max); if (zrange_min > zrange_max) { d_tmp = zrange_max; zrange_max = zrange_min; zrange_min = d_tmp; } } /* parse irange */ if (irange_opt->answer != NULL) { if (irange_opt->answers[0] == NULL) G_fatal_error(_("Invalid %s"), irange_opt->key); sscanf(irange_opt->answers[0], "%lf", &irange_min); sscanf(irange_opt->answers[1], "%lf", &irange_max); if (irange_min > irange_max) { d_tmp = irange_max; irange_max = irange_min; irange_min = d_tmp; } } point_binning_set(&point_binning, method_opt->answer, pth_opt->answer, trim_opt->answer, FALSE); base_array = NULL; if (strcmp("CELL", type_opt->answer) == 0) rtype = CELL_TYPE; else if (strcmp("DCELL", type_opt->answer) == 0) rtype = DCELL_TYPE; else rtype = FCELL_TYPE; if (point_binning.method == METHOD_N) rtype = CELL_TYPE; if (res_opt->answer) { /* align to resolution */ res = atof(res_opt->answer); if (!G_scan_resolution(res_opt->answer, &res, region.proj)) G_fatal_error(_("Invalid input <%s=%s>"), res_opt->key, res_opt->answer); if (res <= 0) G_fatal_error(_("Option '%s' must be > 0.0"), res_opt->key); region.ns_res = region.ew_res = res; region.north = ceil(region.north / res) * res; region.south = floor(region.south / res) * res; region.east = ceil(region.east / res) * res; region.west = floor(region.west / res) * res; G_adjust_Cell_head(®ion, 0, 0); } else if (extents_flag->answer) { /* align to current region */ Rast_align_window(®ion, &loc_wind); } Rast_set_output_window(®ion); rows = last_rows = region.rows; npasses = 1; if (percent < 100) { rows = (int)(region.rows * (percent / 100.0)); npasses = region.rows / rows; last_rows = region.rows - npasses * rows; if (last_rows) npasses++; else last_rows = rows; } cols = region.cols; G_debug(2, "region.n=%f region.s=%f region.ns_res=%f", region.north, region.south, region.ns_res); G_debug(2, "region.rows=%d [box_rows=%d] region.cols=%d", region.rows, rows, region.cols); /* using row-based chunks (used for output) when input and output * region matches and using segment library when they don't */ int use_segment = 0; int use_base_raster_res = 0; /* TODO: see if the input region extent is smaller than the raster * if yes, the we need to load the whole base raster if the -e * flag was defined (alternatively clip the regions) */ if (base_rast_res_flag->answer) use_base_raster_res = 1; if (base_raster_opt->answer && (res_opt->answer || use_base_raster_res || extents_flag->answer)) use_segment = 1; if (base_raster_opt->answer && !use_segment) { /* TODO: do we need to test existence first? mapset? */ base_raster = Rast_open_old(base_raster_opt->answer, ""); base_raster_data_type = Rast_get_map_type(base_raster); base_array = G_calloc((size_t)rows * (cols + 1), Rast_cell_size(base_raster_data_type)); } if (base_raster_opt->answer && use_segment) { if (use_base_raster_res) { /* read raster actual extent and resolution */ Rast_get_cellhd(base_raster_opt->answer, "", &input_region); /* TODO: make it only as small as the output is or points are */ Rast_set_input_window(&input_region); /* we have split window */ } else { Rast_get_input_window(&input_region); } rast_segment_open(&base_segment, base_raster_opt->answer, &base_raster_data_type); } if (!scan_flag->answer) { if (!check_rows_cols_fit_to_size_t(rows, cols)) G_fatal_error(_("Unable to process the hole map at once. " "Please set the '%s' option to some value lower than 100."), percent_opt->key); point_binning_memory_test(&point_binning, rows, cols, rtype); } /* open output map */ out_fd = Rast_open_new(outmap, rtype); /* allocate memory for a single row of output data */ raster_row = Rast_allocate_output_buf(rtype); G_message(_("Reading data ...")); count_total = line_total = 0; /* main binning loop(s) */ for (pass = 1; pass <= npasses; pass++) { if (npasses > 1) G_message(_("Pass #%d (of %d) ..."), pass, npasses); /* figure out segmentation */ row0 = (pass - 1) * rows; if (pass == npasses) { rows = last_rows; } if (base_array) { G_debug(2, "filling base raster array"); for (row = 0; row < rows; row++) { Rast_get_row(base_raster, base_array + ((size_t) row * cols * Rast_cell_size(base_raster_data_type)), row, base_raster_data_type); } } G_debug(2, "pass=%d/%d rows=%d", pass, npasses, rows); point_binning_allocate(&point_binning, rows, cols, rtype); line = 0; count = 0; counter = 0; G_percent_reset(); /* loop of input files */ for (i = 0; i < infiles.num_items; i++) { infile = infiles.items[i]; /* we already know file is there, so just do basic checks */ LAS_reader = LASReader_Create(infile); if (LAS_reader == NULL) G_fatal_error(_("Unable to open file <%s>"), infile); while ((LAS_point = LASReader_GetNextPoint(LAS_reader)) != NULL) { line++; counter++; if (counter == 100000) { /* speed */ if (line < estimated_lines) G_percent(line, estimated_lines, 3); counter = 0; } /* We always count them and report because behavior * changed in between 7.0 and 7.2 from undefined (but skipping * invalid points) to filtering them out only when requested. */ if (!LASPoint_IsValid(LAS_point)) { n_invalid++; if (only_valid) continue; } x = LASPoint_GetX(LAS_point); y = LASPoint_GetY(LAS_point); if (intens_flag->answer) /* use intensity as z here to allow all filters (and * modifications) below to be applied for intensity */ z = LASPoint_GetIntensity(LAS_point); else z = LASPoint_GetZ(LAS_point); int return_n = LASPoint_GetReturnNumber(LAS_point); int n_returns = LASPoint_GetNumberOfReturns(LAS_point); if (return_filter_is_out(&return_filter_struct, return_n, n_returns)) { n_filtered++; continue; } point_class = (int) LASPoint_GetClassification(LAS_point); if (class_filter_is_out(&class_filter, point_class)) continue; if (y <= region.south || y > region.north) { continue; } if (x < region.west || x >= region.east) { continue; } /* find the bin in the current array box */ arr_row = (int)((region.north - y) / region.ns_res) - row0; if (arr_row < 0 || arr_row >= rows) continue; arr_col = (int)((x - region.west) / region.ew_res); z = z * zscale; if (base_array) { double base_z; if (row_array_get_value_row_col(base_array, arr_row, arr_col, cols, base_raster_data_type, &base_z)) z -= base_z; else continue; } else if (use_segment) { double base_z; if (rast_segment_get_value_xy(&base_segment, &input_region, base_raster_data_type, x, y, &base_z)) z -= base_z; else continue; } if (zrange_opt->answer) { if (z < zrange_min || z > zrange_max) { continue; } } if (intens_import_flag->answer || irange_opt->answer) { intensity = LASPoint_GetIntensity(LAS_point); intensity *= iscale; if (irange_opt->answer) { if (intensity < irange_min || intensity > irange_max) { continue; } } /* use intensity for statistics */ if (intens_import_flag->answer) z = intensity; } count++; /* G_debug(5, "x: %f, y: %f, z: %f", x, y, z); */ update_value(&point_binning, &bin_index_nodes, cols, arr_row, arr_col, rtype, x, y, z); } /* while !EOF of one input file */ /* close input LAS file */ LASReader_Destroy(LAS_reader); } /* end of loop for all input files files */ G_percent(1, 1, 1); /* flush */ G_debug(2, "pass %d finished, %lu coordinates in box", pass, count); count_total += count; line_total += line; /* calc stats and output */ G_message(_("Writing to map ...")); for (row = 0; row < rows; row++) { /* potentially vector writing can be independent on the binning */ write_values(&point_binning, &bin_index_nodes, raster_row, row, cols, rtype, NULL); /* write out line of raster data */ Rast_put_row(out_fd, raster_row, rtype); } /* free memory */ point_binning_free(&point_binning, &bin_index_nodes); } /* passes loop */ if (base_array) Rast_close(base_raster); if (use_segment) Segment_close(&base_segment); G_percent(1, 1, 1); /* flush */ G_free(raster_row); /* close raster file & write history */ Rast_close(out_fd); sprintf(title, "Raw X,Y,Z data binned into a raster grid by cell %s", method_opt->answer); Rast_put_cell_title(outmap, title); Rast_short_history(outmap, "raster", &history); Rast_command_history(&history); Rast_set_history(&history, HIST_DATSRC_1, infile); Rast_write_history(outmap, &history); /* set computation region to the new raster map */ /* TODO: should be in the done message */ if (set_region_flag->answer) G_put_window(®ion); if (n_invalid && only_valid) G_message(_("%lu input points were invalid and filtered out"), n_invalid); if (n_invalid && !only_valid) G_message(_("%lu input points were invalid, use -%c flag to filter" " them out"), n_invalid, only_valid_flag->key); if (infiles.num_items > 1) { sprintf(buff, _("Raster map <%s> created." " %lu points from %d files found in region."), outmap, count_total, infiles.num_items); } else { sprintf(buff, _("Raster map <%s> created." " %lu points found in region."), outmap, count_total); } G_done_msg("%s", buff); G_debug(1, "Processed %lu points.", line_total); string_list_free(&infiles); exit(EXIT_SUCCESS); }
static int write_pca(double **eigmat, int *inp_fd, char *out_basename, int bands, int scale, int scale_min, int scale_max) { int i, j; void *outbuf, *outptr; double min = 0.; double max = 0.; double old_range = 0.; double new_range = 0.; int rows = Rast_window_rows(); int cols = Rast_window_cols(); int cell_mapsiz = Rast_cell_size(CELL_TYPE); int dcell_mapsiz = Rast_cell_size(DCELL_TYPE); DCELL *d_buf; /* 2 passes for rescale. 1 pass for no rescale */ int PASSES = (scale) ? 2 : 1; /* temporary row storage */ d_buf = (DCELL *) G_malloc(cols * sizeof(double)); /* allocate memory for output row buffer */ outbuf = (scale) ? Rast_allocate_buf(CELL_TYPE) : Rast_allocate_buf(DCELL_TYPE); if (!outbuf) G_fatal_error(_("Unable to allocate memory for raster row")); for (i = 0; i < bands; i++) { char name[100]; int out_fd; int pass; sprintf(name, "%s.%d", out_basename, i + 1); G_message(_("Transforming <%s>..."), name); /* open a new file for output */ if (scale) out_fd = Rast_open_c_new(name); else { out_fd = Rast_open_fp_new(name); Rast_set_fp_type(DCELL_TYPE); } for (pass = 1; pass <= PASSES; pass++) { void *rowbuf = NULL; int row, col; if (scale && (pass == PASSES)) { G_message(_("Rescaling <%s> to range %d,%d..."), name, scale_min, scale_max); old_range = max - min; new_range = (double)(scale_max - scale_min); } for (row = 0; row < rows; row++) { void *rowptr; G_percent(row, rows, 2); /* reset d_buf */ for (col = 0; col < cols; col++) d_buf[col] = 0.; for (j = 0; j < bands; j++) { RASTER_MAP_TYPE maptype = Rast_get_map_type(inp_fd[j]); /* don't assume each image is of the same type */ if (rowbuf) G_free(rowbuf); if (!(rowbuf = Rast_allocate_buf(maptype))) G_fatal_error(_("Unable allocate memory for row buffer")); Rast_get_row(inp_fd[j], rowbuf, row, maptype); rowptr = rowbuf; outptr = outbuf; /* add into the output cell eigmat[i][j] * corresp cell * of j-th band for current j */ for (col = 0; col < cols; col++) { /* handle null cells */ if (Rast_is_null_value(rowptr, maptype)) { if (scale) { Rast_set_null_value(outptr, 1, CELL_TYPE); outptr = G_incr_void_ptr(outptr, cell_mapsiz); } else { Rast_set_null_value(outptr, 1, DCELL_TYPE); outptr = G_incr_void_ptr(outptr, dcell_mapsiz); } rowptr = G_incr_void_ptr(rowptr, Rast_cell_size(maptype)); continue; } /* corresp. cell of j-th band */ d_buf[col] += eigmat[i][j] * Rast_get_d_value(rowptr, maptype); /* the cell entry is complete */ if (j == (bands - 1)) { if (scale && (pass == 1)) { if ((row == 0) && (col == 0)) min = max = d_buf[0]; if (d_buf[col] < min) min = d_buf[col]; if (d_buf[col] > max) max = d_buf[col]; } else if (scale) { if (min == max) { Rast_set_c_value(outptr, 1, CELL_TYPE); } else { /* map data to 0, (new_range-1) and then adding new_min */ CELL tmpcell = round_c((new_range * (d_buf[col] - min) / old_range) + scale_min); Rast_set_c_value(outptr, tmpcell, CELL_TYPE); } } else { /* (!scale) */ Rast_set_d_value(outptr, d_buf[col], DCELL_TYPE); } } outptr = (scale) ? G_incr_void_ptr(outptr, cell_mapsiz) : G_incr_void_ptr(outptr, dcell_mapsiz); rowptr = G_incr_void_ptr(rowptr, Rast_cell_size(maptype)); } } /* for j = 0 to bands */ if (pass == PASSES) { if (scale) Rast_put_row(out_fd, outbuf, CELL_TYPE); else Rast_put_row(out_fd, outbuf, DCELL_TYPE); } } G_percent(row, rows, 2); /* close output file */ if (pass == PASSES) Rast_close(out_fd); } } if (d_buf) G_free(d_buf); if (outbuf) G_free(outbuf); return 0; }
int main(int argc, char *argv[]) { struct GModule *module; struct Option *in_opt, *out_opt, *feature_opt, *column_name; struct Flag *smooth_flg, *value_flg, *z_flg, *no_topol, *notab_flg; int feature, notab_flag; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("conversion")); G_add_keyword(_("geometry")); G_add_keyword(_("vectorization")); module->description = _("Converts a raster map into a vector map."); in_opt = G_define_standard_option(G_OPT_R_INPUT); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); feature_opt = G_define_standard_option(G_OPT_V_TYPE); feature_opt->required = YES; feature_opt->multiple = NO; feature_opt->options = "point,line,area"; feature_opt->answer = NULL; column_name = G_define_standard_option(G_OPT_DB_COLUMN); column_name->label = _("Name of attribute column to store value"); column_name->description = _("Name must be SQL compliant"); column_name->answer = "value"; smooth_flg = G_define_flag(); smooth_flg->key = 's'; smooth_flg->description = _("Smooth corners of area features"); value_flg = G_define_flag(); value_flg->key = 'v'; value_flg->description = _("Use raster values as categories instead of unique sequence (CELL only)"); value_flg->guisection = _("Attributes"); z_flg = G_define_flag(); z_flg->key = 'z'; z_flg->label = _("Write raster values as z coordinate"); z_flg->description = _("Table is not created. " "Currently supported only for points."); z_flg->guisection = _("Attributes"); no_topol = G_define_flag(); no_topol->key = 'b'; no_topol->label = _("Do not build vector topology"); no_topol->description = _("Recommended for massive point conversion"); notab_flg = G_define_standard_flag(G_FLG_V_TABLE); if (G_parser(argc, argv)) exit(EXIT_FAILURE); feature = Vect_option_to_types(feature_opt); smooth_flag = (smooth_flg->answer) ? SMOOTH : NO_SMOOTH; value_flag = value_flg->answer; notab_flag = notab_flg->answer; if (z_flg->answer && (feature != GV_POINT)) G_fatal_error(_("z flag is supported only for points")); /* Open files */ input_fd = Rast_open_old(in_opt->answer, ""); data_type = Rast_get_map_type(input_fd); data_size = Rast_cell_size(data_type); G_get_window(&cell_head); if (value_flag && data_type != CELL_TYPE) { if (!notab_flag) G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be written to the table.")); else if (z_flg->answer) G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be z coordinate.")); else G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be lost.")); value_flag = 0; } if (!value_flag && notab_flag) { G_warning(_("Categories will be unique sequence, raster values will be lost.")); } if (Vect_open_new(&Map, out_opt->answer, z_flg->answer) < 0) G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); Vect_hist_command(&Map); Cats = Vect_new_cats_struct(); /* Open category labels */ if (data_type == CELL_TYPE) { if (0 == Rast_read_cats(in_opt->answer, "", &RastCats)) has_cats = 1; } else has_cats = 0; db_init_string(&sql); db_init_string(&label); /* Create table */ if ((feature & (GV_AREA | GV_POINT | GV_LINE)) && (!value_flag || (value_flag && has_cats)) && !(z_flg->answer) && !notab_flag) { char buf[1000]; Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE); Vect_map_add_dblink(&Map, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database, Fi->driver); driver = db_start_driver_open_database(Fi->driver, Vect_subst_var(Fi->database, &Map)); if (driver == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); db_set_error_handler_driver(driver); /* Create new table */ db_zero_string(&sql); sprintf(buf, "create table %s ( cat integer", Fi->table); db_append_string(&sql, buf); if (!value_flag) { /* add value to the table */ if (data_type == CELL_TYPE) { db_append_string(&sql, ", "); db_append_string(&sql, column_name->answer); db_append_string(&sql, " integer"); } else { db_append_string(&sql, ","); db_append_string(&sql, column_name->answer); db_append_string(&sql, " double precision"); } } if (has_cats) { int i, len; int clen = 0; /* Get maximum column length */ for (i = 0; i < RastCats.ncats; i++) { len = strlen(RastCats.labels[i]); if (len > clen) clen = len; } clen += 10; sprintf(buf, ", label varchar(%d)", clen); db_append_string(&sql, buf); } db_append_string(&sql, ")"); G_debug(3, db_get_string(&sql)); if (db_execute_immediate(driver, &sql) != DB_OK) G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql)); if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK) G_warning(_("Unable to create index")); if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) G_fatal_error(_("Unable to grant privileges on table <%s>"), Fi->table); db_begin_transaction(driver); } else { driver = NULL; } /* init variables for lines and areas */ first_read = 1; last_read = 0; direction = FORWARD; row_length = cell_head.cols; n_rows = cell_head.rows; row_count = 0; if (feature == GV_LINE) { alloc_lines_bufs(row_length + 2); extract_lines(); } else if (feature == GV_AREA) { alloc_areas_bufs(row_length + 2); extract_areas(); } else { /* GV_POINT */ extract_points(z_flg->answer); } Rast_close(input_fd); if (!no_topol->answer) Vect_build(&Map); /* insert cats and optionally labels if raster cats were used */ if (driver && value_flag) { char buf[1000]; int c, i, cat, fidx, ncats, lastcat, tp, id; fidx = Vect_cidx_get_field_index(&Map, 1); if (fidx >= 0) { ncats = Vect_cidx_get_num_cats_by_index(&Map, fidx); lastcat = -1; G_important_message(_("Updating attributes...")); for (c = 0; c < ncats; c++) { Vect_cidx_get_cat_by_index(&Map, fidx, c, &cat, &tp, &id); if (lastcat == cat) continue; /* find label, slow -> TODO faster */ db_set_string(&label, ""); for (i = 0; i < RastCats.ncats; i++) { if (cat == (int)RastCats.q.table[i].dLow) { /* cats are in dLow/High not in cLow/High !!! */ db_set_string(&label, RastCats.labels[i]); db_double_quote_string(&label); break; } } G_debug(3, "cat = %d label = %s", cat, db_get_string(&label)); sprintf(buf, "insert into %s values ( %d, '%s')", Fi->table, cat, db_get_string(&label)); db_set_string(&sql, buf); G_debug(3, db_get_string(&sql)); if (db_execute_immediate(driver, &sql) != DB_OK) G_fatal_error(_("Unable to insert into table: %s"), db_get_string(&sql)); lastcat = cat; } } } if (has_cats) Rast_free_cats(&RastCats); if (driver != NULL) { db_commit_transaction(driver); db_close_database_shutdown_driver(driver); } Vect_close(&Map); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { struct Cell_head window; RASTER_MAP_TYPE raster_type, mag_raster_type = -1; int layer_fd; void *raster_row, *ptr; int nrows, ncols; int aspect_c = -1; float aspect_f = -1.0; double scale; int skip, no_arrow; char *mag_map = NULL; void *mag_raster_row = NULL, *mag_ptr = NULL; double length = -1; int mag_fd = -1; struct FPRange range; double mag_min, mag_max; struct GModule *module; struct Option *opt1, *opt2, *opt3, *opt4, *opt5, *opt6, *opt7, *opt8, *opt9; struct Flag *align; double t, b, l, r; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("map annotations")); G_add_keyword(_("raster")); module->description = _("Draws arrows representing cell aspect direction " "for a raster map containing aspect data."); opt1 = G_define_standard_option(G_OPT_R_MAP); opt1->description = _("Name of raster aspect map to be displayed"); opt2 = G_define_option(); opt2->key = "type"; opt2->type = TYPE_STRING; opt2->required = NO; opt2->answer = "grass"; opt2->options = "grass,compass,agnps,answers"; opt2->description = _("Type of existing raster aspect map"); opt3 = G_define_standard_option(G_OPT_C); opt3->key = "color"; opt3->answer = "green"; opt3->label = _("Color for drawing arrows"); opt3->guisection = _("Colors"); opt4 = G_define_standard_option(G_OPT_CN); opt4->key = "grid_color"; opt4->answer = "gray"; opt4->label = _("Color for drawing drawing grid"); opt4->guisection = _("Colors"); opt5 = G_define_standard_option(G_OPT_CN); opt5->key = "null_color"; opt5->answer = DEFAULT_FG_COLOR; opt5->label = _("Color for drawing null values (X symbol)"); opt5->guisection = _("Colors"); opt6 = G_define_standard_option(G_OPT_CN); opt6->key = "unknown_color"; opt6->answer = "red"; opt6->label = _("Color for showing unknown information (? symbol)"); opt6->guisection = _("Colors"); opt9 = G_define_option(); opt9->key = "skip"; opt9->type = TYPE_INTEGER; opt9->required = NO; opt9->answer = "1"; opt9->description = _("Draw arrow every Nth grid cell"); opt7 = G_define_option(); opt7->key = "magnitude_map"; opt7->type = TYPE_STRING; opt7->required = NO; opt7->multiple = NO; opt7->gisprompt = "old,cell,raster"; opt7->description = _("Raster map containing values used for arrow length"); opt8 = G_define_option(); opt8->key = "scale"; opt8->type = TYPE_DOUBLE; opt8->required = NO; opt8->answer = "1.0"; opt8->description = _("Scale factor for arrows (magnitude map)"); align = G_define_flag(); align->key = 'a'; align->description = _("Align grids with raster cells"); /* Check command line */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); layer_name = opt1->answer; arrow_color = D_translate_color(opt3->answer); /* Convert none (transparent) to -1 which in this module means that we will not draw things having this color (-1). We don't do that for arrow because we always want them. (This is specified by the gisprompt ('type') of the options.) */ if (strcmp("none", opt4->answer) == 0) grid_color = -1; else grid_color = D_translate_color(opt4->answer); if (strcmp("none", opt5->answer) == 0) x_color = -1; else x_color = D_translate_color(opt5->answer); if (strcmp("none", opt6->answer) == 0) unknown_color = -1; else unknown_color = D_translate_color(opt6->answer); if (strcmp("grass", opt2->answer) == 0) map_type = 1; else if (strcmp("agnps", opt2->answer) == 0) map_type = 2; else if (strcmp("answers", opt2->answer) == 0) map_type = 3; else if (strcmp("compass", opt2->answer) == 0) map_type = 4; scale = atof(opt8->answer); if (scale <= 0.0) G_fatal_error(_("Illegal value for scale factor")); skip = atoi(opt9->answer); if (skip <= 0) G_fatal_error(_("Illegal value for skip factor")); if (opt7->answer) { if (map_type != 1 && map_type != 4) G_fatal_error(_("Magnitude is only supported for GRASS and compass aspect maps.")); mag_map = opt7->answer; } else if (scale != 1.0) G_warning(_("Scale option requires magnitude_map")); /* Setup driver and check important information */ D_open_driver(); D_setup(0); /* Read in the map window associated with window */ G_get_window(&window); if (align->answer) { struct Cell_head wind; Rast_get_cellhd(layer_name, "", &wind); /* expand window extent by one wind resolution */ wind.west += wind.ew_res * ((int)((window.west - wind.west) / wind.ew_res) - (window.west < wind.west)); wind.east += wind.ew_res * ((int)((window.east - wind.east) / wind.ew_res) + (window.east > wind.east)); wind.south += wind.ns_res * ((int)((window.south - wind.south) / wind.ns_res) - (window.south < wind.south)); wind.north += wind.ns_res * ((int)((window.north - wind.north) / wind.ns_res) + (window.north > wind.north)); wind.rows = (wind.north - wind.south) / wind.ns_res; wind.cols = (wind.east - wind.west) / wind.ew_res; Rast_set_window(&wind); nrows = wind.rows; ncols = wind.cols; t = (wind.north - window.north) * nrows / (wind.north - wind.south); b = t + (window.north - window.south) * nrows / (wind.north - wind.south); l = (window.west - wind.west) * ncols / (wind.east - wind.west); r = l + (window.east - window.west) * ncols / (wind.east - wind.west); } else { nrows = window.rows; ncols = window.cols; t = 0; b = nrows; l = 0; r = ncols; } D_set_src(t, b, l, r); D_update_conversions(); /* figure out arrow scaling if using a magnitude map */ if (opt7->answer) { Rast_init_fp_range(&range); /* really needed? */ if (Rast_read_fp_range(mag_map, "", &range) != 1) G_fatal_error(_("Problem reading range file")); Rast_get_fp_range_min_max(&range, &mag_min, &mag_max); scale *= 1.5 / fabs(mag_max); G_debug(3, "scaling=%.2f rast_max=%.2f", scale, mag_max); } if (grid_color > 0) { /* ie not "none" */ /* Set color */ D_use_color(grid_color); /* Draw vertical grids */ for (col = 0; col < ncols; col++) D_line_abs(col, 0, col, nrows); /* Draw horizontal grids */ for (row = 0; row < nrows; row++) D_line_abs(0, row, ncols, row); } /* open the raster map */ layer_fd = Rast_open_old(layer_name, ""); raster_type = Rast_get_map_type(layer_fd); /* allocate the cell array */ raster_row = Rast_allocate_buf(raster_type); if (opt7->answer) { /* open the magnitude raster map */ mag_fd = Rast_open_old(mag_map, ""); mag_raster_type = Rast_get_map_type(mag_fd); /* allocate the cell array */ mag_raster_row = Rast_allocate_buf(mag_raster_type); } /* loop through cells, find value, determine direction (n,s,e,w,ne,se,sw,nw), and call appropriate function to draw an arrow on the cell */ for (row = 0; row < nrows; row++) { Rast_get_row(layer_fd, raster_row, row, raster_type); ptr = raster_row; if (opt7->answer) { Rast_get_row(mag_fd, mag_raster_row, row, mag_raster_type); mag_ptr = mag_raster_row; } for (col = 0; col < ncols; col++) { if (row % skip != 0) no_arrow = TRUE; else no_arrow = FALSE; if (col % skip != 0) no_arrow = TRUE; /* find aspect direction based on cell value */ if (raster_type == CELL_TYPE) aspect_f = *((CELL *) ptr); else if (raster_type == FCELL_TYPE) aspect_f = *((FCELL *) ptr); else if (raster_type == DCELL_TYPE) aspect_f = *((DCELL *) ptr); if (opt7->answer) { if (mag_raster_type == CELL_TYPE) length = *((CELL *) mag_ptr); else if (mag_raster_type == FCELL_TYPE) length = *((FCELL *) mag_ptr); else if (mag_raster_type == DCELL_TYPE) length = *((DCELL *) mag_ptr); length *= scale; if (Rast_is_null_value(mag_ptr, mag_raster_type)) { G_debug(5, "Invalid arrow length [NULL]. Skipping."); no_arrow = TRUE; } else if (length <= 0.0) { /* use fabs() or theta+=180? */ G_debug(5, "Illegal arrow length [%.3f]. Skipping.", length); no_arrow = TRUE; } } if (no_arrow) { ptr = G_incr_void_ptr(ptr, Rast_cell_size(raster_type)); if (opt7->answer) mag_ptr = G_incr_void_ptr(mag_ptr, Rast_cell_size(mag_raster_type)); no_arrow = FALSE; continue; } /* treat AGNPS and ANSWERS data like old zero-as-null CELL */ /* TODO: update models */ if (map_type == 2 || map_type == 3) { if (Rast_is_null_value(ptr, raster_type)) aspect_c = 0; else aspect_c = (int)(aspect_f + 0.5); } /** Now draw the arrows **/ /* case switch for standard GRASS aspect map measured in degrees counter-clockwise from east */ if (map_type == 1) { D_use_color(arrow_color); if (Rast_is_null_value(ptr, raster_type)) { /* don't draw anything if x_color is none (transparent) */ if (x_color > 0) { D_use_color(x_color); draw_x(); D_use_color(arrow_color); } } else if (aspect_f >= 0.0 && aspect_f <= 360.0) { if (opt7->answer) arrow_mag(aspect_f, length); else arrow_360(aspect_f); } else if (unknown_color > 0) { /* don't draw if unknown_color is none (transparent) */ D_use_color(unknown_color); unknown_(); D_use_color(arrow_color); } } /* case switch for AGNPS type aspect map */ else if (map_type == 2) { D_use_color(arrow_color); switch (aspect_c) { case 0: /* only draw if x_color is not none (transparent) */ if (x_color > 0) { D_use_color(x_color); draw_x(); D_use_color(arrow_color); } break; case 1: arrow_n(); break; case 2: arrow_ne(); break; case 3: arrow_e(); break; case 4: arrow_se(); break; case 5: arrow_s(); break; case 6: arrow_sw(); break; case 7: arrow_w(); break; case 8: arrow_nw(); break; default: /* only draw if unknown_color is not none */ if (unknown_color > 0) { D_use_color(unknown_color); unknown_(); D_use_color(arrow_color); } break; } } /* case switch for ANSWERS type aspect map */ else if (map_type == 3) { D_use_color(arrow_color); if (aspect_c >= 15 && aspect_c <= 360) /* start at zero? */ arrow_360((double)aspect_c); else if (aspect_c == 400) { if (unknown_color > 0) { /* only draw if unknown_color is not none */ D_use_color(unknown_color); unknown_(); D_use_color(arrow_color); } } else if (x_color > 0) { /* only draw if x_color is not none (transparent) */ D_use_color(x_color); draw_x(); D_use_color(arrow_color); } } /* case switch for compass type aspect map measured in degrees clockwise from north */ else if (map_type == 4) { D_use_color(arrow_color); if (Rast_is_null_value(ptr, raster_type)) { if (x_color > 0) { /* only draw if x_color is not none */ D_use_color(x_color); draw_x(); D_use_color(arrow_color); } } else if (aspect_f >= 0.0 && aspect_f <= 360.0) { if (opt7->answer) arrow_mag(90 - aspect_f, length); else arrow_360(90 - aspect_f); } else if (unknown_color > 0) { /* only draw if unknown_color is not none */ D_use_color(unknown_color); unknown_(); D_use_color(arrow_color); } } ptr = G_incr_void_ptr(ptr, Rast_cell_size(raster_type)); if (opt7->answer) mag_ptr = G_incr_void_ptr(mag_ptr, Rast_cell_size(mag_raster_type)); } } Rast_close(layer_fd); if (opt7->answer) Rast_close(mag_fd); D_save_command(G_recreate_command()); D_close_driver(); exit(EXIT_SUCCESS); }
static int calc_covariance(int *fds, double **covar, double *mu, int bands) { int j, k; int rows = Rast_window_rows(); int cols = Rast_window_cols(); int row, col; for (j = 0; j < bands; j++) { RASTER_MAP_TYPE maptype = Rast_get_map_type(fds[j]); void *rowbuf1 = NULL; void *rowbuf2 = NULL; /* don't assume each image is of the same type */ if (rowbuf1) G_free(rowbuf1); if ((rowbuf1 = Rast_allocate_buf(maptype)) == NULL) G_fatal_error(_("Unable allocate memory for row buffer")); G_message(_("Computing row %d (of %d) of covariance matrix..."), j + 1, bands); for (row = 0; row < rows; row++) { void *ptr1, *ptr2; G_percent(row, rows - 1, 2); Rast_get_row(fds[j], rowbuf1, row, maptype); for (k = j; k < bands; k++) { RASTER_MAP_TYPE maptype2 = Rast_get_map_type(fds[k]); /* don't assume each image is of the same type */ if (rowbuf2) G_free(rowbuf2); if ((rowbuf2 = Rast_allocate_buf(maptype2)) == NULL) G_fatal_error(_("Unable to allocate memory for row buffer")); Rast_get_row(fds[k], rowbuf2, row, maptype2); ptr1 = rowbuf1; ptr2 = rowbuf2; for (col = 0; col < cols; col++) { /* skip null cells */ if (Rast_is_null_value(ptr1, maptype) || Rast_is_null_value(ptr2, maptype2)) { ptr1 = G_incr_void_ptr(ptr1, Rast_cell_size(maptype)); ptr2 = G_incr_void_ptr(ptr2, Rast_cell_size(maptype2)); continue; } covar[j][k] += ((double)Rast_get_d_value(ptr1, maptype) - mu[j]) * ((double)Rast_get_d_value(ptr2, maptype2) - mu[k]); ptr1 = G_incr_void_ptr(ptr1, Rast_cell_size(maptype)); ptr2 = G_incr_void_ptr(ptr2, Rast_cell_size(maptype2)); } covar[k][j] = covar[j][k]; } } } return 0; }
int main(int argc, char *argv[]) { char *input; char *output; char *title; char *temp; FILE *fd, *ft; int cf, direction, sz; struct Cell_head cellhd; struct History history; void *rast, *rast_ptr; int row, col; int nrows, ncols; double x; char y[128]; struct GModule *module; struct { struct Option *input, *output, *title, *mult, *nv, *type; } parm; struct { struct Flag *s; } flag; char *null_val_str; DCELL mult; RASTER_MAP_TYPE data_type; double atof(); G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("import")); G_add_keyword(_("conversion")); G_add_keyword("ASCII"); module->description = _("Converts a GRASS ASCII raster file to binary raster map."); parm.input = G_define_standard_option(G_OPT_F_INPUT); parm.input->label = _("Name of input file to be imported"); parm.input->description = _("'-' for standard input"); parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.type = G_define_option(); parm.type->key = "type"; parm.type->type = TYPE_STRING; parm.type->required = NO; parm.type->options = "CELL,FCELL,DCELL"; parm.type->label = _("Storage type for resultant raster map"); parm.type->description = _("Default: CELL for integer values, DCELL for floating-point values"); parm.title = G_define_option(); parm.title->key = "title"; parm.title->key_desc = "phrase"; parm.title->type = TYPE_STRING; parm.title->required = NO; parm.title->description = _("Title for resultant raster map"); parm.mult = G_define_option(); parm.mult->key = "multiplier"; parm.mult->type = TYPE_DOUBLE; parm.mult->description = _("Default: read from header"); parm.mult->required = NO; parm.mult->label = _("Multiplier for ASCII data"); parm.nv = G_define_standard_option(G_OPT_M_NULL_VALUE); parm.nv->description = _("Default: read from header"); parm.nv->label = _("String representing NULL value data cell"); parm.nv->guisection = _("NULL data"); flag.s = G_define_flag(); flag.s->key = 's'; flag.s->description = _("SURFER (Golden Software) ASCII file will be imported"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); input = parm.input->answer; output = parm.output->answer; temp = G_tempfile(); ft = fopen(temp, "w+"); if (ft == NULL) G_fatal_error(_("Unable to open temporary file <%s>"), temp); if ((title = parm.title->answer)) G_strip(title); if (!parm.mult->answer) Rast_set_d_null_value(&mult, 1); else if ((sscanf(parm.mult->answer, "%lf", &mult)) != 1) G_fatal_error(_("Wrong entry for multiplier: %s"), parm.mult->answer); null_val_str = parm.nv->answer; data_type = -1; if (parm.type->answer) { switch(parm.type->answer[0]) { case 'C': data_type = CELL_TYPE; break; case 'F': data_type = FCELL_TYPE; break; case 'D': data_type = DCELL_TYPE; break; } } if (strcmp(input, "-") == 0) { Tmp_file = G_tempfile(); if (NULL == (Tmp_fd = fopen(Tmp_file, "w+"))) G_fatal_error(_("Unable to open temporary file <%s>"), Tmp_file); unlink(Tmp_file); if (0 > file_cpy(stdin, Tmp_fd)) G_fatal_error(_("Unable to read input from stdin")); fd = Tmp_fd; } else fd = fopen(input, "r"); if (fd == NULL) { G_fatal_error(_("Unable to read input from <%s>"), input); } direction = 1; sz = 0; if (flag.s->answer) { sz = getgrdhead(fd, &cellhd); /* for Surfer files, the data type is always FCELL_TYPE, the multiplier and the null_val_str are never used */ data_type = FCELL_TYPE; mult = 1.; null_val_str = ""; /* rows in surfer files are ordered from bottom to top, opposite of normal GRASS ordering */ direction = -1; } else sz = gethead(fd, &cellhd, &data_type, &mult, &null_val_str); if (!sz) G_fatal_error(_("Can't get cell header")); nrows = cellhd.rows; ncols = cellhd.cols; Rast_set_window(&cellhd); if (nrows != Rast_window_rows()) G_fatal_error(_("OOPS: rows changed from %d to %d"), nrows, Rast_window_rows()); if (ncols != Rast_window_cols()) G_fatal_error(_("OOPS: cols changed from %d to %d"), ncols, Rast_window_cols()); rast_ptr = Rast_allocate_buf(data_type); rast = rast_ptr; cf = Rast_open_new(output, data_type); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); for (col = 0; col < ncols; col++) { if (fscanf(fd, "%s", y) != 1) { Rast_unopen(cf); G_fatal_error(_("Data conversion failed at row %d, col %d"), row + 1, col + 1); } if (strcmp(y, null_val_str)) { x = atof(y); if ((float)x == GS_BLANK) { Rast_set_null_value(rast_ptr, 1, data_type); } else { Rast_set_d_value(rast_ptr, (DCELL) (x * mult), data_type); } } else { Rast_set_null_value(rast_ptr, 1, data_type); } rast_ptr = G_incr_void_ptr(rast_ptr, Rast_cell_size(data_type)); } fwrite(rast, Rast_cell_size(data_type), ncols, ft); rast_ptr = rast; } G_percent(nrows, nrows, 2); G_debug(1, "Creating support files for %s", output); sz = 0; if (direction < 0) { sz = -ncols * Rast_cell_size(data_type); G_fseek(ft, sz, SEEK_END); sz *= 2; } else { G_fseek(ft, 0L, SEEK_SET); } for (row = 0; row < nrows; row += 1) { fread(rast, Rast_cell_size(data_type), ncols, ft); Rast_put_row(cf, rast, data_type); G_fseek(ft, sz, SEEK_CUR); } fclose(ft); unlink(temp); Rast_close(cf); if (title) Rast_put_cell_title(output, title); Rast_short_history(output, "raster", &history); Rast_command_history(&history); Rast_write_history(output, &history); G_done_msg(" "); exit(EXIT_SUCCESS); }
/* ************************************************************************* */ void write_vtk_points(input_maps * in, FILE * fp, RASTER3D_Region region, int dp, int type, double scale) { int x, y, z, percentage = 0; int rows, cols, depths; void *rast_top = NULL; void *rast_bottom = NULL; void *ptr_top = NULL; void *ptr_bottom = NULL; double topval = 0, bottomval = 0; double zcoor, ycoor, xcoor; double zcoor1, ycoor1, xcoor1; rows = region.rows; cols = region.cols; depths = region.depths; rast_top = Rast_allocate_buf(in->topMapType); rast_bottom = Rast_allocate_buf(in->bottomMapType); G_debug(3, _("write_vtk_points: Writing point coordinates")); for (z = 0; z < depths; z++) { for (y = 0; y < rows; y++) { G_percent(percentage, (rows * depths - 1), 10); percentage++; Rast_get_row(in->top, rast_top, y, in->topMapType); Rast_get_row(in->bottom, rast_bottom, y, in->bottomMapType); for (x = 0, ptr_top = rast_top, ptr_bottom = rast_bottom; x < cols; x++, ptr_top = G_incr_void_ptr(ptr_top, Rast_cell_size(in->topMapType)), ptr_bottom = G_incr_void_ptr(ptr_bottom, Rast_cell_size(in->bottomMapType))) { /*Get the values */ topval = get_raster_value_as_double(in->topMapType, ptr_top, 0.0); bottomval = get_raster_value_as_double(in->bottomMapType, ptr_bottom, 0.0); if (type == 1) { /*Structured Grid */ /*Calculate the coordinates */ xcoor = region.west + (region.ew_res / 2 + region.ew_res * (x)); /* Here the raster3d north->south coordinate system is used */ ycoor = region.north - (region.ns_res / 2 + region.ns_res * (y)); zcoor = (bottomval + z * (topval - bottomval) / (depths - 1)) * scale; xcoor -= x_extent; ycoor -= y_extent; fprintf(fp, "%.*f ", dp, xcoor); fprintf(fp, "%.*f ", dp, ycoor); fprintf(fp, "%.*f\n", dp, zcoor); } else { /*Unstructured Grid */ /*Write for every cell the coordinates for a hexahedron -> 8 points */ /*VTK Hexaeder */ /* bottom * 3 --- 2 * | | * 0 --- 1 * top * 7 --- 6 * | | * 4 --- 5 */ xcoor = region.west + (region.ew_res * (x)); /*0, 3, 4, 7 */ /* Here the raster3d north->south coordinate system is used */ ycoor = region.north - (region.ns_res * (y)); /*2, 3, 6, 7 */ zcoor = (bottomval + z * (topval - bottomval) / (depths)) * scale; /*0, 1, 2, 3 */ xcoor1 = region.west + (region.ew_res + region.ew_res * (x)); /*1, 2, 5, 6 */ /* Here the raster3d north->south coordinate system is used */ ycoor1 = region.north - (region.ns_res + region.ns_res * (y)); /*0, 1, 4, 5 */ zcoor1 = (bottomval + z * (topval - bottomval) / (depths) + (topval - bottomval) / (depths)) * scale; /*4, 5, ,6 ,7 */ xcoor -= x_extent; ycoor -= y_extent; xcoor1 -= x_extent; ycoor1 -= y_extent; /*0 */ fprintf(fp, "%.*f ", dp, xcoor); fprintf(fp, "%.*f ", dp, ycoor1); fprintf(fp, "%.*f\n", dp, zcoor); /*1 */ fprintf(fp, "%.*f ", dp, xcoor1); fprintf(fp, "%.*f ", dp, ycoor1); fprintf(fp, "%.*f\n", dp, zcoor); /*2 */ fprintf(fp, "%.*f ", dp, xcoor1); fprintf(fp, "%.*f ", dp, ycoor); fprintf(fp, "%.*f\n", dp, zcoor); /*3 */ fprintf(fp, "%.*f ", dp, xcoor); fprintf(fp, "%.*f ", dp, ycoor); fprintf(fp, "%.*f\n", dp, zcoor); /*4 */ fprintf(fp, "%.*f ", dp, xcoor); fprintf(fp, "%.*f ", dp, ycoor1); fprintf(fp, "%.*f\n", dp, zcoor1); /*5 */ fprintf(fp, "%.*f ", dp, xcoor1); fprintf(fp, "%.*f ", dp, ycoor1); fprintf(fp, "%.*f\n", dp, zcoor1); /*6 */ fprintf(fp, "%.*f ", dp, xcoor1); fprintf(fp, "%.*f ", dp, ycoor); fprintf(fp, "%.*f\n", dp, zcoor1); /*7 */ fprintf(fp, "%.*f ", dp, xcoor); fprintf(fp, "%.*f ", dp, ycoor); fprintf(fp, "%.*f\n", dp, zcoor1); } } } } if (type == 1) fprintf(fp, "POINT_DATA %i\n", region.cols * region.rows * region.depths); /*We have pointdata */ return; }
int main(int argc, char **argv) { char *mapname, /* ptr to name of output layer */ *setname, /* ptr to name of input mapset */ *ipolname; /* name of interpolation method */ int fdi, /* input map file descriptor */ fdo, /* output map file descriptor */ method, /* position of method in table */ permissions, /* mapset permissions */ cell_type, /* output celltype */ cell_size, /* size of a cell in bytes */ row, col, /* counters */ irows, icols, /* original rows, cols */ orows, ocols, have_colors, /* Input map has a colour table */ overwrite, /* Overwrite */ curr_proj; /* output projection (see gis.h) */ void *obuffer; /* buffer that holds one output row */ struct cache *ibuffer; /* buffer that holds the input map */ func interpolate; /* interpolation routine */ double xcoord2, /* temporary x coordinates */ ycoord2, /* temporary y coordinates */ onorth, osouth, /* save original border coords */ oeast, owest, inorth, isouth, ieast, iwest; char north_str[30], south_str[30], east_str[30], west_str[30]; struct Colors colr; /* Input map colour table */ struct History history; struct pj_info iproj, /* input map proj parameters */ oproj; /* output map proj parameters */ struct Key_Value *in_proj_info, /* projection information of */ *in_unit_info, /* input and output mapsets */ *out_proj_info, *out_unit_info; struct GModule *module; struct Flag *list, /* list files in source location */ *nocrop, /* don't crop output map */ *print_bounds, /* print output bounds and exit */ *gprint_bounds; /* same but print shell style */ struct Option *imapset, /* name of input mapset */ *inmap, /* name of input layer */ *inlocation, /* name of input location */ *outmap, /* name of output layer */ *indbase, /* name of input database */ *interpol, /* interpolation method: nearest neighbor, bilinear, cubic */ *memory, /* amount of memory for cache */ *res; /* resolution of target map */ struct Cell_head incellhd, /* cell header of input map */ outcellhd; /* and output map */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("projection")); G_add_keyword(_("transformation")); module->description = _("Re-projects a raster map from given location to the current location."); inmap = G_define_standard_option(G_OPT_R_INPUT); inmap->description = _("Name of input raster map to re-project"); inmap->required = NO; inmap->guisection = _("Source"); inlocation = G_define_option(); inlocation->key = "location"; inlocation->type = TYPE_STRING; inlocation->required = YES; inlocation->description = _("Location containing input raster map"); inlocation->gisprompt = "old,location,location"; inlocation->key_desc = "name"; imapset = G_define_standard_option(G_OPT_M_MAPSET); imapset->label = _("Mapset containing input raster map"); imapset->description = _("Default: name of current mapset"); imapset->guisection = _("Source"); indbase = G_define_option(); indbase->key = "dbase"; indbase->type = TYPE_STRING; indbase->required = NO; indbase->description = _("Path to GRASS database of input location"); indbase->gisprompt = "old,dbase,dbase"; indbase->key_desc = "path"; indbase->guisection = _("Source"); outmap = G_define_standard_option(G_OPT_R_OUTPUT); outmap->required = NO; outmap->description = _("Name for output raster map (default: same as 'input')"); outmap->guisection = _("Target"); ipolname = make_ipol_list(); interpol = G_define_option(); interpol->key = "method"; interpol->type = TYPE_STRING; interpol->required = NO; interpol->answer = "nearest"; interpol->options = ipolname; interpol->description = _("Interpolation method to use"); interpol->guisection = _("Target"); interpol->descriptions = make_ipol_desc(); memory = G_define_option(); memory->key = "memory"; memory->type = TYPE_INTEGER; memory->required = NO; memory->answer = "300"; memory->label = _("Maximum memory to be used (in MB)"); memory->description = _("Cache size for raster rows"); res = G_define_option(); res->key = "resolution"; res->type = TYPE_DOUBLE; res->required = NO; res->description = _("Resolution of output raster map"); res->guisection = _("Target"); list = G_define_flag(); list->key = 'l'; list->description = _("List raster maps in input mapset and exit"); list->guisection = _("Print"); nocrop = G_define_flag(); nocrop->key = 'n'; nocrop->description = _("Do not perform region cropping optimization"); print_bounds = G_define_flag(); print_bounds->key = 'p'; print_bounds->description = _("Print input map's bounds in the current projection and exit"); print_bounds->guisection = _("Print"); gprint_bounds = G_define_flag(); gprint_bounds->key = 'g'; gprint_bounds->description = _("Print input map's bounds in the current projection and exit (shell style)"); gprint_bounds->guisection = _("Print"); /* The parser checks if the map already exists in current mapset, we switch out the check and do it in the module after the parser */ overwrite = G_check_overwrite(argc, argv); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* get the method */ for (method = 0; (ipolname = menu[method].name); method++) if (strcmp(ipolname, interpol->answer) == 0) break; if (!ipolname) G_fatal_error(_("<%s=%s> unknown %s"), interpol->key, interpol->answer, interpol->key); interpolate = menu[method].method; mapname = outmap->answer ? outmap->answer : inmap->answer; if (mapname && !list->answer && !overwrite && !print_bounds->answer && !gprint_bounds->answer && G_find_raster(mapname, G_mapset())) G_fatal_error(_("option <%s>: <%s> exists."), "output", mapname); setname = imapset->answer ? imapset->answer : G_store(G_mapset()); if (strcmp(inlocation->answer, G_location()) == 0 && (!indbase->answer || strcmp(indbase->answer, G_gisdbase()) == 0)) #if 0 G_fatal_error(_("Input and output locations can not be the same")); #else G_warning(_("Input and output locations are the same")); #endif G_get_window(&outcellhd); if(gprint_bounds->answer && !print_bounds->answer) print_bounds->answer = gprint_bounds->answer; curr_proj = G_projection(); /* Get projection info for output mapset */ if ((out_proj_info = G_get_projinfo()) == NULL) G_fatal_error(_("Unable to get projection info of output raster map")); if ((out_unit_info = G_get_projunits()) == NULL) G_fatal_error(_("Unable to get projection units of output raster map")); if (pj_get_kv(&oproj, out_proj_info, out_unit_info) < 0) G_fatal_error(_("Unable to get projection key values of output raster map")); /* Change the location */ G_create_alt_env(); G__setenv("GISDBASE", indbase->answer ? indbase->answer : G_gisdbase()); G__setenv("LOCATION_NAME", inlocation->answer); permissions = G__mapset_permissions(setname); if (permissions < 0) /* can't access mapset */ G_fatal_error(_("Mapset <%s> in input location <%s> - %s"), setname, inlocation->answer, permissions == 0 ? _("permission denied") : _("not found")); /* if requested, list the raster maps in source location - MN 5/2001 */ if (list->answer) { int i; char **list; G_verbose_message(_("Checking location <%s> mapset <%s>"), inlocation->answer, setname); list = G_list(G_ELEMENT_RASTER, G__getenv("GISDBASE"), G__getenv("LOCATION_NAME"), setname); for (i = 0; list[i]; i++) { fprintf(stdout, "%s\n", list[i]); } fflush(stdout); exit(EXIT_SUCCESS); /* leave r.proj after listing */ } if (!inmap->answer) G_fatal_error(_("Required parameter <%s> not set"), inmap->key); if (!G_find_raster(inmap->answer, setname)) G_fatal_error(_("Raster map <%s> in location <%s> in mapset <%s> not found"), inmap->answer, inlocation->answer, setname); /* Read input map colour table */ have_colors = Rast_read_colors(inmap->answer, setname, &colr); /* Get projection info for input mapset */ if ((in_proj_info = G_get_projinfo()) == NULL) G_fatal_error(_("Unable to get projection info of input map")); if ((in_unit_info = G_get_projunits()) == NULL) G_fatal_error(_("Unable to get projection units of input map")); if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0) G_fatal_error(_("Unable to get projection key values of input map")); G_free_key_value(in_proj_info); G_free_key_value(in_unit_info); G_free_key_value(out_proj_info); G_free_key_value(out_unit_info); if (G_verbose() > G_verbose_std()) pj_print_proj_params(&iproj, &oproj); /* this call causes r.proj to read the entire map into memeory */ Rast_get_cellhd(inmap->answer, setname, &incellhd); Rast_set_input_window(&incellhd); if (G_projection() == PROJECTION_XY) G_fatal_error(_("Unable to work with unprojected data (xy location)")); /* Save default borders so we can show them later */ inorth = incellhd.north; isouth = incellhd.south; ieast = incellhd.east; iwest = incellhd.west; irows = incellhd.rows; icols = incellhd.cols; onorth = outcellhd.north; osouth = outcellhd.south; oeast = outcellhd.east; owest = outcellhd.west; orows = outcellhd.rows; ocols = outcellhd.cols; if (print_bounds->answer) { G_message(_("Input map <%s@%s> in location <%s>:"), inmap->answer, setname, inlocation->answer); outcellhd.north = -1e9; outcellhd.south = 1e9; outcellhd.east = -1e9; outcellhd.west = 1e9; bordwalk2(&incellhd, &outcellhd, &iproj, &oproj); inorth = outcellhd.north; isouth = outcellhd.south; ieast = outcellhd.east; iwest = outcellhd.west; G_format_northing(inorth, north_str, curr_proj); G_format_northing(isouth, south_str, curr_proj); G_format_easting(ieast, east_str, curr_proj); G_format_easting(iwest, west_str, curr_proj); if(gprint_bounds->answer) { fprintf(stdout, "n=%s s=%s w=%s e=%s rows=%d cols=%d\n", north_str, south_str, west_str, east_str, irows, icols); } else { fprintf(stdout, "Source cols: %d\n", icols); fprintf(stdout, "Source rows: %d\n", irows); fprintf(stdout, "Local north: %s\n", north_str); fprintf(stdout, "Local south: %s\n", south_str); fprintf(stdout, "Local west: %s\n", west_str); fprintf(stdout, "Local east: %s\n", east_str); } /* somehow approximate local ewres, nsres ?? (use 'g.region -m' on lat/lon side) */ exit(EXIT_SUCCESS); } /* Cut non-overlapping parts of input map */ if (!nocrop->answer) bordwalk(&outcellhd, &incellhd, &oproj, &iproj); /* Add 2 cells on each side for bilinear/cubic & future interpolation methods */ /* (should probably be a factor based on input and output resolution) */ incellhd.north += 2 * incellhd.ns_res; incellhd.east += 2 * incellhd.ew_res; incellhd.south -= 2 * incellhd.ns_res; incellhd.west -= 2 * incellhd.ew_res; if (incellhd.north > inorth) incellhd.north = inorth; if (incellhd.east > ieast) incellhd.east = ieast; if (incellhd.south < isouth) incellhd.south = isouth; if (incellhd.west < iwest) incellhd.west = iwest; Rast_set_input_window(&incellhd); /* And switch back to original location */ G_switch_env(); /* Adjust borders of output map */ if (!nocrop->answer) bordwalk(&incellhd, &outcellhd, &iproj, &oproj); #if 0 outcellhd.west = outcellhd.south = HUGE_VAL; outcellhd.east = outcellhd.north = -HUGE_VAL; for (row = 0; row < incellhd.rows; row++) { ycoord1 = Rast_row_to_northing((double)(row + 0.5), &incellhd); for (col = 0; col < incellhd.cols; col++) { xcoord1 = Rast_col_to_easting((double)(col + 0.5), &incellhd); pj_do_proj(&xcoord1, &ycoord1, &iproj, &oproj); if (xcoord1 > outcellhd.east) outcellhd.east = xcoord1; if (ycoord1 > outcellhd.north) outcellhd.north = ycoord1; if (xcoord1 < outcellhd.west) outcellhd.west = xcoord1; if (ycoord1 < outcellhd.south) outcellhd.south = ycoord1; } } #endif if (res->answer != NULL) /* set user defined resolution */ outcellhd.ns_res = outcellhd.ew_res = atof(res->answer); G_adjust_Cell_head(&outcellhd, 0, 0); Rast_set_output_window(&outcellhd); G_message(" "); G_message(_("Input:")); G_message(_("Cols: %d (%d)"), incellhd.cols, icols); G_message(_("Rows: %d (%d)"), incellhd.rows, irows); G_message(_("North: %f (%f)"), incellhd.north, inorth); G_message(_("South: %f (%f)"), incellhd.south, isouth); G_message(_("West: %f (%f)"), incellhd.west, iwest); G_message(_("East: %f (%f)"), incellhd.east, ieast); G_message(_("EW-res: %f"), incellhd.ew_res); G_message(_("NS-res: %f"), incellhd.ns_res); G_message(" "); G_message(_("Output:")); G_message(_("Cols: %d (%d)"), outcellhd.cols, ocols); G_message(_("Rows: %d (%d)"), outcellhd.rows, orows); G_message(_("North: %f (%f)"), outcellhd.north, onorth); G_message(_("South: %f (%f)"), outcellhd.south, osouth); G_message(_("West: %f (%f)"), outcellhd.west, owest); G_message(_("East: %f (%f)"), outcellhd.east, oeast); G_message(_("EW-res: %f"), outcellhd.ew_res); G_message(_("NS-res: %f"), outcellhd.ns_res); G_message(" "); /* open and read the relevant parts of the input map and close it */ G_switch_env(); Rast_set_input_window(&incellhd); fdi = Rast_open_old(inmap->answer, setname); cell_type = Rast_get_map_type(fdi); ibuffer = readcell(fdi, memory->answer); Rast_close(fdi); G_switch_env(); Rast_set_output_window(&outcellhd); if (strcmp(interpol->answer, "nearest") == 0) { fdo = Rast_open_new(mapname, cell_type); obuffer = (CELL *) Rast_allocate_output_buf(cell_type); } else { fdo = Rast_open_fp_new(mapname); cell_type = FCELL_TYPE; obuffer = (FCELL *) Rast_allocate_output_buf(cell_type); } cell_size = Rast_cell_size(cell_type); xcoord2 = outcellhd.west + (outcellhd.ew_res / 2); ycoord2 = outcellhd.north - (outcellhd.ns_res / 2); G_important_message(_("Projecting...")); for (row = 0; row < outcellhd.rows; row++) { /* obufptr = obuffer */; G_percent(row, outcellhd.rows - 1, 2); #if 0 /* parallelization does not always work, * segfaults in the interpolation functions * can happen */ #pragma omp parallel for schedule (static) #endif for (col = 0; col < outcellhd.cols; col++) { void *obufptr = (void *)((const unsigned char *)obuffer + col * cell_size); double xcoord1 = xcoord2 + (col) * outcellhd.ew_res; double ycoord1 = ycoord2; /* project coordinates in output matrix to */ /* coordinates in input matrix */ if (pj_do_proj(&xcoord1, &ycoord1, &oproj, &iproj) < 0) Rast_set_null_value(obufptr, 1, cell_type); else { /* convert to row/column indices of input matrix */ /* column index in input matrix */ double col_idx = (xcoord1 - incellhd.west) / incellhd.ew_res; /* row index in input matrix */ double row_idx = (incellhd.north - ycoord1) / incellhd.ns_res; /* and resample data point */ interpolate(ibuffer, obufptr, cell_type, col_idx, row_idx, &incellhd); } /* obufptr = G_incr_void_ptr(obufptr, cell_size); */ } Rast_put_row(fdo, obuffer, cell_type); xcoord2 = outcellhd.west + (outcellhd.ew_res / 2); ycoord2 -= outcellhd.ns_res; } Rast_close(fdo); release_cache(ibuffer); if (have_colors > 0) { Rast_write_colors(mapname, G_mapset(), &colr); Rast_free_colors(&colr); } Rast_short_history(mapname, "raster", &history); Rast_command_history(&history); Rast_write_history(mapname, &history); G_done_msg(" "); exit(EXIT_SUCCESS); }
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 main(int argc, char *argv[]) { int out_fd; CELL *result, *rp; int nrows, ncols; int row, col, count_sum; int field; struct GModule *module; struct Option *in_opt, *out_opt, *field_opt; struct Option *method_opt, *size_opt; struct Map_info In; double radius; struct boxlist *List; struct Cell_head region; struct bound_box box; struct line_pnts *Points; struct line_cats *Cats; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("algebra")); G_add_keyword(_("statistics")); G_add_keyword(_("raster")); G_add_keyword(_("aggregation")); module->label = _("Neighborhood analysis tool for vector point maps."); module->description = _("Makes each cell value a " "function of the attribute values assigned to the vector points or centroids " "around it, and stores new cell values in an output raster map."); in_opt = G_define_standard_option(G_OPT_V_INPUT); field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL); out_opt = G_define_standard_option(G_OPT_R_OUTPUT); method_opt = G_define_option(); method_opt->key = "method"; method_opt->type = TYPE_STRING; method_opt->required = YES; method_opt->options = "count"; method_opt->answer = "count"; method_opt->description = _("Neighborhood operation"); size_opt = G_define_option(); size_opt->key = "size"; size_opt->type = TYPE_DOUBLE; size_opt->required = YES; size_opt->description = _("Neighborhood diameter in map units"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); radius = atof(size_opt->answer) / 2; /* open input vector */ Vect_set_open_level(2); if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < 0) G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer); field = Vect_get_field_number(&In, field_opt->answer); G_get_set_window(®ion); nrows = Rast_window_rows(); ncols = Rast_window_cols(); result = Rast_allocate_buf(CELL_TYPE); Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); List = Vect_new_boxlist(0); /*open the new cellfile */ out_fd = Rast_open_new(out_opt->answer, CELL_TYPE); box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; count_sum = 0; for (row = 0; row < nrows; row++) { double x, y; G_percent(row, nrows, 2); y = Rast_row_to_northing(row + 0.5, ®ion); box.N = y + radius; box.S = y - radius; Rast_set_null_value(result, ncols, CELL_TYPE); rp = result; for (col = 0; col < ncols; col++) { int i, count; CELL value; x = Rast_col_to_easting(col + 0.5, ®ion); box.E = x + radius; box.W = x - radius; Vect_select_lines_by_box(&In, &box, GV_POINTS, List); G_debug(3, " %d lines in box", List->n_values); count = 0; for (i = 0; i < List->n_values; i++) { Vect_read_line(&In, Points, Cats, List->id[i]); if (field != -1 && Vect_cat_get(Cats, field, NULL) == 0) continue; if (Vect_points_distance(x, y, 0.0, Points->x[0], Points->y[0], 0.0, 0) <= radius) count++; } if (count > 0) { value = count; Rast_set_d_value(rp, value, CELL_TYPE); } rp = G_incr_void_ptr(rp, Rast_cell_size(CELL_TYPE)); count_sum += count; } Rast_put_row(out_fd, result, CELL_TYPE); } G_percent(1, 1, 1); Vect_close(&In); Rast_close(out_fd); if (count_sum < 1) G_warning(_("No points found")); exit(EXIT_SUCCESS); }