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