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/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 "../srs/Config.h"
31 #include "EWKBWriter.h"
32 #include "Utils.h"
33 
34 // STL
35 #include <cassert>
36 #include <cstring>
37 #include <typeinfo>
38 
39 inline char* Write2EWKB(char* ewkb, const te::gm::LineString* l)
40 {
41  unsigned int nPts = static_cast<unsigned int>(l->getNPoints());
42  te::gm::Coord2D* coords = l->getCoordinates();
43  double* zA = l->getZ();
44  double* mA = l->getM();
45 
46  memcpy(ewkb, &nPts, 4);
47  ewkb += 4;
48 
49  switch(l->getGeomTypeId())
50  {
52  memcpy(ewkb, coords, 16 * nPts);
53  ewkb += (nPts * 16);
54  break;
55 
57  for(size_t i = 0; i < nPts; ++i)
58  {
59  memcpy(ewkb, &(coords[i]), 16);
60  memcpy(ewkb + 16, &(zA[i]), 8);
61  ewkb += 24;
62  }
63  break;
64 
66  for(size_t i = 0; i < nPts; ++i)
67  {
68  memcpy(ewkb, &(coords[i]), 16);
69  memcpy(ewkb + 16, &(mA[i]), 8);
70  ewkb += 24;
71  }
72  break;
73 
75  for(size_t i = 0; i < nPts; ++i)
76  {
77  memcpy(ewkb, &(coords[i]), 16);
78  memcpy(ewkb + 16, &(zA[i]), 8);
79  memcpy(ewkb + 24, &(mA[i]), 8);
80  ewkb += 32;
81  }
82  break;
83 
84  default:
85  assert(false);
86  break;
87  }
88 
89  return ewkb;
90 }
91 
93  : m_ewkb(ewkb),
94  m_byteOrder(byteOrder),
95  m_outputSRID(true)
96 {
97 // ewkb must be at least = g->getWkbSize() + 4
98 }
99 
101 {
102 }
103 
105 {
106  geom->accept(*this);
107 }
108 
110 {
111  EWKBWriter w(wkb, byteOrder);
112 
113  geom->accept(w);
114 }
115 
117 {
118  m_ewkb = ewkb;
119  m_byteOrder = byteOrder;
120  m_outputSRID = true;
121 }
122 
124 {
125  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
126 
127  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
128  unsigned int nGeoms = static_cast<unsigned int>(visited.getNumGeometries());
129  int srid = visited.getSRID();
130 
131  if(srid <= TE_UNKNOWN_SRS)
132  srid = PGIS_UNKNOWN_SRS;
133 
134  Convert2PostGISWKBType(gType);
135 
136  if(m_outputSRID)
137  {
138  gType |= TE_EWKB_SRID_FLAG;
139 
140  memcpy(m_ewkb + 1, &gType, 4);
141  memcpy(m_ewkb + 5, &srid, 4);
142  memcpy(m_ewkb + 9, &nGeoms, 4);
143 
144  m_ewkb += 13;
145 
146  m_outputSRID = false;
147  }
148  else
149  {
150  memcpy(m_ewkb + 1, &gType, 4);
151  memcpy(m_ewkb + 5, &nGeoms, 4);
152  m_ewkb += 9;
153  }
154 
155  for(unsigned int i = 0; i < nGeoms; ++i)
156  visited.getGeometryN(i)->accept(*this);
157 }
158 
160 {
161  m_ewkb = Write2EWKB(m_ewkb, &visited);
162 }
163 
165 {
166  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
167 
168  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
169  int srid = visited.getSRID();
170 
171  if(srid <= TE_UNKNOWN_SRS)
172  srid = PGIS_UNKNOWN_SRS;
173 
174  Convert2PostGISWKBType(gType);
175 
176  if(m_outputSRID)
177  {
178  gType |= TE_EWKB_SRID_FLAG;
179 
180  memcpy(m_ewkb + 1, &gType, 4);
181  memcpy(m_ewkb + 5, &srid, 4);
182 
183  m_ewkb += 9;
184 
185  m_outputSRID = false;
186  }
187  else
188  {
189  memcpy(m_ewkb + 1, &gType, 4);
190  m_ewkb += 5;
191  }
192 
193  m_ewkb = Write2EWKB(m_ewkb, &visited);
194 }
195 
197 {
198  visit((const te::gm::GeometryCollection&)visited);
199 }
200 
202 {
203  visit((const te::gm::GeometryCollection&)visited);
204 }
205 
207 {
208  visit((const te::gm::GeometryCollection&)visited);
209 }
210 
212 {
213  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
214 
215  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
216  int srid = visited.getSRID();
217 
218  if(srid <= TE_UNKNOWN_SRS)
219  srid = PGIS_UNKNOWN_SRS;
220 
221  Convert2PostGISWKBType(gType);
222 
223  if(m_outputSRID)
224  {
225  gType |= TE_EWKB_SRID_FLAG;
226 
227  memcpy(m_ewkb + 1, &gType, 4);
228  memcpy(m_ewkb + 5, &srid, 4);
229 
230  m_ewkb += 9;
231 
232  m_outputSRID = false;
233  }
234  else
235  {
236  memcpy(m_ewkb + 1, &gType, 4);
237  m_ewkb += 5;
238  }
239 
240  memcpy(m_ewkb, &(visited.getX()), 8); // copy x
241  memcpy(m_ewkb + 8, &(visited.getY()), 8); // copy y
242 
243  int size = 16;
244 
245  if(gType & TE_EWKB_Z_OFFSET)
246  {
247  memcpy(m_ewkb + size, &(visited.getZ()), 8); // copy z
248  size += 8;
249  }
250 
251  if(gType & TE_EWKB_M_OFFSET)
252  {
253  memcpy(m_ewkb + size, &(visited.getM()), 8); // copy m
254  size += 8;
255  }
256 
257  m_ewkb += size;
258 }
259 
261 {
262  visit((const te::gm::Point&)visited);
263 }
264 
266 {
267  visit((const te::gm::Point&)visited);
268 }
269 
271 {
272  visit((const te::gm::Point&)visited);
273 }
274 
276 {
277  memcpy(m_ewkb, &te::common::Globals::sm_machineByteOrder, 1);
278 
279  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
280  unsigned int nRings = static_cast<unsigned int>(visited.getNumRings());
281  int srid = visited.getSRID();
282 
283  if(srid <= TE_UNKNOWN_SRS)
284  srid = PGIS_UNKNOWN_SRS;
285 
286  Convert2PostGISWKBType(gType);
287 
288  if(m_outputSRID)
289  {
290  gType |= TE_EWKB_SRID_FLAG;
291 
292  memcpy(m_ewkb + 1, &gType, 4);
293  memcpy(m_ewkb + 5, &srid, 4);
294  memcpy(m_ewkb + 9, &nRings, 4);
295 
296  m_ewkb += 13;
297 
298  m_outputSRID = false;
299  }
300  else
301  {
302  memcpy(m_ewkb + 1, &gType, 4);
303  memcpy(m_ewkb + 5, &nRings, 4);
304 
305  m_ewkb += 9;
306  }
307 
308  for(unsigned int i = 0; i < nRings; ++i)
309  visited.getRingN(i)->accept(*this);
310 }
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
virtual const double & getM() const
It returns the Point m-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:178
An utility class for writing a PostGIS EWKB.
Definition: EWKBWriter.h:48
#define TE_EWKB_SRID_FLAG
Definition: Config.h:163
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
void write(const te::gm::Geometry *geom)
It serializes the geometry to an EWKB representation into the specified buffer.
Definition: EWKBWriter.cpp:104
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
virtual const double & getZ() const
It returns the Point z-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:164
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
#define TE_EWKB_M_OFFSET
Definition: Config.h:162
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
~EWKBWriter()
Destructor.
Definition: EWKBWriter.cpp:100
A point with z-coordinate value.
Definition: PointZ.h:51
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
#define TE_EWKB_Z_OFFSET
Definition: Config.h:161
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:150
An utility class for writing a PostGIS EWKB.
A point with x and y coordinate values.
Definition: Point.h:50
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:44
Utility functions for PostgreSQL.
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
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
void visit(const te::gm::Curve &)
Definition: EWKBWriter.h:95
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
MultiLineString is a MultiCurve whose elements are LineStrings.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
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:116
EWKBWriter(char *ewkb, te::common::MachineByteOrder byteOrder=te::common::NDR)
It constructs a new EWKB writer.
Definition: EWKBWriter.cpp:92
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
const double & getZ(std::size_t i) const
It returns the n-th z coordinate value.
Definition: LineString.cpp:397
void Convert2PostGISWKBType(unsigned int &gType)
Definition: Utils.h:930
const double & getM(std::size_t i) const
It returns the n-th m measure value.
Definition: LineString.cpp:403
#define PGIS_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in PostGIS.
Definition: Config.h:101
It is a collection of other geometric objects.
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:136
Curve * getRingN(std::size_t i) const
It returns the n-th ring for this curve polygon as a curve.
Definition: CurvePolygon.h:193
char * Write2EWKB(char *ewkb, const te::gm::LineString *l)
Definition: EWKBWriter.cpp:39