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