All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MultipartToSinglepartDialog.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/MultipartToSinglepartDialog.cpp
22 
23  \brief A Multipart to Singlepart operation dialog
24 */
25 
26 // TerraLib
27 #include "../../common/progress/ProgressManager.h"
28 #include "../../common/Logger.h"
29 #include "../../common/Translator.h"
30 #include "../../common/STLUtils.h"
31 #include "../../dataaccess/dataset/DataSetType.h"
32 #include "../../dataaccess/dataset/ObjectIdSet.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 "../../statistics/core/Utils.h"
47 #include "../Config.h"
48 #include "../Exception.h"
49 #include "../MultipartToSinglepart.h"
51 #include "ui_MultipartToSinglepartDialogForm.h"
52 #include "Utils.h"
53 
54 // Qt
55 #include <QFileDialog>
56 #include <QList>
57 #include <QListWidget>
58 #include <QListWidgetItem>
59 #include <QMessageBox>
60 #include <QTreeWidget>
61 
62 // Boost
63 #include <boost/algorithm/string.hpp>
64 #include <boost/filesystem.hpp>
65 #include <boost/uuid/random_generator.hpp>
66 #include <boost/uuid/uuid_io.hpp>
67 
69 
71  : QDialog(parent, f),
72  m_ui(new Ui::MultipartToSinglepartDialogForm),
73  m_layers(std::list<te::map::AbstractLayerPtr>()),
74  m_selectedLayer(0),
75  m_toFile(false)
76 {
77 // add controls
78  m_ui->setupUi(this);
79 
80 // add icons
81  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("vp-multiparttosinglepart-hint").pixmap(112,48));
82  m_ui->m_targetDatasourceToolButton->setIcon(QIcon::fromTheme("datasource"));
83 
84  connect(m_ui->m_layersComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onLayerComboBoxChanged(int)));
85  connect(m_ui->m_targetDatasourceToolButton, SIGNAL(pressed()), this, SLOT(onTargetDatasourceToolButtonPressed()));
86  connect(m_ui->m_targetFileToolButton, SIGNAL(pressed()), this, SLOT(onTargetFileToolButtonPressed()));
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/vp/vp_multiparttosinglepart.html");
92 
94  m_ui->m_newLayerNameLineEdit->setEnabled(true);
95 }
96 
98 {
99 }
100 
101 void te::vp::MultipartToSinglepartDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
102 {
103  m_layers = layers;
104 
105  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
106 
107  while(it != m_layers.end())
108  {
109  std::auto_ptr<te::da::DataSetType> dsType = it->get()->getSchema();
110  if(dsType->hasGeom())
111  m_ui->m_layersComboBox->addItem(it->get()->getTitle().c_str(), QVariant(QVariant::fromValue(*it)));
112 
113  ++it;
114  }
115 }
116 
118 {
119  return m_layer;
120 }
121 
123 {
124  QVariant varLayer = m_ui->m_layersComboBox->itemData(index, Qt::UserRole);
125  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
126 
127  m_selectedLayer = layer;
128 
129  std::string layerID = m_ui->m_layersComboBox->itemData(index, Qt::UserRole).toString().toStdString();
130 }
131 
133 {
134  m_ui->m_newLayerNameLineEdit->clear();
135  m_ui->m_newLayerNameLineEdit->setEnabled(true);
137  dlg.exec();
138 
139  std::list<te::da::DataSourceInfoPtr> dsPtrList = dlg.getSelecteds();
140 
141  if(dsPtrList.size() <= 0)
142  return;
143 
144  std::list<te::da::DataSourceInfoPtr>::iterator it = dsPtrList.begin();
145 
146  m_ui->m_repositoryLineEdit->setText(QString(it->get()->getTitle().c_str()));
147 
148  m_outputDatasource = *it;
149 
150  m_toFile = false;
151 }
152 
154 {
155  m_ui->m_newLayerNameLineEdit->clear();
156  m_ui->m_repositoryLineEdit->clear();
157 
158  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."),
159  QString(), tr("Shapefile (*.shp *.SHP);;"),0, QFileDialog::DontConfirmOverwrite);
160 
161  if (fileName.isEmpty())
162  return;
163 
164  boost::filesystem::path outfile(fileName.toStdString());
165  std::string aux = outfile.leaf().string();
166  m_ui->m_newLayerNameLineEdit->setText(aux.c_str());
167  aux = outfile.string();
168  m_ui->m_repositoryLineEdit->setText(aux.c_str());
169 
170  m_toFile = true;
171  m_ui->m_newLayerNameLineEdit->setEnabled(false);
172 }
173 
175 {
176  QMessageBox::information(this, "Help", "Under development");
177 }
178 
180 {
181  if(m_ui->m_layersComboBox->count() == 0)
182  {
183  QMessageBox::information(this, tr("Multipart To Singlepart"), tr("Select an input layer."));
184  return;
185  }
186 
187  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(m_selectedLayer.get());
188 
189  if(!dsLayer)
190  {
191  QMessageBox::information(this, tr("Multipart To Singlepart"), tr("Can not execute this operation on this type of layer."));
192  return;
193  }
194 
195  const te::da::ObjectIdSet* oidSet = 0;
196 
197  if(m_ui->m_onlySelectedCheckBox->isChecked())
198  {
199  oidSet = m_selectedLayer->getSelected();
200  if(!oidSet)
201  {
202  QMessageBox::information(this, tr("Multipart To Singlepart"), tr("None selected object!"));
203  return;
204  }
205  }
206 
207  te::da::DataSourcePtr inDataSource = te::da::GetDataSource(dsLayer->getDataSourceId(), true);
208  if (!inDataSource.get())
209  {
210  QMessageBox::information(this, tr("Multipart To Singlepart"), tr("The selected input data source can not be accessed."));
211  return;
212  }
213 
214  std::string outputdataset = m_ui->m_newLayerNameLineEdit->text().toStdString();
215 
216  if(m_ui->m_repositoryLineEdit->text().isEmpty())
217  {
218  QMessageBox::information(this, tr("Multipart To Singlepart"), tr("Define a repository for the result."));
219  return;
220  }
221 
222  if(m_ui->m_newLayerNameLineEdit->text().isEmpty())
223  {
224  QMessageBox::information(this, tr("Multipart To Singlepart"), "Define a name for the resulting layer.");
225  return;
226  }
227 
228  //progress
231 
232  try
233  {
234  bool res;
235 
236  if (m_toFile)
237  {
238  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toStdString());
239 
240  if (boost::filesystem::exists(uri))
241  {
242  QMessageBox::information(this, tr("Multipart To Singlepart"), "Output file already exists. Remove it or select a new name and try again.");
243  return;
244  }
245 
246  std::size_t idx = outputdataset.find(".");
247  if (idx != std::string::npos)
248  outputdataset=outputdataset.substr(0,idx);
249 
250  std::map<std::string, std::string> dsinfo;
251  dsinfo["URI"] = uri.string();
252 
254  dsOGR->setConnectionInfo(dsinfo);
255  dsOGR->open();
256  if (dsOGR->dataSetExists(outputdataset))
257  {
258  QMessageBox::information(this, tr("Multipart To Singlepart"), "There is already a dataset with the requested name in the output data source. Remove it or select a new name and try again.");
259  return;
260  }
261 
262  this->setCursor(Qt::WaitCursor);
263 
265 
266  m2s->setInput(inDataSource, dsLayer->getDataSetName(),dsLayer->getSchema(), oidSet);
267  m2s->setOutput(dsOGR, outputdataset);
268 
269  res = m2s->run();
270 
271  if (!res)
272  {
273  this->setCursor(Qt::ArrowCursor);
274  dsOGR->close();
275  QMessageBox::information(this, tr("Multipart To Singlepart"), tr("Error: could not operate."));
276  reject();
277  }
278  dsOGR->close();
279 
280  delete m2s;
281 
282  // let's include the new datasource in the managers
283  boost::uuids::basic_random_generator<boost::mt19937> gen;
284  boost::uuids::uuid u = gen();
285  std::string id_ds = boost::uuids::to_string(u);
286 
288  ds->setConnInfo(dsinfo);
289  ds->setTitle(uri.stem().string());
290  ds->setAccessDriver("OGR");
291  ds->setType("OGR");
292  ds->setDescription(uri.string());
293  ds->setId(id_ds);
294 
295  te::da::DataSourcePtr newds = te::da::DataSourceManager::getInstance().get(id_ds, "OGR", ds->getConnInfo());
296  newds->open();
298  m_outputDatasource = ds;
299  }
300  else
301  {
302  te::da::DataSourcePtr aux = te::da::GetDataSource(m_outputDatasource->getId());
303  if (!aux)
304  {
305  QMessageBox::information(this, tr("Multipart To Singlepart"), "The selected output datasource can not be accessed.");
306  return;
307  }
308 
309  if (aux->dataSetExists(outputdataset))
310  {
311  QMessageBox::information(this, tr("Multipart To Singlepart"), "Dataset already exists. Remove it or select a new name and try again.");
312  return;
313  }
314  this->setCursor(Qt::WaitCursor);
315 
317 
318  m2s->setInput(inDataSource, dsLayer->getDataSetName(), dsLayer->getSchema(), oidSet);
319  m2s->setOutput(aux, outputdataset);
320 
321  res = m2s->run();
322 
323  delete m2s;
324 
325  if (!res)
326  {
327  this->setCursor(Qt::ArrowCursor);
328  QMessageBox::information(this, tr("Multipart To Singlepart"), tr("Error: could not operate."));
329  reject();
330  }
331  }
332 
333  // creating a layer for the result
334  te::da::DataSourcePtr outDataSource = te::da::GetDataSource(m_outputDatasource->getId());
335 
336  te::qt::widgets::DataSet2Layer converter(m_outputDatasource->getId());
337 
338  te::da::DataSetTypePtr dt(outDataSource->getDataSetType(outputdataset).release());
339  m_layer = converter(dt);
340  }
341  catch(const std::exception& e)
342  {
343  this->setCursor(Qt::ArrowCursor);
344 
345  QMessageBox::information(this, tr("Multipart To Singlepart"), e.what());
346 
347 #ifdef TERRALIB_LOGGER_ENABLED
348  std::string str = "Multipart To Singlepart - ";
349  str += e.what();
350  te::common::Logger::logDebug("vp", str.c_str());
351 #endif
352 
354  return;
355  }
356 
358  this->setCursor(Qt::ArrowCursor);
359 
360  accept();
361 }
362 
364 {
365  reject();
366 }
367 
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
A Multipart to Singlepart operation dialog.
Utility functions for the data access module.
const std::string & getDataSetName() const
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
te::da::DataSourceInfoPtr m_outputDatasource
DataSource information.
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
std::auto_ptr< Ui::MultipartToSinglepartDialogForm > m_ui
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr)
void removeViewer(int viewerId)
Dettach a progress viewer.
static ProgressManager & getInstance()
It returns a reference to the singleton instance.
const std::string & getDataSourceId() const
void setOutput(te::da::DataSourcePtr outDsrc, std::string outDsName)
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:55
static std::auto_ptr< DataSource > make(const std::string &dsType)
te::map::AbstractLayerPtr getLayer()
Get the generated layer.
MultipartToSinglepartDialog(QWidget *parent=0, Qt::WindowFlags f=0)
int addViewer(AbstractProgressViewer *apv)
Attach a progress viewer.
const std::list< te::da::DataSourceInfoPtr > & getSelecteds() const
void setInput(te::da::DataSourcePtr inDsrc, std::string inDsName, std::auto_ptr< te::da::DataSetType > inDsType, const te::da::ObjectIdSet *oidSet=0)
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.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr