All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WKBWriter.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 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/geometry/WKBWriter.cpp
22 
23  \brief A class that serializes a geometry to the WKB format.
24 */
25 
26 // TerraLib
27 #include "../common/ByteSwapUtils.h"
28 #include "../common/Globals.h"
29 #include "../common/Translator.h"
30 #include "Exception.h"
31 #include "GeometryCollection.h"
32 #include "LinearRing.h"
33 #include "MultiLineString.h"
34 #include "MultiPoint.h"
35 #include "MultiPolygon.h"
36 #include "PointM.h"
37 #include "PointZ.h"
38 #include "PointZM.h"
39 #include "Polygon.h"
40 #include "PolyhedralSurface.h"
41 #include "WKBWriter.h"
42 
43 // STL
44 #include <cstring>
45 
46 namespace te
47 {
48  namespace gm
49  {
50 
51  /*!
52  \brief It encodes the line to WKB.
53 
54  This is a special helper function that writes just the number of points in the line and its coordinates.
55  No byte order or geometry type is written to the buffer.
56 
57  \param l The line to be serialized to a wkb.
58  \param nPts The number of points in the line to be encoded in the WKB..
59  \param wkb The buffer to serialize the line number of points and coordinates.
60  \param byteOrder The byte order used to encode the wkb.
61  */
62  inline char* Write2WKB(const LineString& l, unsigned int nPts, char* wkb, te::common::MachineByteOrder byteOrder)
63  {
64  char* aux = wkb;
65 
66  memcpy(wkb, &nPts, 4);
67 
68  wkb += 4; // skip nPts
69 
70  Coord2D* coords = l.getCoordinates();
71 
72  switch(l.getGeomTypeId())
73  {
74  case LineStringType :
75  memcpy(wkb, coords, 16 * nPts);
76  wkb += (16 * nPts);
77  break;
78 
79  case LineStringZType :
80  for(unsigned int i = 0; i < nPts; ++i)
81  {
82  memcpy(wkb, &(coords[i]), 16);
83  memcpy(wkb + 16, &(l.getZ()[i]), 8);
84  wkb += 24;
85  }
86  break;
87 
88  case LineStringMType :
89  for(unsigned int i = 0; i < nPts; ++i)
90  {
91  memcpy(wkb, &(coords[i]), 16);
92  memcpy(wkb + 16, &(l.getM()[i]), 8);
93  wkb += 24;
94  }
95  break;
96 
97  case LineStringZMType :
98  for(unsigned int i = 0; i < nPts; ++i)
99  {
100  memcpy(wkb, &(coords[i]), 16);
101  memcpy(wkb + 16, &(l.getZ()[i]), 8);
102  memcpy(wkb + 24, &(l.getM()[i]), 8);
103  wkb += 32;
104  }
105  break;
106 
107  default:
108  throw Exception(TR_GEOM("Invalid geometry type to encode to a WKB!"));
109  }
110 
112  {
114 
115  aux += 4;
116 
117  int dim = 2;
118 
119  if(l.getZ())
120  ++dim;
121 
122  if(l.getM())
123  ++dim;
124 
125  std::size_t nStep = nPts * dim;
126 
127  for(std::size_t i = 0; i < nStep; ++i)
128  {
130  aux += 8;
131  }
132  }
133 
134  return wkb;
135  }
136  } // end namespace gm
137 } // end namespace te
138 
140  : m_wkb(wkb),
141  m_byteOrder(byteOrder)
142 {
143 }
144 
146 {
147 }
148 
150 {
151  geom->accept(*this);
152 }
153 
154 void te::gm::WKBWriter::write(const Geometry* geom, char* wkb, te::common::MachineByteOrder byteOrder)
155 {
156  WKBWriter w(wkb, byteOrder);
157 
158  geom->accept(w);
159 }
160 
162 {
163  m_wkb = wkb;
164  m_byteOrder = byteOrder;
165 }
166 
168 {
169  memcpy(m_wkb, &m_byteOrder, 1);
170 
171  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
172  unsigned int nGeoms = static_cast<unsigned int>(visited.getNumGeometries()); // please, don't swap this value!
173  unsigned int nGeomsAux = nGeoms;
174 
176  {
177  te::common::SwapBytes(nGeomsAux);
178  te::common::SwapBytes(gType);
179  }
180 
181  memcpy(m_wkb + 1, &gType, 4);
182  memcpy(m_wkb + 5, &nGeomsAux, 4);
183 
184  m_wkb += 9;
185 
186  for(unsigned int i = 0; i < nGeoms; ++i)
187  visited.getGeometryN(i)->accept(*this);
188 }
189 
191 {
192  m_wkb = Write2WKB(visited, static_cast<unsigned int>(visited.size()), m_wkb, m_byteOrder);
193 }
194 
195 void te::gm::WKBWriter::visit(const LineString & visited)
196 {
197  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
198  unsigned int nPts = static_cast<unsigned int>(visited.size());
199 
200  memcpy(m_wkb, &m_byteOrder, 1);
201  memcpy(m_wkb + 1, &gType, 4);
202 
204  te::common::Swap4Bytes(m_wkb + 1);
205 
206  m_wkb = Write2WKB(visited, nPts, m_wkb + 5, m_byteOrder);
207 }
208 
210 {
211  visit((const GeometryCollection&)visited);
212 }
213 
215 {
216  visit((const GeometryCollection&)visited);
217 }
218 
220 {
221  visit((const GeometryCollection&)visited);
222 }
223 
224 void te::gm::WKBWriter::visit(const Point& visited)
225 {
226  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
227 
228  memcpy(m_wkb, &m_byteOrder, 1);
229  memcpy(m_wkb + 1, &gType, 4);
230  memcpy(m_wkb + 5, &(visited.getX()), 8);
231  memcpy(m_wkb + 13, &(visited.getY()), 8);
232 
234  {
235  te::common::Swap4Bytes(m_wkb + 1);
236  te::common::Swap8Bytes(m_wkb + 5);
237  te::common::Swap8Bytes(m_wkb + 13);
238  }
239 
240  m_wkb += 21;
241 }
242 
243 void te::gm::WKBWriter::visit(const PointM& visited)
244 {
245  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
246 
247  memcpy(m_wkb, &m_byteOrder, 1);
248  memcpy(m_wkb + 1, &gType, 4);
249  memcpy(m_wkb + 5, &(visited.getX()), 8);
250  memcpy(m_wkb + 13, &(visited.getY()), 8);
251  memcpy(m_wkb + 21, &(visited.getM()), 8);
252 
254  {
255  te::common::Swap4Bytes(m_wkb + 1);
256  te::common::Swap8Bytes(m_wkb + 5);
257  te::common::Swap8Bytes(m_wkb + 13);
258  te::common::Swap8Bytes(m_wkb + 21);
259  }
260 
261  m_wkb += 29;
262 }
263 
264 void te::gm::WKBWriter::visit(const PointZ& visited)
265 {
266  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
267 
268  memcpy(m_wkb, &m_byteOrder, 1);
269  memcpy(m_wkb + 1, &gType, 4);
270  memcpy(m_wkb + 5, &(visited.getX()), 8);
271  memcpy(m_wkb + 13, &(visited.getY()), 8);
272  memcpy(m_wkb + 21, &(visited.getZ()), 8);
273 
275  {
276  te::common::Swap4Bytes(m_wkb + 1);
277  te::common::Swap8Bytes(m_wkb + 5);
278  te::common::Swap8Bytes(m_wkb + 13);
279  te::common::Swap8Bytes(m_wkb + 21);
280  }
281 
282  m_wkb += 29;
283 }
284 
285 void te::gm::WKBWriter::visit(const PointZM& visited)
286 {
287  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
288 
289  memcpy(m_wkb, &m_byteOrder, 1);
290  memcpy(m_wkb + 1, &gType, 4);
291  memcpy(m_wkb + 5, &(visited.getX()), 8);
292  memcpy(m_wkb + 13, &(visited.getY()), 8);
293  memcpy(m_wkb + 21, &(visited.getZ()), 8);
294  memcpy(m_wkb + 29, &(visited.getM()), 8);
295 
297  {
298  te::common::Swap4Bytes(m_wkb + 1);
299  te::common::Swap8Bytes(m_wkb + 5);
300  te::common::Swap8Bytes(m_wkb + 13);
301  te::common::Swap8Bytes(m_wkb + 21);
302  te::common::Swap8Bytes(m_wkb + 29);
303  }
304 
305  m_wkb += 37;
306 }
307 
308 void te::gm::WKBWriter::visit(const Polygon& visited)
309 {
310  unsigned int nRings = static_cast<unsigned int>(visited.getNumRings());
311  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
312 
313  memcpy(m_wkb, &m_byteOrder, 1);
314  memcpy(m_wkb + 1, &gType, 4);
315  memcpy(m_wkb + 5, &nRings, 4);
316 
318  {
319  te::common::Swap4Bytes(m_wkb + 1);
320  te::common::Swap4Bytes(m_wkb + 5);
321  }
322 
323  m_wkb += 9;
324 
325  for(unsigned int i = 0; i < nRings; ++i)
326  visited.getRingN(i)->accept(*this);
327 }
328 
330 {
331  unsigned int nPols = static_cast<unsigned int>(visited.getNumPatches());
332  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
333 
334  memcpy(m_wkb, &m_byteOrder, 1);
335  memcpy(m_wkb + 1, &gType, 4);
336  memcpy(m_wkb + 5, &nPols, 4);
337 
339  {
340  te::common::Swap4Bytes(m_wkb + 1);
341  te::common::Swap4Bytes(m_wkb + 5);
342  }
343 
344  m_wkb += 9;
345 
346  for(unsigned int i = 0; i < nPols; ++i)
347  visited.getPatchN(i)->accept(*this);
348 }
349 
350 void te::gm::WKBWriter::visit(const TIN& visited)
351 {
352  visit((const PolyhedralSurface&)visited);
353 }
354 
355 void te::gm::WKBWriter::visit(const Triangle& visited)
356 {
357  visit((const Polygon&)visited);
358 }
359 
MultiLineString is a MultiCurve whose elements are LineStrings.
PolyhedralSurface is a contiguous collection of polygons, which share common boundary segments...
A class that serializes a geometry to the WKB format.
Definition: WKBWriter.h:46
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
std::size_t getNumPatches() const
It returns the number of including polygons.
void Swap8Bytes(char *v)
It swaps an array of eight bytes in local.
WKBWriter(char *wkb, te::common::MachineByteOrder byteOrder=te::common::NDR)
It constructs a new WKB writer.
Definition: WKBWriter.cpp:139
Polygon * getPatchN(std::size_t i) const
It returns a polygon in this surface, the order is arbitrary.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
A point with z-coordinate value.
Definition: PointZ.h:51
void Swap4Bytes(T &v)
It swaps four bytes in local.
Definition: ByteSwapUtils.h:82
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
std::size_t getNumRings() const
It returns the number of rings in this CurvePolygon.
Definition: CurvePolygon.h:153
TIN (triangulated irregular network) is a PolyhedralSurface consisting only of Triangle patches...
Definition: TIN.h:50
A class that serializes a geometry to the WKB format.
An exception class for the Geometry module.
std::size_t size() const
It returns the number of points (vertexes) in the geometry.
Definition: LineString.h:262
A LinearRing is a LineString that is both closed and simple.
#define TR_GEOM(message)
It marks a string in order to get translated. This is a special mark used in the Vector Geometry modu...
Definition: Config.h:58
It is a collection of other geometric objects.
A point with z-coordinate value.
MultiPoint is a GeometryCollection whose elements are restricted to points.
A point with a z-coordinate value and an associated measurement.
Definition: PointZM.h:51
const double & getZ(std::size_t i) const
It returns the n-th z coordinate value.
Definition: LineString.cpp:357
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
void SwapBytes(T &v)
It swaps the bytes in local.
void visit(const Curve &)
Definition: WKBWriter.h:93
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:136
void write(const Geometry *geom)
It serializes the geometry to a WKB representation into the specified buffer.
Definition: WKBWriter.cpp:149
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
Definition: Globals.h:55
const double & getZ() const
It returns the Point z-coordinate value.
Definition: PointZ.h:138
const double & getM() const
It returns the Point z-coordinate value.
Definition: PointM.h:160
void reset(char *wkb, te::common::MachineByteOrder byteOrder=te::common::NDR)
It resets the WKB writer an allows a new geometry to be seriealized to a new buffer.
Definition: WKBWriter.cpp:161
MachineByteOrder
Endianness.
Definition: Enums.h:116
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
char * Write2WKB(const LineString &l, unsigned int nPts, char *wkb, te::common::MachineByteOrder byteOrder)
It encodes the line to WKB.
Definition: WKBWriter.cpp:62
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
A point with x and y coordinate values.
Definition: Point.h:50
const double & getM(std::size_t i) const
It returns the n-th m measure value.
Definition: LineString.cpp:363
A point with an associated measure.
Definition: PointM.h:51
A point with a z-coordinate value and an associated measurement.
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
It is a collection of other geometric objects.
PolyhedralSurface is a contiguous collection of polygons, which share common boundary segments...
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
MultiPolygon is a MultiSurface whose elements are Polygons.
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
Triangle is a polygon with 3 distinct, non-collinear vertices and no interior boundary.
Definition: Triangle.h:50
const double & getM() const
It returns the Point z-coordinate value.
Definition: PointZM.h:174
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:150
~WKBWriter()
Destructor.
Definition: WKBWriter.cpp:145
const double & getZ() const
It returns the Point z-coordinate value.
Definition: PointZM.h:160
A point with an associated measure.
MultiLineString is a MultiCurve whose elements are LineStrings.
Curve * getRingN(std::size_t i) const
It returns the n-th ring for this curve polygon as a curve.
Definition: CurvePolygon.h:193