VectorizationWizard.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 //Terralib
21 #include "../../../common/progress/ProgressManager.h"
22 #include "../../../dataaccess/datasource/DataSource.h"
23 #include "../../../dataaccess/datasource/DataSourceInfoManager.h"
24 #include "../../../dataaccess/datasource/DataSourceInfoManager.h"
25 #include "../../../dataaccess/datasource/DataSourceManager.h"
26 #include "../../../dataaccess/utils/Utils.h"
27 #include "../../../core/filesystem/FileSystem.h"
28 #include "../../../datatype/SimpleProperty.h"
29 #include "../../../geometry/GeometryProperty.h"
30 #include "../../../memory/DataSet.h"
31 #include "../../../memory/DataSetItem.h"
32 #include "../../widgets/layer/utils/DataSet2Layer.h"
33 #include "../help/HelpPushButton.h"
34 #include "../layer/search/LayerSearchWidget.h"
35 #include "../layer/search/LayerSearchWizardPage.h"
36 #include "../progress/ProgressViewerDialog.h"
37 #include "VectorizationWizard.h"
39 
40 // BOOST
41 #include <boost/algorithm/string.hpp>
42 #include <boost/filesystem.hpp>
43 #include <boost/lexical_cast.hpp>
44 #include <boost/uuid/random_generator.hpp>
45 #include <boost/uuid/uuid_io.hpp>
46 
47 // Qt
48 #include <QApplication>
49 #include <QMessageBox>
50 
52 QWizard(parent)
53 {
54  this->setWizardStyle(QWizard::ModernStyle);
55  this->setWindowTitle(tr("Vectorization"));
56 
57  this->setOption(QWizard::HaveHelpButton, true);
58  this->setOption(QWizard::HelpButtonOnRight, false);
59 
61 
62  this->setButton(QWizard::HelpButton, helpButton);
63 
64  helpButton->setPageReference("plugins/rp/rp_vectorization.html");
65 
66  connect(this, SIGNAL(currentIdChanged(int)), SLOT(onPageChanged(int)));
67 
68  addPages();
69 }
70 
72 
74 {
75  if(currentPage() == m_layerSearchPage.get())
76  {
77  std::list<te::map::AbstractLayerPtr> list = m_layerSearchPage->getSearchWidget()->getSelecteds();
78 
79  if(list.empty() == false)
80  {
81  te::map::AbstractLayerPtr l = *list.begin();
82 
83  m_vectorPage->setLayer(l);
84  }
85 
86  return m_layerSearchPage->isComplete();
87  }
88  else if(currentPage() == m_vectorPage.get())
89  {
90  return execute();
91  }
92 
93  return true;
94 }
95 
96 void te::qt::widgets::VectorizationWizard::setList(std::list<te::map::AbstractLayerPtr> &layerList)
97 {
98  m_layerSearchPage->getSearchWidget()->setList(layerList);
99  m_layerSearchPage->getSearchWidget()->filterOnlyByRaster();
100 }
101 
103 {
104  return m_outputLayer;
105 }
106 
108 {
109  m_layerSearchPage.reset(new LayerSearchWizardPage(this));
110  addPage(m_layerSearchPage.get());
111 
112  m_vectorPage.reset(new VectorizationWizardPage(this));
113  addPage(m_vectorPage.get());
114 }
115 
117 {
118  if(te::core::FileSystem::exists(m_vectorPage->getRepositoryName()))
119  {
120  QMessageBox::warning(this, tr("Vectorization"), tr("File already exists."));
121  return false;
122  }
123 
124  //check output parameters
125  std::string outputdataset = m_vectorPage->getLayerName();
126 
127  if(outputdataset.empty())
128  {
129  QMessageBox::warning(this, tr("Vectorizer"), tr("Output dataset name not defined."));
130  return false;
131  }
132 
133  std::string uriStr = m_vectorPage->getRepositoryName();
134 
135  if(uriStr.empty())
136  {
137  QMessageBox::warning(this, tr("Vectorizer"), tr("Output repository name not defined."));
138  return false;
139  }
140 
141  //check output datasource parameters
142  te::da::DataSourceInfoPtr outDSInfo;
143 
144  bool toFile = m_vectorPage->outputDataSourceToFile();
145 
146  if(toFile)
147  {
148  boost::filesystem::path uri(uriStr);
149 
150  std::size_t idx = outputdataset.find(".");
151  if(idx != std::string::npos)
152  outputdataset = outputdataset.substr(0,idx);
153 
154  const std::string connInfo("file://" + uri.string());
155 
156  // let's include the new datasource in the managers
157  boost::uuids::basic_random_generator<boost::mt19937> gen;
158  boost::uuids::uuid u = gen();
159  std::string id = boost::uuids::to_string(u);
160 
162  ds->setConnInfo(connInfo);
163  ds->setTitle(uri.stem().string());
164  ds->setAccessDriver("OGR");
165  ds->setType("OGR");
166  ds->setDescription(uri.string());
167  ds->setId(id);
168 
170  outDSInfo = ds;
171  }
172  else
173  {
174  outDSInfo = m_vectorPage->getDataSourceInfo();
175  }
176 
177  //input parameters
178  std::unique_ptr<te::rst::Raster> raster = m_vectorPage->getRaster();
179  unsigned int band = m_vectorPage->getBand();
180  unsigned int maxGeom = 0;
181  m_vectorPage->hasMaxGeom(maxGeom);
182 
183  //output parameters
184  std::vector<te::gm::Geometry*> geomVec;
185  std::vector< double > geomsValues;
186 
187  //progress
189 
190  QApplication::setOverrideCursor(Qt::WaitCursor);
191 
192  try
193  {
194  //run operation
195  raster->vectorize(geomVec, band, maxGeom, &geomsValues);
196  }
197  catch(const std::exception& e)
198  {
199  QMessageBox::warning(this, tr("Vectorizer"), e.what());
200 
201  QApplication::restoreOverrideCursor();
202 
203  return false;
204  }
205  catch(...)
206  {
207  QMessageBox::warning(this, tr("Vectorizer"), tr("An exception has occurred!"));
208 
209  QApplication::restoreOverrideCursor();
210 
211  return false;
212  }
213 
214  try
215  {
216  //save data
217  std::unique_ptr<te::da::DataSetType> dsType = createDataSetType(outputdataset, raster->getSRID());
218 
219  std::unique_ptr<te::mem::DataSet> dsMem = createDataSet(dsType.get(), geomVec, geomsValues);
220 
221  te::da::DataSourcePtr ds = te::da::DataSourceManager::getInstance().get(outDSInfo->getId(), outDSInfo->getType(), outDSInfo->getConnInfo());
222 
223  saveDataSet(dsMem.get(), dsType.get(), ds, outputdataset);
224 
225  //create output layer
226  te::da::DataSourcePtr outDataSource = te::da::GetDataSource(outDSInfo->getId());
227 
228  te::qt::widgets::DataSet2Layer converter(outDSInfo->getId());
229 
230  te::da::DataSetTypePtr dt(outDataSource->getDataSetType(outputdataset).release());
231 
232  m_outputLayer = converter(dt);
233 
234  QMessageBox::information(this, tr("Vectorizer"), tr("Vectorizer ended sucessfully."));
235  }
236  catch(const std::exception& e)
237  {
238  QMessageBox::warning(this, tr("Vectorizer"), e.what());
239 
240  QApplication::restoreOverrideCursor();
241 
242  return false;
243  }
244  catch(...)
245  {
246  QMessageBox::warning(this, tr("Vectorizer"), tr("An exception has occurred saving geometries!"));
247 
248  QApplication::restoreOverrideCursor();
249 
250  return false;
251  }
252 
253  QApplication::restoreOverrideCursor();
254 
255  return true;
256 }
257 
258 std::unique_ptr<te::da::DataSetType> te::qt::widgets::VectorizationWizard::createDataSetType(std::string dataSetName, int srid)
259 {
260  std::unique_ptr<te::da::DataSetType> dsType(new te::da::DataSetType(dataSetName));
261 
262  //create id property
264  dsType->add(idProperty);
265 
266  te::dt::SimpleProperty* valueProperty = new te::dt::SimpleProperty("value", te::dt::DOUBLE_TYPE, true);
267  dsType->add(valueProperty);
268 
269  //create geometry property
270  te::gm::GeometryProperty* geomProperty = new te::gm::GeometryProperty("geom", srid, te::gm::PolygonType);
271  dsType->add(geomProperty);
272 
273  //create primary key
274  std::string pkName = "pk_id";
275  pkName+= "_" + dataSetName;
276  te::da::PrimaryKey* pk = new te::da::PrimaryKey(pkName, dsType.get());
277  pk->add(idProperty);
278 
279  return dsType;
280 }
281 
282 std::unique_ptr<te::mem::DataSet> te::qt::widgets::VectorizationWizard::createDataSet(te::da::DataSetType* dsType, std::vector<te::gm::Geometry*>& geoms, std::vector< double >& geomsValues)
283 {
284  std::unique_ptr<te::mem::DataSet> ds(new te::mem::DataSet(dsType));
285 
286  for(std::size_t t = 0; t < geoms.size(); ++t)
287  {
288  //create dataset item
289  te::mem::DataSetItem* item = new te::mem::DataSetItem(ds.get());
290 
291  //set id
292  item->setInt32(0, (int)t);
293 
294  //set Value
295  item->setDouble( 1, geomsValues[ t ] );
296 
297  //set geometry
298  item->setGeometry(2, geoms[t]);
299 
300  ds->add(item);
301  }
302 
303  return ds;
304 }
305 
307 {
308  //save dataset
309  dataSet->moveBeforeFirst();
310 
311  std::map<std::string, std::string> options;
312 
313  ds->createDataSet(dsType, options);
314 
315  ds->add(dataSetName, dataSet, options);
316 }
317 
319 {
320  this->adjustSize();
321 }
322 
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
void saveDataSet(te::mem::DataSet *dataSet, te::da::DataSetType *dsType, te::da::DataSourcePtr ds, std::string dataSetName)
unsigned int band
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 setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
static bool exists(const std::string &path)
Checks if a given path in UTF-8 exists.
Definition: FileSystem.cpp:142
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
An atomic property like an integer or double.
te::map::AbstractLayerPtr m_outputLayer
boost::shared_ptr< DataSource > DataSourcePtr
A class that models the description of a dataset.
Definition: DataSetType.h:72
void setPageReference(const QString &ref)
Sets the documentation page reference.
static te::dt::Date ds(2010, 01, 01)
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
std::unique_ptr< te::qt::widgets::LayerSearchWizardPage > m_layerSearchPage
static DataSourceInfoManager & getInstance()
It returns a reference to the singleton instance.
static te::dt::TimeDuration dt(20, 30, 50, 11)
std::unique_ptr< te::qt::widgets::VectorizationWizardPage > m_vectorPage
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
void setList(std::list< te::map::AbstractLayerPtr > &layerList)
Push button that uses te::qt::widgets::HelpManager on its mouse pressed implementation.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
A class that represents a data source component.
std::unique_ptr< te::da::DataSetType > createDataSetType(std::string dataSetName, int srid)
te::map::AbstractLayerPtr getOutputLayer()
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
std::unique_ptr< te::mem::DataSet > createDataSet(te::da::DataSetType *dsType, std::vector< te::gm::Geometry * > &geoms, std::vector< double > &geomsValues)
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr