Skip to content

Instantly share code, notes, and snippets.

@stuartlynn
Created October 27, 2019 13:57
Show Gist options
  • Save stuartlynn/e4b856d7e771c5c420dfd764c4bdbd8c to your computer and use it in GitHub Desktop.
Save stuartlynn/e4b856d7e771c5c420dfd764c4bdbd8c to your computer and use it in GitHub Desktop.
Fast Agg point in polygon search
pub fn agg_in(&self, poly: &Geometry<f32>) -> HashMap<String, f32> {
// Find the bounds of the target polygon
let bounds = match poly {
Geometry::Polygon(p) => Ok(p.bounding_rect().unwrap()),
Geometry::MultiPolygon(p) => Ok(p.bounding_rect().unwrap()),
_ => Err("Wrong poly type"),
}
.unwrap();
// Use the bounds to create an r-tree query
let target_bounds =
AABB::from_corners([bounds.min.x, bounds.min.y], [bounds.max.x, bounds.max.y]);
let mut results: HashMap<String, f32> = HashMap::new();
// Do the r-tree search to get back the candidates points
let candidates = self.rtree.locate_in_envelope(&target_bounds);
// Filter the candidates to make sure we only have points explicitly within
// the polygon
let hits = candidates.filter(|p| match poly {
Geometry::MultiPolygon(target) => target.contains(&p.coords),
_ => false,
});
let mut count = 0;
// Calculate the aggregates
for hit in hits {
count = count + 1;
for key in hit.data.keys() {
let val = hit.data.get(key).unwrap();
*results.entry(key.to_string()).or_insert(0.0) += val;
}
}
results.insert("count".to_string(), count as f32);
// Return!
results
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment