geo/algorithm/relate/geomgraph/
node.rs

1use super::{CoordPos, Dimensions, EdgeEnd, EdgeEndBundleStar, IntersectionMatrix, Label};
2use crate::{Coord, GeoFloat};
3
4#[derive(Debug, Clone, PartialEq)]
5pub(crate) struct CoordNode<F>
6where
7    F: GeoFloat,
8{
9    coordinate: Coord<F>,
10    label: Label,
11}
12
13impl<F: GeoFloat> CoordNode<F> {
14    pub fn swap_label_args(&mut self) {
15        self.label.swap_args()
16    }
17
18    pub(crate) fn label(&self) -> &Label {
19        &self.label
20    }
21
22    pub(crate) fn label_mut(&mut self) -> &mut Label {
23        &mut self.label
24    }
25
26    pub(crate) fn is_isolated(&self) -> bool {
27        self.label.geometry_count() == 1
28    }
29}
30
31impl<F> CoordNode<F>
32where
33    F: GeoFloat,
34{
35    pub fn new(coordinate: Coord<F>) -> CoordNode<F> {
36        CoordNode {
37            coordinate,
38            label: Label::empty_line_or_point(),
39        }
40    }
41
42    pub fn coordinate(&self) -> &Coord<F> {
43        &self.coordinate
44    }
45
46    pub fn set_label_on_position(&mut self, geom_index: usize, position: CoordPos) {
47        self.label.set_on_position(geom_index, position)
48    }
49
50    /// Updates the label of a node to BOUNDARY, obeying the mod-2 rule.
51    pub fn set_label_boundary(&mut self, geom_index: usize) {
52        let new_position = match self.label.on_position(geom_index) {
53            Some(CoordPos::OnBoundary) => CoordPos::Inside,
54            Some(CoordPos::Inside) => CoordPos::OnBoundary,
55            None | Some(CoordPos::Outside) => CoordPos::OnBoundary,
56        };
57        self.label.set_on_position(geom_index, new_position);
58    }
59
60    // In JTS this method is implemented on a `GraphComponent` superclass, but since it's only used
61    // by this one "subclass" I've implemented it directly on the node, rather than introducing
62    // something like a `GraphComponent` trait
63    pub fn update_intersection_matrix(&self, intersection_matrix: &mut IntersectionMatrix) {
64        assert!(self.label.geometry_count() >= 2, "found partial label");
65        intersection_matrix.set_at_least_if_in_both(
66            self.label.on_position(0),
67            self.label.on_position(1),
68            Dimensions::ZeroDimensional,
69        );
70        debug!("updated intersection_matrix: {intersection_matrix:?} from node: {self:?}");
71    }
72}