All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EWKBWriter.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/postgis/EWKBWriter.cpp
22 
23  \brief An utility class for writing a PostGIS EWKB.
24 */
25 
26 // TerraLib
27 #include "../common/ByteSwapUtils.h"
28 #include "../common/Globals.h"
29 #include "../geometry.h"
30 #include "EWKBWriter.h"
31 #include "Utils.h"
32 
33 // STL
34 #include <cassert>
35 #include <cstring>
36 #include <typeinfo>
37 
38 inline char* Write2EWKB(char* ewkb, const te::gm::LineString* l)
39 {
40  unsigned int nPts = static_cast<unsigned int>(l->getNPoints());
41  te::gm::Coord2D* coords = l->getCoordinates();
42  double* zA = l->getZ();
43  double* mA = l->getM();
44 
45  memcpy(ewkb, &nPts, 4);
46  ewkb += 4;
47 
48  switch(l->getGeomTypeId())
49  {
51  memcpy(ewkb, coords, 16 * nPts);
52  ewkb += (nPts * 16);
53  break;
54 
56  for(size_t i = 0; i < nPts; ++i)
57  {
58  memcpy(ewkb, &(coords[i]), 16);
59  memcpy(ewkb + 16, &(zA[i]), 8);
60  ewkb += 24;
61  }
62  break;
63 
65  for(size_t i = 0; i < nPts; ++i)
66  {
67  memcpy(ewkb, &(coords[i]), 16);
68  memcpy(ewkb + 16, &(mA[i]), 8);
69  ewkb += 24;
70  }
71  break;
72 
74  for(size_t i = 0; i < nPts; ++i)
75  {
76  memcpy(ewkb, &(coords[i]), 16);
77  memcpy(ewkb + 16, &(zA[i]), 8);
78  memcpy(ewkb + 24, &(mA[i]), 8);
79  ewkb += 32;
80  }
81  break;
82 
83  default:
84  assert(false);
85  break;
86  }
87 
88  return ewkb;
89 }
90 
92  : m_ewkb(ewkb),
93  m_byteOrder(byteOrder),
94  m_outputSRID(true)
95 {
96 // ewkb must be at least = g->getWkbSize() + 4
97 }
98 
100 {
101 }
102 
104 {
105  geom->accept(*this);
106 }
107 
109 {
110  EWKBWriter w(wkb, byteOrder);
111 
112  geom->accept(w);
113 }
114 
116 {
117  m_ewkb = ewkb;
118  m_byteOrder = byteOrder;
119  m_outputSRID = true;
120 }
121 
123 {
124  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
125 
126  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
127  unsigned int nGeoms = static_cast<unsigned int>(visited.getNumGeometries());
128  int srid = visited.getSRID();
129 
130  Convert2PostGISWKBType(gType);
131 
132  if(m_outputSRID)
133  {
134  gType |= TE_EWKB_SRID_FLAG;
135 
136  memcpy(m_ewkb + 1, &gType, 4);
137  memcpy(m_ewkb + 5, &srid, 4);
138  memcpy(m_ewkb + 9, &nGeoms, 4);
139 
140  m_ewkb += 13;
141 
142  m_outputSRID = false;
143  }
144  else
145  {
146  memcpy(m_ewkb + 1, &gType, 4);
147  memcpy(m_ewkb + 5, &nGeoms, 4);
148  m_ewkb += 9;
149  }
150 
151  for(unsigned int i = 0; i < nGeoms; ++i)
152  visited.getGeometryN(i)->accept(*this);
153 }
154 
156 {
157  m_ewkb = Write2EWKB(m_ewkb, &visited);
158 }
159 
161 {
162  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
163 
164  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
165  int srid = visited.getSRID();
166 
167  Convert2PostGISWKBType(gType);
168 
169  if(m_outputSRID)
170  {
171  gType |= TE_EWKB_SRID_FLAG;
172 
173  memcpy(m_ewkb + 1, &gType, 4);
174  memcpy(m_ewkb + 5, &srid, 4);
175 
176  m_ewkb += 9;
177 
178  m_outputSRID = false;
179  }
180  else
181  {
182  memcpy(m_ewkb + 1, &gType, 4);
183  m_ewkb += 5;
184  }
185 
186  m_ewkb = Write2EWKB(m_ewkb, &visited);
187 }
188 
190 {
191  visit((const te::gm::GeometryCollection&)visited);
192 }
193 
195 {
196  visit((const te::gm::GeometryCollection&)visited);
197 }
198 
200 {
201  visit((const te::gm::GeometryCollection&)visited);
202 }
203 
205 {
206  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
207 
208  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
209  int srid = visited.getSRID();
210 
211  Convert2PostGISWKBType(gType);
212 
213  if(m_outputSRID)
214  {
215  gType |= TE_EWKB_SRID_FLAG;
216 
217  memcpy(m_ewkb + 1, &gType, 4);
218  memcpy(m_ewkb + 5, &srid, 4);
219 
220  m_ewkb += 9;
221 
222  m_outputSRID = false;
223  }
224  else
225  {
226  memcpy(m_ewkb + 1, &gType, 4);
227  m_ewkb += 5;
228  }
229 
230  memcpy(m_ewkb, &(visited.getX()), 8); // copy x
231  memcpy(m_ewkb + 8, &(visited.getY()), 8); // copy y
232 
233  int size = 16;
234 
235  if(gType & TE_EWKB_Z_OFFSET)
236  {
237  memcpy(m_ewkb + size, &(visited.getZ()), 8); // copy z
238  size += 8;
239  }
240 
241  if(gType & TE_EWKB_M_OFFSET)
242  {
243  memcpy(m_ewkb + size, &(visited.getM()), 8); // copy m
244  size += 8;
245  }
246 
247  m_ewkb += size;
248 }
249 
251 {
252  visit((const te::gm::Point&)visited);
253 }
254 
256 {
257  visit((const te::gm::Point&)visited);
258 }
259 
261 {
262  visit((const te::gm::Point&)visited);
263 }
264 
266 {
267  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
268 
269  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
270  unsigned int nRings = static_cast<unsigned int>(visited.getNumRings());
271  int srid = visited.getSRID();
272 
273  Convert2PostGISWKBType(gType);
274 
275  if(m_outputSRID)
276  {
277  gType |= TE_EWKB_SRID_FLAG;
278 
279  memcpy(m_ewkb + 1, &gType, 4);
280  memcpy(m_ewkb + 5, &srid, 4);
281  memcpy(m_ewkb + 9, &nRings, 4);
282 
283  m_ewkb += 13;
284 
285  m_outputSRID = false;
286  }
287  else
288  {
289  memcpy(m_ewkb + 1, &gType, 4);
290  memcpy(m_ewkb + 5, &nRings, 4);
291 
292  m_ewkb += 9;
293  }
294 
295  for(unsigned int i = 0; i < nRings; ++i)
296  visited.getRingN(i)->accept(*this);
297 }
MultiLineString is a MultiCurve whose elements are LineStrings.
int getSRID() const
It returns the Spatial Reference System ID associated to this geometric object.
Definition: Geometry.h:189
void Convert2PostGISWKBType(unsigned int &gType)
Definition: Utils.h:930
#define TE_EWKB_M_OFFSET
Definition: Config.h:186
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
char * Write2EWKB(char *ewkb, const te::gm::LineString *l)
Definition: EWKBWriter.cpp:38
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
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
#define TE_EWKB_Z_OFFSET
Definition: Config.h:185
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
EWKBWriter(char *ewkb, te::common::MachineByteOrder byteOrder=te::common::NDR)
It constructs a new EWKB writer.
Definition: EWKBWriter.cpp:91
void write(const te::gm::Geometry *geom)
It serializes the geometry to an EWKB representation into the specified buffer.
Definition: EWKBWriter.cpp:103
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
An utility class for writing a PostGIS EWKB.
Definition: EWKBWriter.h:48
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
MachineByteOrder
Endianness.
Definition: Enums.h:116
virtual const double & getZ() const
It returns the Point z-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:164
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
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
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
void visit(const te::gm::Curve &)
Definition: EWKBWriter.h:95
It is a collection of other geometric objects.
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
Utility functions for PostgreSQL.
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:150
void reset(char *ewkb, te::common::MachineByteOrder byteOrder=te::common::NDR)
It resets the EWKB writer an allows a new geometry to be seriealized to a new buffer.
Definition: EWKBWriter.cpp:115
~EWKBWriter()
Destructor.
Definition: EWKBWriter.cpp:99
Curve * getRingN(std::size_t i) const
It returns the n-th ring for this curve polygon as a curve.
Definition: CurvePolygon.h:193
An utility class for writing a PostGIS EWKB.
#define TE_EWKB_SRID_FLAG
Definition: Config.h:187
virtual const double & getM() const
It returns the Point m-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:178