CreateLayerWidget.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/qt/widgets/layer/utils/CreateLayerWidget.cpp
22 
23 \brief This interface is used to create new layer operation.
24 */
25 
26 // TerraLib
27 #include "../../../../common/STLUtils.h"
28 #include "../../../../dataaccess/datasource/DataSourceFactory.h"
29 #include "../../../../dataaccess/datasource/DataSourceInfoManager.h"
30 #include "../../../../dataaccess/datasource/DataSourceManager.h"
31 #include "../../../../dataaccess/utils/Utils.h"
32 #include "../../../../datatype/Utils.h"
33 #include "../../../../qt/widgets/datasource/selector/DataSourceSelectorDialog.h"
34 #include "../../../../qt/widgets/property/NewPropertyWidget.h"
35 #include "../../../../se/Style.h"
36 #include "../../layer/utils/DataSet2Layer.h"
37 #include "CreateLayerWidget.h"
38 #include "ui_CreateLayerWidgetForm.h"
39 
40 // Qt
41 #include <QFileDialog>
42 #include <QMessageBox>
43 
44 // Boost
45 #include <boost/filesystem.hpp>
46 #include <boost/uuid/random_generator.hpp>
47 #include <boost/uuid/uuid_io.hpp>
48 
50 
51 te::qt::widgets::CreateLayerWidget::CreateLayerWidget(QWidget* parent, Qt::WindowFlags f)
52  : QWidget(parent, f),
53  m_ui(new Ui::CreateLayerWidgetForm)
54 {
55  // add controls
56  m_ui->setupUi(this);
57  m_ui->m_targetDatasourceToolButton->setIcon(QIcon::fromTheme("datasource"));
58  m_ui->m_addToolButton->setIcon(QIcon::fromTheme("list-add"));
59  m_ui->m_clearToolButton->setIcon(QIcon::fromTheme("edit-clear"));
60 
61  //add new property widget
62  QGridLayout* layout = new QGridLayout(m_ui->m_widget);
63  layout->setContentsMargins(0, 0, 0, 0);
64 
65  m_newPropWidget = new te::qt::widgets::NewPropertyWidget(m_ui->m_widget);
66 
67  layout->addWidget(m_newPropWidget);
68 
69  //mapper initializer
70  m_removeMapper = new QSignalMapper(this);
71 
72  //connects
73  connect(m_ui->m_addToolButton, SIGNAL(pressed()), this, SLOT(onAddPushButtonClicked()));
74  connect(m_ui->m_targetDatasourceToolButton, SIGNAL(pressed()), this, SLOT(onTargetDatasourceToolButtonPressed()));
75  connect(m_ui->m_targetFileToolButton, SIGNAL(pressed()), this, SLOT(onTargetFileToolButtonPressed()));
76  connect(m_ui->m_refLayerComboBox, SIGNAL(activated(int)), this, SLOT(onRefLayerComboBoxActivated(int)));
77 
78  connect(m_ui->m_clearToolButton, SIGNAL(clicked()), this, SLOT(onClearToolButtonTriggered()));
79 
80  connect(m_removeMapper, SIGNAL(mapped(int)), this, SLOT(onRemoveAttrExecuted(int)));
81 }
82 
84 {
85  clear();
86 }
87 
89 {
90  m_outputDatasource = dsInfo;
91 
93 
94  m_ui->m_repositoryLineEdit->setText(m_outputDatasource->getTitle().c_str());
95 
96  m_toFile = false;
97 
98  m_ui->m_targetFileToolButton->setEnabled(false);
99  m_ui->m_targetDatasourceToolButton->setEnabled(false);
100 
101  m_ui->m_newLayerNameLineEdit->clear();
102  m_ui->m_newLayerNameLineEdit->setEnabled(true);
103 }
104 
105 void te::qt::widgets::CreateLayerWidget::setReferenceLayers(std::list<te::map::AbstractLayerPtr> refLayers)
106 {
107  m_ui->m_refLayerComboBox->clear();
108  m_ui->m_refLayerComboBox->addItem("");
109 
110  for (auto i : refLayers)
111  {
112  m_ui->m_refLayerComboBox->addItem(QString::fromUtf8(i->getTitle().c_str()), QVariant::fromValue(i));
113  }
114 }
115 
117 {
118  if (index == 0)
119  return;
120 
121  QVariant v = m_ui->m_refLayerComboBox->currentData(Qt::UserRole);
123 
124  std::unique_ptr<te::da::DataSetType> schema = refLayer->getSchema();
125 
126  std::vector<te::dt::Property*> props = schema->getProperties();
127 
128 
129  for (auto i : props)
130  {
131  m_props.push_back(i->clone());
132  }
133 
134  listProperties();
135 }
136 
138 {
139  clear();
140  listProperties();
141 }
142 
143 bool te::qt::widgets::CreateLayerWidget::createLayer(std::string& errorMessage)
144 {
145  if (!m_outputDatasource.get())
146  {
147  errorMessage = "Define the data source first.";
148  return false;
149  }
150 
151  if (m_props.empty())
152  {
153  errorMessage = "Define the properties first.";
154  return false;
155  }
156 
157  if (m_ui->m_newLayerNameLineEdit->text().isEmpty())
158  {
159  errorMessage = "Layer name not defined.";
160  return false;
161  }
162 
163  std::string dsTypeName = m_ui->m_newLayerNameLineEdit->text().toUtf8().data();
164 
165  std::unique_ptr<te::da::DataSetType> dsType(new te::da::DataSetType(dsTypeName));
166 
167  for (std::size_t t = 0; t < m_props.size(); ++t)
168  {
169  dsType->add(m_props[t]->clone());
170  }
171 
172  //create
173  std::map<std::string, std::string> nopt;
174 
175  if (m_toFile)
176  {
177  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toUtf8().data());
178 
179  const std::string connInfo("file://" + uri.string());
180  te::da::DataSourcePtr dsOGR(te::da::DataSourceFactory::make("OGR", connInfo).release());
181  dsOGR->open();
182 
183  try
184  {
185  dsOGR->createDataSet(dsType.get(), nopt);
186  }
187  catch (const std::exception& ex)
188  {
189  errorMessage = ex.what();
190  return false;
191  }
192  catch (...)
193  {
194  errorMessage = "Error creating layer.";
195  return false;
196  }
197  }
198  else
199  {
201 
202  try
203  {
204  outputDataSource->createDataSet(dsType.get(), nopt);
205  }
206  catch (const std::exception& ex)
207  {
208  errorMessage = ex.what();
209  return false;
210  }
211  catch (...)
212  {
213  errorMessage = "Error creating layer.";
214  return false;
215  }
216  }
217 
218  return true;
219 }
220 
222 {
223  //std::string driverName = m_outputDatasource->getType();
224  //std::map<std::string, std::string> connInfo = m_outputDatasource->getConnInfo();
225  std::string dataSetName = m_ui->m_newLayerNameLineEdit->text().toUtf8().data();
226 
227  std::size_t idx = dataSetName.find(".");
228  if (idx != std::string::npos)
229  dataSetName = dataSetName.substr(0, idx);
230 
232 
233  //static boost::uuids::basic_random_generator<boost::mt19937> gen;
234 
235  //boost::uuids::uuid valU = gen();
236  //std::string id = boost::uuids::to_string(valU);
237 
238  //std::unique_ptr<te::da::DataSource> ds(te::da::DataSourceFactory::make(driverName));
239  //ds->setConnectionInfo(connInfo);
240  //ds->open();
241 
242  ////add ds info
243  //te::da::DataSourceInfoPtr dsInfoPtr(new te::da::DataSourceInfo);
244  //dsInfoPtr->setConnInfo(connInfo);
245  //dsInfoPtr->setId(id);
246  //dsInfoPtr->setTitle(dataSetName);
247  //dsInfoPtr->setAccessDriver(driverName);
248  //dsInfoPtr->setType(driverName);
249 
250  //te::da::DataSourceInfoManager::getInstance().add(dsInfoPtr);
251 
252  //add ds
254  //dsPtr->setId(id);
255 
256  //te::da::DataSourceManager::getInstance().insert(dsPtr);
257 
258  //create layer
259  te::da::DataSetTypePtr dsType(dsPtr->getDataSetType(dataSetName).release());
260 
261  te::qt::widgets::DataSet2Layer ds2l(dsPtr->getId());
262 
263  layer = ds2l(dsType);
264 
265  QVariant v = m_ui->m_refLayerComboBox->currentData(Qt::UserRole);
267 
268  if (refLayer)
269  {
270  layer->setStyle(refLayer->getStyle()->clone());
271  layer->setSRID(refLayer->getSRID());
272  layer->setEncoding(refLayer->getEncoding());
273  }
274 
275  return layer;
276 }
277 
279 {
281  m_props.clear();
282 
283  listProperties();
284 }
285 
287 {
289  {
290  //get property
292 
293  m_props.push_back(sp);
294 
295  if (m_outputDatasource.get())
297 
298  listProperties();
299  }
300 }
301 
303 {
304  m_ui->m_newLayerNameLineEdit->clear();
305  m_ui->m_newLayerNameLineEdit->setEnabled(true);
306 
308  dlg.exec();
309 
310  std::list<te::da::DataSourceInfoPtr> dsPtrList = dlg.getSelecteds();
311 
312  if (dsPtrList.size() <= 0)
313  return;
314 
315  std::list<te::da::DataSourceInfoPtr>::iterator it = dsPtrList.begin();
316 
317  m_ui->m_repositoryLineEdit->setText(QString(it->get()->getTitle().c_str()));
318 
319  m_outputDatasource = *it;
320 
322 
323  outputDataSource->open();
324 
326 
327  m_toFile = false;
328 }
329 
331 {
332  m_ui->m_newLayerNameLineEdit->clear();
333  m_ui->m_repositoryLineEdit->clear();
334 
335  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."), QString(), tr("Shapefile (*.shp *.SHP);;"), nullptr, QFileDialog::DontConfirmOverwrite);
336 
337  if (fileName.isEmpty())
338  return;
339 
340  boost::filesystem::path outfile(fileName.toUtf8().data());
341 
342  m_ui->m_repositoryLineEdit->setText(outfile.string().c_str());
343 
344  m_ui->m_newLayerNameLineEdit->setText(outfile.leaf().string().c_str());
345 
346  m_ui->m_newLayerNameLineEdit->setEnabled(false);
347 
348  m_toFile = true;
349 
350  //create new data source
351  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toUtf8().data());
352 
353  const std::string connInfo("file://" + uri.string());
354  std::unique_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("OGR", connInfo);
355  ds->open();
356 
357  boost::uuids::basic_random_generator<boost::mt19937> gen;
358  boost::uuids::uuid u = gen();
359  std::string id_ds = boost::uuids::to_string(u);
360 
362  dsInfoPtr->setConnInfo(connInfo);
363  dsInfoPtr->setTitle(uri.stem().string());
364  dsInfoPtr->setAccessDriver("OGR");
365  dsInfoPtr->setType("OGR");
366  dsInfoPtr->setDescription(uri.string());
367  dsInfoPtr->setId(id_ds);
368 
370 
371  m_outputDatasource = dsInfoPtr;
372 
374 
375  outputDataSource->open();
376 
378 }
379 
381 {
382  m_props.erase(m_props.begin() + row);
383 
384  listProperties();
385 }
386 
388 {
389  disconnect(m_ui->m_tableWidget, SIGNAL(cellChanged(int, int)), this, SLOT(onTableWidgetCellChanged(int, int)));
390 
391  m_ui->m_tableWidget->setRowCount(0);
392 
393  for (std::size_t t = 0; t < m_props.size(); ++t)
394  {
395  te::dt::Property* p = m_props[t];
396 
397  //set property info into table widget
398  int newrow = m_ui->m_tableWidget->rowCount();
399  m_ui->m_tableWidget->insertRow(newrow);
400 
401  //name
402  QTableWidgetItem* itemName = new QTableWidgetItem(p->getName().c_str());
403  m_ui->m_tableWidget->setItem(newrow, 2, itemName);
404 
405  //type
406  std::string propType = te::dt::ConvertDataTypeToString(p->getType());
407  QTableWidgetItem* itemType = new QTableWidgetItem(propType.c_str());
408  itemType->setFlags(itemType->flags() ^ Qt::ItemIsEditable);
409  m_ui->m_tableWidget->setItem(newrow, 1, itemType);
410 
411  //remove button
412  QToolButton* removeToolButton = new QToolButton(m_ui->m_tableWidget);
413  removeToolButton->setIcon(QIcon::fromTheme("list-remove"));
414  m_ui->m_tableWidget->setCellWidget(newrow, 0, removeToolButton);
415 
416  m_removeMapper->setMapping(removeToolButton, newrow);
417  connect(removeToolButton, SIGNAL(pressed()), m_removeMapper, SLOT(map()));
418  }
419 
420  m_ui->m_tableWidget->resizeColumnsToContents();
421  #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
422  m_ui->m_tableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
423  #endif
424 
425  connect(m_ui->m_tableWidget, SIGNAL(cellChanged(int, int)), this, SLOT(onTableWidgetCellChanged(int, int)));
426 }
427 
429 {
430  if (column != 2)
431  return;
432 
433  QTableWidgetItem* item = m_ui->m_tableWidget->item(row, column);
434  QString newName = item->text();
435 
436  m_props[row]->setName(newName.toUtf8().data());
437 }
438 
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
TEDATATYPEEXPORT std::string ConvertDataTypeToString(const int &dataType)
Function used to convert from a int (Data Type Enum) to a string.
std::unique_ptr< Ui::CreateLayerWidgetForm > m_ui
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
void setDataSource(te::da::DataSourceInfoPtr dsInfo)
This interface is used to create new layer operation.
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
An atomic property like an integer or double.
QSignalMapper * m_removeMapper
The mapper used to know which action was executed.
te::dt::SimpleProperty * getProperty()
It returns a simple property class object.
boost::shared_ptr< DataSource > DataSourcePtr
A class that models the description of a dataset.
Definition: DataSetType.h:72
te::map::AbstractLayerPtr getLayer()
bool createLayer(std::string &errorMessage)
static te::dt::Date ds(2010, 01, 01)
It models a property definition.
Definition: Property.h:59
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr) te
void setReferenceLayers(std::list< te::map::AbstractLayerPtr > refLayers)
te::da::DataSourceInfoPtr m_outputDatasource
static DataSourceManager & getInstance()
It returns a reference to the singleton instance.
URI C++ Library.
Definition: Attributes.h:37
void onTableWidgetCellChanged(int row, int column)
te::gm::Polygon * p
te::qt::widgets::NewPropertyWidget * m_newPropWidget
int getType() const
It returns the property data type.
Definition: Property.h:161
void setDataSourceId(std::string id)
Used to get all data types supported by this data source.
const std::list< te::da::DataSourceInfoPtr > & getSelecteds() const
std::vector< te::dt::Property * > m_props
A dialog for selecting a data source.
A class that represents a data source component.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
const std::string & getName() const
It returns the property name.
Definition: Property.h:127