CurvePolygon.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/CurvePolygon.cpp
22 
23  \brief CurvePolygon is a planar surface defined by 1 exterior boundary and 0 or more interior boundaries.
24 */
25 
26 // TerraLib
27 #include "../common/STLUtils.h"
28 #include "../core/translator/Translator.h"
29 #include "Config.h"
30 #include "Coord2D.h"
31 #include "Curve.h"
32 #include "CurvePolygon.h"
33 #include "Envelope.h"
34 #include "GEOSWriter.h"
35 #include "Point.h"
36 
37 #ifdef TERRALIB_GEOS_ENABLED
38 // GEOS
39 #include <geos/algorithm/CentroidArea.h>
40 #include <geos/geom/Geometry.h>
41 #include <geos/geom/IntersectionMatrix.h>
42 #include <geos/operation/buffer/OffsetCurveBuilder.h>
43 #include <geos/util/GEOSException.h>
44 #endif
45 
46 const std::string te::gm::CurvePolygon::sm_typeName("CurvePolygon");
47 
48 te::gm::CurvePolygon::CurvePolygon(std::size_t nRings, GeomType t, int srid, Envelope* mbr)
49  : Surface(t, srid, mbr),
50  m_rings(nRings)
51 {
52 }
53 
55  : Surface(rhs)
56 {
58 }
59 
61 {
63 }
64 
66 {
67  if(this != &rhs)
68  {
69  Surface::operator=(rhs);
70 
72 
73  m_rings.clear();
74 
76  }
77 
78  return *this;
79 }
80 
82 {
83  return new CurvePolygon(*this);
84 }
85 
87 {
88  assert(m_rings.size() > 0);
89  return m_rings[0];
90 }
91 
93 {
94  return (m_rings.size() > 0) ? (m_rings.size() - 1) : 0;
95 }
96 
97 void te::gm::CurvePolygon::setNumRings(std::size_t size)
98 {
99  if(size < m_rings.size())
100  {
101  std::size_t oldSize = m_rings.size();
102  for(std::size_t i = size; i < oldSize; ++i)
103  delete m_rings[i];
104  }
105 
106  m_rings.resize(size);
107 }
108 
110 {
111  assert(i < getNumInteriorRings());
112  return m_rings[i + 1];
113 }
114 
115 void te::gm::CurvePolygon::setRingN(std::size_t i, Curve* r)
116 {
117  assert(i < m_rings.size());
118  delete m_rings[i];
119 
120  r->setSRID(this->getSRID());
121  m_rings[i] = r;
122 }
123 
125 {
126  assert(i < m_rings.size());
127  delete m_rings[i];
128  m_rings.erase(m_rings.begin() + i);
129 }
130 
132 {
133  ring->setSRID(this->getSRID());
134  m_rings.push_back(ring);
135 }
136 
138 {
139  ring->setSRID(this->getSRID());
140  m_rings.push_back(ring);
141 }
142 
144 {
146  m_rings.clear();
147 }
148 
150 {
151 #ifdef TERRALIB_GEOS_ENABLED
152  try
153  {
154  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
155 
156  return g->getArea();
157  }
158  catch(geos::util::GEOSException& e)
159  {
160  throw Exception(e.what());
161  }
162 
163 #else
164  throw Exception(TE_TR("getArea routine is supported by GEOS! Please, enable the GEOS support."));
165 #endif
166 }
167 
169 {
170 #ifdef TERRALIB_GEOS_ENABLED
171  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
172 
173  geos::algorithm::CentroidArea c;
174 
175  c.add(thisGeom.get());
176 
177  geos::geom::Coordinate coord;
178 
179  if(c.getCentroid(coord))
180  {
181  Point* pt = new Point(coord.x, coord.y, m_srid);
182 
183  return pt;
184  }
185 
186  return nullptr;
187 
188 #else
189  throw te::common::Exception(TE_TR("getCentroid routine is supported by GEOS! Please, enable the GEOS support."));
190 #endif
191 }
192 
194 {
196 
197  if(p)
198  {
199  te::gm::Coord2D* coord = new te::gm::Coord2D(p->getX(), p->getY());
200 
201  delete p;
202 
203  return coord;
204  }
205 
206  return nullptr;
207 }
208 
210 {
211  return nullptr;
212 }
213 
215 {
216  return nullptr;
217 }
218 
220 {
221 #ifdef TERRALIB_GEOS_ENABLED
222  try
223  {
224  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
225 
226  return g->getLength();
227  }
228  catch(geos::util::GEOSException& e)
229  {
230  throw Exception(e.what());
231  }
232 
233 #else
234  throw Exception(TE_TR("getLength routine is supported by GEOS! Please, enable the GEOS support."));
235 #endif
236 }
237 
238 const std::string& te::gm::CurvePolygon::getGeometryType() const throw()
239 {
240  return sm_typeName;
241 }
242 
243 void te::gm::CurvePolygon::setSRID(int srid) throw()
244 {
245  std::size_t n = m_rings.size();
246 
247  for(std::size_t i = 0; i < n; ++i)
248  m_rings[i]->setSRID(srid);
249 
250  m_srid = srid;
251 }
252 
254 {
255 #ifdef TERRALIB_MOD_SRS_ENABLED
256  if(srid == m_srid)
257  return;
258 
259  std::size_t n = m_rings.size();
260 
261  for(std::size_t i = 0; i < n; ++i)
262  m_rings[i]->transform(srid);
263 
264  if(m_mbr)
265  computeMBR(true); // just update the polygon MBR
266 
267  m_srid = srid;
268 #else
269  throw Exception(TE_TR("transform method is not supported!"));
270 #endif // TERRALIB_MOD_SRS_ENABLED
271 }
272 
273 void te::gm::CurvePolygon::computeMBR(bool cascade) const throw()
274 {
275  if(m_mbr == nullptr)
276  m_mbr = new Envelope;
277  else
278  m_mbr->makeInvalid();
279 
280  std::size_t n = m_rings.size();
281 
282  if(n == 0)
283  return;
284 
285  if(cascade)
286  m_rings[0]->computeMBR(true);
287 
288  *m_mbr = *(m_rings[0]->getMBR());
289 
290  if(cascade)
291  for(std::size_t i = 1; i < n; ++i)
292  m_rings[i]->computeMBR(true);
293 }
294 
295 std::size_t te::gm::CurvePolygon::getNPoints() const throw()
296 {
297  std::size_t n = m_rings.size();
298 
299  std::size_t sum = 0;
300 
301  for(std::size_t i = 0; i < n; ++i)
302  sum += m_rings[i]->getNPoints();
303 
304  return sum;
305 }
306 
virtual CurvePolygon & operator=(const CurvePolygon &rhs)
Assignment operator.
Curve * getInteriorRingN(std::size_t i) const
It returns the n-th interior ring for this curve polygon as a curve.
void add(Curve *ring)
It adds the ring to the curve polygon.
void push_back(Curve *ring)
It adds the curve to the curve polygon.
void makeInvalid()
It will invalidated the envelope.
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
virtual const std::string & getGeometryType() const
The name of the geometry subtype for curve polygons is: CurvePolygon.
void transform(int srid)
It converts the coordinate values of the geometry to the new spatial reference system.
void setSRID(int srid)
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
Configuration flags for the Vector Geometry Model of TerraLib.
Base exception class for plugin module.
Curve is an abstract class that represents 1-dimensional geometric objects stored as a sequence of co...
Definition: Curve.h:58
std::size_t getNumInteriorRings() const
It returns the number of interior rings in this CurvePolygon.
int m_srid
The Spatial Reference System code associated to the Geometry.
double getPerimeter() const
It returns the length of the boundary for the surface.
A point with x and y coordinate values.
Curve * getExteriorRing() const
It returns the exterior ring of this CurvePolygon.
void removeRingN(std::size_t i)
It removes the n-th ring in this CurvePolygon.
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:242
void setNumRings(std::size_t size)
It sets the number of rings in this curve polygon.
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
An Envelope defines a 2D rectangular region.
static const std::string sm_typeName
Definition: CurvePolygon.h:435
std::size_t getNPoints() const
it returns the number of points (vertexes) in the geometry.
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
An Envelope defines a 2D rectangular region.
CurvePolygon is a planar surface defined by 1 exterior boundary and 0 or more interior boundaries...
Point * getPointOnSurface() const
It returns a point guaranteed to be on this surface.
CurvePolygon(std::size_t nRings, GeomType t, int srid=0, Envelope *mbr=0)
It initializes the curve polygon with the specified spatial reference system id and envelope...
te::gm::Polygon * p
CurvePolygon is a planar surface defined by 1 exterior boundary and 0 or more interior boundaries...
Definition: CurvePolygon.h:57
virtual ~CurvePolygon()
Virtual destructor.
virtual Surface & operator=(const Surface &rhs)
Assignment operator.
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
static geos::geom::Geometry * write(const Geometry *teGeom)
It reads a TerraLib geometry and make a GEOS geometry.
Coord2D * getCoordOnSurface() const
It returns a coordinate guaranteed to be on this surface.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Curve is an abstract class that represents 1-dimensional geometric objects stored as a sequence of co...
Envelope * m_mbr
The geometry minimum bounding rectangle.
A class that converts a TerraLib geometry to a GEOS geometry.
double getArea() const
It returns the area of this surface, as measured in the spatial reference system of this surface...
void computeMBR(bool cascade) const
It computes the minimum bounding rectangle for the curve polygon.
Coord2D * getCentroidCoord() const
It returns the mathematical centroid for this surface as a coordinate.
virtual void setSRID(int srid) _NOEXCEPT_OP(true)=0
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
Point * getCentroid() const
It returns the mathematical centroid for this surface as a point.
void clear()
It deletes all the rings of the CurvePolygon and clear it.
virtual te::dt::AbstractData * clone() const
It clones the linestring.
void Clone(const std::vector< T * > &src, std::vector< T * > &dst)
This function can be applied to a vector of pointers.
Definition: STLUtils.h:237
An utility struct for representing 2D coordinates.
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
void setRingN(std::size_t i, Curve *r)
It sets the informed position ring to the new one.
Surface is an abstract class that represents a 2-dimensional geometric objects.
Definition: Surface.h:54
std::vector< Curve * > m_rings
An array with the ring list.
Definition: CurvePolygon.h:433