All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ClippingWizard.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/qt/widgets/rp/ClippingWizard.cpp
22 
23  \brief A Qt dialog that allows users to run a clipping operation defined by RP module.
24 */
25 
26 // TerraLib
27 #include "../../../common/progress/ProgressManager.h"
28 #include "../../../geometry/Envelope.h"
29 #include "../../../dataaccess/dataset/DataSet.h"
30 #include "../../../dataaccess/utils/Utils.h"
31 #include "../../../geometry/Geometry.h"
32 #include "../../../geometry/GeometryCollection.h"
33 #include "../../../raster/Grid.h"
34 #include "../../../raster/Interpolator.h"
35 #include "../../../raster/PositionIterator.h"
36 #include "../../../raster/Raster.h"
37 #include "../../../raster/RasterFactory.h"
38 #include "../../../raster/Utils.h"
39 #include "../help/HelpPushButton.h"
40 #include "../layer/search/LayerSearchWidget.h"
41 #include "../layer/search/LayerSearchWizardPage.h"
42 #include "../progress/ProgressViewerDialog.h"
43 #include "ClippingWizard.h"
44 #include "ClippingWizardPage.h"
45 #include "RasterInfoWidget.h"
46 #include "RasterInfoWizardPage.h"
47 #include "Utils.h"
48 
49 // STL
50 #include <cassert>
51 
52 // Qt
53 #include <QApplication>
54 #include <QMessageBox>
55 
56 
58  : QWizard(parent)
59 {
60  //configure the wizard
61  this->setWizardStyle(QWizard::ModernStyle);
62  this->setWindowTitle(tr("Clipping"));
63  //this->setFixedSize(640, 580);
64 
65  this->setOption(QWizard::HaveHelpButton, true);
66  this->setOption(QWizard::HelpButtonOnRight, false);
67 
69 
70  this->setButton(QWizard::HelpButton, helpButton);
71 
72  helpButton->setPageReference("plugins/rp/rp_clipping.html");
73 
74  addPages();
75 }
76 
78 {
79 
80 }
81 
83 {
84  if(currentPage() == m_layerSearchPage.get())
85  {
86  std::list<te::map::AbstractLayerPtr> list = m_layerSearchPage->getSearchWidget()->getSelecteds();
87 
88  if(list.empty() == false)
89  {
90  te::map::AbstractLayerPtr l = *list.begin();
91 
92  m_clippingPage->set(l);
93  }
94 
95  return m_layerSearchPage->isComplete();
96  }
97  else if(currentPage() == m_clippingPage.get())
98  {
99  bool res = m_clippingPage->isComplete();
100 
101  if(!res)
102  QMessageBox::warning(this, tr("Warning"), tr("Select at least one band."));
103 
104  return res;
105  }
106  else if(currentPage() == m_rasterInfoPage.get())
107  {
108  return execute();
109  }
110 
111  return true;
112 }
113 
114 void te::qt::widgets::ClippingWizard::setList(std::list<te::map::AbstractLayerPtr>& layerList)
115 {
116  m_layerSearchPage->getSearchWidget()->setList(layerList);
117  m_layerSearchPage->getSearchWidget()->filterOnlyByRaster();
118 
119  m_clippingPage->setList(layerList);
120 }
121 
123 {
124  m_clippingPage->set(layer);
125 }
126 
127 std::vector<te::map::AbstractLayerPtr> te::qt::widgets::ClippingWizard::getOutputLayers()
128 {
129  return m_outputLayer;
130 }
131 
133 {
134  m_layerSearchPage.reset(new te::qt::widgets::LayerSearchWizardPage(this));
135  m_clippingPage.reset(new te::qt::widgets::ClippingWizardPage(this));
136  m_rasterInfoPage.reset(new te::qt::widgets::RasterInfoWizardPage(this));
137 
138  addPage(m_layerSearchPage.get());
139  addPage(m_clippingPage.get());
140  addPage(m_rasterInfoPage.get());
141 
142  //for contrast only one layer can be selected
143  m_layerSearchPage->getSearchWidget()->enableMultiSelection(false);
144 }
145 
147 {
148  if(m_rasterInfoPage->getWidget()->fileExists())
149  {
150  QMessageBox::warning(this, tr("Clipping"), tr("File already exists."));
151  return false;
152  }
153 
154  //progress
157 
158  QApplication::setOverrideCursor(Qt::WaitCursor);
159 
160  bool res = false;
161 
162  try
163  {
164  if(m_clippingPage->isExtentClipping())
165  res = executeExtentClipping();
166  else if(m_clippingPage->isDimensionClipping())
167  res = executeDimensionClipping();
168  else if(m_clippingPage->isLayerClipping())
169  res = executeLayerClipping();
170  }
171  catch(const std::exception& e)
172  {
173  QMessageBox::warning(this, tr("Clipping"), e.what());
174 
176 
177  QApplication::restoreOverrideCursor();
178 
179  return false;
180  }
181  catch(...)
182  {
183  QMessageBox::warning(this, tr("Clipping"), tr("An exception has occurred!"));
184 
186 
187  QApplication::restoreOverrideCursor();
188 
189  return false;
190  }
191 
193 
194  QApplication::restoreOverrideCursor();
195 
196  return res;
197 }
198 
200 {
201  //get raster
202  te::map::AbstractLayerPtr layer = m_clippingPage->get();
203  std::auto_ptr<te::da::DataSet> ds = layer->getData();
204 
205  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
206  std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
207 
208  //get parameters
209  te::gm::Envelope env;
210 
211  m_clippingPage->getExtentClipping(env);
212 
213  if(!env.intersects(*inputRst->getExtent()))
214  {
215  QMessageBox::warning(this, tr("Clipping"), tr("Selected area do not intersects the raster extent."));
216  return false;
217  }
218 
219  std::map<std::string, std::string> info = m_rasterInfoPage->getWidget()->getInfo();
220 
221  //execute clipping
222  te::rst::Raster* outputRst = inputRst->trim(&env, info);
223 
224  if(outputRst)
225  {
226  delete outputRst;
227 
228  //set output layer
229  m_outputLayer.push_back(te::qt::widgets::createLayer(m_rasterInfoPage->getWidget()->getType(),
230  m_rasterInfoPage->getWidget()->getInfo()));
231  }
232  return true;
233 }
234 
236 {
237  //get raster
238  te::map::AbstractLayerPtr layer = m_clippingPage->get();
239  std::auto_ptr<te::da::DataSet> ds = layer->getData();
240 
241  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
242  std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
243 
244  //get parameters
245  int x, y, width, height;
246 
247  m_clippingPage->getDimensionClipping(x, y, width, height);
248 
249  std::map<std::string, std::string> info = m_rasterInfoPage->getWidget()->getInfo();
250 
251  if(y + height > (int)inputRst->getNumberOfRows() ||
252  x + width > (int)inputRst->getNumberOfColumns())
253  {
254  QMessageBox::warning(this, tr("Clipping"), tr("Selected area beyond the raster boundaries."));
255  return false;
256  }
257 
258  //execute clipping
259  te::rst::Raster* outputRst = inputRst->resample(te::rst::NearestNeighbor, y, x, height, width, height, width, info);
260 
261  if(outputRst)
262  {
263  delete outputRst;
264 
265  //set output layer
266  m_outputLayer.push_back(te::qt::widgets::createLayer(m_rasterInfoPage->getWidget()->getType(),
267  m_rasterInfoPage->getWidget()->getInfo()));
268  }
269 
270  return true;
271 }
272 
274 {
275  //get raster
276  te::map::AbstractLayerPtr layer = m_clippingPage->get();
277  std::auto_ptr<te::da::DataSet> ds = layer->getData();
278 
279  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
280  std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
281 
282  //get parameters
283  std::auto_ptr< te::gm::GeometryCollection > geomColl;
284  m_clippingPage->getLayerClipping(geomColl);
285 
286  if(geomColl->isEmpty())
287  return false;
288 
289  if( geomColl->getSRID() != inputRst->getSRID() )
290  {
291  geomColl->transform( inputRst->getSRID() );
292  }
293 
294  if(m_clippingPage->isSingleRasterResult())
295  {
296  //output raster
297  std::vector<te::rst::BandProperty*> bands;
298 
299  for(std::size_t t = 0; t < inputRst->getNumberOfBands(); ++t)
300  {
301  te::rst::BandProperty* b = new te::rst::BandProperty(t, inputRst->getBand(t)->getProperty()->getType());
302  bands.push_back(b);
303  }
304 
305  te::gm::Envelope* env = new te::gm::Envelope(*geomColl->getMBR());
306  te::rst::Grid* grid = new te::rst::Grid(inputRst->getGrid()->getResolutionX(), inputRst->getGrid()->getResolutionY(), env, inputRst->getSRID());
307 
308  std::string type = m_rasterInfoPage->getWidget()->getType();
309 
310  std::map<std::string, std::string> rinfo = m_rasterInfoPage->getWidget()->getInfo();
311  std::auto_ptr<te::rst::Raster> outputRst( te::rst::RasterFactory::make(type, grid, bands, rinfo) );
312  te::rst::FillRaster(outputRst.get(), outputRst->getBand( 0 )->getProperty()->m_noDataValue );
313 
314  te::gm::Polygon* polygon = 0;
315 // te::rst::PolygonIterator<double> it;
316 // te::rst::PolygonIterator<double> itend;
317  std::vector<double> doubleVec;
318  te::gm::Coord2D inputCoord;
319  te::gm::Coord2D outputCoord;
320 
321  for(std::size_t i = 0; i < geomColl->getNumGeometries(); ++i)
322  {
323  polygon = static_cast<te::gm::Polygon*> (geomColl->getGeometryN(i));
324 
327 
328  while (it != itend)
329  {
330  inputRst->getValues(it.getColumn(), it.getRow(), doubleVec);
331 
332  inputCoord = inputRst->getGrid()->gridToGeo(it.getColumn(), it.getRow());
333  outputCoord = outputRst->getGrid()->geoToGrid(inputCoord.x, inputCoord.y);
334  outputCoord.x = te::rst::Round(outputCoord.x);
335  outputCoord.y = te::rst::Round(outputCoord.y);
336 
337  if(
338  (
339  ( outputCoord.x >= 0 )
340  &&
341  ( outputCoord.x < (int)outputRst->getNumberOfColumns() )
342  )
343  &&
344  (
345  ( outputCoord.y >= 0 )
346  &&
347  ( outputCoord.y < (int)outputRst->getNumberOfRows() )
348  )
349  )
350  {
351  outputRst->setValues(outputCoord.x, outputCoord.y, doubleVec);
352  }
353 
354  ++it;
355  }
356  }
357 
358  outputRst.reset();
359 
360  //set output layer
361  m_outputLayer.push_back(te::qt::widgets::createLayer(m_rasterInfoPage->getWidget()->getType(),
362  m_rasterInfoPage->getWidget()->getInfo()));
363  }
364  else
365  {
366  for(std::size_t i = 0; i < geomColl->getNumGeometries(); ++i)
367  {
368  //output raster
369  std::vector<te::rst::BandProperty*> bands;
370 
371  for(std::size_t t = 0; t < inputRst->getNumberOfBands(); ++t)
372  {
373  te::rst::BandProperty* b = new te::rst::BandProperty(t, inputRst->getBand(t)->getProperty()->getType());
374  bands.push_back(b);
375  }
376 
377  te::gm::Envelope* env = new te::gm::Envelope(*geomColl->getMBR());
378  te::rst::Grid* grid = new te::rst::Grid(inputRst->getGrid()->getResolutionX(), inputRst->getGrid()->getResolutionY(), env, inputRst->getSRID());
379 
380  std::string type = m_rasterInfoPage->getWidget()->getType();
381 
382  std::map<std::string, std::string> rinfo = m_rasterInfoPage->getWidget()->getInfo(i);
383  std::auto_ptr<te::rst::Raster> outputRst( te::rst::RasterFactory::make(type, grid, bands, rinfo) );
384 
385  te::rst::FillRaster(outputRst.get(), 255);
386 
387  te::gm::Polygon* polygon = static_cast<te::gm::Polygon*> (geomColl->getGeometryN(i));
388 
391 
392  while (it != itend)
393  {
394  std::vector<double> doubleVec;
395  inputRst->getValues(it.getColumn(), it.getRow(), doubleVec);
396 
397  te::gm::Coord2D inputCoord = inputRst->getGrid()->gridToGeo(it.getColumn(), it.getRow());
398  te::gm::Coord2D outputCoord = outputRst->getGrid()->geoToGrid(inputCoord.x, inputCoord.y);
399 
400  if( (te::rst::Round(inputCoord.x) >= 0 && te::rst::Round(outputCoord.x) < (int)inputRst->getNumberOfColumns()) &&
401  (te::rst::Round(inputCoord.y) >= 0 && te::rst::Round(outputCoord.y) < (int)inputRst->getNumberOfRows()))
402  outputRst->setValues(te::rst::Round(outputCoord.x), te::rst::Round(outputCoord.y), doubleVec);
403 
404  ++it;
405  }
406 
407  outputRst.reset();
408 
409  //set output layer
410  m_outputLayer.push_back(te::qt::widgets::createLayer(m_rasterInfoPage->getWidget()->getType(),
411  m_rasterInfoPage->getWidget()->getInfo(i)));
412  }
413  }
414 
415  return true;
416 }
417 
Near neighborhood interpolation method.
Definition: Enums.h:95
Utility functions for the data access module.
double y
y-coordinate.
Definition: Coord2D.h:114
bool intersects(const Envelope &rhs) const
It returns true if the envelopes "spatially intersects".
Definition: Envelope.h:493
A raster band description.
Definition: BandProperty.h:61
double x
x-coordinate.
Definition: Coord2D.h:113
void setPageReference(const QString &ref)
Sets the documentation page reference.
virtual Raster * trim(const te::gm::Envelope *env, const std::map< std::string, std::string > &rinfo) const
Subsetting operation for trimming (cropping) the raster.
Definition: Raster.cpp:422
This class implements the strategy to iterate with spatial restriction, the iteration occurs inside a...
virtual Raster * resample(int method, unsigned int drow, unsigned int dcolumn, unsigned int height, unsigned int width, unsigned int newheight, unsigned int newwidth, const std::map< std::string, std::string > &rinfo) const
Resample a subset of the raster, given a box.
Definition: Raster.cpp:565
TERASTEREXPORT void FillRaster(te::rst::Raster *rin, const std::complex< double > &value)
Fill a Raster with provided value (all bands).
Definition: Utils.cpp:418
unsigned int getRow() const
Returns the current row in iterator.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
A Qt dialog that allows users to run a clipping operation defined by RP module.
This file defines a class for a Raster Info Wizard page.
This file defines a class for a Clipping Wizard page.
std::vector< te::map::AbstractLayerPtr > getOutputLayers()
static PolygonIterator end(const te::rst::Raster *r, const te::gm::Polygon *p)
Returns an iterator referring to after the end of the iterator.
void removeViewer(int viewerId)
Dettach a progress viewer.
static ProgressManager & getInstance()
It returns a reference to the singleton instance.
TERASTEREXPORT int Round(double val)
Round a double value to a integer value.
Definition: Utils.cpp:298
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.
This file has the RasterInfoWidget class.
void setLayer(te::map::AbstractLayerPtr layer)
int addViewer(AbstractProgressViewer *apv)
Attach a progress viewer.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
static PolygonIterator begin(const te::rst::Raster *r, const te::gm::Polygon *p)
Returns an iterator referring to the first value of the band.
Push button that uses te::qt::widgets::HelpManager on its mouse pressed implementation.
static Raster * make()
It creates and returns an empty raster with default raster driver.
void setList(std::list< te::map::AbstractLayerPtr > &layerList)
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:481
unsigned int getColumn() const
Returns the current column in iterator.
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
TEQTWIDGETSEXPORT te::map::AbstractLayerPtr createLayer(const std::string &driverName, const std::map< std::string, std::string > &connInfo)
Definition: Utils.cpp:40
This class is GUI used to define the clipping parameters for the RP constast operation.