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