QueryDialog.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/query/QueryDialog.h
22 
23  \brief This file defines a class for a Query Dialog Dialog.
24 */
25 
26 // TerraLib
27 #include "../../../common/StringUtils.h"
28 #include "../../../dataaccess/dataset/DataSet.h"
29 #include "../../../dataaccess/dataset/DataSetType.h"
30 #include "../../../dataaccess/dataset/ObjectIdSet.h"
31 #include "../../../dataaccess/datasource/DataSourceCapabilities.h"
32 #include "../../../dataaccess/query/FunctionNames.h"
33 #include "../../../dataaccess/query/QueryCapabilities.h"
34 #include "../../../dataaccess/query_h.h"
35 #include "../../../dataaccess/utils/Utils.h"
36 #include "../../../maptools/DataSetLayer.h"
37 #include "../../../maptools/QueryLayer.h"
38 #include "../../../geometry/GeometryProperty.h"
39 #include "../../../se/Utils.h"
40 #include "../layer/explorer/LayerItemView.h"
41 #include "../layer/explorer/TreeItem.h"
42 #include "../utils/ColorPickerToolButton.h"
43 #include "QueryDialog.h"
44 #include "WhereClauseWidget.h"
45 #include "ui_QueryDialogForm.h"
46 
47 // Qt
48 #include <QGridLayout>
49 #include <QMessageBox>
50 
51 // Boost
52 #include <boost/uuid/random_generator.hpp>
53 #include <boost/uuid/uuid_io.hpp>
54 
55 // STL
56 #include <cassert>
57 #include <memory>
58 
60 
61 te::qt::widgets::QueryDialog::QueryDialog(QWidget* parent, Qt::WindowFlags f)
62  : QDialog(parent, f),
63  m_ui(new Ui::QueryDialogForm)
64 {
65  m_ui->setupUi(this);
66 
67  // Build form
68  QGridLayout* layout = new QGridLayout(m_ui->m_widget);
69  m_whereClauseWidget.reset( new te::qt::widgets::WhereClauseWidget(m_ui->m_widget));
70  layout->addWidget(m_whereClauseWidget.get());
71  layout->setContentsMargins(0, 0, 0, 0);
72 
73  // Color Picker
74  m_colorPicker = new te::qt::widgets::ColorPickerToolButton(this);
75  m_colorPicker->setFixedSize(70, 24);
76  m_colorPicker->setColor(QColor(255, 255, 0, 128));
77 
78  // Adjusting...
79  QGridLayout* colorPickerLayout = new QGridLayout(m_ui->m_colorPickerFrame);
80  colorPickerLayout->setContentsMargins(0, 0, 0, 0);
81  colorPickerLayout->addWidget(m_colorPicker);
82 
83  // Signals¨& slots
84  connect(m_ui->m_inputLayerComboBox, SIGNAL(activated(QString)), this, SLOT(onInputLayerActivated(QString)));
85  connect(m_ui->m_applyPushButton, SIGNAL(clicked()), this, SLOT(onApplyPushButtonClicked()));
86  connect(m_ui->m_createLayerPushButton, SIGNAL(clicked()), this, SLOT(onCreateLayerPushButtonClicked()));
87 
88  //
89  m_ui->m_helpPushButton->setPageReference("widgets/query/query_dialog.html");
90 }
91 
93 
94 void te::qt::widgets::QueryDialog::setLayerList(std::list<te::map::AbstractLayerPtr>& layerList)
95 {
96  m_whereClauseWidget->setLayerList(layerList);
97 
98  m_ui->m_inputLayerComboBox->clear();
99 
100  std::list<te::map::AbstractLayerPtr>::iterator it = layerList.begin();
101 
102  while(it != layerList.end())
103  {
105 
106  std::unique_ptr<te::da::DataSetType> dsType = l->getSchema();
107 
108  if(dsType->hasGeom())
109  m_ui->m_inputLayerComboBox->addItem(l->getTitle().c_str(), QVariant::fromValue(l));
110 
111  ++it;
112  }
113 
114  if(m_ui->m_inputLayerComboBox->count() > 0)
115  {
116  QString s = m_ui->m_inputLayerComboBox->currentText();
117 
119  }
120 }
121 
123 {
124  for(int i = 0; i < m_ui->m_inputLayerComboBox->count(); ++i)
125  {
126  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(i, Qt::UserRole);
128 
129  if(layer == l)
130  {
131  m_ui->m_inputLayerComboBox->setCurrentIndex(i);
132  break;
133  }
134  }
135 
136  if(m_ui->m_inputLayerComboBox->count() > 0)
137  {
138  QString s = m_ui->m_inputLayerComboBox->currentText();
139 
141  }
142 }
143 
144 std::string te::qt::widgets::QueryDialog::setAliasName(std::string value)
145 {
146  if(value.empty() == false)
147  {
148  std::string dataSetName = value;
149  std::string aliasName = value;
150 
151  size_t pos = dataSetName.find(".");
152 
153  if(pos != std::string::npos)
154  {
155  aliasName = dataSetName.substr(pos + 1, dataSetName.size() - 1);
156  }
157 
158  return aliasName;
159  }
160  return "";
161 }
162 
164 {
165  return m_whereClauseWidget->getWhere();
166 }
167 
169 {
170  //setCurrentLayer(layer);
171 }
172 
174 {
175  //add layer to input layer combo box
176  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(layer.get());
177 
178  if(dsLayer)
179  m_ui->m_inputLayerComboBox->addItem(layer->getTitle().c_str(), QVariant::fromValue(layer));
180 
181  int curIdx = m_ui->m_inputLayerComboBox->currentIndex();
182 
183  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(curIdx, Qt::UserRole);
185 
186  if(l == layer)
187  {
188  QString s = m_ui->m_inputLayerComboBox->currentText();
189 
191  }
192 
193  //add layer to spatial layer combo box
194  if (dsLayer)
195  m_whereClauseWidget->addLayer(layer);
196 }
197 
199 {
200  //remove layer from input layer combo box
201  int curIdx = m_ui->m_inputLayerComboBox->currentIndex();
202 
203  for(int i = 0; i < m_ui->m_inputLayerComboBox->count(); ++i)
204  {
205  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(i, Qt::UserRole);
207 
208  if(l == layer)
209  {
210  m_ui->m_inputLayerComboBox->removeItem(i);
211 
212  if(i == curIdx)
213  {
214  if(m_ui->m_inputLayerComboBox->count() != 0)
215  {
216  m_ui->m_inputLayerComboBox->setCurrentIndex(0);
217 
218  QString s = m_ui->m_inputLayerComboBox->currentText();
219 
221  }
222  else
223  {
224  m_whereClauseWidget->resetInterface();
225  }
226  }
227  }
228  }
229 
230  //remove layer from spatial layer combo box
231  m_whereClauseWidget->removeLayer(layer);
232 }
233 
235 {
236  m_whereClauseWidget->resetInterface();
237 
238  // Gets the input layer
239  int idxLayer = m_ui->m_inputLayerComboBox->currentIndex();
240 
241  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(idxLayer, Qt::UserRole);
242 
243  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
244 
245  // Sets the DataSource
246  std::string dataSourceName = layer->getDataSourceId();
247 
248  te::da::DataSourcePtr dsPtr = te::da::GetDataSource(dataSourceName);
249 
250  if(!dsPtr->isOpened())
251  dsPtr->open();
252 
253  m_whereClauseWidget->setDataSource(dsPtr);
254 
255  // Gets the capabilities
256  std::vector<std::string> vecOperators;
257  std::vector<std::string> vecSpatialOperators;
258  std::vector<std::string> vecConnectors;
259 
260  te::da::DataSourceCapabilities dsCap = dsPtr->getCapabilities();
262 
263  std::set<std::string>::iterator it;
264 
265  it = queryCap.getArithmeticOperators().begin();
266  while(it != queryCap.getArithmeticOperators().end())
267  {
268  vecOperators.push_back(*it);
269  ++it;
270  }
271 
272  it = queryCap.getComparsionOperators().begin();
273  while(it != queryCap.getComparsionOperators().end())
274  {
275  vecOperators.push_back(*it);
276  ++it;
277  }
278 
279  m_whereClauseWidget->setOperatorsList(vecOperators);
280 
281  it = queryCap.getSpatialTopologicOperators().begin();
282  while(it != queryCap.getSpatialTopologicOperators().end())
283  {
284  vecSpatialOperators.push_back(*it);
285  ++it;
286  }
287 
288  // For while! TODO: Revision!!!
289  if(vecSpatialOperators.size() == 1 && vecSpatialOperators[0] == te::da::FunctionNames::sm_ST_EnvelopeIntersects)
290  {
291  vecSpatialOperators.clear();
292  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Intersects);
293  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Disjoint);
294  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Touches);
295  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Overlaps);
296  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Crosses);
297  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Within);
298  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Contains);
299  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Equals);
300  }
301 
302  m_whereClauseWidget->setSpatialOperatorsList(vecSpatialOperators);
303 
304  it = queryCap.getLogicalOperators().begin();
305  while(it != queryCap.getLogicalOperators().end())
306  {
307  vecConnectors.push_back(*it);
308  ++it;
309  }
310 
311  m_whereClauseWidget->setConnectorsList(vecConnectors);
312 
313  // Gets data set information
314  std::unique_ptr<te::da::DataSetType> dsType = layer->getSchema();
315 
316  std::string dsName = dsType->getName();
317  std::string aliasName = setAliasName(dsName);
318 
319  std::vector<std::pair<std::string, std::string> > list;
320  list.push_back(std::pair<std::string, std::string>(dsName, aliasName));
321 
322  m_whereClauseWidget->setFromItems(list);
323 
324  // Get properties
325  std::vector<std::string> inputProperties;
326  std::vector<std::string> geomProperties;
327 
328  for(size_t i = 0; i < dsType->size(); ++i)
329  {
330  std::string propName = dsType->getProperty(i)->getName();
331 
332  if(dsType->getProperty(i)->getType() == te::dt::GEOMETRY_TYPE)
333  geomProperties.push_back(propName);
334  else
335  inputProperties.push_back(propName);
336  }
337 
338  m_whereClauseWidget->setAttributeList(inputProperties);
339  m_whereClauseWidget->setGeomAttributeList(geomProperties, layer->getSRID());
340 }
341 
343 {
344  // Gets the defined restriction
345  te::da::Where* wh = getWhere();
346  if (wh == nullptr || wh->getExp() == nullptr)
347  {
348  QMessageBox::information(this, tr("Query"), tr("Add a restriction expression first."));
349  return;
350  }
351 
352  // Gets the selected layer
353  int index = m_ui->m_inputLayerComboBox->currentIndex();
354 
355  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(index, Qt::UserRole);
356 
357  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
358 
359  std::unique_ptr<te::da::DataSetType> schema = layer->getSchema();
360 
361  std::vector<std::string> tokens;
362  te::common::Tokenize(schema->getName(), tokens, ".");
363 
364  std::string alias;
365 
366  if (tokens.size() > 1)
367  alias = tokens[1];
368  else
369  alias = schema->getName();
370 
371  assert(layer.get());
372 
373  static boost::uuids::basic_random_generator<boost::mt19937> gen;
374  boost::uuids::uuid u = gen();
375  std::string id = boost::uuids::to_string(u);
376 
377  te::map::AbstractLayerPtr aLayer(new te::map::QueryLayer(id, layer->getTitle()));
378  aLayer->setDataSourceId(layer->getDataSourceId());
379 
380  te::map::QueryLayer* qLayer = dynamic_cast<te::map::QueryLayer*>(aLayer.get());
381 
382  qLayer->setRendererType("QUERY_LAYER_RENDERER");
383 
384  //fields
385  te::da::Fields* fields = new te::da::Fields;
386 
387  std::vector<te::dt::Property*> props = schema->getProperties();
388  for (auto p : props)
389  {
390  fields->push_back(new te::da::Field(alias + "." + p->getName()));
391  }
392 
393  //from
394  te::da::From* from = new te::da::From;
395 
396  te::da::FromItem* fromItem = new te::da::DataSetName(schema->getName(), alias);
397  from->push_back(fromItem);
398 
399  //build the select object
400  te::da::Select* s = new te::da::Select(fields, from, wh);
401 
402  qLayer->setQuery(s);
403 
405  if (gp)
406  {
407  qLayer->computeExtent();
408  qLayer->setSRID(gp->getSRID());
409 
410  // style
412  }
413 
414  emit createLayer(aLayer);
415 }
416 
418 {
419  // Gets the defined restriction
420  te::da::Where* wh = getWhere();
421  if(wh == nullptr || wh->getExp() == nullptr)
422  {
423  QMessageBox::information(this, tr("Query"), tr("Add a restriction expression first."));
424  return;
425  }
426 
427  // Gets the selected layer
428  int index = m_ui->m_inputLayerComboBox->currentIndex();
429 
430  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(index, Qt::UserRole);
431 
432  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
433 
434  assert(layer.get());
435 
436  // Let's execute the query
437  try
438  {
439  setCursor(Qt::WaitCursor);
440 
441  // The filter expression
442  te::da::Expression* e = wh->getExp()->clone();
443 
444  // Gets the layer schema
445  std::unique_ptr<const te::map::LayerSchema> schema(layer->getSchema());
446 
447  // Gets the dataset
448  std::unique_ptr<te::da::DataSet> dataset = layer->getData(e);
449  assert(dataset.get());
450 
451  if(m_ui->m_newSelRadioButton->isChecked())
452  {
453  // Generates the oids
454  dataset->moveBeforeFirst();
455  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataset.get(), schema.get());
456 
457  oids->setExpression(wh->getExp()->clone(), false);
458 
459  layer->clearSelected();
460  layer->select(oids);
461 
462  emit layerSelectedObjectsChanged(layer);
463  }
464  else if(m_ui->m_addSelRadioButton->isChecked())
465  {
466  // Generates the oids
467  dataset->moveBeforeFirst();
468  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataset.get(), schema.get());
469 
470  oids->setExpression(wh->getExp()->clone(), false);
471 
472  layer->select(oids);
473 
474  emit layerSelectedObjectsChanged(layer);
475  }
476 
477  emit highlightLayerObjects(layer, dataset.get(), m_colorPicker->getColor());
478 
479  setCursor(Qt::ArrowCursor);
480 
481  QMessageBox::information(this, tr("Query"), tr("Query executed with successfully."));
482  }
483  catch(std::exception& e)
484  {
485  setCursor(Qt::ArrowCursor);
486  QMessageBox::information(this, tr("Query"), e.what());
487  }
488 }
489 
490 
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
const std::set< std::string > & getComparsionOperators() const
void createLayer(te::map::AbstractLayerPtr layer)
Geometric property.
std::unique_ptr< te::qt::widgets::WhereClauseWidget > m_whereClauseWidget
Definition: QueryDialog.h:141
An abstract class that models a source of data in a query.
Definition: FromItem.h:50
The Field class can be used to model an expression that takes part of the output items of a SELECT...
static const std::string sm_ST_Equals
Definition: FunctionNames.h:85
A class that models the name of a dataset used in a From clause.
Definition: DataSetName.h:43
static const std::string sm_ST_Overlaps
Definition: FunctionNames.h:98
boost::shared_ptr< DataSource > DataSourcePtr
static const std::string sm_ST_Touches
static const std::string sm_ST_Intersects
Definition: FunctionNames.h:88
virtual void layerAdded(te::map::AbstractLayerPtr layer)
This method is used to add a new layer.
virtual Expression * clone() const =0
It creates a new copy of this expression.
void highlightLayerObjects(const te::map::AbstractLayerPtr &layer, te::da::DataSet *dataset, const QColor &color)
void setCurrentLayer(te::map::AbstractLayerPtr layer)
This method is used to set current layer.
A class that represents the known capabilities of a specific data source, i.e. this class informs all...
const std::set< std::string > & getArithmeticOperators() const
A layer resulting from a query.
Definition: QueryLayer.h:50
virtual void layerRemoved(te::map::AbstractLayerPtr layer)
This method is used to remove a layer.
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
static const std::string sm_ST_Contains
Definition: FunctionNames.h:75
const QueryCapabilities & getQueryCapabilities() const
std::unique_ptr< Ui::QueryDialogForm > m_ui
Definition: QueryDialog.h:140
This is an abstract class that models a query expression.
TESEEXPORT Style * CreateFeatureTypeStyle(const te::gm::GeomType &geomType)
Try creates an appropriate feature type style based on given geometry type.
const std::set< std::string > & getLogicalOperators() const
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr) te
Definition: QueryDialog.cpp:59
void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
It tokenizes a given string with a delimiter of your own choice.
Definition: StringUtils.h:221
void setRendererType(const std::string &t)
Definition: QueryLayer.cpp:402
static const std::string sm_ST_Crosses
Definition: FunctionNames.h:77
Custom tool button used to pick a color.
A class that informs the query support of a given data source.
int getSRID() const
It returns the spatial reference system identifier associated to this property.
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:55
This file has the DataSetWidget class.
URI C++ Library.
Definition: Attributes.h:37
te::da::Where * getWhere()
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
boost::ptr_vector< Field > Fields
Fields is just a boost::ptr_vector of Field pointers.
Definition: Fields.h:37
A class that can be used to model a filter expression that can be applied to a query.
Definition: Where.h:47
te::gm::Polygon * p
static const std::string sm_ST_EnvelopeIntersects
Definition: FunctionNames.h:84
Expression * getExp() const
Definition: Where.cpp:58
TEDATAACCESSEXPORT ObjectIdSet * GenerateOIDSet(DataSet *dataset, const DataSetType *type)
This class is used to define the WHERE object of select operation.
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
std::string setAliasName(std::string value)
This method is used to set the alias name.
const std::set< std::string > & getSpatialTopologicOperators() const
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
ColorPickerToolButton * m_colorPicker
Definition: QueryDialog.h:142
virtual void layerSelected(te::map::AbstractLayerPtr layer)
This method is used to set current layer.
This file defines a class for a Query Dialog Dialog.
static const std::string sm_ST_Disjoint
Definition: FunctionNames.h:79
void onInputLayerActivated(QString value)
virtual void setSRID(int srid)
It sets the Spatial Reference System ID associated to the Layer.
void setQuery(te::da::Select *s)
Definition: QueryLayer.cpp:390
static const std::string sm_ST_Within
virtual void setStyle(te::se::Style *style)
It sets the Style associated to the layer.
A layer with reference to a dataset.
Definition: DataSetLayer.h:47
void layerSelectedObjectsChanged(const te::map::AbstractLayerPtr &layer)
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
void setLayerList(std::list< te::map::AbstractLayerPtr > &layerList)
This method is used to set the list of layers.
Definition: QueryDialog.cpp:94
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr