All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 "../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(TE_TR("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 
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
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:139
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
void Swap8Bytes(char *v)
It swaps an array of eight bytes in local.
~WKBWriter()
Destructor.
Definition: WKBWriter.cpp:145
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: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
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
PolyhedralSurface is a contiguous collection of polygons, which share common boundary segments...
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
void write(const Geometry *geom)
It serializes the geometry to a WKB representation into the specified buffer.
Definition: WKBWriter.cpp:149
A class that serializes a geometry to the WKB format.
A point with an associated measure.
Definition: PointM.h:51
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
A point with z-coordinate value.
Definition: PointZ.h:51
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:150
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.
const double & getZ() const
It returns the Point z-coordinate value.
Definition: PointZM.h:160
MultiPolygon is a MultiSurface whose elements are Polygons.
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
An exception class for the Geometry module.
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.
MultiLineString is a MultiCurve whose elements are LineStrings.
const double & getZ() const
It returns the Point z-coordinate value.
Definition: PointZ.h:138
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
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
void visit(const Curve &)
Definition: WKBWriter.h:93
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.
A point with z-coordinate value.
A point with a z-coordinate value and an associated measurement.
A point with an associated measure.
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.
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