All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TimeSeries.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 TimeSeries.cpp
22 
23  \brief This file contains a class to represent a time series.
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 "../../../datatype/SimpleData.h"
32 #include "../../../datatype/AbstractData.h"
33 #include "../../../geometry/Geometry.h"
34 
35 //ST
36 #include "TimeSeries.h"
37 #include "TimeSeriesObservation.h"
38 #include "../interpolator/AbstractTimeSeriesInterp.h"
39 #include "../interpolator/NearestValueAtTimeInterp.h"
40 
42  : m_observations(),
43  m_interpolator(&NearestValueAtTimeInterp::getInstance()),
44  m_location(),
45  m_id()
46 {
47 }
48 
49 te::st::TimeSeries::TimeSeries(const std::string& id)
50  : m_observations(),
51  m_interpolator(&NearestValueAtTimeInterp::getInstance()),
52  m_location(),
53  m_id(id)
54 {
55 }
56 
58  : m_observations(),
59  m_interpolator(interp),
60  m_location(),
61  m_id(id)
62 {
63 }
64 
66  te::gm::Geometry* geom)
67  : m_observations(),
68  m_interpolator(interp),
69  m_location(geom),
70  m_id(id)
71 {
72 }
73 
75  const std::string& id, te::gm::Geometry* geom)
76  : m_observations(obs),
77  m_interpolator(interp),
78  m_location(geom),
79  m_id(id)
80 {
81 }
82 
84  const std::string& id, te::gm::Geometry* geom)
85  : m_observations(),
86  m_interpolator(interp),
87  m_location(geom),
88  m_id(id)
89 {
90  TimeSeriesIterator it = patch.begin();
91  while(it!=patch.end())
92  {
93  //add shared pointers
94  m_observations.insert(*it);
95  ++it;
96  }
97 }
99  : m_observations(ts.m_observations),
100  m_interpolator(ts.m_interpolator),
101  m_location(static_cast<te::gm::Geometry*>(ts.m_location->clone())),
102  m_id(ts.m_id)
103 {
104 }
105 
107 {
108  if(this != &other)
109  {
110  m_observations = other.m_observations;
111  m_interpolator = other.m_interpolator;
112  m_location.reset(static_cast<te::gm::Geometry*>(other.m_location->clone()));
113  m_id = other.m_id;
114  }
115  return *this;
116 }
117 
119 {
120  TimeSeries* result = new TimeSeries(m_interpolator, m_id, static_cast<te::gm::Geometry*>(m_location->clone()));
121  TimeSeriesObservationSet::const_iterator it = m_observations.begin();
122  TimeSeriesObservationSet::const_iterator ite = m_observations.end();
123  while(it != ite)
124  {
125  te::dt::DateTime* t = static_cast<te::dt::DateTime*>(it->getTime()->clone());
126  te::dt::AbstractData* v = it->getValue()->clone();
127  result->add(t,v);
128  ++it;
129  }
130  return result;
131 }
132 
134 {
135  return m_observations;
136 }
137 
139 {
140  return m_interpolator;
141 }
142 
144 {
145  m_interpolator = interp;
146 }
147 
148 std::string te::st::TimeSeries::getId() const
149 {
150  return m_id;
151 }
152 
153 void te::st::TimeSeries::setId(const std::string& id)
154 {
155  m_id = id;
156 }
157 
159 {
160  return m_location.get();
161 }
162 
164 {
165  m_location.reset(geom);
166 }
167 
169 {
170  TimeSeriesObservation item(time, value);
171  m_observations.insert(item);
172 }
173 
174 void te::st::TimeSeries::add(te::dt::DateTime* time, double value)
175 {
176  te::dt::Double* v = new te::dt::Double(value);
177  TimeSeriesObservation item(time, v);
178  m_observations.insert(item);
179 }
180 
182 {
183  te::dt::Int32* v = new te::dt::Int32(value);
184  TimeSeriesObservation item(time, v);
185  m_observations.insert(item);
186 }
187 
188 void te::st::TimeSeries::add(te::dt::DateTime* time, const std::string& value)
189 {
190  te::dt::String* v = new te::dt::String(value);
191  TimeSeriesObservation item(time, v);
192  m_observations.insert(item);
193 }
194 
196 {
197  m_observations.insert(item);
198 }
199 
200 std::size_t te::st::TimeSeries::size() const
201 {
202  return m_observations.size();
203 }
204 
206 {
207  TimeSeriesObservationSet::const_iterator it = m_observations.begin();
208  return TimeSeriesIterator(it);
209 }
210 
212 {
213  TimeSeriesObservationSet::const_iterator it = m_observations.end();
214  return TimeSeriesIterator(it);
215 }
216 
218 {
219  TimeSeriesObservation item(t,0);
220  TimeSeriesObservationSet::const_iterator it = m_observations.find(item);
221  return TimeSeriesIterator(it);
222 }
223 
224 std::auto_ptr<te::dt::AbstractData> te::st::TimeSeries::getValue(te::dt::DateTime* t) const
225 {
226  TimeSeriesObservation item(t,0);
227  TimeSeriesObservationSet::const_iterator it = m_observations.find(item);
228  TimeSeriesObservationSet::const_iterator ite = m_observations.end();
229  if(it!=ite)
230  return std::auto_ptr<te::dt::AbstractData>(it->getValue()->clone());
231  return std::auto_ptr<te::dt::AbstractData>(m_interpolator->estimate(*this,t));
232 }
233 
235 {
236  std::auto_ptr<te::dt::AbstractData> v(getValue(t));
237  return atof(v->toString().c_str());
238 }
239 
241 {
242  std::auto_ptr<te::dt::AbstractData> v(getValue(t));
243  return atoi(v->toString().c_str());
244 }
245 
247 {
248  std::auto_ptr<te::dt::AbstractData> v(getValue(t));
249  return v->toString();
250 }
251 
252 std::auto_ptr<te::dt::DateTimePeriod> te::st::TimeSeries::getTemporalExtent() const
253 {
254  TimeSeriesObservationSet::iterator it1 = m_observations.begin();
255  TimeSeriesObservationSet::reverse_iterator it2 = m_observations.rbegin();
256 
257  te::dt::DateTime* bt = it1->getTime();
258  te::dt::DateTime* et = it2->getTime();
259  //This function does not take the ownership of the given times
260  return std::auto_ptr<te::dt::DateTimePeriod> (te::dt::GetTemporalExtent(bt, et));
261 }
262 
263 void te::st::TimeSeries::getValueExtent(double& minValue, double& maxValue)
264 {
265  minValue = m_observations.get<1>().begin()->getDouble();
266  minValue = m_observations.get<1>().rbegin()->getDouble();
267  return;
268 }
269 
270 void te::st::TimeSeries::getValueExtent(int& minValue, int& maxValue)
271 {
272  minValue = m_observations.get<1>().begin()->getInt();
273  minValue = m_observations.get<1>().rbegin()->getInt();
274 }
275 
276 void te::st::TimeSeries::getValueExtent(std::string& minValue, std::string& maxValue)
277 {
278  minValue = m_observations.get<2>().begin()->getString();
279  minValue = m_observations.get<2>().rbegin()->getString();
280 }
281 
283  te::dt::TemporalRelation r) const
284 {
285  //Note: the end iterator of a patch points to the position AFTER the last required observation
286  TimeSeriesObservationSet::const_iterator itb = m_observations.end();
287  TimeSeriesObservationSet::const_iterator ite = m_observations.end();
288 
289  if(r==te::dt::AFTER) //2
290  {
291  TimeSeriesObservation item(static_cast<te::dt::DateTime*>(dt.clone()),0);
292  itb = m_observations.upper_bound(item);
293  return TimeSeriesPatch(itb,ite);
294  }
295  if(r==(te::dt::AFTER | te::dt::EQUALS)) // 2 OU 8 = 10
296  {
297  TimeSeriesObservation item(static_cast<te::dt::DateTime*>(dt.clone()),0);
298  itb = m_observations.find(item);
299  if(itb==m_observations.end())
300  itb = m_observations.upper_bound(item);
301  return TimeSeriesPatch(itb,ite);
302  }
303  if(r==te::dt::BEFORE) // 1
304  {
305  TimeSeriesObservation item(static_cast<te::dt::DateTime*>(dt.clone()),0);
306  itb = m_observations.begin();
307  ite = m_observations.find(item);
308  if(ite==m_observations.end())
309  ite = m_observations.upper_bound(item);
310  return TimeSeriesPatch(itb,ite);
311  }
312  if(r==(te::dt::BEFORE | te::dt::EQUALS)) // 1 OU 8 = 9
313  {
314  TimeSeriesObservation item(static_cast<te::dt::DateTime*>(dt.clone()),0);
315  itb = m_observations.begin();
316  ite = m_observations.upper_bound(item);
317  return TimeSeriesPatch(itb,ite);
318  }
319  if(r==te::dt::DURING) //4
320  {
321  std::auto_ptr<te::dt::DateTimePeriod> period(static_cast<te::dt::DateTimePeriod*>(dt.clone()));
322  TimeSeriesObservation item1(period->getInitialInstant(),0);
323  TimeSeriesObservation item2(period->getInitialInstant(),0);
324  itb = m_observations.find(item1);
325  if(itb==m_observations.end())
326  itb = m_observations.upper_bound(item1);
327  ite = m_observations.upper_bound(item2);
328  return TimeSeriesPatch(itb,ite);
329  }
330  if(r==te::dt::EQUALS) //8
331  {
332  TimeSeriesObservation item(static_cast<te::dt::DateTime*>(dt.clone()),0);
333  std::pair<TimeSeriesObservationSet::const_iterator, TimeSeriesObservationSet::const_iterator> itPair;
334  itPair = m_observations.equal_range(item);
335  itb = itPair.first;
336  ite = itPair.second;
337  if(ite!= m_observations.end())
338  ++ite;
339  return TimeSeriesPatch(itb,ite);
340  }
341 
342  return TimeSeriesPatch(itb,ite);
343 }
344 
346  std::vector<TimeSeriesPatch>& result) const
347 {
348  //Note: the end iterator of a patch points to the position AFTER the last required observation
349  std::map<te::dt::DateTime*, te::dt::AbstractData*, te::dt::CompareDateTime> resultTS;
350  getResultOrderedByTime(v, r, resultTS);
351 
353  te::dt::CompareDateTime>::const_iterator itResultBegin = resultTS.begin();
354  std::map<te::dt::DateTime*, te::dt::AbstractData*,
355  te::dt::CompareDateTime>::const_iterator itResultEnd = resultTS.end();
356 
357  TimeSeriesObservation item(static_cast<te::dt::DateTime*>(itResultBegin->first->clone()),0);
358  TimeSeriesObservationSet::const_iterator itOriginBegin = m_observations.find(item);
359  TimeSeriesObservationSet::const_iterator itOriginEnd = m_observations.end();
360 
361  TimeSeriesObservationSet::const_iterator patchBegin;
362  TimeSeriesObservationSet::const_iterator patchEnd;
363 
364  while(itResultBegin!=itResultEnd && itOriginBegin!=itOriginEnd)
365  {
366  patchBegin = itOriginBegin; //The beginning of a patch
367 
368  //Enquanto os ponteiros forem iguais estamos no meio de um patch
369  while( (itResultBegin!=itResultEnd) && (itOriginBegin!=itOriginEnd) &&
370  (itResultBegin->first == itOriginBegin->getTime()))
371  {
372  patchEnd = itOriginBegin;
373  ++itResultBegin;
374  ++itOriginBegin;
375  }
376 
377  //get the patch
378  //the end of a patch MUST point to the position AFTER the required observations
379  if(patchEnd!=itOriginEnd)
380  ++patchEnd;
381  TimeSeriesPatch r(patchBegin, patchEnd);
382  result.push_back(r);
383 
384  //update the origin begin
385  if(itResultBegin!=itResultEnd)
386  {
387  item.setTime(static_cast<te::dt::DateTime*>(itResultBegin->first->clone()));
388  itOriginBegin = m_observations.find(item);
389  }
390  } //while
391 
392  return;
393 }
394 
397  std::vector<TimeSeriesPatch>& result) const
398 {
399  TimeSeriesPatch patch = getPatch(dt,tr);
400  TimeSeries ts(patch,m_interpolator,"-1",0);
401  std::vector<TimeSeriesPatch> patches;
402  ts.getPatches(v,r,patches);
403 
404  std::vector<TimeSeriesPatch>::const_iterator it = patches.begin();
405  TimeSeriesObservationSet::const_iterator ite = m_observations.end();
406 
407  while(it!=patches.end())
408  {
409  TimeSeriesIterator itAuxBegin = (*it).begin();
410  TimeSeriesIterator itAuxEnd = (*it).end();
411 
412  TimeSeriesIterator itBegin(ite);
413  TimeSeriesIterator itEnd(ite);
414 
415  //Get the first position
416  if(itAuxBegin!=ts.end())
417  {
418  te::dt::DateTime* t = itAuxBegin.getTime();
419  itBegin = at(t);
420  }
421 
422  //Get the last position
423  if(itAuxEnd==ts.end())
424  --itAuxEnd;
425 
426  te::dt::DateTime* t = itAuxEnd.getTime();
427  itEnd = at(t);
428  ++itEnd;
429 
430  //Get the patch
431  if(itBegin!=itEnd)
432  {
433  TimeSeriesPatch p(itBegin, itEnd);
434  result.push_back(p);
435  }
436 
437  ++it;
438  }
439 
440  return;
441 }
442 
444  std::map<te::dt::DateTime*, te::dt::AbstractData*, te::dt::CompareDateTime>& result) const
445 {
446  TimeSeriesByValue::const_iterator itResultBeg = m_observations.get<1>().end();
447  TimeSeriesByValue::const_iterator itResultEnd = m_observations.get<1>().end();
448 
449  if(r==te::dt::LESS) //1
450  {
451  itResultBeg = m_observations.get<1>().begin();
452  itResultEnd = m_observations.get<1>().find(v);
453  if(itResultEnd==m_observations.get<1>().end())
454  itResultEnd = m_observations.get<1>().upper_bound(v);
455  }
456  else if(r==te::dt::MORE) //2
457  {
458  itResultBeg = m_observations.get<1>().upper_bound(v);
459  }
460  else if(r==te::dt::EQUAL) //4
461  {
462  std::pair<TimeSeriesByValue::const_iterator, TimeSeriesByValue::const_iterator> itPair;
463  itPair = m_observations.get<1>().equal_range(v);
464  itResultBeg = itPair.first;
465  itResultEnd = itPair.second;
466  if(itResultEnd!= m_observations.get<1>().end())
467  ++itResultEnd;
468  }
469  else if( r == (te::dt::LESS | te::dt::EQUAL)) // 1 (001) | 4 (100) = 5 (101)
470  {
471  itResultBeg = m_observations.get<1>().begin();
472  itResultEnd = m_observations.get<1>().upper_bound(v);
473  }
474  else if( r == (te::dt::MORE | te::dt::EQUAL)) // 2 (010) | 4 (100) = 6 (110)
475  {
476  itResultBeg = m_observations.get<1>().find(v);
477  if(itResultBeg==m_observations.get<1>().end())
478  itResultBeg = m_observations.get<1>().upper_bound(v);
479  }
480 
481  //Put the result in a map orderded by time
482  while(itResultBeg!=itResultEnd)
483  {
484  result.insert(std::pair<te::dt::DateTime*,te::dt::AbstractData*>(itResultBeg->getTime(), itResultBeg->getValue()));
485  ++itResultBeg;
486  }
487  return;
488 }
489 
491 {
492 }
493 
494 
This file contains a class to represent a time series observation.
SimpleData< std::string, STRING_TYPE > String
Definition: SimpleData.h:229
TimeSeries & operator=(const TimeSeries &other)
Copy assignment operator.
Definition: TimeSeries.cpp:106
TimeSeries * clone() const
It returns a clone of this time series.
Definition: TimeSeries.cpp:118
void setInterpolator(AbstractTimeSeriesInterp *interp)
It sets the interpolator associated to the time series.
Definition: TimeSeries.cpp:143
std::string getId() const
It returns the time series identifier.
Definition: TimeSeries.cpp:148
BasicRelation
Relations between simple attribute values.
Definition: Enums.h:158
TimeSeriesIterator at(te::dt::DateTime *t) const
It returns an iterator that points to an observation at a given time.
Definition: TimeSeries.cpp:217
A class to traverse the observations of a TimeSeries.
double getDouble(te::dt::DateTime *t) const
It returns the value as a double associated to a given date and time.
Definition: TimeSeries.cpp:234
TimeSeriesIterator end() const
std::auto_ptr< te::dt::DateTimePeriod > getTemporalExtent() const
It returns the temporal extent or range of the time series.
Definition: TimeSeries.cpp:252
virtual ~TimeSeries()
It returns time series subsets that satisfy the given relations.
Definition: TimeSeries.cpp:490
std::size_t size() const
It returns the size of the time series observation set.
Definition: TimeSeries.cpp:200
SimpleData< boost::int32_t, INT32_TYPE > Int32
Definition: SimpleData.h:221
TemporalRelation
Temporal relations between date and time (Source: Allen, 1991).
Definition: Enums.h:140
te::dt::DateTime * getTime() const
It returns the datetime pointed by the internal cursor.
An auxiliary struct to compare two datetime pointers.
Definition: DateTime.h:117
void getValueExtent(double &minValue, double &maxValue)
It returns the minimal and maximun values of the time series.
Definition: TimeSeries.cpp:263
This file contains a class to represent a time series.
A class to represent an observation (time and value) of a time series.
std::string getString(te::dt::DateTime *t) const
It returns the value as a string associated to a given date and time.
Definition: TimeSeries.cpp:246
int getInt(te::dt::DateTime *t) const
It returns the value as an integer associated to a given date and time.
Definition: TimeSeries.cpp:240
void add(te::dt::DateTime *time, te::dt::AbstractData *value)
It adds an observation (time and attribute value) into the time series.
Definition: TimeSeries.cpp:168
std::auto_ptr< te::dt::AbstractData > getValue(te::dt::DateTime *t) const
It returns the value associated to a given date and time.
Definition: TimeSeries.cpp:224
TimeSeriesIterator begin() const
AbstractTimeSeriesInterp * m_interpolator
The interpolator used to estimate values at non-observed times.
Definition: TimeSeries.h:532
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
TimeSeriesPatch getPatch(const te::dt::DateTime &dt, te::dt::TemporalRelation r=te::dt::DURING) const
It returns a time series subset that satisfies a given temporal relation.
Definition: TimeSeries.cpp:282
TimeSeries()
Empty constructor.
Definition: TimeSeries.cpp:41
const TimeSeriesObservationSet & getObservations() const
It returns the time series observations.
Definition: TimeSeries.cpp:133
te::gm::Geometry * getLocation() const
It returns the time series location.
Definition: TimeSeries.cpp:158
A struct to represent a patch or a continuous piece of a time series.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
void setTime(te::dt::DateTime *t)
It sets the date time.
TimeSeriesObservationSet m_observations
The time series observations.
Definition: TimeSeries.h:531
An abstract class for an interpolation function or interpolator that estimate a value at non-observav...
void setLocation(te::gm::Geometry *geom)
It sets the time series location.
Definition: TimeSeries.cpp:163
A class to represent time series.
Definition: TimeSeries.h:66
SimpleData< double, DOUBLE_TYPE > Double
Definition: SimpleData.h:227
void getResultOrderedByTime(const double &v, te::dt::BasicRelation r, std::map< te::dt::DateTime *, te::dt::AbstractData *, te::dt::CompareDateTime > &result) const
It returns the result of a basic relation ordered by time.
Definition: TimeSeries.cpp:443
std::string m_id
The time series identification.
Definition: TimeSeries.h:534
void setId(const std::string &id)
It sets the time series identifier.
Definition: TimeSeries.cpp:153
TEDATATYPEEXPORT DateTimePeriod * GetTemporalExtent(const DateTime *t1, const DateTime *t2)
It returns the temporal extent of two date and time types.
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
std::auto_ptr< te::gm::Geometry > m_location
The time series location.
Definition: TimeSeries.h:533
void getPatches(const double &v, te::dt::BasicRelation r, std::vector< TimeSeriesPatch > &result) const
It returns time series subsets that satisfy a given relation.
Definition: TimeSeries.cpp:345
virtual AbstractData * clone() const =0
It returns a clone of this object.
AbstractTimeSeriesInterp * getInterpolator() const
It returns the interpolator associated to the time series.
Definition: TimeSeries.cpp:138
TimeSeriesIterator end() const
It returns an iterator that points to the end of the time series.
Definition: TimeSeries.cpp:211
TimeSeriesIterator begin() const
It returns an iterator that points to the first observation of the time series.
Definition: TimeSeries.cpp:205
It is an interpolation function the estimates the nearest value at a given non-observed time of a tim...
boost::multi_index_container< TimeSeriesObservation, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::identity< TimeSeriesObservation > >, boost::multi_index::ordered_non_unique< boost::multi_index::const_mem_fun< TimeSeriesObservation, double,&TimeSeriesObservation::getDouble > >, boost::multi_index::ordered_non_unique< boost::multi_index::const_mem_fun< TimeSeriesObservation, std::string,&TimeSeriesObservation::getString > > > > TimeSeriesObservationSet