All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Functions.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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/Functions.cpp
22 
23  \brief Raster Processing functions.
24 */
25 
26 // TerraLib
27 
28 #include "Functions.h"
29 
30 #include "../dataaccess/dataset/DataSetType.h"
31 #include "../dataaccess/datasource/DataSourceFactory.h"
32 #include "../dataaccess/utils/Utils.h"
33 #include "../datatype/Enums.h"
34 #include "../raster/BandProperty.h"
35 #include "../raster/Grid.h"
36 #include "../raster/RasterFactory.h"
37 #include "../raster/RasterProperty.h"
38 #include "../raster/RasterIterator.h"
39 #include "../raster/Utils.h"
40 #include "../geometry/Point.h"
41 #include "../common/MatrixUtils.h"
42 #include "Exception.h"
43 #include "Macros.h"
44 #include "RasterHandler.h"
45 
46 // Boost
47 #include <boost/filesystem.hpp>
48 #include <boost/numeric/ublas/io.hpp>
49 #include <boost/numeric/ublas/matrix.hpp>
50 #include <boost/shared_ptr.hpp>
51 #include <boost/shared_array.hpp>
52 #include <boost/random.hpp>
53 #include <boost/random/uniform_int_distribution.hpp>
54 #include <boost/lexical_cast.hpp>
55 #include <boost/thread.hpp>
56 #include <boost/numeric/ublas/lu.hpp>
57 #include <boost/numeric/ublas/matrix.hpp>
58 
59 
60 // STL
61 #include <cstring>
62 #include <string>
63 #include <limits>
64 #include <map>
65 #include <memory>
66 
67 #ifndef M_PI
68  #define M_PI 3.14159265358979323846
69 #endif
70 
71 namespace te
72 {
73  namespace rp
74  {
76  {
79  double* m_meanValuePtr;
82  boost::mutex* m_mutexPtr;
83  };
84 
86  {
91  double m_meanValue;
93  boost::mutex* m_mutexPtr;
94  };
95 
97  {
104  double m_mean1Value;
105  double m_mean2Value;
106  boost::mutex* m_mutexPtr;
107  };
108 
110  {
112  std::vector< unsigned int > const * m_inputRasterBandsPtr;
114  boost::numeric::ublas::matrix< double > const * m_remapMatrixPtr;
117  boost::mutex* m_mutexPtr;
118  };
119 
120  bool CreateNewRaster( const te::rst::Grid& rasterGrid,
121  const std::vector< te::rst::BandProperty* >& bandsProperties,
122  const std::string& outDataSetName,
123  const std::string& dataSourceType,
124  RasterHandler& outRasterHandler )
125  {
126  // Creating a new datasource
127 
128  std::auto_ptr< te::da::DataSource > dataSourcePtr(
129  te::da::DataSourceFactory::make( dataSourceType ) );
130  if( dataSourcePtr.get() == 0 ) return false;
131 
132  RasterHandler internalRasterHandler;
133 
134  if( CreateNewRaster( rasterGrid, bandsProperties,
135  outDataSetName, *dataSourcePtr, internalRasterHandler ) )
136  {
137  std::auto_ptr< te::da::DataSource > dummyDataSourcePtr;
138  std::auto_ptr< te::da::DataSourceTransactor > transactorPtr;
139  std::auto_ptr< te::da::DataSet > dataSetPtr;
140  std::auto_ptr< te::rst::Raster > rasterPtr;
141 
142  internalRasterHandler.release( dummyDataSourcePtr, transactorPtr,
143  dataSetPtr, rasterPtr );
144 
145  outRasterHandler.reset( dataSourcePtr.release(), transactorPtr.release(),
146  dataSetPtr.release(), rasterPtr.release() );
147 
148  return true;
149  }
150  else
151  {
152  return false;
153  }
154  }
155 
156  bool CreateNewRaster( const te::rst::Grid& rasterGrid,
157  const std::vector< te::rst::BandProperty* >& bandsProperties,
158  const std::string& outDataSetName,
159  te::da::DataSource& outDataSource,
160  RasterHandler& outRasterHandler )
161  {
162  // Defining the raster properties
163 
164  std::auto_ptr< te::rst::RasterProperty > rasterPropertyPtr(
165  new te::rst::RasterProperty( new te::rst::Grid( rasterGrid ),
166  bandsProperties, std::map< std::string, std::string >(),
167  false, 0, 0 ) );
168 
169  // acquiring a transactor instance
170 
171  std::auto_ptr< te::da::DataSourceTransactor > transactorPtr(
172  outDataSource.getTransactor() );
173 
174  if( transactorPtr.get() == 0 )
175  {
176  return false;
177  }
178 
179  // Creating a data set instance
180 
181  if( transactorPtr->dataSetExists( outDataSetName ) )
182  {
183  transactorPtr->dropDataSet( outDataSetName );
184  }
185 
186  std::auto_ptr< te::da::DataSetType > dataSetTypePtr(
187  new te::da::DataSetType( outDataSetName ) );
188  dataSetTypePtr->add( rasterPropertyPtr.release() );
189 
190  try
191  {
192  transactorPtr->createDataSet( dataSetTypePtr.get(),
193  std::map< std::string, std::string >() );
194  }
195  catch( ... )
196  {
197  return false;
198  }
199 
200  if( ! transactorPtr->dataSetExists( outDataSetName ) ) return false;
201 
202  std::auto_ptr< te::da::DataSet > dataSetPtr( transactorPtr->getDataSet(
203  outDataSetName, te::common::FORWARDONLY, true, te::common::RWAccess ) );
204 
205  if( dataSetPtr.get() == 0 )
206  {
207  return false;
208  }
209 
210  // Creating a raster instance
211 
212  std::auto_ptr< te::rst::Raster > rasterPtr( dataSetPtr->getRaster( 0 ) );
213 
214  if( rasterPtr.get() )
215  {
216  outRasterHandler.reset( transactorPtr.release(), dataSetPtr.release(), rasterPtr.release() );
217  return true;
218  }
219  else
220  {
221  return false;
222  }
223  }
224 
225  bool CreateNewMemRaster( const te::rst::Grid& rasterGrid,
226  std::vector< te::rst::BandProperty* > bandsProperties,
227  RasterHandler& outRasterHandler )
228  {
229  std::string dataSetName = std::string( "createNewMemRaster" ) +
230  boost::lexical_cast< std::string >( &outRasterHandler );
231 
232  return CreateNewRaster( rasterGrid, bandsProperties, dataSetName,
233  "MEM", outRasterHandler );
234  }
235 
236  bool CreateNewGdalRaster( const te::rst::Grid& rasterGrid,
237  std::vector< te::rst::BandProperty* > bandsProperties,
238  const std::string& fileName,
239  RasterHandler& outRasterHandler )
240  {
241 
242  boost::filesystem::path pathInfo( fileName );
243 
244  // Creating a new datasource
245 
246  std::auto_ptr< te::da::DataSource > dataSourcePtr(
248  if( dataSourcePtr.get() == 0 ) return false;
249 
250  std::map<std::string, std::string> outputRasterInfo;
251  outputRasterInfo["SOURCE"] = pathInfo.parent_path().string().empty() ?
252  "." : pathInfo.parent_path().string();
253 
254  dataSourcePtr->setConnectionInfo(outputRasterInfo);
255  dataSourcePtr->open();
256  if( ! dataSourcePtr->isOpened() ) return false;
257 
258  RasterHandler internalRasterHandler;
259 
260  if( CreateNewRaster( rasterGrid, bandsProperties,
261  pathInfo.filename().string(), *dataSourcePtr, internalRasterHandler ) )
262  {
263  std::auto_ptr< te::da::DataSource > dummyDataSourcePtr;
264  std::auto_ptr< te::da::DataSourceTransactor > transactorPtr;
265  std::auto_ptr< te::da::DataSet > dataSetPtr;
266  std::auto_ptr< te::rst::Raster > rasterPtr;
267 
268  internalRasterHandler.release( dummyDataSourcePtr, transactorPtr,
269  dataSetPtr, rasterPtr );
270 
271  outRasterHandler.reset( dataSourcePtr.release(), transactorPtr.release(),
272  dataSetPtr.release(), rasterPtr.release() );
273 
274  return true;
275  }
276  else
277  {
278  return false;
279  }
280  }
281 
282  bool TERPEXPORT Copy2DiskRaster( const te::rst::Raster& inputRaster,
283  const std::string& fileName )
284  {
285  if( !(inputRaster.getAccessPolicy() & te::common::RAccess ) )
286  {
287  return false;
288  };
289 
290  const unsigned int nBands = inputRaster.getNumberOfBands();
291  const unsigned int nCols = inputRaster.getNumberOfColumns();
292  const unsigned int nRows = inputRaster.getNumberOfRows();
293  unsigned int bandIdx =0;
294  unsigned int col = 0;
295  unsigned int row = 0;
296 
297  std::vector< te::rst::BandProperty* > bandsProperties;
298  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
299  {
300  bandsProperties.push_back( new te::rst::BandProperty(
301  *( inputRaster.getBand( bandIdx )->getProperty() ) ) );
302  }
303 
304  RasterHandler outRasterHandler;
305 
306  if( ! CreateNewGdalRaster( *( inputRaster.getGrid() ), bandsProperties,
307  fileName, outRasterHandler ) )
308  {
309  return false;
310  }
311 
312  double value = 0;
313 
314  for( bandIdx = 0 ; bandIdx < nBands ; ++bandIdx )
315  {
316  const te::rst::Band& inBand = *inputRaster.getBand( bandIdx );
317  te::rst::Band& outBand = *outRasterHandler.getRasterPtr()->getBand( bandIdx );
318 
319  for( row = 0 ; row < nRows ; ++row )
320  {
321  for( col = 0 ; col < nCols ; ++col )
322  {
323  inBand.getValue( col, row, value );
324  outBand.setValue( col, row, value );
325  }
326  }
327  }
328 
329  return true;
330  }
331 
332  void Convert2DoublesVector( void* inputVector, const int inputVectorDataType,
333  unsigned int inputVectorSize, double* outputVector )
334  {
335  switch( inputVectorDataType )
336  {
337  case te::dt::CHAR_TYPE :
338  {
339  char* vPtr = (char*)inputVector;
340  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
341  outputVector[ idx ] = (double)vPtr[ idx ];
342  break;
343  }
344  case te::dt::BIT_TYPE :
345  case te::dt::UCHAR_TYPE :
346  {
347  unsigned char* vPtr = (unsigned char*)inputVector;
348  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
349  outputVector[ idx ] = (double)vPtr[ idx ];
350  break;
351  }
352  case te::dt::INT16_TYPE :
353  {
354  short int* vPtr = (short int*)inputVector;
355  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
356  outputVector[ idx ] = (double)vPtr[ idx ];
357  break;
358  }
359  case te::dt::CINT16_TYPE :
360  {
361  std::complex< short int >* vPtr = (std::complex< short int >*)
362  inputVector;
363  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
364  outputVector[ idx ] = (double)vPtr[ idx ].real();
365  break;
366  }
367  case te::dt::UINT16_TYPE :
368  {
369  unsigned short int* vPtr = (unsigned short int*)inputVector;
370  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
371  outputVector[ idx ] = (double)vPtr[ idx ];
372  break;
373  }
374  case te::dt::INT32_TYPE :
375  {
376  int* vPtr = (int*)inputVector;
377  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
378  outputVector[ idx ] = (double)vPtr[ idx ];
379  break;
380  }
381  case te::dt::CINT32_TYPE :
382  {
383  std::complex< int >* vPtr = (std::complex< int >*)
384  inputVector;
385  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
386  outputVector[ idx ] = (double)vPtr[ idx ].real();
387  break;
388  }
389  case te::dt::UINT32_TYPE :
390  {
391  unsigned int* vPtr = (unsigned int*)inputVector;
392  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
393  outputVector[ idx ] = (double)vPtr[ idx ];
394  break;
395  }
396  case te::dt::INT64_TYPE :
397  {
398  long int* vPtr = (long int*)inputVector;
399  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
400  outputVector[ idx ] = (double)vPtr[ idx ];
401  break;
402  }
403  case te::dt::UINT64_TYPE :
404  {
405  unsigned long int* vPtr = (unsigned long int*)inputVector;
406  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
407  outputVector[ idx ] = (double)vPtr[ idx ];
408  break;
409  }
410  case te::dt::FLOAT_TYPE :
411  {
412  float* vPtr = (float*)inputVector;
413  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
414  outputVector[ idx ] = (double)vPtr[ idx ];
415  break;
416  }
417  case te::dt::CFLOAT_TYPE :
418  {
419  std::complex< float >* vPtr = (std::complex< float >*)
420  inputVector;
421  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
422  outputVector[ idx ] = (double)vPtr[ idx ].real();
423  break;
424  }
425  case te::dt::DOUBLE_TYPE :
426  {
427  memcpy( outputVector, inputVector, inputVectorSize * sizeof( double ) );
428  break;
429  }
430  case te::dt::CDOUBLE_TYPE :
431  {
432  std::complex< double >* vPtr = (std::complex< double >*)
433  inputVector;
434  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
435  outputVector[ idx ] = (double)vPtr[ idx ].real();
436  break;
437  }
438  default :
439  throw te::rp::Exception( "Invalid data type" );
440  break;
441  };
442  }
443 
444  void ConvertDoublesVector( double* inputVector,
445  unsigned int inputVectorSize, const int outputVectorDataType,
446  void* outputVector )
447  {
448  switch( outputVectorDataType )
449  {
450  case te::dt::CHAR_TYPE :
451  {
452  char* vPtr = (char*)outputVector;
453  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
454  vPtr[ idx ] = (char)inputVector[ idx ];
455  break;
456  }
457  case te::dt::BIT_TYPE :
458  case te::dt::UCHAR_TYPE :
459  {
460  unsigned char* vPtr = (unsigned char*)outputVector;
461  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
462  vPtr[ idx ] = (unsigned char)inputVector[ idx ];
463  break;
464  }
465  case te::dt::INT16_TYPE :
466  {
467  short int* vPtr = (short int*)outputVector;
468  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
469  vPtr[ idx ] = (short int)inputVector[ idx ];
470  break;
471  }
472  case te::dt::CINT16_TYPE :
473  {
474  std::complex< short int >* vPtr = (std::complex< short int >*)
475  outputVector;
476  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
477  vPtr[ idx ]= ( (short int)inputVector[ idx ] );
478  break;
479  }
480  case te::dt::UINT16_TYPE :
481  {
482  unsigned short int* vPtr = (unsigned short int*)outputVector;
483  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
484  vPtr[ idx ] = (unsigned short int)inputVector[ idx ];
485  break;
486  }
487  case te::dt::INT32_TYPE :
488  {
489  int* vPtr = (int*)outputVector;
490  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
491  vPtr[ idx ] = (int)inputVector[ idx ];
492  break;
493  }
494  case te::dt::CINT32_TYPE :
495  {
496  std::complex< int >* vPtr = (std::complex< int >*)
497  outputVector;
498  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
499  vPtr[ idx ] = ( (int)inputVector[ idx ] );
500  break;
501  }
502  case te::dt::UINT32_TYPE :
503  {
504  unsigned int* vPtr = (unsigned int*)outputVector;
505  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
506  vPtr[ idx ] = (unsigned int)inputVector[ idx ];
507  break;
508  }
509  case te::dt::INT64_TYPE :
510  {
511  long int* vPtr = (long int*)outputVector;
512  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
513  vPtr[ idx ] = (long int)inputVector[ idx ];
514  break;
515  }
516  case te::dt::UINT64_TYPE :
517  {
518  unsigned long int* vPtr = (unsigned long int*)outputVector;
519  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
520  vPtr[ idx ] = (unsigned long int)inputVector[ idx ];
521  break;
522  }
523  case te::dt::FLOAT_TYPE :
524  {
525  float* vPtr = (float*)outputVector;
526  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
527  vPtr[ idx ] = (float)inputVector[ idx ];
528  break;
529  }
530  case te::dt::CFLOAT_TYPE :
531  {
532  std::complex< float >* vPtr = (std::complex< float >*)
533  outputVector;
534  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
535  vPtr[ idx ] = ( (float)inputVector[ idx ] );
536  break;
537  }
538  case te::dt::DOUBLE_TYPE :
539  {
540  memcpy( outputVector, inputVector, inputVectorSize * sizeof( double ) );
541  break;
542  }
543  case te::dt::CDOUBLE_TYPE :
544  {
545  std::complex< double >* vPtr = (std::complex< double >*)
546  outputVector;
547  for( register unsigned int idx = 0 ; idx < inputVectorSize ; ++idx )
548  vPtr[ idx ] = ( (double)inputVector[ idx ] );
549  break;
550  }
551  default :
552  throw te::rp::Exception( "Invalid data type" );
553  break;
554  };
555  }
556 
557  std::vector<std::string> GetBandNames()
558  {
559  static std::vector<std::string> bandNames;
560 
561  bandNames.push_back("CBERS2_CCD_1_BLUE");
562  bandNames.push_back("CBERS2_CCD_2_GREEN");
563  bandNames.push_back("CBERS2_CCD_3_RED");
564  bandNames.push_back("CBERS2_CCD_4_NIR");
565  bandNames.push_back("CBERS2_CCD_5_PAN");
566 
567  bandNames.push_back("LANDSAT5_TM_1_BLUE");
568  bandNames.push_back("LANDSAT5_TM_2_GREEN");
569  bandNames.push_back("LANDSAT5_TM_3_RED");
570  bandNames.push_back("LANDSAT5_TM_4_NIR");
571  bandNames.push_back("LANDSAT5_TM_5_SWIR");
572  bandNames.push_back("LANDSAT5_TM_6_THERMAL");
573  bandNames.push_back("LANDSAT5_TM_7_MIR");
574 
575  bandNames.push_back("LANDSAT7_ETM+_1_BLUE");
576  bandNames.push_back("LANDSAT7_ETM+_2_GREEN");
577  bandNames.push_back("LANDSAT7_ETM+_3_RED");
578  bandNames.push_back("LANDSAT7_ETM+_4_NIR");
579  bandNames.push_back("LANDSAT7_ETM+_5_SWIR");
580  bandNames.push_back("LANDSAT7_ETM+_6_THERMAL");
581  bandNames.push_back("LANDSAT7_ETM+_7_MIR");
582  bandNames.push_back("LANDSAT7_ETM+_8_PAN");
583 
584  bandNames.push_back("WV2_MUL_1_COASTAL");
585  bandNames.push_back("WV2_MUL_2_BLUE");
586  bandNames.push_back("WV2_MUL_3_GREEN");
587  bandNames.push_back("WV2_MUL_4_YELLOW");
588  bandNames.push_back("WV2_MUL_5_RED");
589  bandNames.push_back("WV2_MUL_6_REDEDGE");
590  bandNames.push_back("WV2_MUL_7_NIR1");
591  bandNames.push_back("WV2_MUL_8_NIR2");
592  bandNames.push_back("WV2_PAN");
593 
594  return bandNames;
595  }
596 
597  std::pair<double, double> GetSpectralBandInfo(std::string bandName)
598  {
599  static std::map<std::string, std::pair<double, double> > BandInfo;
600 
601  BandInfo["CBERS2_CCD_1_BLUE"] = std::pair<double, double> (0.45, 0.52);
602  BandInfo["CBERS2_CCD_2_GREEN"] = std::pair<double, double> (0.52, 0.59);
603  BandInfo["CBERS2_CCD_3_RED"] = std::pair<double, double> (0.63, 0.69);
604  BandInfo["CBERS2_CCD_4_NIR"] = std::pair<double, double> (0.77, 0.89);
605  BandInfo["CBERS2_CCD_5_PAN"] = std::pair<double, double> (0.51, 0.73);
606 
607  BandInfo["LANDSAT5_TM_1_BLUE"] = std::pair<double, double> (0.45, 0.52);
608  BandInfo["LANDSAT5_TM_2_GREEN"] = std::pair<double, double> (0.52, 0.60);
609  BandInfo["LANDSAT5_TM_3_RED"] = std::pair<double, double> (0.63, 0.69);
610  BandInfo["LANDSAT5_TM_4_NIR"] = std::pair<double, double> (0.76, 0.90);
611  BandInfo["LANDSAT5_TM_5_SWIR"] = std::pair<double, double> (1.55, 1.75);
612  BandInfo["LANDSAT5_TM_6_THERMAL"] = std::pair<double, double> (10.40, 12.50);
613  BandInfo["LANDSAT5_TM_7_MIR"] = std::pair<double, double> (2.08, 2.35);
614 
615  BandInfo["LANDSAT7_ETM+_1_BLUE"] = std::pair<double, double> (0.45, 0.515);
616  BandInfo["LANDSAT7_ETM+_2_GREEN"] = std::pair<double, double> (0.525, 0.605);
617  BandInfo["LANDSAT7_ETM+_3_RED"] = std::pair<double, double> (0.63, 0.69);
618  BandInfo["LANDSAT7_ETM+_4_NIR"] = std::pair<double, double> (0.75, 0.90);
619  BandInfo["LANDSAT7_ETM+_5_SWIR"] = std::pair<double, double> (1.55, 1.75);
620  BandInfo["LANDSAT7_ETM+_6_THERMAL"] = std::pair<double, double> (10.40, 12.5);
621  BandInfo["LANDSAT7_ETM+_7_MIR"] = std::pair<double, double> (2.09, 2.35);
622  BandInfo["LANDSAT7_ETM+_8_PAN"] = std::pair<double, double> (0.52, 0.90);
623 
624  BandInfo["WV2_MUL_1_COASTAL"] = std::pair<double, double> (0.4, 0.45);
625  BandInfo["WV2_MUL_2_BLUE"] = std::pair<double, double> (0.45, 0.51);
626  BandInfo["WV2_MUL_3_GREEN"] = std::pair<double, double> (0.51, 0.58);
627  BandInfo["WV2_MUL_4_YELLOW"] = std::pair<double, double> (0.585, 0.625);
628  BandInfo["WV2_MUL_5_RED"] = std::pair<double, double> (0.66, 0.69);
629  BandInfo["WV2_MUL_6_REDEDGE"] = std::pair<double, double> (0.705, 0.745);
630  BandInfo["WV2_MUL_7_NIR1"] = std::pair<double, double> (0.77, 0.895);
631  BandInfo["WV2_MUL_8_NIR2"] = std::pair<double, double> (0.86, 0.104);
632  BandInfo["WV2_PAN"] = std::pair<double, double> (0.45, 0.8);
633 
634  // needs more Band Info from other sensors/bands
635 
636  if (BandInfo.find(bandName) == BandInfo.end())
637  return std::pair<double, double> (0.0, 1.0);
638 
639  return BandInfo[bandName];
640  }
641 
642  double GetSpectralBandMin(std::string bandName)
643  {
644  return GetSpectralBandInfo(bandName).first;
645  }
646 
647  double GetSpectralBandMax(std::string bandName)
648  {
649  return GetSpectralBandInfo(bandName).second;
650  }
651 
652  std::pair<double, double> GetDigitalNumberBandInfo(std::string bandName)
653  {
654  static std::map<std::string, std::pair<double, double> > DNBandInfo;
655 
656  DNBandInfo["CBERS2_CCD_1_BLUE"] = std::pair<double, double> (0.0, 255.0);
657  DNBandInfo["CBERS2_CCD_2_GREEN"] = std::pair<double, double> (0.0, 255.0);
658  DNBandInfo["CBERS2_CCD_3_RED"] = std::pair<double, double> (0.0, 255.0);
659  DNBandInfo["CBERS2_CCD_4_NIR"] = std::pair<double, double> (0.0, 255.0);
660  DNBandInfo["CBERS2_CCD_5_PAN"] = std::pair<double, double> (0.0, 255.0);
661 
662  DNBandInfo["LANDSAT5_TM_1_BLUE"] = std::pair<double, double> (0.0, 255.0);
663  DNBandInfo["LANDSAT5_TM_2_GREEN"] = std::pair<double, double> (0.0, 255.0);
664  DNBandInfo["LANDSAT5_TM_3_RED"] = std::pair<double, double> (0.0, 255.0);
665  DNBandInfo["LANDSAT5_TM_4_NIR"] = std::pair<double, double> (0.0, 255.0);
666  DNBandInfo["LANDSAT5_TM_5_SWIR"] = std::pair<double, double> (0.0, 255.0);
667  DNBandInfo["LANDSAT5_TM_6_THERMAL"] = std::pair<double, double> (0.0, 255.0);
668  DNBandInfo["LANDSAT5_TM_7_MIR"] = std::pair<double, double> (0.0, 255.0);
669 
670  DNBandInfo["LANDSAT7_ETM+_1_BLUE"] = std::pair<double, double> (0.0, 255.0);
671  DNBandInfo["LANDSAT7_ETM+_2_GREEN"] = std::pair<double, double> (0.0, 255.0);
672  DNBandInfo["LANDSAT7_ETM+_3_RED"] = std::pair<double, double> (0.0, 255.0);
673  DNBandInfo["LANDSAT7_ETM+_4_NIR"] = std::pair<double, double> (0.0, 255.0);
674  DNBandInfo["LANDSAT7_ETM+_5_SWIR"] = std::pair<double, double> (0.0, 255.0);
675  DNBandInfo["LANDSAT7_ETM+_6_THERMAL"] = std::pair<double, double> (0.0, 255.0);
676  DNBandInfo["LANDSAT7_ETM+_7_MIR"] = std::pair<double, double> (0.0, 255.0);
677  DNBandInfo["LANDSAT7_ETM+_8_PAN"] = std::pair<double, double> (0.0, 255.0);
678 
679  DNBandInfo["WV2_MUL_1_COASTAL"] = std::pair<double, double> (0.0, 2048.0);
680  DNBandInfo["WV2_MUL_2_BLUE"] = std::pair<double, double> (0.0, 2048.0);
681  DNBandInfo["WV2_MUL_3_GREEN"] = std::pair<double, double> (0.0, 2048.0);
682  DNBandInfo["WV2_MUL_4_YELLOW"] = std::pair<double, double> (0.0, 2048.0);
683  DNBandInfo["WV2_MUL_5_RED"] = std::pair<double, double> (0.0, 2048.0);
684  DNBandInfo["WV2_MUL_6_REDEDGE"] = std::pair<double, double> (0.0, 2048.0);
685  DNBandInfo["WV2_MUL_7_NIR1"] = std::pair<double, double> (0.0, 2048.0);
686  DNBandInfo["WV2_MUL_7_NIR2"] = std::pair<double, double> (0.0, 2048.0);
687  DNBandInfo["WV2_PAN"] = std::pair<double, double> (0.0, 2048.0);
688 
689  // needs more Band Info from other sensors/bands
690 
691  if (DNBandInfo.find(bandName) == DNBandInfo.end())
692  return std::pair<double, double> (0.0, 255.0);
693 
694  return DNBandInfo[bandName];
695  }
696 
697  double GetDigitalNumberBandMax(std::string bandName)
698  {
699  return GetDigitalNumberBandInfo(bandName).second;
700  }
701 
702  bool NormalizeRaster(te::rst::Raster& inraster, double nmin, double nmax)
703  {
704  if (nmin > nmax)
705  return false;
706 
707  // computing old maximuns and minimums for each band
708  std::vector<double> omins;
709  std::vector<double> omaxs;
710  std::vector<unsigned int> bands;
711 
712  for (unsigned int b = 0; b < inraster.getNumberOfBands(); b++)
713  {
714  omins.push_back(inraster.getBand(b)->getMinValue().real());
715  omaxs.push_back(inraster.getBand(b)->getMaxValue().real());
716 
717  bands.push_back(b);
718  }
719 
720  // calculating amplitudes to avoid multiple subtractions
721  double value;
722  const double namplitude = nmax - nmin;
723  std::vector<double> oamplitude;
724  for (unsigned int b = 0; b < inraster.getNumberOfBands(); b++)
725  oamplitude.push_back(omaxs[b] - omins[b]);
726 
727  // iterating over raster to normalize pixel values
730 
731  while (it != itend)
732  {
733  for (unsigned int b = 0; b < inraster.getNumberOfBands(); b++)
734  {
735  value = ((*it)[b] - omins[b]) * namplitude / oamplitude[b] + nmin;
736 
737  inraster.setValue(it.getColumn(), it.getRow(), value, b);
738  }
739 
740  ++it;
741  }
742 
743  return true;
744  }
745 
746  std::vector<te::gm::Point*> GetRandomPointsInRaster(const te::rst::Raster& inputRaster, unsigned int numberOfPoints)
747  {
748  std::vector<te::gm::Point*> randomPoints;
749  double randX;
750  double randY;
751 
752  boost::random::mt19937 generator((boost::random::mt19937::result_type) time(0));
753  boost::random::uniform_int_distribution<> random_rows(0, inputRaster.getNumberOfRows() - 1);
754  boost::random::uniform_int_distribution<> random_columns(0, inputRaster.getNumberOfColumns() - 1);
755 
756  for (unsigned int p = 0; p < numberOfPoints; p++)
757  {
758  inputRaster.getGrid()->gridToGeo(random_columns(generator), random_rows(generator), randX, randY);
759  randomPoints.push_back(new te::gm::Point(randX, randY, inputRaster.getSRID()));
760  }
761 
762  return randomPoints;
763  }
764 
765  bool ConvertRGB2IHS( const te::rst::Raster& inputRGBRaster,
766  const unsigned int redBandIdx, const unsigned int greenBandIdx,
767  const unsigned int blueBandIdx, const double rgbRangeMin,
768  const double rgbRangeMax, te::rst::Raster& outputIHSRaster )
769  {
770  if( ( inputRGBRaster.getAccessPolicy() & te::common::RAccess ) == 0 )
771  return false;
772  if( redBandIdx > inputRGBRaster.getNumberOfBands() ) return false;
773  if( greenBandIdx > inputRGBRaster.getNumberOfBands() ) return false;
774  if( blueBandIdx > inputRGBRaster.getNumberOfBands() ) return false;
775  if( ( outputIHSRaster.getAccessPolicy() & te::common::WAccess ) == 0 )
776  return false;
777  if( outputIHSRaster.getNumberOfBands() < 3 ) return false;
778  if( inputRGBRaster.getNumberOfColumns() != outputIHSRaster.getNumberOfColumns() )
779  return false;
780  if( inputRGBRaster.getNumberOfRows() != outputIHSRaster.getNumberOfRows() )
781  return false;
782 
783  const te::rst::Band& redBand = *inputRGBRaster.getBand( redBandIdx );
784  const te::rst::Band& greenBand = *inputRGBRaster.getBand( greenBandIdx );
785  const te::rst::Band& blueBand = *inputRGBRaster.getBand( blueBandIdx );
786 
787  const unsigned int outNCols = outputIHSRaster.getNumberOfColumns();
788  const unsigned int outNRows = outputIHSRaster.getNumberOfRows();
789  const double redNoData = redBand.getProperty()->m_noDataValue;
790  const double greenNoData = greenBand.getProperty()->m_noDataValue;
791  const double blueNoData = inputRGBRaster.getBand(
792  blueBandIdx )->getProperty()->m_noDataValue;
793 
794  unsigned int outRow = 0;
795  unsigned int outCol = 0;
796  double red = 0;
797  double green = 0;
798  double blue = 0;
799  double teta = 0;
800  double redNorm = 0, greenNorm = 0, blueNorm = 0;
801  double rMinusG = 0, rMinusB = 0;
802  double rgbSum = 0;
803  double cosValue = 0;
804  const double twoPi = 2.0 * ((double)M_PI);
805  const double pi2 = ((double)M_PI) / 2.0;
806  const double rgbNormFac = ( rgbRangeMax == rgbRangeMin ) ? 0.0 :
807  ( 1.0 / ( rgbRangeMax - rgbRangeMin ) );
808  double intensity = 0;
809  double hue = 0;
810  double saturation = 0;
811 
812  for( outRow = 0 ; outRow < outNRows ; ++outRow )
813  {
814  for( outCol = 0 ; outCol < outNCols ; ++outCol )
815  {
816  redBand.getValue( outCol, outRow, red );
817  greenBand.getValue( outCol, outRow, green );
818  blueBand.getValue( outCol, outRow, blue );
819 
820  if( ( red == redNoData ) || ( green == greenNoData ) ||
821  ( blue == blueNoData ) )
822  {
823  intensity = 0.0;
824  hue = 0.0;
825  saturation = 0.0;
826  }
827  else
828  {
829  if( ( red == green ) && ( green == blue ) )
830  { // Gray scale case
831  // From Wikipedia:
832  // h = 0 is used for grays though the hue has no geometric
833  // meaning there, where the saturation s = 0. Similarly,
834  // the choice of 0 as the value for s when l is equal to 0 or 1
835  // is arbitrary.
836 
837  hue = 0.0;
838  saturation = 0.0;
839  intensity = ( red * rgbNormFac ); // or green or blue since they all are the same.
840  }
841  else
842  { // Color case
843  redNorm = ( red - rgbRangeMin ) * rgbNormFac;
844  greenNorm = ( green - rgbRangeMin ) * rgbNormFac;
845  blueNorm = ( blue - rgbRangeMin ) * rgbNormFac;
846 
847  rMinusG = redNorm - greenNorm;
848  rMinusB = redNorm - blueNorm;
849 
850  cosValue = std::sqrt( ( rMinusG * rMinusG ) + ( rMinusB *
851  ( greenNorm - blueNorm ) ) );
852 
853  if( cosValue == 0.0 )
854  {
855  teta = pi2;
856  }
857  else
858  {
859  cosValue = ( 0.5 * ( rMinusG + rMinusB ) ) /
860  cosValue;
861  teta = std::acos( cosValue );
862  }
863 
864  assert( ( cosValue >= (-1.0) ) && ( cosValue <= (1.0) ) );
865 
866  if( blueNorm > greenNorm )
867  {
868  hue = ( twoPi - teta );
869  }
870  else
871  {
872  hue = teta;
873  }
874 
875  rgbSum = ( redNorm + greenNorm + blueNorm );
876 
877  saturation = ( 1.0 - ( 3 * std::min( std::min( redNorm, greenNorm ), blueNorm ) /
878  rgbSum ) );
879 
880  intensity = ( rgbSum / 3.0 );
881  }
882  }
883 
884  outputIHSRaster.setValue( outCol, outRow, intensity, 0 );
885  outputIHSRaster.setValue( outCol, outRow, hue, 1 );
886  outputIHSRaster.setValue( outCol, outRow, saturation, 2 );
887  }
888  }
889 
890  return true;
891  }
892 
893  bool ConvertIHS2RGB( const te::rst::Raster& inputIHSRaster,
894  const unsigned int intensityBandIdx, const unsigned int hueBandIdx,
895  const unsigned int saturationBandIdx, const double rgbRangeMin,
896  const double rgbRangeMax, te::rst::Raster& outputRGBRaster )
897  {
898  if( ( inputIHSRaster.getAccessPolicy() & te::common::RAccess ) == 0 )
899  return false;
900  if( intensityBandIdx > inputIHSRaster.getNumberOfBands() ) return false;
901  if( hueBandIdx > inputIHSRaster.getNumberOfBands() ) return false;
902  if( saturationBandIdx > inputIHSRaster.getNumberOfBands() ) return false;
903  if( ( outputRGBRaster.getAccessPolicy() & te::common::WAccess ) == 0 )
904  return false;
905  if( outputRGBRaster.getNumberOfBands() < 3 ) return false;
906  if( inputIHSRaster.getNumberOfColumns() != outputRGBRaster.getNumberOfColumns() )
907  return false;
908  if( inputIHSRaster.getNumberOfRows() != outputRGBRaster.getNumberOfRows() )
909  return false;
910 
911  const unsigned int nCols = outputRGBRaster.getNumberOfColumns();
912  const unsigned int nRows = outputRGBRaster.getNumberOfRows();
913  const double intensityNoData = inputIHSRaster.getBand(
914  intensityBandIdx )->getProperty()->m_noDataValue;
915  const double hueNoData = inputIHSRaster.getBand(
916  hueBandIdx )->getProperty()->m_noDataValue;
917  const double saturationNoData = inputIHSRaster.getBand(
918  saturationBandIdx )->getProperty()->m_noDataValue;
919 
920  const double rgbNormFac = ( rgbRangeMax == rgbRangeMin ) ? 0.0 :
921  ( rgbRangeMax - rgbRangeMin );
922  const double pi3 = M_PI / 3.0; // 60
923  const double twoPi3 = 2.0 * M_PI / 3.0; // 120
924  const double fourPi3 = 4.0 * M_PI / 3.0; // 240
925  unsigned int row = 0;
926  unsigned int col = 0;
927  double hue = 0;
928  double lig = 0;
929  double sat = 0;
930  double red = 0;
931  double green = 0;
932  double blue = 0;
933  const te::rst::Band& intensityBand = *inputIHSRaster.getBand( intensityBandIdx );
934  const te::rst::Band& hueBand = *inputIHSRaster.getBand( hueBandIdx );
935  const te::rst::Band& saturationBand = *inputIHSRaster.getBand( saturationBandIdx );
936  te::rst::Band& redBand = *outputRGBRaster.getBand( 0 );
937  te::rst::Band& greenBand = *outputRGBRaster.getBand( 1 );
938  te::rst::Band& blueBand = *outputRGBRaster.getBand( 2 );
939 
940  for( row = 0 ; row < nRows ; ++row )
941  {
942  for( col = 0 ; col < nCols ; ++col )
943  {
944  intensityBand.getValue( col, row, lig );
945  hueBand.getValue( col, row, hue );
946  saturationBand.getValue( col, row, sat );
947 
948  if( ( lig == intensityNoData ) || ( hue == hueNoData ) ||
949  ( sat == saturationNoData ) )
950  {
951  red = green = blue = 0;
952  }
953  else
954  {
955  if( ( hue == 0.0 ) && ( sat == 0.0 ) )
956  { // Gray scale case
957  red = green = blue = ( lig * rgbNormFac );
958  }
959  else
960  { // color case
961  /* Hue inside RG sector */
962  if( hue < twoPi3 )
963  {
964  blue = lig * ( 1.0 - sat );
965  red = lig * ( 1.0 + ( sat * std::cos( hue ) /
966  std::cos( pi3 - hue ) ) );
967  green = ( 3.0 * lig ) - ( red + blue );
968  }
969  else if( hue < fourPi3 )
970  { /* Hue inside GB sector */
971 
972  hue -= twoPi3;
973 
974  red = lig * ( 1.0 - sat );
975  green = lig * ( 1.0 + ( sat * std::cos( hue ) /
976  std::cos( pi3 - hue ) ) );
977  blue = ( 3.0 * lig ) - ( red + green );
978  }
979  else
980  { /* Hue inside BR sector */
981 
982  hue -= fourPi3;
983 
984  green = lig * ( 1.0 - sat );
985  blue = lig * ( 1.0 + ( sat * std::cos( hue ) /
986  std::cos( pi3 - hue ) ) );
987  red = ( 3.0 * lig ) - ( green + blue );
988  }
989 
990  red = ( red * rgbNormFac ) + rgbRangeMin;
991  green = ( green * rgbNormFac ) + rgbRangeMin;
992  blue = ( blue * rgbNormFac ) + rgbRangeMin;
993  }
994  }
995 
996  red = MIN( red, rgbRangeMax );
997  green = MIN( green, rgbRangeMax );
998  blue = MIN( blue, rgbRangeMax );
999 
1000  red = MAX( red, rgbRangeMin );
1001  green = MAX( green, rgbRangeMin );
1002  blue = MAX( blue, rgbRangeMin );
1003 
1004  redBand.setValue( col, row, red );
1005  greenBand.setValue( col, row, green );
1006  blueBand.setValue( col, row, blue );
1007  }
1008  }
1009 
1010  return true;
1011  }
1012 
1014  {
1015  paramsPtr->m_mutexPtr->lock();
1016  const unsigned int blockElementsNumber = paramsPtr->m_inputBandPtr->getProperty()->m_blkh *
1017  paramsPtr->m_inputBandPtr->getProperty()->m_blkw;
1018  const int blockDataType = paramsPtr->m_inputBandPtr->getProperty()->getType();
1019  const int blockSizeBytes = paramsPtr->m_inputBandPtr->getBlockSize();
1020  const double noDataValue = paramsPtr->m_inputBandPtr->getProperty()->m_noDataValue;
1021  paramsPtr->m_mutexPtr->unlock();
1022 
1023  boost::scoped_array< unsigned char > blockBuffer( new unsigned char[ blockSizeBytes ] );
1024  boost::scoped_array< double > doubleBuffer( new double[ blockElementsNumber ] );
1025  unsigned blkX = 0;
1026  unsigned int elementIdx = 0;
1027  double mean = 0;
1028  double meanElementsNumber = 0;
1029 
1030  for( unsigned blkY = 0 ; blkY < paramsPtr->m_rasterBlocksStatusPtr->getLinesNumber() ;
1031  ++blkY )
1032  {
1033  for( blkX = 0 ; blkX < paramsPtr->m_rasterBlocksStatusPtr->getColumnsNumber() ;
1034  ++blkX )
1035  {
1036  paramsPtr->m_mutexPtr->lock();
1037 
1038  if( paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) )
1039  {
1040  paramsPtr->m_mutexPtr->unlock();
1041  }
1042  else
1043  {
1044  paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) = true;
1045 
1046  paramsPtr->m_inputBandPtr->read( blkX, blkY, blockBuffer.get() );
1047 
1048  paramsPtr->m_mutexPtr->unlock();
1049 
1050  Convert2DoublesVector( blockBuffer.get(), blockDataType, blockElementsNumber,
1051  doubleBuffer.get() );
1052 
1053  for( elementIdx = 0 ; elementIdx < blockElementsNumber ; ++elementIdx )
1054  {
1055  if( noDataValue != doubleBuffer[ elementIdx ] )
1056  {
1057  mean =
1058  (
1059  (
1060  mean
1061  *
1062  meanElementsNumber
1063  )
1064  +
1065  doubleBuffer[ elementIdx ]
1066  )
1067  /
1068  (
1069  meanElementsNumber
1070  +
1071  1.0
1072  );
1073 
1074  meanElementsNumber = meanElementsNumber + 1.0;
1075  }
1076  }
1077  }
1078  }
1079  }
1080 
1081  paramsPtr->m_mutexPtr->lock();
1082  ( *(paramsPtr->m_meanValuePtr) ) =
1083  (
1084  (
1085  ( *(paramsPtr->m_meanValuePtr) )
1086  *
1087  ( *( paramsPtr->m_pixelsNumberValuePtr ) )
1088  )
1089  +
1090  (
1091  mean
1092  *
1093  meanElementsNumber
1094  )
1095  )
1096  /
1097  (
1098  ( *( paramsPtr->m_pixelsNumberValuePtr ) )
1099  +
1100  meanElementsNumber
1101  );
1102  ( *( paramsPtr->m_pixelsNumberValuePtr ) ) += meanElementsNumber;
1103  paramsPtr->m_mutexPtr->unlock();
1104  }
1105 
1106  bool GetMeanValue( const te::rst::Band& band,
1107  const unsigned int maxThreads,
1108  double& meanValue )
1109  {
1110  Matrix< bool > rasterBlocksStatus;
1111  if( ! rasterBlocksStatus.reset( band.getProperty()->m_nblocksy,
1113  {
1114  return false;
1115  }
1116  for( unsigned int row = 0 ; row < rasterBlocksStatus.getLinesNumber() ;
1117  ++row )
1118  {
1119  for( unsigned int col = 0 ; col < rasterBlocksStatus.getColumnsNumber() ;
1120  ++col )
1121  {
1122  rasterBlocksStatus( row, col ) = false;
1123  }
1124  }
1125 
1126  meanValue = 0.0;
1127 
1128  double pixelsNumber = 0.0;
1129 
1130  boost::mutex mutex;
1131 
1132  GetMeanValueThreadParams params;
1133  params.m_inputBandPtr = &band;
1134  params.m_rasterBlocksStatusPtr = &rasterBlocksStatus;
1135  params.m_meanValuePtr = &meanValue;
1136  params.m_pixelsNumberValuePtr = &pixelsNumber;
1137  params.m_returnStatus = true;
1138  params.m_mutexPtr = &mutex;
1139 
1140  if( maxThreads == 1 )
1141  {
1142  GetMeanValueThread( &params );
1143  }
1144  else
1145  {
1146  unsigned int threadsNumber = maxThreads ? maxThreads : te::common::GetPhysProcNumber();
1147 
1148  boost::thread_group threads;
1149 
1150  for( unsigned int threadIdx = 0 ; threadIdx < threadsNumber ;
1151  ++threadIdx )
1152  {
1153  threads.add_thread( new boost::thread( GetMeanValueThread,
1154  &params ) );
1155  };
1156 
1157  threads.join_all();
1158  }
1159 
1160  return params.m_returnStatus;
1161  }
1162 
1164  {
1165  paramsPtr->m_mutexPtr->lock();
1166  const unsigned int blockElementsNumber = paramsPtr->m_inputBandPtr->getProperty()->m_blkh *
1167  paramsPtr->m_inputBandPtr->getProperty()->m_blkw;
1168  const int blockDataType = paramsPtr->m_inputBandPtr->getProperty()->getType();
1169  const int blockSizeBytes = paramsPtr->m_inputBandPtr->getBlockSize();
1170  const double noDataValue = paramsPtr->m_inputBandPtr->getProperty()->m_noDataValue;
1171  const double& meanValue = paramsPtr->m_meanValue;
1172  paramsPtr->m_mutexPtr->unlock();
1173 
1174  boost::scoped_array< unsigned char > blockBuffer( new unsigned char[ blockSizeBytes ] );
1175  boost::scoped_array< double > doubleBuffer( new double[ blockElementsNumber ] );
1176  unsigned blkX = 0;
1177  unsigned int elementIdx = 0;
1178  double diff = 0;
1179  double squaresDifsSum = 0;
1180  double elementsNumber = 0;
1181 
1182 
1183  for( unsigned blkY = 0 ; blkY < paramsPtr->m_rasterBlocksStatusPtr->getLinesNumber() ;
1184  ++blkY )
1185  {
1186  for( blkX = 0 ; blkX < paramsPtr->m_rasterBlocksStatusPtr->getColumnsNumber() ;
1187  ++blkX )
1188  {
1189  paramsPtr->m_mutexPtr->lock();
1190 
1191  if( paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) )
1192  {
1193  paramsPtr->m_mutexPtr->unlock();
1194  }
1195  else
1196  {
1197  paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) = true;
1198 
1199  paramsPtr->m_inputBandPtr->read( blkX, blkY, blockBuffer.get() );
1200 
1201  paramsPtr->m_mutexPtr->unlock();
1202 
1203  Convert2DoublesVector( blockBuffer.get(), blockDataType, blockElementsNumber,
1204  doubleBuffer.get() );
1205 
1206  for( elementIdx = 0 ; elementIdx < blockElementsNumber ; ++elementIdx )
1207  {
1208  if( noDataValue != doubleBuffer[ elementIdx ] )
1209  {
1210  diff = doubleBuffer[ elementIdx ] - meanValue;
1211  diff *= diff;
1212  squaresDifsSum += diff;
1213  elementsNumber = elementsNumber + 1.0;
1214  }
1215  }
1216  }
1217  }
1218  }
1219 
1220  paramsPtr->m_mutexPtr->lock();
1221  ( *(paramsPtr->m_stdDevValuePtr) ) =
1222  (
1223  ( *(paramsPtr->m_stdDevValuePtr) )
1224  +
1225  squaresDifsSum
1226  );
1227  ( *( paramsPtr->m_pixelsNumberValuePtr ) ) += elementsNumber;
1228  paramsPtr->m_mutexPtr->unlock();
1229  }
1230 
1231  bool GetStdDevValue( const te::rst::Band& band,
1232  const unsigned int maxThreads, double const * const meanValuePtr,
1233  double& stdDevValue )
1234  {
1235  double mean = 0;
1236  if( meanValuePtr )
1237  {
1238  mean = (*meanValuePtr);
1239  }
1240  else
1241  {
1242  if( ! GetMeanValue( band, maxThreads, mean ) )
1243  {
1244  return false;
1245  }
1246  }
1247 
1248  Matrix< bool > rasterBlocksStatus;
1249  if( ! rasterBlocksStatus.reset( band.getProperty()->m_nblocksy,
1251  {
1252  return false;
1253  }
1254  for( unsigned int row = 0 ; row < rasterBlocksStatus.getLinesNumber() ;
1255  ++row )
1256  {
1257  for( unsigned int col = 0 ; col < rasterBlocksStatus.getColumnsNumber() ;
1258  ++col )
1259  {
1260  rasterBlocksStatus( row, col ) = false;
1261  }
1262  }
1263 
1264  stdDevValue = 0.0;
1265 
1266  double pixelsNumber = 0.0;
1267 
1268  boost::mutex mutex;
1269 
1271  params.m_inputBandPtr = &band;
1272  params.m_rasterBlocksStatusPtr = &rasterBlocksStatus;
1273  params.m_stdDevValuePtr = &stdDevValue;
1274  params.m_pixelsNumberValuePtr = &pixelsNumber;
1275  params.m_meanValue = mean;
1276  params.m_returnStatus = true;
1277  params.m_mutexPtr = &mutex;
1278 
1279  if( maxThreads == 1 )
1280  {
1281  GetStdDevValueThread( &params );
1282  }
1283  else
1284  {
1285  unsigned int threadsNumber = maxThreads ? maxThreads : te::common::GetPhysProcNumber();
1286 
1287  boost::thread_group threads;
1288 
1289  for( unsigned int threadIdx = 0 ; threadIdx < threadsNumber ;
1290  ++threadIdx )
1291  {
1292  threads.add_thread( new boost::thread( GetStdDevValueThread,
1293  &params ) );
1294  };
1295 
1296  threads.join_all();
1297  }
1298 
1299  stdDevValue = std::sqrt( stdDevValue / pixelsNumber );
1300 
1301  return params.m_returnStatus;
1302  }
1303 
1305  {
1306  paramsPtr->m_mutexPtr->lock();
1307  const unsigned int blockElementsNumber = paramsPtr->m_inputBand1Ptr->getProperty()->m_blkh *
1308  paramsPtr->m_inputBand1Ptr->getProperty()->m_blkw;
1309  const int blockDataType1 = paramsPtr->m_inputBand1Ptr->getProperty()->getType();
1310  const int blockDataType2 = paramsPtr->m_inputBand2Ptr->getProperty()->getType();
1311  const int blockSizeBytes1 = paramsPtr->m_inputBand1Ptr->getBlockSize();
1312  const int blockSizeBytes2 = paramsPtr->m_inputBand2Ptr->getBlockSize();
1313  const double noDataValue1 = paramsPtr->m_inputBand1Ptr->getProperty()->m_noDataValue;
1314  const double noDataValue2 = paramsPtr->m_inputBand2Ptr->getProperty()->m_noDataValue;
1315  paramsPtr->m_mutexPtr->unlock();
1316 
1317  boost::scoped_array< unsigned char > blockBuffer1( new unsigned char[ blockSizeBytes1 ] );
1318  boost::scoped_array< unsigned char > blockBuffer2( new unsigned char[ blockSizeBytes2 ] );
1319  boost::scoped_array< double > doubleBuffer1( new double[ blockElementsNumber ] );
1320  boost::scoped_array< double > doubleBuffer2( new double[ blockElementsNumber ] );
1321  unsigned blkX = 0;
1322  unsigned int elementIdx = 0;
1323  double covariance = 0;
1324  double elementsNumber = 0;
1325  double diff1 = 0;
1326  double diff2 = 0;
1327 
1328  for( unsigned blkY = 0 ; blkY < paramsPtr->m_rasterBlocksStatusPtr->getLinesNumber() ;
1329  ++blkY )
1330  {
1331  for( blkX = 0 ; blkX < paramsPtr->m_rasterBlocksStatusPtr->getColumnsNumber() ;
1332  ++blkX )
1333  {
1334  paramsPtr->m_mutexPtr->lock();
1335 
1336  if( paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) )
1337  {
1338  paramsPtr->m_mutexPtr->unlock();
1339  }
1340  else
1341  {
1342  paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) = true;
1343 
1344  paramsPtr->m_inputBand1Ptr->read( blkX, blkY, blockBuffer1.get() );
1345  paramsPtr->m_inputBand2Ptr->read( blkX, blkY, blockBuffer2.get() );
1346 
1347  paramsPtr->m_mutexPtr->unlock();
1348 
1349  Convert2DoublesVector( blockBuffer1.get(), blockDataType1, blockElementsNumber,
1350  doubleBuffer1.get() );
1351  Convert2DoublesVector( blockBuffer2.get(), blockDataType2, blockElementsNumber,
1352  doubleBuffer2.get() );
1353 
1354  for( elementIdx = 0 ; elementIdx < blockElementsNumber ; ++elementIdx )
1355  {
1356  if( ( noDataValue1 != doubleBuffer1[ elementIdx ] ) &&
1357  ( noDataValue2 != doubleBuffer2[ elementIdx ] ) )
1358  {
1359  diff1 = doubleBuffer1[ elementIdx ] - paramsPtr->m_mean1Value;
1360  diff2 = doubleBuffer2[ elementIdx ] - paramsPtr->m_mean2Value;
1361 
1362  covariance += ( diff1 * diff2 );
1363 
1364  elementsNumber = elementsNumber + 1.0;
1365  }
1366  }
1367  }
1368  }
1369  }
1370 
1371  paramsPtr->m_mutexPtr->lock();
1372  ( *(paramsPtr->m_covarianceValuePtr) ) += covariance;
1373  ( *( paramsPtr->m_pixelsNumberValuePtr ) ) += elementsNumber;
1374  paramsPtr->m_mutexPtr->unlock();
1375  }
1376 
1377  bool GetCovarianceValue( const te::rst::Band& band1,
1378  const te::rst::Band& band2, const unsigned int maxThreads,
1379  double const * const mean1ValuePtr, double const * const mean2ValuePtr,
1380  double& covarianceValue )
1381  {
1382  if( ( band1.getProperty()->m_blkw * band1.getProperty()->m_nblocksx ) !=
1383  ( band2.getProperty()->m_blkw * band2.getProperty()->m_nblocksx ) )
1384  {
1385  return false;
1386  }
1387 
1388  if( ( band1.getProperty()->m_blkh * band1.getProperty()->m_nblocksy ) !=
1389  ( band2.getProperty()->m_blkh * band2.getProperty()->m_nblocksy ) )
1390  {
1391  return false;
1392  }
1393 
1394  double mean1 = 0;
1395  if( mean1ValuePtr )
1396  {
1397  mean1 = (*mean1ValuePtr);
1398  }
1399  else
1400  {
1401  if( ! GetMeanValue( band1, maxThreads, mean1 ) )
1402  {
1403  return false;
1404  }
1405  }
1406 
1407  double mean2 = 0;
1408  if( mean2ValuePtr )
1409  {
1410  mean2 = (*mean2ValuePtr);
1411  }
1412  else
1413  {
1414  if( ! GetMeanValue( band2, maxThreads, mean2 ) )
1415  {
1416  return false;
1417  }
1418  }
1419 
1420  if( ( band1.getProperty()->m_blkw == band2.getProperty()->m_blkw )
1421  && ( band1.getProperty()->m_blkh == band2.getProperty()->m_blkh )
1422  && ( band1.getProperty()->m_nblocksx == band2.getProperty()->m_nblocksx )
1423  && ( band1.getProperty()->m_nblocksy == band2.getProperty()->m_nblocksy ) )
1424  {
1425  Matrix< bool > rasterBlocksStatus;
1426  if( ! rasterBlocksStatus.reset( band1.getProperty()->m_nblocksy,
1428  {
1429  return false;
1430  }
1431  for( unsigned int row = 0 ; row < rasterBlocksStatus.getLinesNumber() ;
1432  ++row )
1433  {
1434  for( unsigned int col = 0 ; col < rasterBlocksStatus.getColumnsNumber() ;
1435  ++col )
1436  {
1437  rasterBlocksStatus( row, col ) = false;
1438  }
1439  }
1440 
1441  covarianceValue = 0.0;
1442 
1443  double pixelsNumber = 0.0;
1444 
1445  boost::mutex mutex;
1446 
1448  params.m_inputBand1Ptr = &band1;
1449  params.m_inputBand2Ptr = &band2;
1450  params.m_rasterBlocksStatusPtr = &rasterBlocksStatus;
1451  params.m_covarianceValuePtr = &covarianceValue;
1452  params.m_pixelsNumberValuePtr = &pixelsNumber;
1453  params.m_returnStatus = true;
1454  params.m_mutexPtr = &mutex;
1455  params.m_mean1Value = mean1;
1456  params.m_mean2Value = mean2;
1457 
1458  if( maxThreads == 1 )
1459  {
1460  GetCovarianceValueThread( &params );
1461  }
1462  else
1463  {
1464  unsigned int threadsNumber = maxThreads ? maxThreads : te::common::GetPhysProcNumber();
1465 
1466  boost::thread_group threads;
1467 
1468  for( unsigned int threadIdx = 0 ; threadIdx < threadsNumber ;
1469  ++threadIdx )
1470  {
1471  threads.add_thread( new boost::thread( GetCovarianceValueThread,
1472  &params ) );
1473  };
1474 
1475  threads.join_all();
1476  }
1477 
1478  if( pixelsNumber != 0.0 )
1479  {
1480  covarianceValue /= pixelsNumber;
1481  }
1482 
1483  return params.m_returnStatus;
1484  }
1485  else
1486  {
1487  const unsigned int nCols = band1.getProperty()->m_blkw * band1.getProperty()->m_nblocksx;
1488  const unsigned int nRows = band1.getProperty()->m_blkh * band1.getProperty()->m_nblocksy;
1489  double value1 = 0;
1490  double value2 = 0;
1491  const double noDataValue1 = band1.getProperty()->m_noDataValue;
1492  const double noDataValue2 = band2.getProperty()->m_noDataValue;
1493  unsigned int col = 0;
1494  double pixelsNumber = 0.0;
1495 
1496  covarianceValue = 0;
1497 
1498  for( unsigned int row = 0 ; row < nRows ; ++row )
1499  {
1500  for( col = 0 ; col < nCols ; ++col )
1501  {
1502  band1.getValue( col, row, value1 );
1503  band2.getValue( col, row, value2 );
1504 
1505  if( ( noDataValue1 != value1 ) &&
1506  ( noDataValue2 != value2 ) )
1507  {
1508  covarianceValue += ( ( value1 - mean1 ) * ( value2 - mean2 ) );
1509 
1510  pixelsNumber = pixelsNumber + 1.0;
1511  }
1512  }
1513  }
1514 
1515  if( pixelsNumber != 0.0 )
1516  {
1517  covarianceValue /= pixelsNumber;
1518  }
1519 
1520  return true;
1521  }
1522  }
1523 
1525  const te::rst::Raster& inputRaster,
1526  const std::vector< unsigned int >& inputRasterBands,
1527  boost::numeric::ublas::matrix< double >& pcaMatrix,
1528  te::rst::Raster& pcaRaster,
1529  const unsigned int maxThreads )
1530  {
1531  if( ( inputRaster.getAccessPolicy() & te::common::RAccess ) == 0 )
1532  {
1533  return false;
1534  }
1535  if( ( pcaRaster.getAccessPolicy() & te::common::WAccess ) == 0 )
1536  {
1537  return false;
1538  }
1539  if( inputRaster.getNumberOfBands() != pcaRaster.getNumberOfBands() )
1540  {
1541  return false;
1542  }
1543  if( pcaRaster.getNumberOfBands() != inputRasterBands.size() )
1544  {
1545  return false;
1546  }
1547  if( inputRaster.getNumberOfRows() != pcaRaster.getNumberOfRows() )
1548  {
1549  return false;
1550  }
1551  if( inputRaster.getNumberOfColumns() != pcaRaster.getNumberOfColumns() )
1552  {
1553  return false;
1554  }
1555 
1556  // Covariance matrix
1557 
1558  boost::numeric::ublas::matrix< double > covarianceMatrix;
1559 
1560  covarianceMatrix.resize( inputRasterBands.size(), inputRasterBands.size() );
1561 
1562  for( unsigned int covMatrixIdx1 = 0 ; covMatrixIdx1 < inputRasterBands.size() ;
1563  ++covMatrixIdx1 )
1564  {
1565  if( inputRasterBands[ covMatrixIdx1 ] >= inputRaster.getNumberOfBands() )
1566  {
1567  return false;
1568  }
1569 
1570  for( unsigned int covMatrixIdx2 = 0 ; covMatrixIdx2 < inputRasterBands.size() ;
1571  ++covMatrixIdx2 )
1572  {
1573  if( inputRasterBands[ covMatrixIdx2 ] >= inputRaster.getNumberOfBands() )
1574  {
1575  return false;
1576  }
1577 
1578  if( covMatrixIdx1 > covMatrixIdx2 )
1579  {
1580  covarianceMatrix( covMatrixIdx1, covMatrixIdx2 ) =
1581  covarianceMatrix( covMatrixIdx2, covMatrixIdx1 );
1582  }
1583  else
1584  {
1585  if( ! GetCovarianceValue( *( inputRaster.getBand( inputRasterBands[ covMatrixIdx1 ] ) ),
1586  *( inputRaster.getBand( inputRasterBands[ covMatrixIdx2 ] ) ),
1587  maxThreads, 0, 0, covarianceMatrix( covMatrixIdx1, covMatrixIdx2 ) ) )
1588  {
1589  return false;
1590  }
1591  }
1592  }
1593  }
1594 
1595 //std::cout << std::endl << "Covariance matrix:" << covarianceMatrix << std::endl;
1596 
1597  // Eigen stuff
1598 
1599  boost::numeric::ublas::matrix< double > eigenValues;
1600  boost::numeric::ublas::matrix< double > eigenVectors;
1601 
1602  if( ! te::common::EigenVectors( covarianceMatrix, eigenVectors, eigenValues ) )
1603  {
1604  return false;
1605  }
1606 
1607  pcaMatrix = boost::numeric::ublas::trans( eigenVectors );
1608 
1609  return RemapValues( inputRaster, inputRasterBands, pcaMatrix, pcaRaster, maxThreads );
1610  }
1611 
1613  const te::rst::Raster& pcaRaster,
1614  const boost::numeric::ublas::matrix< double >& pcaMatrix,
1615  te::rst::Raster& outputRaster,
1616  const unsigned int maxThreads )
1617  {
1618  boost::numeric::ublas::matrix< double > inversePcaMatrix;
1619  if( ! te::common::GetInverseMatrix( pcaMatrix, inversePcaMatrix ) )
1620  {
1621  return false;
1622  }
1623 
1624  std::vector< unsigned int > inputRasterBands;
1625 
1626  for( unsigned int bandIdx = 0 ; bandIdx < pcaRaster.getNumberOfBands() ;
1627  ++bandIdx )
1628  {
1629  inputRasterBands.push_back( bandIdx );
1630  }
1631 
1632  return RemapValues( pcaRaster, inputRasterBands, inversePcaMatrix,
1633  outputRaster, maxThreads );
1634  }
1635 
1637  {
1638  paramsPtr->m_mutexPtr->lock();
1639 
1640  assert( paramsPtr->m_inputRasterBandsPtr->operator[]( 0 ) <
1641  paramsPtr->m_inputRasterPtr->getNumberOfBands() );
1642  const unsigned int blockElementsNumber = paramsPtr->m_inputRasterPtr->getBand(
1643  paramsPtr->m_inputRasterBandsPtr->operator[]( 0 ) )->getProperty()->m_blkh *
1644  paramsPtr->m_inputRasterPtr->getBand( paramsPtr->m_inputRasterBandsPtr->operator[]( 0 ) )->getProperty()->m_blkw;
1645 
1646  const std::vector< unsigned int > inputRasterBands = *( paramsPtr->m_inputRasterBandsPtr );
1647  const unsigned int inputRasterBandsSize = (unsigned int)inputRasterBands.size();
1648  assert( inputRasterBandsSize == paramsPtr->m_outputRasterPtr->getNumberOfBands() );
1649 
1650  unsigned int maxBlocksSizesBytes = 0;
1651  std::vector< double > inputBandsNoDataValues( inputRasterBandsSize, 0.0 );
1652  std::vector< double > outputBandsNoDataValues( inputRasterBandsSize, 0.0 );
1653  std::vector< boost::shared_array< double > > inDoubleBuffersHandlers( inputRasterBandsSize );
1654  std::vector< boost::shared_array< double > > outDoubleBuffersHandlers( inputRasterBandsSize );
1655  unsigned int inputRasterBandsIdx = 0;
1656  boost::numeric::ublas::matrix< double > remapMatrix = *( paramsPtr->m_remapMatrixPtr );
1657  std::vector< double > outputMinValue( inputRasterBandsSize );
1658  std::vector< double > outputMaxValue( inputRasterBandsSize );
1659  boost::shared_array< double* > inDoubleBuffersPtrsHandler( new double*[ inputRasterBandsSize ] );
1660  boost::shared_array< double* > outDoubleBuffersPtrsHandler( new double*[ inputRasterBandsSize ] );
1661  double** inDoubleBuffers = inDoubleBuffersPtrsHandler.get();
1662  double** outDoubleBuffers = outDoubleBuffersPtrsHandler.get();
1663 
1664  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
1665  ++inputRasterBandsIdx )
1666  {
1667  const unsigned int& inBandIdx = inputRasterBands[ inputRasterBandsIdx ];
1668  assert( inBandIdx < paramsPtr->m_inputRasterPtr->getNumberOfBands() );
1669 
1670  te::rst::Band const * const inBandPtr = paramsPtr->m_inputRasterPtr->getBand( inBandIdx );
1671  te::rst::Band * const outBandPtr = paramsPtr->m_outputRasterPtr->getBand( inputRasterBandsIdx );
1672 
1673  maxBlocksSizesBytes = std::max( maxBlocksSizesBytes, (unsigned int)inBandPtr->getBlockSize() );
1674  maxBlocksSizesBytes = std::max( maxBlocksSizesBytes, (unsigned int)outBandPtr->getBlockSize() );
1675 
1676  inputBandsNoDataValues[ inputRasterBandsIdx ] = inBandPtr->getProperty()->m_noDataValue;
1677  outputBandsNoDataValues[ inputRasterBandsIdx ] = outBandPtr->getProperty()->m_noDataValue;
1678 
1679  inDoubleBuffersHandlers[ inputRasterBandsIdx ].reset( new double[ blockElementsNumber ] );
1680  inDoubleBuffers[ inputRasterBandsIdx ] = inDoubleBuffersHandlers[ inputRasterBandsIdx ].get();
1681 
1682  outDoubleBuffersHandlers[ inputRasterBandsIdx ].reset( new double[ blockElementsNumber ] );
1683  outDoubleBuffers[ inputRasterBandsIdx ] = outDoubleBuffersHandlers[ inputRasterBandsIdx ].get();
1684 
1686  outBandPtr->getProperty()->getType(),
1687  outputMinValue[ inputRasterBandsIdx ],
1688  outputMaxValue[ inputRasterBandsIdx ] );
1689  }
1690 
1691  paramsPtr->m_mutexPtr->unlock();
1692 
1693  boost::scoped_array< unsigned char > blockBuffer( new unsigned char[ maxBlocksSizesBytes ] );
1694  unsigned blkX = 0;
1695  unsigned int elementIdx = 0;
1696  boost::numeric::ublas::matrix< double > pixelValues( inputRasterBandsSize, 1 );
1697  boost::numeric::ublas::matrix< double > remappedPixelValues( inputRasterBandsSize, 1 );
1698  bool elementIsValid = false;
1699 
1700  for( unsigned blkY = 0 ; blkY < paramsPtr->m_rasterBlocksStatusPtr->getLinesNumber() ;
1701  ++blkY )
1702  {
1703  for( blkX = 0 ; blkX < paramsPtr->m_rasterBlocksStatusPtr->getColumnsNumber() ;
1704  ++blkX )
1705  {
1706  paramsPtr->m_mutexPtr->lock();
1707 
1708  if( paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) )
1709  {
1710  paramsPtr->m_mutexPtr->unlock();
1711  }
1712  else
1713  {
1714  paramsPtr->m_rasterBlocksStatusPtr->operator()( blkY, blkX ) = true;
1715 
1716  // reading the input blocks
1717 
1718  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
1719  ++inputRasterBandsIdx )
1720  {
1721  const unsigned int& inBandIdx = inputRasterBands[ inputRasterBandsIdx ];
1722  te::rst::Band const * const inBandPtr = paramsPtr->m_inputRasterPtr->getBand( inBandIdx );
1723 
1724  inBandPtr->read( blkX, blkY, blockBuffer.get() );
1725  Convert2DoublesVector( blockBuffer.get(),
1726  inBandPtr->getProperty()->getType(),
1727  blockElementsNumber,
1728  inDoubleBuffers[ inputRasterBandsIdx ] );
1729  }
1730 
1731  paramsPtr->m_mutexPtr->unlock();
1732 
1733  // Remapping the values using the remap matrix
1734 
1735  for( elementIdx = 0 ; elementIdx < blockElementsNumber ; ++elementIdx )
1736  {
1737  elementIsValid = true;
1738 
1739  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
1740  ++inputRasterBandsIdx )
1741  {
1742  if( inDoubleBuffers[ inputRasterBandsIdx ][ elementIdx ] ==
1743  inputBandsNoDataValues[ inputRasterBandsIdx ] )
1744  {
1745  elementIsValid = false;
1746  break;
1747  }
1748  else
1749  {
1750  pixelValues( inputRasterBandsIdx, 0 ) =
1751  inDoubleBuffers[ inputRasterBandsIdx ][ elementIdx ];
1752  }
1753  }
1754 
1755  if( elementIsValid )
1756  {
1757 //std::cout << std::endl << "pixelValues:" << pixelValues << std::endl;
1758 
1759  remappedPixelValues = boost::numeric::ublas::prod( remapMatrix, pixelValues );
1760 
1761 //std::cout << std::endl << "remappedPixelValues:" << remappedPixelValues << std::endl;
1762 
1763  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
1764  ++inputRasterBandsIdx )
1765  {
1766  outDoubleBuffers[ inputRasterBandsIdx ][ elementIdx ] =
1767  std::max(
1768  outputMinValue[ inputRasterBandsIdx ],
1769  std::min(
1770  outputMaxValue[ inputRasterBandsIdx ],
1771  remappedPixelValues( inputRasterBandsIdx, 0 )
1772  )
1773  );
1774  }
1775  }
1776  }
1777 
1778  // Writing the remmaped blocks
1779 
1780  paramsPtr->m_mutexPtr->lock();
1781 
1782  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
1783  ++inputRasterBandsIdx )
1784  {
1785  te::rst::Band* outBandPtr = paramsPtr->m_outputRasterPtr->getBand( inputRasterBandsIdx );
1786 
1787  ConvertDoublesVector( outDoubleBuffers[ inputRasterBandsIdx ],
1788  blockElementsNumber, outBandPtr->getProperty()->getType(),
1789  blockBuffer.get() );
1790 
1791  outBandPtr->write( blkX, blkY, blockBuffer.get() );
1792  }
1793 
1794  paramsPtr->m_mutexPtr->unlock();
1795  }
1796  }
1797  }
1798 
1799  }
1800 
1802  const te::rst::Raster& inputRaster,
1803  const std::vector< unsigned int >& inputRasterBands,
1804  const boost::numeric::ublas::matrix< double >& remapMatrix,
1805  te::rst::Raster& outputRaster,
1806  const unsigned int maxThreads )
1807  {
1808  if( ( inputRaster.getAccessPolicy() & te::common::RAccess ) == 0 )
1809  {
1810  return false;
1811  }
1812  if( ( outputRaster.getAccessPolicy() & te::common::WAccess ) == 0 )
1813  {
1814  return false;
1815  }
1816  if( remapMatrix.size1() != inputRasterBands.size() )
1817  {
1818  return false;
1819  }
1820  if( remapMatrix.size2() != inputRasterBands.size() )
1821  {
1822  return false;
1823  }
1824  if( outputRaster.getNumberOfBands() != inputRasterBands.size() )
1825  {
1826  return false;
1827  }
1828  if( inputRaster.getNumberOfRows() != outputRaster.getNumberOfRows() )
1829  {
1830  return false;
1831  }
1832  if( inputRaster.getNumberOfColumns() != outputRaster.getNumberOfColumns() )
1833  {
1834  return false;
1835  }
1836 
1837  // Checking if optmized PCA can be executed
1838 
1839  bool useOptimizedRemap = true;
1840 
1841  {
1842  for( unsigned int inputRasterBandsIdx = 0 ; inputRasterBandsIdx <
1843  inputRaster.getNumberOfBands() ; ++inputRasterBandsIdx )
1844  {
1845  if(
1846  (
1847  inputRaster.getBand( inputRasterBands[ inputRasterBandsIdx ] )->getProperty()->m_blkw
1848  !=
1849  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_blkw
1850  )
1851  ||
1852  (
1853  inputRaster.getBand( inputRasterBands[ inputRasterBandsIdx ] )->getProperty()->m_blkh
1854  !=
1855  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_blkh
1856  )
1857  ||
1858  (
1859  inputRaster.getBand( inputRasterBands[ inputRasterBandsIdx ] )->getProperty()->m_nblocksx
1860  !=
1861  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_nblocksx
1862  )
1863  ||
1864  (
1865  inputRaster.getBand( inputRasterBands[ inputRasterBandsIdx ] )->getProperty()->m_nblocksy
1866  !=
1867  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_nblocksy
1868  )
1869  ||
1870  (
1871  outputRaster.getBand( inputRasterBandsIdx )->getProperty()->m_blkw
1872  !=
1873  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_blkw
1874  )
1875  ||
1876  (
1877  outputRaster.getBand( inputRasterBandsIdx )->getProperty()->m_blkh
1878  !=
1879  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_blkh
1880  )
1881  ||
1882  (
1883  outputRaster.getBand( inputRasterBandsIdx )->getProperty()->m_nblocksx
1884  !=
1885  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_nblocksx
1886  )
1887  ||
1888  (
1889  outputRaster.getBand( inputRasterBandsIdx )->getProperty()->m_nblocksy
1890  !=
1891  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_nblocksy
1892  )
1893  )
1894  {
1895  useOptimizedRemap = false;
1896  break;
1897  }
1898  }
1899  }
1900 
1901  // remapping
1902 
1903  if( useOptimizedRemap )
1904  {
1905  Matrix< bool > rasterBlocksStatus;
1906  if( ! rasterBlocksStatus.reset(
1907  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_nblocksy,
1908  inputRaster.getBand( inputRasterBands[ 0 ] )->getProperty()->m_nblocksx,
1910  {
1911  return false;
1912  }
1913  for( unsigned int row = 0 ; row < rasterBlocksStatus.getLinesNumber() ;
1914  ++row )
1915  {
1916  for( unsigned int col = 0 ; col < rasterBlocksStatus.getColumnsNumber() ;
1917  ++col )
1918  {
1919  rasterBlocksStatus( row, col ) = false;
1920  }
1921  }
1922 
1923  boost::mutex mutex;
1924 
1925  RemapValuesThreadParams params;
1926  params.m_inputRasterPtr = &inputRaster;
1927  params.m_inputRasterBandsPtr = &inputRasterBands;
1928  params.m_outputRasterPtr = &outputRaster;
1929  params.m_remapMatrixPtr = &remapMatrix;
1930  params.m_rasterBlocksStatusPtr = &rasterBlocksStatus;
1931  params.m_returnStatus = true;
1932  params.m_mutexPtr = &mutex;
1933 
1934  if( maxThreads == 1 )
1935  {
1936  RemapValuesThread( &params );
1937  }
1938  else
1939  {
1940  unsigned int threadsNumber = maxThreads ? maxThreads : te::common::GetPhysProcNumber();
1941 
1942  boost::thread_group threads;
1943 
1944  for( unsigned int threadIdx = 0 ; threadIdx < threadsNumber ;
1945  ++threadIdx )
1946  {
1947  threads.add_thread( new boost::thread( RemapValuesThread,
1948  &params ) );
1949  };
1950 
1951  threads.join_all();
1952  }
1953 
1954  return params.m_returnStatus;
1955  }
1956  else
1957  {
1958  const unsigned int inputRasterBandsSize = inputRasterBands.size();
1959  const unsigned int nRows = inputRaster.getNumberOfRows();
1960  const unsigned int nCols = inputRaster.getNumberOfColumns();
1961  boost::numeric::ublas::matrix< double > pixelValues( inputRasterBands.size(), 1 );
1962  boost::numeric::ublas::matrix< double > remappedPixelValues( inputRasterBands.size(), 1 );
1963  std::vector< double > inputNoDataValues( inputRasterBandsSize );
1964  std::vector< double > outputNoDataValues( inputRasterBandsSize );
1965  std::vector< double > outputMinValue( inputRasterBandsSize );
1966  std::vector< double > outputMaxValue( inputRasterBandsSize );
1967  unsigned int inputRasterBandsIdx = 0;
1968  unsigned int row = 0;
1969  unsigned int col = 0;
1970  bool pixelIsValid = false;
1971 
1972  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
1973  ++inputRasterBandsIdx )
1974  {
1975  if( inputRasterBands[ inputRasterBandsIdx ] >= inputRaster.getNumberOfBands() )
1976  {
1977  return false;
1978  }
1979 
1980  inputNoDataValues[ inputRasterBandsIdx ] = inputRaster.getBand(
1981  inputRasterBands[ inputRasterBandsIdx ] )->getProperty()->m_noDataValue;
1982 
1983  outputNoDataValues[ inputRasterBandsIdx ] = outputRaster.getBand(
1984  inputRasterBandsIdx )->getProperty()->m_noDataValue;
1985 
1987  outputRaster.getBand( inputRasterBandsIdx )->getProperty()->getType(),
1988  outputMinValue[ inputRasterBandsIdx ],
1989  outputMaxValue[ inputRasterBandsIdx ] );
1990  }
1991 
1992  for( row = 0 ; row < nRows ; ++row )
1993  {
1994  for( col = 0 ; col < nCols ; ++col )
1995  {
1996  pixelIsValid = true;
1997 
1998  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
1999  ++inputRasterBandsIdx )
2000  {
2001  inputRaster.getValue( col, row, pixelValues( inputRasterBandsIdx, 0 ),
2002  inputRasterBands[ inputRasterBandsIdx ] );
2003 
2004  if( pixelValues( inputRasterBandsIdx, 0 ) == inputNoDataValues[ inputRasterBandsIdx ] )
2005  {
2006  pixelIsValid = false;
2007  break;
2008  }
2009  }
2010 
2011  if( pixelIsValid )
2012  {
2013  remappedPixelValues = boost::numeric::ublas::prod( remapMatrix, pixelValues );
2014 
2015  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
2016  ++inputRasterBandsIdx )
2017  {
2018  outputRaster.setValue(
2019  col,
2020  row,
2021  std::max(
2022  outputMinValue[ inputRasterBandsIdx ]
2023  ,
2024  std::min(
2025  outputMaxValue[ inputRasterBandsIdx ]
2026  ,
2027  remappedPixelValues( inputRasterBandsIdx, 0 )
2028  )
2029  ),
2030  inputRasterBandsIdx );
2031  }
2032  }
2033  else
2034  {
2035  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx < inputRasterBandsSize ;
2036  ++inputRasterBandsIdx )
2037  {
2038  outputRaster.setValue( col, row, outputNoDataValues[ inputRasterBandsIdx ],
2039  inputRasterBandsIdx );
2040  }
2041  }
2042  }
2043  }
2044  }
2045 
2046  return true;
2047  }
2048 
2049  } // end namespace rp
2050 } // end namespace te
double GetDigitalNumberBandMax(std::string bandName)
Returns the maximum digital number of a given sensor/band.
Definition: Functions.cpp:697
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.
Definition: Raster.cpp:233
virtual std::complex< double > getMinValue(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0) const
It computes and returns the minimum occurring value in a window of the band.
Definition: Band.cpp:80
void reset()
Reset the internal state (all internal pointed objects are deleted).
te::rst::Raster * m_outputRasterPtr
Definition: Functions.cpp:113
TERASTEREXPORT void GetDataTypeRanges(const int &dataType, double &min, double &max)
Return the values range of a given data type.
Definition: Utils.cpp:331
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
Matrix< bool > * m_rasterBlocksStatusPtr
Definition: Functions.cpp:78
unsigned int getRow() const
Returns the current row in iterator.
A raster band description.
Definition: BandProperty.h:61
A class that models the description of a dataset.
Definition: DataSetType.h:72
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.
bool GetMeanValue(const te::rst::Band &band, const unsigned int maxThreads, double &meanValue)
Get the mean of band pixel values.
Definition: Functions.cpp:1106
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
This class implements and iterator to "navigate" over a raster, with a predefined number of bands...
virtual std::auto_ptr< DataSourceTransactor > getTransactor()=0
It returns an object that can execute transactions in the context of a data source.
bool ConvertIHS2RGB(const te::rst::Raster &inputIHSRaster, const unsigned int intensityBandIdx, const unsigned int hueBandIdx, const unsigned int saturationBandIdx, const double rgbRangeMin, const double rgbRangeMax, te::rst::Raster &outputRGBRaster)
IHS to RGB conversion.
Definition: Functions.cpp:893
std::vector< std::string > GetBandNames()
Returns a vector os with band's names.
Definition: Functions.cpp:557
bool CreateNewMemRaster(const te::rst::Grid &rasterGrid, std::vector< te::rst::BandProperty * > bandsProperties, RasterHandler &outRasterHandler)
Create a new raster into a new memory datasource.
Definition: Functions.cpp:225
#define MIN(a, b)
Macro that returns min between two values.
void release(std::auto_ptr< te::da::DataSource > &dataSourcePtr, std::auto_ptr< te::da::DataSourceTransactor > &transactorPtr, std::auto_ptr< te::da::DataSet > &dataSetPtr, std::auto_ptr< te::rst::Raster > &rasterPtr)
Relase the internal state and give the ownership to the given pointers.
virtual void read(int x, int y, void *buffer) const =0
It reads a data block to the specified buffer.
Matrix< bool > * m_rasterBlocksStatusPtr
Definition: Functions.cpp:115
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:118
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
Definition: BandProperty.h:136
te::rst::Band const * m_inputBandPtr
Definition: Functions.cpp:77
double GetSpectralBandMax(std::string bandName)
Returns the maximum reflectance value of a given sensor/band.
Definition: Functions.cpp:647
#define MAX(a, b)
Macro that returns max between two values.
Raster property.
Exception class.
Raster Processing functions.
bool ConvertRGB2IHS(const te::rst::Raster &inputRGBRaster, const unsigned int redBandIdx, const unsigned int greenBandIdx, const unsigned int blueBandIdx, const double rgbRangeMin, const double rgbRangeMax, te::rst::Raster &outputIHSRaster)
RGB to IHS conversion.
Definition: Functions.cpp:765
std::vector< unsigned int > const * m_inputRasterBandsPtr
Definition: Functions.cpp:112
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Definition: Raster.cpp:89
bool TERPEXPORT Copy2DiskRaster(const te::rst::Raster &inputRaster, const std::string &fileName)
Create a new raster into a GDAL datasource.
Definition: Functions.cpp:282
#define M_PI
Definition: Functions.cpp:68
TECOMMONEXPORT unsigned int GetPhysProcNumber()
Returns the number of physical processors.
te::rst::Band const * m_inputBand1Ptr
Definition: Functions.cpp:98
A point with x and y coordinate values.
Definition: Point.h:50
bool NormalizeRaster(te::rst::Raster &inraster, double nmin, double nmax)
Normalizes one raster in a given interval.
Definition: Functions.cpp:702
An abstract class for raster data strucutures.
Definition: Raster.h:71
static RasterIterator begin(Raster *r, const std::vector< unsigned int > &bands)
Returns an iterator referring to the first value.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
bool GetStdDevValue(const te::rst::Band &band, const unsigned int maxThreads, double const *const meanValuePtr, double &stdDevValue)
Get the standard deviation of band pixel values.
Definition: Functions.cpp:1231
unsigned int getColumnsNumber() const
The number of current matrix columns.
Definition: Matrix.h:678
static std::auto_ptr< DataSource > make(const std::string &dsType)
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:370
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.
std::pair< double, double > GetDigitalNumberBandInfo(std::string bandName)
Returns the maximun and minimum digital numbers of a given sensor/band.
Definition: Functions.cpp:652
te::rst::Raster const * m_inputRasterPtr
Definition: Functions.cpp:111
#define TERPEXPORT
You can use this macro in order to export/import classes and functions from this module.
Definition: Config.h:111
Raster tuple.
virtual void write(int x, int y, void *buffer)=0
It writes a data block from the specified buffer.
virtual std::complex< double > getMaxValue(unsigned int rs=0, unsigned int cs=0, unsigned int rf=0, unsigned int cf=0) const
It computes and returns the maximum occurring value in a window of the band.
Definition: Band.cpp:109
void Convert2DoublesVector(void *inputVector, const int inputVectorDataType, unsigned int inputVectorSize, double *outputVector)
Convert vector elements.
Definition: Functions.cpp:332
te::rst::Band const * m_inputBand2Ptr
Definition: Functions.cpp:99
RasterHandler.
Definition: RasterHandler.h:47
bool EigenVectors(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &eigenVectorsMatrix, boost::numeric::ublas::matrix< T > &eigenValuesMatrix)
Computes the eigenvectors of a given matrix.
Definition: MatrixUtils.h:211
void GetMeanValueThread(GetMeanValueThreadParams *paramsPtr)
Definition: Functions.cpp:1013
bool DirectPrincipalComponents(const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, boost::numeric::ublas::matrix< double > &pcaMatrix, te::rst::Raster &pcaRaster, const unsigned int maxThreads)
Generate all principal components from the given input raster.
Definition: Functions.cpp:1524
A raster band description.
Definition: Band.h:63
Matrix< bool > * m_rasterBlocksStatusPtr
Definition: Functions.cpp:88
Grid * getGrid()
It returns the raster grid.
Definition: Raster.cpp:94
std::vector< te::gm::Point * > GetRandomPointsInRaster(const te::rst::Raster &inputRaster, unsigned int numberOfPoints)
Creates a vector of random positions (points) inside the raster.
Definition: Functions.cpp:746
te::rst::Band const * m_inputBandPtr
Definition: Functions.cpp:87
void reset()
Reset (clear) the active instance data.
Definition: Matrix.h:480
virtual void getValue(unsigned int c, unsigned int r, double &value, std::size_t b=0) const
Returns the attribute value of a band of a cell.
Definition: Raster.cpp:228
void RemapValuesThread(RemapValuesThreadParams *paramsPtr)
Definition: Functions.cpp:1636
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
bool CreateNewRaster(const te::rst::Grid &rasterGrid, const std::vector< te::rst::BandProperty * > &bandsProperties, const std::string &outDataSetName, const std::string &dataSourceType, RasterHandler &outRasterHandler)
Create a new raster into the givem data source.
Definition: Functions.cpp:120
bool GetCovarianceValue(const te::rst::Band &band1, const te::rst::Band &band2, const unsigned int maxThreads, double const *const mean1ValuePtr, double const *const mean2ValuePtr, double &covarianceValue)
Get the covariance of band pixel values.
Definition: Functions.cpp:1377
int getSRID() const
Returns the raster spatial reference system identifier.
Definition: Raster.cpp:203
double GetSpectralBandMin(std::string bandName)
Returns the minimum reflectance value of a given sensor/band.
Definition: Functions.cpp:642
bool GetInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Matrix inversion.
Definition: MatrixUtils.h:104
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
bool InversePrincipalComponents(const te::rst::Raster &pcaRaster, const boost::numeric::ublas::matrix< double > &pcaMatrix, te::rst::Raster &outputRaster, const unsigned int maxThreads)
Regenerate the original raster from its principal components.
Definition: Functions.cpp:1612
static RasterIterator end(Raster *r, const std::vector< unsigned int > &bands)
Returns an iterator referring to after the end of the iterator.
te::rst::Raster * getRasterPtr()
Returns a pointer the the handled raster instance or NULL if no instance is handled.
unsigned int getColumn() const
Returns the current column in iterator.
int getType() const
It returns the data type of the elements in the band.
Definition: BandProperty.h:113
bool CreateNewGdalRaster(const te::rst::Grid &rasterGrid, std::vector< te::rst::BandProperty * > bandsProperties, const std::string &fileName, RasterHandler &outRasterHandler)
Create a new raster into a GDAL datasource.
Definition: Functions.cpp:236
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
std::pair< double, double > GetSpectralBandInfo(std::string bandName)
Returns the maximun and minimum reflectance values of a given sensor/band.
Definition: Functions.cpp:597
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
boost::numeric::ublas::matrix< double > const * m_remapMatrixPtr
Definition: Functions.cpp:114
void GetCovarianceValueThread(GetCovarianceValueThreadParams *paramsPtr)
Definition: Functions.cpp:1304
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
Definition: Band.cpp:572
void GetStdDevValueThread(GetStdDevValueThreadParams *paramsPtr)
Definition: Functions.cpp:1163
unsigned int getLinesNumber() const
The number of current matrix lines.
Definition: Matrix.h:671
bool RemapValues(const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, const boost::numeric::ublas::matrix< double > &remapMatrix, te::rst::Raster &outputRaster, const unsigned int maxThreads)
Remap pixel values using a remap function matrix.
Definition: Functions.cpp:1801
void ConvertDoublesVector(double *inputVector, unsigned int inputVectorSize, const int outputVectorDataType, void *outputVector)
Convert a doubles vector.
Definition: Functions.cpp:444