routee-compass-core 0.11.3

The core routing algorithms and data structures of the RouteE-Compass energy-aware routing engine
Documentation
use super::map_error::MapError;
use super::map_model_config::MapModelConfig;
use super::matching_type::MatchingType;
use super::spatial_index::SpatialIndex;
use super::{geometry_model::GeometryModel, matching_type::MapInputResult};
use crate::algorithm::search::SearchInstance;
use crate::model::network::{EdgeId, Graph};
use geo::LineString;
use std::sync::Arc;

pub struct MapModel {
    pub matching_type: MatchingType,
    pub spatial_index: SpatialIndex,
    pub geometry_model: GeometryModel,
    pub queries_without_destinations: bool,
}

impl MapModel {
    pub fn new(graph: Arc<Graph>, config: MapModelConfig) -> Result<MapModel, MapError> {
        let matching_type = config.get_matching_type()?;
        match config {
            MapModelConfig::VertexMapModelConfig {
                tolerance,
                geometry_input_file,
                queries_without_destinations,
                matching_type: _,
            } => {
                let tol_unpacked = tolerance.map(|t| t.unpack());
                let spatial_index =
                    SpatialIndex::new_vertex_oriented(&graph.clone().vertices, tol_unpacked);
                let geometry_model = match geometry_input_file {
                    None => GeometryModel::new_from_vertices(graph),
                    Some(file) => GeometryModel::new_from_edges(&file, graph.clone()),
                }?;

                let map_model = MapModel {
                    matching_type,
                    spatial_index,
                    geometry_model,
                    queries_without_destinations,
                };
                Ok(map_model)
            }
            MapModelConfig::EdgeMapModelConfig {
                tolerance,
                geometry_input_file,
                queries_without_destinations,
                matching_type: _,
            } => {
                let tol_unpacked = tolerance.map(|t| t.unpack());
                let geometry_model =
                    GeometryModel::new_from_edges(&geometry_input_file, graph.clone())?;
                let spatial_index =
                    SpatialIndex::new_edge_oriented(graph.clone(), &geometry_model, tol_unpacked);
                let map_model = MapModel {
                    matching_type,
                    spatial_index,
                    geometry_model,
                    queries_without_destinations,
                };
                Ok(map_model)
            }
        }
    }

    pub fn get<'a>(&'a self, edge_id: &EdgeId) -> Result<&'a LineString<f32>, MapError> {
        self.geometry_model.get(edge_id)
    }

    pub fn map_match(
        &self,
        query: &mut serde_json::Value,
        si: &SearchInstance,
    ) -> Result<(), MapError> {
        self.matching_type.process_origin(query, si)?;
        match self.matching_type.process_destination(query, si)? {
            MapInputResult::NotFound if !self.queries_without_destinations => {
                Err(MapError::DestinationsRequired(self.matching_type.clone()))
            }
            _ => Ok(()),
        }
    }
}