Trajectory.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 Trajectory.cpp
22 
23  \brief This file contains a class to represent a trajectory.
24 */
25 
26 // TerraLib
27 #include "../../../datatype/DateTime.h"
28 #include "../../../datatype/DateTimePeriod.h"
29 #include "../../../datatype/DateTimeInstant.h"
30 #include "../../../datatype/DateTimeUtils.h"
31 #include "../../../geometry/Geometry.h"
32 #include "../../../geometry/Utils.h"
33 #include "../../../sam/rtree/Index.h"
34 
35 //ST
36 #include "Trajectory.h"
37 #include "../timeseries/TimeSeries.h"
38 #include "../interpolator/AbstractTrajectoryInterp.h"
39 #include "../interpolator/NearestGeometryAtTimeInterp.h"
40 
41 //STL
42 #include <algorithm>
43 
45  : m_interpolator(&NearestGeometryAtTimeInterp::getInstance()), m_id("-1")
46 
47 {
48  //create the internal empty RTree
50 }
51 
52 te::st::Trajectory::Trajectory(const std::string& id)
53  : m_interpolator(&NearestGeometryAtTimeInterp::getInstance()), m_id(id)
54 
55 {
56  //create the internal empty RTree
58 }
59 
61  const std::string& id)
62  : m_interpolator(interp), m_id(id)
63 
64 {
65  //create the internal empty RTree
67 }
68 
70  const std::string& id)
71  : m_observations(obs),
73  m_id(id)
74 
75 {
76  //create the internal empty RTree
78 }
79 
82  const std::string& id)
83  : m_observations(obs), m_interpolator(interp), m_id(id)
84 
85 {
86  //create the internal empty RTree
88 }
89 
92  const std::string& id)
93  : m_interpolator(interp), m_id(id)
94 
95 {
96  //create the internal empty RTree
98 
99  TrajectoryIterator it = patch.begin();
100  while(it!=patch.end())
101  {
102  //add shared pointers and creates the internal RTree
103  m_observations.insert(*it);
104  ++it;
105  }
106 }
107 
109 
110  = default;
111 
113 {
114  if(this != &other)
115  {
118  m_id = other.m_id;
119  m_rtree = other.m_rtree; //shared pointer
120  }
121  return *this;
122 }
123 
125 {
126  Trajectory* result = new Trajectory(m_interpolator, m_id);
127  TrajectoryObservationSet::const_iterator it = m_observations.begin();
128  while(it != m_observations.end())
129  {
130  te::dt::DateTime* t = static_cast<te::dt::DateTime*>(it->first->clone());
131  te::gm::Geometry* g = static_cast<te::gm::Geometry*>(it->second->clone());
132  result->add(t,g);
133  ++it;
134  }
135  return result;
136 }
137 
139 {
140  return m_observations;
141 }
142 
144 {
145  return m_interpolator;
146 }
147 
149 {
150  m_interpolator = interp;
151 }
152 
153 std::string te::st::Trajectory::getId() const
154 {
155  return m_id;
156 }
157 
158 void te::st::Trajectory::setId(const std::string& id)
159 {
160  m_id = id;
161 }
162 
164 {
165  te::dt::DateTimeShrPtr t(time);
166  te::gm::GeometryShrPtr g(geom);
167 
168  std::pair<te::dt::DateTimeShrPtr, te::gm::GeometryShrPtr> pr(t,g);
169  add(pr);
170 }
171 
173 {
174  m_observations.insert(p);
175  const te::gm::Envelope* env = p.second->getMBR();
176  m_rtree->insert(*env, p.first.get());
177 }
178 
179 std::size_t te::st::Trajectory::size() const
180 {
181  return m_observations.size();
182 }
183 
185 {
186  TrajectoryObservationSet::const_iterator it = m_observations.begin();
187  return TrajectoryIterator(it);
188 }
189 
191 {
192  TrajectoryObservationSet::const_iterator it = m_observations.end();
193  return TrajectoryIterator(it);
194 }
195 
197 {
198  te::dt::DateTimeShrPtr aux(static_cast<te::dt::DateTime*>(t->clone()));
199  TrajectoryObservationSet::const_iterator it = m_observations.find(aux);
200  return TrajectoryIterator (it);
201 }
202 
203 std::unique_ptr<te::gm::Geometry> te::st::Trajectory::getGeometry(te::dt::DateTime* t) const
204 {
205  te::dt::DateTimeShrPtr aux(static_cast<te::dt::DateTime*>(t->clone()));
206  TrajectoryObservationSet::const_iterator it = m_observations.find(aux);
207  if(it!=m_observations.end())
208  return std::unique_ptr<te::gm::Geometry>(static_cast<te::gm::Geometry*>(it->second->clone()));
209 
210  return std::unique_ptr<te::gm::Geometry>(m_interpolator->estimate(*this,t));
211 }
212 
213 std::unique_ptr<te::dt::DateTimePeriod> te::st::Trajectory::getTemporalExtent() const
214 {
215  te::dt::DateTime* bt = m_observations.begin()->first.get();
216  te::dt::DateTime* et = m_observations.rbegin()->first.get();
217  //This function does not take the ownership of the given times
218  return std::unique_ptr<te::dt::DateTimePeriod>(te::dt::GetTemporalExtent(bt, et));
219 }
220 
222 {
223  return m_rtree->getMBR();
224 }
225 
228  te::dt::TemporalRelation r) const
229 {
230  //Note: the end iterator of a patch points to the position AFTER the last required observation
231  TrajectoryObservationSet::const_iterator itb = m_observations.end();
232  TrajectoryObservationSet::const_iterator ite = m_observations.end();
233 
234  te::dt::DateTimeShrPtr shrdt(static_cast<te::dt::DateTime*>(dt.clone()));
235 
236  if(r==te::dt::AFTER) //2
237  {
238  itb = m_observations.upper_bound(shrdt);
239  return TrajectoryPatch(itb,ite);
240  }
241  if(r==(te::dt::AFTER | te::dt::EQUALS)) // 2 OU 8 = 10
242  {
243  itb = m_observations.find(shrdt);
244  if(itb==m_observations.end())
245  itb = m_observations.upper_bound(shrdt);
246  return TrajectoryPatch(itb,ite);
247  }
248  if(r==te::dt::BEFORE) // 1
249  {
250  itb = m_observations.begin();
251  ite = m_observations.find(shrdt);
252  if(ite==m_observations.end())
253  ite = m_observations.upper_bound(shrdt);
254  return TrajectoryPatch(itb,ite);
255  }
256  if(r==(te::dt::BEFORE | te::dt::EQUALS)) // 1 OU 8 = 9
257  {
258  itb = m_observations.begin();
259  ite = m_observations.upper_bound(shrdt);
260  return TrajectoryPatch(itb,ite);
261  }
262  if(r==te::dt::DURING) //4
263  {
264  te::dt::DateTimeShrPtr t1(static_cast<te::dt::DateTimePeriod*>(shrdt.get())->getInitialInstant());
265  te::dt::DateTimeShrPtr t2(static_cast<te::dt::DateTimePeriod*>(shrdt.get())->getFinalInstant());
266  itb = m_observations.find(t1);
267  if(itb==m_observations.end())
268  itb = m_observations.upper_bound(t1);
269  ite = m_observations.upper_bound(t2);
270  return TrajectoryPatch(itb,ite);
271  }
272  if(r==te::dt::EQUALS) //8
273  {
274  std::pair<TrajectoryObservationSet::const_iterator, TrajectoryObservationSet::const_iterator> itPair;
275  itPair = m_observations.equal_range(shrdt);
276  itb = itPair.first;
277  ite = itPair.second;
278  if(ite!= m_observations.end())
279  ++ite;
280  return TrajectoryPatch(itb,ite);
281  }
282 
283  return TrajectoryPatch(itb,ite);
284 }
285 
286 void
288  std::vector<TrajectoryPatch>& result) const
289 {
290  //Note: the end iterator of a patch points to the position AFTER the last required observation
291  if(r!=te::gm::INTERSECTS)
292  return;
293 
294  //times when the trajectory intersects the envelope
295  std::vector<te::dt::DateTime*> report;
296  m_rtree->search(g, report);
297  std::sort(report.begin(), report.end(), te::dt::CompareDateTime());
298 
299  std::vector<te::dt::DateTime*>::const_iterator itResultBegin = report.begin();
300  std::vector<te::dt::DateTime*>::const_iterator itResultEnd = report.end();
301 
302  te::dt::DateTimeShrPtr shrdt(static_cast<te::dt::DateTime*>((*itResultBegin)->clone()));
303  TrajectoryObservationSet::const_iterator itOriginBegin = m_observations.find(shrdt);
304  TrajectoryObservationSet::const_iterator itOriginEnd = m_observations.end();
305 
306  TrajectoryObservationSet::const_iterator pathBegin;
307  TrajectoryObservationSet::const_iterator pathEnd;
308 
309  while(itResultBegin!=itResultEnd && itOriginBegin!=itOriginEnd)
310  {
311  pathBegin = itOriginBegin; //The beginning of a patch
312 
313  //Enquanto os ponteiros forem iguais estamos no meio de um patch
314  while( (itResultBegin!=itResultEnd) && (itOriginBegin!=itOriginEnd) &&
315  (*itResultBegin == itOriginBegin->first.get()))
316  {
317  pathEnd = itOriginBegin;
318  ++itResultBegin;
319  ++itOriginBegin;
320  }
321 
322  //get the patch
323  //the end of a patch MUST point to the position AFTER the required observations
324  if(pathEnd!=itOriginEnd)
325  ++pathEnd;
326  TrajectoryPatch r(pathBegin, pathEnd);
327  result.push_back(r);
328 
329  //update the origin begin
330  if(itResultBegin!=itResultEnd)
331  {
332  shrdt.reset(static_cast<te::dt::DateTime*>((*itResultBegin)->clone()));
333  itOriginBegin = m_observations.find(shrdt);
334  }
335  }
336 
337  return;
338 }
339 
340 void
342  std::vector<TrajectoryPatch>& result) const
343 {
344  if(r!=te::gm::INTERSECTS)
345  return;
346 
347  //times when the trajectory intersects the envelope
348  std::vector<te::dt::DateTime*> report;
349  m_rtree->search(*geom.getMBR(), report);
350 
351  std::sort(report.begin(), report.end(), te::dt::CompareDateTime());
352 
353  std::vector<te::dt::DateTime*>::const_iterator itResultBegin = report.begin();
354  std::vector<te::dt::DateTime*>::const_iterator itResultEnd = report.end();
355 
356  te::dt::DateTimeShrPtr shrdt(static_cast<te::dt::DateTime*>((*itResultBegin)->clone()));
357  TrajectoryObservationSet::const_iterator itOriginBegin = m_observations.find(shrdt);
358  TrajectoryObservationSet::const_iterator itOriginEnd = m_observations.end();
359 
360  TrajectoryObservationSet::const_iterator pathBegin;
361  TrajectoryObservationSet::const_iterator pathEnd;
362 
363  while(itResultBegin!=itResultEnd && itOriginBegin!=itOriginEnd)
364  {
365  if(!geom.intersects(itOriginBegin->second.get())) //looking for a patch
366  {
367  ++itResultBegin;
368  if(itResultBegin!=itResultEnd)
369  {
370  shrdt.reset(static_cast<te::dt::DateTime*>((*itResultBegin)->clone()));
371  itOriginBegin = m_observations.find(shrdt);
372  }
373  }
374  else //the beginning of a patch was found
375  {
376  pathBegin = itOriginBegin;
377  //enquanto os datetimes forem sequenciais e as geometrias interceptam geom estamos no meio do patch!
378  while( itResultBegin!=itResultEnd && itOriginBegin!=itOriginEnd
379  && (*itResultBegin == itOriginBegin->first.get())
380  && geom.intersects(itOriginBegin->second.get()))
381  {
382  pathEnd = itOriginBegin;
383  ++itResultBegin;
384  if(itResultBegin!=itResultEnd)
385  {
386  shrdt.reset(static_cast<te::dt::DateTime*>((*itResultBegin)->clone()));
387  itOriginBegin = m_observations.find(shrdt);
388  }
389  }
390 
391  //get the patch
392  //the end of a patch MUST point to the position AFTER the required observations
393  if(pathEnd!=itOriginEnd)
394  ++pathEnd;
395  TrajectoryPatch r(pathBegin, pathEnd);
396  result.push_back(r);
397 
398  }//else
399  }//while
400 
401  return;
402 }
403 
404 
407  std::vector<TrajectoryPatch>& result) const
408 {
409  //first: find the patch that satisfy the temporal relation
410  TrajectoryPatch res1 = getPatch(dt, tr);
411 
412  //second: find the patches using the spatial relation
413  Trajectory tj(res1, m_interpolator, m_id);
414  std::vector<TrajectoryPatch> res2;
415  tj.getPatches(e, sr, res2); //sr: must be INTERSECTS for while
416 
417  std::vector<TrajectoryPatch>::const_iterator it = res2.begin();
418 
419  TrajectoryObservationSet::const_iterator itObsEnd = m_observations.end();
420 
421  while(it!=res2.end())
422  {
423  TrajectoryIterator itAuxBegin = (*it).begin();
424  TrajectoryIterator itAuxEnd = (*it).end();
425 
426  TrajectoryIterator itBegin(itObsEnd);
427  TrajectoryIterator itEnd(itObsEnd);
428 
429  //Get the first position
430  if(itAuxBegin!=tj.end())
431  {
432  te::dt::DateTime* t = itAuxBegin.getTime();
433  itBegin = at(t);
434  }
435 
436  //Get the last position
437  if(itAuxEnd==tj.end())
438  --itAuxEnd;
439 
440  te::dt::DateTime* t = itAuxEnd.getTime();
441  itEnd = at(t);
442  ++itEnd;
443 
444  //Get the patch
445  if(itBegin!=itEnd)
446  {
447  TrajectoryPatch p(itBegin, itEnd);
448  result.push_back(p);
449  }
450 
451  ++it;
452  }
453 
454  return;
455 }
456 
459  std::vector<TrajectoryPatch>& result) const
460 {
461  //first: find the patch that satisfy the temporal relation
462  TrajectoryPatch res1 = getPatch(dt, tr);
463 
464  //second: find the patches using the spatial relation
465  Trajectory tj(res1, m_interpolator, m_id);
466  std::vector<TrajectoryPatch> res2;
467  tj.getPatches(geom, sr, res2); //sr: must be INTERSECTS for while
468 
469  std::vector<TrajectoryPatch>::const_iterator it = res2.begin();
470 
471  TrajectoryObservationSet::const_iterator itObsEnd = m_observations.end();
472 
473  while(it!=res2.end())
474  {
475  TrajectoryIterator itAuxBegin = (*it).begin();
476  TrajectoryIterator itAuxEnd = (*it).end();
477 
478  TrajectoryIterator itBegin(itObsEnd);
479  TrajectoryIterator itEnd(itObsEnd);
480 
481  //Get the first position
482  if(itAuxBegin!=tj.end())
483  {
484  te::dt::DateTime* t = itAuxBegin.getTime();
485  itBegin = at(t);
486  }
487 
488  //Get the last position
489  if(itAuxEnd==tj.end())
490  --itAuxEnd;
491 
492  te::dt::DateTime* t = itAuxEnd.getTime();
493  itEnd = at(t);
494  ++itEnd;
495 
496  //Get the patch
497  if(itBegin!=itEnd)
498  {
499  TrajectoryPatch p(itBegin, itEnd);
500  result.push_back(p);
501  }
502 
503  ++it;
504  }
505 
506  return;
507 }
508 
510  const te::gm::Geometry& /*geom*/, te::st::SpatioTemporalRelation /*str*/,
511  const std::vector<TrajectoryPatch>& /*result*/) const
512 {
513 }
514 
515 std::unique_ptr<te::st::TimeSeries> te::st::Trajectory::getDistance(const Trajectory& other) const
516 {
517  std::unique_ptr<te::st::TimeSeries> result(new te::st::TimeSeries());
518  TrajectoryObservationSet::const_iterator it = m_observations.begin();
519  //te::st::TimeSeries* result =
520  while(it!=m_observations.end())
521  {
522  te::dt::DateTime* t = it->first.get();
523  std::unique_ptr<te::gm::Geometry> otherGeom(other.getGeometry(t));
524 
525  double dist = it->second->distance(otherGeom.get());
526 
527  //insert into the new time series!
528  result->add(static_cast<te::dt::DateTime*>(t->clone()),dist);
529  ++it;
530  }
531  return result;
532 }
533 
534 std::unique_ptr<te::st::TimeSeries> te::st::Trajectory::getDistance(
535  const te::gm::Geometry& /*geom*/)
536 {
537  std::unique_ptr<te::st::TimeSeries> res;
538 
539  return res;
540 }
541 
static boost::posix_time::ptime bt
AbstractTrajectoryInterp * m_interpolator
The interpolator used to estimate non-observed times.
Definition: Trajectory.h:460
This file contains a class to represent a trajectory.
void setId(const std::string &id)
It sets the trajectory id.
Definition: Trajectory.cpp:158
A struct to represent a patch or a continuous piece of a trajectory.
A class that represents an R-tree.
TrajectoryIterator end() const
It returns an iterator that points to the end of the trajectory.
Definition: Trajectory.cpp:190
TrajectoryIterator end() const
TemporalRelation
Temporal relations between date and time (Source: Allen, 1991).
Trajectory()
Empty constructor.
Definition: Trajectory.cpp:44
An auxiliary struct to compare two datetime pointers.
Definition: DateTime.h:117
SpatialRelation
Spatial relations between geometric objects.
It is an interpolation function the estimates the nearest geometry at a given non-observed time of a ...
const TrajectoryObservationSet & getObservations() const
It returns the trajectory observations.
Definition: Trajectory.cpp:138
virtual bool intersects(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object spatially intersects rhs geometry.
TrajectoryIterator at(te::dt::DateTime *t) const
It returns an iterator that points to an observation at a given time.
Definition: Trajectory.cpp:196
std::map< te::dt::DateTimeShrPtr, te::gm::GeometryShrPtr, CompareShrDateTime > TrajectoryObservationSet
TrajectoryPatch getPatch(const te::dt::DateTime &dt, te::dt::TemporalRelation r=te::dt::DURING) const
It returns a trajectory subset that satisfies a given temporal relation.
Definition: Trajectory.cpp:227
boost::shared_ptr< DateTime > DateTimeShrPtr
Definition: DateTime.h:126
TrajectoryObservationSet m_observations
The trajectory observations.
Definition: Trajectory.h:459
An abstract class for an interpolation function or interpolator that estimates geometries at non-obse...
SpatioTemporalRelation
An enum for the types of spatiotemporal relation.
std::pair< te::dt::DateTimeShrPtr, te::gm::GeometryShrPtr > TrajectoryObservation
std::string getId() const
It returns the trajectory id.
Definition: Trajectory.cpp:153
const Envelope * getMBR() const _NOEXCEPT_OP(true)
It returns the minimum bounding rectangle for the geometry in an internal representation.
An Envelope defines a 2D rectangular region.
static te::dt::TimeDuration dt(20, 30, 50, 11)
void getPatches(const te::gm::Envelope &g, te::gm::SpatialRelation r, std::vector< TrajectoryPatch > &result) const
It returns trajectory subsets that satisfy a given spatial relation.
Definition: Trajectory.cpp:287
te::gm::Polygon * p
virtual AbstractData * clone() const =0
It returns a clone of this object.
std::unique_ptr< te::dt::DateTimePeriod > getTemporalExtent() const
It returns the temporal extent of the trajectory observations.
Definition: Trajectory.cpp:213
void setInterpolator(AbstractTrajectoryInterp *interp)
It sets the interpolator associated to the path.
Definition: Trajectory.cpp:148
te::gm::Envelope getSpatialExtent() const
It returns the spatial extent of the trajectory observations.
Definition: Trajectory.cpp:221
Trajectory * clone() const
It returns a clone of this trajectory.
Definition: Trajectory.cpp:124
te::dt::DateTime * getTime() const
It returns the datetime pointed by the internal cursor.
Trajectory & operator=(const Trajectory &other)
Copy assignment operator.
Definition: Trajectory.cpp:112
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
std::size_t size() const
It returns the size of the trajectory observations.
Definition: Trajectory.cpp:179
TrajectoryIterator begin() const
virtual ~Trajectory()
Virtual destructor.
virtual std::unique_ptr< te::gm::Geometry > estimate(const Trajectory &tj, te::dt::DateTime *time) const =0
It estimates a geometry of a trajectory at a given non-observed time .
A class to represent time series.
Definition: TimeSeries.h:66
std::unique_ptr< te::gm::Geometry > getGeometry(te::dt::DateTime *t) const
It returns the geometry associated to a given date and time.
Definition: Trajectory.cpp:203
A class to represent trajectory.
Definition: Trajectory.h:75
TjRTreeShrPtr m_rtree
The RTree to index the trajectory geometries.
Definition: Trajectory.h:462
TEDATATYPEEXPORT DateTimePeriod * GetTemporalExtent(const DateTime *t1, const DateTime *t2)
It returns the temporal extent of two date and time types.
std::string m_id
The trajectory identification.
Definition: Trajectory.h:461
A class to traverse the observations of a trajectory.
std::unique_ptr< TimeSeries > getDistance(const Trajectory &other) const
It returns the distance between two trajectories.
Definition: Trajectory.cpp:515
boost::shared_ptr< Geometry > GeometryShrPtr
void add(te::dt::DateTime *time, te::gm::Geometry *geom)
It adds an observation (time and geometry) into the trajectory.
Definition: Trajectory.cpp:163
AbstractTrajectoryInterp * getInterpolator() const
It returns the interpolator associated to the trajectory.
Definition: Trajectory.cpp:143
TrajectoryIterator begin() const
It returns an iterator that points to the first observation of the trajectory.
Definition: Trajectory.cpp:184