All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Utils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 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/Utils.cpp
22 
23  \brief Utility functions for the raster module.
24 */
25 
26 // TerraLib
27 #include "../datatype/Enums.h"
28 #include "../geometry/Coord2D.h"
29 #include "BandIterator.h"
30 #include "Exception.h"
31 #include "RasterFactory.h"
32 #include "Utils.h"
33 
34 // Boost
35 #include <boost/cstdint.hpp>
36 
37 // STL
38 #include <cassert>
39 
40 #include <limits>
41 
42 static int sg_pixelSize[] = { 0,
43  0,
44  0,
45  sizeof(char) * 8,
46  sizeof(unsigned char),
47  sizeof(boost::int16_t),
48  sizeof(boost::uint16_t),
49  sizeof(boost::int32_t),
50  sizeof(boost::uint32_t),
51  sizeof(boost::int64_t),
52  sizeof(boost::uint64_t),
53  sizeof(bool),
54  sizeof(float),
55  sizeof(double),
56  0,
57  0,
58  0,
59  0,
60  0,
61  0,
62  0,
63  0,
64  0,
65  sizeof(boost::int16_t) * 2,
66  sizeof(boost::int32_t) * 2,
67  sizeof(float) * 2,
68  sizeof(double) * 2,
69  0,
70  0,
71  0,
72  sizeof(unsigned char), // 4bits = 4/8 sizeof(unsigned char)
73  sizeof(unsigned char), // 2bits = 2/8 sizeof(unsigned char)
74  sizeof(unsigned char) // 1bit = 1/8 sizeof(unsigned char)
75  };
76 
77 int te::rst::GetPixelSize(int datatype)
78 {
79  return sg_pixelSize[datatype];
80 }
81 
82 std::vector<te::rst::BandProperty*> te::rst::GetBandProperties(const std::map<std::string, std::string>& rinfo)
83 {
84  std::size_t nBands;
85  int tBands;
86  std::vector<te::rst::BandProperty*> bprops;
87 
88  std::map<std::string, std::string>::const_iterator it = rinfo.find("NBANDS");
89 
90  if(it == rinfo.end())
91  throw Exception(("Number of bands must be set!"));
92 
93  nBands = atoi(it->second.c_str());
94 
95  it = rinfo.find("BANDSTYPE");
96 
97  if(it == rinfo.end())
98  throw Exception(("Data type of bands must be set!"));
99 
100  tBands = atoi(it->second.c_str());
101 
102  for (std::size_t b = 0; b < nBands; b++)
103  bprops.push_back(new te::rst::BandProperty(b, tBands));
104 
105  return bprops;
106 }
107 
108 te::rst::Grid* te::rst::GetGrid(const std::map<std::string, std::string>& rinfo)
109 {
110  unsigned nCols, nRows;
111  double resX = 1.0, resY = 1.0, ulX =0.0, ulY=0.0;
112  int srid = TE_UNKNOWN_SRS;
113  te::gm::Coord2D* ulc;
114 
115  std::map<std::string, std::string>::const_iterator it = rinfo.find("NCOLS");
116 
117  if(it == rinfo.end())
118  throw Exception(("Number of columns must be set!"));
119 
120  nCols = atoi(it->second.c_str());
121 
122  it = rinfo.find("NROWS");
123 
124  if(it == rinfo.end())
125  throw Exception(("Number of rows must be set!"));
126 
127  nRows = atoi(it->second.c_str());
128 
129  it = rinfo.find("RESX");
130  if(it != rinfo.end())
131  resX = atof(it->second.c_str());
132 
133  it = rinfo.find("RESY");
134  if(it != rinfo.end())
135  resY = atof(it->second.c_str());
136 
137  it = rinfo.find("SRID");
138  if(it != rinfo.end())
139  srid = atoi(it->second.c_str());
140 
141  it = rinfo.find("ULX");
142  if(it != rinfo.end())
143  ulX = atof(it->second.c_str());
144 
145  it = rinfo.find("ULY");
146  if(it != rinfo.end())
147  ulY = atof(it->second.c_str());
148 
149  ulc = new te::gm::Coord2D(ulX, ulY);
150 
151  return (new te::rst::Grid(nCols, nRows, resX, resY, ulc, srid));
152 }
153 
155 {
156  assert(rin.getNumberOfBands() == rout.getNumberOfBands());
158 
159  const std::size_t nbands = rin.getNumberOfBands();
160  const unsigned int nRows = rin.getNumberOfRows();
161  const unsigned int nCols = rin.getNumberOfColumns();
162  unsigned int row = 0;
163  unsigned int col = 0;
164  std::complex< double > value;
165 
166  for(std::size_t b = 0; b < nbands; b++)
167  {
168  if(rin.getBand(b)->getProperty()->getType() == rout.getBand(b)->getProperty()->getType())
169  {
170  Copy(*rin.getBand(b), *rout.getBand(b));
171  }
172  else
173  {
174  const te::rst::Band& bin = *rin.getBand(b);
175  te::rst::Band& bout = *rout.getBand(b);
176 
177  for(row = 0 ; row < nRows ; ++row)
178  for(col = 0 ; col < nCols ; ++col)
179  {
180  bin.getValue(col, row, value);
181 
182  bout.setValue(col, row, value);
183  }
184  }
185  }
186 }
187 
189 {
190  assert(*bin.getRaster()->getGrid() == *bout.getRaster()->getGrid());
191 
192 // when both bands have the same data type
193  if (bin.getProperty()->getType() == bout.getProperty()->getType())
194  {
195  unsigned char* buffer = new unsigned char[bin.getBlockSize()];
196 
197  int nblocksx = bin.getProperty()->m_nblocksx;
198  int nblocksy = bin.getProperty()->m_nblocksy;
199 
200  const int blkw = bin.getProperty()->m_blkw;
201  const int blkh = bin.getProperty()->m_blkh;
202 
203  // when both rasters have the same block size, copy the entire blocks from in to out
204  if((blkw == bout.getProperty()->m_blkw) &&
205  (blkh == bout.getProperty()->m_blkh))
206  {
207  for(int y = 0; y < nblocksy; ++y)
208  {
209  for(int x = 0; x < nblocksx; ++x)
210  {
211  bin.read(x, y, buffer);
212  bout.write(x, y, buffer);
213  }
214  }
215  }
216  // get all values from input block, and copy pixel by pixel to the output band
217  else
218  {
219  std::complex<double> value;
220 
221  const unsigned int ncols = bin.getRaster()->getNumberOfColumns();
222  const unsigned int nrows = bin.getRaster()->getNumberOfRows();
223 
224  for(int y = 0; y < nblocksy; ++y)
225  {
226  for(int x = 0; x < nblocksx; ++x)
227  {
228  unsigned int w = blkw * (x + 1);
229 
230  w = w > ncols ? ncols : w;
231 
232  unsigned int h = blkh * (y + 1);
233 
234  h = h > nrows ? nrows : h;
235 
236  for(int r = blkh * y; r < (int)h; ++r)
237  {
238  for(int c = blkw * x; c < (int)w; ++c)
239  {
240  bin.getValue(c, r, value);
241 
242  bout.setValue(c, r, value);
243  }
244  }
245  }
246  }
247  }
248 
249  delete [] buffer;
250  }
251 // if bands have different data types, use iterator
252  else
253  {
255 
257 
258  while(rit != ritend)
259  {
260  bout.setValue(rit.getColumn(), rit.getRow(), *rit);
261 
262  ++rit;
263  }
264  }
265 }
266 
267 void te::rst::Copy(unsigned int drow, unsigned int dcolumn, unsigned int height, unsigned int width, const Raster& rin, Raster& rout)
268 {
269  assert(drow + height <= rin.getNumberOfRows());
270  assert(dcolumn + width <= rin.getNumberOfColumns());
271 
272 // define variables for interpolation
273  std::vector<std::complex<double> > v;
274 
275  for (unsigned r = drow; r < drow + height; r++)
276  {
277  for (unsigned c = dcolumn; c < dcolumn + width; c++)
278  {
279  te::gm::Coord2D inputGeo = rin.getGrid()->gridToGeo(c, r);
280 
281  te::gm::Coord2D outputGrid = rout.getGrid()->geoToGrid(inputGeo.x, inputGeo.y);
282 
283  int x = Round(outputGrid.x);
284  int y = Round(outputGrid.y);
285 
286  if((x >=0 && x < (int)rout.getNumberOfColumns()) && (y >=0 && y < (int)rout.getNumberOfRows()))
287  {
288  rin.getValues(c, r, v);
289  rout.setValues(x, y, v);
290  }
291  }
292  }
293 }
294 
295 int te::rst::Round(double val)
296 {
297  if (val>=0)
298  return (int)(val+.5);
299  else
300  return (int)(val-.5);
301 }
302 
304  const std::string& uri,
305  const std::string &rType)
306 {
307  std::map<std::string, std::string> rasterInfo;
308  rasterInfo["URI"] = uri;
309 
310  std::vector<te::rst::BandProperty*> bandsProperties;
311 
312  unsigned int bandIndex = 0;
313 
314  for(bandIndex = 0; bandIndex < rin.getNumberOfBands(); ++bandIndex)
315  {
316  bandsProperties.push_back(new te::rst::BandProperty(*(rin.getBand(bandIndex )->getProperty())));
317  }
318 
319  te::rst::RasterPtr outRasterPtr;
320 
321  outRasterPtr.reset( te::rst::RasterFactory::make( rType, new te::rst::Grid(*(rin.getGrid())), bandsProperties, rasterInfo, 0, 0));
322 
323  if(outRasterPtr.get() == 0)
324  return outRasterPtr;
325 
326  Copy(rin, *outRasterPtr);
327 
328  return outRasterPtr;
329 }
330 
331 void te::rst::GetDataTypeRanges( const int& dataType, double& min, double& max )
332 {
333  switch( dataType )
334  {
335  case te::dt::R4BITS_TYPE:
336  min = 0;
337  max = 15;
338  break;
339 
340  case te::dt::R2BITS_TYPE:
341  min = 0;
342  max = 3;
343  break;
344 
345  case te::dt::R1BIT_TYPE:
346  min = 0;
347  max = 1;
348  break;
349 
350  case te::dt::UCHAR_TYPE:
351  min = 0;
352  max = 255;
353  break;
354 
355  case te::dt::CHAR_TYPE:
356  min = -127;
357  max = 127;
358  break;
359 
360  case te::dt::UINT16_TYPE:
361  min = 0;
362  max = (double)std::numeric_limits<unsigned short int>::max();
363  break;
364 
365  case te::dt::INT16_TYPE:
366  min = (double)std::numeric_limits<short int>::min();
367  max = (double)std::numeric_limits<short int>::max();
368  break;
369 
370  case te::dt::UINT32_TYPE:
371  min = 0;
372  max = (double)std::numeric_limits<unsigned int>::max();
373  break;
374 
375  case te::dt::INT32_TYPE:
376  min = (double)std::numeric_limits<int>::min();
377  max = (double)std::numeric_limits<int>::max();
378  break;
379 
380  case te::dt::FLOAT_TYPE:
381  min = -(double)std::numeric_limits< float >::max();
382  max = (double)std::numeric_limits< float >::max();
383  break;
384 
385  case te::dt::DOUBLE_TYPE:
386  min = -std::numeric_limits< double >::max();
387  max = std::numeric_limits< double >::max();
388  break;
389 
390  case te::dt::CINT16_TYPE:
391  min = (double)std::numeric_limits<short int>::min();
392  max = (double)std::numeric_limits<short int>::max();
393  break;
394 
395  case te::dt::CINT32_TYPE:
396  min = (double)std::numeric_limits<int>::min();
397  max = (double)std::numeric_limits<int>::max();
398  break;
399 
400  case te::dt::CFLOAT_TYPE:
401  min = -(double)std::numeric_limits< float >::max();
402  max = (double)std::numeric_limits< float >::max();
403  break;
404 
406  min = -std::numeric_limits< double >::max();
407  max = std::numeric_limits< double >::max();
408  break;
409 
410  default:
411  throw te::rst::Exception("Invalid data type");
412  }
413 }
414 
415 void te::rst::FillRaster(te::rst::Raster* rin, const std::complex<double>& value)
416 {
417  for (unsigned int b = 0; b < rin->getNumberOfBands(); b++)
418  te::rst::FillBand(rin->getBand(b), value);
419 }
420 
421 void te::rst::FillBand(te::rst::Band* bin, const std::complex<double>& value)
422 {
423  for (unsigned int r = 0; r < bin->getRaster()->getNumberOfRows(); r++)
424  for (unsigned int c = 0; c < bin->getRaster()->getNumberOfColumns(); c++)
425  bin->setValue(c, r, value);
426 }
virtual void setValues(unsigned int c, unsigned int r, const std::vector< double > &values)
Sets the imaginary attribute values in all complex bands of a cell.
Definition: Raster.cpp:286
unsigned int getRow() const
Returns the current row in iterator.
Definition: BandIterator.h:389
TERASTEREXPORT void FillBand(te::rst::Band *bin, const std::complex< double > &value)
Fill a Raster Band with provided value.
Definition: Utils.cpp:421
double y
y-coordinate.
Definition: Coord2D.h:87
TERASTEREXPORT void GetDataTypeRanges(const int &dataType, double &min, double &max)
Return the values range of a given data type.
Definition: Utils.cpp:331
unsigned int getColumn() const
Returns the current column in iterator.
Definition: BandIterator.h:394
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
A raster band description.
Definition: BandProperty.h:61
double x
x-coordinate.
Definition: Coord2D.h:86
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
void Copy(const std::vector< T * > &src, std::vector< T * > &dst)
This function can be applied to a vector of pointers. It will copy element by element through its cop...
Definition: STLUtils.h:255
TERASTEREXPORT te::rst::RasterPtr CreateCopy(const te::rst::Raster &rin, const std::string &uri, const std::string &rType=std::string("GDAL"))
Create a new raster from existing one.
Definition: Utils.cpp:303
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
virtual void getValues(unsigned int c, unsigned int r, std::vector< double > &values) const
Returns the imaginary attribute values in all complex bands of a cell.
Definition: Raster.cpp:258
TERASTEREXPORT void Copy(const Raster &rin, Raster &rout)
Copies the pixel values from one raster to another.
Definition: Utils.cpp:154
static int sg_pixelSize[]
Definition: Utils.cpp:42
virtual void read(int x, int y, void *buffer) const =0
It reads a data block to the specified buffer.
TERASTEREXPORT void FillRaster(te::rst::Raster *rin, const std::complex< double > &value)
Fill a Raster with provided value (all bands).
Definition: Utils.cpp:415
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
This class implements an iterator to "navigate" over a single band (const).
Definition: BandIterator.h:211
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
Definition: Grid.cpp:307
static ConstBandIterator begin(const Band *b)
Returns an iterator referring to the first value of the band.
Definition: BandIterator.h:592
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Definition: Raster.cpp:89
boost::shared_ptr< Raster > RasterPtr
Definition: Raster.h:648
An exception class for the Raster module.
TERASTEREXPORT int Round(double val)
Round a double value to a integer value.
Definition: Utils.cpp:295
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:44
An abstract class for raster data strucutures.
Definition: Raster.h:71
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:370
It implements an iterator to "navigate" over a single band (const or not const).
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
Utility functions for the raster module.
virtual Raster * getRaster() const =0
Returns the associated raster.
virtual void write(int x, int y, void *buffer)=0
It writes a data block from the specified buffer.
A raster band description.
Definition: Band.h:63
Grid * getGrid()
It returns the raster grid.
Definition: Raster.cpp:94
TERASTEREXPORT int GetPixelSize(int datatype)
Returns the byte size of a given datatype.
Definition: Utils.cpp:77
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
TERASTEREXPORT Grid * GetGrid(const std::map< std::string, std::string > &rinfo)
Returns a grid based on a given raster info.
Definition: Utils.cpp:108
static Raster * make()
It creates and returns an empty raster with default raster driver.
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
Definition: Grid.cpp:301
int getType() const
It returns the data type of the elements in the band.
Definition: BandProperty.h:113
This is the abstract factory for Rasters.
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
Definition: Band.cpp:572
TERASTEREXPORT std::vector< BandProperty * > GetBandProperties(const std::map< std::string, std::string > &rinfo)
Returns a vector of band properties, based on a given raster info.
Definition: Utils.cpp:82
static ConstBandIterator end(const Band *b)
Returns an iterator referring to after the end of the iterator.
Definition: BandIterator.h:597