SplineGrass.cpp
Go to the documentation of this file.
1 /*!
2 \file terralib/mnt/core/SplineGrass.cpp
3 
4 \brief This file contains a class to calculate a grid from Sample using spline grass interpolator.
5 
6 */
7 
8 #include "SplineGrass.h"
9 #include "Utils.h"
10 
11 #include "../../common/progress/TaskProgress.h"
12 
14 {
15  unsigned int nro_neighb;
16  double rx1, ry2;
17  unsigned int NCols;
18  unsigned int NLines;
19 
20  m_tolerance = m_resx / 4;
21 
22  std::unique_ptr<te::rst::Raster> rst = Initialize(true, nro_neighb, rx1, ry2, NCols, NLines);
23 
24  //divide in x overlaping parts
25  unsigned int nPartsX = m_nPartsX;
26  unsigned int nPartsY = m_nPartsY;
27  double deltx = m_env.getUpperRightX() - m_env.getLowerLeftX();
28  double delty = m_env.getUpperRightY() - m_env.getLowerLeftY();
29 
30  double ew_region = deltx / (double)nPartsX;
31  double ns_region = delty / (double)nPartsY;
32 
33  double percentageDist = m_overlapping;
34 
35  unsigned int _minimoPontos = std::min(m_minpoints, (unsigned int)m_dataset.size());
36 
37  double resX = m_resx;
38  double resY = m_resy;
39 
40  double zdummy = m_nodatavalue;
41  int nsteps = (int)(m_nPartsY*m_nPartsY + 1);
42 
43  te::common::TaskProgress task("Generating DTM...", te::common::TaskProgress::UNDEFINED, nsteps);
44 
45  double X1 = m_env.getLowerLeftX() + resX / 2.;
46  double Y1 = m_env.getLowerLeftY() - resY / 2.;
47 
48  for (unsigned int i = 0; i < m_nPartsY; i++)
49  {
50  double begin_y = Y1 + (i*ns_region);
51  double end_y = Y1 + ((i + 1)*ns_region);
52 
53  double disty = (end_y - begin_y) * percentageDist;
54 
55  for (unsigned int j = 0; j < m_nPartsX; j++)
56  {
57  if (!task.isActive())
58  return false;
59  task.pulse();
60  //Calculate the init and final area
61  double begin_x = X1 + (j*ew_region);
62  double end_x = X1 + ((j + 1)*ew_region);
63 
64  double distx = (end_x - begin_x) * percentageDist;
65 
66  double min_x = begin_x;
67  double min_y = begin_y;
68 
69  int nOverlaping = 1;
70  bool poucosPontos = false;
71  do
72  {
73  double overlapDistX = distx*nOverlaping;
74  double overlapDistY = disty*nOverlaping;
75 
76  int beginLine = std::max((int)((begin_y - Y1 - overlapDistY) / resY), 0);
77  int endLine = std::min((int)((end_y - Y1 + overlapDistY) / resY), (int)NLines);
78 
79  min_y = std::max(Y1, begin_y - overlapDistY);
80  if (beginLine == 0)
81  min_y = Y1;
82  else
83  min_y = begin_y - overlapDistY;
84 
85  int beginCol = std::max((int)((begin_x - X1 - overlapDistX) / resX), 0);
86  int endCol = std::min((int)((end_x - X1 + overlapDistX) / resX), (int)NCols);
87 
88  min_x = std::max(X1, begin_x - overlapDistX);
89  if (beginCol == 0)
90  min_x = X1;
91  else
92  min_x = begin_x - overlapDistX;
93 
94  //inits the interpolation
95  initInterpolation(beginLine, endLine, beginCol, endCol);
96 
97  //add the points control and the overlaping area
98  setControlPoints(min_x, min_y);
99 
100  poucosPontos = m_obsVect.size() < _minimoPontos;
101  nOverlaping++;
102 
103  } while (poucosPontos && (nOverlaping < 3));
104 
105  /*--------------------------------------*/
106  m_N.resize(m_nparameters);
107  m_TN.resize(m_nparameters);
108  m_parVect.resize(m_nparameters);
109  for (unsigned int k = 0; k < m_nparameters; k++)
110  {
111  m_N[k].resize(m_BW);
112  }
113  /*--------------------------------------*/
114 
115  //calculate the grid
116  calculateGrid(min_x, min_y);
117 
118  /*--------------------------------------*/
119  for (unsigned int k = 0; k < m_nparameters; k++)
120  {
121  m_N[k].clear();
122  }
123  m_N.clear();
124  m_TN.clear();
125  /*--------------------------------------*/
126 
127  //calculate the grid
128  unsigned int firstLine = (unsigned int)std::max((int)((begin_y - Y1) / resY), 0);
129  unsigned int lastLine = std::min((unsigned int)((end_y - Y1) / resY), NLines);
130 
131  unsigned int firstCol = (unsigned int)std::max((int)((begin_x - X1) / resX), 0);
132  unsigned int lastCol = std::min((unsigned int)((end_x - X1) / resX), NCols);
133 
134  //allows calculated values to grid
135  unsigned int l, c;
136  //allows only the lines of the medium
137  for (l = firstLine; l<lastLine; l++)
138  {
139  for (c = firstCol; c < lastCol; c++)
140  {
142  pg.setX(X1 + (double)(c*m_resx));
143  pg.setY(Y1 + (double)(l*m_resy));
144  pg.setZ(m_nodatavalue);
145 
146  double interpolation = 0;
147  bool doInterpolation;
148  if (m_inter == SplineBilinear)
149  interpolation = dataInterpolateBilin(pg.getX(), pg.getY(), min_x, min_y, doInterpolation);
150  else
151  interpolation = dataInterpolateBicubic(pg.getX(), pg.getY(), min_x, min_y, doInterpolation);
152 
153  if (!doInterpolation)
154  continue;
155 
156  if (nPointInterest())
157  interpolation += pointsControlMean();
158  else
159  interpolation = zdummy;
160 
161  pg.setZ(interpolation);
162 
163  if (interpolation != m_nodatavalue)
164  {
165  m_max = (interpolation > m_max) ? interpolation : m_max;
166  m_min = (interpolation < m_min) ? interpolation : m_min;
167  }
168 
169  m_rst->setValue(c, NLines - l - 1, pg.getZ());
170  }
171  }
172  m_parVect.clear();
173  }
174  }
175 
176  rst.release();
177 
178  return true;
179 }
180 
181 void te::mnt::SplineInterpolationGrass::initInterpolation(int beginLine, int endLine, int beginCol, int endCol)
182 {
183  //define splines number
184  m_nsplx = (unsigned int)(endCol - beginCol);
185  m_nsply = (unsigned int)(endLine - beginLine);
186 
187  //define parameters number
189 
190  //define north and west step
193 
194  //define lambda
195  m_lambda = 1;
196 
197  //define o bandwich
198  m_BW = 0;
199  if (m_inter == SplineBilinear)
200  m_BW = (2 * m_nsply + 1);
201  else //bicubico
202  m_BW = (4 * m_nsply + 3);
203 }
204 
206 {
207  int i_x; /* x = (xMin + (i_x * passoWidth) + csi_x) */
208  double csi_x;
209 
210  int i_y; /* y = (yMin + (i_y * passoHeight) + csi_y) */
211  double csi_y;
212 
213  std::size_t nVectorPoints = m_dataset.size();
214 
215  //initialize mean and points
216  m_mean = 0;
217  m_npoints = 0;
218 
219  //calculate mean and points
220  for (unsigned int i = 0; i<nVectorPoints; i++)
221  {
222  te::gm::Point pp3d = m_dataset.at(i).second;
223  node_x(pp3d.getX(), i_x, csi_x, xMin, m_passoWidth);
224  node_y(pp3d.getY(), i_y, csi_y, yMin, m_passoHeight);
225 
226  if ((i_x >= -1) && (i_x < (int)m_nsplx) && (i_y >= -1) && (i_y < (int)m_nsply))
227  {
228  m_mean += pp3d.getZ();
229  m_npoints++;
230  }
231  }
232  m_mean /= (double)m_npoints;
233 
234  //create point list
235  m_obsVect.clear();
236  for (unsigned int i = 0; i<nVectorPoints; i++)
237  {
238  te::gm::Point pp3d = m_dataset[i].second;
239  node_x(pp3d.getX(), i_x, csi_x, xMin, m_passoWidth);
240  node_y(pp3d.getY(), i_y, csi_y, yMin, m_passoHeight);
241 
242  if ((i_x >= -1) && (i_x < (int)m_nsplx) && (i_y >= -1) && (i_y < (int)m_nsply))
243  {
244  //update new point
245  te::gm::Point npp3d = pp3d;
246  npp3d.setZ(pp3d.getZ() - m_mean);
247 
248  //add a new point
249  m_obsVect.push_back(npp3d);
250  }
251  }
252 }
253 
254 /*!
255 * \brief Normal system computation for bilinear spline interpolation
256 */
257 
259 {
260  double alpha[2][2]; /* coefficients */
261 
262  int i_x; /* x = (xMin + (i_x * passoWidth) + csi_x) */
263  double csi_x;
264 
265  int i_y; /* y = (yMin + (i_y * passoHeight) + csi_y) */
266  double csi_y;
267 
268  /*--------------------------------------*/
269  for (unsigned int k = 0; k < m_nparameters; k++)
270  {
271  for (unsigned int h = 0; h < m_BW; h++)
272  m_N[k][h] = 0.;/* Normal matrix inizialization */
273  m_TN[k] = 0.;/* Normal vector inizialization */
274  }
275  /*--------------------------------------*/
276 
277  unsigned int n0;
278  for (unsigned int i = 0; i < m_npoints; i++)
279  {
280  te::gm::Point pp3D = m_obsVect[i];
281  node_x(pp3D.getX(), i_x, csi_x, xMin, m_passoWidth);
282  node_y(pp3D.getY(), i_y, csi_y, yMin, m_passoHeight);
283 
284  if ((i_x >= -1) && (i_x < (int)m_nsplx) && (i_y >= -1) && (i_y < (int)m_nsply))
285  {
286  csi_x = csi_x / m_passoWidth;
287  csi_y = csi_y / m_passoHeight;
288 
289  alpha[0][0] = phi(csi_x, csi_y);
290  alpha[0][1] = phi(csi_x, 1 - csi_y);
291  alpha[1][0] = phi(1 - csi_x, csi_y);
292  alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
293 
294  for (unsigned int k = 0; k <= 1; k++)
295  {
296  for (unsigned int h = 0; h <= 1; h++)
297  {
298  if (((i_x + k) <= (m_nsplx - 1)) && ((i_y + h) <= (m_nsply - 1)))
299  {
300  for (unsigned int m = k; m <= 1; m++)
301  {
302  if (m == k) n0 = h;
303  else n0 = 0;
304 
305  for (unsigned int n = n0; n <= 1; n++)
306  {
307  if (((i_x + m) < m_nsplx) && ((i_y + n) < m_nsply))
308  {
309  m_N[(unsigned int)order(i_x + (int)k, i_y + (int)h, m_nsply)][(unsigned int)(order(i_x + (int)m, i_y + (int)n, m_nsply) - \
310  order(i_x + (int)k, i_y + (int)h, m_nsply))] += alpha[k][h] * alpha[m][n];
311  }
312  }
313  }
314  m_TN[(unsigned int)order(i_x + (int)k, i_y + (int)h, m_nsply)] += pp3D.getZ()* alpha[k][h];
315  }
316  }
317  }
318  }
319  }
320 
321  return;
322 }
323 
324 /*!
325 * \brief Normal system computation for bicubic spline interpolation
326 */
327 
329 {
330  double alpha[4][4]; /* coefficients */
331 
332  int i_x; /* x = (xMin + (i_x * passoWidth) + csi_x) */
333  double csi_x;
334 
335  int i_y; /* y = (yMin + (i_y * passoHeight) + csi_y) */
336  double csi_y;
337 
338  /*--------------------------------------*/
339  for (unsigned int k = 0; k < m_nparameters; k++)
340  {
341  for (unsigned int h = 0; h < m_BW; h++)
342  m_N[k][h] = 0.; /* Normal matrix inizialization */
343  m_TN[k] = 0.; /* Normal vector inizialization */
344  }
345  /*--------------------------------------*/
346 
347  for (unsigned int i = 0; i < m_npoints; i++)
348  {
349  te::gm::Point pp3D = m_obsVect[i];
350  node_x(pp3D.getX(), i_x, csi_x, xMin, m_passoWidth);
351  node_y(pp3D.getY(), i_y, csi_y, yMin, m_passoHeight);
352 
353  if ((i_x >= -2) && (i_x <= (int)m_nsplx) && (i_y >= -2) && (i_y <= (int)m_nsply))
354  {
355  csi_x = csi_x / m_passoWidth;
356  csi_y = csi_y / m_passoHeight;
357 
358  alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
359  alpha[0][1] = phi_43(1 + csi_x, csi_y);
360  alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
361  alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
362 
363  alpha[1][0] = phi_34(csi_x, 1 + csi_y);
364  alpha[1][1] = phi_33(csi_x, csi_y);
365  alpha[1][2] = phi_33(csi_x, 1 - csi_y);
366  alpha[1][3] = phi_34(csi_x, 2 - csi_y);
367 
368  alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
369  alpha[2][1] = phi_33(1 - csi_x, csi_y);
370  alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
371  alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
372 
373  alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
374  alpha[3][1] = phi_43(2 - csi_x, csi_y);
375  alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
376  alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
377 
378  int n0;
379  for (int k = -1; k <= 2; k++)
380  {
381  for (int h = -1; h <= 2; h++)
382  {
383  if (((i_x + k) >= 0) && ((i_x + k) < (int)m_nsplx) && ((i_y + h) >= 0) && ((i_y + h) < (int)m_nsply))
384  {
385  for (int m = k; m <= 2; m++)
386  {
387  if (m == k) n0 = h;
388  else n0 = -1;
389 
390  for (int n = n0; n <= 2; n++) {
391  if (((i_x + m) >= 0) && ((i_x + m) < (int)m_nsplx) && ((i_y + n) >= 0) && ((i_y + n) < (int)m_nsply)) {
392  m_N[(unsigned int)order(i_x + k, i_y + h, m_nsply)][(unsigned int)(order(i_x + m, i_y + n, m_nsply) - \
393  order(i_x + k, i_y + h, m_nsply))] += alpha[(unsigned int)(k + 1)][(unsigned int)(h + 1)] * alpha[(unsigned int)(m + 1)][(unsigned int)(n + 1)];
394  }
395  }
396  }
397  m_TN[(unsigned int)order(i_x + k, i_y + h, m_nsply)] += pp3D.getZ() * alpha[(unsigned int)(k + 1)][(unsigned int)(h + 1)];
398  }
399  }
400  }
401  }
402  }
403 
404  return;
405 }
406 
407 /*!
408 * \brief 1-DELTA discretization
409 */
411 {
412  unsigned int i;
413  unsigned int parNum;
414 
415  double alpha[3];
416  double lambdaX, lambdaY;
417 
418  lambdaX = m_lambda * (m_passoHeight / m_passoWidth);
419  lambdaY = m_lambda * (m_passoWidth / m_passoHeight);
420 
421  parNum = m_nsplx * m_nsply;
422 
423  alpha[0] = 2 * lambdaX + 2 * lambdaY;
424  alpha[1] = -lambdaX;
425  alpha[2] = -lambdaY;
426 
427  for (i = 0; i < parNum; i++) {
428  m_N[i][0] += alpha[0];
429 
430  if ((i + 1) < parNum)
431  m_N[i][1] += alpha[2];
432 
433  if ((i + 1 * m_nsply) < parNum)
434  m_N[i][1 * m_nsply] += alpha[1];
435  }
436 
437  return;
438 }
439 
440 /*!
441 * \brief Tcholetsky decomposition -> T= Lower Triangular Matrix
442 */
443 
444 bool te::mnt::SplineInterpolationGrass::tcholDec(std::vector< std::vector<double> > &T)
445 {
446  unsigned int i, j, k;
447  double somma;
448 
449  for (i = 0; i < m_nparameters; i++)
450  {
451  for (j = 0; j < m_BW; j++)
452  {
453  somma = m_N[i][j];
454  for (k = 1; k < m_BW; k++)
455  if ((int(i - k) >= 0) && ((j + k) < m_BW))
456  somma -= T[i - k][k] * T[i - k][j + k];
457  if (j == 0) {
458  if (somma <= 0.0)
459  return false;
460  T[i][0] = sqrt(somma);
461  }
462  else T[i][j] = somma / T[i][0];
463  }
464  }
465 
466  return true;
467 }
468 
469 /*!
470 * \brief Data interpolation in a generic point
471 */
472 
473 double te::mnt::SplineInterpolationGrass::dataInterpolateBilin(double x, double y, double xMin, double yMin, bool &interp)
474 {
475  double z; /* abscissa, ordinate and associated value */
476 
477  int k, h; /* counters */
478  double alpha[2][2]; /* coefficients */
479 
480  int i_x, i_y; /* x = (xMin + (i_x * passoWidth) + csi_x) */
481  double csi_x, csi_y; /* y = (yMin + (i_y * passoHeight) + csi_y) */
482 
483  z = 0;
484 
485  interp = false;
486 
487  node_x(x, i_x, csi_x, xMin, m_passoWidth);
488  node_y(y, i_y, csi_y, yMin, m_passoHeight);
489 
490  if ((i_x >= -1) && (i_x <(int)m_nsplx) && (i_y >= -1) && (i_y < (int)m_nsply))
491  {
492  csi_x = csi_x / m_passoWidth;
493  csi_y = csi_y / m_passoHeight;
494 
495  alpha[0][0] = phi(csi_x, csi_y);
496  alpha[0][1] = phi(csi_x, 1 - csi_y);
497 
498  alpha[1][0] = phi(1 - csi_x, csi_y);
499  alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
500 
501  for (k = 0; k <= 1; k++)
502  {
503  for (h = 0; h <= 1; h++)
504  {
505  if (((i_x + k) >= 0) && ((i_x + k) < (int)m_nsplx) && ((i_y + h) >= 0) && ((i_y + h) < (int)m_nsply))
506  z += m_parVect[(unsigned int)order(i_x + k, i_y + h, m_nsply)] * alpha[(unsigned int)k][(unsigned int)h];
507  }
508  }
509 
510  interp = true;
511  }
512 
513  return z;
514 }
515 
516 /*!
517 * \brief Data interpolation in a generic point
518 */
519 
520 double te::mnt::SplineInterpolationGrass::dataInterpolateBicubic(double x, double y, double xMin, double yMin, bool &interp)
521 {
522  double z; /* abscissa, ordinate and associated value */
523 
524  int k, h; /* counters */
525  double alpha[4][4]; /* coefficients */
526 
527  int i_x, i_y; /* x = (xMin + (i_x * passoWidth) + csi_x) */
528  double csi_x, csi_y; /* y = (yMin + (i_y * passoHeight) + csi_y) */
529 
530  z = 0;
531  interp = false;
532 
533  node_x(x, i_x, csi_x, xMin, m_passoWidth);
534  node_y(y, i_y, csi_y, yMin, m_passoHeight);
535 
536  if ((i_x >= -2) && (i_x <= (int)m_nsplx) && (i_y >= -2) && (i_y <= (int)m_nsply)) {
537 
538  csi_x = csi_x / m_passoWidth;
539  csi_y = csi_y / m_passoHeight;
540 
541  alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
542  alpha[0][1] = phi_43(1 + csi_x, csi_y);
543  alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
544  alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
545 
546  alpha[1][0] = phi_34(csi_x, 1 + csi_y);
547  alpha[1][1] = phi_33(csi_x, csi_y);
548  alpha[1][2] = phi_33(csi_x, 1 - csi_y);
549  alpha[1][3] = phi_34(csi_x, 2 - csi_y);
550 
551  alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
552  alpha[2][1] = phi_33(1 - csi_x, csi_y);
553  alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
554  alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
555 
556  alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
557  alpha[3][1] = phi_43(2 - csi_x, csi_y);
558  alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
559  alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
560 
561  for (k = -1; k <= 2; k++)
562  {
563  for (h = -1; h <= 2; h++)
564  {
565  if (((i_x + k) >= 0) && ((i_x + k) < (int)m_nsplx) && ((i_y + h) >= 0) && ((i_y + h) < (int)m_nsply))
566  z += m_parVect[(unsigned int)order(i_x + k, i_y + h, m_nsply)] * alpha[(unsigned int)(k + 1)][(unsigned int)(h + 1)];
567  }
568  }
569  interp = true;
570  }
571 
572  return z;
573 }
574 
575 /*!
576 * \brief Tcholetsky matrix solution
577 */
579 {
580  std::vector< std::vector<double> > T;
581  size_t i, j;
582 
583  T = m_N;
584 
585  if (!tcholDec(T)) /* T computation */
586  return false;
587 
588  /* Forward substitution */
589  m_parVect[0] = m_TN[0] / T[0][0];
590  for (i = 1; i < m_nparameters; i++)
591  {
592  m_parVect[i] = m_TN[i];
593  for (j = 0; j < i; j++)
594  if ((i - j) < m_BW) m_parVect[i] -= T[j][i - j] * m_parVect[j];
595  m_parVect[i] = m_parVect[i] / T[i][0];
596  }
597 
598  /* Backward substitution */
599  m_parVect[m_nparameters - 1] = m_parVect[m_nparameters - 1] / T[m_nparameters - 1][0];
600  for (int ii = (int)m_nparameters - 2; ii >= 0; ii--)
601  {
602  i = (size_t)ii;
603  for (j = i + 1; j < m_nparameters; j++)
604  if ((j - i) < m_BW) m_parVect[i] -= T[i][j - i] * m_parVect[j];
605  m_parVect[i] = m_parVect[i] / T[i][0];
606  }
607  return true;
608 }
609 
611 {
612  //calcula a grade
613  if (m_inter == SplineBilinear)
614  {//Bilinear
615  normalDefBilin(xMin, yMin);
616  }
617  else
618  {//Bicubica
619  normalDefBicubic(xMin, yMin);
620  }
621 
622  nCorrectGrad();
623 
624  //resolve
625  if (!tcholSolve())
626  {
627  return false;
628  }
629  return true;
630 }
631 
633 {
634  size_t npts = ls->getNPoints();
635  size_t npte = npts;
636 
637  te::gm::Coord2D* vxy = ls->getCoordinates();
638 
639  // If line is too short or snap is zero do nothing
640  if (npts <= 3 || snap == 0.)
641  {
643  for (size_t i = 0; i < npts; i++)
644  {
645  ptlist->setPointZ(i, vxy[i].getX(), vxy[i].getY(), Zvalue);
646  }
647  return ptlist;
648  }
649 
650  size_t npt;
651  bool island = false;
652  // Check for islands before defining number of points to be used
653  if (vxy[0] == vxy[npte - 1])
654  {
655  npt = npte - 1;
656  island = true;
657  }
658  else
659  npt = npte;
660 
661  // initialize variables
662  size_t i = 0;
663  size_t numa = 0;
664  size_t numpf = npt - 1;
665 
666  // define anchor
667  te::gm::Coord2D axy = vxy[numa];
668 
669  // define floating point
670  te::gm::Coord2D pfxy = vxy[numpf];
671 
672  bool retv;
673  double dmax, d,
674  a = 0, b = 0,
675  aa1 = 0;
676  size_t numdmax;
677 
678  while (numa < (npt - 1))
679  {
680  // Compute coeficients of straight line y=ax+b
681  if (pfxy.getX() == axy.getX())
682  retv = true;
683  else
684  {
685  retv = false;
686  a = (pfxy.getY() - axy.getY()) / (pfxy.getX() - axy.getX());
687  b = pfxy.getY() - a * pfxy.getX();
688  aa1 = sqrt(a * a + 1.);
689  }
690 
691  dmax = 0;
692  numdmax = numpf;
693  size_t k;
694 
695  for (k = numa + 1; k < numpf; k++)
696  {
697  // Distance between point and line
698  if (retv)
699  d = fabs(axy.getX() - vxy[k].getX());
700  else
701  d = fabs(vxy[k].getY() - a*vxy[k].getX() - b) / aa1;
702 
703  if (d > dmax)
704  {
705  dmax = d;
706  numdmax = k;
707  }
708  }
709 
710  if (dmax <= snap)
711  {
712  // Store selected point
713  vxy[i++] = axy;
714 
715  // Shift anchor
716  numa = numpf;
717  axy = vxy[numpf];
718  numpf = npt - 1;
719  }
720  else
721  // Shift floating point
722  numpf = numdmax;
723 
724  pfxy = vxy[numpf];
725  }
726 
727  // Store results
728  vxy[i] = vxy[numa];
729  npts = i + 1;
730 
731  if ((Distance(vxy[i], vxy[i - 1]) < snap) || (Distance(vxy[i], vxy[0]) < snap))
732  npts = i;
733 
734  size_t newpts;
735  if (island)
736  newpts = npts + 1;
737  else
738  newpts = npts;
739 
741 
742  for (i = 0; i < npts; i++)
743  {
744  ptlist->setPointZ(i, vxy[i].getX(), vxy[i].getY(), Zvalue);
745  }
746 
747  if (island)
748  ptlist->setPointZ(npts, vxy[0].getX(), vxy[0].getY(), Zvalue);
749 
750  AdjustLinear(ptlist, snap * 5.);
751 
752  return ptlist;
753 }
754 
756 {
757  if (maxDist == 0.)
758  return false;
759 
760  std::size_t npte = ptol->getNPoints();
761  if (npte < 2)
762  return false;
763 
764  double z = ptol->getZ(0);
765  te::gm::Coord2D* vxy = ptol->getCoordinates();
766  std::vector<te::gm::Point> pts;
767 
768  double xA, yA, xB, yB;
769  for (std::size_t i = 0; i < npte - 1; i++)
770  {
771  xA = vxy[i].getX();
772  yA = vxy[i].getY();
773  xB = vxy[i + 1].getX();
774  yB = vxy[i + 1].getY();
775  double dist = sqrt((xA - xB)*(xA - xB) + (yA - yB)*(yA - yB));
776  int nsteps = (int)((dist / maxDist) + 1);
777  if (nsteps > 1000)
778  nsteps = 1000;
779  for (int j = 0; j < nsteps; j++)
780  {
781  double t = (double)j / (double)nsteps;
782  double x = (xB - xA)*t + xA;
783  double y = (yB - yA)*t + yA;
784 
786  pt.setX(x);
787  pt.setY(y);
788  pt.setZ(z);
789  pts.push_back(pt);
790  }
791  if (i == npte - 2)
792  {
793  double x = xB;
794  double y = yB;
795 
797  pt.setX(x);
798  pt.setY(y);
799  pt.setZ(z);
800  pts.push_back(pt);
801 
802  pts.push_back(pt);
803  }
804  }
805 
806  ptol->setNumCoordinates(pts.size());
807  for (size_t i = 0; i < pts.size(); i++)
808  {
809  ptol->setPointN(i, pts[i]);
810  }
811 
812  return true;
813 }
814 
double m_mean
Media da area local.
Definition: SplineGrass.h:129
double m_nodatavalue
no data value
virtual void setValue(unsigned int c, unsigned int r, const double value, std::size_t b=0)
Sets the attribute value in a band of a cell.
int order(int i_x, int i_y, unsigned int yNum)
Node order computation.
Definition: SplineGrass.h:70
unsigned int m_nsplx
Numero de colunas do spline.
Definition: SplineGrass.h:125
std::unique_ptr< te::rst::Raster > Initialize(bool spline, unsigned int &nro_neighb, double &rx1, double &ry2, unsigned int &outputWidth, unsigned int &outputHeight)
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
unsigned int m_nPartsY
number of parts considered in the x and y directions
Definition: SplineGrass.h:122
std::vector< te::gm::Point > m_obsVect
Interpolation and least-square vectors.
Definition: SplineGrass.h:132
bool tcholDec(std::vector< std::vector< double > > &)
Tcholetsky decomposition -> T= Lower Triangular Matrix.
TEMNTEXPORT double Distance(const te::gm::Coord2D &pt1, const te::gm::Coord2D &pt2)
const double & getUpperRightX() const
It returns a constant refernce to the x coordinate of the upper right corner.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
std::vector< double > m_TN
Definition: SplineGrass.h:133
double phi_34(double csi_x, double csi_y)
Design matrix coefficients computation.
Definition: SplineGrass.h:87
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
bool tcholSolve()
Tcholetsky matrix solution.
double phi(double csi_x, double csi_y)
Design matrix coefficients computation.
Definition: SplineGrass.h:99
bool calculateGrid(double xMin, double yMin)
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
double getY() const
It returns the y-coordinate.
Definition: Coord2D.h:108
double m_max
Output DTM limits.
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
bool isActive() const
Verify if the task is active.
Interpolator m_inter
selected interpolation method
Utility functions for MNT support.
int b
Definition: TsRtree.cpp:32
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:152
A point with x and y coordinate values.
Definition: Point.h:50
void normalDefBilin(double xMin, double yMin)
Normal system computation for bilinear spline interpolation.
void node_y(double y, int &i_y, double &csi_y, double yMin, double deltaY)
Ordinate node index computation.
Definition: SplineGrass.h:61
void setControlPoints(double xMin, double yMin)
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
void setNumCoordinates(std::size_t size)
It reserves room for the number of coordinates in this LineString.
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
te::gm::Envelope m_env
Attribute used to restrict the area to generate the raster.
void setPointZ(std::size_t i, const double &x, const double &y, const double &z)
It sets the value of the specified point.
std::vector< double > m_parVect
Interpolating and least-square vectors.
Definition: SplineGrass.h:133
const double & getZ() const
It returns the Point z-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:166
unsigned int m_npoints
Numero de pontos de interesse.
Definition: SplineGrass.h:130
unsigned int m_nsply
Numero de linhas do spline.
Definition: SplineGrass.h:126
void initInterpolation(int beginLine, int endLine, int beginCol, int endCol)
double dataInterpolateBilin(double x, double y, double xMin, double yMin, bool &interp)
Data interpolation in a generic point.
double getX() const
It returns the x-coordinate.
Definition: Coord2D.h:102
std::vector< std::pair< te::gm::Coord2D, te::gm::Point > > m_dataset
double phi_43(double csi_x, double csi_y)
Design matrix coefficients computation.
Definition: SplineGrass.h:91
void setX(const double &x)
It sets the Point x-coordinate value.
Definition: Point.h:145
std::vector< std::vector< double > > m_N
Interpolation and least-square matrix.
Definition: SplineGrass.h:134
void node_x(double x, int &i_x, double &csi_x, double xMin, double deltaX)
Ordinate node index computation.
Definition: SplineGrass.h:52
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
This file contains a class to calculate retangular grid from Samples using Spline Grass Interpolation...
const double & getZ(std::size_t i) const
It returns the n-th z coordinate value.
double phi_44(double csi_x, double csi_y)
Design matrix coefficients computation.
Definition: SplineGrass.h:95
void setPointN(std::size_t i, const Point &p)
It sets the value of the specified point to this new one.
void setY(const double &y)
It sets the Point y-coordinate value.
Definition: Point.h:159
double dataInterpolateBicubic(double x, double y, double xMin, double yMin, bool &interp)
Data interpolation in a generic point.
te::rst::Raster * m_rst
void normalDefBicubic(double xMin, double yMin)
Normal system computation for bicubic spline interpolation.
double m_resy
grid resolution in X and Y
double m_overlapping
overlap value considered
Definition: SplineGrass.h:124
void nCorrectGrad()
1-DELTA discretization
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
unsigned int m_minpoints
minimum of points considered
Definition: SplineGrass.h:123
static bool AdjustLinear(te::gm::LineString *ptol, double maxDist)
METHOD TO ADJUST A LINEAR CURVE TO A SET OF LINE POINTS.
double phi_33(double csi_x, double csi_y)
Design matrix coefficients computation.
Definition: SplineGrass.h:83
void setZ(const double &z)
It sets the Point z-coordinate value.
Definition: Point.h:173
double m_tolerance
tolerance used to simplify lines
static te::gm::LineString * pointListSimplify(te::gm::LineString *ls, double snap, double Zvalue)