All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RasterToVectorDialog.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/attributefill/RasterToVectorDialog.cpp
22 
23  \brief Raster to vector attributefill dialog.
24 */
25 
26 // TerraLib
27 #include "terralib_config.h"
28 #include "../../common/Logger.h"
29 #include "../../common/progress/ProgressManager.h"
30 #include "../../common/Translator.h"
31 #include "../../common/STLUtils.h"
32 #include "../../dataaccess/dataset/DataSetType.h"
33 #include "../../dataaccess/datasource/DataSourceCapabilities.h"
34 #include "../../dataaccess/datasource/DataSourceInfo.h"
35 #include "../../dataaccess/datasource/DataSourceInfoManager.h"
36 #include "../../dataaccess/datasource/DataSourceFactory.h"
37 #include "../../dataaccess/datasource/DataSourceManager.h"
38 #include "../../dataaccess/utils/Utils.h"
39 #include "../../datatype/Enums.h"
40 #include "../../datatype/Property.h"
41 #include "../../maptools/AbstractLayer.h"
42 #include "../../qt/af/Utils.h"
43 #include "../../qt/widgets/datasource/selector/DataSourceSelectorDialog.h"
44 #include "../../qt/widgets/layer/utils/DataSet2Layer.h"
45 #include "../../qt/widgets/progress/ProgressViewerDialog.h"
46 #include "../../qt/widgets/Utils.h"
47 #include "../../raster/RasterProperty.h"
48 #include "../../statistics/core/Utils.h"
49 #include "../Config.h"
50 #include "../Exception.h"
51 #include "RasterToVectorDialog.h"
52 #include "../RasterToVector.h"
53 #include "ui_RasterToVectorDialogForm.h"
54 
55 // Qt
56 #include <QFileDialog>
57 #include <QList>
58 #include <QListWidget>
59 #include <QListWidgetItem>
60 #include <QMessageBox>
61 
62 // Boost
63 #include <boost/algorithm/string.hpp>
64 #include <boost/filesystem.hpp>
65 #include <boost/lexical_cast.hpp>
66 #include <boost/uuid/random_generator.hpp>
67 #include <boost/uuid/uuid_io.hpp>
68 
70  : QDialog(parent, f),
71  m_ui(new Ui::RasterToVectorDialogForm),
72  m_layers(std::list<te::map::AbstractLayerPtr>())
73 {
74  // add controls
75  m_ui->setupUi(this);
76 
77  // add icons
78  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("raster-vector-hint").pixmap(112,48));
79  m_ui->m_targetDatasourceToolButton->setIcon(QIcon::fromTheme("datasource"));
80 
81  connect(m_ui->m_inRasterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onRasterComboBoxChanged(int)));
82  connect(m_ui->m_inVectorComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onVectorComboBoxChanged(int)));
83 
84  connect(m_ui->m_targetDatasourceToolButton, SIGNAL(pressed()), this, SLOT(onTargetDatasourceToolButtonPressed()));
85  connect(m_ui->m_targetFileToolButton, SIGNAL(pressed()), this, SLOT(onTargetFileToolButtonPressed()));
86 
87  connect(m_ui->m_okPushButton, SIGNAL(clicked()), this, SLOT(onOkPushButtonClicked()));
88  connect(m_ui->m_cancelPushButton, SIGNAL(clicked()), this, SLOT(onCancelPushButtonClicked()));
89 
90  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
91  m_ui->m_helpPushButton->setPageReference("plugins/attributefill/attrfill_raster_to_vector.html");
92 
93 }
94 
96 {
97 }
98 
99 void te::attributefill::RasterToVectorDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
100 {
101  m_layers = layers;
102 
103  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
104 
105  while(it != m_layers.end())
106  {
107  std::auto_ptr<te::da::DataSetType> dsType = it->get()->getSchema();
108  if(dsType->hasRaster())
109  m_ui->m_inRasterComboBox->addItem(QString(it->get()->getTitle().c_str()), QVariant(it->get()->getId().c_str()));
110  if(dsType->hasGeom())
111  m_ui->m_inVectorComboBox->addItem(QString(it->get()->getTitle().c_str()), QVariant(it->get()->getId().c_str()));
112  ++it;
113  }
114 }
115 
117 {
118  return m_outLayer;
119 }
120 
122 {
123  std::vector<unsigned int> vecBands;
124 
125  for(int i = 0; i < m_ui->m_bandsListWidget->count(); ++i)
126  {
127  if(m_ui->m_bandsListWidget->isItemSelected(m_ui->m_bandsListWidget->item(i)))
128  {
129  vecBands.push_back(i);
130  }
131  }
132  return vecBands;
133 }
134 
135 std::vector<te::stat::StatisticalSummary> te::attributefill::RasterToVectorDialog::getSelectedStatistics()
136 {
137  std::vector<te::stat::StatisticalSummary> vecStatistics;
138 
139  for(int i = 0; i < m_ui->m_statisticsListWidget->count(); ++i)
140  {
141  if(m_ui->m_statisticsListWidget->isItemSelected(m_ui->m_statisticsListWidget->item(i)))
142  {
143  switch(i)
144  {
145  case 0:
146  vecStatistics.push_back(te::stat::MIN_VALUE);
147  break;
148  case 1:
149  vecStatistics.push_back(te::stat::MAX_VALUE);
150  break;
151  case 2:
152  vecStatistics.push_back(te::stat::MEAN);
153  break;
154  case 3:
155  vecStatistics.push_back(te::stat::SUM);
156  break;
157  case 4:
158  vecStatistics.push_back(te::stat::COUNT);
159  break;
160  case 5:
161  vecStatistics.push_back(te::stat::VALID_COUNT);
162  break;
163  case 6:
164  vecStatistics.push_back(te::stat::STANDARD_DEVIATION);
165  break;
166  case 7:
167  vecStatistics.push_back(te::stat::VARIANCE);
168  break;
169  case 8:
170  vecStatistics.push_back(te::stat::SKEWNESS);
171  break;
172  case 9:
173  vecStatistics.push_back(te::stat::KURTOSIS);
174  break;
175  case 10:
176  vecStatistics.push_back(te::stat::AMPLITUDE);
177  break;
178  case 11:
179  vecStatistics.push_back(te::stat::MEDIAN);
180  break;
181  case 12:
182  vecStatistics.push_back(te::stat::VAR_COEFF);
183  break;
184  case 13:
185  vecStatistics.push_back(te::stat::MODE);
186  break;
187  default:
188  continue;
189  }
190  }
191  }
192  return vecStatistics;
193 }
194 
196 {
197  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
198 
199  std::string layerID = m_ui->m_inRasterComboBox->itemData(index, Qt::UserRole).toString().toStdString();
200 
201  while(it != m_layers.end())
202  {
203  if(layerID == it->get()->getId().c_str())
204  m_rasterLayer = it->get();
205 
206  ++it;
207  }
208 
209  m_ui->m_bandsListWidget->clear();
210 
211  std::auto_ptr<te::da::DataSetType> dsType = m_rasterLayer->getSchema();
212  te::rst::RasterProperty* rasterProp = te::da::GetFirstRasterProperty(dsType.get());
213  std::auto_ptr<te::da::DataSet> dsRaster = m_rasterLayer->getData();
214  std::auto_ptr<te::rst::Raster> raster = dsRaster->getRaster(rasterProp->getName());
215  std::size_t n_bands = raster->getNumberOfBands();
216 
217  for(std::size_t b = 0; b < n_bands; ++b)
218  m_ui->m_bandsListWidget->addItem(boost::lexical_cast<std::string>(b).c_str());
219 
220 
221  m_ui->m_statisticsListWidget->clear();
222 
223  m_ui->m_statisticsListWidget->addItem("Minimum value");
224  m_ui->m_statisticsListWidget->addItem("Maximum value");
225  m_ui->m_statisticsListWidget->addItem("Mean");
226  m_ui->m_statisticsListWidget->addItem("Sum of values");
227  m_ui->m_statisticsListWidget->addItem("Total number of values");
228  m_ui->m_statisticsListWidget->addItem("Total not null values");
229  m_ui->m_statisticsListWidget->addItem("Standard deviation");
230  m_ui->m_statisticsListWidget->addItem("Variance");
231  m_ui->m_statisticsListWidget->addItem("Skewness");
232  m_ui->m_statisticsListWidget->addItem("Kurtosis");
233  m_ui->m_statisticsListWidget->addItem("Amplitude");
234  m_ui->m_statisticsListWidget->addItem("Median");
235  m_ui->m_statisticsListWidget->addItem("Coefficient variation");
236  m_ui->m_statisticsListWidget->addItem("Mode");
237 
238 }
239 
241 {
242  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
243 
244  std::string layerID = m_ui->m_inVectorComboBox->itemData(index, Qt::UserRole).toString().toStdString();
245 
246  while(it != m_layers.end())
247  {
248  if(layerID == it->get()->getId().c_str())
249  m_vectorLayer = it->get();
250 
251  ++it;
252  }
253 }
254 
256 {
257  m_ui->m_newLayerNameLineEdit->clear();
258  m_ui->m_newLayerNameLineEdit->setEnabled(true);
260  dlg.exec();
261 
262  std::list<te::da::DataSourceInfoPtr> dsPtrList = dlg.getSelecteds();
263 
264  if(dsPtrList.size() <= 0)
265  return;
266 
267  std::list<te::da::DataSourceInfoPtr>::iterator it = dsPtrList.begin();
268 
269  m_ui->m_repositoryLineEdit->setText(QString(it->get()->getTitle().c_str()));
270 
271  m_outputDatasource = *it;
272 
273  m_toFile = false;
274 }
275 
277 {
278  m_ui->m_newLayerNameLineEdit->clear();
279  m_ui->m_repositoryLineEdit->clear();
280 
281  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."),
282  QString(), tr("Shapefile (*.shp *.SHP);;"),0, QFileDialog::DontConfirmOverwrite);
283 
284  if (fileName.isEmpty())
285  return;
286 
287  boost::filesystem::path outfile(fileName.toStdString());
288  std::string aux = outfile.leaf().string();
289  m_ui->m_newLayerNameLineEdit->setText(aux.c_str());
290  aux = outfile.string();
291  m_ui->m_repositoryLineEdit->setText(aux.c_str());
292 
293  m_toFile = true;
294  m_ui->m_newLayerNameLineEdit->setEnabled(false);
295 }
296 
298 {
299  QMessageBox::information(this, "Help", "Under development");
300 }
301 
303 {
304  if(m_ui->m_inRasterComboBox->count() == 0)
305  {
306  QMessageBox::information(this, "Fill", "Select an input raster layer.");
307  return;
308  }
309 
310  if(m_ui->m_inVectorComboBox->count() == 0)
311  {
312  QMessageBox::information(this, "Fill", "Select an input vector layer.");
313  return;
314  }
315 
316 
317  te::map::DataSetLayer* dsRasterLayer = dynamic_cast<te::map::DataSetLayer*>(m_rasterLayer.get());
318 
319  if(!dsRasterLayer)
320  {
321  QMessageBox::information(this, "Fill", "Can not execute this operation on this type of layer.");
322  return;
323  }
324 
325  te::map::DataSetLayer* dsVectorLayer = dynamic_cast<te::map::DataSetLayer*>(m_vectorLayer.get());
326 
327  if(!dsVectorLayer)
328  {
329  QMessageBox::information(this, "Fill", "Can not execute this operation on this type of layer.");
330  return;
331  }
332 
333  te::da::DataSourcePtr inRasterDataSource = te::da::GetDataSource(dsRasterLayer->getDataSourceId(), true);
334  if (!inRasterDataSource.get())
335  {
336  QMessageBox::information(this, "Fill", "The selected raster data source can not be accessed.");
337  return;
338  }
339 
340  te::da::DataSourcePtr inVectorDataSource = te::da::GetDataSource(dsVectorLayer->getDataSourceId(), true);
341  if (!inVectorDataSource.get())
342  {
343  QMessageBox::information(this, "Fill", "The selected vector data source can not be accessed.");
344  return;
345  }
346 
347  std::vector<unsigned int> vecBands = getSelectedBands();
348  if(vecBands.empty())
349  {
350  QMessageBox::information(this, "Fill", "Select at least one band.");
351  return;
352  }
353 
354 
355  std::vector<te::stat::StatisticalSummary> vecStatistics = getSelectedStatistics();
356  m_texture = m_ui->m_textureCheckBox->isChecked();
357 
358  if(vecStatistics.empty() && m_texture == false)
359  {
360  QMessageBox::information(this, "Fill", "Select at least one statistic operation or select the texture checkbox.");
361  return;
362  }
363 
364  if(m_ui->m_repositoryLineEdit->text().isEmpty())
365  {
366  QMessageBox::information(this, "Fill", "Define a repository for the result.");
367  return;
368  }
369 
370  if(m_ui->m_newLayerNameLineEdit->text().isEmpty())
371  {
372  QMessageBox::information(this, "Fill", "Define a name for the resulting layer.");
373  return;
374  }
375 
376  std::string outputdataset = m_ui->m_newLayerNameLineEdit->text().toStdString();
377 
378  //progress
381 
382  try
383  {
384  bool res;
385 
386  if(m_toFile)
387  {
388  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toStdString());
389 
390  if (boost::filesystem::exists(uri))
391  {
392  QMessageBox::information(this, "Fill", "Output file already exists. Remove it or select a new name and try again.");
393  return;
394  }
395 
396  std::size_t idx = outputdataset.find(".");
397  if (idx != std::string::npos)
398  outputdataset=outputdataset.substr(0,idx);
399 
400  std::map<std::string, std::string> dsinfo;
401  dsinfo["URI"] = uri.string();
402 
404  dsOGR->setConnectionInfo(dsinfo);
405  dsOGR->open();
406  if (dsOGR->dataSetExists(outputdataset))
407  {
408  QMessageBox::information(this, "Fill", "There is already a dataset with the requested name in the output data source. Remove it or select a new name and try again.");
409  return;
410  }
411 
412  this->setCursor(Qt::WaitCursor);
413 
415  rst2vec->setInput(inRasterDataSource,
416  dsRasterLayer->getDataSetName(),
417  dsRasterLayer->getSchema(),
418  inVectorDataSource,
419  dsVectorLayer->getDataSetName(),
420  dsVectorLayer->getSchema());
421 
422  rst2vec->setParams(vecBands, vecStatistics, m_texture);
423 
424  rst2vec->setOutput(dsOGR, outputdataset);
425 
426  if (!rst2vec->paramsAreValid())
427  res = false;
428  else
429  res = rst2vec->run();
430 
431  if (!res)
432  {
433  this->setCursor(Qt::ArrowCursor);
434  dsOGR->close();
435  QMessageBox::information(this, "Fill", "Error: could not generate the operation.");
436  reject();
437  }
438  dsOGR->close();
439 
440  delete rst2vec;
441 
442  // let's include the new datasource in the managers
443  boost::uuids::basic_random_generator<boost::mt19937> gen;
444  boost::uuids::uuid u = gen();
445  std::string id_ds = boost::uuids::to_string(u);
446 
448  ds->setConnInfo(dsinfo);
449  ds->setTitle(uri.stem().string());
450  ds->setAccessDriver("OGR");
451  ds->setType("OGR");
452  ds->setDescription(uri.string());
453  ds->setId(id_ds);
454 
455  te::da::DataSourcePtr newds = te::da::DataSourceManager::getInstance().get(id_ds, "OGR", ds->getConnInfo());
456  newds->open();
458  m_outputDatasource = ds;
459  }
460  else
461  {
462  te::da::DataSourcePtr aux = te::da::GetDataSource(m_outputDatasource->getId());
463  if (!aux)
464  {
465  QMessageBox::information(this, "Fill", "The selected output datasource can not be accessed.");
466  return;
467  }
468 
469  if (aux->dataSetExists(outputdataset))
470  {
471  QMessageBox::information(this, "Fill", "Dataset already exists. Remove it or select a new name and try again.");
472  return;
473  }
474  this->setCursor(Qt::WaitCursor);
475 
477 
478  rst2vec->setInput(inRasterDataSource,
479  dsRasterLayer->getDataSetName(),
480  dsRasterLayer->getSchema(),
481  inVectorDataSource,
482  dsVectorLayer->getDataSetName(),
483  dsVectorLayer->getSchema());
484 
485  rst2vec->setParams(vecBands, vecStatistics, m_texture);
486 
487  rst2vec->setOutput(aux, outputdataset);
488 
489  if (!rst2vec->paramsAreValid())
490  res = false;
491  else
492  res = rst2vec->run();
493 
494  delete rst2vec;
495 
496  if (!res)
497  {
498  this->setCursor(Qt::ArrowCursor);
499  QMessageBox::information(this, "Fill", "Error: could not generate the operation.");
501 
502  reject();
503  }
504  }
505 
506  // creating a layer for the result
507  te::da::DataSourcePtr outDataSource = te::da::GetDataSource(m_outputDatasource->getId());
508 
509  te::qt::widgets::DataSet2Layer converter(m_outputDatasource->getId());
510 
511  te::da::DataSetTypePtr dt(outDataSource->getDataSetType(outputdataset).release());
512  m_outLayer = converter(dt);
513  }
514  catch(const std::exception& e)
515  {
516  this->setCursor(Qt::ArrowCursor);
517 
518  QMessageBox::information(this, "Fill", e.what());
519 
520 #ifdef TERRALIB_LOGGER_ENABLED
521  te::common::Logger::logDebug("attributefill", e.what());
522 #endif // TERRALIB_LOGGER_ENABLED
523 
525 
526  return;
527  }
528 
530  this->setCursor(Qt::ArrowCursor);
531  accept();
532 }
533 
535 {
536  reject();
537 }
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
Definition: Utils.cpp:262
Raster to vector attributefill dialog.
Mean.
Definition: Enums.h:43
TEDATAACCESSEXPORT te::rst::RasterProperty * GetFirstRasterProperty(const DataSetType *dt)
Definition: Utils.cpp:571
std::vector< unsigned int > getSelectedBands()
Get the selected bands based on selected QListWidgetItem.
const std::string & getDataSetName() const
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
Skewness.
Definition: Enums.h:49
Total not null values.
Definition: Enums.h:46
Total number of values.
Definition: Enums.h:45
void setOutput(te::da::DataSourcePtr outDsrc, std::string dsName)
void setParams(std::vector< unsigned int > bands, std::vector< te::stat::StatisticalSummary > statSum, bool texture)
Raster property.
Minimum value.
Definition: Enums.h:41
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
void removeViewer(int viewerId)
Dettach a progress viewer.
static ProgressManager & getInstance()
It returns a reference to the singleton instance.
std::auto_ptr< Ui::RasterToVectorDialogForm > m_ui
User interface.
const std::string & getDataSourceId() const
Median.
Definition: Enums.h:52
static std::auto_ptr< DataSource > make(const std::string &dsType)
Kurtosis.
Definition: Enums.h:50
Standard deviation.
Definition: Enums.h:47
Sum of values.
Definition: Enums.h:44
te::map::AbstractLayerPtr getLayer()
Get the generated layer.
void setInput(te::da::DataSourcePtr inRasterDsrc, std::string inRasterName, std::auto_ptr< te::da::DataSetType > inRasterDsType, te::da::DataSourcePtr inVectorDsrc, std::string inVectorName, std::auto_ptr< te::da::DataSetType > inVectorDsType)
Coefficient variation.
Definition: Enums.h:53
int addViewer(AbstractProgressViewer *apv)
Attach a progress viewer.
const std::list< te::da::DataSourceInfoPtr > & getSelecteds() const
Mode.
Definition: Enums.h:54
A dialog for selecting a data source.
A class that represents a data source component.
A layer with reference to a dataset.
Definition: DataSetLayer.h:47
std::auto_ptr< LayerSchema > getSchema() const
It returns the layer schema.
std::vector< te::stat::StatisticalSummary > getSelectedStatistics()
Get the selected statistics based on selected QListWidgetItem.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
Variance.
Definition: Enums.h:48
Maximum value.
Definition: Enums.h:42
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
Amplitude.
Definition: Enums.h:51
RasterToVectorDialog(QWidget *parent=0, Qt::WindowFlags f=0)
const std::string & getName() const
It returns the property name.
Definition: Property.h:127