All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 "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/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  QMessageBox::information(this, "Help", "Under development");
288 }
289 
291 {
292  if(m_ui->m_inVectorComboBox->count() == 0)
293  {
294  QMessageBox::information(this, "Fill", "Select an input vector layer.");
295  return;
296  }
297 
298  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(m_selectedLayer.get());
299 
300  if(!dsLayer)
301  {
302  QMessageBox::information(this, "Fill", "Can not execute this operation on this type of layer.");
303  return;
304  }
305 
306  te::da::DataSourcePtr inDataSource = te::da::GetDataSource(dsLayer->getDataSourceId(), true);
307  if (!inDataSource.get())
308  {
309  QMessageBox::information(this, "Fill", "The selected input data source can not be accessed.");
310  m_ui->m_targetFileToolButton->setFocus();
311  return;
312  }
313 
314  if(m_widget->getOutputValues().size() == 0)
315  {
316  QMessageBox::information(this, "Fill", "Select at least one output attribute to represent the band of the raster.");
317  return;
318  }
319 
320  if(m_ui->m_resXLineEdit->text().isEmpty())
321  {
322  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
323  m_ui->m_resXLineEdit->setFocus();
324  return;
325  }
326 
327  if(m_ui->m_resYLineEdit->text().isEmpty())
328  {
329  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
330  m_ui->m_resYLineEdit->setFocus();
331  return;
332  }
333 
334  if(m_ui->m_colsLineEdit->text().isEmpty())
335  {
336  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
337  m_ui->m_colsLineEdit->setFocus();
338  return;
339  }
340 
341  if(m_ui->m_rowsLineEdit->text().isEmpty())
342  {
343  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
344  m_ui->m_rowsLineEdit->setFocus();
345  return;
346  }
347 
348  if(m_ui->m_dummyCheckBox->isChecked())
349  {
350  if(m_ui->m_dummyLineEdit->text().isEmpty())
351  {
352  QMessageBox::information(this, "Fill", "Define a dummy value for the output raster.");
353  m_ui->m_dummyLineEdit->setFocus();
354  return;
355  }
356  }
357 
358  if(m_ui->m_repositoryLineEdit->text().isEmpty())
359  {
360  QMessageBox::information(this, "Fill", "Define a repository for the result.");
361  m_ui->m_targetFileToolButton->setFocus();
362  return;
363  }
364 
365  if(m_ui->m_newLayerNameLineEdit->text().isEmpty())
366  {
367  QMessageBox::information(this, "Fill", "Define a name for the resulting layer.");
368  m_ui->m_newLayerNameLineEdit->setFocus();
369  return;
370  }
371 
372  std::string outputdataset = m_ui->m_newLayerNameLineEdit->text().toStdString();
373 
374  //progress
377 
378  try
379  {
380  bool res;
381 
382  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toStdString());
383 
384  if (boost::filesystem::exists(uri))
385  {
386  QMessageBox::information(this, "Fill", "Output file already exists. Remove it or select a new name and try again.");
387  return;
388  }
389 
390  std::size_t idx = outputdataset.find(".");
391  if (idx != std::string::npos)
392  outputdataset=outputdataset.substr(0,idx);
393 
394  std::map<std::string, std::string> dsinfo;
395  dsinfo["URI"] = uri.string();
396 
398  dsOGR->setConnectionInfo(dsinfo);
399  dsOGR->open();
400  if (dsOGR->dataSetExists(outputdataset))
401  {
402  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.");
403  return;
404  }
405 
406  this->setCursor(Qt::WaitCursor);
407 
409  vec2rst->setInput(inDataSource, dsLayer->getTitle(), dsLayer->getSchema());
410  vec2rst->setParams( m_widget->getOutputValues(),
411  m_ui->m_resXLineEdit->text().toDouble(),
412  m_ui->m_resYLineEdit->text().toDouble(),
413  m_ui->m_colsLineEdit->text().toInt(),
414  m_ui->m_rowsLineEdit->text().toInt(),
415  m_ui->m_dummyCheckBox->isChecked(),
416  m_ui->m_dummyLineEdit->text().toInt());
417  vec2rst->setOutput(dsOGR, outputdataset);
418 
419  if (!vec2rst->paramsAreValid())
420  res = false;
421  else
422  res = vec2rst->run();
423 
424  if(!res)
425  {
426  this->setCursor(Qt::ArrowCursor);
427  dsOGR->close();
428  QMessageBox::information(this, "Fill", "Error: could not generate the operation.");
429  reject();
430  }
431  dsOGR->close();
432 
433  delete vec2rst;
434 
435 // let's include the new datasource in the managers
436  boost::uuids::basic_random_generator<boost::mt19937> gen;
437  boost::uuids::uuid u = gen();
438  std::string id_ds = boost::uuids::to_string(u);
439 
441  ds->setConnInfo(dsinfo);
442  ds->setTitle(uri.stem().string());
443  ds->setAccessDriver("GDAL");
444  ds->setType("GDAL");
445  ds->setDescription(uri.string());
446  ds->setId(id_ds);
447 
448  te::da::DataSourcePtr newds = te::da::DataSourceManager::getInstance().get(id_ds, "GDAL", ds->getConnInfo());
449  newds->open();
451  m_outputDatasource = ds;
452 
453  }
454  catch(const std::exception& e)
455  {
456  this->setCursor(Qt::ArrowCursor);
457 
458  QMessageBox::information(this, "Fill", e.what());
459 
460 #ifdef TERRALIB_LOGGER_ENABLED
461  te::common::Logger::logDebug("attributefill", e.what());
462 #endif // TERRALIB_LOGGER_ENABLED
463 
465 
466  return;
467  }
468 
469  m_outLayer = te::qt::widgets::createLayer("GDAL",
470  m_outputDatasource->getConnInfo());
471 
473  this->setCursor(Qt::ArrowCursor);
474 
475  accept();
476 
477 }
478 
480 {
481  reject();
482 }
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)
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