All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
FusionWizard.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/qt/widgets/rp/FusionWizard.cpp
22 
23  \brief A Qt dialog that allows users to run a fusion operation defined by RP module.
24 */
25 
26 // TerraLib
27 #include "../../../common/progress/ProgressManager.h"
28 #include "../../../dataaccess/dataset/DataSet.h"
29 #include "../../../dataaccess/utils/Utils.h"
30 #include "../../../raster/Raster.h"
31 #include "../../../rp/IHSFusion.h"
32 #include "../../../rp/Module.h"
33 #include "../../../rp/PCAFusion.h"
34 #include "../help/HelpPushButton.h"
35 #include "../layer/search/LayerSearchWidget.h"
36 #include "../layer/search/LayerSearchWizardPage.h"
37 #include "../progress/ProgressViewerDialog.h"
38 #include "FusionWizard.h"
39 #include "FusionWizardPage.h"
40 #include "RasterInfoWidget.h"
41 #include "RasterInfoWizardPage.h"
42 #include "Utils.h"
43 
44 // STL
45 #include <cassert>
46 
47 // Qt
48 #include <QMessageBox>
49 #include <QApplication>
50 
51 
53  : QWizard(parent)
54 {
55  //configure the wizard
56  this->setWizardStyle(QWizard::ModernStyle);
57  this->setWindowTitle(tr("Fusion"));
58  //this->setFixedSize(640, 480);
59 
60  this->setOption(QWizard::HaveHelpButton, true);
61  this->setOption(QWizard::HelpButtonOnRight, false);
62 
64 
65  this->setButton(QWizard::HelpButton, helpButton);
66 
67  helpButton->setPageReference("plugins/rp/rp_fusion.html");
68 
69  addPages();
70 }
71 
73 {
74 
75 }
76 
78 {
79  if(currentPage() == m_layerLowerSearchPage.get())
80  {
81  std::list<te::map::AbstractLayerPtr> list = m_layerLowerSearchPage->getSearchWidget()->getSelecteds();
82 
83  if(list.empty() == false)
84  {
85  te::map::AbstractLayerPtr l = *list.begin();
86 
87  m_fusionPage->setLower(l);
88  }
89 
90  return m_layerLowerSearchPage->isComplete();
91  }
92  else if(currentPage() == m_layerHigherSearchPage.get())
93  {
94  std::list<te::map::AbstractLayerPtr> list = m_layerHigherSearchPage->getSearchWidget()->getSelecteds();
95 
96  if(list.empty() == false)
97  {
98  te::map::AbstractLayerPtr l = *list.begin();
99 
100  m_fusionPage->setHigher(l);
101  }
102 
103  return m_layerHigherSearchPage->isComplete();
104  }
105  else if(currentPage() == m_fusionPage.get())
106  {
107  return m_fusionPage->isComplete();
108  }
109  else if(currentPage() == m_rasterInfoPage.get())
110  {
111  return execute();
112  }
113 
114  return true;
115 }
116 
117 void te::qt::widgets::FusionWizard::setList(std::list<te::map::AbstractLayerPtr>& layerList)
118 {
119  m_layerLowerSearchPage->getSearchWidget()->setList(layerList);
120  m_layerLowerSearchPage->getSearchWidget()->filterOnlyByRaster();
121 
122  m_layerHigherSearchPage->getSearchWidget()->setList(layerList);
123  m_layerHigherSearchPage->getSearchWidget()->filterOnlyByRaster();
124 }
125 
127 {
128  return m_outputLayer;
129 }
130 
132 {
133  m_layerLowerSearchPage.reset(new te::qt::widgets::LayerSearchWizardPage(this));
134  m_layerHigherSearchPage.reset(new te::qt::widgets::LayerSearchWizardPage(this));
135  m_fusionPage.reset(new te::qt::widgets::FusionWizardPage(this));
136  m_rasterInfoPage.reset(new te::qt::widgets::RasterInfoWizardPage(this));
137 
138  addPage(m_layerLowerSearchPage.get());
139  addPage(m_layerHigherSearchPage.get());
140  addPage(m_fusionPage.get());
141  addPage(m_rasterInfoPage.get());
142 
143  //for contrast only one layer can be selected
144  m_layerLowerSearchPage->setSubTitle(tr("Allows selection of layers using filters for selection. Select the layer with a LOWER raster resolution."));
145  m_layerLowerSearchPage->getSearchWidget()->enableMultiSelection(false);
146  m_layerHigherSearchPage->setSubTitle(tr("Allows selection of layers using filters for selection. Select the layer with a HIGHER raster resolution."));
147  m_layerHigherSearchPage->getSearchWidget()->enableMultiSelection(false);
148 }
149 
151 {
152  if(m_fusionPage->isIHSFusion())
153  return executeIHS();
154 
155  if(m_fusionPage->isPCAFusion())
156  return executePCA();
157 
158  return false;
159 }
160 
162 {
163  //get layer lower
164  std::list<te::map::AbstractLayerPtr> listLower = m_layerLowerSearchPage->getSearchWidget()->getSelecteds();
165  te::map::AbstractLayerPtr lLower = *listLower.begin();
166  std::auto_ptr<te::da::DataSet> dsLower = lLower->getData();
167 
168  std::size_t rpos = te::da::GetFirstPropertyPos(dsLower.get(), te::dt::RASTER_TYPE);
169 
170  te::rst::Raster* inputRstLower = dsLower->getRaster(rpos).release();
171 
172  //get layer higher
173  std::list<te::map::AbstractLayerPtr> listHigher = m_layerHigherSearchPage->getSearchWidget()->getSelecteds();
174  te::map::AbstractLayerPtr lHigher = *listHigher.begin();
175  std::auto_ptr<te::da::DataSet> dsHigher = lHigher->getData();
176 
177  rpos = te::da::GetFirstPropertyPos(dsHigher.get(), te::dt::RASTER_TYPE);
178 
179  te::rst::Raster* inputRstHigher = dsHigher->getRaster(rpos).release();
180 
181  te::rst::Raster* rasterLower = 0;
182  te::rst::Raster* rasterHigher = 0;
183 
184  adjustRasters(inputRstLower, inputRstHigher, rasterLower, rasterHigher);
185 
186  //run IHS Fusion
187  te::rp::IHSFusion algorithmInstance;
188 
189  te::rp::IHSFusion::InputParameters algoInputParams = m_fusionPage->getInputIHSParams();
190  algoInputParams.m_lowResRasterPtr = rasterLower;
191  algoInputParams.m_highResRasterPtr = rasterHigher;
192 
193  te::rp::IHSFusion::OutputParameters algoOutputParams = m_fusionPage->getOutputIHSParams();
194  algoOutputParams.m_rInfo = m_rasterInfoPage->getWidget()->getInfo();
195  algoOutputParams.m_rType = m_rasterInfoPage->getWidget()->getType();
196 
197  //progress
200 
201  QApplication::setOverrideCursor(Qt::WaitCursor);
202 
203  try
204  {
205  if(algorithmInstance.initialize(algoInputParams))
206  {
207  if(algorithmInstance.execute(algoOutputParams))
208  {
209  algoOutputParams.reset();
210 
211  //set output layer
212  m_outputLayer = te::qt::widgets::createLayer(m_rasterInfoPage->getWidget()->getType(),
213  m_rasterInfoPage->getWidget()->getInfo());
214 
215  QMessageBox::information(this, tr("Fusion"), tr("Fusion ended sucessfully"));
216  }
217  else
218  {
219  QMessageBox::critical(this, tr("Fusion"), tr("Fusion execution error.") +
220  ( " " + te::rp::Module::getLastLogStr() ).c_str());
221 
223 
224  QApplication::restoreOverrideCursor();
225 
226  delete rasterLower;
227  delete rasterHigher;
228 
229  return false;
230  }
231  }
232  else
233  {
234  QMessageBox::critical(this, tr("Fusion"), tr("Fusion initialization error.") +
235  ( " " + te::rp::Module::getLastLogStr() ).c_str() );
236 
238 
239  QApplication::restoreOverrideCursor();
240 
241  delete rasterLower;
242  delete rasterHigher;
243 
244  return false;
245  }
246  }
247  catch(const std::exception& e)
248  {
249  QMessageBox::warning(this, tr("Fusion"), e.what());
250 
252 
253  QApplication::restoreOverrideCursor();
254 
255  delete rasterLower;
256  delete rasterHigher;
257 
258  return false;
259  }
260  catch(...)
261  {
262  QMessageBox::warning(this, tr("Fusion"), tr("An exception has occurred!"));
263 
265 
266  QApplication::restoreOverrideCursor();
267 
268  delete rasterLower;
269  delete rasterHigher;
270 
271  return false;
272  }
273 
275 
276  QApplication::restoreOverrideCursor();
277 
278  delete rasterLower;
279  delete rasterHigher;
280 
281  return true;
282 }
283 
285 {
286 //get layer lower
287  std::list<te::map::AbstractLayerPtr> listLower = m_layerLowerSearchPage->getSearchWidget()->getSelecteds();
288  te::map::AbstractLayerPtr lLower = *listLower.begin();
289  std::auto_ptr<te::da::DataSet> dsLower = lLower->getData();
290 
291  std::size_t rpos = te::da::GetFirstPropertyPos(dsLower.get(), te::dt::RASTER_TYPE);
292 
293  te::rst::Raster* inputRstLower = dsLower->getRaster(rpos).release();
294 
295  //get layer higher
296  std::list<te::map::AbstractLayerPtr> listHigher = m_layerHigherSearchPage->getSearchWidget()->getSelecteds();
297  te::map::AbstractLayerPtr lHigher = *listHigher.begin();
298  std::auto_ptr<te::da::DataSet> dsHigher = lHigher->getData();
299 
300  rpos = te::da::GetFirstPropertyPos(dsHigher.get(), te::dt::RASTER_TYPE);
301 
302  te::rst::Raster* inputRstHigher = dsHigher->getRaster(rpos).release();
303 
304  te::rst::Raster* rasterLower = 0;
305  te::rst::Raster* rasterHigher = 0;
306 
307  adjustRasters(inputRstLower, inputRstHigher, rasterLower, rasterHigher);
308 
309 
310  //run PCA Fusion
311  te::rp::PCAFusion algorithmInstance;
312 
313  te::rp::PCAFusion::InputParameters algoInputParams = m_fusionPage->getInputPCAParams();
314  algoInputParams.m_lowResRasterPtr = rasterLower;
315  algoInputParams.m_highResRasterPtr = rasterHigher;
316 
317  te::rp::PCAFusion::OutputParameters algoOutputParams = m_fusionPage->getOutputPCAParams();
318  algoOutputParams.m_rInfo = m_rasterInfoPage->getWidget()->getInfo();
319  algoOutputParams.m_rType = m_rasterInfoPage->getWidget()->getType();
320 
321  //progress
324 
325  QApplication::setOverrideCursor(Qt::WaitCursor);
326 
327  try
328  {
329  if(algorithmInstance.initialize(algoInputParams))
330  {
331  if(algorithmInstance.execute(algoOutputParams))
332  {
333  algoOutputParams.reset();
334 
335  //set output layer
336  m_outputLayer = te::qt::widgets::createLayer(m_rasterInfoPage->getWidget()->getType(),
337  m_rasterInfoPage->getWidget()->getInfo());
338 
339  QMessageBox::information(this, tr("Fusion"), tr("Fusion ended sucessfully"));
340  }
341  else
342  {
343  QMessageBox::critical(this, tr("Fusion"), tr("Fusion execution error.") +
344  ( " " + te::rp::Module::getLastLogStr() ).c_str());
345 
347 
348  QApplication::restoreOverrideCursor();
349 
350  delete rasterLower;
351  delete rasterHigher;
352 
353  return false;
354  }
355  }
356  else
357  {
358  QMessageBox::critical(this, tr("Fusion"), tr("Fusion initialization error.") +
359  ( " " + te::rp::Module::getLastLogStr() ).c_str() );
360 
362 
363  QApplication::restoreOverrideCursor();
364 
365  delete rasterLower;
366  delete rasterHigher;
367 
368  return false;
369  }
370  }
371  catch(const std::exception& e)
372  {
373  QMessageBox::warning(this, tr("Fusion"), e.what());
374 
376 
377  QApplication::restoreOverrideCursor();
378 
379  delete rasterLower;
380  delete rasterHigher;
381 
382  return false;
383  }
384  catch(...)
385  {
386  QMessageBox::warning(this, tr("Fusion"), tr("An exception has occurred!"));
387 
389 
390  QApplication::restoreOverrideCursor();
391 
392  delete rasterLower;
393  delete rasterHigher;
394 
395  return false;
396  }
397 
399 
400  QApplication::restoreOverrideCursor();
401 
402  delete rasterLower;
403  delete rasterHigher;
404 
405  return true;
406 }
407 
409 {
410  assert(rInLower);
411  assert(rInHigher);
412 
413  if(!m_fusionPage->cropRasters())
414  {
415  rOutLower = rInLower;
416  rOutHigher = rInHigher;
417 
418  return;
419  }
420 
421  //get box
422  te::gm::Envelope boxLower = *rInLower->getExtent();
423  te::gm::Envelope boxHigher = *rInHigher->getExtent();
424 
425  //check if the box is equal
426  if(boxLower.equals(boxHigher))
427  {
428  rOutLower = rInLower;
429  rOutHigher = rInHigher;
430 
431  return;
432  }
433 
434  //check if a reprojection is necessary
435  bool reproject = rInLower->getSRID() != rInHigher->getSRID();
436 
437  if(reproject)
438  boxHigher.transform(rInHigher->getSRID(), rInLower->getSRID());
439 
440  //check the intersection box
441  if(!boxLower.intersects(boxHigher))
442  return;
443 
444  te::gm::Envelope interBox = boxLower.intersection(boxHigher);
445 
446  //generate lower raster
447  std::map<std::string, std::string> rLowerInfo;
448  rLowerInfo["FORCE_MEM_DRIVER"] = "TRUE";
449  rLowerInfo["MEM_RASTER_NROWS"] = boost::lexical_cast<std::string>(interBox.getHeight() / rInLower->getResolutionX());
450  rLowerInfo["MEM_RASTER_NCOLS"] = boost::lexical_cast<std::string>(interBox.getWidth() / rInLower->getResolutionY());
451  rLowerInfo["MEM_RASTER_DATATYPE"] = boost::lexical_cast<std::string>(rInLower->getBandDataType(0));
452  rLowerInfo["MEM_RASTER_NBANDS"] = boost::lexical_cast<std::string>(rInLower->getNumberOfBands());
453 
454  rOutLower = rInLower->trim(&interBox, rLowerInfo);
455 
456  //generate higher raster
457  std::map<std::string, std::string> rHigherInfo;
458  rHigherInfo["FORCE_MEM_DRIVER"] = "TRUE";
459  rHigherInfo["MEM_RASTER_NROWS"] = boost::lexical_cast<std::string>(interBox.getHeight() / rInHigher->getResolutionX());
460  rHigherInfo["MEM_RASTER_NCOLS"] = boost::lexical_cast<std::string>(interBox.getWidth() / rInHigher->getResolutionY());
461  rHigherInfo["MEM_RASTER_DATATYPE"] = boost::lexical_cast<std::string>(rInHigher->getBandDataType(0));
462  rHigherInfo["MEM_RASTER_NBANDS"] = boost::lexical_cast<std::string>(rInHigher->getNumberOfBands());
463 
464  if(reproject)
465  {
466  boxHigher.transform(rInLower->getSRID(), rInHigher->getSRID());
467 
468  rOutHigher = rInHigher->transform(rInLower->getSRID(), boxHigher.getLowerLeftX(), boxHigher.getLowerLeftY(), boxHigher.getUpperRightX(), boxHigher.getUpperRightY(), rHigherInfo);
469  }
470  else
471  rOutHigher = rInHigher->trim(&interBox, rHigherInfo);
472 }
void adjustRasters(te::rst::Raster *rInLower, te::rst::Raster *rInHigher, te::rst::Raster *&rOutLower, te::rst::Raster *&rOutHigher)
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
Definition: PCAFusion.cpp:141
te::gm::Envelope * getExtent()
Returns the geographic extension of the raster data.
Definition: Raster.cpp:104
te::rst::Raster const * m_highResRasterPtr
Input high-resolution raster.
Definition: PCAFusion.h:66
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
Definition: IHSFusion.h:114
Utility functions for the data access module.
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
Definition: IHSFusion.h:112
Fusion of a low-resolution multi-band image with a high resolution image using the IHS method...
Definition: IHSFusion.h:56
bool intersects(const Envelope &rhs) const
It returns true if the envelopes "spatially intersects".
Definition: Envelope.h:493
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: PCAFusion.cpp:109
void setPageReference(const QString &ref)
Sets the documentation page reference.
IHSFusion output parameters.
Definition: IHSFusion.h:108
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
Definition: PCAFusion.h:100
const double & getUpperRightX() const
It returns a constant refernce to the x coordinate of the upper right corner.
Definition: Envelope.h:410
IHSFusion input parameters.
Definition: IHSFusion.h:64
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
Definition: Envelope.h:400
PCAFusion output parameters.
Definition: PCAFusion.h:96
double getWidth() const
It returns the envelope width.
Definition: Envelope.h:443
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
Definition: Envelope.h:420
Fusion of a low-resolution multi-band image with a high resolution image using the PCA (Principal com...
Definition: PCAFusion.h:50
te::rst::Raster const * m_lowResRasterPtr
Input low-resolution multi-band raster.
Definition: PCAFusion.h:62
This file defines a class for a Raster Info Wizard page.
This file defines a class for a Fusion Wizard page.
static const std::string & getLastLogStr()
Returns the last log string generated by this module.
Definition: Module.h:53
void removeViewer(int viewerId)
Dettach a progress viewer.
static ProgressManager & getInstance()
It returns a reference to the singleton instance.
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
Definition: IHSFusion.cpp:150
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
An abstract class for raster data strucutures.
Definition: Raster.h:71
This class is GUI used to define the raster info parameters for raster factory.
te::map::AbstractLayerPtr getOutputLayer()
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
Definition: PCAFusion.cpp:280
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
double getResolutionX() const
Returns the raster horizontal (x-axis) resolution.
Definition: Raster.cpp:218
This file has the RasterInfoWidget class.
virtual Raster * trim(const te::gm::Envelope *env, const std::map< std::string, std::string > &rinfo)
Subsetting operation for trimming (cropping) the raster.
Definition: Raster.cpp:422
This class is GUI used to define the fusion parameters for the RP fusion operation.
A Qt dialog that allows users to run a fusion operation defined by RP module.
bool equals(const Envelope &rhs) const
It returns true if the envelopes are "spatially equal".
Definition: Envelope.h:477
virtual bool validateCurrentPage()
int addViewer(AbstractProgressViewer *apv)
Attach a progress viewer.
int getSRID() const
Returns the raster spatial reference system identifier.
Definition: Raster.cpp:203
virtual Raster * transform(int srid, const std::map< std::string, std::string > &rinfo, int m=1) const
Reprojects this raster to a distinct SRS. This method reprojects this raster to a distinct SRS...
Definition: Raster.cpp:597
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: IHSFusion.cpp:118
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
Definition: PCAFusion.h:102
Push button that uses te::qt::widgets::HelpManager on its mouse pressed implementation.
PCAFusion input parameters.
Definition: PCAFusion.h:58
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
Definition: Envelope.h:390
double getResolutionY() const
Returns the raster vertical (y-axis) resolution.
Definition: Raster.cpp:223
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:432
te::rst::Raster const * m_highResRasterPtr
Input high-resolution raster.
Definition: IHSFusion.h:76
Envelope intersection(const Envelope &rhs) const
It returns an envelope that represents the point set intersection with another envelope.
Definition: Envelope.h:543
te::rst::Raster const * m_lowResRasterPtr
Input low-resolution multi-band raster.
Definition: IHSFusion.h:68
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
Definition: IHSFusion.cpp:241
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void transform(int oldsrid, int newsrid)
It will transform the coordinates of the Envelope from the old SRS to the new one.
Definition: Envelope.cpp:90
TEQTWIDGETSEXPORT te::map::AbstractLayerPtr createLayer(const std::string &driverName, const std::map< std::string, std::string > &connInfo)
Definition: Utils.cpp:40
virtual int getBandDataType(std::size_t i) const =0
Returns the data type in a particular band (or dimension).
double getHeight() const
It returns the envelope height.
Definition: Envelope.h:448
void setList(std::list< te::map::AbstractLayerPtr > &layerList)