WKBWriter.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/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 "../core/translator/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 "Point.h"
37 #include "Polygon.h"
38 #include "PolyhedralSurface.h"
39 #include "WKBWriter.h"
40 
41 // STL
42 #include <cstring>
43 
44 namespace te
45 {
46  namespace gm
47  {
48 
49  /*!
50  \brief It encodes the line to WKB.
51 
52  This is a special helper function that writes just the number of points in the line and its coordinates.
53  No byte order or geometry type is written to the buffer.
54 
55  \param l The line to be serialized to a wkb.
56  \param nPts The number of points in the line to be encoded in the WKB..
57  \param wkb The buffer to serialize the line number of points and coordinates.
58  \param byteOrder The byte order used to encode the wkb.
59  */
60  inline char* Write2WKB(const LineString& l, unsigned int nPts, char* wkb, te::common::MachineByteOrder byteOrder)
61  {
62  char* aux = wkb;
63 
64  memcpy(wkb, &nPts, 4);
65 
66  wkb += 4; // skip nPts
67 
68  Coord2D* coords = l.getCoordinates();
69 
70  switch(l.getGeomTypeId())
71  {
72  case LineStringType :
73  memcpy(wkb, coords, 16 * nPts);
74  wkb += (16 * nPts);
75  break;
76 
77  case LineStringZType :
78  for(unsigned int i = 0; i < nPts; ++i)
79  {
80  memcpy(wkb, &(coords[i]), 16);
81  memcpy(wkb + 16, &(l.getZ()[i]), 8);
82  wkb += 24;
83  }
84  break;
85 
86  case LineStringMType :
87  for(unsigned int i = 0; i < nPts; ++i)
88  {
89  memcpy(wkb, &(coords[i]), 16);
90  memcpy(wkb + 16, &(l.getM()[i]), 8);
91  wkb += 24;
92  }
93  break;
94 
95  case LineStringZMType :
96  for(unsigned int i = 0; i < nPts; ++i)
97  {
98  memcpy(wkb, &(coords[i]), 16);
99  memcpy(wkb + 16, &(l.getZ()[i]), 8);
100  memcpy(wkb + 24, &(l.getM()[i]), 8);
101  wkb += 32;
102  }
103  break;
104 
105  default:
106  throw Exception(TE_TR("Invalid geometry type to encode to a WKB!"));
107  }
108 
110  {
112 
113  aux += 4;
114 
115  int dim = 2;
116 
117  if(l.getZ())
118  ++dim;
119 
120  if(l.getM())
121  ++dim;
122 
123  std::size_t nStep = nPts * dim;
124 
125  for(std::size_t i = 0; i < nStep; ++i)
126  {
128  aux += 8;
129  }
130  }
131 
132  return wkb;
133  }
134  } // end namespace gm
135 } // end namespace te
136 
138  : m_wkb(wkb),
139  m_byteOrder(byteOrder)
140 {
141 }
142 
144 
146 {
147  geom->accept(*this);
148 }
149 
150 void te::gm::WKBWriter::write(const Geometry* geom, char* wkb, te::common::MachineByteOrder byteOrder)
151 {
152  WKBWriter w(wkb, byteOrder);
153 
154  geom->accept(w);
155 }
156 
158 {
159  m_wkb = wkb;
160  m_byteOrder = byteOrder;
161 }
162 
164 {
165  memcpy(m_wkb, &m_byteOrder, 1);
166 
167  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
168  unsigned int nGeoms = static_cast<unsigned int>(visited.getNumGeometries()); // please, don't swap this value!
169  unsigned int nGeomsAux = nGeoms;
170 
172  {
173  te::common::SwapBytes(nGeomsAux);
174  te::common::SwapBytes(gType);
175  }
176 
177  memcpy(m_wkb + 1, &gType, 4);
178  memcpy(m_wkb + 5, &nGeomsAux, 4);
179 
180  m_wkb += 9;
181 
182  for(unsigned int i = 0; i < nGeoms; ++i)
183  visited.getGeometryN(i)->accept(*this);
184 }
185 
187 {
188  m_wkb = Write2WKB(visited, static_cast<unsigned int>(visited.size()), m_wkb, m_byteOrder);
189 }
190 
191 void te::gm::WKBWriter::visit(const LineString & visited)
192 {
193  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
194  unsigned int nPts = static_cast<unsigned int>(visited.size());
195 
196  memcpy(m_wkb, &m_byteOrder, 1);
197  memcpy(m_wkb + 1, &gType, 4);
198 
201 
202  m_wkb = Write2WKB(visited, nPts, m_wkb + 5, m_byteOrder);
203 }
204 
206 {
207  visit((const GeometryCollection&)visited);
208 }
209 
211 {
212  visit((const GeometryCollection&)visited);
213 }
214 
216 {
217  visit((const GeometryCollection&)visited);
218 }
219 
220 void te::gm::WKBWriter::visit(const Point& visited)
221 {
222  switch (visited.getGeomTypeId())
223  {
224  case (PointType) :
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  {
238  }
239 
240  m_wkb += 21;
241 
242  break;
243  }
244  case(PointMType) :
245  {
246  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
247 
248  memcpy(m_wkb, &m_byteOrder, 1);
249  memcpy(m_wkb + 1, &gType, 4);
250  memcpy(m_wkb + 5, &(visited.getX()), 8);
251  memcpy(m_wkb + 13, &(visited.getY()), 8);
252  memcpy(m_wkb + 21, &(visited.getM()), 8);
253 
255  {
260  }
261 
262  m_wkb += 29;
263 
264  break;
265  }
266  case(PointZType):
267  {
268  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
269 
270  memcpy(m_wkb, &m_byteOrder, 1);
271  memcpy(m_wkb + 1, &gType, 4);
272  memcpy(m_wkb + 5, &(visited.getX()), 8);
273  memcpy(m_wkb + 13, &(visited.getY()), 8);
274  memcpy(m_wkb + 21, &(visited.getZ()), 8);
275 
277  {
282  }
283 
284  m_wkb += 29;
285 
286  break;
287  }
288  default: //zm
289  {
290  assert(visited.getGeomTypeId() == te::gm::PointZMType);
291  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
292 
293  memcpy(m_wkb, &m_byteOrder, 1);
294  memcpy(m_wkb + 1, &gType, 4);
295  memcpy(m_wkb + 5, &(visited.getX()), 8);
296  memcpy(m_wkb + 13, &(visited.getY()), 8);
297  memcpy(m_wkb + 21, &(visited.getZ()), 8);
298  memcpy(m_wkb + 29, &(visited.getM()), 8);
299 
301  {
307  }
308 
309  m_wkb += 37;
310 
311  break;
312  }
313  }
314 }
315 
316 void te::gm::WKBWriter::visit(const Polygon& visited)
317 {
318  unsigned int nRings = static_cast<unsigned int>(visited.getNumRings());
319  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
320 
321  memcpy(m_wkb, &m_byteOrder, 1);
322  memcpy(m_wkb + 1, &gType, 4);
323  memcpy(m_wkb + 5, &nRings, 4);
324 
326  {
329  }
330 
331  m_wkb += 9;
332 
333  for(unsigned int i = 0; i < nRings; ++i)
334  visited.getRingN(i)->accept(*this);
335 }
336 
338 {
339  unsigned int nPols = static_cast<unsigned int>(visited.getNumPatches());
340  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
341 
342  memcpy(m_wkb, &m_byteOrder, 1);
343  memcpy(m_wkb + 1, &gType, 4);
344  memcpy(m_wkb + 5, &nPols, 4);
345 
347  {
350  }
351 
352  m_wkb += 9;
353 
354  for(unsigned int i = 0; i < nPols; ++i)
355  visited.getPatchN(i)->accept(*this);
356 }
357 
358 void te::gm::WKBWriter::visit(const TIN& visited)
359 {
360  visit((const PolyhedralSurface&)visited);
361 }
362 
363 void te::gm::WKBWriter::visit(const Triangle& visited)
364 {
365  visit((const Polygon&)visited);
366 }
367 
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:157
PolyhedralSurface is a contiguous collection of polygons, which share common boundary segments...
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.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
WKBWriter(char *wkb, te::common::MachineByteOrder byteOrder=te::common::NDR)
It constructs a new WKB writer.
Definition: WKBWriter.cpp:137
A LinearRing is a LineString that is both closed and simple.
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
Base exception class for plugin module.
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
void Swap8Bytes(char *v)
It swaps an array of eight bytes in local.
~WKBWriter()
Destructor.
A point with x and y coordinate values.
Polygon * getPatchN(std::size_t i) const
It returns a polygon in this surface, the order is arbitrary.
char * Write2WKB(const LineString &l, unsigned int nPts, char *wkb, te::common::MachineByteOrder byteOrder)
It encodes the line to WKB.
Definition: WKBWriter.cpp:60
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
PolyhedralSurface is a contiguous collection of polygons, which share common boundary segments...
MultiPoint is a GeometryCollection whose elements are restricted to points.
void write(const Geometry *geom)
It serializes the geometry to a WKB representation into the specified buffer.
Definition: WKBWriter.cpp:145
A class that serializes a geometry to the WKB format.
TIN (triangulated irregular network) is a PolyhedralSurface consisting only of Triangle patches...
Definition: TIN.h:50
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
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
Triangle is a polygon with 3 distinct, non-collinear vertices and no interior boundary.
Definition: Triangle.h:50
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:152
A point with x and y coordinate values.
Definition: Point.h:50
void Swap4Bytes(T &v)
It swaps four bytes in local.
Definition: ByteSwapUtils.h:82
MultiLineString is a MultiCurve whose elements are LineStrings.
URI C++ Library.
Definition: Attributes.h:37
MultiPolygon is a MultiSurface whose elements are Polygons.
MachineByteOrder
Endianness.
const double & getZ() const
It returns the Point z-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:166
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
te::common::MachineByteOrder m_byteOrder
The byte order used to encode the WKB.
Definition: WKBWriter.h:116
MultiLineString is a MultiCurve whose elements are LineStrings.
A class that serializes a geometry to the WKB format.
Definition: WKBWriter.h:46
std::size_t getNumPatches() const
It returns the number of including polygons.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
void visit(const Curve &)
Definition: WKBWriter.h:93
const double & getM() const
It returns the Point m-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:180
const double & getZ(std::size_t i) const
It returns the n-th z coordinate value.
const double & getM(std::size_t i) const
It returns the n-th m measure value.
It is a collection of other geometric objects.
char * m_wkb
A pointer that marks the current position in a buffer to be write when parsing the geometry...
Definition: WKBWriter.h:115
An exception class for the Geometry module.
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
void SwapBytes(T &v)
It swaps the bytes in local.
It is a collection of other geometric objects.
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