qt/plugins/mobile/geopackage/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::gpkg::DataSet::DataSet(OGRDataSource* dsrc, OGRLayer* layer) :
52 te::gpkg::DataSet::DataSet(GDALDataset* dsrc, OGRLayer* layer) :
53 te::da::DataSet(),
54 m_dt(0),
55 m_ogrDs(dsrc),
56 m_layer(layer),
57 m_currentFeature(0),
58 m_i(-1),
59 m_wkbArray(0),
60 m_wkbArraySize(0),
61 m_srid(TE_UNKNOWN_SRS)
62 {
63  assert(layer);
64 
65  layer->ResetReading();
66 
67  m_dt = Convert2TerraLib(layer->GetLayerDefn());
68 
69  assert(m_dt);
70 
71  if(m_dt->hasGeom())
72  {
73  OGRSpatialReference* osrs = m_layer->GetSpatialRef();
74  if(osrs)
76  }
77 }
78 
80 {
81  OGRFeature::DestroyFeature(m_currentFeature);
82 
83  delete [] m_wkbArray;
84 
85  delete m_dt;
86 
87  m_ogrDs->ReleaseResultSet(m_layer);
88 
89  //OGRDataSource::DestroyDataSource(m_ogrDs);
90  //GDALClose(m_ogrDs);
91  GDALClose((GDALDatasetH)m_ogrDs);
92 }
93 
95 {
96  return m_dt->size();
97 }
98 
99 int te::gpkg::DataSet::getPropertyDataType(std::size_t pos) const
100 {
101  return m_dt->getProperty(pos)->getType();
102 }
103 
104 std::string te::gpkg::DataSet::getPropertyName(std::size_t pos) const
105 {
106  return m_dt->getProperty(pos)->getName();
107 }
108 
109 std::string te::gpkg::DataSet::getDatasetNameOfProperty(std::size_t pos) const
110 {
111  return "";
112 }
113 
115 {
116  return !(size() > 0);
117 }
118 
119 std::auto_ptr<te::gm::Envelope> te::gpkg::DataSet::getExtent(std::size_t /*i*/)
120 {
121  OGREnvelope psExtent;
122  m_layer->GetExtent(&psExtent);
123  te::gm::Envelope* env = Convert2TerraLib(&psExtent);
124  return std::auto_ptr<te::gm::Envelope>(env);
125 }
126 
127 std::size_t te::gpkg::DataSet::size() const
128 {
129  return m_layer->GetFeatureCount();
130 }
131 
133 {
134  OGRFeature::DestroyFeature(m_currentFeature);
135 
136  m_currentFeature = m_layer->GetNextFeature();
137 
138  m_i++;
139  return m_currentFeature != 0;
140 }
141 
143 {
144  return move(m_i - 1);
145 }
146 
148 {
149  m_layer->ResetReading();
150  m_i = -1;
151  return true;
152 }
153 
155 {
156  m_layer->ResetReading();
157  m_i = -1;
158  return moveNext();
159 }
160 
162 {
163  int lastPos = m_layer->GetFeatureCount() - 1;
164  return move(lastPos);
165 }
166 
167 bool te::gpkg::DataSet::move(std::size_t i)
168 {
169  if(m_i == i)
170  return true;
171 
172  int p = static_cast<int>(i);
173 
174  OGRErr error = m_layer->SetNextByIndex(p);
175 
176  m_i = p - 1;
177  if(error == OGRERR_NONE)
178  return moveNext();
179  else
180  return false;
181 }
182 
184 {
185  return m_i == 0;
186 }
187 
189 {
190  return m_i < 0;
191 }
192 
194 {
195  return m_i >= (int)size();
196 }
197 
199 {
200  return m_i > static_cast<int>(size());
201 }
202 
203 char te::gpkg::DataSet::getChar(std::size_t /*i*/) const
204 {
205  throw te::common::Exception(TE_TR("OGR driver: getChar not supported."));
206 }
207 
208 unsigned char te::gpkg::DataSet::getUChar(std::size_t /*i*/) const
209 {
210  throw te::common::Exception(TE_TR("OGR driver: getUChar not supported."));
211 }
212 
213 boost::int16_t te::gpkg::DataSet::getInt16(std::size_t /*i*/) const
214 {
215  throw te::common::Exception(TE_TR("OGR driver: getInt16 not supported."));
216 }
217 
218 boost::int32_t te::gpkg::DataSet::getInt32(std::size_t i) const
219 {
220  return m_currentFeature->GetFieldAsInteger(i);
221 }
222 
223 boost::int64_t te::gpkg::DataSet::getInt64(std::size_t i) const
224 {
225  return m_currentFeature->GetFieldAsInteger64(i);
226 }
227 
228 bool te::gpkg::DataSet::getBool(std::size_t /*i*/) const
229 {
230  throw te::common::Exception(TE_TR("OGR driver: getBool not supported."));
231 }
232 
233 float te::gpkg::DataSet::getFloat(std::size_t /*i*/) const
234 {
235  throw te::common::Exception(TE_TR("OGR driver: getFloat not supported."));
236 }
237 
238 double te::gpkg::DataSet::getDouble(std::size_t i) const
239 {
240  return m_currentFeature->GetFieldAsDouble(i);
241 }
242 
243 std::string te::gpkg::DataSet::getNumeric(std::size_t i) const
244 {
245  return m_currentFeature->GetFieldAsString(i);
246 }
247 
248 std::string te::gpkg::DataSet::getString(std::size_t i) const
249 {
250  return m_currentFeature->GetFieldAsString(i);
251 }
252 
253 std::auto_ptr<te::dt::ByteArray> te::gpkg::DataSet::getByteArray(std::size_t i) const
254 {
255  int size = 0;
256  GByte* bytes = m_currentFeature->GetFieldAsBinary(i, &size);
257 
258  te::dt::ByteArray* byteArray = new te::dt::ByteArray(size);
259  byteArray->copy((char*)bytes, size);
260 
261  return std::auto_ptr<te::dt::ByteArray>(byteArray);
262 }
263 
264 std::auto_ptr<te::gm::Geometry> te::gpkg::DataSet::getGeometry(std::size_t /*i*/) const
265 {
266  char* wkb = (char*)getWKB();
267 
269  geom->setSRID(m_srid);
270 
271  return std::auto_ptr<te::gm::Geometry>(geom);
272 }
273 
274 std::auto_ptr<te::rst::Raster> te::gpkg::DataSet::getRaster(std::size_t /*i*/) const
275 {
276  throw te::common::Exception(TE_TR("OGR driver: getRaster not supported."));
277 }
278 
279 std::auto_ptr<te::dt::DateTime> te::gpkg::DataSet::getDateTime(std::size_t i) const
280 {
281  if(m_dt == 0)
282  return std::auto_ptr<te::dt::DateTime>(0);
283 
284  int pnYear,
285  pnMonth,
286  pnDay,
287  pnHour,
288  pnMinute,
289  pnSecond,
290  pnTZFlag;
291 
292  if(m_currentFeature->GetFieldAsDateTime(i, &pnYear, &pnMonth, &pnDay, &pnHour, &pnMinute, &pnSecond, &pnTZFlag) == FALSE)
293  return std::auto_ptr<te::dt::DateTime>(new te::dt::Date);
294 
296  te::dt::DateTimeType subType = static_cast<te::dt::DateTimeProperty*>(p)->getSubType();
297  te::dt::DateTime* dateTime = 0;
298 
299  if(subType == te::dt::DATE)
300  {
301  dateTime = new te::dt::Date((unsigned short)pnYear, (unsigned short)pnMonth, (unsigned short)pnDay);
302  }
303  else if(subType == te::dt::TIME_DURATION)
304  {
305  dateTime = new te::dt::TimeDuration(pnHour, pnMinute, pnSecond);
306  }
307  else if(subType == te::dt::TIME_INSTANT)
308  {
309  te::dt::Date d(pnYear, pnMonth, pnDay);
310  te::dt::TimeDuration td(pnHour, pnMinute, pnSecond);
311  dateTime = new te::dt::TimeInstant(d, td);
312  }
313 
314  return std::auto_ptr<te::dt::DateTime>(dateTime);
315 }
316 
317 std::auto_ptr<te::dt::Array> te::gpkg::DataSet::getArray(std::size_t /*i*/) const
318 {
319  return std::auto_ptr<te::dt::Array>(0); // Not supported by OGR library
320 }
321 
322 bool te::gpkg::DataSet::isNull(std::size_t i) const
323 {
324  if(m_currentFeature->IsFieldSet(i) == 0)
325  return true;
326 
327  return false;
328 }
329 
330 const unsigned char* te::gpkg::DataSet::getWKB() const
331 {
332  // The OGR library supports only one geometry field
333  OGRGeometry* geom = m_currentFeature->GetGeometryRef()->clone();
334 
335  if(geom == 0)
336  return 0;
337 
338  if(geom->getGeometryType() == wkbPolygon)
339  geom = OGRGeometryFactory::forceToMultiPolygon(geom);
340  else if(geom->getGeometryType() == wkbLineString)
341  geom = OGRGeometryFactory::forceToMultiLineString(geom);
342  else if(geom->getGeometryType() == wkbPoint)
343  geom = OGRGeometryFactory::forceToMultiPoint(geom);
344 
345  int wkbSize = geom->WkbSize();
346 
347  if(wkbSize > m_wkbArraySize)
348  {
349  m_wkbArraySize = wkbSize;
350  delete [] m_wkbArray;
351  m_wkbArray = new unsigned char[m_wkbArraySize];
352  }
353 
354  geom->exportToWkb(wkbNDR, m_wkbArray);
355 
356 // 2.5D geometries have a special code!
357  if(geom->getGeometryType() & 0x80000000)
358  {
359  unsigned int newcode = 0x0FFFFFFF & geom->getGeometryType();
360  newcode += 1000;
361  memcpy(m_wkbArray + 1, &newcode, sizeof(unsigned int));
362  }
363 
364  OGRGeometryFactory::destroyGeometry(geom);
365 
366  return (const unsigned char*)m_wkbArray;
367 }
static te::dt::TimeDuration td(20, 30, 50, 11)
std::auto_ptr< te::dt::ByteArray > getByteArray(std::size_t i) const
Method for retrieving a byte array.
Property * getProperty(std::size_t i) const
It returns the i-th property.
Implementation of a DataSet for OGR data provider.
bool isNull(std::size_t i) const
It checks if the attribute value is NULL.
bool moveFirst()
It moves the internal pointer to the first item in the collection.
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
boost::int32_t getInt32(std::size_t i) const
Method for retrieving a 32-bit integer attribute value (4 bytes long).
bool hasGeom() const
It returns true if the DataSetType has at least one geometry property; otherwise, it returns false...
Definition: DataSetType.h:655
DataSet()
Default constructor.
boost::int64_t getInt64(std::size_t i) const
Method for retrieving a 64-bit integer attribute value (8 bytes long).
std::size_t getNumProperties() const
It returns the number of properties that composes an item of the dataset.
bool isAfterEnd() const
It tells if the dataset internal pointer is on the sentinel position after the last element of the co...
bool isBeforeBegin() const
It tells if the dataset internal pointer is in a position before the first element of the collection ...
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
std::string getString(std::size_t i) const
Method for retrieving a string value attribute.
It models a property definition.
Definition: Property.h:59
A class to represent time instant.
Definition: TimeInstant.h:55
std::string getDatasetNameOfProperty(std::size_t pos) const
It returns the underlying dataset name of the property at position pos.
std::auto_ptr< te::rst::Raster > getRaster(std::size_t i) const
Method for retrieving a raster attribute value.
std::size_t size() const
It returns the collection size, if it is known.
bool getBool(std::size_t i) const
Method for retrieving a boolean attribute value.
boost::int16_t getInt16(std::size_t i) const
Method for retrieving a 16-bit integer attribute value (2 bytes long).
An Envelope defines a 2D rectangular region.
A base class for date data types.
Definition: Date.h:53
std::auto_ptr< te::dt::Array > getArray(std::size_t i) const
Method for retrieving an array.
URI C++ Library.
Definition: Attributes.h:37
bool isAtBegin() const
It tells if the dataset internal pointer is on the first element of the collection or not...
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
std::string getPropertyName(std::size_t pos) const
It returns the property name at position pos.
std::string getNumeric(std::size_t i) const
Method for retrieving a numeric attribute value.
bool isEmpty() const
It returns true if the collection is empty.
te::gm::Polygon * p
TERRAMOBILEPLUGINSDLLEXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
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.
std::auto_ptr< te::gm::Envelope > getExtent(std::size_t i)
It computes the bounding rectangle for a spatial property of the dataset.
std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
unsigned char getUChar(std::size_t i) const
Method for retrieving an unsigned character attribute value (1 byte long).
bool isAtEnd() const
It tells if the dataset internal pointer is on the last element of the collection.
te::da::DataSetType * m_dt
DataSetType.
bool movePrevious()
It moves the internal pointer to the previous item of the collection.
int getType() const
It returns the property data type.
Definition: Property.h:161
const unsigned char * getWKB() const
bool moveLast()
It sets the dataset internal pointer to the last item in the collection.
A class to represent time duration with nano-second/micro-second resolution.
Definition: TimeDuration.h:51
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...
int getPropertyDataType(std::size_t pos) const
It returns the underlying data type of the property at position pos.
bool moveNext()
It moves the internal pointer to the next item of the collection.
float getFloat(std::size_t i) const
Method for retrieving a float attribute value.
DateTimeType
The subtype of date and time type, based on ISO 8621.
TERRAMOBILEPLUGINSDLLEXPORT int Convert2TerraLibProjection(OGRSpatialReference *osrs)
It converts the OGR Projection to TerraLib Projection.
void copy(char *data, std::size_t size)
It copies the data from the given pointer to the byte array.
Definition: ByteArray.cpp:128
int m_srid
The SRS id associated to this dataset.
bool move(std::size_t i)
It moves the dataset internal pointer to a given position.
std::auto_ptr< te::dt::DateTime > getDateTime(std::size_t i) const
Method for retrieving a date and time attribute value.
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
double getDouble(std::size_t i) const
Method for retrieving a double attribute value.
char getChar(std::size_t i) const
Method for retrieving a signed character attribute value (1 byte long).
const std::string & getName() const
It returns the property name.
Definition: Property.h:127