src/terralib/postgis/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 
103 {
104  geom->accept(*this);
105 }
106 
108 {
109  EWKBWriter w(wkb, byteOrder);
110 
111  geom->accept(w);
112 }
113 
115 {
116  m_ewkb = ewkb;
117  m_byteOrder = byteOrder;
118  m_outputSRID = true;
119 }
120 
122 {
124 
125  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
126  unsigned int nGeoms = static_cast<unsigned int>(visited.getNumGeometries());
127  int srid = visited.getSRID();
128 
129  if(srid <= TE_UNKNOWN_SRS)
130  srid = PGIS_UNKNOWN_SRS;
131 
132  Convert2PostGISWKBType(gType);
133 
134  if(m_outputSRID)
135  {
136  gType |= TE_EWKB_SRID_FLAG;
137 
138  memcpy(m_ewkb + 1, &gType, 4);
139  memcpy(m_ewkb + 5, &srid, 4);
140  memcpy(m_ewkb + 9, &nGeoms, 4);
141 
142  m_ewkb += 13;
143 
144  m_outputSRID = false;
145  }
146  else
147  {
148  memcpy(m_ewkb + 1, &gType, 4);
149  memcpy(m_ewkb + 5, &nGeoms, 4);
150  m_ewkb += 9;
151  }
152 
153  for(unsigned int i = 0; i < nGeoms; ++i)
154  visited.getGeometryN(i)->accept(*this);
155 }
156 
158 {
159  m_ewkb = Write2EWKB(m_ewkb, &visited);
160 }
161 
163 {
165 
166  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
167  int srid = visited.getSRID();
168 
169  if(srid <= TE_UNKNOWN_SRS)
170  srid = PGIS_UNKNOWN_SRS;
171 
172  Convert2PostGISWKBType(gType);
173 
174  if(m_outputSRID)
175  {
176  gType |= TE_EWKB_SRID_FLAG;
177 
178  memcpy(m_ewkb + 1, &gType, 4);
179  memcpy(m_ewkb + 5, &srid, 4);
180 
181  m_ewkb += 9;
182 
183  m_outputSRID = false;
184  }
185  else
186  {
187  memcpy(m_ewkb + 1, &gType, 4);
188  m_ewkb += 5;
189  }
190 
191  m_ewkb = Write2EWKB(m_ewkb, &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  visit((const te::gm::GeometryCollection&)visited);
207 }
208 
210 {
212 
213  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
214  int srid = visited.getSRID();
215 
216  if(srid <= TE_UNKNOWN_SRS)
217  srid = PGIS_UNKNOWN_SRS;
218 
219  Convert2PostGISWKBType(gType);
220 
221  if(m_outputSRID)
222  {
223  gType |= TE_EWKB_SRID_FLAG;
224 
225  memcpy(m_ewkb + 1, &gType, 4);
226  memcpy(m_ewkb + 5, &srid, 4);
227 
228  m_ewkb += 9;
229 
230  m_outputSRID = false;
231  }
232  else
233  {
234  memcpy(m_ewkb + 1, &gType, 4);
235  m_ewkb += 5;
236  }
237 
238  memcpy(m_ewkb, &(visited.getX()), 8); // copy x
239  memcpy(m_ewkb + 8, &(visited.getY()), 8); // copy y
240 
241  int size = 16;
242 
243  if(gType & TE_EWKB_Z_OFFSET)
244  {
245  memcpy(m_ewkb + size, &(visited.getZ()), 8); // copy z
246  size += 8;
247  }
248 
249  if(gType & TE_EWKB_M_OFFSET)
250  {
251  memcpy(m_ewkb + size, &(visited.getM()), 8); // copy m
252  size += 8;
253  }
254 
255  m_ewkb += size;
256 }
257 
259 {
261 
262  unsigned int gType = static_cast<unsigned int>(visited.getGeomTypeId());
263  unsigned int nRings = static_cast<unsigned int>(visited.getNumRings());
264  int srid = visited.getSRID();
265 
266  if(srid <= TE_UNKNOWN_SRS)
267  srid = PGIS_UNKNOWN_SRS;
268 
269  Convert2PostGISWKBType(gType);
270 
271  if(m_outputSRID)
272  {
273  gType |= TE_EWKB_SRID_FLAG;
274 
275  memcpy(m_ewkb + 1, &gType, 4);
276  memcpy(m_ewkb + 5, &srid, 4);
277  memcpy(m_ewkb + 9, &nRings, 4);
278 
279  m_ewkb += 13;
280 
281  m_outputSRID = false;
282  }
283  else
284  {
285  memcpy(m_ewkb + 1, &gType, 4);
286  memcpy(m_ewkb + 5, &nRings, 4);
287 
288  m_ewkb += 9;
289  }
290 
291  for(unsigned int i = 0; i < nRings; ++i)
292  visited.getRingN(i)->accept(*this);
293 }
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
An utility class for writing a PostGIS EWKB.
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
void write(const te::gm::Geometry *geom)
It serializes the geometry to an EWKB representation into the specified buffer.
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
An utility class for writing a PostGIS EWKB.
Utility functions for PostgreSQL.
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
char * Write2EWKB(char *ewkb, const te::gm::LineString *l)
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
te::common::MachineByteOrder m_byteOrder
The byte order used to encode the EWKB.
#define TE_EWKB_SRID_FLAG
#define TE_EWKB_Z_OFFSET
char * m_ewkb
A pointer that marks the current position in a buffer to be write when parsing the geometry...
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
~EWKBWriter()
Destructor.
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
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
bool m_outputSRID
If true we add a bit indicating that the srid will be outputed with the gometry.
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
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.
void visit(const te::gm::Curve &)
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.
EWKBWriter(char *ewkb, te::common::MachineByteOrder byteOrder=te::common::NDR)
It constructs a new EWKB writer.
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.
void Convert2PostGISWKBType(unsigned int &gType)
const double & getM(std::size_t i) const
It returns the n-th m measure value.
It is a collection of other geometric objects.
#define TE_EWKB_M_OFFSET
#define PGIS_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in PostGIS.
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
Curve * getRingN(std::size_t i) const
It returns the n-th ring for this curve polygon as a curve.
Definition: CurvePolygon.h:193