MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / spatial_join

Function spatial_join

nodedb-spatial/src/spatial_join.rs:39–89  ·  view source on GitHub ↗

Execute a spatial join using R-tree probe. `indexed_side`: R-tree built on one collection. `probe_side`: entries from the other collection to probe against. `get_geometry`: callback to retrieve the full geometry for an entry ID (needed for exact predicate evaluation after R-tree bbox filter). `predicate`: which spatial predicate to apply (intersects, contains, etc.).

(
    indexed_side: &RTree,
    probe_entries: &[(u64, BoundingBox)],
    get_indexed_geom: &dyn Fn(u64) -> Option<Geometry>,
    get_probe_geom: &dyn Fn(u64) -> Option<Geometry>,
    predicate: Spati

Source from the content-addressed store, hash-verified

37/// (needed for exact predicate evaluation after R-tree bbox filter).
38/// `predicate`: which spatial predicate to apply (intersects, contains, etc.).
39pub fn spatial_join(
40 indexed_side: &RTree,
41 probe_entries: &[(u64, BoundingBox)],
42 get_indexed_geom: &dyn Fn(u64) -> Option<Geometry>,
43 get_probe_geom: &dyn Fn(u64) -> Option<Geometry>,
44 predicate: SpatialJoinPredicate,
45) -> SpatialJoinResult {
46 let mut pairs = Vec::new();
47 let mut probes = 0;
48 let mut exact_evals = 0;
49
50 for &(probe_id, ref probe_bbox) in probe_entries {
51 // R-tree range search: find indexed entries whose bbox intersects probe bbox.
52 let candidates = indexed_side.search(probe_bbox);
53 probes += 1;
54
55 for candidate in &candidates {
56 // Exact predicate evaluation.
57 let Some(indexed_geom) = get_indexed_geom(candidate.id) else {
58 continue;
59 };
60 let Some(probe_geom) = get_probe_geom(probe_id) else {
61 continue;
62 };
63 exact_evals += 1;
64
65 let matches = match predicate {
66 SpatialJoinPredicate::Intersects => {
67 predicates::st_intersects(&probe_geom, &indexed_geom)
68 }
69 SpatialJoinPredicate::Contains => {
70 predicates::st_contains(&probe_geom, &indexed_geom)
71 }
72 SpatialJoinPredicate::Within => predicates::st_within(&probe_geom, &indexed_geom),
73 SpatialJoinPredicate::DWithin(dist) => {
74 predicates::st_dwithin(&probe_geom, &indexed_geom, dist)
75 }
76 };
77
78 if matches {
79 pairs.push((probe_id, candidate.id));
80 }
81 }
82 }
83
84 SpatialJoinResult {
85 pairs,
86 probes,
87 exact_evals,
88 }
89}
90
91/// Build an R-tree from a list of (entry_id, geometry) pairs for join.
92pub fn build_join_index(entries: &[(u64, Geometry)]) -> RTree {

Callers 3

join_overlapping_squaresFunction · 0.85
join_no_overlapFunction · 0.85
join_with_dwithinFunction · 0.85

Calls 6

st_intersectsFunction · 0.85
st_containsFunction · 0.85
st_withinFunction · 0.85
st_dwithinFunction · 0.85
searchMethod · 0.45
pushMethod · 0.45

Tested by 3

join_overlapping_squaresFunction · 0.68
join_no_overlapFunction · 0.68
join_with_dwithinFunction · 0.68