TINCalculateGrid.cpp
Go to the documentation of this file.
1 /*!
2 \file terralib/mnt/core/TINCalculateGrid.cpp
3 
4 \brief This file contains a class to calculate a grid from TIN.
5 
6 */
7 
8 #include "TINCalculateGrid.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 <limits>
18 #include <cmath>
19 
21 {
22  delete m_rst;
23 }
24 
25 /*!
26 \brief Method that generates a regular Grid from a given TIN
27 \param grid is a pointer to the grid that will be created
28 \param gridtype is the type of interpolator fitted to each triangle
29 \return TRUE if the regular grid is created or FALSE otherwise
30 */
31 
33 {
35 
36 //Create greater box 1/2 resolution
37  double rx1 = m_env.getLowerLeftX() - m_resx/2.;
38  double ry2 = m_env.getUpperRightY() + m_resy/2.;
39 
40  unsigned int outputWidth = (unsigned int)ceil(m_env.getWidth() / m_resx);
41  unsigned int outputHeight = (unsigned int)ceil(m_env.getHeight() / m_resy);
42 
43  te::gm::Coord2D ulc(rx1, ry2);
44 
45  te::rst::Grid* grid = new te::rst::Grid(outputWidth, outputHeight, m_resx, m_resy, &ulc, m_srid);
46 
47  std::vector<te::rst::BandProperty*> bands;
48 
49  bands.push_back(new te::rst::BandProperty(0, te::dt::DOUBLE_TYPE, "DTM GRID"));
50  bands[0]->m_nblocksx = 1;
51  bands[0]->m_nblocksy = (int)outputHeight;
52  bands[0]->m_blkw = (int)outputWidth;
53  bands[0]->m_blkh = 1;
54  bands[0]->m_colorInterp = te::rst::GrayIdxCInt;
55  bands[0]->m_noDataValue = m_nodatavalue;
56 
57  // create raster
58  std::unique_ptr<te::rst::Raster> rst(te::rst::RasterFactory::make("GDAL", grid, bands, m_dsinfo));
59 
60  m_rst = rst.release();
61 
62  double dummyvalue = m_rst->getBand(0)->getProperty()->m_noDataValue;
63 
64  int32_t fbnode = 0;
65 
66  if (m_gridtype == Quintico) //Quintic Surface Adjust without breaklines
67  {
68  fbnode = m_fbnode;
69  m_fbnode = 0;
70  }
71 
72  if ((m_gridtype == QuinticoBrkLine) || (m_gridtype == Quintico)) //Quintic Surface Adjust
73  if (!m_nsderiv.size())
74  // Calculate derivatives
75  if (!NodeDerivatives())
76  return false;
77 
78  int32_t neighsid[3];
79  int32_t nodesid[3];
83  int32_t flin, llin, fcol, lcol;
84  short j;
85  double coef[27];
86 
87  te::common::TaskProgress task("Generating DTM...", te::common::TaskProgress::UNDEFINED, (int)m_triang.size());
88 
89  // To each triangle
90  for (unsigned int i = 0; i < m_triang.size(); i++)
91  { // Find Triangle Box
92  if (!task.isActive())
93  return false;
94  task.pulse();
95  if (!NodesId((int32_t)i, nodesid))
96  continue;
97  if (!DefineInterLinesColumns(nodesid, flin, llin, fcol, lcol))
98  continue;
99  for (j = 0; j < 3; j++)
100  {
101  p3da[j].setX(m_node[(unsigned int)nodesid[j]].getNPoint().getX());
102  p3da[j].setY(m_node[(unsigned int)nodesid[j]].getNPoint().getY());
103  p3da[j].setZ(m_node[(unsigned int)nodesid[j]].getZ());
104  }
105 
106  if ((p3da[0].getZ() == dummyvalue) ||
107  (p3da[1].getZ() == dummyvalue) ||
108  (p3da[2].getZ() == dummyvalue))
109  {
110  FillGridValue((int32_t)i, flin, llin, fcol, lcol, dummyvalue);
111  }
112  else if ((p3da[0].getZ() == p3da[1].getZ()) &&
113  (p3da[0].getZ() == p3da[2].getZ()) && (m_gridtype == Linear))
114  FillGridValue((int32_t)i, flin, llin, fcol, lcol, p3da[0].getZ());
115  else if ((m_gridtype == Quintico) || (m_gridtype == QuinticoBrkLine))
116  {
117  if (!NeighborsId((int32_t)i, neighsid))
118  continue;
119  for (j = 0; j < 3; j++)
120  if (neighsid[j] == -1)
121  break;
122  if (j == 3)
123  {
124  if (DefineAkimaCoeficients((int32_t)i, nodesid, p3da, coef))
125  FillGridQuintic((int32_t)i, flin, llin, fcol, lcol, coef);
126  }
127  else
128  FillGridValue((int32_t)i, flin, llin, fcol, lcol, m_nodatavalue);
129  }
130  else
131  FillGridLinear((int32_t)i, p3da, flin, llin, fcol, lcol);
132  }
133 
134  if (m_gridtype == Quintico) //Quintic Surface Adjust without breaklines
135  m_fbnode = fbnode;
136 
137  return true;
138 }
139 
140 
142  std::string inDsetName,
143  std::unique_ptr<te::da::DataSetType> inDsetType)
144 {
145  m_inDsrc = inDsrc;
146  m_inDsetName = inDsetName;
147  m_inDsetType = std::move(inDsetType);
148 }
149 
150 void te::mnt::TINCalculateGrid::setOutput(std::map<std::string, std::string> &dsinfo)
151 {
152  m_dsinfo = dsinfo;
153 }
154 
155 void te::mnt::TINCalculateGrid::setParams(double resx, double resy, Interpolator gt)
156 {
157  m_resx = resx;
158  m_resy = resy;
159  m_gridtype = gt;
160 }
161 
162 
163 
164 /*!
165 \brief Method that fills the grid locations, inside a triangle, with a zvalue linearly evaluated
166 \param grid is a pointer to a grid object
167 \param triid is the triangle identification number
168 \param flin and llin are the first and the last lines (rows) of the grid
169 \param fcol and lcol are the first and the last columns of the grid
170 \param zvalue is the z value to be stored in the grid inside the triangle region
171 \return TRUE always
172 */
173 
174 bool te::mnt::TINCalculateGrid::FillGridLinear(int32_t triid, te::gm::Point *p3da, int32_t flin, int32_t llin, int32_t fcol, int32_t lcol)
175 {
177  te::gm::Coord2D cg;
178  double x1_x0, x2_x0, y1_y0, y2_y0, z1_z0, z2_z0,
179  detx, dety, detz;
180  double zvalue;
181  int32_t nlin, ncol;
182  x1_x0 = p3da[1].getX() - p3da[0].getX();
183  x2_x0 = p3da[2].getX() - p3da[0].getX();
184  y1_y0 = p3da[1].getY() - p3da[0].getY();
185  y2_y0 = p3da[2].getY() - p3da[0].getY();
186  z1_z0 = (double)(p3da[1].getZ() - p3da[0].getZ());
187  z2_z0 = (double)(p3da[2].getZ() - p3da[0].getZ());
188  for (nlin = flin; nlin <= llin; nlin++){
189  for (ncol = fcol; ncol <= lcol; ncol++){
190  cg = m_rst->getGrid()->gridToGeo(ncol, nlin);
191  pg.setX(cg.getX());
192  pg.setY(cg.getY());
193  if (!(ContainsPoint(triid, pg)))
194  continue;
195  detx = ((y1_y0 * z2_z0) - (y2_y0 * z1_z0)) *
196  (pg.getX() - p3da[0].getX());
197  dety = ((z1_z0 * x2_x0) - (z2_z0 * x1_x0)) *
198  (pg.getY() - p3da[0].getY());
199  detz = (x1_x0 * y2_y0) - (x2_x0 * y1_y0);
200 
201  zvalue = ((detx + dety - detz * p3da[0].getZ()) / -detz);
202 
203  m_rst->setValue((unsigned int)ncol, (unsigned int)nlin, zvalue);
204  }
205  }
206 
207  return true;
208 }
209 
210 
211 /*!
212 \brief Method that fills the grid locations, inside a triangle, with a zvalue evaluated by a quintic polynomium
213 \param grid is a pointer to a grid object
214 \param triid is the triangle identification number
215 \param p3da is a pointer to a Point3d object, vector with 3D samples (not used in this method)
216 \param flin and llin are the first and the last lines (rows) of the grid
217 \param fcol and lcol are the first and the last columns of the grid
218 \param zvalue is the z value to be stored in the grid inside the triangle region
219 \return TRUE always
220 */
221 
222 bool te::mnt::TINCalculateGrid::FillGridQuintic(int32_t triid, int32_t flin, int32_t llin, int32_t fcol, int32_t lcol, double *coef)
223 {
225  te::gm::Coord2D cg;
226  double u, v, ap, bp, cp, dp, x0, y0,
227  p00, p01, p02, p03, p04, p05,
228  p10, p11, p12, p13, p14,
229  p20, p21, p22, p23,
230  p30, p31, p32,
231  p40, p41, p50,
232  p0, p1, p2, p3, p4;
233  double zvalue;
234  int32_t nlin, ncol;
235 
236  // Polynomial coefficients
237  p00 = coef[0]; p01 = coef[1]; p02 = coef[2]; p03 = coef[3]; p04 = coef[4]; p05 = coef[5];
238  p10 = coef[6]; p11 = coef[7]; p12 = coef[8]; p13 = coef[9]; p14 = coef[10];
239  p20 = coef[11]; p21 = coef[12]; p22 = coef[13]; p23 = coef[14];
240  p30 = coef[15]; p31 = coef[16]; p32 = coef[17];
241  p40 = coef[18]; p41 = coef[19];
242  p50 = coef[20];
243 
244  // Coefficients of conversion from XY to UV coordinates
245  ap = coef[21]; bp = coef[22]; cp = coef[23]; dp = coef[24];
246  x0 = coef[25]; y0 = coef[26];
247 
248  for (nlin = flin; nlin <= llin; nlin++)
249  {
250  for (ncol = fcol; ncol <= lcol; ncol++)
251  {
252  cg = m_rst->getGrid()->gridToGeo(ncol, nlin);
253  pg.setX(cg.getX());
254  pg.setY(cg.getY());
255  if (!(ContainsPoint(triid, pg)))
256  continue;
257  // Converts point from XY to UV
258  u = ap*(pg.getX() - x0) +
259  bp*(pg.getY() - y0);
260  v = cp*(pg.getX() - x0) +
261  dp*(pg.getY() - y0);
262 
263  // Evaluates the polynomial
264  p0 = p00 + v*(p01 + v*(p02 + v*(p03 + v*(p04 + v*p05))));
265  p1 = p10 + v*(p11 + v*(p12 + v*(p13 + v*p14)));
266  p2 = p20 + v*(p21 + v*(p22 + v*p23));
267  p3 = p30 + v*(p31 + v*p32);
268  p4 = p40 + v*p41;
269 
270  zvalue = p0 + u*(p1 + u*(p2 + u*(p3 + u*(p4 + u*p50))));
271  m_rst->setValue((unsigned int)ncol, (unsigned int)nlin, zvalue);
272  }
273  }
274 
275  return true;
276 }
277 
278 
int m_srid
Attribute with spatial reference information.
Definition: Tin.h:596
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.
bool FillGridLinear(int32_t triid, te::gm::Point *p3da, int32_t flin, int32_t llin, int32_t fcol, int32_t lcol)
Method that fills the grid locations, inside a triangle, with a zvalue linearly evaluated.
bool ContainsPoint(int32_t triangId, te::gm::Point &pt)
Method that verifies if a triangle contains a given point.
Definition: Tin.cpp:461
Index into a lookup table.
bool FillGridValue(int32_t triid, int32_t flin, int32_t llin, int32_t fcol, int32_t lcol, double zvalue)
Method that fills the grid locations, inside a triangle, with a zvalue.
Definition: Tin.cpp:3256
bool NodesId(int32_t triangId, int32_t *nodeIds)
Method that reads the identification number of the nodes of a given triangle.
Definition: Tin.cpp:913
boost::shared_ptr< DataSource > DataSourcePtr
double m_resx
Definition: Tin.h:627
A raster band description.
Definition: BandProperty.h:61
bool NodeDerivatives()
Method that calculates the first and second derivatives in the nodes of a given triangle.
Definition: Tin.cpp:1743
te::gm::Envelope m_env
Attribute used to restrict the area to generate the samples.
Definition: Tin.h:598
bool run()
Method that generates a regular Grid from a given TIN.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
double getWidth() const
It returns the envelope width.
bool FillGridQuintic(int32_t triid, int32_t flin, int32_t llin, int32_t fcol, int32_t lcol, double *coef)
Method that fills the grid locations, inside a triangle, with a zvalue evaluated by a quintic polynom...
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_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
int32_t m_fbnode
First break node number.
Definition: Tin.h:617
std::vector< TinTriang > m_triang
Triangulation triangles vector.
Definition: Tin.h:605
bool DefineInterLinesColumns(int32_t *nodesid, int32_t &flin, int32_t &llin, int32_t &fcol, int32_t &lcol)
Method that calculates the lines and the columns intercepted by a triangle.
Definition: Tin.cpp:3279
Utility functions for MNT support.
double m_nodatavalue
Definition: Tin.h:622
std::vector< TinNode > m_nsderiv
Definition: Tin.h:613
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
bool NeighborsId(int32_t triangId, int32_t *neighsId)
Definition: Tin.cpp:950
BandProperty * getProperty()
Returns the band property.
std::unique_ptr< te::da::DataSetType > m_inDsetType
list bands
Definition: compose.py:2
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
std::map< std::string, std::string > m_dsinfo
double m_resy
Definition: Tin.h:627
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
const double & getZ() const
It returns the Point z-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:166
te::rst::Raster * m_rst
Definition: Tin.h:626
double getX() const
It returns the x-coordinate.
Definition: Coord2D.h:102
This file contains a class to calculate a grid from a TIN. Adapted from SPRING.
void setX(const double &x)
It sets the Point x-coordinate value.
Definition: Point.h:145
std::vector< TinNode > m_node
Triangulation nodes vector.
Definition: Tin.h:606
te::da::DataSourcePtr m_inDsrc
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 setInput(te::da::DataSourcePtr inDsrc, std::string inDsetName, std::unique_ptr< te::da::DataSetType > inDsetType)
It sets the Datasource that is being used to generate TIN.
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
bool LoadTin(te::da::DataSourcePtr &inDsrc, std::string &inDsetName, double zmin=std::numeric_limits< double >::min(), double zmax=std::numeric_limits< double >::max())
Method used to load a triangular network (TIN)
Definition: Tin.cpp:1624
void setParams(double resx, double resy, Interpolator gt)
It sets the parameters that is being used to save TIN.
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
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
double getHeight() const
It returns the envelope height.
bool DefineAkimaCoeficients(int32_t triid, double *coef)
Method that defines the coefficients of the Akima polynomium fitted in a given triangle.
Definition: Tin.cpp:2991
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