int main(int argc, char *argv[]) { /* Global variable & function declarations */ struct GModule *module; struct { struct Option *orig, *real, *imag; } opt; const char *Cellmap_real, *Cellmap_imag; const char *Cellmap_orig; int realfd, imagfd, outputfd, maskfd; /* the input and output file descriptors */ struct Cell_head realhead, imaghead; DCELL *cell_real, *cell_imag; CELL *maskbuf; int i, j; /* Loop control variables */ int rows, cols; /* number of rows & columns */ long totsize; /* Total number of data points */ double (*data)[2]; /* Data structure containing real & complex values of FFT */ G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("imagery")); G_add_keyword(_("transformation")); G_add_keyword(_("Fast Fourier Transform")); module->description = _("Inverse Fast Fourier Transform (IFFT) for image processing."); /* define options */ opt.real = G_define_standard_option(G_OPT_R_INPUT); opt.real->key = "real"; opt.real->description = _("Name of input raster map (image fft, real part)"); opt.imag = G_define_standard_option(G_OPT_R_INPUT); opt.imag->key = "imaginary"; opt.imag->description = _("Name of input raster map (image fft, imaginary part"); opt.orig = G_define_standard_option(G_OPT_R_OUTPUT); opt.orig->description = _("Name for output raster map"); /*call parser */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); Cellmap_real = opt.real->answer; Cellmap_imag = opt.imag->answer; Cellmap_orig = opt.orig->answer; /* get and compare the original window data */ Rast_get_cellhd(Cellmap_real, "", &realhead); Rast_get_cellhd(Cellmap_imag, "", &imaghead); if (realhead.proj != imaghead.proj || realhead.zone != imaghead.zone || realhead.north != imaghead.north || realhead.south != imaghead.south || realhead.east != imaghead.east || realhead.west != imaghead.west || realhead.ew_res != imaghead.ew_res || realhead.ns_res != imaghead.ns_res) G_fatal_error(_("The real and imaginary original windows did not match")); Rast_set_window(&realhead); /* set the window to the whole cell map */ /* open input raster map */ realfd = Rast_open_old(Cellmap_real, ""); imagfd = Rast_open_old(Cellmap_imag, ""); /* get the rows and columns in the current window */ rows = Rast_window_rows(); cols = Rast_window_cols(); totsize = rows * cols; /* Allocate appropriate memory for the structure containing the real and complex components of the FFT. DATA[0] will contain the real, and DATA[1] the complex component. */ data = G_malloc(rows * cols * 2 * sizeof(double)); /* allocate the space for one row of cell map data */ cell_real = Rast_allocate_d_buf(); cell_imag = Rast_allocate_d_buf(); #define C(i, j) ((i) * cols + (j)) /* Read in cell map values */ G_message(_("Reading raster maps...")); for (i = 0; i < rows; i++) { Rast_get_d_row(realfd, cell_real, i); Rast_get_d_row(imagfd, cell_imag, i); for (j = 0; j < cols; j++) { data[C(i, j)][0] = cell_real[j]; data[C(i, j)][1] = cell_imag[j]; } G_percent(i+1, rows, 2); } /* close input cell maps */ Rast_close(realfd); Rast_close(imagfd); /* Read in cell map values */ G_message(_("Masking raster maps...")); maskfd = Rast_maskfd(); if (maskfd >= 0) { maskbuf = Rast_allocate_c_buf(); for (i = 0; i < rows; i++) { Rast_get_c_row(maskfd, maskbuf, i); for (j = 0; j < cols; j++) { if (maskbuf[j] == 0) { data[C(i, j)][0] = 0.0; data[C(i, j)][1] = 0.0; } } G_percent(i+1, rows, 2); } Rast_close(maskfd); G_free(maskbuf); } #define SWAP1(a, b) \ do { \ double temp = (a); \ (a) = (b); \ (b) = temp; \ } while (0) #define SWAP2(a, b) \ do { \ SWAP1(data[(a)][0], data[(b)][0]); \ SWAP1(data[(a)][1], data[(b)][1]); \ } while (0) /* rotate the data array for standard display */ G_message(_("Rotating data...")); for (i = 0; i < rows; i++) for (j = 0; j < cols / 2; j++) SWAP2(C(i, j), C(i, j + cols / 2)); for (i = 0; i < rows / 2; i++) for (j = 0; j < cols; j++) SWAP2(C(i, j), C(i + rows / 2, j)); /* perform inverse FFT */ G_message(_("Starting Inverse FFT...")); fft2(1, data, totsize, cols, rows); /* open the output cell map */ outputfd = Rast_open_fp_new(Cellmap_orig); /* Write out result to a new cell map */ G_message(_("Writing raster map <%s>..."), Cellmap_orig); for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) cell_real[j] = data[C(i, j)][0]; Rast_put_d_row(outputfd, cell_real); G_percent(i+1, rows, 2); } Rast_close(outputfd); G_free(cell_real); G_free(cell_imag); fft_colors(Cellmap_orig); /* Release memory resources */ G_free(data); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int fd, maskfd; CELL *cell, *mask; struct Cell_head window; int row, col; double north, east; double dx, dy; double maxdist, dist; double sum1, sum2; int i, n, max; struct GModule *module; struct History history; struct { struct Option *input, *npoints, *output; } parm; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("surface")); G_add_keyword(_("interpolation")); G_add_keyword(_("IDW")); module->description = _("Surface generation program."); parm.input = G_define_standard_option(G_OPT_R_INPUT); parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.npoints = G_define_option(); parm.npoints->key = "npoints"; parm.npoints->key_desc = "count"; parm.npoints->type = TYPE_INTEGER; parm.npoints->required = NO; parm.npoints->description = _("Number of interpolation points"); parm.npoints->answer = "12"; if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* Make sure that the current projection is not lat/long */ if ((G_projection() == PROJECTION_LL)) G_fatal_error(_("Lat/long databases not supported by r.surf.idw2. Use r.surf.idw instead!")); if (sscanf(parm.npoints->answer, "%d", &search_points) != 1 || search_points < 1) G_fatal_error(_("%s=%s - illegal number of interpolation points"), parm.npoints->key, parm.npoints->answer); list = (struct Point *)G_calloc(search_points, sizeof(struct Point)); /* read the elevation points from the input raster map */ read_cell(parm.input->answer); if (npoints == 0) G_fatal_error(_("%s: no data points found"), G_program_name()); nsearch = npoints < search_points ? npoints : search_points; /* get the window, allocate buffers, etc. */ G_get_set_window(&window); cell = Rast_allocate_c_buf(); if ((maskfd = Rast_maskfd()) >= 0) mask = Rast_allocate_c_buf(); else mask = NULL; fd = Rast_open_c_new(parm.output->answer); G_message(_("Interpolating raster map <%s>... %d rows... "), parm.output->answer, window.rows); north = window.north - window.ns_res / 2.0; for (row = 0; row < window.rows; row++) { G_percent(row, window.rows, 2); if (mask) Rast_get_c_row(maskfd, mask, row); north += window.ns_res; east = window.west - window.ew_res / 2.0; for (col = 0; col < window.cols; col++) { east += window.ew_res; /* don't interpolate outside of the mask */ if (mask && mask[col] == 0) { cell[col] = 0; continue; } /* fill list with first nsearch points */ for (i = 0; i < nsearch; i++) { dy = points[i].north - north; dx = points[i].east - east; list[i].dist = dy * dy + dx * dx; list[i].z = points[i].z; } /* find the maximum distance */ maxdist = list[max = 0].dist; for (n = 1; n < nsearch; n++) { if (maxdist < list[n].dist) maxdist = list[max = n].dist; } /* go thru rest of the points now */ for (; i < npoints; i++) { dy = points[i].north - north; dx = points[i].east - east; dist = dy * dy + dx * dx; if (dist < maxdist) { /* replace the largest dist */ list[max].z = points[i].z; list[max].dist = dist; maxdist = list[max = 0].dist; for (n = 1; n < nsearch; n++) { if (maxdist < list[n].dist) maxdist = list[max = n].dist; } } } /* interpolate */ sum1 = 0.0; sum2 = 0.0; for (n = 0; n < nsearch; n++) { if ((dist = list[n].dist)) { sum1 += list[n].z / dist; sum2 += 1.0 / dist; } else { sum1 = list[n].z; sum2 = 1.0; break; } } cell[col] = (CELL) (sum1 / sum2 + 0.5); } Rast_put_row(fd, cell, CELL_TYPE); } G_free(points); G_free(cell); Rast_close(fd); /* writing history file */ Rast_short_history(parm.output->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(parm.output->answer, &history); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { MELEMENT *rowlist; SHORT nrows, ncols; SHORT datarows; int npoints; struct GModule *module; struct History history; struct { struct Option *input, *output, *npoints; } parm; struct { struct Flag *e; } flag; int n, fd, maskfd; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("surface")); G_add_keyword(_("interpolation")); G_add_keyword(_("IDW")); module->description = _("Surface interpolation utility for raster map."); parm.input = G_define_standard_option(G_OPT_R_INPUT); parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.npoints = G_define_option(); parm.npoints->key = "npoints"; parm.npoints->type = TYPE_INTEGER; parm.npoints->required = NO; parm.npoints->description = _("Number of interpolation points"); parm.npoints->answer = "12"; flag.e = G_define_flag(); flag.e->key = 'e'; flag.e->description = _("Output is the interpolation error"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (sscanf(parm.npoints->answer, "%d", &n) != 1 || n <= 0) G_fatal_error(_("Illegal value for '%s' (%s)"), parm.npoints->key, parm.npoints->answer); npoints = n; error_flag = flag.e->answer; input = parm.input->answer; output = parm.output->answer; /* Get database window parameters */ G_get_window(&window); /* find number of rows and columns in window */ nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* create distance squared or latitude lookup tables */ /* initialize function pointers */ lookup_and_function_ptrs(nrows, ncols); /* allocate buffers for row i/o */ cell = Rast_allocate_c_buf(); if ((maskfd = Rast_maskfd()) >= 0 || error_flag) { /* apply mask to output */ if (error_flag) /* use input as mask when -e option chosen */ maskfd = Rast_open_old(input, ""); mask = Rast_allocate_c_buf(); } else mask = NULL; /* Open input cell layer for reading */ fd = Rast_open_old(input, ""); /* Store input data in array-indexed doubly-linked lists and close input file */ rowlist = row_lists(nrows, ncols, &datarows, &n, fd, cell); Rast_close(fd); if (npoints > n) npoints = n; /* open cell layer for writing output */ fd = Rast_open_c_new(output); /* call the interpolation function */ interpolate(rowlist, nrows, ncols, datarows, npoints, fd, maskfd); /* free allocated memory */ free_row_lists(rowlist, nrows); G_free(rowlook); G_free(collook); if (ll) free_dist_params(); Rast_close(fd); /* writing history file */ Rast_short_history(output, "raster", &history); Rast_command_history(&history); Rast_write_history(output, &history); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int fd, maskfd; CELL *mask; DCELL *dcell; struct GModule *module; struct History history; int row, col; int searchrow, searchcolumn, pointsfound; int *shortlistrows = NULL, *shortlistcolumns = NULL; long ncells = 0; double north, east; double dist; double sum1, sum2, interp_value; int n; double p; struct { struct Option *input, *npoints, *power, *output, *dfield, *col; } parm; struct { struct Flag *noindex; } flag; struct cell_list { int row, column; struct cell_list *next; }; struct cell_list **search_list = NULL, **search_list_start = NULL; int max_radius, radius; int searchallpoints = 0; char *tmpstr1, *tmpstr2; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("surface")); G_add_keyword(_("interpolation")); G_add_keyword(_("IDW")); module->description = _("Provides surface interpolation from vector point data by Inverse " "Distance Squared Weighting."); parm.input = G_define_standard_option(G_OPT_V_INPUT); parm.dfield = G_define_standard_option(G_OPT_V_FIELD); parm.col = G_define_standard_option(G_OPT_DB_COLUMN); parm.col->required = NO; parm.col->label = _("Name of attribute column with values to interpolate"); parm.col->description = _("If not given and input is 2D vector map then category values are used. " "If input is 3D vector map then z-coordinates are used."); parm.col->guisection = _("Values"); parm.output = G_define_standard_option(G_OPT_R_OUTPUT); parm.npoints = G_define_option(); parm.npoints->key = "npoints"; parm.npoints->key_desc = "count"; parm.npoints->type = TYPE_INTEGER; parm.npoints->required = NO; parm.npoints->description = _("Number of interpolation points"); parm.npoints->answer = "12"; parm.npoints->guisection = _("Settings"); parm.power = G_define_option(); parm.power->key = "power"; parm.power->type = TYPE_DOUBLE; parm.power->answer = "2.0"; parm.power->label = _("Power parameter"); parm.power->description = _("Greater values assign greater influence to closer points"); parm.power->guisection = _("Settings"); flag.noindex = G_define_flag(); flag.noindex->key = 'n'; flag.noindex->label = _("Don't index points by raster cell"); flag.noindex->description = _("Slower but uses" " less memory and includes points from outside region" " in the interpolation"); flag.noindex->guisection = _("Settings"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (sscanf(parm.npoints->answer, "%d", &search_points) != 1 || search_points < 1) G_fatal_error(_("Illegal number (%s) of interpolation points"), parm.npoints->answer); list = (struct list_Point *) G_calloc((size_t) search_points, sizeof(struct list_Point)); p = atof(parm.power->answer); /* get the window, dimension arrays */ G_get_window(&window); if (!flag.noindex->answer) { npoints_currcell = (long **)G_malloc(window.rows * sizeof(long *)); points = (struct Point ***)G_malloc(window.rows * sizeof(struct Point **)); for (row = 0; row < window.rows; row++) { npoints_currcell[row] = (long *)G_malloc(window.cols * sizeof(long)); points[row] = (struct Point **)G_malloc(window.cols * sizeof(struct Point *)); for (col = 0; col < window.cols; col++) { npoints_currcell[row][col] = 0; points[row][col] = NULL; } } } /* read the elevation points from the input sites file */ read_sites(parm.input->answer, parm.dfield->answer, parm.col->answer, flag.noindex->answer); if (npoints == 0) G_fatal_error(_("No points found")); nsearch = npoints < search_points ? npoints : search_points; if (!flag.noindex->answer) { /* Arbitrary point to switch between searching algorithms. Could do * with refinement PK */ if ((window.rows * window.cols) / npoints > 400) { /* Using old algorithm.... */ searchallpoints = 1; ncells = 0; /* Make an array to contain the row and column indices that have * sites in them; later will just search through all these. */ for (searchrow = 0; searchrow < window.rows; searchrow++) for (searchcolumn = 0; searchcolumn < window.cols; searchcolumn++) if (npoints_currcell[searchrow][searchcolumn] > 0) { shortlistrows = (int *)G_realloc(shortlistrows, (1 + ncells) * sizeof(int)); shortlistcolumns = (int *)G_realloc(shortlistcolumns, (1 + ncells) * sizeof(int)); shortlistrows[ncells] = searchrow; shortlistcolumns[ncells] = searchcolumn; ncells++; } } else { /* Fill look-up table of row and column offsets for * doing a circular region growing search looking for sites */ /* Use units of column width */ max_radius = (int)(0.5 + sqrt(window.cols * window.cols + (window.rows * window.ns_res / window.ew_res) * (window.rows * window.ns_res / window.ew_res))); search_list = (struct cell_list **)G_malloc(max_radius * sizeof(struct cell_list *)); search_list_start = (struct cell_list **)G_malloc(max_radius * sizeof(struct cell_list *)); for (radius = 0; radius < max_radius; radius++) search_list[radius] = NULL; for (row = 0; row < window.rows; row++) for (col = 0; col < window.cols; col++) { radius = (int)sqrt(col * col + (row * window.ns_res / window.ew_res) * (row * window.ns_res / window.ew_res)); if (search_list[radius] == NULL) search_list[radius] = search_list_start[radius] = G_malloc(sizeof(struct cell_list)); else search_list[radius] = search_list[radius]->next = G_malloc(sizeof(struct cell_list)); search_list[radius]->row = row; search_list[radius]->column = col; search_list[radius]->next = NULL; } } } /* allocate buffers, etc. */ dcell = Rast_allocate_d_buf(); if ((maskfd = Rast_maskfd()) >= 0) mask = Rast_allocate_c_buf(); else mask = NULL; fd = Rast_open_new(parm.output->answer, DCELL_TYPE); /* GTC Count of window rows */ G_asprintf(&tmpstr1, n_("%d row", "%d rows", window.rows), window.rows); /* GTC Count of window columns */ G_asprintf(&tmpstr2, n_("%d column", "%d columns", window.cols), window.cols); /* GTC First argument is map name, second - message about number of rows, third - columns. */ G_important_message(_("Interpolating raster map <%s> (%s, %s)..."), parm.output->answer, tmpstr1, tmpstr2); G_free(tmpstr1); G_free(tmpstr2); north = window.north + window.ns_res / 2.0; for (row = 0; row < window.rows; row++) { G_percent(row, window.rows, 1); if (mask) Rast_get_c_row(maskfd, mask, row); north -= window.ns_res; east = window.west - window.ew_res / 2.0; for (col = 0; col < window.cols; col++) { east += window.ew_res; /* don't interpolate outside of the mask */ if (mask && mask[col] == 0) { Rast_set_d_null_value(&dcell[col], 1); continue; } /* If current cell contains more than nsearch points just average * all the points in this cell and don't look in any others */ if (!(flag.noindex->answer) && npoints_currcell[row][col] >= nsearch) { sum1 = 0.0; for (i = 0; i < npoints_currcell[row][col]; i++) sum1 += points[row][col][i].z; interp_value = sum1 / npoints_currcell[row][col]; } else { if (flag.noindex->answer) calculate_distances_noindex(north, east); else { pointsfound = 0; i = 0; if (searchallpoints == 1) { /* If there aren't many sites just check them all to find * the nearest */ for (n = 0; n < ncells; n++) calculate_distances(shortlistrows[n], shortlistcolumns[n], north, east, &pointsfound); } else { radius = 0; while (pointsfound < nsearch) { /* Keep widening the search window until we find * enough points */ search_list[radius] = search_list_start[radius]; while (search_list[radius] != NULL) { /* Always */ if (row < (window.rows - search_list[radius]->row) && col < (window.cols - search_list[radius]->column)) { searchrow = row + search_list[radius]->row; searchcolumn = col + search_list[radius]->column; calculate_distances(searchrow, searchcolumn, north, east, &pointsfound); } /* Only if at least one offset is not 0 */ if ((search_list[radius]->row > 0 || search_list[radius]->column > 0) && row >= search_list[radius]->row && col >= search_list[radius]->column) { searchrow = row - search_list[radius]->row; searchcolumn = col - search_list[radius]->column; calculate_distances(searchrow, searchcolumn, north, east, &pointsfound); } /* Only if both offsets are not 0 */ if (search_list[radius]->row > 0 && search_list[radius]->column > 0) { if (row < (window.rows - search_list[radius]->row) && col >= search_list[radius]->column) { searchrow = row + search_list[radius]->row; searchcolumn = col - search_list[radius]->column; calculate_distances(searchrow, searchcolumn, north, east, &pointsfound); } if (row >= search_list[radius]->row && col < (window.cols - search_list[radius]->column)) { searchrow = row - search_list[radius]->row; searchcolumn = col + search_list[radius]->column; calculate_distances(searchrow, searchcolumn, north, east, &pointsfound); } } search_list[radius] = search_list[radius]->next; } radius++; } } } /* interpolate */ sum1 = 0.0; sum2 = 0.0; for (n = 0; n < nsearch; n++) { if ((dist = sqrt(list[n].dist))) { sum1 += list[n].z / pow(dist, p); sum2 += 1.0 / pow(dist, p); } else { /* If one site is dead on the centre of the cell, ignore * all the other sites and just use this value. * (Unlikely when using floating point numbers?) */ sum1 = list[n].z; sum2 = 1.0; break; } } interp_value = sum1 / sum2; } dcell[col] = (DCELL) interp_value; } Rast_put_d_row(fd, dcell); } G_percent(1, 1, 1); Rast_close(fd); /* writing history file */ Rast_short_history(parm.output->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(parm.output->answer, &history); G_done_msg(" "); exit(EXIT_SUCCESS); }