1use crate::{
2 data_store::vector::{Vector, VectorStore},
3 geometry::{LonLat, S1ChordAngle, S2Cap, S2CellId, S2Point, convert},
4 parsers::FeatureReader,
5};
6use alloc::{vec, vec::Vec};
7use core::marker::PhantomData;
8use s2json::{
9 Face, GetM, GetXY, GetZ, JSONCollection, MValue, Projection, VectorFeature, VectorFeatureType,
10 VectorGeometry, VectorPoint,
11};
12use serde::{Deserialize, Serialize, de::DeserializeOwned};
13
14pub type LocalPointIndex<M = MValue> = PointIndex<M, Vector<S2CellId, IndexPoint<M>>>;
16
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
19pub struct IndexPoint<M> {
20 pub s2point: S2Point,
22 pub data: M,
24}
25impl<M> IndexPoint<M> {
26 pub fn new(s2point: S2Point, data: M) -> Self {
28 IndexPoint { s2point, data }
29 }
30}
31impl<M> GetXY for IndexPoint<M> {
32 fn x(&self) -> f64 {
33 self.s2point.x()
34 }
35 fn y(&self) -> f64 {
36 self.s2point.y()
37 }
38}
39impl<M> GetZ for IndexPoint<M> {
40 fn z(&self) -> Option<f64> {
41 self.s2point.z()
42 }
43}
44impl<M> GetM<M> for IndexPoint<M> {
45 fn m(&self) -> Option<&M> {
46 Some(&self.data)
47 }
48}
49
50#[derive(Debug, Default)]
56pub struct PointIndex<
57 M: Clone + Default + Serialize + DeserializeOwned = MValue,
58 S: VectorStore<S2CellId, IndexPoint<M>> = Vector<S2CellId, IndexPoint<M>>,
59> {
60 store: S,
61 sorted: bool,
62 projection: Projection,
63 _marker: PhantomData<M>,
64}
65impl<M: Clone + Default + Serialize + DeserializeOwned, S: VectorStore<S2CellId, IndexPoint<M>>>
66 PointIndex<M, S>
67{
68 pub fn new(store: Option<S>, projection: Option<Projection>) -> Self {
70 let store = store.unwrap_or_else(|| S::new(None));
71 let projection = projection.unwrap_or(Projection::S2);
72 PointIndex { store, sorted: true, projection, _marker: PhantomData }
73 }
74
75 pub fn len(&self) -> u64 {
77 self.store.len()
78 }
79
80 pub fn is_empty(&self) -> bool {
82 self.store.is_empty()
83 }
84
85 pub fn get_index(&self, index: u64) -> Option<&(S2CellId, IndexPoint<M>)> {
87 self.store.get_index(index)
88 }
89
90 pub fn get_index_mut(&mut self, index: u64) -> Option<&mut (S2CellId, IndexPoint<M>)> {
92 self.store.get_index_mut(index)
93 }
94
95 pub fn insert(&mut self, cell: S2CellId, point: S2Point, data: Option<M>) {
97 self.store.push(cell, IndexPoint::new(point, data.unwrap_or_default()));
98 self.sorted = false;
99 }
100
101 pub fn insert_point<T: GetXY>(&mut self, point: T, data: Option<M>) {
103 self.insert_vector_point(VectorPoint::new(point.x(), point.y(), None, data));
104 }
105
106 pub fn insert_lon_lat(&mut self, mut vp: LonLat<M>) {
108 self.insert_vector_point(vp.take());
109 }
110
111 pub fn insert_vector_point(&mut self, vp: VectorPoint<M>) {
113 self.insert_feature(JSONCollection::<(), M, M>::VectorFeature(VectorFeature {
114 _type: VectorFeatureType::VectorFeature,
115 geometry: VectorGeometry::new_point(vp, None),
116 ..Default::default()
117 }));
118 }
119
120 pub fn insert_face_st(&mut self, face: Face, s: f64, t: f64, data: M) {
122 self.insert_feature(JSONCollection::<(), M, M>::VectorFeature(VectorFeature {
123 _type: VectorFeatureType::S2Feature,
124 face,
125 geometry: VectorGeometry::new_point(VectorPoint::new(s, t, None, Some(data)), None),
126 ..Default::default()
127 }));
128 }
129
130 pub fn insert_reader<T: Clone, F: FeatureReader<T, M, M>>(&mut self, reader: &F) {
133 for feature in reader.iter() {
134 self.insert_feature(JSONCollection::<T, M, M>::VectorFeature(feature))
135 }
136 }
137
138 pub fn insert_feature<T: Clone>(&mut self, data: JSONCollection<T, M, M>) {
141 let features = convert(self.projection, &data, Some(true), Some(true));
142 for feature in features {
143 match feature.geometry {
144 VectorGeometry::Point(geometry) => {
145 let coordinates = geometry.coordinates;
146 self._insert_face_st(
147 feature.face.into(),
148 coordinates.x,
149 coordinates.y,
150 coordinates.m.or(Some(feature.properties)),
151 );
152 }
153 VectorGeometry::MultiPoint(geometry) => {
154 for point in geometry.coordinates {
155 self._insert_face_st(
156 feature.face.into(),
157 point.x,
158 point.y,
159 point.m.or(Some(feature.properties.clone())),
160 );
161 }
162 }
163 _ => {}
164 }
165 }
166 }
167
168 pub fn sort(&mut self) {
170 if self.sorted {
171 return;
172 }
173 self.store.sort();
174 self.sorted = true;
175 }
176
177 pub fn lower_bound(&self, id: S2CellId) -> u64 {
179 assert!(self.sorted);
180 let mut lo: u64 = 0;
182 let mut hi: u64 = self.store.len();
183 let mut mid: u64;
184
185 while lo < hi {
186 mid = (lo + hi) / 2;
187 let (mid_cell, _) = self.store.get_index(mid).unwrap();
188 if *mid_cell < id {
189 lo = mid + 1;
190 } else {
191 hi = mid;
192 }
193 }
194
195 lo
196 }
197
198 pub fn search_range(
200 &self,
201 mut low: S2CellId,
202 high: Option<S2CellId>,
203 max_results: Option<usize>,
204 ) -> Vec<&(S2CellId, IndexPoint<M>)> {
205 assert!(self.sorted);
206 let max_results = max_results.unwrap_or(usize::MAX);
207 let mut res = vec![];
208 let high = high.unwrap_or_else(|| {
209 let (lo, hi) = low.range();
210 low = lo;
211 hi
212 });
213 let mut lo_idx = self.lower_bound(low);
214
215 let len = self.store.len();
216 loop {
217 if lo_idx >= len {
218 break;
219 }
220 let curr_lo = self.store.get_index(lo_idx).unwrap();
221 if curr_lo.0 > high {
222 break;
223 }
224 res.push(curr_lo);
225 if res.len() >= max_results {
226 break;
227 }
228 lo_idx += 1;
229 }
230
231 res
232 }
233
234 pub fn search_range_mut(
236 &mut self,
237 mut low: S2CellId,
238 high: Option<S2CellId>,
239 max_results: Option<usize>,
240 ) -> Vec<&mut (S2CellId, IndexPoint<M>)> {
241 let max_results = max_results.unwrap_or(usize::MAX);
243 self.sort();
244 let high = high.unwrap_or_else(|| {
245 let (lo, hi) = low.range();
246 low = lo;
247 hi
248 });
249 let mut lo_idx = self.lower_bound(low);
250
251 let mut res = vec![];
252 let len = self.store.len();
253 while lo_idx < len {
254 let entry_ptr: *mut (S2CellId, IndexPoint<M>) =
255 self.store.get_index_mut(lo_idx).unwrap() as *mut _; if unsafe { (*entry_ptr).0 } > high {
257 break;
258 }
259 unsafe {
261 res.push(&mut *entry_ptr);
262 }
263 if res.len() >= max_results {
265 break;
266 }
267 lo_idx += 1;
268 }
269
270 res
271 }
272
273 pub fn search_radius<M2: Clone + Default>(
276 &self,
277 target: &LonLat<M2>,
278 radius: S1ChordAngle,
279 max_results: Option<usize>,
280 ) -> Vec<&(S2CellId, IndexPoint<M>)> {
281 self.s2_search_radius(self.adjust_lon_lat(target), radius, max_results)
282 }
283
284 pub fn s2_search_radius(
286 &self,
287 target: S2Point,
288 radius: S1ChordAngle,
289 max_results: Option<usize>,
290 ) -> Vec<&(S2CellId, IndexPoint<M>)> {
291 assert!(self.sorted);
292 let max_results = max_results.unwrap_or(usize::MAX);
293 if radius < 0. {
294 return vec![];
295 }
296 let cap = S2Cap::new(target, radius, ());
297 let mut res = vec![];
298 for cell in cap.get_intersecting_cells() {
299 let (min, max) = cell.range();
302 for point in self.search_range(min, Some(max), Some(max_results)) {
303 if S1ChordAngle::from_s2_points(&target, &(point.1.s2point)) < radius {
304 res.push(point);
305 }
306 if res.len() >= max_results {
307 break;
308 }
309 }
310 }
311
312 res
313 }
314
315 pub fn search_radius_mut<M2: Clone + Default>(
318 &mut self,
319 target: &LonLat<M2>,
320 radius: S1ChordAngle,
321 max_results: Option<usize>,
322 ) -> Vec<&mut (S2CellId, IndexPoint<M>)> {
323 self.s2_search_radius_mut(self.adjust_lon_lat(target), radius, max_results)
324 }
325
326 pub fn s2_search_radius_mut(
328 &mut self,
329 target: S2Point,
330 radius: S1ChordAngle,
331 max_results: Option<usize>,
332 ) -> Vec<&mut (S2CellId, IndexPoint<M>)> {
333 let max_results = max_results.unwrap_or(usize::MAX);
334 self.sort();
335 if radius < 0. {
336 return vec![];
337 }
338 let cap = S2Cap::new(target, radius, ());
340 let mut raw_ptrs = vec![];
341 for cell in cap.get_intersecting_cells() {
342 let (min, max) = cell.range();
345 let search_results = self.search_range_mut(min, Some(max), Some(max_results));
346 for point in search_results {
347 let s2point = &point.1.s2point;
348 let angle = S1ChordAngle::from_s2_points(&target, s2point);
349 let ptr: *mut (S2CellId, IndexPoint<M>) = point as *mut _; if angle < radius {
351 raw_ptrs.push(ptr);
352 }
353 if raw_ptrs.len() >= max_results {
354 break;
355 }
356 }
357 }
358
359 let mut res = vec![];
361 unsafe {
362 for ptr in raw_ptrs {
363 res.push(&mut *ptr);
364 }
365 }
366 res
367 }
368
369 fn adjust_lon_lat<M2: Clone + Default>(&self, lonlat: &LonLat<M2>) -> S2Point {
370 if self.projection == Projection::WG {
371 let mut projected = lonlat.0.clone();
372 projected.project(None);
373 return S2Point::from_face_st(0, projected.x, projected.y);
374 }
375 lonlat.into()
376 }
377
378 fn _insert_face_st(&mut self, face: u8, s: f64, t: f64, data: Option<M>) {
380 let point = S2Point::from_face_st(face, s, t);
381 self.insert((&point).into(), point, data);
382 }
383
384 pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'a (S2CellId, IndexPoint<M>)>
386 where
387 IndexPoint<M>: 'a,
388 {
389 self.store.iter()
390 }
391
392 pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut (S2CellId, IndexPoint<M>)>
394 where
395 IndexPoint<M>: 'a,
396 {
397 self.store.iter_mut()
398 }
399}