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