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; }
void process(void) { /*--------------------------------------------------------------------------*/ /* INITIALISE */ /*--------------------------------------------------------------------------*/ DCELL *row_in, /* Buffer large enough to hold `wsize' */ *row_out = NULL, /* raster rows. When GRASS reads in a */ /* raster row, each element is of type */ /* DCELL */ *window_ptr, /* Stores local terrain window. */ centre; /* Elevation of central cell in window. */ CELL *featrow_out = NULL; /* store features in CELL */ struct Cell_head region; /* Structure to hold region information */ int nrows, /* Will store the current number of */ ncols, /* rows and columns in the raster. */ row, col, /* Counts through each row and column */ /* of the input raster. */ wind_row, /* Counts through each row and column */ wind_col, /* of the local neighbourhood window. */ *index_ptr; /* Row permutation vector for LU decomp. */ double **normal_ptr, /* Cross-products matrix. */ *obs_ptr, /* Observed vector. */ temp; /* Unused */ double *weight_ptr; /* Weighting matrix for observed values. */ /*--------------------------------------------------------------------------*/ /* GET RASTER AND WINDOW DETAILS */ /*--------------------------------------------------------------------------*/ G_get_window(®ion); /* Fill out the region structure (the */ /* geographical limits etc.) */ nrows = Rast_window_rows(); /* Find out the number of rows and */ ncols = Rast_window_cols(); /* columns of the raster. */ if ((region.ew_res / region.ns_res >= 1.01) || /* If EW and NS resolns are */ (region.ns_res / region.ew_res >= 1.01)) { /* >1% different, warn user. */ G_warning(_("E-W and N-S grid resolutions are different. Taking average.")); resoln = (region.ns_res + region.ew_res) / 2; } else resoln = region.ns_res; /*--------------------------------------------------------------------------*/ /* RESERVE MEMORY TO HOLD Z VALUES AND MATRICES */ /*--------------------------------------------------------------------------*/ row_in = (DCELL *) G_malloc(ncols * sizeof(DCELL) * wsize); /* Reserve `wsize' rows of memory. */ if (mparam != FEATURE) row_out = Rast_allocate_buf(DCELL_TYPE); /* Initialise output row buffer. */ else featrow_out = Rast_allocate_buf(CELL_TYPE); /* Initialise output row buffer. */ window_ptr = (DCELL *) G_malloc(SQR(wsize) * sizeof(DCELL)); /* Reserve enough memory for local wind. */ weight_ptr = (double *)G_malloc(SQR(wsize) * sizeof(double)); /* Reserve enough memory weights matrix. */ normal_ptr = dmatrix(0, 5, 0, 5); /* Allocate memory for 6*6 matrix */ index_ptr = ivector(0, 5); /* and for 1D vector holding indices */ obs_ptr = dvector(0, 5); /* and for 1D vector holding observed z */ /* ---------------------------------------------------------------- */ /* - CALCULATE LEAST SQUARES COEFFICIENTS - */ /* ---------------------------------------------------------------- */ /*--- Calculate weighting matrix. ---*/ find_weight(weight_ptr); /* Initial coefficients need only be found once since they are constant for any given window size. The only element that changes is the observed vector (RHS of normal equations). */ /*--- Find normal equations in matrix form. ---*/ find_normal(normal_ptr, weight_ptr); /*--- Apply LU decomposition to normal equations. ---*/ if (constrained) { G_ludcmp(normal_ptr, 5, index_ptr, &temp); /* To constrain the quadtratic through the central cell, ignore the calculations involving the coefficient f. Since these are all in the last row and column of the matrix, simply redimension. */ /* disp_matrix(normal_ptr,obs_ptr,obs_ptr,5); */ } else { G_ludcmp(normal_ptr, 6, index_ptr, &temp); /* disp_matrix(normal_ptr,obs_ptr,obs_ptr,6); */ } /*--------------------------------------------------------------------------*/ /* PROCESS INPUT RASTER AND WRITE OUT RASTER LINE BY LINE */ /*--------------------------------------------------------------------------*/ if (mparam != FEATURE) for (wind_row = 0; wind_row < EDGE; wind_row++) Rast_put_row(fd_out, row_out, DCELL_TYPE); /* Write out the edge cells as NULL. */ else for (wind_row = 0; wind_row < EDGE; wind_row++) Rast_put_row(fd_out, featrow_out, CELL_TYPE); /* Write out the edge cells as NULL. */ for (wind_row = 0; wind_row < wsize - 1; wind_row++) Rast_get_row(fd_in, row_in + (wind_row * ncols), wind_row, DCELL_TYPE); /* Read in enough of the first rows to */ /* allow window to be examined. */ for (row = EDGE; row < (nrows - EDGE); row++) { G_percent(row + 1, nrows - EDGE, 2); Rast_get_row(fd_in, row_in + ((wsize - 1) * ncols), row + EDGE, DCELL_TYPE); for (col = EDGE; col < (ncols - EDGE); col++) { /* Find central z value */ centre = *(row_in + EDGE * ncols + col); for (wind_row = 0; wind_row < wsize; wind_row++) for (wind_col = 0; wind_col < wsize; wind_col++) /* Express all window values relative */ /* to the central elevation. */ *(window_ptr + (wind_row * wsize) + wind_col) = *(row_in + (wind_row * ncols) + col + wind_col - EDGE) - centre; /*--- Use LU back substitution to solve normal equations. ---*/ find_obs(window_ptr, obs_ptr, weight_ptr); /* disp_wind(window_ptr); disp_matrix(normal_ptr,obs_ptr,obs_ptr,6); */ if (constrained) { G_lubksb(normal_ptr, 5, index_ptr, obs_ptr); /* disp_matrix(normal_ptr,obs_ptr,obs_ptr,5); */ } else { G_lubksb(normal_ptr, 6, index_ptr, obs_ptr); /* disp_matrix(normal_ptr,obs_ptr,obs_ptr,6); */ } /*--- Calculate terrain parameter based on quad. coefficients. ---*/ if (mparam == FEATURE) *(featrow_out + col) = (CELL) feature(obs_ptr); else *(row_out + col) = param(mparam, obs_ptr); if (mparam == ELEV) *(row_out + col) += centre; /* Add central elevation back */ } if (mparam != FEATURE) Rast_put_row(fd_out, row_out, DCELL_TYPE); /* Write the row buffer to the output */ /* raster. */ else /* write FEATURE to CELL */ Rast_put_row(fd_out, featrow_out, CELL_TYPE); /* Write the row buffer to the output */ /* raster. */ /* 'Shuffle' rows down one, and read in */ /* one new row. */ for (wind_row = 0; wind_row < wsize - 1; wind_row++) for (col = 0; col < ncols; col++) *(row_in + (wind_row * ncols) + col) = *(row_in + ((wind_row + 1) * ncols) + col); } for (wind_row = 0; wind_row < EDGE; wind_row++) { if (mparam != FEATURE) Rast_put_row(fd_out, row_out, DCELL_TYPE); /* Write out the edge cells as NULL. */ else Rast_put_row(fd_out, featrow_out, CELL_TYPE); /* Write out the edge cells as NULL. */ } /*--------------------------------------------------------------------------*/ /* FREE MEMORY USED TO STORE RASTER ROWS, LOCAL WINDOW AND MATRICES */ /*--------------------------------------------------------------------------*/ G_free(row_in); if (mparam != FEATURE) G_free(row_out); else G_free(featrow_out); G_free(window_ptr); free_dmatrix(normal_ptr, 0, 5, 0, 5); free_dvector(obs_ptr, 0, 5); free_ivector(index_ptr, 0, 5); }
/* * * Recursively processes each segment in a tree by: * * a) finding points from neighbouring segments so that the total number of * points is between KMIN and KMAX2 by calling tree function MT_get_region(). * * b) creating and solving the system of linear equations using these points * and interp() by calling matrix_create() and G_ludcmp(). * * c) checking the interpolating function values at points by calling * check_points(). * * d) computing grid for this segment using points and interp() by calling * grid_calc(). * */ int IL_interp_segments_2d(struct interp_params *params, struct tree_info *info, /* info for the quad tree */ struct multtree *tree, /* current leaf of the quad tree */ 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 */ int totsegm, /* total number of segments */ off_t offset1, /* offset for temp file writing */ double dnorm) { double xmn, xmx, ymn, ymx, distx, disty, distxp, distyp, temp1, temp2; int i, npt, nptprev, MAXENC; struct quaddata *data; static int cursegm = 0; static double *b = NULL; static int *indx = NULL; static double **matrix = NULL; double ew_res, ns_res; static int first_time = 1; static double smseg; int MINPTS; double pr; struct triple *point; struct triple skip_point; int m_skip, skip_index, j, k, segtest; double xx, yy, zz; /* find the size of the smallest segment once */ if (first_time) { smseg = smallest_segment(info->root, 4); first_time = 0; } ns_res = (((struct quaddata *)(info->root->data))->ymax - ((struct quaddata *)(info->root->data))->y_orig) / params->nsizr; ew_res = (((struct quaddata *)(info->root->data))->xmax - ((struct quaddata *)(info->root->data))->x_orig) / params->nsizc; if (tree == NULL) return -1; if (tree->data == NULL) return -1; if (((struct quaddata *)(tree->data))->points == NULL) { for (i = 0; i < 4; i++) { IL_interp_segments_2d(params, info, tree->leafs[i], bitmask, zmin, zmax, zminac, zmaxac, gmin, gmax, c1min, c1max, c2min, c2max, ertot, totsegm, offset1, dnorm); } return 1; } else { distx = (((struct quaddata *)(tree->data))->n_cols * ew_res) * 0.1; disty = (((struct quaddata *)(tree->data))->n_rows * ns_res) * 0.1; distxp = 0; distyp = 0; xmn = ((struct quaddata *)(tree->data))->x_orig; xmx = ((struct quaddata *)(tree->data))->xmax; ymn = ((struct quaddata *)(tree->data))->y_orig; ymx = ((struct quaddata *)(tree->data))->ymax; i = 0; MAXENC = 0; /* data is a window with zero points; some fields don't make sence in this case so they are zero (like resolution,dimentions */ /* CHANGE */ /* Calcutaing kmin for surrent segment (depends on the size) */ /*****if (smseg <= 0.00001) MINPTS=params->kmin; else {} ***/ pr = pow(2., (xmx - xmn) / smseg - 1.); MINPTS = params->kmin * (pr / (1 + params->kmin * pr / params->KMAX2)); /* fprintf(stderr,"MINPTS=%d, KMIN=%d, KMAX=%d, pr=%lf, smseg=%lf, DX=%lf \n", MINPTS,params->kmin,params->KMAX2,pr,smseg,xmx-xmn); */ data = (struct quaddata *)quad_data_new(xmn - distx, ymn - disty, xmx + distx, ymx + disty, 0, 0, 0, params->KMAX2); npt = MT_region_data(info, info->root, data, params->KMAX2, 4); while ((npt < MINPTS) || (npt > params->KMAX2)) { if (i >= 70) { G_warning(_("Taking too long to find points for interpolation - " "please change the region to area where your points are. " "Continuing calculations...")); break; } i++; if (npt > params->KMAX2) /* decrease window */ { MAXENC = 1; nptprev = npt; temp1 = distxp; distxp = distx; distx = distxp - fabs(distx - temp1) * 0.5; temp2 = distyp; distyp = disty; disty = distyp - fabs(disty - temp2) * 0.5; /* decrease by 50% of a previous change in window */ } else { nptprev = npt; temp1 = distyp; distyp = disty; temp2 = distxp; distxp = distx; if (MAXENC) { disty = fabs(disty - temp1) * 0.5 + distyp; distx = fabs(distx - temp2) * 0.5 + distxp; } else { distx += distx; disty += disty; } /* decrease by 50% of extra distance */ } data->x_orig = xmn - distx; /* update window */ data->y_orig = ymn - disty; data->xmax = xmx + distx; data->ymax = ymx + disty; data->n_points = 0; npt = MT_region_data(info, info->root, data, params->KMAX2, 4); } if (totsegm != 0) { G_percent(cursegm, totsegm, 1); } data->n_rows = ((struct quaddata *)(tree->data))->n_rows; data->n_cols = ((struct quaddata *)(tree->data))->n_cols; /* for printing out overlapping segments */ ((struct quaddata *)(tree->data))->x_orig = xmn - distx; ((struct quaddata *)(tree->data))->y_orig = ymn - disty; ((struct quaddata *)(tree->data))->xmax = xmx + distx; ((struct quaddata *)(tree->data))->ymax = ymx + disty; data->x_orig = xmn; data->y_orig = ymn; data->xmax = xmx; data->ymax = ymx; if (!matrix) { if (! (matrix = G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) { G_warning(_("Out of memory")); return -1; } } if (!indx) { if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) { G_warning(_("Out of memory")); return -1; } } if (!b) { if (!(b = G_alloc_vector(params->KMAX2 + 3))) { G_warning(_("Out of memory")); return -1; } } /* allocate memory for CV points only if cv is performed */ if (params->cv) { if (! (point = (struct triple *)G_malloc(sizeof(struct triple) * data->n_points))) { G_warning(_("Out of memory")); return -1; } } /*normalize the data so that the side of average segment is about 1m */ /* put data_points into point only if CV is performed */ for (i = 0; i < data->n_points; i++) { data->points[i].x = (data->points[i].x - data->x_orig) / dnorm; data->points[i].y = (data->points[i].y - data->y_orig) / dnorm; if (params->cv) { point[i].x = data->points[i].x; /*cv stuff */ point[i].y = data->points[i].y; /*cv stuff */ point[i].z = data->points[i].z; /*cv stuff */ } /* commented out by Helena january 1997 as this is not necessary although it may be useful to put normalization of z back? data->points[i].z = data->points[i].z / dnorm; this made smoothing self-adjusting based on dnorm if (params->rsm < 0.) data->points[i].sm = data->points[i].sm / dnorm; */ } /* cv stuff */ if (params->cv) m_skip = data->n_points; else m_skip = 1; /* remove after cleanup - this is just for testing */ skip_point.x = 0.; skip_point.y = 0.; skip_point.z = 0.; /*** TODO: parallelize this loop instead of the LU solver! ***/ for (skip_index = 0; skip_index < m_skip; skip_index++) { if (params->cv) { segtest = 0; j = 0; xx = point[skip_index].x * dnorm + data->x_orig + params->x_orig; yy = point[skip_index].y * dnorm + data->y_orig + params->y_orig; zz = point[skip_index].z; if (xx >= data->x_orig + params->x_orig && xx <= data->xmax + params->x_orig && yy >= data->y_orig + params->y_orig && yy <= data->ymax + params->y_orig) { segtest = 1; skip_point.x = point[skip_index].x; skip_point.y = point[skip_index].y; skip_point.z = point[skip_index].z; for (k = 0; k < m_skip; k++) { if (k != skip_index && params->cv) { data->points[j].x = point[k].x; data->points[j].y = point[k].y; data->points[j].z = point[k].z; j++; } } } /* segment area test */ } if (!params->cv) { if (params-> matrix_create(params, data->points, data->n_points, matrix, indx) < 0) return -1; } else if (segtest == 1) { if (params-> matrix_create(params, data->points, data->n_points - 1, matrix, indx) < 0) return -1; } if (!params->cv) { for (i = 0; i < data->n_points; i++) b[i + 1] = data->points[i].z; b[0] = 0.; G_lubksb(matrix, data->n_points + 1, indx, b); /* put here condition to skip error if not needed */ params->check_points(params, data, b, ertot, zmin, dnorm, skip_point); } else if (segtest == 1) { for (i = 0; i < data->n_points - 1; i++) b[i + 1] = data->points[i].z; b[0] = 0.; G_lubksb(matrix, data->n_points, indx, b); params->check_points(params, data, b, ertot, zmin, dnorm, skip_point); } } /*end of cv loop */ if (!params->cv) if ((params->Tmp_fd_z != NULL) || (params->Tmp_fd_dx != NULL) || (params->Tmp_fd_dy != NULL) || (params->Tmp_fd_xx != NULL) || (params->Tmp_fd_yy != NULL) || (params->Tmp_fd_xy != NULL)) { if (params->grid_calc(params, data, bitmask, zmin, zmax, zminac, zmaxac, gmin, gmax, c1min, c1max, c2min, c2max, ertot, b, offset1, dnorm) < 0) return -1; } /* show after to catch 100% */ cursegm++; if (totsegm < cursegm) G_debug(1, "%d %d", totsegm, cursegm); if (totsegm != 0) { G_percent(cursegm, totsegm, 1); } /* G_free_matrix(matrix); G_free_ivector(indx); G_free_vector(b); */ G_free(data->points); G_free(data); } return 1; }