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