OGRConnectorDialog.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/plugins/datasource/ogr/OGRConnectorDialog.cpp
22 
23  \brief A dialog window for showing the OGR connector widget.
24 */
25 
26 // TerraLib
27 #include "../../../../core/translator/Translator.h"
28 #include "../../../../core/uri/URI.h"
29 #include "../../../../core/uri/Utils.h"
30 #include "../../../../dataaccess/datasource/DataSource.h"
31 #include "../../../../dataaccess/datasource/DataSourceFactory.h"
32 #include "../../../../dataaccess/datasource/DataSourceInfo.h"
33 #include "../../../../dataaccess/datasource/DataSourceManager.h"
34 #include "../../../af/Utils.h"
35 #include "../../../widgets/Exception.h"
36 #include "../../../widgets/Utils.h"
37 #include "OGRConnectorDialog.h"
38 #include "ui_OGRConnectorDialogForm.h"
39 #include "Utils.h"
40 
41 // Boost
42 #include <boost/uuid/random_generator.hpp>
43 #include <boost/uuid/uuid_io.hpp>
44 #include <boost/filesystem.hpp>
45 #include <boost/lexical_cast.hpp>
46 
47 // Qt
48 #include <QFileInfo>
49 #include <QFileDialog>
50 #include <QMessageBox>
51 
52 // STL
53 #include <cassert>
54 
56  : QDialog(parent, f),
57  m_ui(new Ui::OGRConnectorDialogForm)
58 {
59 // add controls
60  m_ui->setupUi(this);
61 
62 // connect signal and slots
63  connect(m_ui->m_openPushButton, SIGNAL(pressed()), this, SLOT(openPushButtonPressed()));
64  connect(m_ui->m_testPushButton, SIGNAL(pressed()), this, SLOT(testPushButtonPressed()));
65  connect(m_ui->m_searchFeatureToolButton, SIGNAL(pressed()), this, SLOT(searchFeatureToolButtonPressed()));
66 
67  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
68  m_ui->m_helpPushButton->setPageReference("plugins/ogr/ogr.html");
69 }
70 
72 
74 {
75  return m_datasource;
76 }
77 
79 {
80  return m_driver;
81 }
82 
84 {
85  m_datasource = ds;
86 
87  if(m_datasource.get() != nullptr)
88  {
89  setConnectionInfo(m_datasource->getConnInfoAsString());
90 
91  m_ui->m_datasourceTitleLineEdit->setText(QString::fromUtf8(m_datasource->getTitle().c_str()));
92 
93  m_ui->m_datasourceDescriptionTextEdit->setText(QString::fromUtf8(m_datasource->getDescription().c_str()));
94  }
95 }
96 
98 {
99  try
100  {
101  // check if driver is loaded
102  if(te::da::DataSourceFactory::find("OGR") == 0)
103  throw te::qt::widgets::Exception(TE_TR("Sorry! No data access driver loaded for OGR data sources!"));
104 
105  // get data source connection info based on form data
106  const std::string dsInfo = getConnectionInfo();
107 
108 // perform connection
109  std::unique_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("OGR", dsInfo);
110  ds->open();
111  m_driver.reset(ds.release());
112 
113  if(m_driver.get() == nullptr)
114  throw te::qt::widgets::Exception(TE_TR("Could not open dataset via OGR due to an unknown error!"));
115 
116  QString title = m_ui->m_datasourceTitleLineEdit->text().trimmed();
117 
118  if(title.isEmpty())
119  title = m_ui->m_featureRepoLineEdit->text();
120 
121  if(m_datasource.get() == nullptr)
122  {
123 // create a new data source based on form data
125 
126  m_datasource->setConnInfo(dsInfo);
127 
128  boost::uuids::basic_random_generator<boost::mt19937> gen;
129  boost::uuids::uuid u = gen();
130  std::string dsId = boost::uuids::to_string(u);
131 
132  m_datasource->setId(dsId);
133  m_driver->setId(dsId);
134  m_datasource->setTitle(title.toUtf8().data());
135  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().toUtf8().data());
136  m_datasource->setAccessDriver("OGR");
137  m_datasource->setType("OGR");
138  }
139  else
140  {
141  m_driver->setId(m_datasource->getId());
142  m_datasource->setConnInfo(dsInfo);
143  m_datasource->setTitle(title.toUtf8().data());
144  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().trimmed().toUtf8().data());
145  }
146 
147  if(m_ui->m_fileRadioButton->isChecked())
148  {
149  QString path = m_ui->m_featureRepoLineEdit->text().trimmed();
150  if(IsShapeFile(path) && !HasShapeFileSpatialIndex(path))
151  {
152  if(QMessageBox::question(this, windowTitle(), tr("Do you want create spatial index to the selected ESRI ShapeFile?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
153  {
154  std::vector<std::string> datasetNames = m_driver->getDataSetNames();
155  assert(!datasetNames.empty());
156 
157  std::string command = "CREATE SPATIAL INDEX ON " + datasetNames[0];
158 
159  QApplication::setOverrideCursor(Qt::WaitCursor);
160 
161  m_driver->execute(command);
162 
163  QApplication::restoreOverrideCursor();
164 
165  QMessageBox::information(this, windowTitle(), "Spatial index created with successfully!");
166  }
167  }
168  }
169  }
170  catch(const std::exception& e)
171  {
172  QMessageBox::warning(this,
173  tr("TerraLib Qt Components"),
174  tr(e.what()));
175  return;
176  }
177  catch(...)
178  {
179  QMessageBox::warning(this,
180  tr("TerraLib Qt Components"),
181  tr("Unknown error while opening feature via OGR!"));
182  return;
183  }
184 
185  accept();
186 }
187 
189 {
190  try
191  {
192  // check if driver is loaded
193  if(te::da::DataSourceFactory::find("OGR") == 0)
194  throw te::qt::widgets::Exception(TE_TR("Sorry! No data access driver loaded for OGR data sources!"));
195 
196  // perform connection
197  std::unique_ptr<te::da::DataSource> ds(te::da::DataSourceFactory::make("OGR", getConnectionInfo()));
198  ds->open();
199 
200  if(ds.get() == nullptr)
201  throw te::qt::widgets::Exception(TE_TR("Could not open feature repository via OGR!"));
202 
203  if (m_ui->m_dirRadioButton->isChecked() && ds->getNumberOfDataSets() <= 0)
204  QMessageBox::information(this,
205  tr("TerraLib Qt Components"),
206  tr("Directory does not contain datasets!"));
207  else
208  QMessageBox::information(this,
209  tr("TerraLib Qt Components"),
210  tr("Data source is ok!"));
211  }
212  catch(const std::exception& e)
213  {
214  QMessageBox::warning(this,
215  tr("TerraLib Qt Components"),
216  tr(e.what()));
217  }
218  catch(...)
219  {
220  QMessageBox::warning(this,
221  tr("TerraLib Qt Components"),
222  tr("Unknown error while testing OGR data source!"));
223  }
224 }
225 
227 {
228  if(m_ui->m_fileRadioButton->isChecked())
229  {
230  QString fileName = QFileDialog::getOpenFileName(this, tr("Open Vector File"),
231  te::qt::widgets::GetFilePathFromSettings("vector"), tr("Esri Shapefile (*.shp *.SHP);; Mapinfo File (*.mif *.MIF);; GeoJSON (*.geojson *.GeoJSON);; GML (*.gml *.GML);; KML (*.kml *.KML);; All Files (*.*)"),
232  nullptr, QFileDialog::ReadOnly);
233 
234  if(fileName.isEmpty())
235  return;
236 
237  QFileInfo info(fileName);
238 
239  te::qt::widgets::AddFilePathToSettings(info.absolutePath(), "vector");
240 
241  m_ui->m_featureRepoLineEdit->setText(fileName);
242  }
243  else if(m_ui->m_dirRadioButton->isChecked())
244  {
245  QString dirName = QFileDialog::getExistingDirectory(this, tr("Select a directory with shape files"),
246  te::qt::widgets::GetFilePathFromSettings("vector"), QFileDialog::ShowDirsOnly);
247 
248  if(dirName.isEmpty())
249  return;
250 
251  te::qt::widgets::AddFilePathToSettings(dirName, "vector");
252 
253  m_ui->m_featureRepoLineEdit->setText(dirName);
254  }
255  else
256  {
257  QMessageBox::warning(this,
258  tr("TerraLib Qt Components"),
259  tr("Sorry, network files are not implemented yet!\nWe will provide it soon!"));
260  }
261 }
262 
264 {
265  QString qstr; // Auxiliary string used to hold temporary data
266 
267  std::string strURI = "file://"; // The base of the URI
268 
269  qstr = m_ui->m_featureRepoLineEdit->text().trimmed();
270 
271  if(qstr.isEmpty())
272  throw te::qt::widgets::Exception(TE_TR("Please select a feature file first!"));
273 
274  strURI += qstr.toUtf8().data();
275 
276  return strURI;
277 }
278 
280 {
281  const te::core::URI uri(connInfo);
282  std::string path = te::core::URIDecode(uri.host() + uri.path());
283 
284  if(!path.empty())
285  {
286  m_ui->m_featureRepoLineEdit->setText(QString::fromUtf8(path.c_str()));
287 
288  if(boost::filesystem::is_directory(path))
289  m_ui->m_dirRadioButton->setChecked(true);
290  else if(boost::filesystem::is_regular_file(path))
291  m_ui->m_fileRadioButton->setChecked(true);
292  }
293 }
294 
const te::da::DataSourcePtr & getDriver() const
std::string path() const
Retrieving the path.
Definition: URI.cpp:118
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
boost::shared_ptr< DataSource > DataSourcePtr
TEQTWIDGETSEXPORT void AddFilePathToSettings(const QString &path, const QString &typeFile)
Save last used path in QSettings.
static te::dt::Date ds(2010, 01, 01)
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
const te::da::DataSourceInfoPtr & getDataSource() const
std::string host() const
Retrieving the host.
Definition: URI.cpp:108
std::unique_ptr< Ui::OGRConnectorDialogForm > m_ui
A dialog window for showing the OGR connector widget.
A class for representing an Uniform Resource Identifier (URI).
Definition: URI.h:49
void set(const te::da::DataSourceInfoPtr &ds)
This file contains utility functions used to manipulate data from a URI.
A class that represents a data source component.
TEQTWIDGETSEXPORT QString GetFilePathFromSettings(const QString &typeFile)
Returns the value of the last saved file path for the typeFile required.
TECOREEXPORT std::string URIDecode(const std::string &srcUri)
Decodes an encoded URI. The algorithm implementation is based on http://www.codeguru.com/cpp/cpp/algorithms/strings/article.php/c12759/URI-Encoding-and-Decoding.htm.
OGRConnectorDialog(QWidget *parent=0, Qt::WindowFlags f=0)
void setConnectionInfo(const std::string &connInfo)
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr