All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GeometricOpWizard.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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/qt/GeometricOpWizard.cpp
22 
23  \brief A Qt dialog that allows users to run the basic geographic operations defined by VP module.
24 */
25 
26 // TerraLib
27 #include "../Enums.h"
28 #include "../../common/Logger.h"
29 #include "../../common/progress/ProgressManager.h"
30 #include "../../dataaccess/dataset/DataSet.h"
31 #include "../../dataaccess/dataset/DataSetType.h"
32 #include "../../dataaccess/datasource/DataSourceCapabilities.h"
33 #include "../../dataaccess/datasource/DataSourceInfo.h"
34 #include "../../dataaccess/datasource/DataSourceInfoManager.h"
35 #include "../../dataaccess/datasource/DataSourceFactory.h"
36 #include "../../dataaccess/datasource/DataSourceManager.h"
37 #include "../../dataaccess/utils/Utils.h"
38 
39 #include "../../maptools/AbstractLayer.h"
40 
41 #include "../../qt/widgets/help/HelpPushButton.h"
42 #include "../../qt/widgets/progress/ProgressViewerDialog.h"
43 #include "../../qt/widgets/layer/search/LayerSearchWidget.h"
44 #include "../../qt/widgets/layer/search/LayerSearchWizardPage.h"
45 #include "../../qt/widgets/layer/utils/DataSet2Layer.h"
46 
47 #include "../Config.h"
48 #include "../Exception.h"
49 
50 #include "GeometricOpWizard.h"
51 #include "GeometricOpWizardPage.h"
53 #include "../GeometricOp.h"
54 #include "../GeometricOpMemory.h"
55 #include "../GeometricOpQuery.h"
56 //#include "Utils.h"
57 
58 // STL
59 #include <cassert>
60 
61 // Qt
62 #include <QMessageBox>
63 
64 // Boost
65 #include <boost/filesystem.hpp>
66 #include <boost/uuid/random_generator.hpp>
67 #include <boost/uuid/uuid_io.hpp>
68 
70  : QWizard(parent)
71 {
72  //configure the wizard
73  this->setWizardStyle(QWizard::ModernStyle);
74  this->setWindowTitle(tr("Geometric Operation"));
75 
76  this->setOption(QWizard::HaveHelpButton, true);
77  this->setOption(QWizard::HelpButtonOnRight, false);
78 
80 
81  this->setButton(QWizard::HelpButton, helpButton);
82 
83  //helpButton->setPageReference("../../help.html");
84 
85  addPages();
86 }
87 
89 {
90 
91 }
92 
94 {
95  if(currentPage() == m_layerSearchPage.get())
96  {
97  std::list<te::map::AbstractLayerPtr> list = m_layerSearchPage->getSearchWidget()->getSelecteds();
98 
99  if(list.empty() == false)
100  {
101  te::map::AbstractLayerPtr l = *list.begin();
102  m_geomOpPage->setLayer(l);
103  m_inLayer = l;
104 
105  std::auto_ptr<te::da::DataSetType> dsType = l->getSchema();
106  std::vector<te::dt::Property*> vecProp = dsType->getProperties();
107  std::vector<std::string> vecPropName;
108 
109  for(std::size_t i = 0; i < vecProp.size(); ++i)
110  {
111  if(vecProp[i]->getType() != te::dt::GEOMETRY_TYPE)
112  vecPropName.push_back(vecProp[i]->getName());
113  }
114 
115  m_geomOpOutputPage->setAttributes(vecPropName);
116  }
117 
118  return m_layerSearchPage->isComplete();
119  }
120  else if(currentPage() == m_geomOpOutputPage.get())
121  {
122  if(!m_geomOpOutputPage->getToFile())
123  {
124  if(!m_geomOpOutputPage->getDsInfoPtr())
125  {
126  QMessageBox::information(this,
127  "Basic Geographic Operation",
128  "Set the output data source before execute the operation.");
129  return false;
130  }
131  if(m_geomOpOutputPage->getOutDsName() == "")
132  {
133  QMessageBox::information(this,
134  "Basic Geographic Operation",
135  "Set a Name for the output dataset before execute the operation.");
136  return false;
137  }
138  }
139 
140  return execute();
141  }
142 
143  return true;
144 }
145 
146 void te::vp::GeometricOpWizard::setList(std::list<te::map::AbstractLayerPtr>& layerList)
147 {
148  m_layerSearchPage->getSearchWidget()->setList(layerList);
149  m_layerSearchPage->getSearchWidget()->filterOnlyByGeom();
150 }
151 
153 {
154  removePage(m_layerSearchId);
155  m_geomOpPage->setLayer(layer);
156 }
157 
159 {
160  return m_inLayer;
161 }
162 
163 std::vector<te::map::AbstractLayerPtr> te::vp::GeometricOpWizard::getOutLayer()
164 {
165  return m_outLayer;
166 }
167 
169 {
170  m_layerSearchPage.reset(new te::qt::widgets::LayerSearchWizardPage(this));
171  m_geomOpPage.reset(new te::vp::GeometricOpWizardPage(this));
172  m_geomOpOutputPage.reset(new te::vp::GeometricOpOutputWizardPage(this));
173 
174  m_layerSearchId = addPage(m_layerSearchPage.get());
175  addPage(m_geomOpPage.get());
176  addPage(m_geomOpOutputPage.get());
177 
178  //for contrast only one layer can be selected
179  m_layerSearchPage->getSearchWidget()->enableMultiSelection(false);
180 }
181 
183 {
184  bool result;
185 
186 // progress
189 
190  try
191  {
192  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(m_inLayer.get());
193  te::da::DataSourcePtr inDataSource = te::da::GetDataSource(dsLayer->getDataSourceId(), true);
194 
195  m_ops.clear();
196 
197  //Params
198  if(m_geomOpOutputPage->hasConvexHull())
199  m_ops.push_back(te::vp::CONVEX_HULL);
200 
201  if(m_geomOpOutputPage->hasCentroid())
202  m_ops.push_back(te::vp::CENTROID);
203 
204  if(m_geomOpOutputPage->hasMBR())
205  m_ops.push_back(te::vp::MBR);
206 
207  if(m_geomOpOutputPage->hasArea())
208  m_ops.push_back(te::vp::AREA);
209 
210  if(m_geomOpOutputPage->hasLine())
211  m_ops.push_back(te::vp::LINE);
212 
213  if(m_geomOpOutputPage->hasPerimeter())
214  m_ops.push_back(te::vp::PERIMETER);
215 
216 // get the selected properties of input layer
217  std::vector<std::string> geoProps = m_geomOpPage->getSelectedProps();
218 
219  std::string outputdataset = m_geomOpOutputPage->getOutDsName();
220  std::vector<std::string> outputDSetNames;
221 
222 //get the selected property if the operation is by attribute
223  m_attribute = m_geomOpOutputPage->getAttribute();
224 
225 // Verify output datasource
226  if(m_geomOpOutputPage->getToFile())
227  {
228  boost::filesystem::path uri(m_geomOpOutputPage->getPath());
229  //boost::filesystem::path uri_file(m_geomOpOutputPage->getPath() + "/" + outputdataset + ".shp");
230 
231  //if (boost::filesystem::exists(uri_file))
232  //{
233  // QMessageBox::information(this, "Basic Geographic Operation", "Output file already exists. Remove it or select a new name and try again.");
234  // return false;
235  //}
236 
237  std::size_t idx = outputdataset.find(".");
238 
239  if (idx != std::string::npos)
240  outputdataset=outputdataset.substr(0,idx);
241 
242  std::map<std::string, std::string> dsinfo;
243  dsinfo["URI"] = uri.string();
244 
245  std::auto_ptr<te::da::DataSource> dsOGR = te::da::DataSourceFactory::make("OGR");
246  dsOGR->setConnectionInfo(dsinfo);
247  dsOGR->open();
248  if (dsOGR->dataSetExists(outputdataset))
249  {
250  QMessageBox::information(this, "Basic Geographic Operation", "There is already a dataset with the requested name in the output data source. Remove it or select a new name and try again.");
251  return false;
252  }
253 
254  this->setCursor(Qt::WaitCursor);
255 
256  // sera feito por algum tipo de factory
257  te::vp::GeometricOp* geomOp = 0;
258 
259  // select a strategy based on the capabilities of the input datasource
260  const te::da::DataSourceCapabilities dsCapabilities = inDataSource->getCapabilities();
261 
262  if(dsCapabilities.supportsPreparedQueryAPI() && dsCapabilities.getQueryCapabilities().supportsSpatialSQLDialect())
263  {
264  geomOp = new te::vp::GeometricOpQuery();
265  }
266  else
267  {
268  geomOp = new te::vp::GeometricOpMemory();
269  }
270 
271  geomOp->setInput(inDataSource, dsLayer->getDataSetName(), dsLayer->getSchema());
272  geomOp->setOutput(dsOGR, outputdataset);
273  geomOp->setParams(geoProps,
274  m_ops,
275  m_geomOpOutputPage->getObjectStrategy(),
276  m_attribute,
277  m_geomOpOutputPage->hasOutputLayer());
278 
279  if (!geomOp->paramsAreValid())
280  result = false;
281  else
282  result = geomOp->run();
283 
284  if (!result)
285  {
286  this->setCursor(Qt::ArrowCursor);
287  QMessageBox::information(this, "Geometric Operation", "Error: could not generate the operation, check the log file.");
288  return false;
289  }
290 
291  outputDSetNames = geomOp->GetOutputDSetNames();
292 
293  delete geomOp;
294 
295  // let's include the new datasource in the managers
296  boost::uuids::basic_random_generator<boost::mt19937> gen;
297  boost::uuids::uuid u = gen();
298  std::string id = boost::uuids::to_string(u);
299 
301  ds->setConnInfo(dsinfo);
302  ds->setTitle(uri.stem().string());
303  ds->setAccessDriver("OGR");
304  ds->setType("OGR");
305  ds->setDescription(uri.string());
306  ds->setId(id);
307 
308  te::da::DataSourcePtr newds = te::da::DataSourceManager::getInstance().get(id, "OGR", ds->getConnInfo());
309  newds->open();
311  m_outputDatasource = ds;
312  }
313  else
314  {
315  m_outputDatasource = m_geomOpOutputPage->getDsInfoPtr();
316  std::auto_ptr<te::da::DataSource> trgDs = te::da::DataSourceFactory::make(m_outputDatasource->getType());
317  trgDs->setConnectionInfo(m_outputDatasource->getConnInfo());
318  trgDs->open();
319 
320  if (!trgDs.get())
321  {
322  QMessageBox::information(this, "Geometric Operation", "The selected output datasource can not be accessed.");
323  return false;
324  }
325 
326  if (trgDs->dataSetExists(outputdataset))
327  {
328  QMessageBox::information(this, "Geometric Operation", "Dataset already exists. Remove it or select a new name and try again.");
329  return false;
330  }
331 
332  te::vp::GeometricOp* geomOp = 0;
333 
334  // select a strategy based on the capabilities of the input datasource
335  const te::da::DataSourceCapabilities dsCapabilities = inDataSource->getCapabilities();
336 
337  if(dsCapabilities.supportsPreparedQueryAPI() && dsCapabilities.getQueryCapabilities().supportsSpatialSQLDialect())
338  {
339  geomOp = new te::vp::GeometricOpQuery();
340  }
341  else
342  {
343  geomOp = new te::vp::GeometricOpMemory();
344  }
345 
346  geomOp->setInput(inDataSource, dsLayer->getDataSetName(), dsLayer->getSchema());
347  geomOp->setOutput(trgDs, outputdataset);
348  geomOp->setParams(geoProps,
349  m_ops,
350  m_geomOpOutputPage->getObjectStrategy(),
351  m_attribute,
352  m_geomOpOutputPage->hasOutputLayer());
353 
354  if (!geomOp->paramsAreValid())
355  result = false;
356  else
357  result = geomOp->run();
358 
359  if (!result)
360  {
361  this->setCursor(Qt::ArrowCursor);
362  QMessageBox::information(this, "Geometric Operation", "Error: could not generate the operation.");
363  return false;
364  }
365 
366  outputDSetNames = geomOp->GetOutputDSetNames();
367 
368  delete geomOp;
369  }
370 
371 // creating a layer for the result
372  te::da::DataSourcePtr outDataSource = te::da::GetDataSource(m_outputDatasource->getId());
373  te::qt::widgets::DataSet2Layer converter(m_outputDatasource->getId());
374 
375  for(std::size_t i = 0; i < outputDSetNames.size(); ++i)
376  {
377  te::da::DataSetTypePtr dt(outDataSource->getDataSetType(outputDSetNames[i]).release());
378  if(dt)
379  m_outLayer.push_back(converter(dt));
380  }
381  }
382  catch(const std::exception& e)
383  {
384  this->setCursor(Qt::ArrowCursor);
385  QMessageBox::information(this, "Basic Greographic Operation", e.what());
386 
387  te::common::Logger::logDebug("vp", e.what());
389  return false;
390  }
391 
393  this->setCursor(Qt::ArrowCursor);
394 
395  return true;
396 }
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:259
void setList(std::list< te::map::AbstractLayerPtr > &layerList)
const std::string & getDataSetName() const
std::vector< std::string > GetOutputDSetNames()
Definition: GeometricOp.cpp:90
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
The geographic operation Line.
Definition: Enums.h:106
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
The geographic operation Minimum Bounding Rectangle.
Definition: Enums.h:104
void setLayer(te::map::AbstractLayerPtr layer)
A class that represents the known capabilities of a specific data source, i.e. this class informs all...
This class is GUI used to define the basic geometric operator parameters for the VP operation...
const QueryCapabilities & getQueryCapabilities() const
The geographic operation Area.
Definition: Enums.h:105
void removeViewer(int viewerId)
Dettach a progress viewer.
static ProgressManager & getInstance()
It returns a reference to the singleton instance.
const std::string & getDataSourceId() const
static std::auto_ptr< DataSource > make(const std::string &dsType)
A Qt dialog that allows users to run the basic geometric operations defined by VP module...
The geographic operation Perimeter.
Definition: Enums.h:107
bool supportsSpatialSQLDialect() const
void setOutput(std::auto_ptr< te::da::DataSource > outDsrc, std::string dsname)
Definition: GeometricOp.cpp:70
The geographic operation Centroid.
Definition: Enums.h:103
std::vector< te::map::AbstractLayerPtr > getOutLayer()
This file defines a class for Basic Geometric Operation Wizard Page.
int addViewer(AbstractProgressViewer *apv)
Attach a progress viewer.
Push button that uses te::qt::widgets::HelpManager on its mouse pressed implementation.
virtual bool paramsAreValid()
Definition: GeometricOp.cpp:76
te::map::AbstractLayerPtr getInLayer()
The geographic operation Convex Hull.
Definition: Enums.h:102
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.
void setInput(te::da::DataSourcePtr inDsrc, std::string inDsetName, std::auto_ptr< te::da::DataSetType > inDsetType)
Definition: GeometricOp.cpp:48
void setParams(std::vector< std::string > selectedProps, std::vector< te::vp::GeometricOperation > operations, te::vp::GeometricOpObjStrategy objStrategy, std::string attribute, bool outputLayer)
Definition: GeometricOp.cpp:57
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
GeometricOpWizard(QWidget *parent)
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
virtual bool run()=0