rstar
rstar copied to clipboard
locate_in_envelope not working?
The following codes should supposedly be able to return data consistent with expectations, but the results cannot be obtained correctly after using locate_in_envlope.
If you are traversing all products and using geo's contains method, you can get the correct result.
Is my usage method wrong? Please teach me, thank you!
use geo::{BoundingRect, Contains, LineString, Point, Polygon};
use rayon::prelude::*;
use rstar::{RTree, RTreeObject, AABB};
use std::time::Instant;
#[derive(Debug, Clone)]
struct Product {
id: u32,
polygon: Polygon<f64>,
}
impl RTreeObject for Product {
type Envelope = AABB<[f64; 2]>;
fn envelope(&self) -> Self::Envelope {
let bbox = self.polygon.bounding_rect().unwrap();
AABB::from_corners([bbox.min().x, bbox.min().y], [bbox.max().x, bbox.max().y])
}
}
fn main() {
// Example product data
let products = vec![
Product {
id: 1,
polygon: Polygon::new(
LineString::from(vec![
(116.0, 39.0),
(116.0, 40.0),
(117.0, 40.0),
(117.0, 39.0),
(116.0, 39.0), // Ensure the polygon is closed
]),
vec![],
),
},
Product {
id: 2,
polygon: Polygon::new(
LineString::from(vec![
(118.0, 39.0),
(118.0, 40.0),
(119.0, 40.0),
(119.0, 39.0),
(118.0, 39.0), // Ensure the polygon is closed
]),
vec![],
),
},
];
// Create R-tree index
let rtree = RTree::bulk_load(products.clone());
// Print the bounding box and polygon points of each product
for product in &products {
let bbox = product.polygon.bounding_rect().unwrap();
println!(
"Product ID: {}, BBox: (({}, {}), ({}, {})), Polygon: {:?}",
product.id,
bbox.min().x,
bbox.min().y,
bbox.max().x,
bbox.max().y,
product.polygon
);
}
// Parallel query function
let query_point = |point: Point<f64>| -> Vec<u32> {
let aabb = AABB::from_point([point.x(), point.y()]);
println!(
"Query Point: ({}, {}), AABB: (({}, {}), ({}, {}))",
point.x(),
point.y(),
aabb.lower()[0],
aabb.lower()[1],
aabb.upper()[0],
aabb.upper()[1]
);
let results: Vec<u32> = rtree
.locate_in_envelope(&aabb)
.filter(|product| {
println!(
"Checking Product ID: {}, Polygon: {:?}",
product.id, product.polygon
);
let contains = product.polygon.contains(&point);
println!(
"Checking Product ID: {}, Point: ({}, {}), Contains: {}",
product.id,
point.x(),
point.y(),
contains
);
contains
})
.map(|product| product.id)
.collect();
println!(
"Query Point: ({}, {}), Results: {:?}",
point.x(),
point.y(),
results
);
results
};
// Example multiple query points
let points = vec![
Point::new(116.5, 39.5), // Should match product ID 1
Point::new(118.5, 39.5), // Should match product ID 2
Point::new(117.5, 39.5), // Should not match any product
];
let start = Instant::now();
// Parallel processing of queries
let results: Vec<Vec<u32>> = points.par_iter().map(|&point| query_point(point)).collect();
let duration = start.elapsed();
println!("{:?}", results); // Output the list of product IDs for each point
println!("Time elapsed in expensive_function() is: {:?}", duration);
}