libspatialindex API Reference  (git-trunk)
TimeRegion.cc
Go to the documentation of this file.
1 /******************************************************************************
2  * Project: libspatialindex - A C++ library for spatial indexing
3  * Author: Marios Hadjieleftheriou, mhadji@gmail.com
4  ******************************************************************************
5  * Copyright (c) 2002, Marios Hadjieleftheriou
6  *
7  * All rights reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included
17  * in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26 ******************************************************************************/
27 
29 
30 #include <cstring>
31 #include <limits>
32 
33 using namespace SpatialIndex;
34 
36  : Region(), m_startTime(-std::numeric_limits<double>::max()), m_endTime(std::numeric_limits<double>::max())
37 {
38 }
39 
40 TimeRegion::TimeRegion(const double* pLow, const double* pHigh, const IInterval& ti, uint32_t dimension)
41  : Region(pLow, pHigh, dimension), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
42 {
43 }
44 
45 TimeRegion::TimeRegion(const double* pLow, const double* pHigh, double tStart, double tEnd, uint32_t dimension)
46  : Region(pLow, pHigh, dimension), m_startTime(tStart), m_endTime(tEnd)
47 {
48 }
49 
50 TimeRegion::TimeRegion(const Point& low, const Point& high, const IInterval& ti)
51  : Region(low, high), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
52 {
53 }
54 
55 TimeRegion::TimeRegion(const Point& low, const Point& high, double tStart, double tEnd)
56  : Region(low, high), m_startTime(tStart), m_endTime(tEnd)
57 {
58 }
59 
60 TimeRegion::TimeRegion(const Region& r, const IInterval& ti)
61  : Region(r), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
62 {
63 }
64 
65 TimeRegion::TimeRegion(const Region& r, double tStart, double tEnd)
66  : Region(r), m_startTime(tStart), m_endTime(tEnd)
67 {
68 }
69 
70 TimeRegion::TimeRegion(const TimePoint& low, const TimePoint& high)
71  : Region( low, high), m_startTime(low.m_startTime), m_endTime(high.m_endTime)
72 {
73 }
74 
77 {
79  m_pLow = nullptr;
80 
81  try
82  {
83  m_pLow = new double[m_dimension];
84  m_pHigh = new double[m_dimension];
85  }
86  catch (...)
87  {
88  delete[] m_pLow;
89  throw;
90  }
91 
92  memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
93  memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
94 }
95 
97 = default;
98 
100 {
101  if(this != &r)
102  {
104  memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
105  memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
106 
108  m_endTime = r.m_endTime;
109  }
110 
111  return *this;
112 }
113 
114 bool TimeRegion::operator==(const TimeRegion& r) const
115 {
116  if (m_startTime < r.m_startTime - std::numeric_limits<double>::epsilon() ||
117  m_startTime > r.m_startTime + std::numeric_limits<double>::epsilon() ||
118  m_endTime < r.m_endTime - std::numeric_limits<double>::epsilon() ||
119  m_endTime > r.m_endTime + std::numeric_limits<double>::epsilon())
120  return false;
121 
122  for (uint32_t i = 0; i < m_dimension; ++i)
123  {
124  if (
125  m_pLow[i] < r.m_pLow[i] - std::numeric_limits<double>::epsilon() ||
126  m_pLow[i] > r.m_pLow[i] + std::numeric_limits<double>::epsilon() ||
127  m_pHigh[i] < r.m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
128  m_pHigh[i] > r.m_pHigh[i] + std::numeric_limits<double>::epsilon())
129  return false;
130  }
131  return true;
132 }
133 
135 {
136  // they should just intersect in time.
137  // check if they intersect in time first.
138  // the first check is needed for the following case:
139  // m_endTime == m_startTime == r.m_startTime.
140  // For open ended intervals this should be considered as an intersection
141  // (takes care of degenarate intervals)
142  //if (m_startTime != r.m_startTime &&
143  // (m_startTime >= r.m_endTime || m_endTime <= r.m_startTime))
144  if (! intersectsInterval(r)) return false;
145  return Region::intersectsRegion(r);
146 }
147 
149 {
150  // it should be contained in time.
151  if (! containsInterval(r)) return false;
152  return Region::containsRegion(r);
153 }
154 
156 {
157  // they should just intersect in time.
158  //if (m_startTime != r.m_startTime &&
159  // (m_startTime >= r.m_endTime || m_endTime <= r.m_startTime))
160  if (!intersectsInterval(r)) return false;
161  return Region::touchesRegion(r);
162 }
163 
165 {
166  // it should be contained in time.
167  //if (p.m_startTime < m_startTime || p.m_endTime > m_endTime) return false;
168  if (containsInterval(p)) return false;
169  return Region::containsPoint(p);
170 }
171 
173 {
174  // they should just intersect in time.
175  //if (m_startTime != p.m_startTime &&
176  // (m_startTime >= p.m_endTime || m_endTime <= p.m_startTime))
177  if (intersectsInterval(p)) return false;
178  return Region::touchesPoint(p);
179 }
180 
182 {
184 
185  m_startTime = std::min(m_startTime, r.m_startTime);
186  m_endTime = std::max(m_endTime, r.m_endTime);
187 }
188 
190 {
191  Region::getCombinedRegion(out, in);
192 
193  out.m_startTime = std::min(m_startTime, in.m_startTime);
194  out.m_endTime = std::max(m_endTime, in.m_endTime);
195 }
196 
197 //
198 // IObject interface
199 //
201 {
202  return new TimeRegion(*this);
203 }
204 
205 //
206 // ISerializable interface
207 //
209 {
210  return (sizeof(uint32_t) + 2 * sizeof(double) + 2 * m_dimension * sizeof(double));
211 }
212 
213 void TimeRegion::loadFromByteArray(const uint8_t* ptr)
214 {
215  uint32_t dimension;
216 
217  memcpy(&dimension, ptr, sizeof(uint32_t));
218  ptr += sizeof(uint32_t);
219  memcpy(&m_startTime, ptr, sizeof(double));
220  ptr += sizeof(double);
221  memcpy(&m_endTime, ptr, sizeof(double));
222  ptr += sizeof(double);
223 
224  makeDimension(dimension);
225  memcpy(m_pLow, ptr, m_dimension * sizeof(double));
226  ptr += m_dimension * sizeof(double);
227  memcpy(m_pHigh, ptr, m_dimension * sizeof(double));
228  //ptr += m_dimension * sizeof(double);
229 }
230 
231 void TimeRegion::storeToByteArray(uint8_t** data, uint32_t& len)
232 {
233  len = getByteArraySize();
234  *data = new uint8_t[len];
235  uint8_t* ptr = *data;
236 
237  memcpy(ptr, &m_dimension, sizeof(uint32_t));
238  ptr += sizeof(uint32_t);
239  memcpy(ptr, &m_startTime, sizeof(double));
240  ptr += sizeof(double);
241  memcpy(ptr, &m_endTime, sizeof(double));
242  ptr += sizeof(double);
243 
244  memcpy(ptr, m_pLow, m_dimension * sizeof(double));
245  ptr += m_dimension * sizeof(double);
246  memcpy(ptr, m_pHigh, m_dimension * sizeof(double));
247  //ptr += m_dimension * sizeof(double);
248 }
249 
250 //
251 // ITimeShape interface
252 //
254 {
255  const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
256  if (pr != nullptr) return intersectsRegionInTime(*pr);
257 
258  const TimePoint* ppt = dynamic_cast<const TimePoint*>(&in);
259  if (ppt != nullptr) return containsPointInTime(*ppt);
260 
261  throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
262 }
263 
264 bool TimeRegion::intersectsShapeInTime(const IInterval&, const ITimeShape&) const
265 {
266  throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
267 }
268 
270 {
271  const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
272  if (pr != nullptr) return containsRegionInTime(*pr);
273 
274  const TimePoint* ppt = dynamic_cast<const TimePoint*>(&in);
275  if (ppt != nullptr) return containsPointInTime(*ppt);
276 
277  throw Tools::IllegalStateException("containsShapeInTime: Not implemented yet!");
278 }
279 
280 bool TimeRegion::containsShapeInTime(const IInterval&, const ITimeShape&) const
281 {
282  throw Tools::IllegalStateException("containsShapeInTime: Not implemented yet!");
283 }
284 
286 {
287  const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
288  if (pr != nullptr) return touchesRegionInTime(*pr);
289 
290  throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
291 }
292 
293 bool TimeRegion::touchesShapeInTime(const IInterval&, const ITimeShape&) const
294 {
295  throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
296 }
297 
299 {
300  throw Tools::IllegalStateException("getAreaInTime: Not implemented yet!");
301 }
302 
303 double TimeRegion::getAreaInTime(const IInterval&) const
304 {
305  throw Tools::IllegalStateException("getAreaInTime: Not implemented yet!");
306 }
307 
309 {
310  throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
311 }
312 
313 double TimeRegion::getIntersectingAreaInTime(const IInterval&, const ITimeShape&) const
314 {
315  throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
316 }
317 
318 //
319 // IInterval interface
320 //
322 {
323  if (this != &i)
324  {
326  m_endTime = i.getUpperBound();
327  }
328 
329  return *this;
330 }
331 
333 {
334  return m_startTime;
335 }
336 
338 {
339  return m_endTime;
340 }
341 
342 void TimeRegion::setBounds(double l, double h)
343 {
344  assert(m_startTime <= m_endTime);
345 
346  m_startTime = l;
347  m_endTime = h;
348 }
349 
350 bool TimeRegion::intersectsInterval(const IInterval& ti) const
351 {
352  return intersectsInterval(ti.getIntervalType(), ti.getLowerBound(), ti.getUpperBound());
353 }
354 
355 bool TimeRegion::intersectsInterval(Tools::IntervalType, const double start, const double end) const
356 {
357  //if (m_startTime != start &&
358  // (m_startTime >= end || m_endTime <= start)) return false;
359  // this will not work for degenarate intervals.
360  if (m_startTime >= end || m_endTime <= start) return false;
361 
362  return true;
363 }
364 
365 bool TimeRegion::containsInterval(const IInterval& ti) const
366 {
367  if (m_startTime <= ti.getLowerBound() && m_endTime >= ti.getUpperBound()) return true;
368  return false;
369 }
370 
372 {
373  return Tools::IT_RIGHTOPEN;
374 }
375 
376 void TimeRegion::makeInfinite(uint32_t dimension)
377 {
378  makeDimension(dimension);
379  for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
380  {
381  m_pLow[cIndex] = std::numeric_limits<double>::max();
382  m_pHigh[cIndex] = -std::numeric_limits<double>::max();
383  }
384 
385  m_startTime = std::numeric_limits<double>::max();
386  m_endTime = -std::numeric_limits<double>::max();
387 }
388 
389 void TimeRegion::makeDimension(uint32_t dimension)
390 {
391  if (m_dimension != dimension)
392  {
393  m_dimension = dimension;
394 
395  delete[] m_pLow;
396  delete[] m_pHigh;
397  m_pLow = nullptr; m_pHigh = nullptr;
398 
399  m_pLow = new double[m_dimension];
400  m_pHigh = new double[m_dimension];
401  }
402 }
403 
404 std::ostream& SpatialIndex::operator<<(std::ostream& os, const TimeRegion& r)
405 {
406  uint32_t i;
407 
408  os << "Low: ";
409  for (i = 0; i < r.m_dimension; ++i)
410  {
411  os << r.m_pLow[i] << " ";
412  }
413 
414  os << ", High: ";
415 
416  for (i = 0; i < r.m_dimension; ++i)
417  {
418  os << r.m_pHigh[i] << " ";
419  }
420 
421  os << ", Start: " << r.m_startTime << ", End: " << r.m_endTime;
422 
423  return os;
424 }
virtual bool containsPoint(const Point &in) const
Definition: Region.cc:374
virtual bool containsPointInTime(const TimePoint &in) const
Definition: TimeRegion.cc:164
virtual bool containsRegion(const Region &in) const
Definition: Region.cc:278
bool containsShapeInTime(const ITimeShape &in) const override
Definition: TimeRegion.cc:269
virtual bool containsRegionInTime(const TimeRegion &in) const
Definition: TimeRegion.cc:148
void storeToByteArray(uint8_t **data, uint32_t &len) override
Definition: TimeRegion.cc:231
void makeInfinite(uint32_t dimension) override
Definition: TimeRegion.cc:376
virtual double getLowerBound() const =0
virtual bool touchesRegion(const Region &in) const
Definition: Region.cc:292
virtual bool operator==(const TimeRegion &) const
Definition: TimeRegion.cc:114
virtual bool touchesRegionInTime(const TimeRegion &in) const
Definition: TimeRegion.cc:155
double * m_pLow
Definition: Region.h:98
virtual void getCombinedRegion(Region &out, const Region &in) const
Definition: Region.cc:524
bool intersectsInterval(const Tools::IInterval &ti) const override
void loadFromByteArray(const uint8_t *data) override
Definition: TimeRegion.cc:213
virtual bool intersectsRegion(const Region &in) const
Definition: Region.cc:264
TimeRegion * clone() override
Definition: TimeRegion.cc:200
virtual bool intersectsRegionInTime(const TimeRegion &in) const
Definition: TimeRegion.cc:134
virtual bool touchesPointInTime(const TimePoint &in) const
Definition: TimeRegion.cc:172
double getIntersectingAreaInTime(const ITimeShape &r) const override
Definition: TimeRegion.cc:308
virtual void combineRegionInTime(const TimeRegion &in)
Definition: TimeRegion.cc:181
virtual void getCombinedRegionInTime(TimeRegion &out, const TimeRegion &in) const
Definition: TimeRegion.cc:189
virtual void combineRegion(const Region &in)
Definition: Region.cc:496
virtual bool touchesPoint(const Point &in) const
Definition: Region.cc:388
uint32_t m_dimension
Definition: Region.h:97
double * m_pHigh
Definition: Region.h:99
Tools::IntervalType getIntervalType() const override
Definition: TimeRegion.cc:371
bool intersectsShapeInTime(const ITimeShape &in) const override
Definition: TimeRegion.cc:253
SIDX_DLL std::ostream & operator<<(std::ostream &os, const Ball &ball)
Definition: Ball.cc:215
virtual TimeRegion & operator=(const TimeRegion &r)
Definition: TimeRegion.cc:99
void setBounds(double, double) override
Definition: TimeRegion.cc:342
uint32_t getByteArraySize() override
Definition: TimeRegion.cc:208
double getAreaInTime() const override
Definition: TimeRegion.cc:298
bool touchesShapeInTime(const ITimeShape &in) const override
Definition: TimeRegion.cc:285
bool containsInterval(const Tools::IInterval &ti) const override
Definition: TimeRegion.cc:365
void makeDimension(uint32_t dimension) override
Definition: TimeRegion.cc:389
double getUpperBound() const override
Definition: TimeRegion.cc:337
IntervalType
Definition: Tools.h:80
double getLowerBound() const override
Definition: TimeRegion.cc:332
virtual double getUpperBound() const =0