src/terralib/gdal/DataSource.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/gdal/DataSource.cpp
22 
23  \brief The implementation of a DataSource that consists of datasets that can be decoded by the GDAL Library.
24 */
25 
26 // TerraLib
27 #include "../common/StringUtils.h"
28 #include "../core/filesystem/FileSystem.h"
29 #include "../core/translator/Translator.h"
30 #include "../core/uri/URI.h"
31 #include "../core/uri/Utils.h"
32 #include "../geometry/Envelope.h"
33 #include "../dataaccess/dataset/DataSetType.h"
34 #include "../raster/Grid.h"
35 #include "../raster/Raster.h"
36 #include "../raster/RasterProperty.h"
37 #include "DataSet.h"
38 #include "DataSource.h"
39 #include "Exception.h"
40 #include "Transactor.h"
41 #include "Utils.h"
42 #include "DataSetUseCounter.h"
43 
44 // GDAL
45 #include <gdal_priv.h>
46 
47 // Boost
48 #include <boost/filesystem.hpp>
49 #include <boost/format.hpp>
50 #include <boost/algorithm/string/replace.hpp>
51 
53 
54 te::gdal::DataSource::DataSource(const std::string& connInfo)
55  : te::da::DataSource(connInfo),
56  m_straccess(""),
57  m_isOpened(false)
58 {
59 }
60 
62  : te::da::DataSource(uri),
63  m_straccess(""),
64  m_isOpened(false)
65 {
66 }
67 
69 
70 std::string te::gdal::DataSource::getType() const
71 {
73 }
74 
75 // open methods retrieves the names of the datasets in the data source
77 {
78  if (m_isOpened)
79  return;
80 
81  if (!m_uri.isValid())
82  throw Exception((boost::format(TE_TR("Invalid data source connection information"))).str());
83 
84  std::string scheme = m_uri.scheme();
85 
86  std::string source;
87 
88  if (scheme == "file")
89  {
90  source = te::core::URIDecode(m_uri.uri());
91  boost::replace_all(source, "file://", "");
92  }
93  else
94  {
96  }
97 
98  if(source.empty())
99  throw Exception((boost::format(TE_TR("Not enough information to open the data source."))).str());
100  else
101  m_straccess = source;
102 
103  m_isOpened = true;
104 }
105 
107 {
108 }
109 
111 {
112  return m_isOpened;
113 }
114 
116 {
117  if (!m_uri.isValid())
118  return false;
119 
120  std::string scheme = m_uri.scheme();
121 
122  std::string source;
123 
124  if (scheme == "file")
125  {
126  source = te::core::URIDecode(m_uri.uri());
127  boost::replace_all(source, "file://", "");
128 
129  //Checking if it is a valid directory or file name
131  return true;
132  else if (te::core::FileSystem::isRegularFile(source))
133  return true;
134  }
135  else
136  {
138  }
139 
140  if(!source.empty())
141  {
142  // if it is another GDAL string let's check it
143  DataSetUseCounter dsUseCounter(GetParentDataSetName(source),
145 
146  GDALDataset* gds = static_cast<GDALDataset*>(GDALOpen(source.c_str(), GA_ReadOnly));
147 
148  if (gds)
149  {
150  GDALClose(gds);
151 
152  return true;
153  }
154  }
155 
156  return false;
157 }
158 
160 {
161  return sm_capabilities;
162 }
163 
164 std::unique_ptr<te::da::DataSourceTransactor> te::gdal::DataSource::getTransactor()
165 {
166  if (!m_isOpened)
167  throw Exception((boost::format(TE_TR("Data source is not open."))).str());
168 
169  return std::unique_ptr<te::da::DataSourceTransactor>(new te::gdal::Transactor(m_straccess));
170 }
171 
173 {
175 }
176 
177 void te::gdal::DataSource::create(const std::string& connInfo)
178 {
179  //Auxiliary URI
180  te::core::URI auxURI(connInfo);
181 
182  if (!auxURI.isValid())
183  throw Exception((boost::format(TE_TR("Invalid data source connection information"))).str());
184 
185  std::string scheme = auxURI.scheme();
186 
187  if (scheme == "file")
188  {
189  // create the needed directory
190  std::string path = te::core::URIDecode(auxURI.uri());
191  boost::replace_all(path, "file://", "");
192 
193  if (!path.empty())
194  {
195  try
196  {
199  else
200  {
201  throw Exception((boost::format(TE_TR("Data source creation is supported only for directory data sources"))).str());
202  }
203  }
204  catch (const boost::filesystem::filesystem_error& e)
205  {
206  throw Exception((boost::format(TE_TR("Could not create the data source due to the following error: %1%.")) % e.what()).str());
207  }
208  }
209  else
210  {
211  throw Exception((boost::format(TE_TR("Empty data source connection information"))).str());
212  }
213  }
214 }
215 
216 bool te::gdal::DataSource::exists(const std::string& connInfo)
217 {
218  //Auxiliary URI
219  te::core::URI auxURI(connInfo);
220 
221  if (!auxURI.isValid())
222  throw Exception((boost::format(TE_TR("Empty ou invalid data source connection information"))).str());
223 
224  std::string scheme = m_uri.scheme();
225 
226  if (scheme == "file")
227  {
228  std::string path = te::core::URIDecode(auxURI.uri());
229  boost::replace_all(path, "file://", "");
230 
231  if (!path.empty())
232  {
233  if (te::core::FileSystem::exists(path) && te::core::FileSystem::isDirectory(path)) // expects a directory?
234  return true;
235  else if (boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)) // expects a file?
236  {
238 
239  GDALDataset* gds = static_cast<GDALDataset*>(GDALOpen(path.c_str(), GA_ReadOnly));
240 
241  if (gds)
242  {
243  GDALClose(gds);
244  return true;
245  }
246  }
247  }
248  }
249  else
250  {
251  std::string source = te::gdal::MakePGConnectionStr(auxURI);
252 
254 
255  GDALDataset* gds = static_cast<GDALDataset*>(GDALOpen(source.c_str(), GA_ReadOnly));
256 
257  if (gds)
258  {
259  GDALClose(gds);
260  return true;
261  }
262  }
263 
264  return false;
265 }
266 
267 void te::gdal::DataSource::drop(const std::string& connInfo)
268 {
269  //Auxiliary URI
270  te::core::URI auxURI(connInfo);
271 
272  std::string scheme = auxURI.scheme();
273 
274  if (scheme == "file")
275  {
276  std::string path = te::core::URIDecode(auxURI.uri());
277  boost::replace_all(path, "file://", "");
278 
279  if (!path.empty())
280  {
281  try
282  {
284  }
285  catch (const boost::filesystem::filesystem_error& /*e*/)
286  {
287  }
288  }
289  }
290 
291  return; // nothing to be done
292 }
293 
294 std::vector<std::string> te::gdal::DataSource::getDataSourceNames(const std::string& connInfo)
295 {
296  //Auxiliary URI
297  te::core::URI auxURI(connInfo);
298 
299  std::string scheme = auxURI.scheme();
300 
301  std::vector<std::string> dsnames;
302 
303  if (scheme == "file")
304  {
305  std::string path = te::core::URIDecode(auxURI.uri());
306  boost::replace_all(path, "file://", "");
307 
308  if (!path.empty())
309  {
310  dsnames.push_back(path);
311  }
312  else
313  throw Exception((boost::format(TE_TR("Empty ou invalid data source connection information"))).str());
314  }
315  else
316  {
317  std::string aux = te::core::URIDecode(auxURI.path().substr(1, auxURI.path().length()));
318 
319  dsnames.push_back(aux);
320  }
321 
322  return dsnames;
323 }
The implementation of a DataSource that consists of datasets that can be decoded by the GDAL Library...
std::string path() const
Retrieving the path.
Definition: URI.cpp:118
std::string scheme() const
Retrieving the scheme.
Definition: URI.cpp:93
static bool exists(const std::string &path)
Checks if a given path in UTF-8 exists.
Definition: FileSystem.cpp:142
void drop(const std::string &connInfo)
It removes the data source with the connection information from a driver.
static bool isDirectory(const std::string &path)
Checks if a given path in UTF-8 is a directory.
Definition: FileSystem.cpp:87
std::vector< std::string > getDataSourceNames(const std::string &connInfo)
It gets the data source names available in a driver.
Base exception class for plugin module.
void create(const std::string &connInfo)
It creates a new data source.
DataSource(const std::string &connInfo)
static void setCapabilities(const te::da::DataSourceCapabilities &capabilities)
A class that represents the known capabilities of a specific data source, i.e. this class informs all...
bool isValid() const
Return if the given URI is valid or not.
Definition: URI.cpp:133
static te::da::DataSourceCapabilities sm_capabilities
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
~DataSource()
Virtual destructor.
std::unique_ptr< te::da::DataSourceTransactor > getTransactor()
It returns the set of parameters used to set up the access channel to the underlying repository...
A driver to access raster data using the GDAL library.
static bool remove(const std::string &path)
Removes a file or directory from a given path in UTF-8.
Definition: FileSystem.cpp:166
std::string MakePGConnectionStr(const te::core::URI &connInfo)
Returns a PostGIS connection string from the URI connection information. The connection string is to ...
bool exists(const std::string &connInfo)
Check the existence of a data source in a driver.
te::da::DataSourceCapabilities capabilities
std::string GetParentDataSetName(const std::string &subDataSetName)
It returns the parent dataset name from a Sub DataSet name.
URI C++ Library.
Definition: Attributes.h:37
const std::string & uri() const
Retrieving the full URI.
Definition: URI.cpp:88
void close()
It closes the data source and clears all the resources used by its internal communication channel...
A class for representing an Uniform Resource Identifier (URI).
Definition: URI.h:49
static bool createDirectory(const std::string &path)
Creates a directory from a given path in UTF-8.
Definition: FileSystem.cpp:147
bool isValid() const
It checks if the data source is valid (available for using).
bool isOpened() const
It returns true if the data source is opened, otherwise it returns false.
This file contains utility functions used to manipulate data from a URI.
te::core::URI m_uri
The URI used to describe the datasource connection;.
GDAL data set use counter.
std::string getType() const
It returns the data source type name (in UPPER CASE). Ex: POSTGIS, SQLITE, WFS, WMS, or MYSQL.
void open()
It opens the data source and makes it ready for using.
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.
An exception class for the GDAL module.
static bool isRegularFile(const std::string &path)
Checks if a given path in UTF-8 is a regular file.
Definition: FileSystem.cpp:98
const te::da::DataSourceCapabilities & getCapabilities() const
It returns the known capabilities of the data source.
#define TE_GDAL_DRIVER_IDENTIFIER