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 
28 #include <cstring>
29 #include <limits>
30 
31 #include <spatialindex/SpatialIndex.h>
32 
33 using namespace SpatialIndex;
34 
TimePoint()35 TimePoint::TimePoint()
36 	: Point(), m_startTime(-std::numeric_limits<double>::max()), m_endTime(std::numeric_limits<double>::max())
37 {
38 }
39 
TimePoint(const double * pCoords,const IInterval & ti,uint32_t dimension)40 TimePoint::TimePoint(const double* pCoords, const IInterval& ti, uint32_t dimension)
41 	: Point(pCoords, dimension), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
42 {
43 }
44 
TimePoint(const double * pCoords,double tStart,double tEnd,uint32_t dimension)45 TimePoint::TimePoint(const double* pCoords, double tStart, double tEnd, uint32_t dimension)
46 	: Point(pCoords, dimension), m_startTime(tStart), m_endTime(tEnd)
47 {
48 }
49 
TimePoint(const Point & p,const IInterval & ti)50 TimePoint::TimePoint(const Point& p, const IInterval& ti)
51 	: Point(p), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
52 {
53 }
54 
TimePoint(const Point & p,double tStart,double tEnd)55 TimePoint::TimePoint(const Point& p, double tStart, double tEnd)
56 	: Point(p), m_startTime(tStart), m_endTime(tEnd)
57 {
58 }
59 
TimePoint(const TimePoint & p)60 TimePoint::TimePoint(const TimePoint& p)
61 	: m_startTime(p.m_startTime), m_endTime(p.m_endTime)
62 {
63 	m_dimension = p.m_dimension;
64 
65 	m_pCoords = new double[m_dimension];
66 	memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
67 }
68 
~TimePoint()69 TimePoint::~TimePoint()
70 {
71 }
72 
operator =(const TimePoint & p)73 TimePoint& TimePoint::operator=(const TimePoint& p)
74 {
75 	if (this != &p)
76 	{
77 		makeDimension(p.m_dimension);
78 		memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
79 		m_startTime = p.m_startTime;
80 		m_endTime = p.m_endTime;
81 	}
82 
83 	return *this;
84 }
85 
operator ==(const TimePoint & p) const86 bool TimePoint::operator==(const TimePoint& p) const
87 {
88 	if (
89 		m_startTime < p.m_startTime - std::numeric_limits<double>::epsilon() ||
90 		m_startTime > p.m_startTime + std::numeric_limits<double>::epsilon() ||
91 		m_endTime < p.m_endTime - std::numeric_limits<double>::epsilon() ||
92 		m_endTime > p.m_endTime + std::numeric_limits<double>::epsilon())
93 		return false;
94 
95 	for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
96 	{
97 		if (
98 			m_pCoords[cDim] < p.m_pCoords[cDim] - std::numeric_limits<double>::epsilon() ||
99 			m_pCoords[cDim] > p.m_pCoords[cDim] + std::numeric_limits<double>::epsilon())
100 			return false;
101 	}
102 
103 	return true;
104 }
105 
106 //
107 // IObject interface
108 //
clone()109 TimePoint* TimePoint::clone()
110 {
111 	return new TimePoint(*this);
112 }
113 
114 //
115 // ISerializable interface
116 //
getByteArraySize()117 uint32_t TimePoint::getByteArraySize()
118 {
119 	return (sizeof(uint32_t) + 2 * sizeof(double) + m_dimension * sizeof(double));
120 }
121 
loadFromByteArray(const byte * ptr)122 void TimePoint::loadFromByteArray(const byte* ptr)
123 {
124 	uint32_t dimension;
125 	memcpy(&dimension, ptr, sizeof(uint32_t));
126 	ptr += sizeof(uint32_t);
127 	memcpy(&m_startTime, ptr, sizeof(double));
128 	ptr += sizeof(double);
129 	memcpy(&m_endTime, ptr, sizeof(double));
130 	ptr += sizeof(double);
131 
132 	makeDimension(dimension);
133 	memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
134 	//ptr += m_dimension * sizeof(double);
135 }
136 
storeToByteArray(byte ** data,uint32_t & len)137 void TimePoint::storeToByteArray(byte** data, uint32_t& len)
138 {
139 	len = getByteArraySize();
140 	*data = new byte[len];
141 	byte* ptr = *data;
142 
143 	memcpy(ptr, &m_dimension, sizeof(uint32_t));
144 	ptr += sizeof(uint32_t);
145 	memcpy(ptr, &m_startTime, sizeof(double));
146 	ptr += sizeof(double);
147 	memcpy(ptr, &m_endTime, sizeof(double));
148 	ptr += sizeof(double);
149 	memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
150 	//ptr += m_dimension * sizeof(double);
151 }
152 
153 //
154 // ITimeShape interface
155 //
intersectsShapeInTime(const ITimeShape & in) const156 bool TimePoint::intersectsShapeInTime(const ITimeShape& in) const
157 {
158 	const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
159 	if (pr != 0) return pr->containsPointInTime(*this);
160 
161 	throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
162 }
163 
intersectsShapeInTime(const IInterval &,const ITimeShape &) const164 bool TimePoint::intersectsShapeInTime(const IInterval&, const ITimeShape&) const
165 {
166 	throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
167 }
168 
containsShapeInTime(const ITimeShape &) const169 bool TimePoint::containsShapeInTime(const ITimeShape&) const
170 {
171 	return false;
172 }
173 
containsShapeInTime(const IInterval &,const ITimeShape &) const174 bool TimePoint::containsShapeInTime(const IInterval&, const ITimeShape&) const
175 {
176 	return false;
177 }
178 
touchesShapeInTime(const ITimeShape &) const179 bool TimePoint::touchesShapeInTime(const ITimeShape&) const
180 {
181 	throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
182 }
183 
touchesShapeInTime(const IInterval &,const ITimeShape &) const184 bool TimePoint::touchesShapeInTime(const IInterval&, const ITimeShape&) const
185 {
186 	throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
187 }
188 
getAreaInTime() const189 double TimePoint::getAreaInTime() const
190 {
191 	return 0.0;
192 }
193 
getAreaInTime(const IInterval &) const194 double TimePoint::getAreaInTime(const IInterval&) const
195 {
196 	return 0.0;
197 }
198 
getIntersectingAreaInTime(const ITimeShape &) const199 double TimePoint::getIntersectingAreaInTime(const ITimeShape&) const
200 {
201 	return 0.0;
202 }
203 
getIntersectingAreaInTime(const IInterval &,const ITimeShape &) const204 double TimePoint::getIntersectingAreaInTime(const IInterval&, const ITimeShape&) const
205 {
206 	return 0.0;
207 }
208 
209 //
210 // IInterval interface
211 //
operator =(const Tools::IInterval & i)212 Tools::IInterval& TimePoint::operator=(const Tools::IInterval& i)
213 {
214 	if (this != &i)
215 	{
216 		m_startTime = i.getLowerBound();
217 		m_endTime = i.getUpperBound();
218 	}
219 
220 	return *this;
221 }
222 
getLowerBound() const223 double TimePoint::getLowerBound() const
224 {
225 	return m_startTime;
226 }
227 
getUpperBound() const228 double TimePoint::getUpperBound() const
229 {
230 	return m_endTime;
231 }
232 
setBounds(double l,double h)233 void TimePoint::setBounds(double l, double h)
234 {
235 	assert(l <= h);
236 
237 	m_startTime = l;
238 	m_endTime = h;
239 }
240 
intersectsInterval(const IInterval & ti) const241 bool TimePoint::intersectsInterval(const IInterval& ti) const
242 {
243 	return intersectsInterval(ti.getIntervalType(), ti.getLowerBound(), ti.getUpperBound());
244 }
245 
intersectsInterval(Tools::IntervalType,const double start,const double end) const246 bool TimePoint::intersectsInterval(Tools::IntervalType, const double start, const double end) const
247 {
248 	//if (m_startTime != start &&
249 	//		(m_startTime >= end || m_endTime <= start)) return false;
250 	if (m_startTime >= end || m_endTime <= start) return false;
251 
252 	return true;
253 }
254 
containsInterval(const IInterval & ti) const255 bool TimePoint::containsInterval(const IInterval& ti) const
256 {
257 	if (m_startTime <= ti.getLowerBound() && m_endTime >= ti.getUpperBound()) return true;
258 	return false;
259 }
260 
getIntervalType() const261 Tools::IntervalType TimePoint::getIntervalType() const
262 {
263 	return Tools::IT_RIGHTOPEN;
264 }
265 
makeInfinite(uint32_t dimension)266 void TimePoint::makeInfinite(uint32_t dimension)
267 {
268 	makeDimension(dimension);
269 	for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
270 	{
271 		m_pCoords[cIndex] = std::numeric_limits<double>::max();
272 	}
273 
274 	m_startTime = std::numeric_limits<double>::max();
275 	m_endTime = -std::numeric_limits<double>::max();
276 }
277 
makeDimension(uint32_t dimension)278 void TimePoint::makeDimension(uint32_t dimension)
279 {
280 	if (m_dimension != dimension)
281 	{
282 		m_dimension = dimension;
283 
284 		delete[] m_pCoords;
285 		m_pCoords = 0;
286 
287 		m_pCoords = new double[m_dimension];
288 	}
289 }
290 
operator <<(std::ostream & os,const TimePoint & pt)291 std::ostream& SpatialIndex::operator<<(std::ostream& os, const TimePoint& pt)
292 {
293 	uint32_t i;
294 
295 	for (i = 0; i < pt.m_dimension; ++i)
296 	{
297 		os << pt.m_pCoords[i] << " ";
298 	}
299 
300 	os << ", Start: " << pt.m_startTime << ", End: " << pt.m_endTime;
301 
302 	return os;
303 }
304