All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
EWKBWriter.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/sqlite/EWKBWriter.cpp
22 
23  \brief A class that serializes a geometry to the SpatiaLite EWKB format.
24 */
25 
26 // TerraLib
27 #include "../common/ByteSwapUtils.h"
28 #include "../common/Globals.h"
29 #include "../common/Translator.h"
30 #include "../dataaccess/Exception.h"
31 #include "../geometry/Envelope.h"
32 #include "../geometry/GeometryCollection.h"
33 #include "../geometry/LinearRing.h"
34 #include "../geometry/LineString.h"
35 #include "../geometry/MultiLineString.h"
36 #include "../geometry/MultiPoint.h"
37 #include "../geometry/MultiPolygon.h"
38 #include "../geometry/PointM.h"
39 #include "../geometry/PointZ.h"
40 #include "../geometry/PointZM.h"
41 #include "../geometry/Polygon.h"
42 #include "EWKBWriter.h"
43 
44 // STL
45 #include <cstring>
46 
47 // SQLite
48 #include <sqlite3.h>
49 
50 #ifdef TE_ENABLE_SPATIALITE
51 // SpatiaLite
52 #include <spatialite/gaiageo.h>
53 
54 namespace te
55 {
56  namespace sqlite
57  {
58 
59  inline unsigned char* Write2WKB(const te::gm::LineString& l, unsigned int nPts, unsigned char* ewkb, te::common::MachineByteOrder byteOrder)
60  {
61  char* aux = (char*)ewkb;
62 
63  memcpy(ewkb, &nPts, 4);
64 
65  ewkb += 4;
66 
67  te::gm::Coord2D* coords = l.getCoordinates();
68 
69  switch(l.getGeomTypeId())
70  {
72  memcpy(ewkb, coords, 16 * nPts);
73  ewkb += (16 * nPts);
74  break;
75 
77  for(unsigned int i = 0; i < nPts; ++i)
78  {
79  memcpy(ewkb, &(coords[i]), 16);
80  memcpy(ewkb + 16, &(l.getZ()[i]), 8);
81  ewkb += 24;
82  }
83  break;
84 
86  for(unsigned int i = 0; i < nPts; ++i)
87  {
88  memcpy(ewkb, &(coords[i]), 16);
89  memcpy(ewkb + 16, &(l.getM()[i]), 8);
90  ewkb += 24;
91  }
92  break;
93 
95  for(unsigned int i = 0; i < nPts; ++i)
96  {
97  memcpy(ewkb, &(coords[i]), 16);
98  memcpy(ewkb + 16, &(l.getZ()[i]), 8);
99  memcpy(ewkb + 24, &(l.getM()[i]), 8);
100  ewkb += 32;
101  }
102  break;
103 
104  default:
105  throw te::da::Exception(TR_COMMON("Invalid geometry type to encode to a SpatiaLIte EWKB!"));
106  }
107 
109  {
111 
112  aux += 4;
113 
114  int dim = 2;
115 
116  if(l.getZ())
117  ++dim;
118 
119  if(l.getM())
120  ++dim;
121 
122  std::size_t nStep = nPts * dim;
123 
124  for(std::size_t i = 0; i < nStep; ++i)
125  {
127  aux += 8;
128  }
129  }
130 
131  return ewkb;
132  }
133 
134  } // end namespace sqlite
135 } // end namespace te
136 
137 te::sqlite::EWKBWriter::EWKBWriter(unsigned char* ewkb, te::common::MachineByteOrder byteOrder)
138  : m_ewkb(ewkb),
139  m_byteOrder(byteOrder)
140 {
141 }
142 
143 te::sqlite::EWKBWriter::~EWKBWriter()
144 {
145 }
146 
147 void te::sqlite::EWKBWriter::write(const te::gm::Geometry* geom)
148 {
149  m_ewkb[0] = GAIA_MARK_START;
150 
151  m_ewkb[1] = GAIA_LITTLE_ENDIAN;
152 
153  int srid = geom->getSRID();
154 
155  te::gm::Envelope mbr(*(geom->getMBR()));
156 
158  {
159  te::common::SwapBytes(srid);
160  te::common::SwapBytes(mbr.m_llx);
161  te::common::SwapBytes(mbr.m_lly);
162  te::common::SwapBytes(mbr.m_urx);
163  te::common::SwapBytes(mbr.m_ury);
164  }
165 
166  *((int*)(m_ewkb + 2)) = srid;
167 
168  *((double*)(m_ewkb + 6)) = mbr.m_llx;
169  *((double*)(m_ewkb + 14)) = mbr.m_lly;
170  *((double*)(m_ewkb + 22)) = mbr.m_urx;
171  *((double*)(m_ewkb + 30)) = mbr.m_ury;
172 
173  m_ewkb[38] = GAIA_MARK_MBR;
174 
175  m_ewkb += 39;
176 
177  geom->accept(*this);
178 
179  m_ewkb[0] = GAIA_MARK_END;
180 }
181 
182 void te::sqlite::EWKBWriter::write(const te::gm::Geometry* geom, unsigned char* ewkb, te::common::MachineByteOrder byteOrder)
183 {
184  EWKBWriter w(ewkb, byteOrder);
185 
186  w.write(geom);
187 }
188 
189 void te::sqlite::EWKBWriter::reset(unsigned char* ewkb, te::common::MachineByteOrder byteOrder)
190 {
191  m_ewkb = ewkb;
192  m_byteOrder = byteOrder;
193 }
194 
195 void te::sqlite::EWKBWriter::visit(const te::gm::GeometryCollection& visited)
196 {
197  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
198  unsigned int nGeoms = static_cast<unsigned int>(visited.getNumGeometries());
199  unsigned int nGeomsAux = nGeoms;
200 
202  {
203  te::common::SwapBytes(nGeomsAux);
204  te::common::SwapBytes(gType);
205  }
206 
207  memcpy(m_ewkb, &gType, 4);
208  memcpy(m_ewkb + 4, &nGeomsAux, 4);
209 
210  m_ewkb += 8;
211 
212  for(unsigned int i = 0; i < nGeoms; ++i)
213  {
214  m_ewkb[0] = GAIA_MARK_ENTITY;
215 
216  m_ewkb += 1;
217 
218  visited.getGeometryN(i)->accept(*this);
219  }
220 }
221 
222 void te::sqlite::EWKBWriter::visit(const te::gm::LinearRing& visited)
223 {
224  m_ewkb = Write2WKB(visited, static_cast<unsigned int>(visited.size()), m_ewkb, m_byteOrder);
225 }
226 
227 void te::sqlite::EWKBWriter::visit(const te::gm::LineString & visited)
228 {
229  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
230  unsigned int nPts = static_cast<unsigned int>(visited.size());
231 
233  te::common::Swap4Bytes(gType);
234 
235  memcpy(m_ewkb, &gType, 4);
236 
237  m_ewkb = Write2WKB(visited, nPts, m_ewkb + 4, m_byteOrder);
238 }
239 
240 void te::sqlite::EWKBWriter::visit(const te::gm:: MultiLineString& visited)
241 {
242  visit((const te::gm::GeometryCollection&)visited);
243 }
244 
245 void te::sqlite::EWKBWriter::visit(const te::gm::MultiPoint& visited)
246 {
247  visit((const te::gm::GeometryCollection&)visited);
248 }
249 
250 void te::sqlite::EWKBWriter::visit(const te::gm::MultiPolygon& visited)
251 {
252  visit((const te::gm::GeometryCollection&)visited);
253 }
254 
255 void te::sqlite::EWKBWriter::visit(const te::gm::Point& visited)
256 {
257  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
258 
259  double x = visited.getX();
260  double y = visited.getY();
261 
263  {
264  te::common::SwapBytes(gType);
267  }
268 
269  memcpy(m_ewkb, &gType, 4);
270  memcpy(m_ewkb + 4, &x, 8);
271  memcpy(m_ewkb + 12, &y, 8);
272 
273  m_ewkb += 20;
274 }
275 
276 void te::sqlite::EWKBWriter::visit(const te::gm::PointM& visited)
277 {
278  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
279 
280  double x = visited.getX();
281  double y = visited.getY();
282  double m = visited.getM();
283 
285  {
286  te::common::SwapBytes(gType);
290  }
291 
292  memcpy(m_ewkb, &gType, 4);
293  memcpy(m_ewkb + 4, &x, 8);
294  memcpy(m_ewkb + 12, &y, 8);
295  memcpy(m_ewkb + 20, &m, 8);
296 
297  m_ewkb += 28;
298 }
299 
300 void te::sqlite::EWKBWriter::visit(const te::gm::PointZ& visited)
301 {
302  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
303 
304  double x = visited.getX();
305  double y = visited.getY();
306  double z = visited.getZ();
307 
309  {
310  te::common::SwapBytes(gType);
314  }
315 
316  memcpy(m_ewkb, &gType, 4);
317  memcpy(m_ewkb + 4, &x, 8);
318  memcpy(m_ewkb + 12, &y, 8);
319  memcpy(m_ewkb + 20, &z, 8);
320 
321  m_ewkb += 28;
322 }
323 
324 void te::sqlite::EWKBWriter::visit(const te::gm::PointZM& visited)
325 {
326  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
327 
328  double x = visited.getX();
329  double y = visited.getY();
330  double z = visited.getZ();
331  double m = visited.getM();
332 
334  {
335  te::common::SwapBytes(gType);
340  }
341 
342  memcpy(m_ewkb, &gType, 4);
343  memcpy(m_ewkb + 4, &x, 8);
344  memcpy(m_ewkb + 12, &y, 8);
345  memcpy(m_ewkb + 20, &z, 8);
346  memcpy(m_ewkb + 28, &m, 8);
347 
348  m_ewkb += 36;
349 }
350 
351 void te::sqlite::EWKBWriter::visit(const te::gm::Polygon& visited)
352 {
353  unsigned int nRings = static_cast<unsigned int>(visited.getNumRings());
354  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
355 
357  {
358  te::common::SwapBytes(nRings);
359  te::common::SwapBytes(gType);
360  }
361 
362  memcpy(m_ewkb, &gType, 4);
363  memcpy(m_ewkb + 4, &nRings, 4);
364 
365  m_ewkb += 8;
366 
367  for(unsigned int i = 0; i < nRings; ++i)
368  visited.getRingN(i)->accept(*this);
369 }
370 
371 #endif // TE_ENABLE_SPATIALITE
372 
std::size_t getNumRings() const
It returns the number of rings in this CurvePolygon.
Definition: CurvePolygon.h:153
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
int getSRID() const
It returns the Spatial Reference System ID associated to this geometric object.
Definition: Geometry.h:189
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
void Swap8Bytes(char *v)
It swaps an array of eight bytes in local.
char * Write2WKB(const LineString &l, unsigned int nPts, char *wkb, te::common::MachineByteOrder byteOrder)
It encodes the line to WKB.
Definition: WKBWriter.cpp:62
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
Definition: Globals.h:54
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
A point with a z-coordinate value and an associated measurement.
Definition: PointZM.h:51
A point with an associated measure.
Definition: PointM.h:51
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
A point with z-coordinate value.
Definition: PointZ.h:51
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:150
A point with x and y coordinate values.
Definition: Point.h:50
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
void Swap4Bytes(T &v)
It swaps four bytes in local.
Definition: ByteSwapUtils.h:82
const double & getZ() const
It returns the Point z-coordinate value.
Definition: PointZM.h:160
const double & getM() const
It returns the Point z-coordinate value.
Definition: PointM.h:160
MachineByteOrder
Endianness.
Definition: Enums.h:116
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
A class that serializes a geometry to the SpatiaLite EWKB format.
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
MultiLineString is a MultiCurve whose elements are LineStrings.
const double & getZ() const
It returns the Point z-coordinate value.
Definition: PointZ.h:138
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
const double & getM() const
It returns the Point z-coordinate value.
Definition: PointZM.h:174
const double & getZ(std::size_t i) const
It returns the n-th z coordinate value.
Definition: LineString.cpp:397
const double & getM(std::size_t i) const
It returns the n-th m measure value.
Definition: LineString.cpp:403
It is a collection of other geometric objects.
const Envelope * getMBR() const
It returns the minimum bounding rectangle for the geometry in an internal representation.
Definition: Geometry.cpp:104
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:136
void SwapBytes(T &v)
It swaps the bytes in local.
Curve * getRingN(std::size_t i) const
It returns the n-th ring for this curve polygon as a curve.
Definition: CurvePolygon.h:193
std::size_t size() const
It returns the number of points (vertexes) in the geometry.
Definition: LineString.h:262