h3ron_graph/graph/
modifiers.rs1use std::marker::PhantomData;
2
3use crate::error::Error;
4use h3ron::collections::H3Treemap;
5use h3ron::{H3Cell, H3DirectedEdge, HasH3Resolution};
6
7use crate::graph::node::NodeType;
8use crate::graph::{EdgeWeight, GetCellEdges, GetCellNode};
9
10pub struct ExcludeCells<'a, G, W> {
12 cells_to_exclude: &'a H3Treemap<H3Cell>,
13 inner_graph: &'a G,
14 phantom_weight: PhantomData<W>,
15}
16
17impl<'a, G, W> ExcludeCells<'a, G, W>
18where
19 G: GetCellNode + GetCellEdges<EdgeWeightType = W> + HasH3Resolution,
20{
21 pub fn new(inner_graph: &'a G, cells_to_exclude: &'a H3Treemap<H3Cell>) -> Self {
22 Self {
23 cells_to_exclude,
24 inner_graph,
25 phantom_weight: Default::default(),
26 }
27 }
28}
29
30impl<'a, G, W> GetCellNode for ExcludeCells<'a, G, W>
31where
32 G: GetCellNode,
33{
34 fn get_cell_node(&self, cell: &H3Cell) -> Option<NodeType> {
35 if self.cells_to_exclude.contains(cell) {
36 None
37 } else {
38 self.inner_graph.get_cell_node(cell)
39 }
40 }
41}
42
43impl<'a, G, W> GetCellEdges for ExcludeCells<'a, G, W>
44where
45 G: GetCellEdges<EdgeWeightType = W>,
46{
47 type EdgeWeightType = G::EdgeWeightType;
48
49 fn get_edges_originating_from(
50 &self,
51 cell: &H3Cell,
52 ) -> Result<Vec<(H3DirectedEdge, EdgeWeight<Self::EdgeWeightType>)>, Error> {
53 if self.cells_to_exclude.contains(cell) {
54 Ok(vec![])
55 } else {
56 let found = self.inner_graph.get_edges_originating_from(cell)?;
57 let mut not_excluded = Vec::with_capacity(found.len());
58 for (edge, edge_value) in found {
59 if self.cells_to_exclude.contains(&edge.destination_cell()?) {
60 continue;
61 }
62
63 let filtered_longedge_opt =
65 if let Some((longedge, longedge_weight)) = edge_value.longedge {
66 if longedge.is_disjoint(self.cells_to_exclude) {
67 Some((longedge, longedge_weight))
68 } else {
69 None
70 }
71 } else {
72 None
73 };
74
75 not_excluded.push((
76 edge,
77 EdgeWeight {
78 weight: edge_value.weight,
79 longedge: filtered_longedge_opt,
80 },
81 ));
82 }
83 Ok(not_excluded)
84 }
85 }
86}
87
88impl<'a, G, W> HasH3Resolution for ExcludeCells<'a, G, W>
89where
90 G: HasH3Resolution,
91{
92 fn h3_resolution(&self) -> u8 {
93 self.inner_graph.h3_resolution()
94 }
95}