All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ConfigInputLayerDialog.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/addressgeocoding/ConfigInputLayerDialog.cpp
22 
23  \brief A dialog configure the input layer to address geocoding operation
24 */
25 
26 // TerraLib
27 #include "../../common/Logger.h"
28 #include "../../common/progress/ProgressManager.h"
29 #include "../../common/Translator.h"
30 #include "../../common/STLUtils.h"
31 #include "../../dataaccess/dataset/DataSetType.h"
32 #include "../../dataaccess/dataset/ObjectIdSet.h"
33 #include "../../dataaccess/datasource/DataSourceCapabilities.h"
34 #include "../../dataaccess/datasource/DataSourceInfo.h"
35 #include "../../dataaccess/datasource/DataSourceInfoManager.h"
36 #include "../../dataaccess/datasource/DataSourceFactory.h"
37 #include "../../dataaccess/datasource/DataSourceManager.h"
38 #include "../../dataaccess/utils/Utils.h"
39 #include "../../datatype/Enums.h"
40 #include "../../datatype/Property.h"
41 #include "../../geometry/GeometryProperty.h"
42 #include "../../maptools/AbstractLayer.h"
43 #include "../../postgis/Transactor.h"
44 #include "../../qt/af/Utils.h"
45 #include "../../qt/widgets/datasource/selector/DataSourceSelectorDialog.h"
46 #include "../../qt/widgets/layer/utils/DataSet2Layer.h"
47 #include "../../qt/widgets/progress/ProgressViewerDialog.h"
48 #include "../../qt/widgets/utils/DoubleListWidget.h"
49 #include "../../statistics/core/Utils.h"
50 #include "../Config.h"
51 #include "../Exception.h"
52 #include "ConfigInputLayerDialog.h"
53 #include "ConfigNumberDialog.h"
54 #include "ui_ConfigInputLayerDialogForm.h"
55 
56 // Qt
57 #include <QFileDialog>
58 #include <QGridLayout>
59 #include <QMessageBox>
60 
61 // Boost
62 #include <boost/algorithm/string.hpp>
63 #include <boost/filesystem.hpp>
64 #include <boost/uuid/random_generator.hpp>
65 #include <boost/uuid/uuid_io.hpp>
66 
67 #include <iostream>
68 #include <string>
69 
71  : QDialog(parent, f),
72  m_ui(new Ui::ConfigInputLayerDialogForm),
73  m_layers(std::list<te::map::AbstractLayerPtr>())
74 {
75 // add controls
76  m_ui->setupUi(this);
77 
78  m_widget.reset(new te::qt::widgets::DoubleListWidget(m_ui->m_widget));
79 
80  QGridLayout* displayLayout = new QGridLayout(m_ui->m_widget);
81  displayLayout->addWidget(m_widget.get());
82 
83  m_widget->setLeftLabel("Available Attributes");
84  m_widget->setRightLabel("Selected Attributes");
85 
86  connect(m_ui->m_inputLayerComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onInputLayerComboBoxChanged(int)));
87 
88 // connect(m_ui->m_numberPushButton, SIGNAL(clicked()), this, SLOT(onNumberPushButtonClicked()));
89 
90  connect(m_ui->m_helpPushButton, SIGNAL(clicked()), this, SLOT(onHelpPushButtonClicked()));
91  connect(m_ui->m_okPushButton, SIGNAL(clicked()), this, SLOT(onOkPushButtonClicked()));
92  connect(m_ui->m_cancelPushButton, SIGNAL(clicked()), this, SLOT(onCancelPushButtonClicked()));
93 
94 }
95 
97 {
98 }
99 
100 void te::addressgeocoding::ConfigInputLayerDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
101 {
102  m_layers = layers;
103 
104  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
105 
106  while(it != m_layers.end())
107  {
108  std::auto_ptr<te::da::DataSetType> dsType = it->get()->getSchema();
109  if(dsType->hasGeom())
110  {
111  te::gm::GeometryProperty* geomProp = te::da::GetFirstGeomProperty(dsType.get());
112  int type = geomProp->getGeometryType();
113 
114  if((type == te::gm::LineStringType) || (type == te::gm::MultiLineStringType))
115  m_ui->m_inputLayerComboBox->addItem(QString(it->get()->getTitle().c_str()), QVariant(it->get()->getId().c_str()));
116  }
117 
118  ++it;
119  }
120 }
121 
123 {
124  return m_selectedLayer;
125 }
126 
128 {
129  return m_dataSource;
130 }
131 
133 {
134  m_widget->clearInputValues();
135  m_widget->clearOutputValues();
136 
137  std::list<te::map::AbstractLayerPtr>::iterator it = m_layers.begin();
138  std::string layerID = m_ui->m_inputLayerComboBox->itemData(index, Qt::UserRole).toString().toStdString();
139 
140  while(it != m_layers.end())
141  {
142  if(layerID == it->get()->getId().c_str())
143  {
144  te::map::AbstractLayerPtr selectedLayer = it->get();
145  m_selectedLayer = selectedLayer;
146  std::auto_ptr<const te::map::LayerSchema> schema(selectedLayer->getSchema());
147  const std::vector<te::dt::Property*>& properties = schema->getProperties();
148  std::vector<std::string> propNames;
149 
150  for(std::size_t i=0; i < properties.size(); ++i)
151  {
152  if(properties[i]->getType() != te::dt::GEOMETRY_TYPE)
153  propNames.push_back(properties[i]->getName());
154  }
155  m_widget->setInputValues(propNames);
156  }
157  ++it;
158  }
159 }
160 
162 {
164  dlg.setLayer(m_selectedLayer);
165 
166  if(dlg.exec()!=QDialog::Accepted)
167  {
168  //m_initialLeft = dlg.getInitialLeft();
169  //m_finalLeft = dlg.getFinalLeft();
170  //m_initialRight = dlg.getInitialRight();
171  //m_finalRight = dlg.getFinalRight();
172  }
173 
174  return;
175 }
176 
178 {
179  QMessageBox::information(this, "Help", "Under development");
180 }
181 
183 {
184  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(m_selectedLayer.get());
185  if(!dsLayer)
186  {
187  QMessageBox::information(this, "Address Geocoding", "Can not execute this operation on this type of layer.");
188  return;
189  }
190 
191  m_dataSource = te::da::GetDataSource(dsLayer->getDataSourceId(), true);
192  if(!m_dataSource.get())
193  {
194  QMessageBox::information(this, "Address Geocoding", "The selected input data source can not be accessed.");
195  }
196 
197  m_selectedProps = m_widget->getOutputValues();
198  if(m_selectedProps.empty())
199  {
200  QMessageBox::information(this, "Address Geocoding", "Select at least one attribute.");
201  return;
202  }
203 
204 //Checks whether the table already contains a column called tsvector.
205  std::auto_ptr<te::da::DataSetType> schema = m_selectedLayer->getSchema();
206  const std::vector<te::dt::Property*>& properties = schema->getProperties();
207 
208  bool addNewColumn = true;
209  for(std::size_t i = 0; i < properties.size(); ++i)
210  {
211  std::string name = properties[i]->getName();
212  if(name == "tsvector")
213  addNewColumn = false;
214  }
215 
216 // ALTER TABLE adding a new columns of tsvector type.
217  if(addNewColumn == true)
218  {
219  std::auto_ptr<te::da::DataSourceTransactor> trans = m_dataSource->getTransactor();
220  std::string alterTable = "ALTER TABLE "+ m_selectedLayer->getTitle() + " ADD tsvector tsvector";
221  trans->execute(alterTable);
222  }
223 
224 
225 
226 // UPDATE values in tsvector column.
227  std::string updateTable = "UPDATE " + m_selectedLayer->getTitle() + " SET tsvector = to_tsvector('english', ";
228 
229  for(std::size_t selProps = 0; selProps < m_selectedProps.size(); ++selProps)
230  {
231  if(selProps == 0)
232  updateTable += " "+ m_selectedProps[selProps];
233  else
234  updateTable += "||' '||"+ m_selectedProps[selProps];
235  }
236 
237  updateTable += ")";
238 
239  m_dataSource->execute(updateTable);
240 
241 
242  unsigned dot = m_selectedLayer->getTitle().find_last_of(".");
243  std::string table = m_selectedLayer->getTitle().substr(dot+1);
244 
245 //DROP INDEX if exists.
246  std::string dropIndex = "DROP INDEX IF EXISTS " + table +"_idx";
247  m_dataSource->execute(dropIndex);
248 
249 //CREATE INDEX to speed up the text search.
250  std::string createIndex = "CREATE INDEX "+ table +"_idx ON "+ m_selectedLayer->getTitle() + " USING GIN(tsvector)";
251 
252  m_dataSource->execute(createIndex);
253 
254  this->accept();
255 }
256 
258 {
259  reject();
260 }
261 
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:262
Geometric property.
Associates address number.
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
std::auto_ptr< Ui::ConfigInputLayerDialogForm > m_ui
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
A dialog configure the input layer to address geocoding operation.
const std::string & getDataSourceId() const
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
void setLayer(te::map::AbstractLayerPtr layer)
A layer with reference to a dataset.
Definition: DataSetLayer.h:47
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:557
ConfigInputLayerDialog(QWidget *parent=0, Qt::WindowFlags f=0)
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
std::auto_ptr< te::qt::widgets::DoubleListWidget > m_widget