1use crate::gis::Gis;
6use crate::node::{M_NODE, Node, Root};
7use loam::{Error, Id, Reader, Result};
8use pointy::{BBox, Bounded, Float};
9use serde::de::DeserializeOwned;
10use std::marker::PhantomData;
11use std::path::{Path, PathBuf};
12
13pub struct RTree<F, G>
19where
20 F: Float + DeserializeOwned,
21 G: Gis<F> + DeserializeOwned,
22{
23 path: PathBuf,
25
26 _float: PhantomData<F>,
27 _geom: PhantomData<G>,
28}
29
30struct RTreeQuery<D, F, G>
32where
33 F: Float + DeserializeOwned,
34 G: Gis<F, Data = D> + DeserializeOwned,
35{
36 reader: Option<Reader>,
38
39 bbox: BBox<F>,
41
42 work: Vec<(Id, usize)>,
44
45 error: Option<Error>,
47
48 _data: PhantomData<D>,
49 _geom: PhantomData<G>,
50}
51
52impl<D, F, G> Iterator for RTreeQuery<D, F, G>
53where
54 F: Float + DeserializeOwned,
55 G: Gis<F, Data = D> + DeserializeOwned,
56{
57 type Item = Result<G>;
58
59 fn next(&mut self) -> Option<Self::Item> {
60 if let Some(err) = self.error.take() {
61 return Some(Err(err));
62 }
63 let reader = self.reader.as_ref()?;
64 while let Some((id, height)) = self.work.pop() {
65 if height > 1 {
66 match reader.lookup::<Node<F>>(id) {
67 Ok(node) => {
68 let children = node.into_entries();
69 for child in children {
70 log::trace!("{height}: {:?}", child.bbox());
71 if child.bounded_by(self.bbox) {
72 self.work.push((child.id(), height - 1));
73 }
74 }
75 }
76 Err(e) => return Some(Err(e)),
77 }
78 } else {
79 match reader.lookup::<G>(id) {
80 Ok(geom) => return Some(Ok(geom)),
81 Err(e) => return Some(Err(e)),
82 }
83 }
84 }
85 None
86 }
87}
88
89impl<D, F, G> RTreeQuery<D, F, G>
90where
91 F: Float + DeserializeOwned,
92 G: Gis<F, Data = D> + DeserializeOwned,
93{
94 fn new(tree: &RTree<F, G>, bbox: BBox<F>) -> Self {
96 match Self::build(tree.path.as_path(), bbox) {
97 Ok(query) => query,
98 Err(e) => Self {
99 reader: None,
100 bbox,
101 work: Vec::new(),
102 error: Some(e),
103 _data: PhantomData,
104 _geom: PhantomData,
105 },
106 }
107 }
108
109 fn build(path: &Path, bbox: BBox<F>) -> Result<Self> {
111 let mut work = Vec::new();
112 let reader = Reader::new(path)?;
113 let id = reader.root()?;
114 let root = reader.lookup::<Root<F>>(id)?;
115 let height = Node::<F>::height(root.n_elem());
116 log::trace!("root: {height}");
117 let node = root.into_node();
118 let children = node.into_entries();
119 work.reserve(height * M_NODE);
120 for child in children {
121 log::trace!("query: {bbox:?}");
122 if child.bounded_by(bbox) {
123 log::trace!("child: {:?}", child.bbox());
124 work.push((child.id(), height));
125 }
126 }
127 Ok(Self {
128 reader: Some(reader),
129 bbox,
130 work,
131 error: None,
132 _data: PhantomData,
133 _geom: PhantomData,
134 })
135 }
136}
137
138impl<D, F, G> RTree<F, G>
139where
140 F: Float + DeserializeOwned,
141 G: Gis<F, Data = D> + DeserializeOwned,
142{
143 pub fn new<P>(path: P) -> Self
145 where
146 P: AsRef<Path>,
147 {
148 let mut tmp = PathBuf::new();
149 tmp.push(path);
150 let path = tmp;
151 Self {
152 path,
153 _float: PhantomData,
154 _geom: PhantomData,
155 }
156 }
157
158 pub fn query<'a>(
164 &'a self,
165 bbox: BBox<F>,
166 ) -> impl Iterator<Item = Result<G>> + 'a
167 where
168 D: 'a,
169 {
170 RTreeQuery::new(self, bbox)
171 }
172}