All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DirectExchangerDialog.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2011-2012 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/qt/widgets/exchanger/DirectExchangerDialog.h
22 
23  \brief A direct exchanger dialog for ADO, POSTGIS and SHP data sources
24 */
25 
26 // TerraLib
27 #include "../../../dataaccess/dataset/DataSetAdapter.h"
28 #include "../../../dataaccess/dataset/PrimaryKey.h"
29 #include "../../../dataaccess/dataset/DataSetTypeConverter.h"
30 #include "../../../dataaccess/datasource/DataSourceFactory.h"
31 #include "../../../dataaccess/datasource/DataSourceInfo.h"
32 #include "../../../dataaccess/datasource/DataSourceInfoManager.h"
33 #include "../../../dataaccess/datasource/DataSourceManager.h"
34 #include "../../../dataaccess/utils/Utils.h"
35 #include "../../../geometry/GeometryProperty.h"
36 #include "../../../maptools/DataSetLayer.h"
37 #include "../../widgets/datasource/selector/DataSourceExplorerDialog.h"
38 #include "../../widgets/srs/SRSManagerDialog.h"
39 #include "DirectExchangerDialog.h"
40 #include "ui_DirectExchangerDialogForm.h"
41 
42 // Qt
43 #include <QFileDialog>
44 #include <QMessageBox>
45 
46 // Boost
47 #include <boost/algorithm/string/replace.hpp>
48 #include <boost/filesystem.hpp>
49 #include <boost/lexical_cast.hpp>
50 #include <boost/uuid/random_generator.hpp>
51 #include <boost/uuid/uuid_io.hpp>
52 
53 
56 
58  : QDialog(parent, f),
59  m_ui(new Ui::DirectExchangerDialogForm)
60 {
61 // setup widget
62  m_ui->setupUi(this);
63 
64 // add icons
65  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("data-exchange-direct-hint").pixmap(112,48));
66  m_ui->m_dsToolButton->setIcon(QIcon::fromTheme("datasource"));
67 
68 //connectors
69  connect(m_ui->m_okPushButton, SIGNAL(clicked()), this, SLOT(onOkPushButtonClicked()));
70  connect(m_ui->m_dirToolButton, SIGNAL(clicked()), this, SLOT(onDirToolButtonClicked()));
71  connect(m_ui->m_dsToolButton, SIGNAL(clicked()), this, SLOT(onDataSoruceToolButtonClicked()));
72  connect(m_ui->m_dsTypeComboBox, SIGNAL(activated(int)), this, SLOT(onDataSourceTypeActivated(int)));
73  connect(m_ui->m_inputLayerComboBox, SIGNAL(activated(QString)), this, SLOT(onInputLayerActivated(QString)));
74 
75  m_ui->m_helpPushButton->setPageReference("widgets/exchanger_direct/exchanger_direct.html");
76 
77  //starup interface
79  m_exchangeToFile = false;
80  m_lastDsType = "";
81 
83 }
84 
86 {
87 }
88 
89 void te::qt::widgets::DirectExchangerDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
90 {
91  m_layers = layers;
92 
93  m_ui->m_inputLayerComboBox->clear();
94 
95  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
96 
97  while(it != m_layers.end())
98  {
100 
101  std::auto_ptr<te::da::DataSetType> dsType = l->getSchema();
102 
103  if(dsType.get() && !dsType->hasRaster())
104  m_ui->m_inputLayerComboBox->addItem(l->getTitle().c_str(), QVariant::fromValue(l));
105 
106  ++it;
107  }
108 
109  if(m_ui->m_inputLayerComboBox->count() > 0)
110  {
111  QString s = m_ui->m_inputLayerComboBox->currentText();
112 
113  onInputLayerActivated(s);
114  }
115 
116  if(m_ui->m_inputLayerComboBox->count() > 1)
117  m_ui->m_inputLayerComboBox->setEnabled(true);
118 }
119 
121 {
122  m_lastDsType = dataSource;
123 }
124 
126 {
127  m_ui->m_outputDataSourceComboBox->clear();
128 
129  std::vector<te::da::DataSourceInfoPtr> datasources;
130 
131  te::da::DataSourceInfoManager::getInstance().getByType(m_outputDataSourceType, datasources);
132 
133  for(std::size_t i = 0; i < datasources.size(); ++i)
134  {
135  const te::da::DataSourceInfoPtr& datasource = datasources[i];
136 
137  if(datasource.get() == 0)
138  continue;
139 
140  const std::string& title = datasource->getTitle();
141 
142  m_ui->m_outputDataSourceComboBox->addItem(title.c_str(), QVariant::fromValue(datasource));
143  }
144 }
145 
147 {
148  int idxLayer = m_ui->m_inputLayerComboBox->currentIndex();
149 
150  if(idxLayer == -1)
151  {
152  QMessageBox::warning(this, tr("Warning"), tr("Input layer not selected."));
153  return false;
154  }
155 
156  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(idxLayer, Qt::UserRole);
157  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
158 
159  if(!layer.get())
160  {
161  QMessageBox::warning(this, tr("Warning"), tr("Error getting selected layer."));
162  return false;
163  }
164 
165  if(m_ui->m_dataSetLineEdit->text().isEmpty())
166  {
167  QMessageBox::warning(this, tr("Warning"), tr("Output File Name not defined."));
168  return false;
169  }
170 
171  try
172  {
173  //create adapter
174  std::auto_ptr<te::da::DataSetType> dsType = layer->getSchema();
175 
176  //create data source
177  std::map<std::string, std::string> connInfo;
178  connInfo["URI"] = m_ui->m_dataSetLineEdit->text().toStdString();
179 
180  std::auto_ptr<te::da::DataSource> dsOGR = te::da::DataSourceFactory::make(m_outputDataSourceType);
181  dsOGR->setConnectionInfo(connInfo);
182  dsOGR->open();
183 
184  te::da::DataSetTypeConverter* converter = new te::da::DataSetTypeConverter(dsType.get(), dsOGR->getCapabilities());
185 
186  te::da::DataSetType* dsTypeResult = converter->getResult();
187 
189 
190  //check srid
191  if(p && (p->getSRID() != layer->getSRID()))
192  {
193  p->setSRID(layer->getSRID());
194  }
195 
196  boost::filesystem::path uri(m_ui->m_dataSetLineEdit->text().toStdString());
197 
198  std::string val = uri.stem().string();
199 
200  dsTypeResult->setName(val);
201 
202  //exchange
203  std::map<std::string,std::string> nopt;
204 
205  std::auto_ptr<te::da::DataSet> dataset = layer->getData();
206 
207  dsOGR->createDataSet(dsTypeResult, nopt);
208 
209  std::auto_ptr<te::da::DataSetAdapter> dsAdapter(te::da::CreateAdapter(dataset.get(), converter));
210 
211  dsAdapter->setSRID(layer->getSRID());
212 
213  if(dataset->moveBeforeFirst())
214  dsOGR->add(dsTypeResult->getName(), dsAdapter.get(), dsOGR->getConnectionInfo());
215 
216  dsOGR->close();
217 
218  QMessageBox::information(this, tr("Exchanger"), tr("Layer exported successfully."));
219  }
220  catch(const std::exception& e)
221  {
222  QString errMsg(tr("Error during exchanger. The reported error is: %1"));
223 
224  errMsg = errMsg.arg(e.what());
225 
226  QMessageBox::information(this, tr("Exchanger"), errMsg);
227 
228  return false;
229  }
230 
231  return true;
232 }
233 
235 {
236  int idxLayer = m_ui->m_inputLayerComboBox->currentIndex();
237 
238  if(idxLayer == -1)
239  {
240  QMessageBox::warning(this, tr("Warning"), tr("Input layer not selected."));
241  return false;
242  }
243 
244  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(idxLayer, Qt::UserRole);
245  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
246 
247  if(!layer.get())
248  {
249  QMessageBox::warning(this, tr("Warning"), tr("Error getting selected layer."));
250  return false;
251  }
252 
253  int idxDataSource = m_ui->m_outputDataSourceComboBox->currentIndex();
254 
255  if(idxLayer == -1)
256  {
257  QMessageBox::warning(this, tr("Warning"), tr("Output data source not selected."));
258  return false;
259  }
260 
261  QVariant varDataSource = m_ui->m_outputDataSourceComboBox->itemData(idxDataSource, Qt::UserRole);
262  te::da::DataSourceInfoPtr dsInfo = varDataSource.value<te::da::DataSourceInfoPtr>();
263 
264  if(!dsInfo.get())
265  {
266  QMessageBox::warning(this, tr("Warning"), tr("Error getting selected data source."));
267  return false;
268  }
269 
270  if(m_ui->m_dataSetLineEdit->text().isEmpty())
271  {
272  QMessageBox::warning(this, tr("Warning"), tr("Data Set name not defined."));
273  return false;
274  }
275 
276  try
277  {
278  //create adapter
279  std::auto_ptr<te::da::DataSetType> dsType = layer->getSchema();
280 
281  te::da::DataSourcePtr targetDSPtr = te::da::DataSourceManager::getInstance().get(dsInfo->getId(), dsInfo->getType(), dsInfo->getConnInfo());
282 
283  te::da::DataSetTypeConverter* converter = new te::da::DataSetTypeConverter(dsType.get(), targetDSPtr->getCapabilities());
284 
285  te::da::DataSetType* dsTypeResult = converter->getResult();
286 
287  dsTypeResult->setName(m_ui->m_dataSetLineEdit->text().toStdString());
288 
289  //create index
290  if(m_ui->m_spatialIndexCheckBox->isChecked())
291  {
293 
294  //check srid
295  if(p && (p->getSRID() != layer->getSRID()))
296  {
297  p->setSRID(layer->getSRID());
298  }
299 
300  if(p)
301  {
302  te::da::Index* idx = new te::da::Index(dsTypeResult);
303 
304  std::string name = m_ui->m_dataSetLineEdit->text().toStdString() + "_" + p->getName() + "_idx";
305 
306  boost::replace_all(name, ".", "_");
307 
308  idx->setName(name);
310 
311  te::dt::Property* pClone = p->clone();
312 
313  idx->add(pClone);
314  }
315  }
316 
317  //create primary key
318  if(dsType->getPrimaryKey())
319  {
320  te::da::PrimaryKey* pk = new te::da::PrimaryKey(dsTypeResult);
321 
322  std::string name = m_ui->m_dataSetLineEdit->text().toStdString() + "_" + dsType->getPrimaryKey()->getName() + "_pk";
323 
324  boost::replace_all(name, ".", "_");
325 
326  pk->setName(name);
327 
328  std::vector<te::dt::Property*> props = dsType->getPrimaryKey()->getProperties();
329 
330  for(size_t t = 0; t < props.size(); ++ t)
331  {
332  te::dt::Property* p = props[t]->clone();
333 
334  pk->add(p);
335  }
336  }
337 
338  //exchange
339  std::map<std::string,std::string> nopt;
340 
341  std::auto_ptr<te::da::DataSet> dataset = layer->getData();
342 
343  targetDSPtr->createDataSet(dsTypeResult, nopt);
344 
345  std::auto_ptr<te::da::DataSetAdapter> dsAdapter(te::da::CreateAdapter(dataset.get(), converter));
346 
347  dsAdapter->setSRID(layer->getSRID());
348 
349  if(dataset->moveBeforeFirst())
350  targetDSPtr->add(dsTypeResult->getName(), dsAdapter.get(), targetDSPtr->getConnectionInfo());
351 
352  QMessageBox::information(this, tr("Exchanger"), tr("Layer exported successfully."));
353  }
354  catch(const std::exception& e)
355  {
356  QString errMsg(tr("Error during exchanger. The reported error is: %1"));
357 
358  errMsg = errMsg.arg(e.what());
359 
360  QMessageBox::information(this, tr("Exchanger"), errMsg);
361 
362  return false;
363  }
364 
365  return true;
366 }
367 
369 {
370  QString value = m_ui->m_dsTypeComboBox->itemData(index).toString();
371 
372  m_outputDataSourceType = value.toStdString();
373 
374  if(m_outputDataSourceType == "POSTGIS")
375  {
376  m_exchangeToFile = false;
377 
378  m_ui->m_outputDataSourceComboBox->setEnabled(true);
379  m_ui->m_dsToolButton->setEnabled(true);
380  m_ui->m_dataSetLineEdit->clear();
381  m_ui->m_dataSetLineEdit->setEnabled(true);
382  m_ui->m_dirToolButton->setEnabled(false);
383  m_ui->m_spatialIndexCheckBox->setEnabled(true);
384  m_ui->m_spatialIndexCheckBox->setChecked(true);
385 
386  setDataSources();
387  }
388  else if(m_outputDataSourceType == "ADO")
389  {
390  m_exchangeToFile = false;
391 
392  m_ui->m_outputDataSourceComboBox->setEnabled(true);
393  m_ui->m_dsToolButton->setEnabled(true);
394  m_ui->m_dataSetLineEdit->clear();
395  m_ui->m_dataSetLineEdit->setEnabled(true);
396  m_ui->m_dirToolButton->setEnabled(false);
397  m_ui->m_spatialIndexCheckBox->setEnabled(false);
398  m_ui->m_spatialIndexCheckBox->setChecked(false);
399 
400  setDataSources();
401  }
402  else if(m_outputDataSourceType == "OGR")
403  {
404  m_exchangeToFile = true;
405 
406  m_ui->m_outputDataSourceComboBox->clear();
407  m_ui->m_outputDataSourceComboBox->setEnabled(false);
408  m_ui->m_dsToolButton->setEnabled(false);
409  m_ui->m_dataSetLineEdit->clear();
410  m_ui->m_dataSetLineEdit->setEnabled(false);
411  m_ui->m_dirToolButton->setEnabled(true);
412  m_ui->m_spatialIndexCheckBox->setEnabled(false);
413  m_ui->m_spatialIndexCheckBox->setChecked(false);
414  }
415 }
416 
418 {
419  onDataSourceTypeActivated(m_ui->m_dsTypeComboBox->currentIndex());
420 
421  if(m_ui->m_dataSetLineEdit->isEnabled())
422  m_ui->m_dataSetLineEdit->setText(value);
423 }
424 
426 {
427  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."),
428  QString(), tr("Shapefile (*.shp *.SHP);;Mapinfo File (*.mif *.MIF);;KML (*.kml *.KML);;GeoJSON (*.geojson *.GEOJSON);;GML (*.gml *.GML);;DXF (*.dxf *.DXF);;DGN (*.dgn *.DGN);;"),0, QFileDialog::DontConfirmOverwrite);
429 
430  if (fileName.isEmpty())
431  return;
432 
433  m_ui->m_dataSetLineEdit->setText(fileName);
434 }
435 
437 {
438  std::auto_ptr<te::qt::widgets::DataSourceExplorerDialog> dExplorer(new te::qt::widgets::DataSourceExplorerDialog(this));
439 
440  if(!m_lastDsType.empty())
441  dExplorer->setDataSourceToUse(m_lastDsType.c_str());
442 
443  dExplorer->exec();
444 
445  setDataSources();
446 }
447 
449 {
450  bool res = false;
451 
452  if(m_exchangeToFile)
453  res = exchangeToFile();
454  else
455  res = exchangeToDatabase();
456 
457  if(res)
458  accept();
459 }
460 
462 {
463  m_ui->m_dsTypeComboBox->clear();
464 
465  m_ui->m_dsTypeComboBox->addItem(QIcon::fromTheme("datasource-postgis"), tr("PostGIS"), QVariant("POSTGIS"));
466  m_ui->m_dsTypeComboBox->addItem(QIcon::fromTheme("datasource-ado"), tr("Microsoft Access"), QVariant("ADO"));
467  m_ui->m_dsTypeComboBox->addItem(QIcon::fromTheme("datasource-ogr"), tr("File - OGR Formats"), QVariant("OGR"));
468 }
virtual void setName(const std::string &name)
It sets the constraint name.
Definition: Constraint.h:126
void setDataSources()
Set the list of data sources that can be used.
Geometric property.
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
A dialog for selecting a data source.
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
A class that models the description of a dataset.
Definition: DataSetType.h:72
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr)
virtual Property * clone() const =0
It returns a clone of the object.
void setIndexType(IndexType t)
It sets the index type.
Definition: Index.h:176
void add(te::dt::Property *p)
It adds the property to the list of properties of the index.
Definition: Index.h:197
te::dt::Property * clone() const
It returns a clone of the object.
It models a property definition.
Definition: Property.h:59
DirectExchangerDialog(QWidget *parent=0, Qt::WindowFlags f=0)
An converter for DataSetType.
void setName(const std::string &name)
It sets the property name.
Definition: Property.h:136
int getSRID() const
It returns the spatial reference system identifier associated to this property.
static DataSourceInfoManager & getInstance()
It returns a reference to the singleton instance.
static std::auto_ptr< DataSource > make(const std::string &dsType)
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
std::auto_ptr< Ui::DirectExchangerDialogForm > m_ui
A direct exchanger dialog for ADO, POSTGIS and SHP data sources.
void setLastDataSource(std::string dataSource)
Function used to set the last data source used.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
void setName(const std::string &name)
It sets the index name.
Definition: Index.h:162
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:508
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
Definition: Utils.cpp:595
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
It describes an index associated to a DataSetType.
Definition: Index.h:54
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
const std::string & getName() const
It returns the property name.
Definition: Property.h:126