CalculateGrid.cpp
Go to the documentation of this file.
1 /*!
2 \file terralib/mnt/core/CalculateGrid.cpp
3 
4 \brief This file contains a class to calculate a grid from Sample.
5 
6 */
7 
8 #include "CalculateGrid.h"
9 #include "Utils.h"
10 
11 #include "../../common/progress/TaskProgress.h"
12 #include "../../raster.h"
13 #include "../../raster/BandProperty.h"
14 #include "../../raster/Grid.h"
15 #include "../../raster/RasterFactory.h"
16 
17 #include <algorithm>
18 #include <fstream>
19 
20 #define THRESHOLD 48
21 
23 {
24  delete m_rst;
25  delete m_adaptativeTree;
26 }
27 
29 {
30  m_tolerance = 0.;
31  m_nodatavalue = std::numeric_limits< double >::max();
33  m_inDsetName_point = "";
34  m_atrZ_sample = "";
35  m_atrZ_point = "";
36  m_srid = 0;
37  m_min = std::numeric_limits<double>::max();
38  m_max = std::numeric_limits<double>::min();
39 }
40 
41 std::unique_ptr<te::rst::Raster> te::mnt::CalculateGrid::Initialize(bool spline, unsigned int &nro_neighb, double &rx1, double &ry2, unsigned int &outputWidth, unsigned int &outputHeight)
42 {
45  std::string geostype;
46  Simplify alg;
47 
48  if (spline)
49  alg = Spline;
50  else
51  alg = AccumulatedDistance;
52 
53  // Get samples
54  size_t nsamples;
55  te::gm::Envelope env;
56 
57  nsamples = ReadPoints(m_inDsetName_point, m_inDsrc_point, m_atrZ_point, m_tolerance, mpt, geostype, env);
58  setEnvelope(env);
59  nsamples += ReadSamples(m_inDsetName_sample, m_inDsrc_sample, m_atrZ_sample, m_tolerance, m_tolerance, alg, mpt, isolines_simp, geostype, env);
60  setEnvelope(env);
61 
62  //Create greater box 1/2 resolution
63  rx1 = m_env.getLowerLeftX() - m_resx / 2.;
64  ry2 = m_env.getUpperRightY() + m_resy / 2.;
65 
66  outputWidth = (unsigned int)ceil(m_env.getWidth() / m_resx);
67  outputHeight = (unsigned int)ceil(m_env.getHeight() / m_resy);
68 
69  te::gm::Coord2D ulc(rx1, ry2);
70 
71  te::rst::Grid* grid = new te::rst::Grid(outputWidth, outputHeight, m_resx, m_resy, &ulc, m_srid);
72 
73  std::vector<te::rst::BandProperty*> bands;
74 
75  bands.push_back(new te::rst::BandProperty(0, te::dt::DOUBLE_TYPE, "DTM GRID"));
76  bands[0]->m_nblocksx = 1;
77  bands[0]->m_nblocksy = (int)outputHeight;
78  bands[0]->m_blkw = (int)outputWidth;
79  bands[0]->m_blkh = 1;
80  bands[0]->m_colorInterp = te::rst::GrayIdxCInt;
81  bands[0]->m_noDataValue = m_nodatavalue;
82 
83  // create raster
84  std::unique_ptr<te::rst::Raster> rst(te::rst::RasterFactory::make("GDAL", grid, bands, m_dsinfo));
85  m_rst = rst.get();
86 
87  std::vector<std::pair<te::gm::Coord2D, te::gm::Point> > dataset1;
88 
89  for (size_t i = 0; i < mpt.getNumGeometries(); i++)
90  {
91  te::gm::Point* gout = dynamic_cast<te::gm::Point*>(mpt.getGeometryN(i));
93  pz.setX(gout->getX());
94  pz.setY(gout->getY());
95  pz.setZ(gout->getZ());
96 
97  te::gm::Coord2D co(gout->getX(), gout->getY());
98  m_dataset.push_back(std::pair<te::gm::Coord2D, te::gm::Point>(co, pz));
99  dataset1.push_back(std::pair<te::gm::Coord2D, te::gm::Point>(co, pz));
100  }
101 
102  std::size_t datasize = m_dataset.size();
103 
105  m_adaptativeTree->build(dataset1);
106 
107  nro_neighb = THRESHOLD;
108  if (datasize < THRESHOLD)
109  nro_neighb = (unsigned int)datasize;
110 
111  if (m_inter == Vizinho) //Nearest Neighbor
112  nro_neighb = 1;
113 
114  return rst;
115 }
116 
118 {
119  try
120  {
121  unsigned int nro_neighb;
122  double rx1, ry2;
123  unsigned int outputWidth;
124  unsigned int outputHeight;
125 
126  std::unique_ptr<te::rst::Raster> rst = Initialize(false, nro_neighb, rx1, ry2, outputWidth, outputHeight);
127 
128  std::vector<double> distneighb;
129  std::vector<te::gm::Point> points;
130  for (unsigned int t = 0; t < nro_neighb; ++t)
131  {
133  pz.setX(std::numeric_limits<double>::max());
134  pz.setY(std::numeric_limits<double>::max());
135  pz.setZ(std::numeric_limits<double>::max());
136  points.push_back(pz);
137  }
138  double zvalue;
139 
140  te::common::TaskProgress task("Calculating DTM...", te::common::TaskProgress::UNDEFINED, (int)(outputHeight*outputWidth));
141 
142  te::gm::Coord2D pg;
143  for (unsigned int l = 0; l < outputHeight; l++)
144  {
145  for (unsigned int c = 0; c < outputWidth; c++)
146  {
147  task.pulse();
148  te::gm::Coord2D pg1(rx1 + (c * m_resx /*+ m_resx / 2.*/), ry2 - (l * m_resy/* + m_resy / 2.*/));
150  pgz.setX(pg1.getX());
151  pgz.setY(pg1.getY());
152  pgz.setZ(m_nodatavalue);
153  m_adaptativeTree->nearestNeighborSearch(pg1, points, distneighb, nro_neighb);
154 
155  // Filter elements by raio_max distance
156  size_t j = 0;
157  for (size_t i = 0; i < points.size(); i++)
158  {
159  if (distneighb[i] <= (m_radius*m_radius))
160  {
161  points[j] = points[i];
162  distneighb[j] = distneighb[i];
163  j++;
164  }
165  }
166  if (j > 0){
167  points.resize(j);
168  Interpolation(pgz, points, distneighb);
169  }
170 
171  zvalue = pgz.getZ();
172  if (zvalue != m_nodatavalue)
173  {
174  m_max = (zvalue > m_max) ? zvalue : m_max;
175  m_min = (zvalue < m_min) ? zvalue : m_min;
176  }
177  m_rst->setValue(c, l, zvalue);
178  }
179  }
180  rst.release();
181  }
182  catch (te::common::Exception& e)
183  {
184  throw e;
185  }
186 
187  return true;
188 }
189 
191  std::string inDsetName,
192  std::unique_ptr<te::da::DataSetType> inDsetType,
193  InputType type)
194 {
195  if (type == Isolines)
196  {
197  m_inDsrc_sample = inDsrc;
198  m_inDsetName_sample = inDsetName;
199  m_inDsetType_sample = std::move(inDsetType);
200  }
201  else
202  {
203  m_inDsrc_point = inDsrc;
204  m_inDsetName_point = inDsetName;
205  m_inDsetType_point = std::move(inDsetType);
206  }
207 }
208 
209 void te::mnt::CalculateGrid::setOutput(std::map<std::string, std::string> &dsinfo)
210 {
211  m_dsinfo = dsinfo;
212 }
213 
214 void te::mnt::CalculateGrid::setParams(const std::string &atrz_iso,
215  const std::string &atrz_pt,
216  double resx,
217  double resy,
218  Interpolator gt,
219  double rd,
220  int pow)
221 {
222  m_resx = resx;
223  m_resy = resy;
224  m_inter = gt;
225  m_atrZ_sample = atrz_iso;
226  m_atrZ_point = atrz_pt;
227  m_radius = rd;
228  m_power = pow;
229 }
230 
232 {
233  m_srid = srid;
234 }
235 
237 {
238  if (m_env.getWidth())
239  m_env.Union(env);
240  else
241  m_env = env;
242 }
243 
244 void te::mnt::CalculateGrid::Interpolation(te::gm::Point& pg, std::vector<te::gm::Point>& points, std::vector<double>& distq)
245 {
246  double Ztotal = 0.;
247  double Wi, Wtotal = 0.;
248 
249  if (distq[0] < 1.0e-5)
250  pg.setZ(points[0].getZ());
251  else
252  {
253  switch (m_inter)
254  {
255  case 0:
256  Ztotal = Interpwqz(pg, points, distq);
257  Wtotal = 1.0;
258  break;
259 
260  case 1:
261  Ztotal = Interpwq(pg, points, distq);
262  Wtotal = 1.0;
263  break;
264 
265  case 2: // Average of Z neighbours values weighted by inverse distance powered by potencia
266  for (unsigned int i = 0; i<points.size(); i++){
267  Wi = 1. / pow(distq[i], m_power / 2.);
268  Ztotal += (points[i].getZ()*Wi);
269  Wtotal += Wi;
270  }
271  break;
272 
273  case 3: // Average of Z values of the neighbours
274  for (unsigned int i = 0; i< points.size(); i++){
275  Ztotal += points[i].getZ();
276  Wtotal += 1.0;
277  }
278  break;
279 
280  case 4: // Nearest neighbour
281  Ztotal = points[0].getZ();
282  Wtotal = 1.0;
283  break;
284 
285  case 5:
286  case 6:
287  case 7:
288  case 8:
289  case 9:
290  case 10:
291  case 11:
292  case 12:
293  default:
294  break;
295  }
296 
297  if (Wtotal > 0.0)
298  pg.setZ(Ztotal / Wtotal);
299  else
300  pg.setZ(m_nodatavalue);
301  }
302 
303 }
304 
305 double te::mnt::CalculateGrid::Interpwq(te::gm::Point& pg, std::vector<te::gm::Point>& points, std::vector<double>& distq)
306 {
307  double Ztotal = 0;
308  double Wi, Wtotal = 0.0;
309  int q1 = 0, q2 = 0, q3 = 0, q4 = 0; // quadrants
310  unsigned int npts = 0;
311 
312  for (unsigned int i = 0; i < points.size(); i++)
313  {
314  //Filter the point by quadrant
315  if ((q1<1) && (points[i].getX() > pg.getX()) && (points[i].getY() > pg.getY()))
316  q1++;
317  else
318  if ((q2 < 1) && (points[i].getX() > pg.getX()) && (points[i].getY()<pg.getY()))
319  q2++;
320  else
321  if ((q3 < 1) && (points[i].getX() < pg.getX()) && (points[i].getY() < pg.getY()))
322  q3++;
323  else
324  if ((q4 < 1) && (points[i].getX() < pg.getX()) && (points[i].getY() > pg.getY()))
325  q4++;
326  else continue;
327 
328  points[npts] = points[i];
329  npts++;
330  }
331 
332  for (unsigned int i = 0; i<npts; i++)
333  {
334  Wi = 1. / pow(distq[i], (double)m_power / 2.);
335  Ztotal += (points[i].getZ()*Wi);
336  Wtotal += Wi;
337  }
338 
339  if (Wtotal >0.0)
340  return(Ztotal / Wtotal);
341  else
342  return (m_nodatavalue);
343 }
344 
345 double te::mnt::CalculateGrid::Interpwqz(te::gm::Point& pg, std::vector<te::gm::Point>& points, std::vector<double>& distq)
346 {
347  double Ztotal = 0;
348  double Wi, Wtotal = 0;
349  int q1 = 0, q2 = 0, q3 = 0, q4 = 0; // quadrants
350  int j;
351 
352  int use_point = 1;
353  for (unsigned int i = 0; i < points.size(); i++)
354  {
355  for (j = (int)i - 1; j >= 0; j--)
356  if (points[(unsigned int)j].getZ() == points[i].getZ())
357  break; // Points with equal Z coordinates
358 
359  use_point = 1; // Use the point
360  if ((i == 0) || (j == -1)) // did not find an equal value
361  {
362  // Filter the point by quadrants
363  if ((q1 < 1) && (points[i].getX() > pg.getX()) && (points[i].getY() > pg.getY()))
364  q1++;
365  else
366  if ((q2 < 1) && (points[i].getX() > pg.getX()) && (points[i].getY() < pg.getY()))
367  q2++;
368  else
369  if ((q3 < 1) && (points[i].getX() < pg.getX()) && (points[i].getY() < pg.getY()))
370  q3++;
371  else
372  if ((q4 < 1) && (points[i].getX() < pg.getX()) && (points[i].getY() > pg.getY()))
373  q4++;
374  else
375  use_point = 0; // do not use the point
376 
377  if (use_point == 1)
378  {
379  Wi = 1. / pow(distq[i], m_power / 2.);
380  Ztotal += (points[i].getZ()*Wi);
381  Wtotal += Wi;
382  }
383  }
384  }
385 
386  if (Wtotal > 0.0)
387  return(Ztotal / Wtotal);
388  else
389  return (m_nodatavalue);
390 }
391 
393 {
394  return true;
395 }
396 
398 {
399  return true;
400 }
401 
void setInput(te::da::DataSourcePtr inDsrc, std::string inDsetName, std::unique_ptr< te::da::DataSetType > inDsetType, InputType type)
It sets the Datasource that is being used to generate TIN.
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
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.
std::string m_inDsetName_point
CalculateGrid()
Default constructor.
bool run()
Calculate GRID \ return true or false.
InputType
Input types.
Index into a lookup table.
std::unique_ptr< te::rst::Raster > Initialize(bool spline, unsigned int &nro_neighb, double &rx1, double &ry2, unsigned int &outputWidth, unsigned int &outputHeight)
boost::shared_ptr< DataSource > DataSourcePtr
A raster band description.
Definition: BandProperty.h:61
void setEnvelope(te::gm::Envelope &env)
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
te::da::DataSourcePtr m_inDsrc_sample
std::string m_atrZ_sample
Attribute used to calculate grid.
std::string m_inDsetName_sample
std::string m_atrZ_point
Attribute used to calculate grid.
double getWidth() const
It returns the envelope width.
int m_srid
Attribute with spatial reference information.
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 GenerateGridSplineMitasova()
Method to calculate a grid from a vector of samples using a Spline (Mitasova) fitting algorithm...
Interpolator m_inter
selected interpolation method
void Union(const Envelope &rhs)
It updates the envelop with coordinates of another envelope.
std::unique_ptr< te::da::DataSetType > m_inDsetType_sample
KD_ADAPTATIVE_TREE * m_adaptativeTree
Utility functions for MNT support.
TEMNTEXPORT size_t ReadPoints(std::string &inDsetName, te::da::DataSourcePtr &inDsrc, std::string &atrZ, double tol, te::gm::MultiPoint &mpt, std::string &geostype, te::gm::Envelope &env)
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
void setParams(const std::string &attriso, const std::string &attrpt, double resx, double resy, Interpolator gt, double rad, int pow)
It sets the parameters that is being used to save TIN.
bool GenerateGridSplineGrass()
Method to calculate a grid from a vector of samples using a Spline (GRASS) fitting algorithm...
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
An Envelope defines a 2D rectangular region.
double Interpwq(te::gm::Point &pg, std::vector< te::gm::Point > &points, std::vector< double > &distq)
Interpolates the z value of the pg point3d using an weighted average by quadrant. \ Implements the in...
void build(std::vector< std::pair< kdKey, kdDataItem > > &dataSet)
It inserts the data set into the tree.
te::sam::kdtree::AdaptativeIndex< KD_ADAPTATIVE_NODE > KD_ADAPTATIVE_TREE
list bands
Definition: compose.py:2
te::da::DataSourcePtr m_inDsrc_point
double m_radius
radius
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
te::gm::Envelope m_env
Attribute used to restrict the area to generate the raster.
void Interpolation(te::gm::Point &pg, std::vector< te::gm::Point > &points, std::vector< double > &distq)
Interpolates the z value of the pg point3d. \ This method interpolates the z value of the pg point3d ...
const double & getZ() const
It returns the Point z-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:166
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
std::unique_ptr< te::da::DataSetType > m_inDsetType_point
double Interpwqz(te::gm::Point &pg, std::vector< te::gm::Point > &points, std::vector< double > &distq)
Interpolates the z value of the pg point3d using an weighted average by quadrant and by z values...
TEMNTEXPORT size_t ReadSamples(std::string &inDsetName, te::da::DataSourcePtr &inDsrc, std::string &atrZ, double tol, double max, Simplify alg, te::gm::MultiPoint &mpt, te::gm::MultiLineString &isolines, std::string &geostype, te::gm::Envelope &env, int srid=0)
#define THRESHOLD
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
std::map< std::string, std::string > m_dsinfo
MultiLineString is a MultiCurve whose elements are LineStrings.
This file contains a class to calculate retangular grid from Samples. Adapted from SPRING...
double getX() const
It returns the x-coordinate.
Definition: Coord2D.h:102
std::vector< std::pair< te::gm::Coord2D, te::gm::Point > > m_dataset
void setX(const double &x)
It sets the Point x-coordinate value.
Definition: Point.h:145
static Raster * make()
It creates and returns an empty raster with default raster driver.
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
void setOutput(std::map< std::string, std::string > &dsinfo)
It sets the Datasource that is being used to save TIN.
void setY(const double &y)
It sets the Point y-coordinate value.
Definition: Point.h:159
te::rst::Raster * m_rst
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
double m_resy
grid resolution in X and Y
void nearestNeighborSearch(const kdKey &key, std::vector< kdDataItem > &report, std::vector< double > &sqrDists, const std::size_t &k) const
It searches the nearest data in nodes: you must pass an array of kdDataItem of size "k" with coordina...
double getHeight() const
It returns the envelope height.
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
void setZ(const double &z)
It sets the Point z-coordinate value.
Definition: Point.h:173
double m_tolerance
tolerance used to simplify lines