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 "../../core/filesystem/FileSystem.h"
28 #include "../../core/logger/Logger.h"
29 #include "../../common/progress/ProgressManager.h"
30 #include "../../core/translator/Translator.h"
31 #include "../../common/STLUtils.h"
32 #include "../../dataaccess/dataset/DataSetType.h"
33 #include "../../dataaccess/dataset/DataSetTypeConverter.h"
34 #include "../../dataaccess/dataset/ObjectIdSet.h"
35 #include "../../dataaccess/datasource/DataSourceCapabilities.h"
36 #include "../../dataaccess/datasource/DataSourceInfo.h"
37 #include "../../dataaccess/datasource/DataSourceInfoManager.h"
38 #include "../../dataaccess/datasource/DataSourceFactory.h"
39 #include "../../dataaccess/datasource/DataSourceManager.h"
40 #include "../../dataaccess/utils/Utils.h"
41 #include "../../datatype/Enums.h"
42 #include "../../datatype/Property.h"
43 #include "../../maptools/AbstractLayer.h"
44 #include "../../qt/af/Utils.h"
45 #include "../../qt/widgets/datasource/selector/DataSourceSelectorDialog.h"
46 #include "../../qt/widgets/layer/utils/DataSet2Layer.h"
47 #include "../../qt/widgets/progress/ProgressViewerDialog.h"
48 #include "../../qt/widgets/rp/Utils.h"
49 #include "../../qt/widgets/Utils.h"
50 #include "../../qt/widgets/utils/DoubleListWidget.h"
51 #include "../../qt/widgets/utils/FileDialog.h"
52 #include "../../statistics/core/Utils.h"
53 #include "../../srs/SpatialReferenceSystemManager.h"
54 #include "../Config.h"
55 #include "../Exception.h"
56 #include "VectorToRasterDialog.h"
57 #include "../VectorToRaster.h"
58 #include "ui_VectorToRasterDialogForm.h"
59 
60 // Qt
61 #include <QDoubleValidator>
62 #include <QFileDialog>
63 #include <QIntValidator>
64 #include <QLineEdit>
65 #include <QList>
66 #include <QListWidget>
67 #include <QListWidgetItem>
68 #include <QMessageBox>
69 
70 // Boost
71 #include <boost/algorithm/string.hpp>
72 #include <boost/filesystem.hpp>
73 #include <boost/lexical_cast.hpp>
74 #include <boost/uuid/random_generator.hpp>
75 #include <boost/uuid/uuid_io.hpp>
76 
78  : QDialog(parent, f),
79  m_ui(new Ui::VectorToRasterDialogForm),
80  m_layers(std::list<te::map::AbstractLayerPtr>())
81 {
82 // add controls
83  m_ui->setupUi(this);
84 
85  // add icons
86  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("vector-raster-hint").pixmap(112,48));
87 
88  m_widget.reset(new te::qt::widgets::DoubleListWidget(m_ui->m_widget));
89  m_widget->setLeftLabel(tr("Available Properties"));
90  m_widget->setRightLabel(tr("Used Properties"));
91 
92  QGridLayout* displayLayout = new QGridLayout(m_ui->m_widget);
93  displayLayout->addWidget(m_widget.get());
94 
95  m_ui->m_colsLineEdit->setValidator( new QIntValidator(this) );
96  m_ui->m_rowsLineEdit->setValidator( new QIntValidator(this) );
97  m_ui->m_resXLineEdit->setValidator(new QDoubleValidator(0, 99999999, 8, this));
98  m_ui->m_resYLineEdit->setValidator(new QDoubleValidator(0, 99999999, 8, this));
99  m_ui->m_dummyLineEdit->setValidator( new QIntValidator(this) );
100 
101  connect(m_ui->m_resXLineEdit, SIGNAL(editingFinished()), this, SLOT(onResXLineEditEditingFinished()));
102  connect(m_ui->m_resYLineEdit, SIGNAL(editingFinished()), this, SLOT(onResYLineEditEditingFinished()));
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 void te::attributefill::VectorToRasterDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
118 {
119  m_layers = layers;
120 
121  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
122 
123  while(it != m_layers.end())
124  {
125  std::unique_ptr<te::da::DataSetType> dsType = it->get()->getSchema();
126  if(dsType->hasGeom())
127  m_ui->m_inVectorComboBox->addItem(QString(it->get()->getTitle().c_str()), QVariant(it->get()->getId().c_str()));
128  ++it;
129  }
130 }
131 
133 {
134  return m_outLayer;
135 }
136 
138 {
139  std::string name = te::srs::SpatialReferenceSystemManager::getInstance().getName(m_srid);
140  name += " - " + boost::lexical_cast<std::string>(m_srid);
141 
142  m_ui->m_sridLabel->setText(name.c_str());
143 }
144 
146 {
147  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
148 
149  std::string layerID = m_ui->m_inVectorComboBox->itemData(index, Qt::UserRole).toString().toUtf8().data();
150 
151  m_widget->clearInputValues();
152  m_widget->clearOutputValues();
153 
154  while(it != m_layers.end())
155  {
156  if(layerID == it->get()->getId())
157  {
158  m_selectedLayer = it->get();
159  std::unique_ptr<const te::map::LayerSchema> schema(m_selectedLayer->getSchema());
160 
161  const std::vector<te::dt::Property*> vecProperties = schema->getProperties();
162  std::vector<std::string> propNameVec;
163 
164  for(std::size_t i = 0; i < vecProperties.size(); ++i)
165  {
166  int type = vecProperties[i]->getType();
167  if( type == te::dt::CDOUBLE_TYPE ||
168  type == te::dt::CFLOAT_TYPE ||
169  type == te::dt::CINT16_TYPE ||
170  type == te::dt::CINT32_TYPE ||
171  type == te::dt::DOUBLE_TYPE ||
172  type == te::dt::FLOAT_TYPE ||
173  type == te::dt::INT16_TYPE ||
174  type == te::dt::INT32_TYPE ||
175  type == te::dt::INT64_TYPE ||
176  type == te::dt::UINT16_TYPE ||
177  type == te::dt::UINT32_TYPE ||
178  type == te::dt::UINT64_TYPE)
179  {
180  propNameVec.push_back(vecProperties[i]->getName());
181  m_properties.push_back(vecProperties[i]);
182  }
183  }
184  m_widget->setInputValues(propNameVec);
185 
186  m_srid = m_selectedLayer->getSRID();
187  showSRS();
188  }
189  ++it;
190  }
191 }
192 
193 
195 {
196  te::gm::Envelope env = m_selectedLayer->getExtent();
197 
198  if(!env.isValid())
199  {
200  QMessageBox::warning(this, tr("Attribute Fill"), tr("Invalid bounding box."));
201  return;
202  }
203 
204  double resX = m_ui->m_resXLineEdit->text().toDouble();
205 
206  int maxCols = (int)ceil((env.m_urx - env.m_llx)/resX);
207  m_ui->m_colsLineEdit->setText(QString::number(maxCols));
208 }
209 
211 {
212  te::gm::Envelope env = m_selectedLayer->getExtent();
213 
214  if(!env.isValid())
215  {
216  QMessageBox::warning(this, tr("Attribute Fill"), tr("Invalid bounding box."));
217  return;
218  }
219 
220  double resY = m_ui->m_resYLineEdit->text().toDouble();
221 
222  int maxRows = (int)ceil((env.m_ury - env.m_lly)/resY);
223  m_ui->m_rowsLineEdit->setText(QString::number(maxRows));
224 }
225 
227 {
228  m_ui->m_newLayerNameLineEdit->clear();
229  m_ui->m_repositoryLineEdit->clear();
230 
232 
233  try {
234  fileDialog.exec();
235  }
236  catch (te::common::Exception& ex) {
237  QMessageBox::warning(this, tr("File information"), ex.what());
238  return;
239  }
240 
241  m_ui->m_repositoryLineEdit->setText(fileDialog.getPath().c_str());
242  m_ui->m_newLayerNameLineEdit->setText(fileDialog.getFileName().c_str());
243 
244  m_toFile = true;
245  m_ui->m_newLayerNameLineEdit->setEnabled(false);
246 }
247 
249 {
250  if(m_ui->m_inVectorComboBox->count() == 0)
251  {
252  QMessageBox::information(this, "Fill", "Select an input vector layer.");
253  return;
254  }
255 
256  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(m_selectedLayer.get());
257 
258  if(!dsLayer)
259  {
260  QMessageBox::information(this, "Fill", "Can not execute this operation on this type of layer.");
261  return;
262  }
263 
264  te::da::DataSourcePtr inDataSource = te::da::GetDataSource(dsLayer->getDataSourceId(), true);
265  if (!inDataSource.get())
266  {
267  QMessageBox::information(this, "Fill", "The selected input data source can not be accessed.");
268  m_ui->m_targetFileToolButton->setFocus();
269  return;
270  }
271 
272  if(m_widget->getOutputValues().size() == 0)
273  {
274  QMessageBox::information(this, "Fill", "Select at least one output attribute to represent the band of the raster.");
275  return;
276  }
277 
278  if(m_ui->m_resXLineEdit->text().isEmpty())
279  {
280  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
281  m_ui->m_resXLineEdit->setFocus();
282  return;
283  }
284 
285  if(m_ui->m_resYLineEdit->text().isEmpty())
286  {
287  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
288  m_ui->m_resYLineEdit->setFocus();
289  return;
290  }
291 
292  if(m_ui->m_colsLineEdit->text().isEmpty())
293  {
294  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
295  m_ui->m_colsLineEdit->setFocus();
296  return;
297  }
298 
299  if(m_ui->m_rowsLineEdit->text().isEmpty())
300  {
301  QMessageBox::information(this, "Fill", "Define a resolution for the output raster.");
302  m_ui->m_rowsLineEdit->setFocus();
303  return;
304  }
305 
306  if(m_ui->m_dummyCheckBox->isChecked())
307  {
308  if(m_ui->m_dummyLineEdit->text().isEmpty())
309  {
310  QMessageBox::information(this, "Fill", "Define a dummy value for the output raster.");
311  m_ui->m_dummyLineEdit->setFocus();
312  return;
313  }
314  }
315 
316  if(m_ui->m_repositoryLineEdit->text().isEmpty())
317  {
318  QMessageBox::information(this, "Fill", "Define a repository for the result.");
319  m_ui->m_targetFileToolButton->setFocus();
320  return;
321  }
322 
323  if(m_ui->m_newLayerNameLineEdit->text().isEmpty())
324  {
325  QMessageBox::information(this, "Fill", "Define a name for the resulting layer.");
326  m_ui->m_newLayerNameLineEdit->setFocus();
327  return;
328  }
329 
330  std::string outputdataset = m_ui->m_newLayerNameLineEdit->text().toUtf8().data();
331 
332  //progress
334 
335  try
336  {
337  bool res;
338 
339  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toUtf8().data());
340 
341  if (te::core::FileSystem::exists(uri.string()))
342  {
343  QMessageBox::information(this, "Fill", "Output file already exists. Remove it or select a new name and try again.");
344  return;
345  }
346 
347  std::size_t idx = outputdataset.find(".");
348  if (idx != std::string::npos)
349  outputdataset=outputdataset.substr(0,idx);
350 
351  std::string dsinfo("file://" + uri.string());
352 
353  te::da::DataSourcePtr dsOGR(te::da::DataSourceFactory::make("OGR", dsinfo).release());
354  dsOGR->open();
355  if (dsOGR->dataSetExists(outputdataset))
356  {
357  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.");
358  return;
359  }
360 
361  std::unique_ptr<te::da::DataSetTypeConverter> converter(new te::da::DataSetTypeConverter(dsLayer->getSchema().get(), inDataSource->getCapabilities(), inDataSource->getEncoding()));
362 
363  te::da::AssociateDataSetTypeConverterSRID(converter.get(), dsLayer->getSRID());
364 
365  this->setCursor(Qt::WaitCursor);
366 
368  vec2rst->setInput(inDataSource, dsLayer->getTitle(), std::move(converter));
369  vec2rst->setParams( m_widget->getOutputValues(),
370  m_ui->m_resXLineEdit->text().toDouble(),
371  m_ui->m_resYLineEdit->text().toDouble(),
372  m_ui->m_colsLineEdit->text().toInt(),
373  m_ui->m_rowsLineEdit->text().toInt(),
374  m_ui->m_dummyCheckBox->isChecked(),
375  m_ui->m_dummyLineEdit->text().toInt());
376  vec2rst->setOutput(dsOGR, outputdataset);
377 
378  if (!vec2rst->paramsAreValid())
379  res = false;
380  else
381  res = vec2rst->run();
382 
383  if(!res)
384  {
385  this->setCursor(Qt::ArrowCursor);
386  dsOGR->close();
387  QMessageBox::information(this, "Fill", "Error: could not generate the operation.");
388  reject();
389  }
390  dsOGR->close();
391 
392  delete vec2rst;
393 
394 // let's include the new datasource in the managers
395  boost::uuids::basic_random_generator<boost::mt19937> gen;
396  boost::uuids::uuid u = gen();
397  std::string id_ds = boost::uuids::to_string(u);
398 
400  ds->setConnInfo(dsinfo);
401  ds->setTitle(uri.stem().string());
402  ds->setAccessDriver("GDAL");
403  ds->setType("GDAL");
404  ds->setDescription(uri.string());
405  ds->setId(id_ds);
406 
407  te::da::DataSourcePtr newds = te::da::DataSourceManager::getInstance().get(id_ds, "GDAL", ds->getConnInfo());
408  newds->open();
411 
412  }
413  catch(const std::exception& e)
414  {
415  this->setCursor(Qt::ArrowCursor);
416 
417  QMessageBox::information(this, "Fill", e.what());
418 
419 #ifdef TERRALIB_LOGGER_ENABLED
420  TE_CORE_LOG_DEBUG("attributefill", e.what());
421 #endif // TERRALIB_LOGGER_ENABLED
422 
423  return;
424  }
425 
427  m_outputDatasource->getConnInfo());
428 
429  this->setCursor(Qt::ArrowCursor);
430 
431  accept();
432 }
433 
435 {
436  reject();
437 }
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
VectorToRasterDialog(QWidget *parent=0, Qt::WindowFlags f=0)
Defines a component for choose a file.
Definition: FileDialog.h:52
static bool exists(const std::string &path)
Checks if a given path in UTF-8 exists.
Definition: FileSystem.cpp:142
boost::shared_ptr< DataSource > DataSourcePtr
TEDATAACCESSEXPORT void AssociateDataSetTypeConverterSRID(DataSetTypeConverter *converter, const int &inputSRID, const int &outputSRID=TE_UNKNOWN_SRS)
virtual const std::string & getTitle() const
It returns the layer title.
virtual const char * what() const
It outputs the exception message.
#define TE_CORE_LOG_DEBUG(channel, message)
Use this tag in order to log a message to a specified logger with the DEBUG level.
Definition: Logger.h:225
std::unique_ptr< Ui::VectorToRasterDialogForm > m_ui
double m_urx
Upper right corner x-coordinate.
std::unique_ptr< LayerSchema > getSchema() const
It returns the layer schema.
static te::dt::Date ds(2010, 01, 01)
An converter for DataSetType.
double m_llx
Lower left corner x-coordinate.
static SpatialReferenceSystemManager & getInstance()
It returns a reference to the singleton instance.
te::map::AbstractLayerPtr m_selectedLayer
Selected layer.
An Envelope defines a 2D rectangular region.
void exec()
This method will open the dialog of file selection and populate the class members with the chosen fil...
Definition: FileDialog.cpp:54
void setInput(te::da::DataSourcePtr inVectorDsrc, std::string inVectorName, std::unique_ptr< te::da::DataSetTypeConverter > inVectorDsType)
URI C++ Library.
Definition: Attributes.h:37
te::map::AbstractLayerPtr getLayer()
Get the generated layer.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
double m_lly
Lower left corner y-coordinate.
void setParams(std::vector< std::string > selectedAttVec, double resolutionX, double resolutionY, int columns, int rows, bool useDummy, int dummy=0)
std::string getPath()
This method will return the chosen path.
Definition: FileDialog.cpp:103
TEQTWIDGETSEXPORT te::map::AbstractLayerPtr createLayer(const std::string &driverName, const te::core::URI &connInfo)
double m_ury
Upper right corner y-coordinate.
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
te::da::DataSourceInfoPtr m_outputDatasource
DataSource information.
std::vector< te::dt::Property * > m_properties
Properties related to the selected Layer.
A class that represents a data source component.
virtual int getSRID() const
It returns the Spatial Reference System ID associated to the Layer.
A layer with reference to a dataset.
Definition: DataSetLayer.h:47
std::string getFileName()
This method will return the file name.
Definition: FileDialog.cpp:113
te::map::AbstractLayerPtr m_outLayer
Generated Layer.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void setOutput(te::da::DataSourcePtr outDsrc, std::string dsName)
virtual const std::string & getDataSourceId() const
bool isValid() const
It tells if the rectangle is valid or not.
std::list< te::map::AbstractLayerPtr > m_layers
List of layers.
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
std::unique_ptr< te::qt::widgets::DoubleListWidget > m_widget
Double list widget.