raster/Grid.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/raster/Grid.cpp
22 
23  \brief A rectified grid is the spatial support for raster data.
24 */
25 
26 // TerraLib
27 #include "../geometry/Coord2D.h"
28 #include "../geometry/Envelope.h"
29 #include "Grid.h"
30 #include "Exception.h"
31 
32 // STL
33 #include <algorithm>
34 #include <cmath>
35 #include <cstring>
36 
38  unsigned int nRows,
39  te::gm::Envelope* mbr,
40  int srid)
41  : m_extent(mbr),
42  m_nCols(nCols),
43  m_nRows(nRows),
44  m_srid(srid)
45 {
46  if(m_extent)
47  {
50  {
51  throw te::rst::Exception("Unable to compute affine parameters");
52  }
53  }
54  else
55  {
56  setGeoreference(te::gm::Coord2D(0, 0), srid, 1.0, 1.0);
57  computeExtent();
58  }
59 }
60 
61 te::rst::Grid::Grid(unsigned int nCols, unsigned int nRows,
62  double resX, double resY,
63  const te::gm::Coord2D* ulc, int srid)
64  : m_extent(nullptr),
65  m_nCols(nCols),
66  m_nRows(nRows),
67  m_srid(srid)
68 {
69  if(ulc)
70  setGeoreference(*ulc, srid, resX, resY);
71  else
72  setGeoreference(te::gm::Coord2D(0, 0), srid, resX, resY);
73  computeExtent();
74 }
75 
76 te::rst::Grid::Grid(unsigned int nCols, unsigned int nRows,
77  double resX, double resY,
78  te::gm::Envelope* mbr, int srid)
79  : m_extent(mbr),
80  m_nCols(nCols),
81  m_nRows(nRows),
82  m_srid(srid)
83 {
84  if(m_extent)
85  {
88  {
89  throw te::rst::Exception("Unable to compute affine parameters");
90  }
91  }
92  else
93  {
94  setGeoreference(te::gm::Coord2D(0, 0), srid, resX, resY);
95  computeExtent();
96  }
97 }
98 
99 te::rst::Grid::Grid(double resX,
100  double resY,
101  te::gm::Envelope* mbr,
102  int srid)
103  : m_extent(mbr),
104  m_nCols(0),
105  m_nRows(0),
106  m_srid(srid)
107 {
108  if( m_extent == nullptr )
109  {
110  throw te::rst::Exception("Missing extent");
111  }
112 
113  m_nCols = static_cast<unsigned int> (mbr->getWidth() / resX + 0.5);
114  m_nRows = static_cast<unsigned int> (mbr->getHeight() / resY + 0.5);
115 
118  {
119  throw te::rst::Exception("Unable to compute affine parameters");
120  }
121 }
122 
123 te::rst::Grid::Grid( const double geoTrans[], unsigned int nCols, unsigned int nRows,
124  int srid)
125  : m_extent(nullptr),
126  m_nCols(nCols),
127  m_nRows(nRows),
128  m_srid(srid)
129 {
130  setGeoreference(geoTrans, srid);
131  computeExtent();
132 }
133 
135  : m_extent(nullptr),
136  m_nCols(rhs.m_nCols),
137  m_nRows(rhs.m_nRows),
138  m_srid(rhs.m_srid)
139 {
140  operator=( rhs );
141 }
142 
144 {
145  if (m_extent)
146  {
147  delete m_extent;
148  }
149 }
150 
152 {
153  if(this != &rhs)
154  {
155  m_nCols = rhs.m_nCols;
156 
157  m_nRows = rhs.m_nRows;
158 
159  m_srid = rhs.m_srid;
160 
161  memcpy(m_geoT, rhs.m_geoT, sizeof(double) * 6);
162  memcpy(m_geoTInverse, rhs.m_geoTInverse, sizeof(double) * 6);
163 
164  if (m_extent)
165  {
166  delete m_extent;
167  m_extent = nullptr;
168  }
169  if( rhs.m_extent )
170  {
171  m_extent = new te::gm::Envelope(*rhs.m_extent);
172  }
173  else
174  {
175  computeExtent();
176  }
177  }
178 
179  return *this;
180 }
181 
183 {
184  m_nCols = nCols;
185 
188  {
189  throw te::rst::Exception("Unable to compute affine parameters");
190  }
191 }
192 
194 {
195  return m_nCols;
196 }
197 
198 void te::rst::Grid::setNumberOfRows(unsigned int nRows)
199 {
200  m_nRows = nRows;
201 
204  {
205  throw te::rst::Exception("Unable to compute affine parameters");
206  }
207 }
208 
209 unsigned int te::rst::Grid::getNumberOfRows() const
210 {
211  return m_nRows;
212 }
213 
214 void te::rst::Grid::setGeoreference(const te::gm::Coord2D& ulLocation, int srid, double resX, double resY)
215 {
216  m_srid = srid;
217 
218  const double extentWidth = ((double)m_nCols) * resX;
219  const double extentheight = ((double)m_nRows) * resY;
220 
221  if( ! computeAffineParameters( extentWidth, extentheight,
222  m_nCols, m_nRows, ulLocation.x, ulLocation.y, m_geoT, m_geoTInverse ) )
223  {
224  throw te::rst::Exception("Unable to compute affine parameters");
225  }
226 
227  computeExtent();
228 }
229 
230 void te::rst::Grid::setGeoreference(const double geoTrans[], int srid)
231 {
232  m_srid = srid;
233  m_geoT[0] = geoTrans[0];
234  m_geoT[1] = geoTrans[1];
235  m_geoT[2] = geoTrans[2];
236  m_geoT[3] = geoTrans[3];
237  m_geoT[4] = geoTrans[4];
238  m_geoT[5] = geoTrans[5];
239 
241  {
242  throw te::rst::Exception("Unable to compute the inverse affine parameters");
243  }
244 
245  computeExtent();
246 }
247 
248 const double* te::rst::Grid::getGeoreference() const
249 {
250  return m_geoT;
251 }
252 
254 {
255  assert( m_extent );
256  return m_extent->getWidth() / ((double)m_nCols );
257 }
258 
260 {
261  assert( m_extent );
262  return m_extent->getHeight() / ((double)m_nRows );
263 }
264 
266 {
267  return m_srid;
268 }
269 
271 {
272  m_srid = srid;
273 }
274 
276 {
277  return m_extent;
278 }
279 
281 {
282  return m_extent;
283 }
284 
286 {
287  te::gm::Coord2D ll = gridToGeo( -0.5, ((double)m_nRows) - 0.5 );
288  te::gm::Coord2D lr = gridToGeo( ((double)m_nCols) - 0.5, ((double)m_nRows) - 0.5 );
289  te::gm::Coord2D ur = gridToGeo( ((double)m_nCols) - 0.5, -0.5 );
290  te::gm::Coord2D ul = gridToGeo( -0.5, -0.5 );
291 
292  if(m_extent)
293  {
294  delete m_extent;
295  }
296 
297  double minX = std::min(std::min(ll.x, ul.x), std::min(lr.x, ur.x));
298  double minY = std::min(std::min(ll.y, ul.y), std::min(lr.y, ur.y));
299  double maxX = std::max(std::max(ll.x, ul.x), std::max(lr.x, ur.x));
300  double maxY = std::max(std::max(ll.y, ul.y), std::max(lr.y, ur.y));
301 
302  m_extent = new te::gm::Envelope( minX, minY, maxX, maxY);
303 }
304 
305 void te::rst::Grid::gridToGeo(const double& col, const double& row, double& x, double& y) const
306 {
307  x = col * m_geoT[0] + row * m_geoT[1] + m_geoT[2];
308  y = col * m_geoT[3] + row * m_geoT[4] + m_geoT[5];
309 }
310 
311 void te::rst::Grid::geoToGrid(const double& x, const double& y, double& col, double& row) const
312 {
313  col = x * m_geoTInverse[0] + y * m_geoTInverse[1] + m_geoTInverse[2];
314  row = x * m_geoTInverse[3] + y * m_geoTInverse[4] + m_geoTInverse[5];
315 }
316 
317 bool te::rst::Grid::operator==(const Grid& rhs) const
318 {
319  computeExtent();
320  rhs.computeExtent();
321 
322  if (!m_extent->equals(*rhs.m_extent) ||
323  m_nCols != rhs.m_nCols ||
324  m_nRows != rhs.m_nRows ||
325  m_srid != rhs.m_srid ||
326  getGeoreference()[0] != rhs.getGeoreference()[0] ||
327  getGeoreference()[1] != rhs.getGeoreference()[1] ||
328  getGeoreference()[2] != rhs.getGeoreference()[2] ||
329  getGeoreference()[3] != rhs.getGeoreference()[3] ||
330  getGeoreference()[4] != rhs.getGeoreference()[4] ||
331  getGeoreference()[5] != rhs.getGeoreference()[5])
332  return false;
333  else
334  return true;
335 }
336 
337 bool te::rst::Grid::computeAffineParameters( const double extentWidth,
338  const double extentHeight, const unsigned int nColumns,
339  const unsigned int nRows, const double extentULX,
340  const double extentULY, double* affineParamsPtr,
341  double* inverseAffineParamsPtr ) const
342 {
343  affineParamsPtr[0] = extentWidth / ((double)nColumns);
344  affineParamsPtr[1] = 0.0;
345  affineParamsPtr[2] = extentULX + ( extentWidth / static_cast<double>(nColumns) / 2.0 );
346  affineParamsPtr[3] = 0.0;
347  affineParamsPtr[4] = -1.0 * extentHeight / ((double)nRows);
348  affineParamsPtr[5] = extentULY - ( extentHeight / static_cast<double>(nRows) / 2.0 );
349 
350  return computeInverseParameters( affineParamsPtr, inverseAffineParamsPtr );
351 }
352 
353 bool te::rst::Grid::computeInverseParameters( double* const affineParamsPtr,
354  double* inverseAffineParamsPtr ) const
355 {
356  const double determinant = ( affineParamsPtr[0] * affineParamsPtr[4] ) -
357  ( affineParamsPtr[1] * affineParamsPtr[3] );
358  if( determinant == 0.0 )
359  {
360  return false;
361  }
362 
363  inverseAffineParamsPtr[0] = affineParamsPtr[4] / determinant;
364  inverseAffineParamsPtr[1] = ( -1.0 * affineParamsPtr[1] ) / determinant;
365  inverseAffineParamsPtr[2] =
366  (
367  ( affineParamsPtr[1] * affineParamsPtr[5] )
368  -
369  ( affineParamsPtr[2] * affineParamsPtr[4] )
370  )
371  /
372  determinant;
373  inverseAffineParamsPtr[3] = ( -1.0 * affineParamsPtr[3] ) / determinant;
374  inverseAffineParamsPtr[4] = ( affineParamsPtr[0] ) / determinant;
375  inverseAffineParamsPtr[5] =
376  (
377  ( -1.0 * ( affineParamsPtr[0] * affineParamsPtr[5] ) )
378  +
379  ( affineParamsPtr[3] * affineParamsPtr[2] )
380  )
381  /
382  determinant;
383 
384  return true;
385 }
An exception class for the Raster module.
unsigned int getNumberOfRows() const
Returns the grid number of rows.
te::gm::Envelope * m_extent
The grid extent.
Definition: raster/Grid.h:292
bool computeInverseParameters(double *const affineParamsPtr, double *inverseAffineParamsPtr) const
Compute inverse affine parameters.
double y
y-coordinate.
Definition: Coord2D.h:114
double x
x-coordinate.
Definition: Coord2D.h:113
int getSRID() const
Returns the grid spatial reference system identifier.
Grid & operator=(const Grid &rhs)
Assignment operator.
Grid(unsigned int nCols=0, unsigned int nRows=0, te::gm::Envelope *mbr=0, int srid=TE_UNKNOWN_SRS)
Constructor.
Definition: raster/Grid.cpp:37
double getWidth() const
It returns the envelope width.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
void setGeoreference(const te::gm::Coord2D &ulLocation, int srid, double resX, double resY)
Sets the information needed to georeference the grid.
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
unsigned int unsigned int nCols
double m_llx
Lower left corner x-coordinate.
An Envelope defines a 2D rectangular region.
int m_srid
The associated SRS.
Definition: raster/Grid.h:295
unsigned int m_nCols
Number of columns.
Definition: raster/Grid.h:293
const double * getGeoreference() const
Returns a list of 6 coefficients describing an affine transformation to georeference a grid...
bool operator==(const Grid &rhs) const
Equal operator.
double m_geoT[6]
A list of 6 coefficients describing an affine transformation to georeference a grid.
Definition: raster/Grid.h:296
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
void setNumberOfRows(unsigned int nRows)
Sets the grid number of rows.
bool equals(const Envelope &rhs) const
It returns true if the envelopes are "spatially equal".
bool computeAffineParameters(const double extentWidth, const double extentHeight, const unsigned int nColumns, const unsigned int nRows, const double extentULX, const double extentULY, double *affineParamsPtr, double *inverseAffineParamsPtr) const
Compute affine parameters from the given input parameters.
void setNumberOfColumns(unsigned int nCols)
Sets the grid number of columns.
~Grid()
Destructor.
A rectified grid is the spatial support for raster data.
double m_ury
Upper right corner y-coordinate.
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
void setSRID(int srid)
Just sets the grid spatial reference system identifier.
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
double getHeight() const
It returns the envelope height.
unsigned int col
void computeExtent() const
Computes the geographic extension of the grid.
double m_geoTInverse[6]
A list of 6 coefficients describing an inverse affine transformation to georeference a grid...
Definition: raster/Grid.h:297
unsigned int m_nRows
Number of rows.
Definition: raster/Grid.h:294