TiePointsLocatorStrategy.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/rp/TiePointsLocatorStrategy.cpp
22  \brief Tie-Pointsr locator strategy.
23 */
24 
26 #include "../raster/Band.h"
27 #include "../raster/BandProperty.h"
28 #include "../raster/Grid.h"
29 #include "../raster/RasterFactory.h"
30 
31 #include <memory.h>
32 
33 namespace te
34 {
35  namespace rp
36  {
38 
40 
41  const std::string& TiePointsLocatorStrategy::getErrorMessage() const
42  {
43  return m_errorMessage;
44  }
45 
47  const TiePointsLocatorStrategy&) = default;
48 
50  const TiePointsLocatorStrategy&) = default;
51 
53  {
54  m_errorMessage.clear();
55  }
56 
58  te::rst::Raster const* rasterPtr,
59  const std::vector< unsigned int >& rasterBands,
60  te::rst::Raster const* maskRasterPtr,
61  const unsigned int maskRasterBand,
62  const unsigned int rasterTargetAreaLineStart,
63  const unsigned int rasterTargetAreaColStart,
64  const unsigned int rasterTargetAreaWidth,
65  const unsigned int rasterTargetAreaHeight,
66  const double desiredRescaleFactorX,
67  const double desiredRescaleFactorY,
68  const te::rst::Interpolator::Method rasterInterpMethod,
69  const unsigned char maxMemPercentUsage,
70  std::vector< boost::shared_ptr< FloatsMatrix > >& loadedRasterData,
71  UCharsMatrix& loadedMaskRasterData,
72  double& achievedRescaleFactorX,
73  double& achievedRescaleFactorY )
74  {
75  // Allocating the output matrixes
76 
77  const unsigned int rescaledNLines = (unsigned int)(
78  ((double)rasterTargetAreaHeight) * desiredRescaleFactorY );
79  const unsigned int rescaledNCols = (unsigned int)(
80  ((double)rasterTargetAreaWidth) * desiredRescaleFactorX );
81 
82  achievedRescaleFactorX = ((double)rescaledNCols) / ((double)rasterTargetAreaWidth);
83  achievedRescaleFactorY = ((double)rescaledNLines) / ((double)rasterTargetAreaHeight);
84 
85  {
86  unsigned char maxMemPercentUsagePerMatrix = MAX( 1u, maxMemPercentUsage /
87  (
88  ( maskRasterPtr ? 1 : 0 )
89  +
90  ((unsigned int)rasterBands.size()) )
91  );
92 
93  loadedRasterData.resize( rasterBands.size() );
94 
95  for( unsigned int rasterBandsIdx = 0 ; rasterBandsIdx < rasterBands.size() ;
96  ++rasterBandsIdx )
97  {
98  loadedRasterData[ rasterBandsIdx ].reset( new FloatsMatrix );
99  TERP_TRUE_OR_RETURN_FALSE( loadedRasterData[ rasterBandsIdx ]->reset(
100  rescaledNLines, rescaledNCols, FloatsMatrix::AutoMemPol,
101  maxMemPercentUsagePerMatrix ),
102  "Cannot allocate image 1 matrix" );
103  maxMemPercentUsagePerMatrix *= 2;
104  }
105 
106  if( maskRasterPtr )
107  {
108  TERP_TRUE_OR_RETURN_FALSE( loadedMaskRasterData.reset(
109  rescaledNLines, rescaledNCols,
110  UCharsMatrix::AutoMemPol, maxMemPercentUsagePerMatrix ),
111  "Cannot allocate image 1 mask matrix" );
112  }
113  }
114 
115  // loading mask data
116 
117  if( maskRasterPtr )
118  {
119  te::rst::Band const* inMaskRasterBand = maskRasterPtr->getBand( maskRasterBand );
120  assert( inMaskRasterBand );
121 
122  unsigned char* outMaskLinePtr = nullptr;
123  unsigned int outLine = 0;
124  unsigned int outCol = 0;
125  unsigned int inLine = 0;
126  unsigned int inCol = 0;
127  double value = 0;
128 
129  for( outLine = 0 ; outLine < rescaledNLines ; ++outLine )
130  {
131  inLine = (unsigned int)( ( ( (double)outLine ) /
132  desiredRescaleFactorY ) + ( (double)rasterTargetAreaLineStart ) );
133 
134  outMaskLinePtr = loadedMaskRasterData[ outLine ];
135 
136  for( outCol = 0 ; outCol < rescaledNCols ; ++outCol )
137  {
138  inCol = (unsigned int)( ( ( (double)outCol ) /
139  desiredRescaleFactorX ) + ( (double)rasterTargetAreaColStart ) );
140 
141  inMaskRasterBand->getValue( inCol, inLine, value );
142 
143  if( value == 0 )
144  outMaskLinePtr[ outCol ] = 0;
145  else
146  outMaskLinePtr[ outCol ] = 255;
147  }
148  }
149  }
150 
151  // loading raster data
152  {
153  const double rasterTargetAreaLineStartDouble = (double)
154  rasterTargetAreaLineStart;
155  const double rasterTargetAreaColStartDouble = (double)
156  rasterTargetAreaColStart;
157  te::rst::Interpolator interpInstance( rasterPtr, rasterInterpMethod );
158  float* floatLinePtr = nullptr;
159  double* doubleLinePtr = nullptr;
160  unsigned int outLine = 0;
161  unsigned int outCol = 0;
162  double inLine = 0;
163  double inCol = 0;
164  std::complex< double > interpolatedValue;
165  unsigned int bandIdx = 0;
166  double bandMin = 0;
167  double bandMax = 0;
168  double gain = 0;
169 
170  DoublesMatrix auxBandData;
171  TERP_TRUE_OR_RETURN_FALSE( auxBandData.reset(
172  rescaledNLines, rescaledNCols, DoublesMatrix::AutoMemPol, 40 ),
173  "Cannot allocate auxiliar matrix" );
174 
175  for( unsigned int rasterBandsIdx = 0 ; rasterBandsIdx < rasterBands.size() ;
176  ++rasterBandsIdx )
177  {
178  bandIdx= rasterBands[ rasterBandsIdx ];
179  bandMin = DBL_MAX;
180  bandMax = -1.0 * DBL_MAX;
181 
182  for( outLine = 0 ; outLine < rescaledNLines ; ++outLine )
183  {
184  inLine = ( ( (double)outLine ) / desiredRescaleFactorY ) +
185  rasterTargetAreaLineStartDouble;
186 
187  doubleLinePtr = auxBandData[ outLine ];
188 
189  for( outCol = 0 ; outCol < rescaledNCols ; ++outCol )
190  {
191  inCol = ( ( (double)outCol ) / desiredRescaleFactorX ) +
192  rasterTargetAreaColStartDouble;
193 
194  interpInstance.getValue( inCol, inLine, interpolatedValue,
195  bandIdx );
196 
197  doubleLinePtr[ outCol ] = interpolatedValue.real();
198 
199  if( interpolatedValue.real() > bandMax ) bandMax = interpolatedValue.real();
200  if( interpolatedValue.real() < bandMin ) bandMin = interpolatedValue.real();
201  }
202  }
203 
204  if( bandMin == bandMax )
205  gain = 0.0;
206  else
207  gain = ( 1.0 / ( bandMax - bandMin ) );
208 
209  for( outLine = 0 ; outLine < rescaledNLines ; ++outLine )
210  {
211  doubleLinePtr = auxBandData[ outLine ];
212  floatLinePtr = loadedRasterData[ rasterBandsIdx ]->operator[]( outLine );
213 
214  for( outCol = 0 ; outCol < rescaledNCols ; ++outCol )
215  {
216  floatLinePtr[ outCol ] = (float)( ( doubleLinePtr[ outCol ] - bandMin ) * gain );
217  }
218  }
219  }
220  }
221 
222  return true;
223  }
224 
226  const FloatsMatrix& rasterData,
227  const InterestPointsSetT& interestPoints,
228  const std::string& tifFileName )
229  {
230  std::map<std::string, std::string> rInfo;
231  rInfo["URI"] = tifFileName + ".tif";
232 
233  std::vector<te::rst::BandProperty*> bandsProperties;
234  bandsProperties.push_back(new te::rst::BandProperty( 0, te::dt::UCHAR_TYPE, "" ));
235  bandsProperties[0]->m_colorInterp = te::rst::RedCInt;
236  bandsProperties[0]->m_noDataValue = 0;
237  bandsProperties.push_back(new te::rst::BandProperty( *bandsProperties[0] ));
238  bandsProperties[1]->m_colorInterp = te::rst::GreenCInt;
239  bandsProperties.push_back(new te::rst::BandProperty( *bandsProperties[0] ));
240  bandsProperties[2]->m_colorInterp = te::rst::BlueCInt;
241 
242  te::rst::Grid* newgrid = new te::rst::Grid( rasterData.getColumnsNumber(),
243  rasterData.getLinesNumber(), nullptr, -1 );
244 
245  std::unique_ptr< te::rst::Raster > outputRasterPtr(
246  te::rst::RasterFactory::make( "GDAL", newgrid, bandsProperties, rInfo, nullptr, nullptr));
247  TERP_TRUE_OR_THROW( outputRasterPtr.get(), "Output raster creation error");
248 
249  unsigned int line = 0;
250  unsigned int col = 0;
251  const unsigned int nLines = rasterData.getLinesNumber();
252  const unsigned int nCols = rasterData.getColumnsNumber();
253  double rasterDataMin = DBL_MAX;
254  double rasterDataMax = (-1.0) * DBL_MAX;
255  double value = 0;
256 
257  for( line = 0 ; line < nLines ; ++line )
258  for( col = 0 ; col < nCols ; ++col )
259  {
260  value = (double)rasterData[ line ][ col ];
261 
262  if( rasterDataMin > value )
263  rasterDataMin = value;
264  if( rasterDataMax < value )
265  rasterDataMax = value;
266  }
267 
268  if( rasterDataMax == rasterDataMin )
269  {
270  rasterDataMin = 0.0;
271  rasterDataMax = 1.0;
272  }
273 
274  for( line = 0 ; line < nLines ; ++line )
275  for( col = 0 ; col < nCols ; ++col )
276  {
277  value = (double)rasterData[ line ][ col ];
278  value = ( value - rasterDataMin ) / ( rasterDataMax - rasterDataMin );
279  value *= 255.0;
280  value = std::max( 0.0, value );
281  value = std::min( 255.0, value );
282 
283  outputRasterPtr->setValue( col, line, value, 0 );
284  outputRasterPtr->setValue( col, line, value, 1 );
285  outputRasterPtr->setValue( col, line, value, 2 );
286  }
287 
288  InterestPointsSetT::const_iterator itB = interestPoints.begin();
289  InterestPointsSetT::const_iterator itE = interestPoints.end();
290 
291  while( itB != itE )
292  {
293  outputRasterPtr->setValue( itB->m_x, itB->m_y, 0, 0 );
294  outputRasterPtr->setValue( itB->m_x, itB->m_y, 255, 1 );
295  outputRasterPtr->setValue( itB->m_x, itB->m_y, 0, 2 );
296 
297  ++itB;
298  }
299  }
300 
302  const InterestPointsSetT& interestPoints,
303  const std::string& fileNameBeginning )
304  {
305  const unsigned int tifLinesNumber = (unsigned int)std::sqrt( (double)
306  features.getColumnsNumber() );
307  const unsigned int featuresColsNumber = features.getColumnsNumber();
308 
309  double const* featureLinePtr = nullptr;
310 
311  InterestPointsSetT::const_iterator iIt = interestPoints.begin();
312 
313  for( unsigned int featuresIdx = 0 ; featuresIdx < features.getLinesNumber() ;
314  ++featuresIdx )
315  {
316  featureLinePtr = features[ featuresIdx ];
317 
318  std::vector<te::rst::BandProperty*> bandsProperties;
319  bandsProperties.push_back(new te::rst::BandProperty( 0, te::dt::UCHAR_TYPE, "" ));
320  bandsProperties[0]->m_colorInterp = te::rst::RedCInt;
321  bandsProperties[0]->m_noDataValue = 0;
322 
323  std::map<std::string, std::string> rInfo;
324  rInfo["URI"] = fileNameBeginning + "_" + boost::lexical_cast< std::string >( iIt->m_x )
325  + "_" + boost::lexical_cast< std::string >( iIt->m_y ) + ".tif";
326 
327  te::rst::Grid* newgrid = new te::rst::Grid( tifLinesNumber,
328  tifLinesNumber, nullptr, -1 );
329 
330  std::unique_ptr< te::rst::Raster > outputRasterPtr(
331  te::rst::RasterFactory::make( "GDAL", newgrid, bandsProperties, rInfo, nullptr, nullptr));
332  TERP_TRUE_OR_THROW( outputRasterPtr.get(), "Output raster creation error");
333 
334  unsigned int line = 0;
335  unsigned int col = 0;
336  double value = 0;
337  double min = 0;
338  double max = 0;
339  double gain = 1.0;
340 
341  for( col = 0 ; col < featuresColsNumber ; ++col )
342  {
343  if( min > featureLinePtr[ col ] ) min = featureLinePtr[ col ];
344  if( max < featureLinePtr[ col ] ) max = featureLinePtr[ col ];
345  }
346 
347  gain = 255.0 / ( max - min );
348 
349  for( line = 0 ; line < tifLinesNumber ; ++line )
350  for( col = 0 ; col < tifLinesNumber ; ++col )
351  {
352  value = featureLinePtr[ ( line * tifLinesNumber ) + col ];
353  value *= gain;
354  value -= min;
355  value = MIN( 255.0, value );
356  value = MAX( 0.0, value );
357 
358  outputRasterPtr->setValue( col, line, value, 0 );
359  }
360 
361  ++iIt;
362  }
363  }
364 
365 
367  const InterestPointsSetT& interestPoints, double& x, double& y )
368  {
369  InterestPointsSetT::const_iterator it1 = interestPoints.begin();
370  InterestPointsSetT::const_iterator it2;
371  const InterestPointsSetT::const_iterator itE = interestPoints.end();
372 
373  while( it1 != itE )
374  {
375  it2 = it1;
376  ++it2;
377 
378  while( it2 != itE )
379  {
380  if( ( it1->m_x == it2->m_x ) && ( it1->m_y == it2->m_y ) )
381  {
382  x = it1->m_x;
383  y = it1->m_y;
384  return false;
385  }
386 
387  ++it2;
388  }
389 
390  ++it1;
391  }
392 
393  return true;
394  }
395 
396  void TiePointsLocatorStrategy::setErrorMessage( const std::string& newErrorMessage )
397  {
398  m_errorMessage = newErrorMessage;
399  }
400 
401  } // end namespace rp
402 } // end namespace te
403 
This file contains include headers for the memory data source of TerraLib.
A raster band description.
Definition: BandProperty.h:61
It interpolates one pixel based on a selected algorithm. Methods currently available are Nearest Neig...
Definition: Interpolator.h:55
TiePointsLocatorStrategy & operator=(const TiePointsLocatorStrategy &)
#define MIN(a, b)
Macro that returns min between two values.
Red channel color interpretation.
void getValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Get the interpolated value at specific band.
Definition: Interpolator.h:93
InterpolationMethod
Allowed interpolation methods.
Tie-Pointsr locator strategy.
#define MAX(a, b)
Macro that returns max between two values.
std::string m_errorMessage
Current error message.
#define TERP_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged and a return of context wi...
Definition: Macros.h:185
unsigned int line
static void createTifFromMatrix(const FloatsMatrix &rasterData, const InterestPointsSetT &interestPoints, const std::string &tifFileName)
Moravec interest points locator.
unsigned int unsigned int nCols
An abstract class for raster data strucutures.
unsigned int getColumnsNumber() const
The number of current matrix columns.
Definition: Matrix.h:798
virtual void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
URI C++ Library.
Definition: Attributes.h:37
std::multiset< InterestPointT > InterestPointsSetT
A raster band description.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
static bool loadRasterData(te::rst::Raster const *rasterPtr, const std::vector< unsigned int > &rasterBands, te::rst::Raster const *maskRasterPtr, const unsigned int maskRasterBand, const unsigned int rasterTargetAreaLineStart, const unsigned int rasterTargetAreaColStart, const unsigned int rasterTargetAreaWidth, const unsigned int rasterTargetAreaHeight, const double desiredRescaleFactorX, const double desiredRescaleFactorY, const te::rst::Interpolator::Method rasterInterpMethod, const unsigned char maxMemPercentUsage, std::vector< boost::shared_ptr< FloatsMatrix > > &loadedRasterData, UCharsMatrix &loadedMaskRasterData, double &achievedRescaleFactorX, double &achievedRescaleFactorY)
Load rasters data (normalized between 0 and 1).
void reset()
Reset (clear) the active instance data.
Definition: Matrix.h:502
Tie-points locator strategy.
static void features2Tiff(const DoublesMatrix &features, const InterestPointsSetT &interestPoints, const std::string &fileNameBeginning)
Save the generated features to tif files.
const std::string & getErrorMessage() const
Return the current error message if there is any.
A generic template matrix.
Definition: Matrix.h:55
static Raster * make()
It creates and returns an empty raster with default raster driver.
void setErrorMessage(const std::string &newErrorMessage)
Set the current error message.
Blue channel color interpretation.
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
Green channel color interpretation.
unsigned int nLines
unsigned int getLinesNumber() const
The number of current matrix lines.
Definition: Matrix.h:791
static bool checkForDuplicatedInterestPoints(const InterestPointsSetT &interestPoints, double &x, double &y)
Check for duplicated interest points.
unsigned int col
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:150
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.