GEOSWriter.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/GEOSWriter.cpp
22 
23  \brief A class that converts a TerraLib geometry to a GEOS geometry.
24 */
25 
26 // TerraLib
27 #include "GEOSWriter.h"
28 
29 #ifdef TERRALIB_GEOS_ENABLED
30 // TerraLib
31 #include "../core/translator/Translator.h"
32 #include "Envelope.h"
33 #include "Exception.h"
34 #include "GeometryCollection.h"
35 #include "GEOSGeometryFactory.h"
36 #include "Line.h"
37 #include "LineString.h"
38 #include "LinearRing.h"
39 #include "MultiLineString.h"
40 #include "MultiPoint.h"
41 #include "MultiPolygon.h"
42 #include "Point.h"
43 #include "Polygon.h"
44 
45 // GEOS
46 #include <geos/geom/Coordinate.h>
47 #include <geos/geom/CoordinateArraySequence.h>
48 #include <geos/geom/Envelope.h>
49 #include <geos/geom/GeometryCollection.h>
50 #include <geos/geom/LineSegment.h>
51 #include <geos/geom/LineString.h>
52 #include <geos/geom/LinearRing.h>
53 #include <geos/geom/MultiLineString.h>
54 #include <geos/geom/MultiPoint.h>
55 #include <geos/geom/MultiPolygon.h>
56 #include <geos/geom/Point.h>
57 #include <geos/geom/Polygon.h>
58 
59 // STL
60 #include <cassert>
61 
62 geos::geom::Geometry* te::gm::GEOSWriter::write(const Geometry* geom)
63 {
64  assert(geom);
65 
66  switch(geom->getGeomTypeId())
67  {
68  case PointType:
69  case PointZType:
70  case PointMType:
71  case PointZMType:
72  return write(static_cast<const Point*>(geom));
73 
74 
75  case LineStringType:
76  case LineStringZType:
77  case LineStringMType:
78  case LineStringZMType:
79  return write(static_cast<const LineString*>(geom));
80 
81  case PolygonType:
82  case PolygonZType:
83  case PolygonMType:
84  case PolygonZMType:
85  return write(static_cast<const Polygon*>(geom));
86 
87  case MultiPolygonType:
88  case MultiPolygonZType:
89  case MultiPolygonMType:
90  case MultiPolygonZMType:
91  return write(static_cast<const MultiPolygon*>(geom));
92 
93  case MultiPointType:
94  case MultiPointZType:
95  case MultiPointMType:
96  case MultiPointZMType:
97  return write(static_cast<const MultiPoint*>(geom));
98 
103  return write(static_cast<const MultiLineString*>(geom));
104 
109  return write(static_cast<const MultiSurface*>(geom));
110 
115  return write(static_cast<const GeometryCollection*>(geom));
116 
117  /*case TriangleType:
118  case TriangleZType:
119  case TriangleMType:
120  case TriangleZMType:
121  return write(static_cast<const Triangle*>(geom));*/
122 
123  /*case TINType:
124  case TINZType:
125  case TINMType:
126  case TINZMType:
127  return write(static_cast<const TIN*>(geom));*/
128 
129  /*case PolyhedralSurfaceType:
130  case PolyhedralSurfaceZType:
131  case PolyhedralSurfaceMType:
132  case PolyhedralSurfaceZMType:
133  return write(static_cast<const PolyhedralSurface*>(geom));*/
134 
135  default:
136  throw Exception(TE_TR("The type of informed geometry can not be converted from TerraLib to GEOS!"));
137  }
138 }
139 
140 geos::geom::Point* te::gm::GEOSWriter::write(const Point* tePt)
141 {
142  geos::geom::Coordinate c;
143  geos::geom::Point* p;
144 
145  switch (tePt->getGeomTypeId())
146  {
147  case(PointType):
148  assert((tePt != nullptr) && (tePt->getGeomTypeId() == PointType));
149 
150  c.x = tePt->getX();
151  c.y = tePt->getY();
152 
153  p = GEOSGeometryFactory::getGeomFactory()->createPoint(c);
154 
155  assert(p);
156 
157  p->setSRID(tePt->getSRID());
158 
159  return p;
160 
161  case(PointZType):
162  assert((tePt != nullptr) && (tePt->getGeomTypeId() == PointZType));
163 
164  c.x = tePt->getX();
165  c.y = tePt->getY();
166  c.z = tePt->getZ();
167 
168  p = GEOSGeometryFactory::getGeomFactory()->createPoint(c);
169 
170  assert(p);
171 
172  p->setSRID(tePt->getSRID());
173 
174  return p;
175 
176  case(PointMType):
177  assert((tePt != nullptr) && (tePt->getGeomTypeId() == PointMType));
178 
179  c.x = tePt->getX();
180  c.y = tePt->getY();
181  c.z = tePt->getM();
182 
183  p = GEOSGeometryFactory::getGeomFactory()->createPoint(c);
184 
185  assert(p);
186 
187  p->setSRID(tePt->getSRID());
188 
189  return p;
190 
191  default : //zm
192  assert((tePt != nullptr) && (tePt->getGeomTypeId() == PointZMType));
193 
194  c.x = tePt->getX();
195  c.y = tePt->getY();
196  c.z = tePt->getZ();
197 
198  p = GEOSGeometryFactory::getGeomFactory()->createPoint(c);
199 
200  assert(p);
201 
202  p->setSRID(tePt->getSRID());
203 
204  return p;
205  }
206 }
207 
208 geos::geom::LineString* te::gm::GEOSWriter::write(const LineString* teLine)
209 {
210  geos::geom::CoordinateSequence* cl = getCoordinateSequence(teLine);
211 
212  geos::geom::LineString* ls = GEOSGeometryFactory::getGeomFactory()->createLineString(cl);
213 
214  ls->setSRID(teLine->getSRID());
215 
216  return ls;
217 }
218 
219 geos::geom::LinearRing* te::gm::GEOSWriter::write(const LinearRing* teRing)
220 {
221  geos::geom::CoordinateSequence* cl = getCoordinateSequence(teRing);
222 
223  geos::geom::LinearRing* r = GEOSGeometryFactory::getGeomFactory()->createLinearRing(cl);
224 
225  r->setSRID(teRing->getSRID());
226 
227  return r;
228 }
229 
230 geos::geom::Polygon* te::gm::GEOSWriter::write(const Polygon* tePoly)
231 {
232  assert((tePoly != nullptr) && (tePoly->getGeomTypeId() == PolygonType ||
233  tePoly->getGeomTypeId() == PolygonMType ||
234  tePoly->getGeomTypeId() == PolygonZType ||
235  tePoly->getGeomTypeId() == PolygonZMType));
236 
237  std::size_t n = tePoly->getNumRings();
238 
239  if(n == 0)
240  {
241  geos::geom::Polygon* poly = GEOSGeometryFactory::getGeomFactory()->createPolygon();
242 
243  poly->setSRID(tePoly->getSRID());
244 
245  return poly;
246  }
247 
248  std::vector<geos::geom::Geometry*>* holes = new std::vector<geos::geom::Geometry*>(n - 1);
249 
250  for(std::size_t i = 1; i < n; ++i)
251  (*holes)[i - 1] = write(static_cast<const LinearRing*>(tePoly->getRingN(i)));
252 
253  geos::geom::LinearRing* outer = write(static_cast<const LinearRing*>(tePoly->getRingN(0)));
254 
255  geos::geom::Polygon* poly = GEOSGeometryFactory::getGeomFactory()->createPolygon(outer, holes);
256 
257  poly->setSRID(tePoly->getSRID());
258 
259  return poly;
260 }
261 
262 geos::geom::MultiPolygon* te::gm::GEOSWriter::write(const MultiPolygon* teMPoly)
263 {
264  assert((teMPoly != nullptr) && (teMPoly->getGeomTypeId() == MultiPolygonType ||
265  teMPoly->getGeomTypeId() == MultiPolygonMType ||
266  teMPoly->getGeomTypeId() == MultiPolygonZType ||
267  teMPoly->getGeomTypeId() == MultiPolygonZMType));
268 
269  std::vector<geos::geom::Geometry*>* geoms = getGeometries(teMPoly);
270 
271  geos::geom::MultiPolygon* mpoly = GEOSGeometryFactory::getGeomFactory()->createMultiPolygon(geoms);
272 
273  assert(mpoly);
274 
275  mpoly->setSRID(teMPoly->getSRID());
276 
277  return mpoly;
278 }
279 
280 geos::geom::MultiLineString* te::gm::GEOSWriter::write(const MultiLineString* teMLine)
281 {
282  assert((teMLine != nullptr) && (teMLine->getGeomTypeId() == MultiLineStringType ||
283  teMLine->getGeomTypeId() == MultiLineStringMType ||
284  teMLine->getGeomTypeId() == MultiLineStringZType ||
285  teMLine->getGeomTypeId() == MultiLineStringZMType));
286 
287  std::vector<geos::geom::Geometry*>* geoms = getGeometries(teMLine);
288 
289  assert(geoms);
290 
291  geos::geom::MultiLineString* mline = GEOSGeometryFactory::getGeomFactory()->createMultiLineString(geoms);
292 
293  assert(mline);
294 
295  mline->setSRID(teMLine->getSRID());
296 
297  return mline;
298 }
299 
300 geos::geom::MultiPoint* te::gm::GEOSWriter::write(const MultiPoint* teMPt)
301 {
302  assert((teMPt != nullptr) && (teMPt->getGeomTypeId() == MultiPointType ||
303  teMPt->getGeomTypeId() == MultiPointMType ||
304  teMPt->getGeomTypeId() == MultiPointZType ||
305  teMPt->getGeomTypeId() == MultiPointZMType));
306 
307  std::vector<geos::geom::Geometry*>* geoms = getGeometries(teMPt);
308 
309  geos::geom::MultiPoint* mpt = GEOSGeometryFactory::getGeomFactory()->createMultiPoint(geoms);
310 
311  assert(mpt);
312 
313  mpt->setSRID(teMPt->getSRID());
314 
315  return mpt;
316 }
317 
318 geos::geom::Envelope* te::gm::GEOSWriter::write(const Envelope* teEnv)
319 {
320  assert(teEnv);
321  geos::geom::Envelope* env = new geos::geom::Envelope(teEnv->getLowerLeftX(), teEnv->getUpperRightX(), teEnv->getLowerLeftY(), teEnv->getUpperRightY());
322  assert(env);
323 
324  return env;
325 }
326 
327 geos::geom::LineSegment* te::gm::GEOSWriter::write(const Line* teLin)
328 {
329  assert(teLin);
330  geos::geom::LineSegment *ls = new geos::geom::LineSegment(teLin->getX(0), teLin->getY(0), teLin->getX(1), teLin->getY(1));
331  assert(ls);
332 
333  return ls;
334 }
335 
336 geos::geom::GeometryCollection* te::gm::GEOSWriter::write(const GeometryCollection* teGeomColl)
337 {
338  assert((teGeomColl != nullptr) && (teGeomColl->getGeomTypeId() == GeometryCollectionType ||
339  teGeomColl->getGeomTypeId() == GeometryCollectionMType ||
340  teGeomColl->getGeomTypeId() == GeometryCollectionZType ||
341  teGeomColl->getGeomTypeId() == GeometryCollectionZMType ||
342  teGeomColl->getGeomTypeId() == MultiSurfaceType ||
343  teGeomColl->getGeomTypeId() == MultiSurfaceMType ||
344  teGeomColl->getGeomTypeId() == MultiSurfaceZType ||
345  teGeomColl->getGeomTypeId() == MultiSurfaceZMType));
346 
347  std::vector<geos::geom::Geometry*>* geoms = getGeometries(teGeomColl);
348 
349  geos::geom::GeometryCollection* geomColl= GEOSGeometryFactory::getGeomFactory()->createGeometryCollection(geoms);
350 
351  assert(geomColl);
352 
353  geomColl->setSRID(teGeomColl->getSRID());
354 
355  return geomColl;
356 }
357 
358 geos::geom::CoordinateSequence* te::gm::GEOSWriter::getCoordinateSequence(const LineString* teLine)
359 {
360  assert((teLine != nullptr) && (teLine->getGeomTypeId() == LineStringType ||
361  teLine->getGeomTypeId() == LineStringMType ||
362  teLine->getGeomTypeId() == LineStringZType ||
363  teLine->getGeomTypeId() == LineStringZMType));
364 
365  const std::size_t nPts = teLine->size();
366 
367  std::vector<geos::geom::Coordinate>* geosCoords = new std::vector<geos::geom::Coordinate>(nPts);
368 
369  Coord2D* teCoords = teLine->getCoordinates();
370 
371  for(std::size_t i = 0; i < nPts; ++i)
372  {
373  (*geosCoords)[i].x = teCoords[i].x;
374  (*geosCoords)[i].y = teCoords[i].y;
375  if (teLine->getGeomTypeId() == LineStringMType ||
376  teLine->getGeomTypeId() == LineStringZType ||
377  teLine->getGeomTypeId() == LineStringZMType)
378  (*geosCoords)[i].z = teLine->getZ(i);
379  }
380 
381  geos::geom::CoordinateSequence* cl = new geos::geom::CoordinateArraySequence(geosCoords);
382 
383  return cl;
384 }
385 
386 std::vector<geos::geom::Geometry*>* te::gm::GEOSWriter::getGeometries(const GeometryCollection* teGeomColl)
387 {
388  assert(teGeomColl);
389 
390  std::size_t size = teGeomColl->getNumGeometries();
391 
392  std::vector<geos::geom::Geometry*>* geoms = new std::vector<geos::geom::Geometry*>(size);
393 
394  for(std::size_t i = 0; i < size; ++i)
395  {
396  geos::geom::Geometry* g = write(teGeomColl->getGeometryN(i));
397 
398  assert(g);
399 
400  (*geoms)[i] = g;
401  }
402 
403  return geoms;
404 }
405 
406 #endif // TERRALIB_GEOS_ENABLED
407 
The global factory used by TerraLib in order to create GEOS geometries.
A Line is LineString with 2 points.
A LinearRing is a LineString that is both closed and simple.
A point with x and y coordinate values.
static std::vector< geos::geom::Geometry * > * getGeometries(const GeometryCollection *teGeomColl)
It creates a vector of GEOS geometry from the input TerraLib geometry collection. ...
static geos::geom::CoordinateSequence * getCoordinateSequence(const LineString *teLine)
It creates a coordinate sequence from the input TerraLib line string (or TerraLib linear ring)...
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
MultiPoint is a GeometryCollection whose elements are restricted to points.
MultiLineString is a MultiCurve whose elements are LineStrings.
te::gm::Polygon * p
MultiPolygon is a MultiSurface whose elements are Polygons.
static geos::geom::Geometry * write(const Geometry *teGeom)
It reads a TerraLib geometry and make a GEOS geometry.
A class that converts a TerraLib geometry to a GEOS geometry.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
LineString is a curve with linear interpolation between points.
It is a collection of other geometric objects.