All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DataPropertiesWidget.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2010-2013 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/externalTable/DataPropertiesWidget.h
22 
23  \brief A class used to configure the properties of a new textual file based layer
24 */
25 
26 //Terralib
27 #include "../../../dataaccess/dataset/DataSetAdapter.h"
28 #include "../../../dataaccess/dataset/DataSetType.h"
29 #include "../../../dataaccess/dataset/DataSetTypeConverter.h"
30 #include "../../../dataaccess/dataset/PrimaryKey.h"
31 #include "../../../dataaccess/datasource/DataSourceFactory.h"
32 #include "../../../dataaccess/datasource/DataSourceInfo.h"
33 #include "../../../dataaccess/datasource/DataSourceInfoManager.h"
34 #include "../../../dataaccess/datasource/DataSourceManager.h"
35 #include "../../../dataaccess/utils/Utils.h"
36 #include "../../../datatype/Property.h"
37 #include "../../../datatype/DateTimeProperty.h"
38 #include "../../../datatype/NumericProperty.h"
39 #include "../../../datatype/SimpleProperty.h"
40 #include "../../../datatype/StringProperty.h"
41 #include "../../../geometry/GeometryProperty.h"
42 #include "../../../memory/DataSet.h"
43 #include "../table/DataSetTableView.h"
44 #include "../Utils.h"
45 #include "SRSManagerDialog.h"
46 #include "DataPropertiesWidget.h"
47 #include "DataSetAdapterWidget.h"
48 #include "ui_DataPropertiesWidgetForm.h"
49 
50 // Qt
51 #include <QCheckBox>
52 #include <QtGui/QComboBox>
53 #include <QtCore/QFileInfo>
54 #include <QtGui/QFileDialog>
55 #include <QtGui/QMessageBox>
56 
57 // Boost
58 #include <boost/filesystem.hpp>
59 #include <boost/lexical_cast.hpp>
60 #include <boost/uuid/random_generator.hpp>
61 #include <boost/uuid/uuid_io.hpp>
62 
63 //Utility functions used mianly to pupulate ui elements.
64 void buidTypeMap(std::map<int, std::string>& typeMap)
65 {
66  typeMap.clear();
67 
68  typeMap.insert(std::map<int, std::string>::value_type(te::dt::ARRAY_TYPE, QObject::tr("Array").toStdString()));
69  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::BIT_TYPE, QObject::tr("Bit").toStdString()));
70  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::BOOLEAN_TYPE, QObject::tr("Boolean").toStdString()));
71  typeMap.insert(std::map<int, std::string>::value_type(te::dt::BYTE_ARRAY_TYPE, QObject::tr("Byte Array").toStdString()));
72  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::CHAR_TYPE, QObject::tr("Char").toStdString()));
73  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::COMPOSITE_TYPE, QObject::tr("Composite").toStdString()));
74  typeMap.insert(std::map<int, std::string>::value_type(te::dt::DATETIME_TYPE, QObject::tr("Date and Time").toStdString()));
75  typeMap.insert(std::map<int, std::string>::value_type(te::dt::DOUBLE_TYPE, QObject::tr("Double").toStdString()));
76  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::FLOAT_TYPE, QObject::tr("Float").toStdString()));
77  typeMap.insert(std::map<int, std::string>::value_type(te::dt::GEOMETRY_TYPE, QObject::tr("Geometry").toStdString()));
78  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::INT16_TYPE, QObject::tr("Int 16").toStdString()));
79  typeMap.insert(std::map<int, std::string>::value_type(te::dt::INT32_TYPE, QObject::tr("Int 32").toStdString()));
80  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::INT64_TYPE, QObject::tr("Int 64").toStdString()));
81  typeMap.insert(std::map<int, std::string>::value_type(te::dt::NUMERIC_TYPE, QObject::tr("Numeric").toStdString()));
82  typeMap.insert(std::map<int, std::string>::value_type(te::dt::STRING_TYPE, QObject::tr("String").toStdString()));
83  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::UCHAR_TYPE, QObject::tr("U Char").toStdString()));
84  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::UINT16_TYPE, QObject::tr("U Int 16").toStdString()));
85  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::UINT32_TYPE, QObject::tr("U Int 32").toStdString()));
86  //typeMap.insert(std::map<int, std::string>::value_type(te::dt::UINT64_TYPE, QObject::tr("U Int 64").toStdString()));
87 }
88 
89 te::dt::SimpleProperty* getConvertedproperty(std::string name, int dataType, std::string defaultValue = "", bool isRequired = false, bool isAutoNumber = true)
90 {
91  te::dt::SimpleProperty* newProperty;
92 
93  switch(dataType)
94  {
96  case te::dt::CHAR_TYPE:
98  case te::dt::FLOAT_TYPE:
99  case te::dt::INT16_TYPE:
100  case te::dt::INT32_TYPE:
101  case te::dt::INT64_TYPE:
102  case te::dt::UCHAR_TYPE:
103  case te::dt::UINT16_TYPE:
104  case te::dt::UINT32_TYPE:
105  case te::dt::UINT64_TYPE:
106  {
107  newProperty = new te::dt::SimpleProperty(name, dataType, isRequired, new std::string(defaultValue));
108  newProperty->setAutoNumber(isAutoNumber);
109  break;
110  }
111 
112  case te::dt::STRING_TYPE:
113  {
114  newProperty = new te::dt::StringProperty(name, te::dt::STRING, isRequired, new std::string(defaultValue));
115  break;
116  }
117 
119  {
120  newProperty = new te::dt::NumericProperty(name, 0, 0, isRequired, new std::string(defaultValue));
121  newProperty->setAutoNumber(isAutoNumber);
122  break;
123  }
124 
126  {
127  newProperty = new te::dt::DateTimeProperty(name, te::dt::DATE, te::dt::UNKNOWN, isRequired, new std::string(defaultValue));
128  break;
129  }
130 
132  {
133  newProperty = new te::gm::GeometryProperty(name, isRequired, new std::string(defaultValue));
134  break;
135  }
136 
137  default:
138  {
139  newProperty = 0;
140  return false;
141  }
142  }
143  return newProperty;
144 }
145 
146 void fillComboBox(std::map<int, std::string> typeMap, QComboBox* box)
147 {
148  for(std::map<int, std::string>::iterator it = typeMap.begin(); it != typeMap.end(); ++it)
149  {
150  box->addItem(QString::fromStdString(it->second), QVariant(it->first));
151  }
152 }
153 
155  : QWidget(parent, f),
156  m_ui(new Ui::DataPropertiesWidgetForm)
157 {
158  m_ui->setupUi(this);
159 
160  //preparing the Type Map
162 
163  m_mapper = new QSignalMapper(this);
164 
165  //Adjusting the dataSetTableView that will be used to display the dataset's data
166  m_tblView.reset(new DataSetTableView(m_ui->m_dataPreviewFrame));
167  QGridLayout* dataPreviewLayout = new QGridLayout(m_ui->m_dataPreviewFrame);
168  dataPreviewLayout->addWidget(m_tblView.get());
169  dataPreviewLayout->setContentsMargins(0, 0, 0, 0);
170 
171  m_tblView->setAlternatingRowColors(true);
172  m_tblView->verticalHeader()->setVisible(false);
173  m_tblView->setSelectionMode(QAbstractItemView::NoSelection);
174 
175  m_ui->m_dataPropertiesTableWidget->setSelectionMode(QAbstractItemView::NoSelection);
176 
177  //add icon
178  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("tabular-import-hint").pixmap(112,48));
179  m_ui->m_sridPushButton->setIcon(QIcon::fromTheme("srs"));
180 
181  //Connecting signals and slots
182  connect(m_ui->m_inputDataToolButton, SIGNAL(clicked()), this, SLOT(onInputDataToolButtonTriggered()));
183  connect(m_ui->m_sridPushButton, SIGNAL(clicked()), this, SLOT(onSridPushButtonCLicked()));
184  connect(m_mapper, SIGNAL(mapped(int)), this, SLOT(onPropertyTypeChanged(int)));
185 }
186 
188 {
189  m_typeMap.clear();
190 }
191 
192 std::auto_ptr<te::da::DataSetTypeConverter> te::qt::widgets::DatapPropertiesWidget::getConverter()
193 {
194  //Configuring a new geometry if the user requested it.
195  if(m_ui->m_geometryGroupBox->isCheckable() && m_ui->m_geometryGroupBox->isChecked())
196  {
197  te::gm::GeometryProperty* newGeom;
198 
199  std::vector<std::string> names;
200  names.push_back(m_ui->m_xAxisComboBox->currentText().toStdString());
201  names.push_back(m_ui->m_yAxisComboBox->currentText().toStdString());
202  newGeom = new te::gm::GeometryProperty("Point", true, new std::string());
204 
205  m_dsConverter->add(names, newGeom, "XYToPointConverter");
206 
207  }
208 
209  //Searching for properties that the user selected to adapt
210  te::da::PrimaryKey* pk = new te::da::PrimaryKey(m_dsConverter->getResult());
211  te::da::PrimaryKey* pkIn = m_dataType->getPrimaryKey();
212  for (int i = 0; i < m_ui->m_dataPropertiesTableWidget->rowCount(); ++i)
213  {
214  if(dynamic_cast<QCheckBox*>(m_ui->m_dataPropertiesTableWidget->cellWidget(i, 0))->isChecked())
215  {
216  QComboBox* box = dynamic_cast<QComboBox*>(m_ui->m_dataPropertiesTableWidget->cellWidget(i, 1));
217  int type = box->itemData(box->currentIndex()).toInt();
218 
219  m_dsConverter->add(m_dataType->getProperty(i)->getName(), getConvertedproperty(m_dataType->getProperty(i)->getName(), type));
220 
221  if(pkIn)
222  {
223  std::vector<te::dt::Property*> props = pkIn->getProperties();
224 
225  for(std::size_t t= 0; t < props.size(); ++t)
226  {
227  if(props[t]->getName() == m_dataType->getProperty(i)->getName())
228  {
229  te::dt::SimpleProperty* sp = getConvertedproperty(m_dataType->getProperty(i)->getName(), type);
230  pk->add(sp);
231 
232  break;
233  }
234  }
235  }
236 
237  }
238  }
239 
240  te::gm::GeometryProperty* gp = te::da::GetFirstGeomProperty(m_dsConverter->getResult());
241 
242  if(gp && !m_ui->m_sridLineEdit->text().isEmpty())
243  gp->setSRID(boost::lexical_cast<int>(m_ui->m_sridLineEdit->text().trimmed().toStdString()));
244 
245  te::da::DataSourceManager::getInstance().insert(m_dataSource);
246  return m_dsConverter;
247 }
248 
250 {
251  return m_dataSet.get();
252 }
253 
255 {
256  return m_dataType.get();
257 }
258 
260 {
261  return m_dataSource.get();
262 }
263 
265 {
266  QString fileName = QFileDialog::getOpenFileName(this, tr("Open Textual File"), te::qt::widgets::GetFilePathFromSettings("tabular"), tr("Comma Separated Value (*.csv *.CSV);; dBASE (*.dbf *.dbf)"),
267  0, QFileDialog::ReadOnly);
268 
269  if(fileName.isEmpty())
270  return;
271 
272  QFileInfo info(fileName);
273 
274  te::qt::widgets::AddFilePathToSettings(info.absolutePath(), "tabular");
275 
276  m_ui->m_inputDataLineEdit->setText(fileName);
277 
278  //Getting the connection info
279  std::string ogrInfo("connection_string=" + fileName.toStdString());
280  std::map<std::string, std::string> connInfo;
281  connInfo["URI"] = fileName.toStdString();
282 
283  boost::filesystem::path uri(m_ui->m_inputDataLineEdit->text().toStdString());
284  std::string file = uri.stem().string();
285 
286  //Creating a DataSource
287  static boost::uuids::basic_random_generator<boost::mt19937> gen;
288  boost::uuids::uuid u = gen();
289 
291  dsInfo->setConnInfo(connInfo);
292  dsInfo->setId(boost::uuids::to_string(u));
293  dsInfo->setTitle(fileName.toStdString());
294  dsInfo->setDescription("");
295  dsInfo->setAccessDriver("OGR");
296  dsInfo->setType("OGR");
297 
299 
300  m_dataSource = te::da::DataSourceFactory::make(dsInfo->getAccessDriver());
301  m_dataSource->setConnectionInfo(dsInfo->getConnInfo());
302 
303  m_dataSource->setId(boost::uuids::to_string(u));
304  m_dataSource->open();
305 
306  //Creating the DataSet and DataType
307  m_dataSet = m_dataSource->getDataSet(file);
308  std::vector<std::string> datasetNames = m_dataSource->getDataSetNames();
309  m_dataType = m_dataSource->getDataSetType(datasetNames[0]);
310 
311  //Creating the DataSetConverter
312  m_dsConverter.reset(new te::da::DataSetTypeConverter(m_dataType.get()));
313 
314  //Filling the data preview table
315  std::vector<std::size_t> properties;
316  for(std::size_t i = 0; i < m_dataSet->getNumProperties(); ++i)
317  properties.push_back(i);
318 
319  //The table will display 5 rows of the data for previewing purposes
320  std::auto_ptr<te::mem::DataSet> memFeature((new te::mem::DataSet(*m_dataSet.get(), properties, 5)));
321 
322  m_tblView->setDataSet(memFeature.release());
323  m_tblView->resizeColumnsToContents();
324  m_tblView->show();
325 
326  m_ui->m_dataPropertiesTableWidget->setRowCount(0);
327 
328  //Filling the properties table widget
329  for(size_t t = 0; t < m_dataType->size(); ++t)
330  {
331  int newrow = m_ui->m_dataPropertiesTableWidget->rowCount();
332  m_ui->m_dataPropertiesTableWidget->insertRow(newrow);
333 
334  //The Property name item
335  std::string propName = m_dataType->getProperty(t)->getName();
336 
337  //A checkbox used to know if the user wants to import that row's property
338  QCheckBox* impCheck = new QCheckBox();
339  impCheck->setText(QString::fromStdString(propName));
340  impCheck->setCheckState(Qt::Checked);
341 
342  m_ui->m_dataPropertiesTableWidget->setCellWidget(newrow, 0, impCheck);
343 
344  //The property type item
345  QComboBox* typeCB = new QComboBox();
346  fillComboBox(m_typeMap, typeCB);
347  typeCB->setCurrentIndex(typeCB->findText(m_typeMap[m_dataType->getProperty(t)->getType()].c_str()));
348 
349  m_mapper->setMapping(typeCB, newrow);
350  connect(typeCB, SIGNAL(currentIndexChanged (int)), m_mapper, SLOT(map()));
351 
352  m_ui->m_dataPropertiesTableWidget->setCellWidget(newrow, 1, typeCB);
353 
354  //check geom
355  if(m_dataType->hasGeom())
356  {
358 
359  if(gp && gp->getName() == propName)
360  {
361  QString srid;
362  srid.setNum(gp->getSRID());
363  m_ui->m_sridLineEdit->setText(srid);
364 
365  impCheck->setEnabled(false);
366  typeCB->setEnabled(false);
367  break;
368  }
369  }
370 
371  //check pk
372  te::da::PrimaryKey* pk = m_dataType->getPrimaryKey();
373 
374  if(pk)
375  {
376  std::vector<te::dt::Property*> props = pk->getProperties();
377 
378  for(std::size_t t= 0; t < props.size(); ++t)
379  {
380  if(props[t]->getName() == propName)
381  {
382  typeCB->setEnabled(false);
383  impCheck->setEnabled(false);
384  break;
385  }
386  }
387  }
388  }
389 
390  m_ui->m_dataPropertiesTableWidget->resizeColumnsToContents();
391  m_ui->m_dataPropertiesTableWidget->resizeRowsToContents();
392  m_ui->m_dataPropertiesTableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
393 
394  //Clearing the Comboxes if they aren't empty
395  m_ui->m_xAxisComboBox->clear();
396  m_ui->m_yAxisComboBox->clear();
397 
398 
399  if(!m_dataType->hasGeom())
400  {
401 
402  //m_ui->m_geometryGroupBox->setEnabled(true);
403  m_ui->m_geometryGroupBox->setCheckable(true);
404  m_ui->m_xAxisComboBox->setEnabled(true);
405  m_ui->m_yAxisComboBox->setEnabled(true);
406  m_ui->m_geometryGroupBox->setChecked(false);
407 
408 
409  //Filling the ComboBoxes that will be used to configure the resulting geometries
410  for(size_t t = 0; t < m_dataType->size(); ++t)
411  {
412  std::string propName = m_dataType->getProperty(t)->getName();
413  int type = m_dataType->getProperty(t)->getType();
414  if((type >= te::dt::INT16_TYPE && type <= te::dt::UINT64_TYPE) ||
415  type == te::dt::FLOAT_TYPE || type == te::dt::DOUBLE_TYPE)
416  {
417  m_ui->m_xAxisComboBox->addItem(QString::fromStdString(propName));
418  m_ui->m_yAxisComboBox->addItem(QString::fromStdString(propName));
419  }
420  }
421  }
422  else
423  {
424  //m_ui->m_geometryGroupBox->setEnabled(false);
425  m_ui->m_geometryGroupBox->setCheckable(false);
426  m_ui->m_xAxisComboBox->setEnabled(false);
427  m_ui->m_yAxisComboBox->setEnabled(false);
428  }
429 }
430 
432 {
433  te::qt::widgets::SRSManagerDialog srsDialog(this);
434  srsDialog.setWindowTitle(tr("Choose the SRS"));
435 
436  if(srsDialog.exec() != QDialog::Rejected)
437  {
438  std::pair<int, std::string> srid = srsDialog.getSelectedSRS();
439  m_ui->m_sridLineEdit->setText(QString::number(srid.first));
440  }
441 }
442 
444 {
445  //Acquiring the name of the cconfigured property and it's new type.
446  QCheckBox* check = dynamic_cast<QCheckBox*>(m_ui->m_dataPropertiesTableWidget->cellWidget(row, 0));
447  QComboBox* box = dynamic_cast<QComboBox*>(m_ui->m_dataPropertiesTableWidget->cellWidget(row, 1));
448  std::string propName = check->text().toStdString();
449  int type = box->itemData(box->currentIndex()).toInt();
450 
451  //Searching the property to see if it is already in the comboBoxes
452  int xyAxis = m_ui->m_xAxisComboBox->findText(QString::fromStdString(propName));
453 
454  //Checking wheather the property needs to be added to or removed from the xAxisoOmboBox and yAxisoCOmboBox.
455  //Their values will always be the same.
456  if(xyAxis == -1)
457  {
458  if((type >= te::dt::INT16_TYPE && type <= te::dt::UINT64_TYPE) || type == te::dt::FLOAT_TYPE || type == te::dt::DOUBLE_TYPE)
459  {
460  m_ui->m_xAxisComboBox->addItem(QString::fromStdString(propName));
461  m_ui->m_yAxisComboBox->addItem(QString::fromStdString(propName));
462  }
463  }
464  else
465  {
466  if((type <= te::dt::INT16_TYPE && type >= te::dt::UINT64_TYPE) || type != te::dt::FLOAT_TYPE || type != te::dt::DOUBLE_TYPE)
467  {
468  m_ui->m_xAxisComboBox->removeItem(xyAxis);
469  m_ui->m_yAxisComboBox->removeItem(xyAxis);
470  }
471  }
472 }
void setGeometryType(GeomType t)
It sets the geometry subtype.
void fillComboBox(std::map< int, std::string > typeMap, QComboBox *box)
te::da::DataSet * getDataSet()
Returns a pointer to the widget&#39;s dataSet.
An atomic property like an integer or double.
An converter for DataSetType.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:64
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:504
te::dt::SimpleProperty * getConvertedproperty(std::string name, int dataType, std::string defaultValue="", bool isRequired=false, bool isAutoNumber=true)
te::da::DataSetType * getDataSetType()
Returns a pointer to the widget&#39;s dataSetType.
A class used to configure the properties of a new textual file based layer.
The type for date and time types: date, date period, date duration, time duration, time instant, time period, time instant with time zone or time period with time zone.
int getSRID() const
It returns the spatial reference system identifier associated to this property.
TEQTWIDGETSEXPORT QString GetFilePathFromSettings(const QString &typeFile)
Returns the value of the last saved file path for the typeFile required.
Definition: Utils.cpp:360
The type for string types: FIXED_STRING, VAR_STRING or STRING.
A class that represents a data source component.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
TEQTWIDGETSEXPORT void AddFilePathToSettings(const QString &path, const QString &typeFile)
Save last used path in QSettings.
Definition: Utils.cpp:351
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
static std::auto_ptr< DataSource > make(const std::string &dsType)
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the primary key.
Definition: PrimaryKey.h:109
void buidTypeMap(std::map< int, std::string > &typeMap)
std::auto_ptr< DataSetTableView > m_tblView
The widget used to preview the data of the new dataset.
DatapPropertiesWidget(QWidget *parent=0, Qt::WindowFlags f=0)
Constructor.
A dialog used to build a SRSManagerDialog element.
QSignalMapper * m_mapper
The mapper used to know which property was configured.
void setAutoNumber(bool a)
It tells if the property is an autonumber or not.
te::da::DataSource * getDataSource()
Returns a pointer to the widget&#39;s dataSource.
const std::pair< int, std::string > & getSelectedSRS() const
Returns the selected SRS in the window.
A customized table view for te::map::AbstractLayer objects. Uses a te::qt::widgets::DataSetModel as i...
std::auto_ptr< Ui::DataPropertiesWidgetForm > m_ui
The widget&#39;s form.
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:116
A class that models the description of a dataset.
Definition: DataSetType.h:72
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
A class used to define the DataSetAdapterWidget class.
The type for arbitrary precison numbers, like numeric(p, q).
static DataSourceManager & getInstance()
It returns a reference to the singleton instance.
std::auto_ptr< te::da::DataSetTypeConverter > getConverter()
Returns a pointer to the generated DataSetTypeConverter.
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
Geometric property.
std::map< int, std::string > m_typeMap
A map that correlates a terralib type with a label.
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111