geometry/LineString.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/LineString.cpp
22 
23  \brief LineString is a curve with linear interpolation between points.
24 */
25 
26 // TerraLib
27 #include "../core/translator/Translator.h"
28 #include "../srs/Converter.h"
29 #include "Config.h"
30 #include "Coord2D.h"
31 #include "Envelope.h"
32 #include "Exception.h"
33 #include "GEOSWriter.h"
34 #include "LineString.h"
35 #include "Point.h"
36 
37 // STL
38 #include <cassert>
39 #include <cstdlib>
40 #include <cstring>
41 #include <memory>
42 
43 #ifdef TERRALIB_GEOS_ENABLED
44 // GEOS
45 #include <geos/geom/Geometry.h>
46 #include <geos/util/GEOSException.h>
47 #endif
48 
49 const std::string te::gm::LineString::sm_typeName("LineString");
50 
52  : Curve(t, srid, mbr),
53  m_coords(nullptr),
54  m_zA(nullptr),
55  m_mA(nullptr),
56  m_nPts(0)
57 {
58 }
59 
60 te::gm::LineString::LineString(std::size_t size, GeomType t, int srid, Envelope* mbr)
61  : Curve(t, srid, mbr),
62  m_zA(nullptr),
63  m_mA(nullptr),
64  m_nPts(size)
65 {
66  m_coords = static_cast<Coord2D*>(malloc(16 * size));
67 
68  if((m_gType & 0xF00) == 0x300)
69  m_zA = static_cast<double*>(malloc(8 * size));
70 
71  if((m_gType & 0xF00) == 0x700)
72  m_mA = static_cast<double*>(malloc(8 * size));
73 
74  if((m_gType & 0xF00) == 0xB00)
75  {
76  assert(m_zA == nullptr);
77  assert(m_mA == nullptr);
78 
79  m_zA = static_cast<double*>(malloc(8 * size));
80  m_mA = static_cast<double*>(malloc(8 * size));
81  }
82 }
83 
85  : Curve(rhs),
86  m_zA(nullptr),
87  m_mA(nullptr),
88  m_nPts(0)
89 {
90  m_nPts = rhs.m_nPts;
91 
92  if(rhs.m_coords)
93  {
94  m_coords = static_cast<Coord2D*>(malloc(16 * rhs.m_nPts));
95  memcpy(m_coords, rhs.m_coords, 16 * rhs.m_nPts);
96  }
97 
98  if(rhs.m_zA)
99  {
100  m_zA = static_cast<double*>(malloc(8 * rhs.m_nPts));
101  memcpy(m_zA, rhs.m_zA, 8 * rhs.m_nPts);
102  }
103 
104  if(rhs.m_mA)
105  {
106  m_mA = static_cast<double*>(malloc(8 * rhs.m_nPts));
107  memcpy(m_mA, rhs.m_mA, 8 * rhs.m_nPts);
108  }
109 }
110 
112 {
113  free(m_coords);
114  free(m_zA);
115  free(m_mA);
116 }
117 
119 {
120  if(this != &rhs)
121  {
122  Curve::operator=(rhs);
123 
124  makeEmpty();
125 
126  if( rhs.m_coords )
127  {
128  m_coords = static_cast<Coord2D*>(malloc(sizeof( Coord2D ) * rhs.m_nPts));
129  memcpy( m_coords, rhs.m_coords, sizeof( Coord2D ) * rhs.m_nPts );
130  }
131  else
132  {
133  m_coords = nullptr;
134  }
135 
136  if( rhs.m_zA )
137  {
138  m_zA = static_cast<double*>(malloc(sizeof( double ) * rhs.m_nPts));
139  memcpy( m_zA, rhs.m_zA, sizeof( double ) * rhs.m_nPts );
140  }
141  else
142  {
143  m_zA = nullptr;
144  }
145 
146  if( rhs.m_mA )
147  {
148  m_mA = static_cast<double*>(malloc(sizeof( double ) * rhs.m_nPts));
149  memcpy( m_mA, rhs.m_mA, sizeof( double ) * rhs.m_nPts);
150  }
151  else
152  {
153  m_mA = nullptr;
154  }
155 
156  m_nPts = rhs.m_nPts;
157  }
158 
159  return *this;
160 }
161 
163 {
164  return new LineString(*this);
165 }
166 
167 const std::string& te::gm::LineString::getGeometryType() const throw()
168 {
169  return sm_typeName;
170 }
171 
172 void te::gm::LineString::setSRID(int srid) throw()
173 {
174  m_srid = srid;
175 }
176 
178 {
179 #ifdef TERRALIB_MOD_SRS_ENABLED
180  if(srid == m_srid)
181  return;
182 
183  std::unique_ptr<te::srs::Converter> converter(new te::srs::Converter());
184 
185  converter->setSourceSRID(getSRID());
186 
187  converter->setTargetSRID(srid);
188 
189  double* pt = (double*)(m_coords);
190 
191  converter->convert(pt, &(pt[1]), static_cast<long>(size()), 2);
192 
193  if(m_mbr)
194  computeMBR(false);
195 
196  m_srid = srid;
197 #else
198  throw Exception(TE_TR("transform method is not supported!"));
199 #endif // TERRALIB_MOD_SRS_ENABLED
200 }
201 
202 void te::gm::LineString::computeMBR(bool /*cascade*/) const throw()
203 {
204  if(m_mbr == nullptr)
205  m_mbr = new Envelope;
206  else
207  m_mbr->makeInvalid();
208 
209  const std::size_t nPts = size();
210 
211  if(nPts == 0)
212  return;
213 
214  double minx = m_coords[0].x;
215  double miny = m_coords[0].y;
216  double maxx = m_coords[0].x;
217  double maxy = m_coords[0].y;
218 
219  for(std::size_t i = 1; i < nPts; ++i)
220  {
221  if(minx > m_coords[i].x) minx = m_coords[i].x;
222  if(miny > m_coords[i].y) miny = m_coords[i].y;
223  if(maxx < m_coords[i].x) maxx = m_coords[i].x;
224  if(maxy < m_coords[i].y) maxy = m_coords[i].y;
225  }
226 
227  m_mbr->m_llx = minx;
228  m_mbr->m_lly = miny;
229  m_mbr->m_urx = maxx;
230  m_mbr->m_ury = maxy;
231 }
232 
233 te::gm::Geometry* te::gm::LineString::locateBetween(const double& /*mStart*/, const double& /*mEnd*/) const throw(Exception)
234 {
235  return nullptr;
236 }
237 
238 //double te::gm::LineString::getLength() const
239 //{
240 // return 0.0;
241 //}
242 
243 std::unique_ptr<te::gm::Point> te::gm::LineString::getStartPoint() const
244 {
245  assert(size() > 1);
246  return getPointN(0);
247 }
248 
249 std::unique_ptr<te::gm::Point> te::gm::LineString::getEndPoint() const
250 {
251  assert(size() > 1);
252  return getPointN(m_nPts - 1);
253 }
254 
256 {
257  assert(size() >= 2);
258  return m_coords[0] == m_coords[m_nPts - 1];
259 }
260 
262 {
263  if(size < m_nPts)
264  { // just decrease the known capacity... realloc just if needed!
265  m_nPts = size;
266  return;
267  }
268 
269  Coord2D* coords = static_cast<Coord2D*>(malloc(16 * size));
270  memcpy(coords, m_coords, (m_nPts < size ? m_nPts * 16 : size * 16));
271  free(m_coords);
272  m_coords = coords;
273 
274  if((m_gType & 0xF00) == 0x300)
275  {
276  double* zA = static_cast<double*>(malloc(8 * size));
277  memcpy(zA, m_zA, (m_nPts < size ? m_nPts : size));
278  free(m_zA);
279  m_zA = zA;
280  }
281 
282  if((m_gType & 0xF00) == 0x700)
283  {
284  double* mA = static_cast<double*>(malloc(8 * size));
285  memcpy(mA, m_mA, (m_nPts < size ? m_nPts : size));
286  free(m_mA);
287  m_mA = mA;
288  }
289 
290  if((m_gType & 0xF00) == 0xB00)
291  {
292  double* zA = static_cast<double*>(malloc(8 * size));
293  memcpy(zA, m_zA, (m_nPts < size ? m_nPts : size));
294  free(m_zA);
295  m_zA = zA;
296 
297  double* mA = static_cast<double*>(malloc(8 * size));
298  memcpy(mA, m_mA, (m_nPts < size ? m_nPts : size));
299  free(m_mA);
300  m_mA = mA;
301  }
302 
303  m_nPts = size;
304 }
305 
307 {
308  free(m_coords);
309  free(m_zA);
310  free(m_mA);
311 
312  m_coords = nullptr;
313  m_zA = nullptr;
314  m_mA = nullptr;
315 
316  m_nPts = 0;
317 }
318 
319 std::unique_ptr<te::gm::Point> te::gm::LineString::getPointN(std::size_t i) const
320 {
321  assert(i < m_nPts);
322 
323  if ((m_gType & 0xF00) == 0x000)
324  {
325  std::unique_ptr<te::gm::Point> p(new Point(m_coords[i].x, m_coords[i].y, m_srid));
326  return p;
327  }
328 
329  if ((m_gType & 0xF00) == 0x300)
330  {
331  std::unique_ptr<te::gm::Point> p(new Point(m_srid, PointZType));
332  p->setX(m_coords[i].x);
333  p->setY(m_coords[i].y);
334  p->setZ(m_zA[i]);
335 
336  return p;
337  }
338  if((m_gType & 0xF00) == 0x700)
339  {
340  std::unique_ptr<te::gm::Point> p(new Point(m_srid, PointMType));
341  p->setX(m_coords[i].x);
342  p->setY(m_coords[i].y);
343  p->setM(m_mA[i]);
344  return p;
345  }
346 
347  std::unique_ptr<te::gm::Point> p(new Point(m_srid, PointZMType));
348  p->setX(m_coords[i].x);
349  p->setY(m_coords[i].y);
350  p->setZ(m_zA[i]);
351  p->setM(m_mA[i]);
352  return p;
353 }
354 
355 void te::gm::LineString::setPointN(std::size_t i, const Point& p)
356 {
357  assert(i < m_nPts);
358 
359  m_coords[i].x = p.getX();
360  m_coords[i].y = p.getY();
361 
362  if(m_zA)
363  m_zA[i] = p.getZ();
364 
365  if(m_mA)
366  m_mA[i] = p.getM();
367 }
368 
369 void te::gm::LineString::setPoint(std::size_t i, const double& x, const double& y)
370 {
371  assert(i < size());
372  m_coords[i].x = x;
373  m_coords[i].y = y;
374 }
375 
376 void te::gm::LineString::setPointZ(std::size_t i, const double& x, const double& y, const double& z)
377 {
378  assert((i < m_nPts) && (m_zA != nullptr));
379  m_coords[i].x = x;
380  m_coords[i].y = y;
381  m_zA[i] = z;
382 }
383 
384 void te::gm::LineString::setPointM(std::size_t i, const double& x, const double& y, const double& m)
385 {
386  assert((i < m_nPts) && (m_mA != nullptr));
387  m_coords[i].x = x;
388  m_coords[i].y = y;
389  m_mA[i] = m;
390 }
391 
392 void te::gm::LineString::setPointZM(std::size_t i, const double& x, const double& y, const double& z, const double& m)
393 {
394  assert((i < m_nPts) && (m_zA != nullptr) && (m_mA != nullptr));
395  m_coords[i].x = x;
396  m_coords[i].y = y;
397  m_zA[i] = z;
398  m_mA[i] = m;
399 }
400 
401 const double& te::gm::LineString::getX(std::size_t i) const
402 {
403  assert(i < size());
404  return m_coords[i].x;
405 }
406 
407 const double& te::gm::LineString::getY(std::size_t i) const
408 {
409  assert(i < size());
410  return m_coords[i].y;
411 }
412 
413 const double& te::gm::LineString::getZ(std::size_t i) const
414 {
415  assert((i < m_nPts) && (m_zA != nullptr));
416  return m_zA[i];
417 }
418 
419 const double& te::gm::LineString::getM(std::size_t i) const
420 {
421  assert((i < m_nPts) && (m_mA != nullptr));
422  return m_mA[i];
423 }
424 
425 
426 void te::gm::LineString::setX(std::size_t i, const double& x)
427 {
428  assert(i < size());
429  m_coords[i].x = x;
430 }
431 
432 void te::gm::LineString::setY(std::size_t i, const double& y)
433 {
434  assert(i < size());
435  m_coords[i].y = y;
436 }
437 
438 void te::gm::LineString::setZ(std::size_t i, const double& z)
439 {
440  assert((i < m_nPts) && (m_zA != nullptr));
441  m_zA[i] = z;
442 }
443 
444 void te::gm::LineString::setM(std::size_t i, const double& m)
445 {
446  assert((i < m_nPts) && (m_mA != nullptr));
447  m_mA[i] = m;
448 }
449 
void setZ(std::size_t i, const double &z)
It sets the n-th z coordinate value.
std::unique_ptr< Point > getEndPoint() const
It returns the curve end point.
void makeInvalid()
It will invalidated the envelope.
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
LineString(GeomType t, int srid=0, Envelope *mbr=0)
It initializes the linestring with the specified spatial reference system id and envelope.
void computeMBR(bool cascade) const
It computes the minimum bounding rectangle for the linestring.
double y
y-coordinate.
Definition: Coord2D.h:114
void setX(std::size_t i, const double &x)
It sets the n-th x coordinate value.
static const std::string sm_typeName
Definition: LineString.h:500
Configuration flags for the Vector Geometry Model of TerraLib.
double x
x-coordinate.
Definition: Coord2D.h:113
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
virtual te::dt::AbstractData * clone() const
It clones the linestring.
void makeEmpty()
It clears all the coordinates.
int m_srid
The Spatial Reference System code associated to the Geometry.
A point with x and y coordinate values.
double m_urx
Upper right corner x-coordinate.
std::unique_ptr< Point > getPointN(std::size_t i) const
It returns the specified point in this LineString.
virtual ~LineString()
Virtual destructor.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
virtual Curve & operator=(const Curve &rhs)
Assignment operator.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
double * m_zA
A pointer to z values.
Definition: LineString.h:494
bool isClosed() const
It returns true if the curve is closed (startPoint = endPoint).
std::size_t m_nPts
The number of coordinates of the LineString.
Definition: LineString.h:496
const double & getY(std::size_t i) const
It returns the n-th y coordinate value.
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
double m_llx
Lower left corner x-coordinate.
An Envelope defines a 2D rectangular region.
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
double * getM() const
It returns a pointer to the internal array of m-values.
Definition: LineString.h:484
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
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
An Envelope defines a 2D rectangular region.
const double & getX(std::size_t i) const
It returns the n-th x coordinate value.
void setNumCoordinates(std::size_t size)
It reserves room for the number of coordinates in this LineString.
te::gm::Polygon * p
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
Coord2D * m_coords
A pointer to x, y values.
Definition: LineString.h:493
void setPointZ(std::size_t i, const double &x, const double &y, const double &z)
It sets the value of the specified point.
virtual LineString & operator=(const LineString &rhs)
Assignment operator.
const double & getZ() const
It returns the Point z-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:166
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Envelope * m_mbr
The geometry minimum bounding rectangle.
A class that converts a TerraLib geometry to a GEOS geometry.
double m_lly
Lower left corner y-coordinate.
void setM(std::size_t i, const double &m)
It sets the n-th m measure value.
A Converter is responsible for the conversion of coordinates between different Coordinate Systems (CS...
Definition: Converter.h:53
Geometry * locateBetween(const double &mStart, const double &mEnd) const
It returns a derived geometry collection value according to the range of coordinate values inclusivel...
void setPointZM(std::size_t i, const double &x, const double &y, const double &z, const double &m)
It sets the value of the specified point.
double m_ury
Upper right corner y-coordinate.
void setSRID(int srid)
It sets the Spatial Reference System ID of the linestring.
const double & getM() const
It returns the Point m-coordinate value, if it has one or DoubleNotANumber otherwise.
Definition: Point.h:180
void setPointM(std::size_t i, const double &x, const double &y, const double &m)
It sets the value of the specified point.
GeomType m_gType
Internal geometry type.
LineString is a curve with linear interpolation between points.
void setPointN(std::size_t i, const Point &p)
It sets the value of the specified point to this new one.
void setY(std::size_t i, const double &y)
It sets the n-th y coordinate value.
An utility struct for representing 2D coordinates.
An exception class for the Geometry module.
double * getZ() const
It returns a pointer to the internal array of z-values.
Definition: LineString.h:470
std::unique_ptr< Point > getStartPoint() const
The length of this Curve in its associated spatial reference.
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
double * m_mA
A pointer to m values.
Definition: LineString.h:495
void transform(int srid)
It converts the coordinate values of the linestring to the new spatial reference system.
std::size_t size() const
It returns the number of points (vertexes) in the geometry.
Definition: LineString.h:262
const std::string & getGeometryType() const
The name of instantiable subtype is: LineString.