GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
segmen2d.c
Go to the documentation of this file.
1 /*
2  ** Written by H. Mitasova, I. Kosinovsky, D. Gerdes Fall 1993
3  ** Copyright H. Mitasova, I. Kosinovsky, D.Gerdes
4  */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <math.h>
9 #include <grass/gis.h>
10 #include <grass/glocale.h>
11 #include <grass/interpf.h>
12 #include <grass/gmath.h>
13 
14 static double smallest_segment(struct multtree *, int);
15 
16 int IL_interp_segments_2d(struct interp_params *params, struct tree_info *info, /* info for the quad tree */
17  struct multtree *tree, /* current leaf of the quad tree */
18  struct BM *bitmask, /* bitmask */
19  double zmin, double zmax, /* min and max input z-values */
20  double *zminac, double *zmaxac, /* min and max interp. z-values */
21  double *gmin, double *gmax, /* min and max inperp. slope val. */
22  double *c1min, double *c1max, double *c2min, double *c2max, /* min and max interp. curv. val. */
23  double *ertot, /* total interplating func. error */
24  int totsegm, /* total number of segments */
25  int offset1, /* offset for temp file writing */
26  double dnorm)
27 /*
28  Recursively processes each segment in a tree by
29  a) finding points from neighbouring segments so that the total number of
30  points is between KMIN and KMAX2 by calling tree function MT_get_region().
31  b) creating and solving the system of linear equations using these points
32  and interp() by calling matrix_create() and G_ludcmp().
33  c) checking the interpolating function values at points by calling
34  check_points().
35  d) computing grid for this segment using points and interp() by calling
36  grid_calc().
37  */
38 {
39  double xmn, xmx, ymn, ymx, distx, disty, distxp, distyp, temp1, temp2;
40  int i, npt, nptprev, MAXENC;
41  struct quaddata *data;
42  static int cursegm = 0;
43  static double *b = NULL;
44  static int *indx = NULL;
45  static double **matrix = NULL;
46  double ew_res, ns_res;
47  static int first_time = 1;
48  static double smseg;
49  int MINPTS;
50  double pr;
51  struct triple *point;
52  struct triple skip_point;
53  int m_skip, skip_index, j, k, segtest;
54  double xx, yy, zz;
55 
56  /* find the size of the smallest segment once */
57  if (first_time) {
58  smseg = smallest_segment(info->root, 4);
59  first_time = 0;
60  }
61  ns_res = (((struct quaddata *)(info->root->data))->ymax -
62  ((struct quaddata *)(info->root->data))->y_orig) /
63  params->nsizr;
64  ew_res =
65  (((struct quaddata *)(info->root->data))->xmax -
66  ((struct quaddata *)(info->root->data))->x_orig) / params->nsizc;
67 
68  if (tree == NULL)
69  return -1;
70  if (tree->data == NULL)
71  return -1;
72  if (((struct quaddata *)(tree->data))->points == NULL) {
73  for (i = 0; i < 4; i++) {
74  IL_interp_segments_2d(params, info, tree->leafs[i],
75  bitmask, zmin, zmax, zminac, zmaxac, gmin,
76  gmax, c1min, c1max, c2min, c2max, ertot,
77  totsegm, offset1, dnorm);
78  }
79  return 1;
80  }
81  else {
82  distx = (((struct quaddata *)(tree->data))->n_cols * ew_res) * 0.1;
83  disty = (((struct quaddata *)(tree->data))->n_rows * ns_res) * 0.1;
84  distxp = 0;
85  distyp = 0;
86  xmn = ((struct quaddata *)(tree->data))->x_orig;
87  xmx = ((struct quaddata *)(tree->data))->xmax;
88  ymn = ((struct quaddata *)(tree->data))->y_orig;
89  ymx = ((struct quaddata *)(tree->data))->ymax;
90  i = 0;
91  MAXENC = 0;
92  /* data is a window with zero points; some fields don't make sence in this case
93  so they are zero (like resolution,dimentions */
94  /* CHANGE */
95  /* Calcutaing kmin for surrent segment (depends on the size) */
96 
97 /*****if (smseg <= 0.00001) MINPTS=params->kmin; else {} ***/
98  pr = pow(2., (xmx - xmn) / smseg - 1.);
99  MINPTS =
100  params->kmin * (pr / (1 + params->kmin * pr / params->KMAX2));
101  /* fprintf(stderr,"MINPTS=%d, KMIN=%d, KMAX=%d, pr=%lf, smseg=%lf, DX=%lf \n", MINPTS,params->kmin,params->KMAX2,pr,smseg,xmx-xmn); */
102 
103  data =
104  (struct quaddata *)quad_data_new(xmn - distx, ymn - disty,
105  xmx + distx, ymx + disty, 0, 0,
106  0, params->KMAX2);
107  npt = MT_region_data(info, info->root, data, params->KMAX2, 4);
108 
109  while ((npt < MINPTS) || (npt > params->KMAX2)) {
110  if (i >= 70) {
111  G_warning(_("Taking too long to find points for interpolation - "
112  "please change the region to area where your points are. "
113  "Continuing calculations..."));
114  break;
115  }
116  i++;
117  if (npt > params->KMAX2)
118  /* decrease window */
119  {
120  MAXENC = 1;
121  nptprev = npt;
122  temp1 = distxp;
123  distxp = distx;
124  distx = distxp - fabs(distx - temp1) * 0.5;
125  temp2 = distyp;
126  distyp = disty;
127  disty = distyp - fabs(disty - temp2) * 0.5;
128  /* decrease by 50% of a previous change in window */
129  }
130  else {
131  nptprev = npt;
132  temp1 = distyp;
133  distyp = disty;
134  temp2 = distxp;
135  distxp = distx;
136  if (MAXENC) {
137  disty = fabs(disty - temp1) * 0.5 + distyp;
138  distx = fabs(distx - temp2) * 0.5 + distxp;
139  }
140  else {
141  distx += distx;
142  disty += disty;
143  }
144  /* decrease by 50% of extra distance */
145  }
146  data->x_orig = xmn - distx; /* update window */
147  data->y_orig = ymn - disty;
148  data->xmax = xmx + distx;
149  data->ymax = ymx + disty;
150  data->n_points = 0;
151  npt = MT_region_data(info, info->root, data, params->KMAX2, 4);
152  }
153 
154  if (totsegm != 0) {
155  G_percent(cursegm, totsegm, 1);
156  }
157  data->n_rows = ((struct quaddata *)(tree->data))->n_rows;
158  data->n_cols = ((struct quaddata *)(tree->data))->n_cols;
159 
160  /* for printing out overlapping segments */
161  ((struct quaddata *)(tree->data))->x_orig = xmn - distx;
162  ((struct quaddata *)(tree->data))->y_orig = ymn - disty;
163  ((struct quaddata *)(tree->data))->xmax = xmx + distx;
164  ((struct quaddata *)(tree->data))->ymax = ymx + disty;
165 
166  data->x_orig = xmn;
167  data->y_orig = ymn;
168  data->xmax = xmx;
169  data->ymax = ymx;
170 
171  if (!matrix) {
172  if (!
173  (matrix =
174  G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) {
175  G_warning(_("Out of memory"));
176  return -1;
177  }
178  }
179  if (!indx) {
180  if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) {
181  G_warning(_("Out of memory"));
182  return -1;
183  }
184  }
185  if (!b) {
186  if (!(b = G_alloc_vector(params->KMAX2 + 3))) {
187  G_warning(_("Out of memory"));
188  return -1;
189  }
190  }
191  /* allocate memory for CV points only if cv is performed */
192  if (params->cv) {
193  if (!
194  (point =
195  (struct triple *)G_malloc(sizeof(struct triple) *
196  data->n_points))) {
197  G_warning(_("Out of memory"));
198  return -1;
199  }
200  }
201 
202  /*normalize the data so that the side of average segment is about 1m */
203  /* put data_points into point only if CV is performed */
204 
205  for (i = 0; i < data->n_points; i++) {
206  data->points[i].x = (data->points[i].x - data->x_orig) / dnorm;
207  data->points[i].y = (data->points[i].y - data->y_orig) / dnorm;
208  if (params->cv) {
209  point[i].x = data->points[i].x; /*cv stuff */
210  point[i].y = data->points[i].y; /*cv stuff */
211  point[i].z = data->points[i].z; /*cv stuff */
212  }
213 
214  /* commented out by Helena january 1997 as this is not necessary
215  although it may be useful to put normalization of z back?
216  data->points[i].z = data->points[i].z / dnorm;
217  this made smoothing self-adjusting based on dnorm
218  if (params->rsm < 0.) data->points[i].sm = data->points[i].sm / dnorm;
219  */
220  }
221 
222  /* cv stuff */
223  if (params->cv)
224  m_skip = data->n_points;
225  else
226  m_skip = 1;
227 
228  /* remove after cleanup - this is just for testing */
229  skip_point.x = 0.;
230  skip_point.y = 0.;
231  skip_point.z = 0.;
232 
233  for (skip_index = 0; skip_index < m_skip; skip_index++) {
234  if (params->cv) {
235  segtest = 0;
236  j = 0;
237  xx = point[skip_index].x * dnorm + data->x_orig +
238  params->x_orig;
239  yy = point[skip_index].y * dnorm + data->y_orig +
240  params->y_orig;
241  zz = point[skip_index].z;
242  if (xx >= data->x_orig + params->x_orig &&
243  xx <= data->xmax + params->x_orig &&
244  yy >= data->y_orig + params->y_orig &&
245  yy <= data->ymax + params->y_orig) {
246  segtest = 1;
247  skip_point.x = point[skip_index].x;
248  skip_point.y = point[skip_index].y;
249  skip_point.z = point[skip_index].z;
250  for (k = 0; k < m_skip; k++) {
251  if (k != skip_index && params->cv) {
252  data->points[j].x = point[k].x;
253  data->points[j].y = point[k].y;
254  data->points[j].z = point[k].z;
255  j++;
256  }
257  }
258  } /* segment area test */
259  }
260  if (!params->cv) {
261  if (params->
262  matrix_create(params, data->points, data->n_points,
263  matrix, indx) < 0)
264  return -1;
265  }
266  else if (segtest == 1) {
267  if (params->
268  matrix_create(params, data->points, data->n_points - 1,
269  matrix, indx) < 0)
270  return -1;
271  }
272  if (!params->cv) {
273  for (i = 0; i < data->n_points; i++)
274  b[i + 1] = data->points[i].z;
275  b[0] = 0.;
276  G_lubksb(matrix, data->n_points + 1, indx, b);
277  /* put here condition to skip ertot if not needed */
278  params->check_points(params, data, b, ertot, zmin, dnorm,
279  skip_point);
280  }
281  else if (segtest == 1) {
282  for (i = 0; i < data->n_points - 1; i++)
283  b[i + 1] = data->points[i].z;
284  b[0] = 0.;
285  G_lubksb(matrix, data->n_points, indx, b);
286  params->check_points(params, data, b, ertot, zmin, dnorm,
287  skip_point);
288  }
289  } /*end of cv loop */
290 
291  if (!params->cv)
292  if ((params->Tmp_fd_z != NULL) || (params->Tmp_fd_dx != NULL) ||
293  (params->Tmp_fd_dy != NULL) || (params->Tmp_fd_xx != NULL) ||
294  (params->Tmp_fd_yy != NULL) || (params->Tmp_fd_xy != NULL)) {
295 
296  if (params->grid_calc(params, data, bitmask,
297  zmin, zmax, zminac, zmaxac, gmin, gmax,
298  c1min, c1max, c2min, c2max, ertot, b,
299  offset1, dnorm) < 0)
300  return -1;
301  }
302 
303  /* show after to catch 100% */
304  cursegm++;
305  if (totsegm < cursegm)
306  G_debug(1, "%d %d", totsegm, cursegm);
307 
308  if (totsegm != 0) {
309  G_percent(cursegm, totsegm, 1);
310  }
311  /*
312  G_free_matrix(matrix);
313  G_free_ivector(indx);
314  G_free_vector(b);
315  */
316  G_free(data->points);
317  G_free(data);
318  }
319  return 1;
320 }
321 
322 static double smallest_segment(struct multtree *tree, int n_leafs)
323 {
324  static int first_time = 1;
325  int ii;
326  static double minside;
327  double side;
328 
329  if (tree == NULL)
330  return 0;
331  if (tree->data == NULL)
332  return 0;
333  if (tree->leafs != NULL) {
334  for (ii = 0; ii < n_leafs; ii++) {
335  side = smallest_segment(tree->leafs[ii], n_leafs);
336  if (first_time) {
337  minside = side;
338  first_time = 0;
339  }
340  if (side < minside)
341  minside = side;
342  }
343  }
344  else {
345  side = ((struct quaddata *)(tree->data))->xmax -
346  ((struct quaddata *)(tree->data))->x_orig;
347  return side;
348  }
349 
350  return minside;
351 }
def info
Display an informational message using g.message -i
Definition: core.py:339
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
float b
Definition: named_colr.c:8
double xmax
Definition: dataquad.c:293
double y_orig
Definition: dataquad.h:33
struct triple * point
Definition: dataquad.c:294
double ** G_alloc_matrix(int rows, int cols)
Matrix memory allocation.
Definition: dalloc.c:60
FILE * Tmp_fd_xy
Definition: interpf.h:60
FILE * Tmp_fd_yy
Definition: interpf.h:60
double z
Definition: dataquad.h:26
int IL_interp_segments_2d(struct interp_params *, struct tree_info *, struct multtree *, struct BM *, double, double, double *, double *, double *, double *, double *, double *, double *, double *, double *, int, int, double)
Definition: segmen2d.c:16
double y_orig
Definition: interpf.h:55
FILE * Tmp_fd_xx
Definition: interpf.h:60
double x_orig
Definition: dataquad.h:32
struct triple * points
Definition: dataquad.h:39
struct quaddata * data
Definition: qtree.h:40
int G_percent(long n, long d, int s)
Print percent complete messages.
Definition: percent.c:63
struct quaddata * quad_data_new(double x_or, double y_or, double xmax, double ymax, int rows, int cols, int n_points, int kmax)
Definition: dataquad.c:36
void G_lubksb(double **a, int n, int *indx, double b[])
Definition: lu.c:71
FILE * Tmp_fd_dx
Definition: interpf.h:60
tuple data
double x
Definition: dataquad.h:24
double ymax
Definition: dataquad.c:293
double x_orig
Definition: interpf.h:55
double ymax
Definition: dataquad.h:35
return NULL
Definition: dbfopen.c:1394
FILE * Tmp_fd_dy
Definition: interpf.h:60
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
FILE * Tmp_fd_z
Definition: interpf.h:60
int MT_region_data(struct tree_info *info, struct multtree *tree, struct quaddata *data, int MAX, int n_leafs)
Definition: qtree.c:165
int * G_alloc_ivector(size_t n)
Vector matrix memory allocation.
Definition: ialloc.c:41
Definition: qtree.h:38
double xmax
Definition: dataquad.h:34
int n_rows
Definition: dataquad.h:36
struct multtree * root
Definition: qtree.h:35
double * G_alloc_vector(size_t n)
Vector matrix memory allocation.
Definition: dalloc.c:41
int(* check_points)()
Definition: interpf.h:66
int(* grid_calc)()
Definition: interpf.h:64
int n_cols
Definition: dataquad.h:37
double y
Definition: dataquad.h:25
struct multtree ** leafs
Definition: qtree.h:41
int n_points
Definition: dataquad.h:38