void p_cubic_f(struct cache *ibuffer, /* input buffer */ void *obufptr, /* ptr in output buffer */ int cell_type, /* raster map type of obufptr */ double *col_idx, /* column index */ double *row_idx, /* row index */ struct Cell_head *cellhd /* cell header of input layer */ ) { /* start nearest neighbor to do some basic tests */ int row, col; /* row/col of nearest neighbor */ FCELL *cellp, cell; /* cut indices to integer */ row = (int)floor(*row_idx); col = (int)floor(*col_idx); /* check for out of bounds - if out of bounds set NULL value */ if (row < 0 || row >= cellhd->rows || col < 0 || col >= cellhd->cols) { Rast_set_null_value(obufptr, 1, cell_type); return; } cellp = CPTR(ibuffer, row, col); /* if nearest is null, all the other interps will be null */ if (Rast_is_f_null_value(cellp)) { Rast_set_null_value(obufptr, 1, cell_type); return; } cell = *cellp; p_cubic(ibuffer, obufptr, cell_type, col_idx, row_idx, cellhd); /* fallback to bilinear if cubic is null */ if (Rast_is_f_null_value(obufptr)) { p_bilinear(ibuffer, obufptr, cell_type, col_idx, row_idx, cellhd); /* fallback to nearest if bilinear is null */ if (Rast_is_f_null_value(obufptr)) Rast_set_f_value(obufptr, cell, cell_type); } }
static int input_data(struct interp_params *params, int first_row, int last_row, struct fcell_triple *points, int fdsmooth, int fdinp, int inp_rows, int inp_cols, double zmin, double inp_ns_res, double inp_ew_res) { double x, y, sm; /* input data and smoothing */ int m1, m2; /* loop counters */ static FCELL *cellinp = NULL; /* cell buffer for input data */ static FCELL *cellsmooth = NULL; /* cell buffer for smoothing */ if (!cellinp) cellinp = Rast_allocate_f_buf(); if (!cellsmooth) cellsmooth = Rast_allocate_f_buf(); for (m1 = 0; m1 <= last_row - first_row; m1++) { Rast_get_f_row(fdinp, cellinp, inp_rows - m1 - first_row); if (fdsmooth >= 0) Rast_get_f_row(fdsmooth, cellsmooth, inp_rows - m1 - first_row); y = params->y_orig + (m1 + first_row - 1 + 0.5) * inp_ns_res; for (m2 = 0; m2 < inp_cols; m2++) { x = params->x_orig + (m2 + 0.5) * inp_ew_res; /* * z = cellinp[m2]*params->zmult; */ if (fdsmooth >= 0) sm = (double)cellsmooth[m2]; else sm = 0.01; points[m1 * inp_cols + m2].x = x - params->x_orig; points[m1 * inp_cols + m2].y = y - params->y_orig; if (!Rast_is_f_null_value(cellinp + m2)) { points[m1 * inp_cols + m2].z = cellinp[m2] * params->zmult - zmin; } else { Rast_set_f_null_value(&(points[m1 * inp_cols + m2].z), 1); } /* fprintf (stdout,"sm: %f\n",sm); */ points[m1 * inp_cols + m2].smooth = sm; } } return 1; }
static void convert_and_write_fi(int fd, const void *vbuf) { const FCELL *buf = vbuf; struct fileinfo *fcb = &R__.fileinfo[fd]; CELL *p = (CELL *) fcb->data; int i; for (i = 0; i < fcb->cellhd.cols; i++) if (Rast_is_f_null_value(&buf[i])) Rast_set_c_null_value(&p[i], 1); else p[i] = (CELL) buf[i]; Rast_put_c_row(fd, p); }
int is_null_value(struct RASTER_MAP_PTR buf, int col) { switch (buf.type) { case CELL_TYPE: return Rast_is_c_null_value(&buf.data.c[col]); break; case FCELL_TYPE: return Rast_is_f_null_value(&buf.data.f[col]); break; case DCELL_TYPE: return Rast_is_d_null_value(&buf.data.d[col]); break; } return -1; }
/*! \brief Load raster map as floating point map Calling function must have already allocated space in buff for wind->rows * wind->cols floats. This routine simply loads the map into a 2d array by repetitve calls to get_f_raster_row. \param wind current window \param map_name raster map name \param[out] buff data buffer \param[out] nullmap null map buffer \param[out] has_null indicates if raster map contains null-data \return 1 on success \return 0 on failure */ int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name, float *buff, struct BM *nullmap, int *has_null) { FILEDESC cellfile; const char *map_set; int offset, row, col; G_debug(3, "Gs_loadmap_as_float(): name=%s", map_name); map_set = G_find_raster2(map_name, ""); if (!map_set) { G_warning(_("Raster map <%s> not found"), map_name); return 0; } *has_null = 0; cellfile = Rast_open_old(map_name, map_set); G_message(_("Loading raster map <%s>..."), G_fully_qualified_name(map_name, map_set)); for (row = 0; row < wind->rows; row++) { offset = row * wind->cols; Rast_get_f_row(cellfile, &(buff[offset]), row); G_percent(row, wind->rows, 2); for (col = 0; col < wind->cols; col++) { if (Rast_is_f_null_value(buff + offset + col)) { *has_null = 1; BM_set(nullmap, col, row, 1); } /* set nm */ } } G_percent(1, 1, 1); G_debug(4, " has_null=%d", *has_null); Rast_close(cellfile); return (1); }
static void convert_float(XDR * xdrs, char *null_buf, const FCELL * rast, int row, int n) { int i; for (i = 0; i < n; i++) { FCELL f; /* substitute embeded null vals by 0's */ if (Rast_is_f_null_value(&rast[i])) { f = 0.; null_buf[i] = 1; } else f = rast[i]; if (!xdr_float(xdrs, &f)) G_fatal_error(_("xdr_float failed for index %d of row %d"), i, row); } }
/* 0 on out of region or NULL, 1 on success */ int rast_segment_get_value_xy(SEGMENT * base_segment, struct Cell_head *input_region, RASTER_MAP_TYPE rtype, double x, double y, double *value) { /* Rast gives double, Segment needs off_t */ off_t base_row = Rast_northing_to_row(y, input_region); off_t base_col = Rast_easting_to_col(x, input_region); /* skip points which are outside the base raster * (null propagation) */ if (base_row < 0 || base_col < 0 || base_row >= input_region->rows || base_col >= input_region->cols) return 0; if (rtype == DCELL_TYPE) { DCELL tmp; Segment_get(base_segment, &tmp, base_row, base_col); if (Rast_is_d_null_value(&tmp)) return 0; *value = (double)tmp; } else if (rtype == FCELL_TYPE) { FCELL tmp; Segment_get(base_segment, &tmp, base_row, base_col); if (Rast_is_f_null_value(&tmp)) return 0; *value = (double)tmp; } else { CELL tmp; Segment_get(base_segment, &tmp, base_row, base_col); if (Rast_is_c_null_value(&tmp)) return 0; *value = (double)tmp; } return 1; }
int main(int argc, char *argv[]) { int m1; struct FPRange range; DCELL cellmin, cellmax; FCELL *cellrow, fcellmin; struct GModule *module; struct { struct Option *input, *elev, *slope, *aspect, *pcurv, *tcurv, *mcurv, *smooth, *maskmap, *zmult, *fi, *segmax, *npmin, *res_ew, *res_ns, *overlap, *theta, *scalex; } parm; struct { struct Flag *deriv, *cprght; } flag; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("resample")); module->description = _("Reinterpolates and optionally computes topographic analysis from " "input raster map to a new raster map (possibly with " "different resolution) using regularized spline with " "tension and smoothing."); parm.input = G_define_standard_option(G_OPT_R_INPUT); parm.res_ew = G_define_option(); parm.res_ew->key = "ew_res"; parm.res_ew->type = TYPE_DOUBLE; parm.res_ew->required = YES; parm.res_ew->description = _("Desired east-west resolution"); parm.res_ns = G_define_option(); parm.res_ns->key = "ns_res"; parm.res_ns->type = TYPE_DOUBLE; parm.res_ns->required = YES; parm.res_ns->description = _("Desired north-south resolution"); parm.elev = G_define_option(); parm.elev->key = "elev"; parm.elev->type = TYPE_STRING; parm.elev->required = NO; parm.elev->gisprompt = "new,cell,raster"; parm.elev->description = _("Output z-file (elevation) map"); parm.elev->guisection = _("Output"); parm.slope = G_define_option(); parm.slope->key = "slope"; parm.slope->type = TYPE_STRING; parm.slope->required = NO; parm.slope->gisprompt = "new,cell,raster"; parm.slope->description = _("Output slope map (or fx)"); parm.slope->guisection = _("Output"); parm.aspect = G_define_option(); parm.aspect->key = "aspect"; parm.aspect->type = TYPE_STRING; parm.aspect->required = NO; parm.aspect->gisprompt = "new,cell,raster"; parm.aspect->description = _("Output aspect map (or fy)"); parm.aspect->guisection = _("Output"); parm.pcurv = G_define_option(); parm.pcurv->key = "pcurv"; parm.pcurv->type = TYPE_STRING; parm.pcurv->required = NO; parm.pcurv->gisprompt = "new,cell,raster"; parm.pcurv->description = _("Output profile curvature map (or fxx)"); parm.pcurv->guisection = _("Output"); parm.tcurv = G_define_option(); parm.tcurv->key = "tcurv"; parm.tcurv->type = TYPE_STRING; parm.tcurv->required = NO; parm.tcurv->gisprompt = "new,cell,raster"; parm.tcurv->description = _("Output tangential curvature map (or fyy)"); parm.tcurv->guisection = _("Output"); parm.mcurv = G_define_option(); parm.mcurv->key = "mcurv"; parm.mcurv->type = TYPE_STRING; parm.mcurv->required = NO; parm.mcurv->gisprompt = "new,cell,raster"; parm.mcurv->description = _("Output mean curvature map (or fxy)"); parm.mcurv->guisection = _("Output"); parm.smooth = G_define_option(); parm.smooth->key = "smooth"; parm.smooth->type = TYPE_STRING; parm.smooth->required = NO; parm.smooth->gisprompt = "old,cell,raster"; parm.smooth->description = _("Name of raster map containing smoothing"); parm.smooth->guisection = _("Settings"); parm.maskmap = G_define_option(); parm.maskmap->key = "maskmap"; parm.maskmap->type = TYPE_STRING; parm.maskmap->required = NO; parm.maskmap->gisprompt = "old,cell,raster"; parm.maskmap->description = _("Name of raster map to be used as mask"); parm.maskmap->guisection = _("Settings"); parm.overlap = G_define_option(); parm.overlap->key = "overlap"; parm.overlap->type = TYPE_INTEGER; parm.overlap->required = NO; parm.overlap->answer = OVERLAP; parm.overlap->description = _("Rows/columns overlap for segmentation"); parm.overlap->guisection = _("Settings"); parm.zmult = G_define_option(); parm.zmult->key = "zmult"; parm.zmult->type = TYPE_DOUBLE; parm.zmult->answer = ZMULT; parm.zmult->required = NO; parm.zmult->description = _("Multiplier for z-values"); parm.zmult->guisection = _("Settings"); parm.fi = G_define_option(); parm.fi->key = "tension"; parm.fi->type = TYPE_DOUBLE; parm.fi->answer = TENSION; parm.fi->required = NO; parm.fi->description = _("Spline tension value"); parm.fi->guisection = _("Settings"); parm.theta = G_define_option(); parm.theta->key = "theta"; parm.theta->type = TYPE_DOUBLE; parm.theta->required = NO; parm.theta->description = _("Anisotropy angle (in degrees)"); parm.theta->guisection = _("Anisotropy"); parm.scalex = G_define_option(); parm.scalex->key = "scalex"; parm.scalex->type = TYPE_DOUBLE; parm.scalex->required = NO; parm.scalex->description = _("Anisotropy scaling factor"); parm.scalex->guisection = _("Anisotropy"); flag.cprght = G_define_flag(); flag.cprght->key = 't'; flag.cprght->description = _("Use dnorm independent tension"); flag.deriv = G_define_flag(); flag.deriv->key = 'd'; flag.deriv->description = _("Output partial derivatives instead of topographic parameters"); flag.deriv->guisection = _("Output"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_get_set_window(&winhd); inp_ew_res = winhd.ew_res; inp_ns_res = winhd.ns_res; inp_cols = winhd.cols; inp_rows = winhd.rows; inp_x_orig = winhd.west; inp_y_orig = winhd.south; input = parm.input->answer; smooth = parm.smooth->answer; maskmap = parm.maskmap->answer; elev = parm.elev->answer; slope = parm.slope->answer; aspect = parm.aspect->answer; pcurv = parm.pcurv->answer; tcurv = parm.tcurv->answer; mcurv = parm.mcurv->answer; cond2 = ((pcurv != NULL) || (tcurv != NULL) || (mcurv != NULL)); cond1 = ((slope != NULL) || (aspect != NULL) || cond2); deriv = flag.deriv->answer; dtens = flag.cprght->answer; ertre = 0.1; if (!G_scan_resolution(parm.res_ew->answer, &ew_res, winhd.proj)) G_fatal_error(_("Unable to read ew_res value")); if (!G_scan_resolution(parm.res_ns->answer, &ns_res, winhd.proj)) G_fatal_error(_("Unable to read ns_res value")); if (sscanf(parm.fi->answer, "%lf", &fi) != 1) G_fatal_error(_("Invalid value for tension")); if (sscanf(parm.zmult->answer, "%lf", &zmult) != 1) G_fatal_error(_("Invalid value for zmult")); if (sscanf(parm.overlap->answer, "%d", &overlap) != 1) G_fatal_error(_("Invalid value for overlap")); if (parm.theta->answer) { if (sscanf(parm.theta->answer, "%lf", &theta) != 1) G_fatal_error(_("Invalid value for theta")); } if (parm.scalex->answer) { if (sscanf(parm.scalex->answer, "%lf", &scalex) != 1) G_fatal_error(_("Invalid value for scalex")); if (!parm.theta->answer) G_fatal_error(_("When using anisotropy both theta and scalex must be specified")); } /* * G_set_embedded_null_value_mode(1); */ outhd.ew_res = ew_res; outhd.ns_res = ns_res; outhd.east = winhd.east; outhd.west = winhd.west; outhd.north = winhd.north; outhd.south = winhd.south; outhd.proj = winhd.proj; outhd.zone = winhd.zone; G_adjust_Cell_head(&outhd, 0, 0); ew_res = outhd.ew_res; ns_res = outhd.ns_res; nsizc = outhd.cols; nsizr = outhd.rows; disk = nsizc * nsizr * sizeof(int); az = G_alloc_vector(nsizc + 1); if (cond1) { adx = G_alloc_vector(nsizc + 1); ady = G_alloc_vector(nsizc + 1); if (cond2) { adxx = G_alloc_vector(nsizc + 1); adyy = G_alloc_vector(nsizc + 1); adxy = G_alloc_vector(nsizc + 1); } } if (smooth != NULL) { fdsmooth = Rast_open_old(smooth, ""); Rast_get_cellhd(smooth, "", &smhd); if ((winhd.ew_res != smhd.ew_res) || (winhd.ns_res != smhd.ns_res)) G_fatal_error(_("Map <%s> is the wrong resolution"), smooth); if (Rast_read_fp_range(smooth, "", &range) >= 0) Rast_get_fp_range_min_max(&range, &cellmin, &cellmax); fcellmin = (float)cellmin; if (Rast_is_f_null_value(&fcellmin) || fcellmin < 0.0) G_fatal_error(_("Smoothing values can not be negative or NULL")); } Rast_get_cellhd(input, "", &inphd); if ((winhd.ew_res != inphd.ew_res) || (winhd.ns_res != inphd.ns_res)) G_fatal_error(_("Input map resolution differs from current region resolution!")); fdinp = Rast_open_old(input, ""); sdisk = 0; if (elev != NULL) sdisk += disk; if (slope != NULL) sdisk += disk; if (aspect != NULL) sdisk += disk; if (pcurv != NULL) sdisk += disk; if (tcurv != NULL) sdisk += disk; if (mcurv != NULL) sdisk += disk; G_message(_("Processing all selected output files will require")); if (sdisk > 1024) { if (sdisk > 1024 * 1024) { if (sdisk > 1024 * 1024 * 1024) { G_message(_("%.2f GB of disk space for temp files."), sdisk / (1024. * 1024. * 1024.)); } else G_message(_("%.2f MB of disk space for temp files."), sdisk / (1024. * 1024.)); } else G_message(_("%.2f KB of disk space for temp files."), sdisk / 1024.); } else G_message(_("%d bytes of disk space for temp files."), sdisk); fstar2 = fi * fi / 4.; tfsta2 = fstar2 + fstar2; deltx = winhd.east - winhd.west; delty = winhd.north - winhd.south; xmin = winhd.west; xmax = winhd.east; ymin = winhd.south; ymax = winhd.north; if (smooth != NULL) smc = -9999; else smc = 0.01; if (Rast_read_fp_range(input, "", &range) >= 0) { Rast_get_fp_range_min_max(&range, &cellmin, &cellmax); } else { cellrow = Rast_allocate_f_buf(); for (m1 = 0; m1 < inp_rows; m1++) { Rast_get_f_row(fdinp, cellrow, m1); Rast_row_update_fp_range(cellrow, m1, &range, FCELL_TYPE); } Rast_get_fp_range_min_max(&range, &cellmin, &cellmax); } fcellmin = (float)cellmin; if (Rast_is_f_null_value(&fcellmin)) G_fatal_error(_("Maximum value of a raster map is NULL.")); zmin = (double)cellmin *zmult; zmax = (double)cellmax *zmult; G_debug(1, "zmin=%f, zmax=%f", zmin, zmax); if (fd4 != NULL) fprintf(fd4, "deltx,delty %f %f \n", deltx, delty); create_temp_files(); IL_init_params_2d(¶ms, NULL, 1, 1, zmult, KMIN, KMAX, maskmap, outhd.rows, outhd.cols, az, adx, ady, adxx, adyy, adxy, fi, MAXPOINTS, SCIK1, SCIK2, SCIK3, smc, elev, slope, aspect, pcurv, tcurv, mcurv, dmin, inp_x_orig, inp_y_orig, deriv, theta, scalex, Tmp_fd_z, Tmp_fd_dx, Tmp_fd_dy, Tmp_fd_xx, Tmp_fd_yy, Tmp_fd_xy, NULL, NULL, 0, NULL); /* In the above line, the penultimate argument is supposed to be a * deviations file pointer. None is obvious, so I used NULL. */ /* The 3rd and 4th argument are int-s, elatt and smatt (from the function * definition. The value 1 seemed like a good placeholder... or not. */ IL_init_func_2d(¶ms, IL_grid_calc_2d, IL_matrix_create, IL_check_at_points_2d, IL_secpar_loop_2d, IL_crst, IL_crstg, IL_write_temp_2d); G_message(_("Temporarily changing the region to desired resolution ...")); Rast_set_window(&outhd); bitmask = IL_create_bitmask(¶ms); /* change region to initial region */ G_message(_("Changing back to the original region ...")); Rast_set_window(&winhd); ertot = 0.; cursegm = 0; G_message(_("Percent complete: ")); NPOINT = IL_resample_interp_segments_2d(¶ms, bitmask, zmin, zmax, &zminac, &zmaxac, &gmin, &gmax, &c1min, &c1max, &c2min, &c2max, &ertot, nsizc, &dnorm, overlap, inp_rows, inp_cols, fdsmooth, fdinp, ns_res, ew_res, inp_ns_res, inp_ew_res, dtens); G_message(_("dnorm in mainc after grid before out1= %f"), dnorm); if (NPOINT < 0) { clean(); G_fatal_error(_("split_and_interpolate() failed")); } if (fd4 != NULL) fprintf(fd4, "max. error found = %f \n", ertot); G_free_vector(az); if (cond1) { G_free_vector(adx); G_free_vector(ady); if (cond2) { G_free_vector(adxx); G_free_vector(adyy); G_free_vector(adxy); } } G_message(_("dnorm in mainc after grid before out2= %f"), dnorm); if (IL_resample_output_2d(¶ms, zmin, zmax, zminac, zmaxac, c1min, c1max, c2min, c2max, gmin, gmax, ertot, input, &dnorm, &outhd, &winhd, smooth, NPOINT) < 0) { clean(); G_fatal_error(_("Unable to write raster maps -- try increasing cell size")); } G_free(zero_array_cell); clean(); if (fd4) fclose(fd4); Rast_close(fdinp); if (smooth != NULL) Rast_close(fdsmooth); G_done_msg(" "); exit(EXIT_SUCCESS); }
int calculateF(int fd, struct area_entry *ad, double *result) { FCELL *buf, *buf_sup, *buf_null; FCELL corrCell, precCell, supCell; long npatch, area; long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp; struct pst *pst; long nalloc, incr; int i, j, k; int connected; int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked; struct Cell_head hd; Rast_get_window(&hd); buf_null = Rast_allocate_f_buf(); Rast_set_f_null_value(buf_null, Rast_window_cols()); buf_sup = buf_null; /* initialize patch ids */ pid_corr = G_malloc(Rast_window_cols() * sizeof(long)); pid_sup = G_malloc(Rast_window_cols() * sizeof(long)); for (j = 0; j < Rast_window_cols(); j++) { pid_corr[j] = 0; pid_sup[j] = 0; } /* open mask if needed */ mask_fd = -1; mask_buf = mask_sup = NULL; masked = FALSE; if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return RLI_ERRORE; mask_buf = G_malloc(ad->cl * sizeof(int)); if (mask_buf == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } mask_sup = G_malloc(ad->cl * sizeof(int)); if (mask_sup == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } for (j = 0; j < ad->cl; j++) mask_buf[j] = 0; masked = TRUE; } /* calculate number of patches */ npatch = 0; area = 0; pid = 0; /* patch size and type */ incr = 1024; if (incr > ad->rl) incr = ad->rl; if (incr > ad->cl) incr = ad->cl; if (incr < 2) incr = 2; nalloc = incr; pst = G_malloc(nalloc * sizeof(struct pst)); for (k = 0; k < nalloc; k++) { pst[k].count = 0; } for (i = 0; i < ad->rl; i++) { buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad); if (i > 0) { buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad); } if (masked) { mask_tmp = mask_sup; mask_sup = mask_buf; mask_buf = mask_tmp; if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) return 0; } ltmp = pid_sup; pid_sup = pid_corr; pid_corr = ltmp; Rast_set_f_null_value(&precCell, 1); connected = 0; for (j = 0; j < ad->cl; j++) { pid_corr[j + ad->x] = 0; corrCell = buf[j + ad->x]; if (masked && (mask_buf[j] == 0)) { Rast_set_f_null_value(&corrCell, 1); } if (Rast_is_f_null_value(&corrCell)) { connected = 0; precCell = corrCell; continue; } area++; supCell = buf_sup[j + ad->x]; if (masked && (mask_sup[j] == 0)) { Rast_set_f_null_value(&supCell, 1); } if (!Rast_is_f_null_value(&precCell) && corrCell == precCell) { pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x]; connected = 1; pst[pid_corr[j + ad->x]].count++; } else { connected = 0; } if (!Rast_is_f_null_value(&supCell) && corrCell == supCell) { if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) { /* connect or merge */ /* after r.clump */ if (connected) { npatch--; if (npatch == 0) { G_fatal_error("npatch == 0 at row %d, col %d", i, j); } } old_pid = pid_corr[j + ad->x]; new_pid = pid_sup[j + ad->x]; pid_corr[j + ad->x] = new_pid; if (old_pid > 0) { /* merge */ /* update left side of the current row */ for (k = 0; k < j; k++) { if (pid_corr[k + ad->x] == old_pid) pid_corr[k + ad->x] = new_pid; } /* update right side of the previous row */ for (k = j + 1; k < ad->cl; k++) { if (pid_sup[k + ad->x] == old_pid) pid_sup[k + ad->x] = new_pid; } pst[new_pid].count += pst[old_pid].count; pst[old_pid].count = 0; if (old_pid == pid) pid--; } else { pst[new_pid].count++; } } connected = 1; } if (!connected) { /* start new patch */ npatch++; pid++; pid_corr[j + ad->x] = pid; if (pid >= nalloc) { pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst)); for (k = nalloc; k < pid + incr; k++) pst[k].count = 0; nalloc = pid + incr; } pst[pid].count = 1; pst[pid].type.t = CELL_TYPE; pst[pid].type.val.c = corrCell; } precCell = corrCell; } } if (npatch > 0) { double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; double area_p; double cell_size_m; double min, max; /* calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows); /* get min and max patch size */ min = 1.0 / 0.0; /* inf */ max = -1.0 / 0.0; /* -inf */ for (old_pid = 1; old_pid <= pid; old_pid++) { if (pst[old_pid].count > 0) { area_p = cell_size_m * pst[old_pid].count / 10000; if (min > area_p) min = area_p; if (max < area_p) max = area_p; } } *result = max - min; } else Rast_set_d_null_value(result, 1); if (masked) { close(mask_fd); G_free(mask_buf); G_free(mask_sup); } G_free(buf_null); G_free(pid_corr); G_free(pid_sup); G_free(pst); return RLI_OK; }
int COGRR1(double x_or, double y_or, double z_or, int n_rows, int n_cols, int n_levs, int n_points, struct quadruple *points, struct point_3d skip_point) /*C C INTERPOLATION BY FUNCTIONAL METHOD : TPS + complete regul. c */ { int secpar_loop(); static double *w2 = NULL; static double *wz2 = NULL; static double *wz1 = NULL; double amaxa; double stepix, stepiy, stepiz, RO, xx, yy, zz, xg, yg, zg, xx2; double wm, dx, dy, dz, dxx, dyy, dxy, dxz, dyz, dzz, h, bmgd1, bmgd2, etar, zcon, r, ww, wz, r2, hcell, zzcell2, etarcell, rcell, wwcell, zzcell; double x_crs,x_crsd,x_crsdd,x_crsdr2; int n1, k1, k2, k, i1, l, l1, n4, n5, m, i; int NGST, LSIZE, ngstc, nszc, ngstr, nszr, ngstl, nszl; int POINT(); int ind, ind1; static int first_time_z = 1; off_t offset, offset1, offset2; int bmask = 1; static FCELL *cell = NULL; int cond1 = (gradient != NULL) || (aspect1 != NULL) || (aspect2 != NULL); int cond2 = (ncurv != NULL) || (gcurv != NULL) || (mcurv != NULL); #define CEULER .57721566 /* C c character*32 fncdsm c normalization c */ offset1 = nsizr * nsizc; stepix = ew_res / dnorm; stepiy = ns_res / dnorm; stepiz = tb_res / dnorm; if (!w2) { if (!(w2 = (double *)G_malloc(sizeof(double) * (KMAX2 + 1)))) { clean(); G_fatal_error(_("Not enough memory for %s"), "w2"); } } if (!wz2) { if (!(wz2 = (double *)G_malloc(sizeof(double) * (KMAX2 + 1)))) { clean(); G_fatal_error(_("Not enough memory for %s"), "wz2"); } } if (!wz1) { if (!(wz1 = (double *)G_malloc(sizeof(double) * (KMAX2 + 1)))) { clean(); G_fatal_error(_("Not enough memory for %s"), "wz1"); } } if (cell == NULL) cell = Rast_allocate_f_buf(); for (i = 1; i <= n_points; i++) { points[i - 1].x = (points[i - 1].x - x_or) / dnorm; points[i - 1].y = (points[i - 1].y - y_or) / dnorm; points[i - 1].z = (points[i - 1].z - z_or) / dnorm; } if (cv) { skip_point.x = (skip_point.x - x_or) / dnorm; skip_point.y = (skip_point.y - y_or) / dnorm; skip_point.z = (skip_point.z - z_or) / dnorm; } n1 = n_points + 1; /* C C GENERATION OF MATRIX C C FIRST COLUMN C */ A[1] = 0.; for (k = 1; k <= n_points; k++) { i1 = k + 1; A[i1] = 1.; } /* C C OTHER COLUMNS C */ RO = rsm; for (k = 1; k <= n_points; k++) { k1 = k * n1 + 1; k2 = k + 1; i1 = k1 + k; if (rsm < 0.) { /*indicates variable smoothing */ A[i1] = points[k - 1].sm; } else { A[i1] = RO; /* constant smoothing */ } for (l = k2; l <= n_points; l++) { xx = points[k - 1].x - points[l - 1].x; yy = points[k - 1].y - points[l - 1].y; zz = points[k - 1].z - points[l - 1].z; r = sqrt(xx * xx + yy * yy + zz * zz); etar = (fi * r) / 2.; if (etar == 0.) { /* printf ("ident. points in segm. \n"); printf ("x[%d]=%lf,x[%d]=%lf,y[%d]=%lf,y[%d]=%lf\n", k - 1, points[k - 1].x, l - 1, points[l - 1].x, k - 1, points[k - 1].y, l - 1, points[l - 1].y); */ } i1 = k1 + l; A[i1] = crs(etar); } } /* C C SYMMETRISATION C */ amaxa = 1.; for (k = 1; k <= n1; k++) { k1 = (k - 1) * n1; k2 = k + 1; for (l = k2; l <= n1; l++) { m = (l - 1) * n1 + k; A[m] = A[k1 + l]; amaxa = amax1(A[m], amaxa); } } /* C RIGHT SIDE C */ n4 = n1 * n1 + 1; A[n4] = 0.; for (l = 1; l <= n_points; l++) { l1 = n4 + l; A[l1] = points[l - 1].w; } n5 = n1 * (n1 + 1); for (i = 1; i <= n5; i++) A[i] = A[i] / amaxa; /* SOLVING OF SYSTEM */ if (LINEQS(n1, n1, 1, &NERROR, &DETERM)) { for (k = 1; k <= n_points; k++) { l = n4 + k; b[k] = A[l]; } b[n_points + 1] = A[n4]; POINT(n_points, points, skip_point); if (cv) return 1; if (devi != NULL && sig1 == 1) return 1; /* C C INTERPOLATION * MOST INNER LOOPS ! C */ NGST = 1; LSIZE = 0; ngstc = (int)(x_or / ew_res + 0.5) + 1; nszc = ngstc + n_cols - 1; ngstr = (int)(y_or / ns_res + 0.5) + 1; nszr = ngstr + n_rows - 1; ngstl = (int)(z_or / tb_res + 0.5) + 1; nszl = ngstl + n_levs - 1; /* fprintf(stderr," Progress percentage for each segment ..." ); */ /*fprintf(stderr,"Before loops,ngstl = %d,nszl =%d\n",ngstl,nszl); */ for (i = ngstl; i <= nszl; i++) { /*fprintf(stderr,"level=%d\n",i); */ /* G_percent(i, nszl, 2); */ offset = offset1 * (i - 1); /* levels offset */ zg = (i - ngstl) * stepiz; for (m = 1; m <= n_points; m++) { wz = zg - points[m - 1].z; wz1[m] = wz; wz2[m] = wz * wz; } for (k = ngstr; k <= nszr; k++) { yg = (k - ngstr) * stepiy; for (m = 1; m <= n_points; m++) { wm = yg - points[m - 1].y; w[m] = wm; w2[m] = wm * wm; } if ((cellinp != NULL) && (cellout != NULL) && (i == ngstl)) Rast_get_f_row(fdcell, cell, n_rows_in - k); for (l = ngstc; l <= nszc; l++) { LSIZE = LSIZE + 1; if (maskmap != NULL) bmask = BM_get(bitmask, l - 1, k - 1); /*bug fix 02/03/00 jh */ xg = (l - ngstc) * stepix; ww = 0.; wwcell = 0.; dx = 0.; dy = 0.; dz = 0.; dxx = 0.; dxy = 0.; dxz = 0.; dyy = 0.; dyz = 0.; dzz = 0.; /* compute everything for area which is not masked out and where cross_input map doesn't have nulls */ if (bmask == 1 && !(cell && Rast_is_f_null_value(&cell[l - 1]))) { h = b[n1]; hcell = b[n1]; for (m = 1; m <= n_points; m++) { xx = xg - points[m - 1].x; xx2 = xx * xx; if ((cellinp != NULL) && (cellout != NULL) && (i == ngstl)) { zcon = (double)(cell[l - 1] * zmult - z_or) - z_orig_in * zmult; /* bug fix 02/03/00 jh */ zcon = zcon / dnorm; zzcell = zcon - points[m - 1].z; zzcell2 = zzcell * zzcell; rcell = sqrt(xx2 + w2[m] + zzcell2); etarcell = (fi * rcell) / 2.; hcell = hcell + b[m] * crs(etarcell); } r2 = xx2 + w2[m] + wz2[m]; r = sqrt(r2); etar = (fi * r) / 2.; crs_full( etar,fi, &x_crs, cond1?&x_crsd:NULL, cond2?&x_crsdr2:NULL, cond2?&x_crsdd:NULL ); h = h + b[m] * x_crs; if(cond1) { bmgd1 = b[m] * x_crsd; dx = dx + bmgd1 * xx; dy = dy + bmgd1 * w[m]; dz = dz + bmgd1 * wz1[m]; } if(cond2) { bmgd2 = b[m] * x_crsdd; bmgd1 = b[m] * x_crsdr2; dyy = dyy + bmgd2 * w2[m] + bmgd1 * w2[m]; dzz = dzz + bmgd2 * wz2[m] + bmgd1 * wz2[m]; dxy = dxy + bmgd2 * xx * w[m] + bmgd1 * xx * w[m]; dxz = dxz + bmgd2 * xx * wz1[m] + bmgd1 * xx * wz1[m]; dyz = dyz + bmgd2 * w[m] * wz1[m] + bmgd1 * w[m] * wz1[m]; } } ww = h + wmin; if ((cellinp != NULL) && (cellout != NULL) && (i == ngstl)) wwcell = hcell + wmin; az[l] = ww; if (first_time_z) { first_time_z = 0; zmaxac = zminac = ww; if ((cellinp != NULL) && (cellout != NULL) && (i == ngstl)) zmaxacell = zminacell = wwcell; } zmaxac = amax1(ww, zmaxac); zminac = amin1(ww, zminac); if ((cellinp != NULL) && (cellout != NULL) && (i == ngstl)) { zmaxacell = amax1(wwcell, zmaxacell); zminacell = amin1(wwcell, zminacell); } if ((ww > wmax + 0.1 * (wmax - wmin)) || (ww < wmin - 0.1 * (wmax - wmin))) { static int once = 0; if (!once) { once = 1; fprintf(stderr, "WARNING:\n"); fprintf(stderr, "Overshoot -- increase in tension suggested.\n"); fprintf(stderr, "Overshoot occurs at (%d,%d,%d) cell\n", l, k, i); fprintf(stderr, "The w-value is %lf, wmin is %lf,wmax is %lf\n", ww, wmin, wmax); } } } /* skip here if you are in masked area, ww should be 0 */ az[l] = ww; adx[l] = dx; ady[l] = dy; adz[l] = dz; /* printf("\n %f", ww); */ adxx[l] = dxx; adxy[l] = dxy; adxz[l] = dxz; adyy[l] = dyy; adyz[l] = dyz; adzz[l] = dzz; if ((gradient != NULL) || (aspect1 != NULL) || (aspect2 != NULL) || (ncurv != NULL) || (gcurv != NULL) || (mcurv != NULL)) if (!(secpar_loop(ngstc, nszc, l))) { clean(); G_fatal_error(_("Secpar_loop failed")); } if ((cellinp != NULL) && (cellout != NULL) && (i == ngstl)) { zero_array_cell[l - 1] = (FCELL) (wwcell); } if (outz != NULL) { zero_array1[l - 1] = (float)(az[l] * sciz); } if (gradient != NULL) { zero_array2[l - 1] = (float)(adx[l]); } if (aspect1 != NULL) { zero_array3[l - 1] = (float)(ady[l]); } if (aspect2 != NULL) { zero_array4[l - 1] = (float)(adz[l]); } if (ncurv != NULL) { zero_array5[l - 1] = (float)(adxx[l]); } if (gcurv != NULL) { zero_array6[l - 1] = (float)(adyy[l]); } if (mcurv != NULL) { zero_array7[l - 1] = (float)(adxy[l]); } } /* columns */ ind = nsizc * (k - 1) + (ngstc - 1); ind1 = ngstc - 1; offset2 = offset + ind; /* rows*cols offset */ if ((cellinp != NULL) && (cellout != NULL) && (i == ngstl)) { G_fseek(Tmp_fd_cell, ((off_t)ind * sizeof(FCELL)), 0); if (! (fwrite (zero_array_cell + ind1, sizeof(FCELL), nszc - ngstc + 1, Tmp_fd_cell))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } if (outz != NULL) { G_fseek(Tmp_fd_z, (off_t)(offset2 * sizeof(float)), 0); if (! (fwrite (zero_array1 + ind1, sizeof(float), nszc - ngstc + 1, Tmp_fd_z))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } if (gradient != NULL) { G_fseek(Tmp_fd_dx, (off_t)(offset2 * sizeof(float)), 0); if (! (fwrite (zero_array2 + ind1, sizeof(float), nszc - ngstc + 1, Tmp_fd_dx))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } if (aspect1 != NULL) { G_fseek(Tmp_fd_dy, (off_t)(offset2 * sizeof(float)), 0); if (! (fwrite (zero_array3 + ind1, sizeof(float), nszc - ngstc + 1, Tmp_fd_dy))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } if (aspect2 != NULL) { G_fseek(Tmp_fd_dz, (off_t)(offset2 * sizeof(float)), 0); if (! (fwrite (zero_array4 + ind1, sizeof(float), nszc - ngstc + 1, Tmp_fd_dz))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } if (ncurv != NULL) { G_fseek(Tmp_fd_xx, (off_t)(offset2 * sizeof(float)), 0); if (! (fwrite (zero_array5 + ind1, sizeof(float), nszc - ngstc + 1, Tmp_fd_xx))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } if (gcurv != NULL) { G_fseek(Tmp_fd_yy, (off_t)(offset2 * sizeof(float)), 0); if (! (fwrite (zero_array6 + ind1, sizeof(float), nszc - ngstc + 1, Tmp_fd_yy))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } if (mcurv != NULL) { G_fseek(Tmp_fd_xy, (off_t)(offset2 * sizeof(float)), 0); if (! (fwrite (zero_array7 + ind1, sizeof(float), nszc - ngstc + 1, Tmp_fd_xy))) { clean(); G_fatal_error (_("Not enough disk space--cannot write files")); } } } } } /* falls here if LINEQS() returns 0 */ /* total++; */ /*fprintf(stderr,"wminac=%lf,wmaxac=%lf\n",zminac,zmaxac); */ return 1; }
/* exact check for each band * returns 0 on success * -1 if given nodata value was present in data * -2 if selected GDAL datatype could not hold all values * */ int exact_checks(GDALDataType export_datatype, const char *name, const char *mapset, struct Cell_head *cellhead, RASTER_MAP_TYPE maptype, double nodataval, const char *nodatakey, int default_nodataval) { double dfCellMin; double dfCellMax; int fd; int cols = cellhead->cols; int rows = cellhead->rows; int ret = 0; /* Open GRASS raster */ fd = Rast_open_old(name, mapset); /* Create GRASS raster buffer */ void *bufer = Rast_allocate_buf(maptype); if (bufer == NULL) { G_warning(_("Unable to allocate buffer for reading raster map")); return -1; } /* the following routine must be kept identical to export_band */ /* Copy data form GRASS raster to GDAL raster */ int row, col; int n_nulls = 0, nodatavalmatch = 0; dfCellMin = TYPE_FLOAT64_MAX; dfCellMax = TYPE_FLOAT64_MIN; /* Better use selected GDAL datatype instead of * the best match with GRASS raster map types ? */ if (maptype == FCELL_TYPE) { FCELL fnullval = (FCELL) nodataval; G_debug(1, "FCELL nodata val: %f", fnullval); for (row = 0; row < rows; row++) { Rast_get_row(fd, bufer, row, maptype); for (col = 0; col < cols; col++) { if (Rast_is_f_null_value(&((FCELL *) bufer)[col])) { n_nulls++; } else { if (((FCELL *) bufer)[col] == fnullval) { nodatavalmatch = 1; } if (dfCellMin > ((FCELL *) bufer)[col]) dfCellMin = ((FCELL *) bufer)[col]; if (dfCellMax < ((FCELL *) bufer)[col]) dfCellMax = ((FCELL *) bufer)[col]; } } G_percent(row + 1, rows, 2); } } else if (maptype == DCELL_TYPE) { DCELL dnullval = (DCELL) nodataval; G_debug(1, "DCELL nodata val: %f", dnullval); for (row = 0; row < rows; row++) { Rast_get_row(fd, bufer, row, maptype); for (col = 0; col < cols; col++) { if (Rast_is_d_null_value(&((DCELL *) bufer)[col])) { ((DCELL *) bufer)[col] = dnullval; n_nulls++; } else { if (((DCELL *) bufer)[col] == dnullval) { nodatavalmatch = 1; } if (dfCellMin > ((DCELL *) bufer)[col]) dfCellMin = ((DCELL *) bufer)[col]; if (dfCellMax < ((DCELL *) bufer)[col]) dfCellMax = ((DCELL *) bufer)[col]; } } G_percent(row + 1, rows, 2); } } else { CELL inullval = (CELL) nodataval; G_debug(1, "CELL nodata val: %d", inullval); for (row = 0; row < rows; row++) { Rast_get_row(fd, bufer, row, maptype); for (col = 0; col < cols; col++) { if (Rast_is_c_null_value(&((CELL *) bufer)[col])) { ((CELL *) bufer)[col] = inullval; n_nulls++; } else { if (((CELL *) bufer)[col] == inullval) { nodatavalmatch = 1; } if (dfCellMin > ((CELL *) bufer)[col]) dfCellMin = ((CELL *) bufer)[col]; if (dfCellMax < ((CELL *) bufer)[col]) dfCellMax = ((CELL *) bufer)[col]; } } G_percent(row + 1, rows, 2); } } G_debug(1, "min %g max %g", dfCellMin, dfCellMax); /* can the GDAL datatype hold the data range to be exported ? */ /* f-flag does not override */ if (exact_range_check(dfCellMin, dfCellMax, export_datatype, name)) { G_warning("Raster export results in data loss."); ret = -2; } G_message(_("Using GDAL data type <%s>"), GDALGetDataTypeName(export_datatype)); /* a default nodata value was used and NULL cells were present */ if (n_nulls && default_nodataval) { if (maptype == CELL_TYPE) G_important_message(_("Input raster map contains cells with NULL-value (no-data). " "The value %d will be used to represent no-data values in the input map. " "You can specify a nodata value with the %s option."), (int)nodataval, nodatakey); else G_important_message(_("Input raster map contains cells with NULL-value (no-data). " "The value %g will be used to represent no-data values in the input map. " "You can specify a nodata value with the %s option."), nodataval, nodatakey); } /* the nodata value was present in the exported data */ if (nodatavalmatch && n_nulls) { /* default nodataval didn't work */ if (default_nodataval) { G_warning(_("The default nodata value is present in raster" "band <%s> and would lead to data loss. Please specify a " "custom nodata value with the %s parameter."), name, nodatakey); } /* user-specified nodataval didn't work */ else { G_warning(_("The user given nodata value %g is present in raster" "band <%s> and would lead to data loss. Please specify a " "different nodata value with the %s parameter."), nodataval, name, nodatakey); } ret = -1; } Rast_close(fd); G_free(bufer); return ret; }
/* actual raster band export * returns 0 on success * -1 on raster data read/write error * */ int export_band(GDALDatasetH hMEMDS, int band, const char *name, const char *mapset, struct Cell_head *cellhead, RASTER_MAP_TYPE maptype, double nodataval, int suppress_main_colortable) { struct Colors sGrassColors; GDALColorTableH hCT; int iColor; int bHaveMinMax; double dfCellMin; double dfCellMax; struct FPRange sRange; int fd; int cols = cellhead->cols; int rows = cellhead->rows; int ret = 0; char value[200]; /* Open GRASS raster */ fd = Rast_open_old(name, mapset); /* Get raster band */ GDALRasterBandH hBand = GDALGetRasterBand(hMEMDS, band); if (hBand == NULL) { G_warning(_("Unable to get raster band")); return -1; } /* Get min/max values. */ if (Rast_read_fp_range(name, mapset, &sRange) == -1) { bHaveMinMax = FALSE; } else { bHaveMinMax = TRUE; Rast_get_fp_range_min_max(&sRange, &dfCellMin, &dfCellMax); } sprintf(value, "GRASS GIS %s", GRASS_VERSION_NUMBER); GDALSetMetadataItem(hBand, "Generated_with", value, NULL); /* use default color rules if no color rules are given */ if (Rast_read_colors(name, mapset, &sGrassColors) >= 0) { int maxcolor, i; CELL min, max; char key[200]; int rcount; Rast_get_c_color_range(&min, &max, &sGrassColors); if (bHaveMinMax) { if (max < dfCellMax) { maxcolor = max; } else { maxcolor = (int)ceil(dfCellMax); } if (maxcolor > GRASS_MAX_COLORS) { maxcolor = GRASS_MAX_COLORS; G_warning("Too many values, color table cut to %d entries", maxcolor); } } else { if (max < GRASS_MAX_COLORS) { maxcolor = max; } else { maxcolor = GRASS_MAX_COLORS; G_warning("Too many values, color table set to %d entries", maxcolor); } } rcount = Rast_colors_count(&sGrassColors); G_debug(3, "dfCellMin: %f, dfCellMax: %f, maxcolor: %d", dfCellMin, dfCellMax, maxcolor); if (!suppress_main_colortable) { hCT = GDALCreateColorTable(GPI_RGB); for (iColor = 0; iColor <= maxcolor; iColor++) { int nRed, nGreen, nBlue; GDALColorEntry sColor; if (Rast_get_c_color(&iColor, &nRed, &nGreen, &nBlue, &sGrassColors)) { sColor.c1 = nRed; sColor.c2 = nGreen; sColor.c3 = nBlue; sColor.c4 = 255; G_debug(3, "Rast_get_c_color: Y, rcount %d, nRed %d, nGreen %d, nBlue %d", rcount, nRed, nGreen, nBlue); GDALSetColorEntry(hCT, iColor, &sColor); } else { sColor.c1 = 0; sColor.c2 = 0; sColor.c3 = 0; sColor.c4 = 0; G_debug(3, "Rast_get_c_color: N, rcount %d, nRed %d, nGreen %d, nBlue %d", rcount, nRed, nGreen, nBlue); GDALSetColorEntry(hCT, iColor, &sColor); } } GDALSetRasterColorTable(hBand, hCT); } if (rcount > 0) { /* Create metadata entries for color table rules */ sprintf(value, "%d", rcount); GDALSetMetadataItem(hBand, "COLOR_TABLE_RULES_COUNT", value, NULL); } /* Add the rules in reverse order */ /* This can cause a GDAL warning with many rules, something like * Warning 1: Lost metadata writing to GeoTIFF ... too large to fit in tag. */ for (i = rcount - 1; i >= 0; i--) { DCELL val1, val2; unsigned char r1, g1, b1, r2, g2, b2; Rast_get_fp_color_rule(&val1, &r1, &g1, &b1, &val2, &r2, &g2, &b2, &sGrassColors, i); sprintf(key, "COLOR_TABLE_RULE_RGB_%d", rcount - i - 1); sprintf(value, "%e %e %d %d %d %d %d %d", val1, val2, r1, g1, b1, r2, g2, b2); GDALSetMetadataItem(hBand, key, value, NULL); } } /* Create GRASS raster buffer */ void *bufer = Rast_allocate_buf(maptype); if (bufer == NULL) { G_warning(_("Unable to allocate buffer for reading raster map")); return -1; } /* the following routine must be kept identical to exact_checks */ /* Copy data form GRASS raster to GDAL raster */ int row, col; int n_nulls = 0; /* Better use selected GDAL datatype instead of * the best match with GRASS raster map types ? */ if (maptype == FCELL_TYPE) { /* Source datatype understandable by GDAL */ GDALDataType datatype = GDT_Float32; FCELL fnullval = (FCELL) nodataval; G_debug(1, "FCELL nodata val: %f", fnullval); for (row = 0; row < rows; row++) { Rast_get_row(fd, bufer, row, maptype); for (col = 0; col < cols; col++) { if (Rast_is_f_null_value(&((FCELL *) bufer)[col])) { ((FCELL *) bufer)[col] = fnullval; if (n_nulls == 0) { GDALSetRasterNoDataValue(hBand, nodataval); } n_nulls++; } } if (GDALRasterIO (hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype, 0, 0) >= CE_Failure) { G_warning(_("Unable to write GDAL raster file")); return -1; } G_percent(row + 1, rows, 2); } } else if (maptype == DCELL_TYPE) { GDALDataType datatype = GDT_Float64; DCELL dnullval = (DCELL) nodataval; G_debug(1, "DCELL nodata val: %f", dnullval); for (row = 0; row < rows; row++) { Rast_get_row(fd, bufer, row, maptype); for (col = 0; col < cols; col++) { if (Rast_is_d_null_value(&((DCELL *) bufer)[col])) { ((DCELL *) bufer)[col] = dnullval; if (n_nulls == 0) { GDALSetRasterNoDataValue(hBand, nodataval); } n_nulls++; } } if (GDALRasterIO (hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype, 0, 0) >= CE_Failure) { G_warning(_("Unable to write GDAL raster file")); return -1; } G_percent(row + 1, rows, 2); } } else { GDALDataType datatype = GDT_Int32; CELL inullval = (CELL) nodataval; G_debug(1, "CELL nodata val: %d", inullval); for (row = 0; row < rows; row++) { Rast_get_row(fd, bufer, row, maptype); for (col = 0; col < cols; col++) { if (Rast_is_c_null_value(&((CELL *) bufer)[col])) { ((CELL *) bufer)[col] = inullval; if (n_nulls == 0) { GDALSetRasterNoDataValue(hBand, nodataval); } n_nulls++; } } if (GDALRasterIO (hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype, 0, 0) >= CE_Failure) { G_warning(_("Unable to write GDAL raster file")); return -1; } G_percent(row + 1, rows, 2); } } Rast_close(fd); G_free(bufer); return ret; }
/* Process the raster and do atmospheric corrections. Params: * INPUT FILE ifd: input file descriptor iref: input file has radiance values (default is reflectance) ? iscale: input file's range (default is min = 0, max = 255) ialt_fd: height map file descriptor, negative if global value is used ivis_fd: visibility map file descriptor, negative if global value is used * OUTPUT FILE ofd: output file descriptor oflt: if true use FCELL_TYPE for output oscale: output file's range (default is min = 0, max = 255) */ static void process_raster(int ifd, InputMask imask, ScaleRange iscale, int ialt_fd, int ivis_fd, int ofd, bool oint, ScaleRange oscale) { FCELL *buf; /* buffer for the input values */ FCELL *alt = NULL; /* buffer for the elevation values */ FCELL *vis = NULL; /* buffer for the visibility values */ FCELL prev_alt = -1.f; FCELL prev_vis = -1.f; int row, col, nrows, ncols; /* switch on optimization automatically if elevation and/or visibility map is given */ bool optimize = (ialt_fd >= 0 || ivis_fd >= 0); #ifdef _NO_OPTIMIZE_ optimize = false; #endif /* do initial computation with global elevation and visibility values */ TransformInput ti; ti = compute(); /* use a cache to increase computation speed when an elevation map * and/or a visibility map is given */ TICache ticache; /* allocate memory for buffers */ buf = (FCELL *) Rast_allocate_buf(FCELL_TYPE); if (ialt_fd >= 0) alt = (FCELL *) Rast_allocate_buf(FCELL_TYPE); if (ivis_fd >= 0) vis = (FCELL *) Rast_allocate_buf(FCELL_TYPE); nrows = Rast_window_rows(); ncols = Rast_window_cols(); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 1); /* keep the user informed of our progress */ /* read the next row */ Rast_get_row(ifd, buf, row, FCELL_TYPE); /* read the next row of elevation values */ if (ialt_fd >= 0) Rast_get_row(ialt_fd, alt, row, FCELL_TYPE); /* read the next row of elevation values */ if (ivis_fd >= 0) Rast_get_row(ivis_fd, vis, row, FCELL_TYPE); /* loop over all the values in the row */ for (col = 0; col < ncols; col++) { if ((vis && Rast_is_f_null_value(&vis[col])) || (alt && Rast_is_f_null_value(&alt[col])) || Rast_is_f_null_value(&buf[col])) { Rast_set_f_null_value(&buf[col], 1); continue; } if (ialt_fd >= 0) { if (alt[col] < 0) alt[col] = 0; /* on or below sea level, all the same for 6S */ else alt[col] /= 1000.0f; /* converting to km from input which should be in meter */ /* round to nearest altitude bin */ /* rounding result: watch out for fp representation error */ alt[col] = ((int) (alt[col] * BIN_ALT + 0.5)) / BIN_ALT; } if (ivis_fd >= 0) { if (vis[col] < 0) vis[col] = 0; /* negative visibility is invalid, print a WARNING ? */ /* round to nearest visibility bin */ /* rounding result: watch out for fp representation error */ vis[col] = ((int) (vis[col] + 0.5)); } /* check if both maps are active and if whether any value has changed */ if ((ialt_fd >= 0) && (ivis_fd >= 0) && ((prev_vis != vis[col]) || (prev_alt != alt[col]))) { prev_alt = alt[col]; /* update new values */ prev_vis = vis[col]; if (optimize) { int in_cache = ticache.search(alt[col], vis[col], &ti); if (!in_cache) { pre_compute_hv(alt[col], vis[col]); /* re-compute transformation inputs */ ti = compute(); /* ... */ ticache.add(ti, alt[col], vis[col]); } } else { pre_compute_hv(alt[col], vis[col]); /* re-compute transformation inputs */ ti = compute(); /* ... */ } } else { /* only one of the maps is being used */ if ((ivis_fd >= 0) && (prev_vis != vis[col])) { prev_vis = vis[col]; /* keep track of previous visibility */ if (optimize) { int in_cache = ticache.search(0, vis[col], &ti); if (!in_cache) { pre_compute_v(vis[col]); /* re-compute transformation inputs */ ti = compute(); /* ... */ ticache.add(ti, 0, vis[col]); } } else { pre_compute_v(vis[col]); /* re-compute transformation inputs */ ti = compute(); /* ... */ } } if ((ialt_fd >= 0) && (prev_alt != alt[col])) { prev_alt = alt[col]; /* keep track of previous altitude */ if (optimize) { int in_cache = ticache.search(alt[col], 0, &ti); if (!in_cache) { pre_compute_h(alt[col]); /* re-compute transformation inputs */ ti = compute(); /* ... */ ticache.add(ti, alt[col], 0); } } else { pre_compute_h(alt[col]); /* re-compute transformation inputs */ ti = compute(); /* ... */ } } } G_debug(3, "Computed r%d (%d), c%d (%d)", row, nrows, col, ncols); /* transform from iscale.[min,max] to [0,1] */ buf[col] = (buf[col] - iscale.min) / ((float)iscale.max - (float)iscale.min); buf[col] = transform(ti, imask, buf[col]); /* transform from [0,1] to oscale.[min,max] */ buf[col] = buf[col] * ((float)oscale.max - (float)oscale.min) + oscale.min; if (oint && (buf[col] > (float)oscale.max)) G_warning(_("The output data will overflow. Reflectance > 100%%")); } /* write output */ if (oint) write_fp_to_cell(ofd, buf); else Rast_put_row(ofd, buf, FCELL_TYPE); } G_percent(1, 1, 1); /* free allocated memory */ G_free(buf); if (ialt_fd >= 0) G_free(alt); if (ivis_fd >= 0) G_free(vis); }
int extract_points(int z_flag) { struct line_pnts *points = Vect_new_line_struct(); CELL *cellbuf; FCELL *fcellbuf; DCELL *dcellbuf; int row, col; double x, y; int count; switch (data_type) { case CELL_TYPE: cellbuf = Rast_allocate_c_buf(); break; case FCELL_TYPE: fcellbuf = Rast_allocate_f_buf(); break; case DCELL_TYPE: dcellbuf = Rast_allocate_d_buf(); break; } G_message(_("Extracting points...")); count = 1; for (row = 0; row < cell_head.rows; row++) { G_percent(row, n_rows, 2); y = Rast_row_to_northing((double)(row + .5), &cell_head); switch (data_type) { case CELL_TYPE: Rast_get_c_row(input_fd, cellbuf, row); break; case FCELL_TYPE: Rast_get_f_row(input_fd, fcellbuf, row); break; case DCELL_TYPE: Rast_get_d_row(input_fd, dcellbuf, row); break; } for (col = 0; col < cell_head.cols; col++) { int cat, val; double dval; x = Rast_col_to_easting((double)(col + .5), &cell_head); switch (data_type) { case CELL_TYPE: if (Rast_is_c_null_value(cellbuf + col)) continue; val = cellbuf[col]; dval = val; break; case FCELL_TYPE: if (Rast_is_f_null_value(fcellbuf + col)) continue; dval = fcellbuf[col]; break; case DCELL_TYPE: if (Rast_is_d_null_value(dcellbuf + col)) continue; dval = dcellbuf[col]; break; } /* value_flag is used only for CELL type */ cat = (value_flag) ? val : count; Vect_reset_line(points); Vect_reset_cats(Cats); Vect_cat_set(Cats, 1, cat); Vect_append_point(points, x, y, dval); Vect_write_line(&Map, GV_POINT, points, Cats); if ((driver != NULL) && !value_flag) { insert_value(cat, val, dval); } count++; } } G_percent(row, n_rows, 2); switch (data_type) { case CELL_TYPE: G_free(cellbuf); break; case FCELL_TYPE: G_free(fcellbuf); break; case DCELL_TYPE: G_free(dcellbuf); break; } Vect_destroy_line_struct(points); return (1); }
int main(int argc, char **argv) { IO rasters[] = { /* rasters stores output buffers */ {"dem",YES,"Input dem","input",UNKNOWN,-1,NULL}, /* WARNING: this one map is input */ {"forms",NO,"Most common geomorphic forms","patterns",CELL_TYPE,-1,NULL}, {"ternary",NO,"code of ternary patterns","patterns",CELL_TYPE,-1,NULL}, {"positive",NO,"code of binary positive patterns","patterns",CELL_TYPE,-1,NULL}, {"negative",NO,"code of binary negative patterns","patterns",CELL_TYPE,-1,NULL}, {"intensity",NO,"rasters containing mean relative elevation of the form","geometry",FCELL_TYPE,-1,NULL}, {"exposition",NO,"rasters containing maximum difference between extend and central cell","geometry",FCELL_TYPE,-1,NULL}, {"range",NO,"rasters containing difference between max and min elevation of the form extend","geometry",FCELL_TYPE,-1,NULL}, {"variance",NO,"rasters containing variance of form boundary","geometry",FCELL_TYPE,-1,NULL}, {"elongation",NO,"rasters containing local elongation","geometry",FCELL_TYPE,-1,NULL}, {"azimuth",NO,"rasters containing local azimuth of the elongation","geometry",FCELL_TYPE,-1,NULL}, {"extend",NO,"rasters containing local extend (area) of the form","geometry",FCELL_TYPE,-1,NULL}, {"width",NO,"rasters containing local width of the form","geometry",FCELL_TYPE,-1,NULL} }; /* adding more maps change IOSIZE macro */ CATCOLORS ccolors[CNT]={ /* colors and cats for forms */ {ZERO, 0, 0, 0, "forms"}, {FL, 220, 220, 220, "flat"}, {PK, 56, 0, 0, "summit"}, {RI, 200, 0, 0, "ridge"}, {SH, 255, 80, 20, "shoulder"}, {CV, 250, 210, 60, "spur"}, {SL, 255, 255, 60, "slope"}, {CN, 180, 230, 20, "hollow"}, {FS, 60, 250, 150, "footslope"}, {VL, 0, 0, 255, "valley"}, {PT, 0, 0, 56, "depression"}, {__, 255, 0, 255, "ERROR"}}; struct GModule *module; struct Option *opt_input, *opt_output[io_size], *par_search_radius, *par_skip_radius, *par_flat_treshold, *par_flat_distance; struct Flag *flag_units, *flag_extended; struct History history; int i,j, n; int meters=0, multires=0, extended=0; /* flags */ int row,cur_row,col,radius; int pattern_size; double max_resolution; char prefix[20]; G_gisinit(argv[0]); { /* interface parameters */ module = G_define_module(); module->description = _("Calculate geomorphons (terrain forms)and associated geometry using machine vision approach"); G_add_keyword("Geomorphons"); G_add_keyword("Terrain patterns"); G_add_keyword("Machine vision geomorphometry"); opt_input = G_define_standard_option(G_OPT_R_INPUT); opt_input->key = rasters[0].name; opt_input->required = rasters[0].required; opt_input->description = _(rasters[0].description); for (i=1;i<io_size;++i) { /* WARNING: loop starts from one, zero is for input */ opt_output[i] = G_define_standard_option(G_OPT_R_OUTPUT); opt_output[i]->key = rasters[i].name; opt_output[i]->required = NO; opt_output[i]->description = _(rasters[i].description); opt_output[i]->guisection = _(rasters[i].gui); } par_search_radius = G_define_option(); par_search_radius->key = "search"; par_search_radius->type = TYPE_INTEGER; par_search_radius->answer = "3"; par_search_radius->required = YES; par_search_radius->description = _("Outer search radius"); par_skip_radius = G_define_option(); par_skip_radius->key = "skip"; par_skip_radius->type = TYPE_INTEGER; par_skip_radius->answer = "0"; par_skip_radius->required = YES; par_skip_radius->description = _("Inner search radius"); par_flat_treshold = G_define_option(); par_flat_treshold->key = "flat"; par_flat_treshold->type = TYPE_DOUBLE; par_flat_treshold->answer = "1"; par_flat_treshold->required = YES; par_flat_treshold->description = _("Flatenss treshold (degrees)"); par_flat_distance = G_define_option(); par_flat_distance->key = "dist"; par_flat_distance->type = TYPE_DOUBLE; par_flat_distance->answer = "0"; par_flat_distance->required = YES; par_flat_distance->description = _("Flatenss distance, zero for none"); flag_units = G_define_flag(); flag_units->key = 'm'; flag_units->description = _("Use meters to define search units (default is cells)"); flag_extended = G_define_flag(); flag_extended->key = 'e'; flag_extended->description = _("Use extended form correction"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); } { /* calculate parameters */ int num_outputs=0; double search_radius, skip_radius, start_radius, step_radius; double ns_resolution; for (i=1;i<io_size;++i) /* check for outputs */ if(opt_output[i]->answer) { if (G_legal_filename(opt_output[i]->answer) < 0) G_fatal_error(_("<%s> is an illegal file name"), opt_output[i]->answer); num_outputs++; } if(!num_outputs && !multires) G_fatal_error(_("At least one output is required")); meters=(flag_units->answer != 0); extended=(flag_extended->answer != 0); nrows = Rast_window_rows(); ncols = Rast_window_cols(); Rast_get_window(&window); G_begin_distance_calculations(); if(G_projection()==PROJECTION_LL) { /* for LL max_res should be NS */ ns_resolution=G_distance(0,Rast_row_to_northing(0, &window),0,Rast_row_to_northing(1, &window)); max_resolution=ns_resolution; } else { max_resolution=MAX(window.ns_res,window.ew_res); /* max_resolution MORE meters per cell */ } G_message("NSRES, %f", ns_resolution); cell_res=max_resolution; /* this parameter is global */ /* search distance */ search_radius=atof(par_search_radius->answer); search_cells=meters?(int)(search_radius/max_resolution):search_radius; if(search_cells<1) G_fatal_error(_("Search radius size must cover at least 1 cell")); row_radius_size=meters?ceil(search_radius/max_resolution):search_radius; row_buffer_size=row_radius_size*2+1; search_distance=(meters)?search_radius:max_resolution*search_cells; /* skip distance */ skip_radius=atof(par_skip_radius->answer); skip_cells=meters?(int)(skip_radius/max_resolution):skip_radius; if(skip_cells>=search_cells) G_fatal_error(_("Skip radius size must be at least 1 cell lower than radius")); skip_distance=(meters)?skip_radius:ns_resolution*skip_cells; /* flatness parameters */ flat_threshold=atof(par_flat_treshold->answer); if(flat_threshold<=0.) G_fatal_error(_("Flatenss treshold must be grater than 0")); flat_threshold=DEGREE2RAD(flat_threshold); flat_distance=atof(par_flat_distance->answer); flat_distance=(meters)?flat_distance:ns_resolution*flat_distance; flat_threshold_height=tan(flat_threshold)*flat_distance; if((flat_distance>0&&flat_distance<=skip_distance)||flat_distance>=search_distance) { G_warning(_("Flatenss distance should be between skip and search radius. Otherwise ignored")); flat_distance=0; } if (search_distance<10*cell_res) extended=0; /* print information about distances */ G_message("Search distance m: %f, cells: %d", search_distance, search_cells); G_message("Skip distance m: %f, cells: %d", skip_distance, skip_cells); G_message("Flat threshold distance m: %f, height: %f",flat_distance, flat_threshold_height); G_message("%s version",(extended)?"extended":"basic"); } /* generate global ternary codes */ for(i=0;i<6561;++i) global_ternary_codes[i]=ternary_rotate(i); /* open DEM */ strcpy(elevation.elevname,opt_input->answer); open_map(&elevation); PATTERN* pattern; PATTERN patterns[4]; void* pointer_buf; int formA, formB, formC; double search_dist=search_distance; double skip_dist=skip_distance; double flat_dist=flat_distance; double area_of_octagon=4*(search_distance*search_distance)*sin(DEGREE2RAD(45.)); cell_step=1; /* prepare outputs */ for (i=1;i<io_size;++i) if(opt_output[i]->answer) { rasters[i].fd=Rast_open_new(opt_output[i]->answer,rasters[i].out_data_type); rasters[i].buffer=Rast_allocate_buf(rasters[i].out_data_type); } /* main loop */ for(row=0;row<nrows;++row) { G_percent(row, nrows, 2); cur_row = (row < row_radius_size)?row: ((row >= nrows-row_radius_size-1) ? row_buffer_size - (nrows-row-1) : row_radius_size); if(row>(row_radius_size) && row<nrows-(row_radius_size+1)) shift_buffers(row); for (col=0;col<ncols;++col) { /* on borders forms ussualy are innatural. */ if(row<(skip_cells+1) || row>nrows-(skip_cells+2) || col<(skip_cells+1) || col>ncols-(skip_cells+2) || Rast_is_f_null_value(&elevation.elev[cur_row][col])) { /* set outputs to NULL and do nothing if source value is null or border*/ for (i=1;i<io_size;++i) if(opt_output[i]->answer) { pointer_buf=rasters[i].buffer; switch (rasters[i].out_data_type) { case CELL_TYPE: Rast_set_c_null_value(&((CELL*)pointer_buf)[col],1); break; case FCELL_TYPE: Rast_set_f_null_value(&((FCELL*)pointer_buf)[col],1); break; case DCELL_TYPE: Rast_set_d_null_value(&((DCELL*)pointer_buf)[col],1); break; default: G_fatal_error(_("Unknown output data type")); } } continue; } /* end null value */ { int cur_form, small_form; search_distance=search_dist; skip_distance=skip_dist; flat_distance=flat_dist; pattern_size=calc_pattern(&patterns[0],row,cur_row,col); pattern=&patterns[0]; cur_form=determine_form(pattern->num_negatives,pattern->num_positives); /* correction of forms */ if(extended) { /* 1) remove extensive innatural forms: ridges, peaks, shoulders and footslopes */ if((cur_form==4||cur_form==8||cur_form==2||cur_form==3)) { search_distance=(search_dist/4.<4*max_resolution)? 4*max_resolution : search_dist/4.; skip_distance=0; flat_distance=0; pattern_size=calc_pattern(&patterns[1],row,cur_row,col); pattern=&patterns[1]; small_form=determine_form(pattern->num_negatives,pattern->num_positives); if(cur_form==4||cur_form==8) cur_form=(small_form==1)? 1 : cur_form; if(cur_form==2||cur_form==3) cur_form=small_form; } } /* end of correction */ pattern=&patterns[0]; if(opt_output[o_forms]->answer) ((CELL*)rasters[o_forms].buffer)[col]=cur_form; } if(opt_output[o_ternary]->answer) ((CELL*)rasters[o_ternary].buffer)[col]=determine_ternary(pattern->pattern); if(opt_output[o_positive]->answer) ((CELL*)rasters[o_positive].buffer)[col]=pattern->num_positives;//rotate(pattern->positives); if(opt_output[o_negative]->answer) ((CELL*)rasters[o_negative].buffer)[col]=pattern->num_negatives;//rotate(pattern->negatives); if(opt_output[o_intensity]->answer) ((FCELL*)rasters[o_intensity].buffer)[col]=intensity(pattern->elevation,pattern_size); if(opt_output[o_exposition]->answer) ((FCELL*)rasters[o_exposition].buffer)[col]=exposition(pattern->elevation); if(opt_output[o_range]->answer) ((FCELL*)rasters[o_range].buffer)[col]=range(pattern->elevation); if(opt_output[o_variance]->answer) ((FCELL*)rasters[o_variance].buffer)[col]=variance(pattern->elevation, pattern_size); // used only for next four shape functions if(opt_output[o_elongation]->answer ||opt_output[o_azimuth]->answer|| opt_output[o_extend]->answer || opt_output[o_width]->answer) { float azimuth,elongation,width; radial2cartesian(pattern); shape(pattern, pattern_size,&azimuth,&elongation,&width); if(opt_output[o_azimuth]->answer) ((FCELL*)rasters[o_azimuth].buffer)[col]=azimuth; if(opt_output[o_elongation]->answer) ((FCELL*)rasters[o_elongation].buffer)[col]=elongation; if(opt_output[o_width]->answer) ((FCELL*)rasters[o_width].buffer)[col]=width; } if(opt_output[o_extend]->answer) ((FCELL*)rasters[o_extend].buffer)[col]=extends(pattern, pattern_size)/area_of_octagon; } /* end for col */ /* write existing outputs */ for (i=1;i<io_size;++i) if(opt_output[i]->answer) Rast_put_row(rasters[i].fd, rasters[i].buffer, rasters[i].out_data_type); } G_percent(row, nrows, 2); /* end main loop */ /* finish and close */ free_map(elevation.elev, row_buffer_size+1); for (i=1;i<io_size;++i) if(opt_output[i]->answer) { G_free(rasters[i].buffer); Rast_close(rasters[i].fd); Rast_short_history(opt_output[i]->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(opt_output[i]->answer, &history); } if(opt_output[o_forms]->answer) write_form_cat_colors(opt_output[o_forms]->answer,ccolors); if(opt_output[o_intensity]->answer) write_contrast_colors(opt_output[o_intensity]->answer); if(opt_output[o_exposition]->answer) write_contrast_colors(opt_output[o_exposition]->answer); if(opt_output[o_range]->answer) write_contrast_colors(opt_output[o_range]->answer); G_message("Done!"); exit(EXIT_SUCCESS); }
int extract_lines(void) { n_alloced_ptrs = 0; row = -3; read_next(); read_next(); G_message(_("Extracting lines...")); switch (data_type) { case CELL_TYPE: { int rows = 1; while (read_next()) { CELL *m = &((CELL *) middle)[1]; CELL *t = &((CELL *) top)[1]; CELL *b = &((CELL *) bottom)[1]; G_percent(rows, n_rows, 2); for (col = 1; col < n_cols - 1; col++, t++, m++, b++) { m = &((CELL *) middle)[col]; t = &((CELL *) top)[col]; b = &((CELL *) bottom)[col]; if ((mc = !Rast_is_c_null_value(m))) { tl = !Rast_is_c_null_value(t - 1); tc = !Rast_is_c_null_value(t); tr = !Rast_is_c_null_value(t + 1); ml = !Rast_is_c_null_value(m - 1); mr = !Rast_is_c_null_value(m + 1); bl = !Rast_is_c_null_value(b - 1); bc = !Rast_is_c_null_value(b); br = !Rast_is_c_null_value(b + 1); update_list(nabors()); } } rows++; } G_percent(rows, n_rows, 2); break; } case FCELL_TYPE: { int rows = 1; while (read_next()) { FCELL *m = &((FCELL *) middle)[1]; FCELL *t = &((FCELL *) top)[1]; FCELL *b = &((FCELL *) bottom)[1]; G_percent(rows, n_rows, 2); for (col = 1; col < n_cols - 1; col++, t++, m++, b++) { m = &((FCELL *) middle)[col]; t = &((FCELL *) top)[col]; b = &((FCELL *) bottom)[col]; if ((mc = !Rast_is_f_null_value(m))) { tl = !Rast_is_f_null_value(t - 1); tc = !Rast_is_f_null_value(t); tr = !Rast_is_f_null_value(t + 1); ml = !Rast_is_f_null_value(m - 1); mr = !Rast_is_f_null_value(m + 1); bl = !Rast_is_f_null_value(b - 1); bc = !Rast_is_f_null_value(b); br = !Rast_is_f_null_value(b + 1); update_list(nabors()); } } rows++; } G_percent(rows, n_rows, 2); break; } case DCELL_TYPE: { int rows = 1; while (read_next()) { DCELL *m = &((DCELL *) middle)[1]; DCELL *t = &((DCELL *) top)[1]; DCELL *b = &((DCELL *) bottom)[1]; G_percent(rows, n_rows, 2); for (col = 1; col < n_cols - 1; col++, t++, m++, b++) { m = &((DCELL *) middle)[col]; t = &((DCELL *) top)[col]; b = &((DCELL *) bottom)[col]; if ((mc = !Rast_is_d_null_value(m))) { tl = !Rast_is_d_null_value(t - 1); tc = !Rast_is_d_null_value(t); tr = !Rast_is_d_null_value(t + 1); ml = !Rast_is_d_null_value(m - 1); mr = !Rast_is_d_null_value(m + 1); bl = !Rast_is_d_null_value(b - 1); bc = !Rast_is_d_null_value(b); br = !Rast_is_d_null_value(b + 1); update_list(nabors()); } } rows++; } G_percent(rows, n_rows, 2); break; } } G_free(top); G_free(middle); G_free(bottom); G_free(v_list); if (n_alloced_ptrs) { /* should not happen */ G_warning("Memory leak: %d points are still in use", n_alloced_ptrs); } return 0; }
int IL_resample_interp_segments_2d(struct interp_params *params, struct BM *bitmask, /* bitmask */ double zmin, double zmax, /* min and max input z-values */ double *zminac, double *zmaxac, /* min and max interp. z-values */ double *gmin, double *gmax, /* min and max inperp. slope val. */ double *c1min, double *c1max, double *c2min, double *c2max, /* min and max interp. curv. val. */ double *ertot, /* total interplating func. error */ off_t offset1, /* offset for temp file writing */ double *dnorm, int overlap, int inp_rows, int inp_cols, int fdsmooth, int fdinp, double ns_res, double ew_res, double inp_ns_res, double inp_ew_res, int dtens) { int i, j, k, l, m, m1, i1; /* loop coounters */ int cursegm = 0; int new_comp = 0; int n_rows, n_cols, inp_r, inp_c; double x_or, y_or, xm, ym; static int first = 1, new_first = 1; double **matrix = NULL, **new_matrix = NULL, *b = NULL; int *indx = NULL, *new_indx = NULL; static struct fcell_triple *in_points = NULL; /* input points */ int inp_check_rows, inp_check_cols, /* total input rows/cols */ out_check_rows, out_check_cols; /* total output rows/cols */ int first_row, last_row; /* first and last input row of segment */ int first_col, last_col; /* first and last input col of segment */ int num, prev; int div; /* number of divides */ int rem_out_row, rem_out_col; /* output rows/cols remainders */ int inp_seg_r, inp_seg_c, /* # of input rows/cols in segment */ out_seg_r, out_seg_c; /* # of output rows/cols in segment */ int ngstc, nszc /* first and last output col of the * segment */ , ngstr, nszr; /* first and last output row of the * segment */ int index; /* index for input data */ int c, r; int overlap1; int p_size; struct quaddata *data; double xmax, xmin, ymax, ymin; int totsegm; /* total number of segments */ int total_points = 0; struct triple triple; /* contains garbage */ xmin = params->x_orig; ymin = params->y_orig; xmax = xmin + ew_res * params->nsizc; ymax = ymin + ns_res * params->nsizr; prev = inp_rows * inp_cols; if (prev <= params->kmax) div = 1; /* no segmentation */ else { /* find the number of divides */ for (i = 2;; i++) { c = inp_cols / i; r = inp_rows / i; num = c * r; if (num < params->kmin) { if (((params->kmin - num) > (prev + 1 - params->kmax)) && (prev + 1 < params->KMAX2)) { div = i - 1; break; } else { div = i; break; } } if ((num > params->kmin) && (num + 1 < params->kmax)) { div = i; break; } prev = num; } } out_seg_r = params->nsizr / div; /* output rows per segment */ out_seg_c = params->nsizc / div; /* output cols per segment */ inp_seg_r = inp_rows / div; /* input rows per segment */ inp_seg_c = inp_cols / div; /* input rows per segment */ rem_out_col = params->nsizc % div; rem_out_row = params->nsizr % div; overlap1 = min1(overlap, inp_seg_c - 1); overlap1 = min1(overlap1, inp_seg_r - 1); out_check_rows = 0; out_check_cols = 0; inp_check_rows = 0; inp_check_cols = 0; if (div == 1) { p_size = inp_seg_c * inp_seg_r; } else { p_size = (overlap1 * 2 + inp_seg_c) * (overlap1 * 2 + inp_seg_r); } if (!in_points) { if (! (in_points = (struct fcell_triple *)G_malloc(sizeof(struct fcell_triple) * p_size * div))) { fprintf(stderr, "Cannot allocate memory for in_points\n"); return -1; } } *dnorm = sqrt(((xmax - xmin) * (ymax - ymin) * p_size) / (inp_rows * inp_cols)); if (dtens) { params->fi = params->fi * (*dnorm) / 1000.; fprintf(stderr, "dnorm = %f, rescaled tension = %f\n", *dnorm, params->fi); } if (div == 1) { /* no segmentation */ totsegm = 1; cursegm = 1; input_data(params, 1, inp_rows, in_points, fdsmooth, fdinp, inp_rows, inp_cols, zmin, inp_ns_res, inp_ew_res); x_or = 0.; y_or = 0.; xm = params->nsizc * ew_res; ym = params->nsizr * ns_res; data = (struct quaddata *)quad_data_new(x_or, y_or, xm, ym, params->nsizr, params->nsizc, 0, params->KMAX2); m1 = 0; for (k = 1; k <= p_size; k++) { if (!Rast_is_f_null_value(&(in_points[k - 1].z))) { data->points[m1].x = in_points[k - 1].x / (*dnorm); data->points[m1].y = in_points[k - 1].y / (*dnorm); /* data->points[m1].z = (double) (in_points[k - 1].z) / (*dnorm); */ data->points[m1].z = (double)(in_points[k - 1].z); data->points[m1].sm = in_points[k - 1].smooth; m1++; } } data->n_points = m1; total_points = m1; if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) { fprintf(stderr, "Cannot allocate memory for indx\n"); return -1; } if (!(matrix = G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) { fprintf(stderr, "Cannot allocate memory for matrix\n"); return -1; } if (!(b = G_alloc_vector(params->KMAX2 + 2))) { fprintf(stderr, "Cannot allocate memory for b\n"); return -1; } if (params->matrix_create(params, data->points, m1, matrix, indx) < 0) return -1; for (i = 0; i < m1; i++) { b[i + 1] = data->points[i].z; } b[0] = 0.; G_lubksb(matrix, m1 + 1, indx, b); params->check_points(params, data, b, ertot, zmin, *dnorm, triple); if (params->grid_calc(params, data, bitmask, zmin, zmax, zminac, zmaxac, gmin, gmax, c1min, c1max, c2min, c2max, ertot, b, offset1, *dnorm) < 0) { fprintf(stderr, "interpolation failed\n"); return -1; } else { if (totsegm != 0) { G_percent(cursegm, totsegm, 1); } /* * if (b) G_free_vector(b); if (matrix) G_free_matrix(matrix); if * (indx) G_free_ivector(indx); */ fprintf(stderr, "dnorm in ressegm after grid before out= %f \n", *dnorm); return total_points; } } out_seg_r = params->nsizr / div; /* output rows per segment */ out_seg_c = params->nsizc / div; /* output cols per segment */ inp_seg_r = inp_rows / div; /* input rows per segment */ inp_seg_c = inp_cols / div; /* input rows per segment */ rem_out_col = params->nsizc % div; rem_out_row = params->nsizr % div; overlap1 = min1(overlap, inp_seg_c - 1); overlap1 = min1(overlap1, inp_seg_r - 1); out_check_rows = 0; out_check_cols = 0; inp_check_rows = 0; inp_check_cols = 0; totsegm = div * div; /* set up a segment */ for (i = 1; i <= div; i++) { /* input and output rows */ if (i <= div - rem_out_row) n_rows = out_seg_r; else n_rows = out_seg_r + 1; inp_r = inp_seg_r; out_check_cols = 0; inp_check_cols = 0; ngstr = out_check_rows + 1; /* first output row of the segment */ nszr = ngstr + n_rows - 1; /* last output row of the segment */ y_or = (ngstr - 1) * ns_res; /* y origin of the segment */ /* * Calculating input starting and ending rows and columns of this * segment */ first_row = (int)(y_or / inp_ns_res) + 1; if (first_row > overlap1) { first_row -= overlap1; /* middle */ last_row = first_row + inp_seg_r + overlap1 * 2 - 1; if (last_row > inp_rows) { first_row -= (last_row - inp_rows); /* bottom */ last_row = inp_rows; } } else { first_row = 1; /* top */ last_row = first_row + inp_seg_r + overlap1 * 2 - 1; } if ((last_row > inp_rows) || (first_row < 1)) { fprintf(stderr, "Row overlap too large!\n"); return -1; } input_data(params, first_row, last_row, in_points, fdsmooth, fdinp, inp_rows, inp_cols, zmin, inp_ns_res, inp_ew_res); for (j = 1; j <= div; j++) { /* input and output cols */ if (j <= div - rem_out_col) n_cols = out_seg_c; else n_cols = out_seg_c + 1; inp_c = inp_seg_c; ngstc = out_check_cols + 1; /* first output col of the segment */ nszc = ngstc + n_cols - 1; /* last output col of the segment */ x_or = (ngstc - 1) * ew_res; /* x origin of the segment */ first_col = (int)(x_or / inp_ew_res) + 1; if (first_col > overlap1) { first_col -= overlap1; /* middle */ last_col = first_col + inp_seg_c + overlap1 * 2 - 1; if (last_col > inp_cols) { first_col -= (last_col - inp_cols); /* right */ last_col = inp_cols; } } else { first_col = 1; /* left */ last_col = first_col + inp_seg_c + overlap1 * 2 - 1; } if ((last_col > inp_cols) || (first_col < 1)) { fprintf(stderr, "Column overlap too large!\n"); return -1; } m = 0; /* Getting points for interpolation (translated) */ xm = nszc * ew_res; ym = nszr * ns_res; data = (struct quaddata *)quad_data_new(x_or, y_or, xm, ym, nszr - ngstr + 1, nszc - ngstc + 1, 0, params->KMAX2); new_comp = 0; for (k = 0; k <= last_row - first_row; k++) { for (l = first_col - 1; l < last_col; l++) { index = k * inp_cols + l; if (!Rast_is_f_null_value(&(in_points[index].z))) { /* if the point is inside the segment (not overlapping) */ if ((in_points[index].x - x_or >= 0) && (in_points[index].y - y_or >= 0) && ((nszc - 1) * ew_res - in_points[index].x >= 0) && ((nszr - 1) * ns_res - in_points[index].y >= 0)) total_points += 1; data->points[m].x = (in_points[index].x - x_or) / (*dnorm); data->points[m].y = (in_points[index].y - y_or) / (*dnorm); /* data->points[m].z = (double) (in_points[index].z) / (*dnorm); */ data->points[m].z = (double)(in_points[index].z); data->points[m].sm = in_points[index].smooth; m++; } else new_comp = 1; /* fprintf(stderr,"%f,%f,%f zmin=%f\n",in_points[index].x,in_points[index].y,in_points[index].z,zmin); */ } } /* fprintf (stdout,"m,index:%di,%d\n",m,index); */ if (m <= params->KMAX2) data->n_points = m; else data->n_points = params->KMAX2; out_check_cols += n_cols; inp_check_cols += inp_c; cursegm = (i - 1) * div + j - 1; /* show before to catch 0% */ if (totsegm != 0) { G_percent(cursegm, totsegm, 1); } if (m == 0) { /* * fprintf(stderr,"Warning: segment with zero points encountered, * insrease overlap\n"); */ write_zeros(params, data, offset1); } else { if (new_comp) { if (new_first) { new_first = 0; if (!b) { if (!(b = G_alloc_vector(params->KMAX2 + 2))) { fprintf(stderr, "Cannot allocate memory for b\n"); return -1; } } if (!(new_indx = G_alloc_ivector(params->KMAX2 + 1))) { fprintf(stderr, "Cannot allocate memory for new_indx\n"); return -1; } if (! (new_matrix = G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) { fprintf(stderr, "Cannot allocate memory for new_matrix\n"); return -1; } } /*new_first */ if (params-> matrix_create(params, data->points, data->n_points, new_matrix, new_indx) < 0) return -1; for (i1 = 0; i1 < m; i1++) { b[i1 + 1] = data->points[i1].z; } b[0] = 0.; G_lubksb(new_matrix, data->n_points + 1, new_indx, b); params->check_points(params, data, b, ertot, zmin, *dnorm, triple); if (params->grid_calc(params, data, bitmask, zmin, zmax, zminac, zmaxac, gmin, gmax, c1min, c1max, c2min, c2max, ertot, b, offset1, *dnorm) < 0) { fprintf(stderr, "interpolate() failed\n"); return -1; } } /*new_comp */ else { if (first) { first = 0; if (!b) { if (!(b = G_alloc_vector(params->KMAX2 + 2))) { fprintf(stderr, "Cannot allocate memory for b\n"); return -1; } } if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) { fprintf(stderr, "Cannot allocate memory for indx\n"); return -1; } if (! (matrix = G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) { fprintf(stderr, "Cannot allocate memory for matrix\n"); return -1; } } /* first */ if (params-> matrix_create(params, data->points, data->n_points, matrix, indx) < 0) return -1; /* } here it was bug */ for (i1 = 0; i1 < m; i1++) b[i1 + 1] = data->points[i1].z; b[0] = 0.; G_lubksb(matrix, data->n_points + 1, indx, b); params->check_points(params, data, b, ertot, zmin, *dnorm, triple); if (params->grid_calc(params, data, bitmask, zmin, zmax, zminac, zmaxac, gmin, gmax, c1min, c1max, c2min, c2max, ertot, b, offset1, *dnorm) < 0) { fprintf(stderr, "interpolate() failed\n"); return -1; } } } if (data) { G_free(data->points); G_free(data); } /* * cursegm++; */ } inp_check_rows += inp_r; out_check_rows += n_rows; } /* run one last time after the loop is done to catch 100% */ if (totsegm != 0) G_percent(1, 1, 1); /* cursegm doesn't get to totsegm so we force 100% */ /* * if (b) G_free_vector(b); if (indx) G_free_ivector(indx); if (matrix) * G_free_matrix(matrix); */ fprintf(stderr, "dnorm in ressegm after grid before out2= %f \n", *dnorm); return total_points; }