nodedb_spatial/rtree/
insert.rs1use nodedb_types::BoundingBox;
6
7use super::node::{ChildRef, NodeKind, REINSERT_COUNT_LEAF, RTreeEntry};
8use super::split::split_node;
9use super::tree::RTree;
10
11impl RTree {
12 pub fn insert(&mut self, entry: RTreeEntry) {
14 let bbox = entry.bbox;
15 let mut reinserted_levels = Vec::new();
16 insert_entry(self, entry, 0, &mut reinserted_levels);
17 self.len += 1;
18 self.nodes[self.root].bbox = self.nodes[self.root].bbox.union(&bbox);
19 }
20
21 pub(crate) fn reinsert_entry(&mut self, entry: RTreeEntry) {
23 let mut reinserted = Vec::new();
24 insert_entry(self, entry, 0, &mut reinserted);
25 }
26}
27
28fn insert_entry(
29 tree: &mut RTree,
30 entry: RTreeEntry,
31 target_level: u32,
32 reinserted_levels: &mut Vec<u32>,
33) {
34 let leaf_idx = choose_subtree(tree, tree.root, &entry.bbox, target_level);
35
36 match &mut tree.nodes[leaf_idx].kind {
37 NodeKind::Leaf { entries } => entries.push(entry),
38 NodeKind::Internal { .. } => {
39 debug_assert!(false, "choose_subtree must return a leaf node");
43 return;
44 }
45 }
46 tree.nodes[leaf_idx].recompute_bbox();
47
48 if tree.nodes[leaf_idx].is_overflow() {
49 treat_overflow(tree, leaf_idx, reinserted_levels);
50 }
51}
52
53fn choose_subtree(
55 tree: &RTree,
56 node_idx: usize,
57 entry_bbox: &BoundingBox,
58 target_level: u32,
59) -> usize {
60 let node = &tree.nodes[node_idx];
61 if node.level == target_level {
62 return node_idx;
63 }
64
65 match &node.kind {
66 NodeKind::Leaf { .. } => node_idx,
67 NodeKind::Internal { children } => {
68 if children.is_empty() {
69 return node_idx;
70 }
71 let best = if tree.nodes[children[0].node_idx].is_leaf() {
72 choose_least_overlap(children, entry_bbox)
73 } else {
74 choose_least_enlargement(children, entry_bbox)
75 };
76 choose_subtree(tree, children[best].node_idx, entry_bbox, target_level)
77 }
78 }
79}
80
81fn choose_least_enlargement(children: &[ChildRef], entry_bbox: &BoundingBox) -> usize {
82 let mut best = 0;
83 let mut best_enlarge = f64::INFINITY;
84 let mut best_area = f64::INFINITY;
85 for (i, child) in children.iter().enumerate() {
86 let enlarge = child.bbox.enlargement(entry_bbox);
87 let area = child.bbox.area();
88 if enlarge < best_enlarge || (enlarge == best_enlarge && area < best_area) {
89 best = i;
90 best_enlarge = enlarge;
91 best_area = area;
92 }
93 }
94 best
95}
96
97fn choose_least_overlap(children: &[ChildRef], entry_bbox: &BoundingBox) -> usize {
98 let mut best = 0;
99 let mut best_oi = f64::INFINITY;
100 let mut best_enlarge = f64::INFINITY;
101 let mut best_area = f64::INFINITY;
102 for (i, child) in children.iter().enumerate() {
103 let enlarged = child.bbox.union(entry_bbox);
104 let mut before = 0.0_f64;
105 let mut after = 0.0_f64;
106 for (j, other) in children.iter().enumerate() {
107 if j != i {
108 before += child.bbox.overlap_area(&other.bbox);
109 after += enlarged.overlap_area(&other.bbox);
110 }
111 }
112 let oi = after - before;
113 let enlarge = child.bbox.enlargement(entry_bbox);
114 let area = child.bbox.area();
115 if oi < best_oi
116 || (oi == best_oi && enlarge < best_enlarge)
117 || (oi == best_oi && enlarge == best_enlarge && area < best_area)
118 {
119 best = i;
120 best_oi = oi;
121 best_enlarge = enlarge;
122 best_area = area;
123 }
124 }
125 best
126}
127
128fn treat_overflow(tree: &mut RTree, node_idx: usize, reinserted_levels: &mut Vec<u32>) {
130 let level = tree.nodes[node_idx].level;
131 if node_idx != tree.root && !reinserted_levels.contains(&level) {
132 reinserted_levels.push(level);
133 let entries = forced_reinsert(tree, node_idx);
134 for entry in entries {
135 insert_entry(tree, entry, 0, reinserted_levels);
136 }
137 } else {
138 split_node(tree, node_idx);
139 }
140}
141
142fn forced_reinsert(tree: &mut RTree, node_idx: usize) -> Vec<RTreeEntry> {
144 let reinsert_count = if tree.nodes[node_idx].is_leaf() {
145 REINSERT_COUNT_LEAF
146 } else {
147 0
148 };
149 if reinsert_count == 0 {
150 return Vec::new();
151 }
152
153 let center_lng = (tree.nodes[node_idx].bbox.min_lng + tree.nodes[node_idx].bbox.max_lng) / 2.0;
154 let center_lat = (tree.nodes[node_idx].bbox.min_lat + tree.nodes[node_idx].bbox.max_lat) / 2.0;
155
156 if let NodeKind::Leaf { entries } = &mut tree.nodes[node_idx].kind {
157 entries.sort_by(|a, b| {
158 let da = dist_sq_center(center_lng, center_lat, &a.bbox);
159 let db = dist_sq_center(center_lng, center_lat, &b.bbox);
160 db.partial_cmp(&da).unwrap_or(std::cmp::Ordering::Equal)
161 });
162 let removed: Vec<RTreeEntry> = entries.drain(..reinsert_count).collect();
163 tree.nodes[node_idx].recompute_bbox();
164 removed
165 } else {
166 Vec::new()
167 }
168}
169
170fn dist_sq_center(lng: f64, lat: f64, bbox: &BoundingBox) -> f64 {
171 let cx = (bbox.min_lng + bbox.max_lng) / 2.0;
172 let cy = (bbox.min_lat + bbox.max_lat) / 2.0;
173 (lng - cx).powi(2) + (lat - cy).powi(2)
174}