ogr/DataSet.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/ogr/DataSet.cpp
22 
23  \brief Implementation of a DataSet for OGR data provider.
24 */
25 
26 // TerraLib
27 #include "../core/translator/Translator.h"
28 #include "../dataaccess/dataset/DataSetType.h"
29 #include "../datatype/ByteArray.h"
30 #include "../datatype/DateTimeProperty.h"
31 #include "../datatype/StringProperty.h"
32 #include "../datatype/TimeInstant.h"
33 #include "../geometry/Envelope.h"
34 #include "../geometry/Geometry.h"
35 #include "../geometry/WKBReader.h"
36 #include "../srs/Config.h"
37 #include "DataSource.h"
38 #include "DataSet.h"
39 #include "Exception.h"
40 #include "Utils.h"
41 
42 // OGR
43 #include <ogrsf_frmts.h>
44 #include <ogr_core.h>
45 #include <gdal_priv.h>
46 
47 // STL
48 #include <cassert>
49 #include <memory>
50 
51 //te::ogr::DataSet::DataSet(OGRDataSource* dsrc, OGRLayer* layer) :
52 te::ogr::DataSet::DataSet(GDALDataset* dsrc, OGRLayer* layer)
53  :
54 
55  m_dt(nullptr),
56  m_ogrDs(dsrc),
57  m_layer(layer),
58  m_currentFeature(nullptr),
59  m_i(-1),
60  m_wkbArray(nullptr),
61  m_wkbArraySize(0),
62  m_srid(TE_UNKNOWN_SRS)
63 {
64  assert(layer);
65 
66  layer->ResetReading();
67 
68  m_dt = Convert2TerraLib(layer->GetLayerDefn());
69 
70  assert(m_dt);
71 
72  if(m_dt->hasGeom())
73  {
74  OGRSpatialReference* osrs = m_layer->GetSpatialRef();
75  if(osrs)
77  }
78 }
79 
81 {
82  OGRFeature::DestroyFeature(m_currentFeature);
83 
84  delete [] m_wkbArray;
85 
86  delete m_dt;
87 
88  m_ogrDs->ReleaseResultSet(m_layer);
89 
90  //OGRDataSource::DestroyDataSource(m_ogrDs);
91  GDALClose(m_ogrDs);
92 }
93 
95 {
96  return m_dt->size();
97 }
98 
99 int te::ogr::DataSet::getPropertyDataType(std::size_t pos) const
100 {
101  return m_dt->getProperty(pos)->getType();
102 }
103 
104 std::string te::ogr::DataSet::getPropertyName(std::size_t pos) const
105 {
106  return m_dt->getProperty(pos)->getName();
107 }
108 
109 std::string te::ogr::DataSet::getDatasetNameOfProperty(std::size_t) const
110 {
111  return "";
112 }
113 
115 {
116  return !(size() > 0);
117 }
118 
119 std::unique_ptr<te::gm::Envelope> te::ogr::DataSet::getExtent(std::size_t /*i*/)
120 {
121  OGREnvelope psExtent;
122  OGRErr error = m_layer->GetExtent(&psExtent);
123 
124  if(error != OGRERR_NONE)
125  {
126  //TODO There are codes that describes the error. Send a message according to it.
127  throw Exception(TE_TR("Fail getting extent from OGR dataset."));
128  }
129 
130  te::gm::Envelope* env = Convert2TerraLib(&psExtent);
131  return std::unique_ptr<te::gm::Envelope>(env);
132 }
133 
134 std::size_t te::ogr::DataSet::size() const
135 {
136  return static_cast<std::size_t>(m_layer->GetFeatureCount());
137 }
138 
140 {
141  OGRFeature::DestroyFeature(m_currentFeature);
142 
143  m_currentFeature = m_layer->GetNextFeature();
144 
145  m_i++;
146  return m_currentFeature != nullptr;
147 }
148 
150 {
151  return move(static_cast<size_t>(m_i - 1));
152 }
153 
155 {
156  m_layer->ResetReading();
157  m_i = -1;
158  return true;
159 }
160 
162 {
163  m_layer->ResetReading();
164  m_i = -1;
165  return moveNext();
166 }
167 
169 {
170  size_t lastPos = static_cast<size_t>(m_layer->GetFeatureCount() - 1);
171  return move(lastPos);
172 }
173 
174 bool te::ogr::DataSet::move(std::size_t i)
175 {
176  if(static_cast<size_t>(m_i) == i)
177  return true;
178 
179  int p = static_cast<int>(i);
180 
181  OGRErr error = m_layer->SetNextByIndex(p);
182 
183  m_i = p - 1;
184  if(error == OGRERR_NONE)
185  return moveNext();
186  else
187  return false;
188 }
189 
191 {
192  return m_i == 0;
193 }
194 
196 {
197  return m_i < 0;
198 }
199 
201 {
202  return m_i == static_cast<int>(size()-1);
203 }
204 
206 {
207  return m_i > static_cast<int>(size());
208 }
209 
211 {
212  return m_i > -1 && m_i < static_cast<int>(size());
213 }
214 
215 char te::ogr::DataSet::getChar(std::size_t /*i*/) const
216 {
217  throw te::common::Exception(TE_TR("OGR driver: getChar not supported."));
218 }
219 
220 unsigned char te::ogr::DataSet::getUChar(std::size_t /*i*/) const
221 {
222  throw te::common::Exception(TE_TR("OGR driver: getUChar not supported."));
223 }
224 
225 boost::int16_t te::ogr::DataSet::getInt16(std::size_t /*i*/) const
226 {
227  throw te::common::Exception(TE_TR("OGR driver: getInt16 not supported."));
228 }
229 
230 boost::int32_t te::ogr::DataSet::getInt32(std::size_t i) const
231 {
232  return m_currentFeature->GetFieldAsInteger(static_cast<int>(i));
233 }
234 
235 boost::int64_t te::ogr::DataSet::getInt64(std::size_t i) const
236 {
237  return m_currentFeature->GetFieldAsInteger64(static_cast<int>(i));
238 }
239 
240 bool te::ogr::DataSet::getBool(std::size_t /*i*/) const
241 {
242  throw te::common::Exception(TE_TR("OGR driver: getBool not supported."));
243 }
244 
245 float te::ogr::DataSet::getFloat(std::size_t /*i*/) const
246 {
247  throw te::common::Exception(TE_TR("OGR driver: getFloat not supported."));
248 }
249 
250 double te::ogr::DataSet::getDouble(std::size_t i) const
251 {
252  return m_currentFeature->GetFieldAsDouble(static_cast<int>(i));
253 }
254 
255 std::string te::ogr::DataSet::getNumeric(std::size_t i) const
256 {
257  return m_currentFeature->GetFieldAsString(static_cast<int>(i));
258 }
259 
260 std::string te::ogr::DataSet::getString(std::size_t i) const
261 {
262  return m_currentFeature->GetFieldAsString(static_cast<int>(i));
263 }
264 
265 std::unique_ptr<te::dt::ByteArray> te::ogr::DataSet::getByteArray(std::size_t i) const
266 {
267  int size = 0;
268  GByte* bytes = m_currentFeature->GetFieldAsBinary(static_cast<int>(i), &size);
269 
270  te::dt::ByteArray* byteArray = new te::dt::ByteArray(static_cast<size_t>(size));
271  byteArray->copy(reinterpret_cast<char*>(bytes), static_cast<size_t>(size));
272 
273  return std::unique_ptr<te::dt::ByteArray>(byteArray);
274 }
275 
276 std::unique_ptr<te::gm::Geometry> te::ogr::DataSet::getGeometry(std::size_t /*i*/) const
277 {
278  char* wkb = (char*)getWKB();
279 
280  te::gm::Geometry* geom = nullptr;
281 
282  if (wkb)
283  {
284  geom = te::gm::WKBReader::read(wkb);
285  geom->setSRID(m_srid);
286  }
287 
288  return std::unique_ptr<te::gm::Geometry>(geom);
289 }
290 
291 std::unique_ptr<te::rst::Raster> te::ogr::DataSet::getRaster(std::size_t /*i*/) const
292 {
293  throw te::common::Exception(TE_TR("OGR driver: getRaster not supported."));
294 }
295 
296 std::unique_ptr<te::dt::DateTime> te::ogr::DataSet::getDateTime(std::size_t i) const
297 {
298  if(m_dt == nullptr)
299  return std::unique_ptr<te::dt::DateTime>(nullptr);
300 
301  int pnYear,
302  pnMonth,
303  pnDay,
304  pnHour,
305  pnMinute,
306  pnSecond,
307  pnTZFlag;
308 
309  if(m_currentFeature->GetFieldAsDateTime(static_cast<int>(i), &pnYear, &pnMonth, &pnDay, &pnHour, &pnMinute, &pnSecond, &pnTZFlag) == FALSE)
310  return std::unique_ptr<te::dt::DateTime>(new te::dt::Date);
311 
313  te::dt::DateTimeType subType = static_cast<te::dt::DateTimeProperty*>(p)->getSubType();
314  te::dt::DateTime* dateTime = nullptr;
315 
316  if(subType == te::dt::DATE)
317  {
318  dateTime = new te::dt::Date(static_cast<unsigned short>(pnYear), static_cast<unsigned short>(pnMonth), static_cast<unsigned short>(pnDay));
319  }
320  else if(subType == te::dt::TIME_DURATION)
321  {
322  dateTime = new te::dt::TimeDuration(pnHour, pnMinute, pnSecond);
323  }
324  else if(subType == te::dt::TIME_INSTANT)
325  {
326  te::dt::Date d(static_cast<unsigned short>(pnYear), static_cast<unsigned short>(pnMonth), static_cast<unsigned short>(pnDay));
327  te::dt::TimeDuration td(pnHour, pnMinute, pnSecond);
328  dateTime = new te::dt::TimeInstant(d, td);
329  }
330 
331  return std::unique_ptr<te::dt::DateTime>(dateTime);
332 }
333 
334 std::unique_ptr<te::dt::Array> te::ogr::DataSet::getArray(std::size_t /*i*/) const
335 {
336  return std::unique_ptr<te::dt::Array>(); // Not supported by OGR library
337 }
338 
339 bool te::ogr::DataSet::isNull(std::size_t i) const
340 {
341  if(m_currentFeature->IsFieldSet(static_cast<int>(i)) == 0)
342  return true;
343 
345  {
346  OGRGeometry* geom = m_currentFeature->GetGeometryRef();
347 
348  if (geom == nullptr || geom->IsEmpty())
349  {
350  OGRGeometryFactory::destroyGeometry(geom);
351  return true;
352  }
353  }
354 
355  return false;
356 }
357 
358 const unsigned char* te::ogr::DataSet::getWKB() const
359 {
360  OGRGeometry* geom;
361 
362  // The OGR library supports only one geometry field
363  if (m_currentFeature->GetGeometryRef())
364  geom = m_currentFeature->GetGeometryRef()->clone();
365  else
366  return nullptr;
367 
368  if(geom == nullptr)
369  return nullptr;
370 
371  if (geom->getGeometryType() == wkbPolygon ||
372  geom->getGeometryType() == wkbPolygonM ||
373  geom->getGeometryType() == wkbPolygonZM ||
374  geom->getGeometryType() == wkbPolygon25D)
375  {
376  geom = OGRGeometryFactory::forceToMultiPolygon(geom);
377  }
378  else if (geom->getGeometryType() == wkbLineString ||
379  geom->getGeometryType() == wkbLineStringM ||
380  geom->getGeometryType() == wkbLineStringZM ||
381  geom->getGeometryType() == wkbLineString25D)
382  {
383  geom = OGRGeometryFactory::forceToMultiLineString(geom);
384  }
385  else if (geom->getGeometryType() == wkbPoint ||
386  geom->getGeometryType() == wkbPointM ||
387  geom->getGeometryType() == wkbPointZM ||
388  geom->getGeometryType() == wkbPoint25D)
389  {
390  geom = OGRGeometryFactory::forceToMultiPoint(geom);
391  }
392 
393  int wkbSize = geom->WkbSize();
394 
395  if(wkbSize > m_wkbArraySize)
396  {
397  m_wkbArraySize = wkbSize;
398  delete [] m_wkbArray;
399  m_wkbArray = new unsigned char[m_wkbArraySize];
400  }
401 
402  geom->exportToWkb(wkbNDR, m_wkbArray, wkbVariantIso);
403 
404  OGRGeometryFactory::destroyGeometry(geom);
405 
406  return static_cast<const unsigned char*>(m_wkbArray);
407 }
static te::dt::TimeDuration td(20, 30, 50, 11)
Property * getProperty(std::size_t i) const
It returns the i-th property.
bool isEmpty() const
It returns true if the collection is empty.
std::size_t getNumProperties() const
It returns the number of properties that composes an item of the dataset.
Definition: ogr/DataSet.cpp:94
te::da::DataSetType * m_dt
DataSetType.
Definition: ogr/DataSet.h:158
std::string getDatasetNameOfProperty(std::size_t pos) const
It returns the underlying dataset name of the property at position pos.
std::unique_ptr< te::dt::ByteArray > getByteArray(std::size_t i) const
Method for retrieving a byte array.
float getFloat(std::size_t i) const
Method for retrieving a float attribute value.
std::string getPropertyName(std::size_t pos) const
It returns the property name at position pos.
std::unique_ptr< te::rst::Raster > getRaster(std::size_t i) const
Method for retrieving a raster attribute value.
bool isBeforeBegin() const
It tells if the dataset internal pointer is in a position before the first element of the collection ...
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
bool hasGeom() const
It returns true if the DataSetType has at least one geometry property; otherwise, it returns false...
Definition: DataSetType.h:655
Base exception class for plugin module.
DataSet()
Default constructor.
Utility functions for OGR support.
int m_srid
The SRS id associated to this dataset.
Definition: ogr/DataSet.h:169
unsigned char getUChar(std::size_t i) const
Method for retrieving an unsigned character attribute value (1 byte long).
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
boost::int64_t getInt64(std::size_t i) const
Method for retrieving a 64-bit integer attribute value (8 bytes long).
bool isAfterEnd() const
It tells if the dataset internal pointer is on the sentinel position after the last element of the co...
It models a property definition.
Definition: Property.h:59
GDALDataset * m_ogrDs
Definition: ogr/DataSet.h:161
A class to represent time instant.
Definition: TimeInstant.h:55
bool isAtEnd() const
It tells if the dataset internal pointer is on the last element of the collection.
~DataSet()
Destructor.
Definition: ogr/DataSet.cpp:80
std::unique_ptr< te::dt::DateTime > getDateTime(std::size_t i) const
Method for retrieving a date and time attribute value.
bool getBool(std::size_t i) const
Method for retrieving a boolean attribute value.
bool isPositionValid() const
It tells if the dataset internal pointer is on a valid position.
unsigned char * m_wkbArray
Definition: ogr/DataSet.h:166
An Envelope defines a 2D rectangular region.
double getDouble(std::size_t i) const
Method for retrieving a double attribute value.
A base class for date data types.
Definition: Date.h:53
bool move(std::size_t i)
It moves the dataset internal pointer to a given position.
std::string getNumeric(std::size_t i) const
Method for retrieving a numeric attribute value.
OGRFeature * m_currentFeature
Definition: ogr/DataSet.h:163
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
std::unique_ptr< te::gm::Envelope > getExtent(std::size_t i)
It computes the bounding rectangle for a spatial property of the dataset.
te::gm::Polygon * p
boost::int16_t getInt16(std::size_t i) const
Method for retrieving a 16-bit integer attribute value (2 bytes long).
std::size_t size() const
It returns the number of properties of the CompositeProperty.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
bool moveNext()
It moves the internal pointer to the next item of the collection.
std::unique_ptr< te::dt::Array > getArray(std::size_t i) const
Method for retrieving an array.
boost::int32_t getInt32(std::size_t i) const
Method for retrieving a 32-bit integer attribute value (4 bytes long).
int getType() const
It returns the property data type.
Definition: Property.h:161
bool isNull(std::size_t i) const
It checks if the attribute value is NULL.
const unsigned char * getWKB() const
std::string getString(std::size_t i) const
Method for retrieving a string value attribute.
A class to represent time duration with nano-second/micro-second resolution.
Definition: TimeDuration.h:51
A class for data providers of OGR.
OGRLayer * m_layer
Definition: ogr/DataSet.h:162
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.
virtual void setSRID(int srid) _NOEXCEPT_OP(true)=0
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
Implementation of a DataSet for OGR data provider.
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
char getChar(std::size_t i) const
Method for retrieving a signed character attribute value (1 byte long).
DateTimeType
The subtype of date and time type, based on ISO 8621.
int getPropertyDataType(std::size_t pos) const
It returns the underlying data type of the property at position pos.
Definition: ogr/DataSet.cpp:99
bool isAtBegin() const
It tells if the dataset internal pointer is on the first element of the collection or not...
An exception class for the OGR module.
std::size_t size() const
It returns the collection size, if it is known.
void copy(char *data, std::size_t size)
It copies the data from the given pointer to the byte array.
Definition: ByteArray.cpp:128
bool movePrevious()
It moves the internal pointer to the previous item of the collection.
bool moveLast()
It sets the dataset internal pointer to the last item in the collection.
std::unique_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
TEOGREXPORT int Convert2TerraLibProjection(OGRSpatialReference *osrs)
It converts the OGR Projection to TerraLib Projection.
A class for representing binary data.
Definition: ByteArray.h:51
static Geometry * read(const char *wkb)
It returns a valid geometry from a given WKB.
Definition: WKBReader.cpp:48
bool moveFirst()
It moves the internal pointer to the first item in the collection.
const std::string & getName() const
It returns the property name.
Definition: Property.h:127