예제 #1
0
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);
    }
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
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;
}
예제 #5
0
파일: Gs3.c 프로젝트: caomw/grass
/*!
   \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);
}
예제 #6
0
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);
    }
}
예제 #7
0
/* 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;
}
예제 #8
0
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(&params, 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(&params, 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(&params);
    /* 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(&params, 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(&params, 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);
}
예제 #9
0
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;
}
예제 #10
0
파일: user3.c 프로젝트: GRASS-GIS/grass-ci
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;

}
예제 #11
0
/* 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;
}
예제 #12
0
/* 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;
}
예제 #13
0
파일: main.cpp 프로젝트: rkrug/grass-ci
/* 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);
}
예제 #14
0
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);
}
예제 #15
0
파일: main.c 프로젝트: wkgreat/CodeInUbuntu
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);
}
예제 #16
0
파일: lines.c 프로젝트: GRASS-GIS/grass-ci
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;
}
예제 #17
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;
}