VectorToRasterDialog.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/vp/VectorToRasterDialog.cpp
22 
23  \brief A dialog for vector to raster operation
24 */
25 
26 // TerraLib
27 #include "../../BuildConfig.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/dataset/ObjectIdSet.h"
34 #include "../../dataaccess/datasource/DataSourceCapabilities.h"
35 #include "../../dataaccess/datasource/DataSourceInfo.h"
36 #include "../../dataaccess/datasource/DataSourceInfoManager.h"
37 #include "../../dataaccess/datasource/DataSourceFactory.h"
38 #include "../../dataaccess/datasource/DataSourceManager.h"
39 #include "../../dataaccess/utils/Utils.h"
40 #include "../../datatype/Enums.h"
41 #include "../../datatype/Property.h"
42 #include "../../maptools/AbstractLayer.h"
43 #include "../../qt/af/Utils.h"
44 #include "../../qt/widgets/datasource/selector/DataSourceSelectorDialog.h"
45 #include "../../qt/widgets/layer/utils/DataSet2Layer.h"
46 #include "../../qt/widgets/progress/ProgressViewerDialog.h"
47 #include "../../qt/widgets/rp/Utils.h"
48 #include "../../qt/widgets/Utils.h"
49 #include "../../qt/widgets/utils/DoubleListWidget.h"
50 #include "../../statistics/core/Utils.h"
51 #include "../../srs/SpatialReferenceSystemManager.h"
52 #include "../Config.h"
53 #include "../Exception.h"
54 #include "VectorToRasterDialog.h"
55 #include "../VectorToRaster.h"
56 #include "ui_VectorToRasterDialogForm.h"
57 
58 // Qt
59 #include <QDoubleValidator>
60 #include <QFileDialog>
61 #include <QIntValidator>
62 #include <QLineEdit>
63 #include <QList>
64 #include <QListWidget>
65 #include <QListWidgetItem>
66 #include <QMessageBox>
67 
68 // Boost
69 #include <boost/algorithm/string.hpp>
70 #include <boost/filesystem.hpp>
71 #include <boost/lexical_cast.hpp>
72 #include <boost/uuid/random_generator.hpp>
73 #include <boost/uuid/uuid_io.hpp>
74 
76  : QDialog(parent, f),
77  m_ui(new Ui::VectorToRasterDialogForm),
78  m_layers(std::list<te::map::AbstractLayerPtr>())
79 {
80 // add controls
81  m_ui->setupUi(this);
82 
83  // add icons
84  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("vector-raster-hint").pixmap(112,48));
85 
86  m_widget.reset(new te::qt::widgets::DoubleListWidget(m_ui->m_widget));
87  m_widget->setLeftLabel("Available Properties");
88  m_widget->setRightLabel("Used Properties");
89 
90  QGridLayout* displayLayout = new QGridLayout(m_ui->m_widget);
91  displayLayout->addWidget(m_widget.get());
92 
93  m_ui->m_colsLineEdit->setValidator( new QIntValidator(this) );
94  m_ui->m_rowsLineEdit->setValidator( new QIntValidator(this) );
95  m_ui->m_resXLineEdit->setValidator( new QDoubleValidator(0, 100, 4, this) );
96  m_ui->m_resYLineEdit->setValidator( new QDoubleValidator(0, 100, 4, this) );
97  m_ui->m_dummyLineEdit->setValidator( new QIntValidator(this) );
98 
99  connect(m_ui->m_resXLineEdit, SIGNAL(editingFinished()), this, SLOT(onResXLineEditEditingFinished()));
100  connect(m_ui->m_resYLineEdit, SIGNAL(editingFinished()), this, SLOT(onResYLineEditEditingFinished()));
101  connect(m_ui->m_colsLineEdit, SIGNAL(editingFinished()), this, SLOT(onColsLineEditEditingFinished()));
102  connect(m_ui->m_rowsLineEdit, SIGNAL(editingFinished()), this, SLOT(onRowsLineEditEditingFinished()));
103 
104  connect(m_ui->m_inVectorComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onVectorComboBoxChanged(int)));
105 
106  connect(m_ui->m_targetFileToolButton, SIGNAL(pressed()), this, SLOT(onTargetFileToolButtonPressed()));
107 
108  connect(m_ui->m_okPushButton, SIGNAL(clicked()), this, SLOT(onOkPushButtonClicked()));
109  connect(m_ui->m_cancelPushButton, SIGNAL(clicked()), this, SLOT(onCancelPushButtonClicked()));
110 
111  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
112  m_ui->m_helpPushButton->setPageReference("plugins/attributefill/attrfill_vector_to_raster.html");
113 }
114 
116 {
117 }
118 
119 void te::attributefill::VectorToRasterDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
120 {
121  m_layers = layers;
122 
123  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
124 
125  while(it != m_layers.end())
126  {
127  std::auto_ptr<te::da::DataSetType> dsType = it->get()->getSchema();
128  if(dsType->hasGeom())
129  m_ui->m_inVectorComboBox->addItem(QString(it->get()->getTitle().c_str()), QVariant(it->get()->getId().c_str()));
130  ++it;
131  }
132 }
133 
135 {
136  return m_outLayer;
137 }
138 
140 {
141  std::string name = te::srs::SpatialReferenceSystemManager::getInstance().getName(m_srid);
142  name += " - " + boost::lexical_cast<std::string>(m_srid);
143 
144  m_ui->m_sridLabel->setText(name.c_str());
145 }
146 
148 {
149  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
150 
151  std::string layerID = m_ui->m_inVectorComboBox->itemData(index, Qt::UserRole).toString().toStdString();
152 
153  m_widget->clearInputValues();
154  m_widget->clearOutputValues();
155 
156  while(it != m_layers.end())
157  {
158  if(layerID == it->get()->getId().c_str())
159  {
160  m_selectedLayer = it->get();
161  std::auto_ptr<const te::map::LayerSchema> schema(m_selectedLayer->getSchema());
162 
163  const std::vector<te::dt::Property*> vecProperties = schema->getProperties();
164  std::vector<std::string> propNameVec;
165 
166  for(std::size_t i = 0; i < vecProperties.size(); ++i)
167  {
168  int type = vecProperties[i]->getType();
169  if( type == te::dt::CDOUBLE_TYPE ||
170  type == te::dt::CFLOAT_TYPE ||
171  type == te::dt::CINT16_TYPE ||
172  type == te::dt::CINT32_TYPE ||
173  type == te::dt::DOUBLE_TYPE ||
174  type == te::dt::FLOAT_TYPE ||
175  type == te::dt::INT16_TYPE ||
176  type == te::dt::INT32_TYPE ||
177  type == te::dt::INT64_TYPE ||
178  type == te::dt::UINT16_TYPE ||
179  type == te::dt::UINT32_TYPE ||
180  type == te::dt::UINT64_TYPE)
181  {
182  propNameVec.push_back(vecProperties[i]->getName().c_str());
183  m_properties.push_back(vecProperties[i]);
184  }
185  }
186  m_widget->setInputValues(propNameVec);
187 
188  m_srid = m_selectedLayer->getSRID();
189  showSRS();
190  }
191  ++it;
192  }
193 }
194 
195 
197 {
198  double resX = m_ui->m_resXLineEdit->text().toDouble();
199 
200  te::gm::Envelope env = m_selectedLayer->getExtent();
201 
202  if(!env.isValid())
203  {
204  QMessageBox::warning(this, tr("Attribute Fill"), tr("Invalid envelope!"));
205  return;
206  }
207 
208  int maxCols = (int)ceil((env.m_urx - env.m_llx)/resX);
209 
210  m_ui->m_colsLineEdit->setText(QString::number(maxCols));
211 }
212 
214 {
215  double resY = m_ui->m_resYLineEdit->text().toDouble();
216 
217  te::gm::Envelope env = m_selectedLayer->getExtent();
218 
219  if(!env.isValid())
220  {
221  QMessageBox::warning(this, tr("Attribute Fill"), tr("Invalid envelope!"));
222  return;
223  }
224 
225  int maxRows = (int)ceil((env.m_ury - env.m_lly)/resY);
226 
227  m_ui->m_rowsLineEdit->setText(QString::number(maxRows));
228 }
229 
231 {
232  int cols = m_ui->m_colsLineEdit->text().toInt();
233 
234  te::gm::Envelope env = m_selectedLayer->getExtent();
235 
236  if(!env.isValid())
237  {
238  QMessageBox::warning(this, tr("Attribute Fill"), tr("Invalid envelope!"));
239  return;
240  }
241 
242  double resX = (env.m_urx - env.m_llx)/cols;
243 
244  m_ui->m_resXLineEdit->setText(QString::number(resX));
245 }
246 
248 {
249  int rows = m_ui->m_rowsLineEdit->text().toInt();
250 
251  te::gm::Envelope env = m_selectedLayer->getExtent();
252 
253  if(!env.isValid())
254  {
255  QMessageBox::warning(this, tr("Attribute Fill"), tr("Invalid envelope!"));
256  return;
257  }
258 
259  double resY = (env.m_ury - env.m_lly)/rows;
260 
261  m_ui->m_resYLineEdit->setText(QString::number(resY));
262 }
263 
265 {
266  m_ui->m_newLayerNameLineEdit->clear();
267  m_ui->m_repositoryLineEdit->clear();
268 
269  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."),
270  QString(), tr("TIFF (*.tif *.TIF);;"),0, QFileDialog::DontConfirmOverwrite);
271 
272  if (fileName.isEmpty())
273  return;
274 
275  boost::filesystem::path outfile(fileName.toStdString());
276  std::string aux = outfile.leaf().string();
277  m_ui->m_newLayerNameLineEdit->setText(aux.c_str());
278  aux = outfile.string();
279  m_ui->m_repositoryLineEdit->setText(aux.c_str());
280 
281  m_toFile = true;
282  m_ui->m_newLayerNameLineEdit->setEnabled(false);
283 }
284 
286 {
287  if(m_ui->m_inVectorComboBox->count() == 0)
288  {
289  QMessageBox::information(this, "Fill", "Select an input vector layer.");
290  return;
291  }
292 
293  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(m_selectedLayer.get());
294 
295  if(!dsLayer)
296  {
297  QMessageBox::information(this, "Fill", "Can not execute this operation on this type of layer.");
298  return;
299  }
300 
301  te::da::DataSourcePtr inDataSource = te::da::GetDataSource(dsLayer->getDataSourceId(), true);
302  if (!inDataSource.get())
303  {
304  QMessageBox::information(this, "Fill", "The selected input data source can not be accessed.");
305  m_ui->m_targetFileToolButton->setFocus();
306  return;
307  }
308 
309  if(m_widget->getOutputValues().size() == 0)
310  {
311  QMessageBox::information(this, "Fill", "Select at least one output attribute to represent the band of the raster.");
312  return;
313  }
314 
315  if(m_ui->m_resXLineEdit->text().isEmpty())
316  {
317  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
318  m_ui->m_resXLineEdit->setFocus();
319  return;
320  }
321 
322  if(m_ui->m_resYLineEdit->text().isEmpty())
323  {
324  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
325  m_ui->m_resYLineEdit->setFocus();
326  return;
327  }
328 
329  if(m_ui->m_colsLineEdit->text().isEmpty())
330  {
331  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
332  m_ui->m_colsLineEdit->setFocus();
333  return;
334  }
335 
336  if(m_ui->m_rowsLineEdit->text().isEmpty())
337  {
338  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
339  m_ui->m_rowsLineEdit->setFocus();
340  return;
341  }
342 
343  if(m_ui->m_dummyCheckBox->isChecked())
344  {
345  if(m_ui->m_dummyLineEdit->text().isEmpty())
346  {
347  QMessageBox::information(this, "Fill", "Define a dummy value for the output raster.");
348  m_ui->m_dummyLineEdit->setFocus();
349  return;
350  }
351  }
352 
353  if(m_ui->m_repositoryLineEdit->text().isEmpty())
354  {
355  QMessageBox::information(this, "Fill", "Define a repository for the result.");
356  m_ui->m_targetFileToolButton->setFocus();
357  return;
358  }
359 
360  if(m_ui->m_newLayerNameLineEdit->text().isEmpty())
361  {
362  QMessageBox::information(this, "Fill", "Define a name for the resulting layer.");
363  m_ui->m_newLayerNameLineEdit->setFocus();
364  return;
365  }
366 
367  std::string outputdataset = m_ui->m_newLayerNameLineEdit->text().toStdString();
368 
369  //progress
372 
373  try
374  {
375  bool res;
376 
377  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toStdString());
378 
379  if (boost::filesystem::exists(uri))
380  {
381  QMessageBox::information(this, "Fill", "Output file already exists. Remove it or select a new name and try again.");
382  return;
383  }
384 
385  std::size_t idx = outputdataset.find(".");
386  if (idx != std::string::npos)
387  outputdataset=outputdataset.substr(0,idx);
388 
389  std::map<std::string, std::string> dsinfo;
390  dsinfo["URI"] = uri.string();
391 
393  dsOGR->setConnectionInfo(dsinfo);
394  dsOGR->open();
395  if (dsOGR->dataSetExists(outputdataset))
396  {
397  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.");
398  return;
399  }
400 
401  this->setCursor(Qt::WaitCursor);
402 
404  vec2rst->setInput(inDataSource, dsLayer->getTitle(), dsLayer->getSchema());
405  vec2rst->setParams( m_widget->getOutputValues(),
406  m_ui->m_resXLineEdit->text().toDouble(),
407  m_ui->m_resYLineEdit->text().toDouble(),
408  m_ui->m_colsLineEdit->text().toInt(),
409  m_ui->m_rowsLineEdit->text().toInt(),
410  m_ui->m_dummyCheckBox->isChecked(),
411  m_ui->m_dummyLineEdit->text().toInt());
412  vec2rst->setOutput(dsOGR, outputdataset);
413 
414  if (!vec2rst->paramsAreValid())
415  res = false;
416  else
417  res = vec2rst->run();
418 
419  if(!res)
420  {
421  this->setCursor(Qt::ArrowCursor);
422  dsOGR->close();
423  QMessageBox::information(this, "Fill", "Error: could not generate the operation.");
424  reject();
425  }
426  dsOGR->close();
427 
428  delete vec2rst;
429 
430 // let's include the new datasource in the managers
431  boost::uuids::basic_random_generator<boost::mt19937> gen;
432  boost::uuids::uuid u = gen();
433  std::string id_ds = boost::uuids::to_string(u);
434 
436  ds->setConnInfo(dsinfo);
437  ds->setTitle(uri.stem().string());
438  ds->setAccessDriver("GDAL");
439  ds->setType("GDAL");
440  ds->setDescription(uri.string());
441  ds->setId(id_ds);
442 
443  te::da::DataSourcePtr newds = te::da::DataSourceManager::getInstance().get(id_ds, "GDAL", ds->getConnInfo());
444  newds->open();
446  m_outputDatasource = ds;
447 
448  }
449  catch(const std::exception& e)
450  {
451  this->setCursor(Qt::ArrowCursor);
452 
453  QMessageBox::information(this, "Fill", e.what());
454 
455 #ifdef TERRALIB_LOGGER_ENABLED
456  te::common::Logger::logDebug("attributefill", e.what());
457 #endif // TERRALIB_LOGGER_ENABLED
458 
460 
461  return;
462  }
463 
464  m_outLayer = te::qt::widgets::createLayer("GDAL",
465  m_outputDatasource->getConnInfo());
466 
468  this->setCursor(Qt::ArrowCursor);
469 
470  accept();
471 
472 }
473 
475 {
476  reject();
477 }
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
VectorToRasterDialog(QWidget *parent=0, Qt::WindowFlags f=0)
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
virtual const std::string & getTitle() const
It returns the layer title.
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
void removeViewer(int viewerId)
Dettach a progress viewer.
static SpatialReferenceSystemManager & getInstance()
It returns a reference to the singleton instance.
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
const std::string & getDataSourceId() const
static std::auto_ptr< DataSource > make(const std::string &dsType)
URI C++ Library.
te::map::AbstractLayerPtr getLayer()
Get the generated layer.
void setInput(te::da::DataSourcePtr inVectorDsrc, std::string inVectorName, std::auto_ptr< te::da::DataSetType > inVectorDsType)
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
int addViewer(AbstractProgressViewer *apv)
Attach a progress viewer.
void setParams(std::vector< std::string > selectedAttVec, double resolutionX, double resolutionY, int columns, int rows, bool useDummy, int dummy=0)
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
std::auto_ptr< Ui::VectorToRasterDialogForm > m_ui
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.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void setOutput(te::da::DataSourcePtr outDsrc, std::string dsName)
TEQTWIDGETSEXPORT te::map::AbstractLayerPtr createLayer(const std::string &driverName, const std::map< std::string, std::string > &connInfo)
Definition: Utils.cpp:40
std::auto_ptr< te::qt::widgets::DoubleListWidget > m_widget
Double list widget.
bool isValid() const
It tells if the rectangle is valid or not.
Definition: Envelope.h:438
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr