1 /******************************************************************************
2 * Project: libspatialindex - A C++ library for spatial indexing
3 * Author: Marios Hadjieleftheriou, mhadji@gmail.com
4 ******************************************************************************
5 * Copyright (c) 2003, 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 <assert.h>
29 #include <iostream>
30 #include <fstream>
31 #include <map>
32 #include <queue>
33 #include <cmath>
34 #include <cstring>
35 #include <limits>
36 #include <cmath>
37
38 using namespace std;
39
40 #define DELETE 0
41 #define INSERT 1
42 #define QUERY 2
43
44
45 #include <spatialindex/tools/Tools.h>
46
47 class TimeRegion
48 {
49 public:
50 double m_xmin, m_ymin, m_xmax, m_ymax;
51 double m_startTime, m_endTime;
52
TimeRegion()53 TimeRegion() {}
54
TimeRegion(double x1,double y1,double x2,double y2,double t1,double t2)55 TimeRegion(double x1, double y1, double x2, double y2, double t1, double t2)
56 {
57 m_xmin = (x1 < x2) ? x1 : x2;
58 m_ymin = (y1 < y2) ? y1 : y2;
59 m_xmax = (x1 > x2) ? x1 : x2;
60 m_ymax = (y1 > y2) ? y1 : y2;
61 m_startTime = t1;
62 m_endTime = (t2 <= 0) ? std::numeric_limits<double>::max() : t2;
63 }
64
intersects(TimeRegion & r)65 bool intersects(TimeRegion& r)
66 {
67 if (m_xmin > r.m_xmax || m_xmax < r.m_xmin ||
68 m_ymin > r.m_ymax || m_ymax < r.m_ymin) return false;
69
70 return true;
71 }
72
intersectsInTime(TimeRegion & r)73 bool intersectsInTime(TimeRegion& r)
74 {
75 //if (m_startTime != r.m_startTime && (m_endTime <= r.m_startTime || m_startTime >= r.m_endTime)) return false;
76 if (m_endTime <= r.m_startTime || m_startTime >= r.m_endTime) return false;
77 return intersects(r);
78 }
79
getMinDist(const TimeRegion & r)80 double getMinDist(const TimeRegion& r)
81 {
82 double ret = 0.0;
83
84 if (r.m_xmax < m_xmin)
85 ret += std::pow(m_xmin - r.m_xmax, 2.0);
86 else if (r.m_xmin > m_xmax)
87 ret += std::pow(r.m_xmin - m_xmax, 2.0);
88
89 if (r.m_ymax < m_ymin)
90 ret += std::pow(m_ymin - r.m_ymax, 2.0);
91 else if (r.m_ymin > m_ymax)
92 ret += std::pow(r.m_ymin - m_ymax, 2.0);
93
94 return ret;
95 }
96 };
97
98 class NNEntry
99 {
100 public:
101 size_t m_id;
102 double m_dist;
103
NNEntry(size_t id,double dist)104 NNEntry(size_t id, double dist) : m_id(id), m_dist(dist) {}
105
106 struct greater : public binary_function<NNEntry*, NNEntry*, bool>
107 {
operator ()NNEntry::greater108 bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_dist > __y->m_dist; }
109 };
110 };
111
main(int argc,char ** argv)112 int main(int argc, char** argv)
113 {
114 if (argc != 3)
115 {
116 cerr << "Usage: " << argv[0] << " data_file query_type [intersection | 10NN]." << endl;
117 return -1;
118 }
119
120 uint32_t queryType = 0;
121
122 if (strcmp(argv[2], "intersection") == 0) queryType = 0;
123 else if (strcmp(argv[2], "10NN") == 0) queryType = 1;
124 else
125 {
126 cerr << "Unknown query type." << endl;
127 return -1;
128 }
129
130 ifstream fin(argv[1]);
131 if (! fin)
132 {
133 cerr << "Cannot open data file" << argv[1] << "." << endl;
134 return -1;
135 }
136
137 multimap<size_t, TimeRegion> data;
138 size_t id;
139 uint32_t op;
140 double x1, x2, y1, y2, t;
141
142 while (fin)
143 {
144 fin >> t >> op >> id >> x1 >> y1 >> x2 >> y2;
145 if (! fin.good()) continue;
146
147 if (op == INSERT)
148 {
149 //insert
150 data.insert(pair<size_t, TimeRegion>(id, TimeRegion(x1, y1, x2, y2, t, std::numeric_limits<double>::max())));
151 }
152 else if (op == DELETE)
153 {
154 //delete
155 // find the live instance of id.
156 multimap<size_t, TimeRegion>::iterator it = data.find(id);
157 assert(it != data.end());
158 while (it->first == id && it->second.m_endTime < std::numeric_limits<double>::max()) it++;
159 assert(it->first == id);
160 (*it).second.m_endTime = t;
161 }
162 else if (op == QUERY)
163 {
164 size_t qt1, qt2;
165 fin >> qt1 >> qt2;
166 if (! fin.good()) continue;
167
168 //query
169 if (queryType == 0)
170 {
171 TimeRegion query = TimeRegion(x1, y1, x2, y2, qt1, qt2);
172 for (multimap<size_t, TimeRegion>::iterator it = data.begin(); it != data.end(); it++)
173 {
174 if (query.intersectsInTime((*it).second)) cout << (*it).first << endl;
175 }
176 }
177 else
178 {
179 /*
180 TimeRegion query = TimeRegion(x1, y1, x1, y1, qt1, qt2);
181
182 priority_queue<NNEntry*, vector<NNEntry*>, NNEntry::greater > queue;
183
184 for (multimap<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
185 {
186 queue.push(new NNEntry((*it).first, (*it).second.getMinDist(query)));
187 }
188
189 size_t count = 0;
190 double knearest = 0.0;
191
192 while (! queue.empty())
193 {
194 NNEntry* e = queue.top(); queue.pop();
195
196 if (count >= 10 && e->m_dist > knearest) break;
197
198 //cout << e->m_id << " " << e->m_dist << endl;
199 cout << e->m_id << endl;
200 count++;
201 knearest = e->m_dist;
202 delete e;
203 }
204
205 while (! queue.empty())
206 {
207 NNEntry* e = queue.top(); queue.pop();
208 delete e;
209 }
210 */
211 }
212 }
213 }
214
215 return 0;
216 }
217