Back to Atlas map viewer
SOURCE / PINNED RELEASE

Made of little things.

Atlas map viewer

Release
1d2807e80b44…
Author-recorded commit
43810ed2b368…
License
LICENSE
Author’s source reference
nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-4757dbabc86

Archive hash verified: 8db6876d96c460ac…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

crates/routing/src/cells/snap.rs
//! Endpoint selection and directional partial-edge costs.
use super::*;
pub(super) fn snap_cells(p: [f64; 2]) -> Vec<(u32, u32)> {
    let lat = (SNAP_LIMIT_METERS / 6_371_000.).to_degrees() + 1e-8;
    let lon = lat / (p[1].abs() + lat).to_radians().cos();
    let a = cell([p[0] - lon, p[1] + lat]);
    let b = cell([p[0] + lon, p[1] - lat]);
    let mut cells = Vec::new();
    for x in a.0..=b.0 {
        for y in a.1..=b.1 {
            cells.push((x, y));
        }
    }
    cells
}
#[derive(Clone)]
pub(super) struct Endpoint {
    pub(super) snap: Snap,
    pub(super) id: u128,
    pub(super) a: Node,
    pub(super) b: Node,
    pub(super) directions: u8,
    pub(super) length: f64,
    pub(super) costs: [f64; 2],
}
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub(super) struct Key {
    pub(super) node: i64,
    pub(super) way: i64,
    pub(super) before: i64,
}
impl Endpoint {
    pub(super) fn connections(&self) -> Vec<(Key, [f64; 2], f64, f64)> {
        let mut v = Vec::new();
        let t = self.snap.t;
        if t <= 1e-12 || self.directions & 2 != 0 {
            v.push((
                Key {
                    node: self.a.id,
                    way: if t <= 1e-12 { 0 } else { self.snap_way() },
                    before: self.b.id,
                },
                self.a.position,
                t * self.costs[1],
                t * self.length,
            ));
        }
        if t >= 1. - 1e-12 || self.directions & 1 != 0 {
            v.push((
                Key {
                    node: self.b.id,
                    way: if t >= 1. - 1e-12 { 0 } else { self.snap_way() },
                    before: self.a.id,
                },
                self.b.position,
                (1. - t) * self.costs[0],
                (1. - t) * self.length,
            ));
        }
        v
    }
    pub(super) fn snap_way(&self) -> i64 {
        self.snap.way_id[4..].parse().unwrap()
    }
    pub(super) fn goals(&self) -> Vec<(i64, [f64; 2], f64, f64, i64)> {
        let mut v = Vec::new();
        let t = self.snap.t;
        if t <= 1e-12 || self.directions & 1 != 0 {
            v.push((
                self.a.id,
                self.a.position,
                t * self.costs[0],
                t * self.length,
                self.b.id,
            ));
        }
        if t >= 1. - 1e-12 || self.directions & 2 != 0 {
            v.push((
                self.b.id,
                self.b.position,
                (1. - t) * self.costs[1],
                (1. - t) * self.length,
                self.a.id,
            ));
        }
        v
    }
}
pub(super) fn snap(cells: &super::cache::CellCache, p: [f64; 2]) -> Option<Endpoint> {
    let mut best: Option<Endpoint> = None;
    for address in snap_cells(p) {
        if let Some(c) = cells.get(&address) {
            if let Some(snap) = c.graph.snap(p) {
                let seg = &c.graph.segments[snap.segment];
                let id = c.ids[snap.segment];
                if best.as_ref().is_none_or(|v| {
                    snap.distance_meters < v.snap.distance_meters
                        || snap.distance_meters == v.snap.distance_meters && id < v.id
                }) {
                    best = Some(Endpoint {
                        id,
                        a: c.graph.nodes[seg.a as usize].clone(),
                        b: c.graph.nodes[seg.b as usize].clone(),
                        directions: seg.directions,
                        length: c.graph.lengths[snap.segment],
                        costs: c.graph.costs[snap.segment],
                        snap,
                    });
                }
            }
        }
    }
    best
}