SaveSelectedObjectsWidget.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/SaveSelectedObjectsWidget.cpp
22 
23 \brief This interface is used to create a new layer based on a layer with selected objects.
24 */
25 
26 // TerraLib
27 
28 #include "../../../../common/STLUtils.h"
29 #include "../../../../dataaccess/datasource/DataSourceFactory.h"
30 #include "../../../../dataaccess/datasource/DataSourceInfoManager.h"
31 #include "../../../../dataaccess/datasource/DataSourceManager.h"
32 #include "../../../../dataaccess/datasource/DataSourceTransactor.h"
33 #include "../../../../dataaccess/dataset/ObjectIdSet.h"
34 #include "../../../../dataaccess/utils/Utils.h"
35 #include "../../../../datatype/Utils.h"
36 #include "../../../../qt/widgets/datasource/selector/DataSourceSelectorDialog.h"
37 #include "../../../../qt/widgets/property/NewPropertyWidget.h"
38 #include "../../layer/utils/DataSet2Layer.h"
40 #include "ui_SaveSelectedObjectsWidgetForm.h"
41 
42 // Qt
43 #include <QFileDialog>
44 #include <QMessageBox>
45 
46 // Boost
47 #include <boost/filesystem.hpp>
48 #include <boost/lexical_cast.hpp>
49 #include <boost/uuid/random_generator.hpp>
50 #include <boost/uuid/uuid_io.hpp>
51 
52 
54  : QWidget(parent, f),
55  m_ui(new Ui::SaveSelectedObjectsWidgetForm)
56 {
57  // add controls
58  m_ui->setupUi(this);
59  m_ui->m_targetDatasourceToolButton->setIcon(QIcon::fromTheme("datasource"));
60 
61  //connects
62  connect(m_ui->m_targetDatasourceToolButton, SIGNAL(pressed()), this, SLOT(onTargetDatasourceToolButtonPressed()));
63  connect(m_ui->m_targetFileToolButton, SIGNAL(pressed()), this, SLOT(onTargetFileToolButtonPressed()));
64 
65 
66 }
67 
69  default;
70 
71 /*! \brief Set parameters execute the operation. */
73 {
74  //Set layer.
75  m_layer = layer;
76 
77  //Verify if Layer is valid.
78  if (!m_layer)
79  {
80  QString msg = tr("Invalid layer selected!");
81  QMessageBox::warning(this, "Save layer as:", msg);
82  return;
83  }
84 
85  //Set the layer SRID.
86  m_srid = m_layer->getSRID();
87 
88  //Set the selected objects.
89  m_oidSet = m_layer->getSelected()->clone();
91 }
92 
93 /*! \brief Update the components window with current values. */
95 {
96  // Set to QLineEdit the layer name.
97  m_ui->m_layerNameLineEdit->setText(QString(m_layer->getDataSetName().c_str()));
98 
99  //Set to Label the SRID
100  m_ui->m_layerSRIDLabel->setText(QString(boost::lexical_cast<std::string>(m_srid).c_str()));
101 
102  //Set to Label the number of selected objects.
103  std::size_t num = 0;
104 
105  if (m_oidSet)
106  num = m_oidSet->size();
107 
108  m_ui->m_NumSelectedObjLabel->setText(QString(boost::lexical_cast<std::string>(num).c_str()));
109 }
110 
112 {
113 
114  std::unique_ptr<te::da::DataSourceTransactor> t = dataSource->getTransactor();
115 
116  std::map<std::string, std::string> options;
117 
118  try
119  {
120  if (dataSource->getType() == "OGR")
121  {
122  // create the dataset
123  dataSource->createDataSet(dataSetType, options);
124 
125  // copy from memory to output datasource
126  dataSet->moveBeforeFirst();
127  std::string name = dataSetType->getName();
128  dataSource->add(dataSetType->getName(), dataSet, options);
129  }
130  else
131  {
132  t->begin();
133 
134  // create the dataset
135  t->createDataSet(dataSetType, options);
136 
137  // copy from memory to output datasource
138  dataSet->moveBeforeFirst();
139  std::string name = dataSetType->getName();
140  t->add(dataSetType->getName(), dataSet, options);
141 
142  t->commit();
143  }
144 
145  }
146  catch (te::common::Exception& e)
147  {
148  t->rollBack();
149  throw e;
150  }
151  catch (std::exception& e)
152  {
153  t->rollBack();
154  throw e;
155  }
156 }
157 
159 {
160  return m_layerResult;
161 }
162 
164 {
165  if (!m_oidSet)
166  {
167  errorMessage = "Select at least one object from selected layer.";
168  return false;
169  }
170 
171  if (!m_outputDatasource.get())
172  {
173  errorMessage = "Define the data source first.";
174  return false;
175  }
176 
177  if (m_ui->m_newLayerNameLineEdit->text().isEmpty())
178  {
179  errorMessage = "Layer name not defined.";
180  return false;
181  }
182 
183  te::da::DataSourcePtr inDataSource = te::da::GetDataSource(m_layer->getDataSourceId(), true);
184  if (!inDataSource.get())
185  {
186  errorMessage = "The selected input data source can not be accessed.";
187  return false;
188  }
189 
190  std::string dsTypeName = m_ui->m_newLayerNameLineEdit->text().toUtf8().data();
191 
192  std::unique_ptr<te::da::DataSetType> dsType(new te::da::DataSetType(dsTypeName));
193 
194  std::unique_ptr<te::da::DataSet> dataSet = inDataSource->getDataSet(m_layer->getTitle(), m_oidSet);
195 
196  std::map<std::string, std::string> nopt;
197 
198  std::unique_ptr<te::map::LayerSchema> schema = m_layer->getSchema();
199 
200  std::vector<te::dt::Property*> propsVec = schema->getProperties();
201 
202  for (std::size_t i = 0; i < propsVec.size(); ++i)
203  dsType->add(propsVec[i]->clone());
204 
205  if (!m_toFile)
206  {
207  te::da::PrimaryKey* pk = schema->getPrimaryKey();
208 
209  if (pk)
210  {
211  te::da::PrimaryKey* newPk = dynamic_cast<te::da::PrimaryKey*>(pk->clone());
212  newPk->setName(dsTypeName + "_pk");
213  dsType->setPrimaryKey(newPk);
214  }
215 
216  }
217 
219 
220  save(outputDataSource.get(), dataSet.get(), dsType.get());
221 
223 
224  te::da::DataSetTypePtr dt(std::move(dsType));
225 
226  m_layerResult = converter(dt);
227 
228  return true;
229 }
230 
232 {
233  m_ui->m_newLayerNameLineEdit->clear();
234  m_ui->m_newLayerNameLineEdit->setEnabled(true);
235 
237  dlg.exec();
238 
239  std::list<te::da::DataSourceInfoPtr> dsPtrList = dlg.getSelecteds();
240 
241  if (dsPtrList.size() <= 0)
242  return;
243 
244  std::list<te::da::DataSourceInfoPtr>::iterator it = dsPtrList.begin();
245 
246  m_ui->m_repositoryLineEdit->setText(QString(it->get()->getTitle().c_str()));
247 
248  m_outputDatasource = *it;
249 
251 
252  outputDataSource->open();
253 
254  m_toFile = false;
255 }
256 
258 {
259  m_ui->m_newLayerNameLineEdit->clear();
260  m_ui->m_repositoryLineEdit->clear();
261 
262  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."), QString(), tr("Shapefile (*.shp *.SHP);;"), nullptr, QFileDialog::DontConfirmOverwrite);
263 
264  if (fileName.isEmpty())
265  return;
266 
267  boost::filesystem::path outfile(fileName.toUtf8().data());
268 
269  m_ui->m_repositoryLineEdit->setText(outfile.string().c_str());
270 
271  m_ui->m_newLayerNameLineEdit->setText(outfile.leaf().string().c_str());
272 
273  m_ui->m_newLayerNameLineEdit->setEnabled(false);
274 
275  m_toFile = true;
276 
277  //create new data source
278  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toUtf8().data());
279 
280  const std::string dsInfo("file://" + uri.string());
281 
282  std::unique_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("OGR", dsInfo);
283  ds->open();
284 
285  boost::uuids::basic_random_generator<boost::mt19937> gen;
286  boost::uuids::uuid u = gen();
287  std::string id_ds = boost::uuids::to_string(u);
288 
290  dsInfoPtr->setConnInfo(dsInfo);
291  dsInfoPtr->setTitle(uri.stem().string());
292  dsInfoPtr->setAccessDriver("OGR");
293  dsInfoPtr->setType("OGR");
294  dsInfoPtr->setDescription(uri.string());
295  dsInfoPtr->setId(id_ds);
296 
298 
299  m_outputDatasource = dsInfoPtr;
300 
302 
303  outputDataSource->open();
304 }
305 
306 
virtual void setName(const std::string &name)
It sets the constraint name.
Definition: Constraint.h:126
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)
SaveSelectedObjectsWidget(QWidget *parent=0, Qt::WindowFlags f=0)
virtual std::unique_ptr< DataSourceTransactor > getTransactor()=0
It returns the set of parameters used to set up the access channel to the underlying repository...
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
This interface is used to create a new layer based on a layer with selected objects.
boost::shared_ptr< DataSource > DataSourcePtr
A class that models the description of a dataset.
Definition: DataSetType.h:72
virtual void createDataSet(DataSetType *dt, const std::map< std::string, std::string > &options)
It creates the dataset schema definition in the target data source.
virtual void add(const std::string &datasetName, DataSet *d, const std::map< std::string, std::string > &options, std::size_t limit=0)
It adds data items to the dataset in the data source.
te::map::AbstractLayerPtr m_layer
TerraLib layer auto ptr.
static te::dt::Date ds(2010, 01, 01)
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
void setExpression(te::da::Expression *expression, bool isClauseIn)
It set the expression that can be used to retrieve the data set that contains the all indentified ele...
Definition: ObjectIdSet.cpp:89
te::da::ObjectIdSet * m_oidSet
Object Id Set.
virtual std::string getType() const =0
It returns the data source type name (in UPPER CASE). Ex: POSTGIS, SQLITE, WFS, WMS, or MYSQL.
void setParameters(te::map::AbstractLayerPtr layer)
Set parameters.
static DataSourceManager & getInstance()
It returns a reference to the singleton instance.
Constraint * clone()
It returns a clone of the object.
std::size_t size() const
It returns the object id set size.
void updateWindowComponents()
Update components with imput data.
static te::dt::TimeDuration dt(20, 30, 50, 11)
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
void save(te::da::DataSource *dataSource, te::da::DataSet *dataSet, te::da::DataSetType *dataSetType)
A dataset is the unit of information manipulated by the data access module of TerraLib.
const std::list< te::da::DataSourceInfoPtr > & getSelecteds() const
std::unique_ptr< Ui::SaveSelectedObjectsWidgetForm > m_ui
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
A dialog for selecting a data source.
A class that represents a data source component.
Expression * getExpressionByInClause(const std::string source="") const
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
const std::string & getName() const
It returns the property name.
Definition: Property.h:127