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