routee_compass_core/model/map/
map_model.rs1use super::map_error::MapError;
2use super::map_model_config::MapModelConfig;
3use super::matching_type::MatchingType;
4use super::spatial_index::SpatialIndex;
5use super::{geometry_model::GeometryModel, matching_type::MapInputResult};
6use crate::algorithm::search::SearchInstance;
7use crate::model::map::map_model_config::MapModelGeometryConfig;
8use crate::model::network::{EdgeId, EdgeListId, Graph};
9use geo::LineString;
10use std::sync::Arc;
11
12pub struct MapModel {
13 pub matching_type: MatchingType,
15 pub spatial_index: SpatialIndex,
17 pub geometry: Vec<GeometryModel>,
19 pub queries_without_destinations: bool,
22 pub config: MapModelConfig,
24}
25
26impl MapModel {
27 pub fn new(graph: Arc<Graph>, config: MapModelConfig) -> Result<MapModel, MapError> {
28 let geometry = config
29 .geometry
30 .iter()
31 .enumerate()
32 .map(|(edge_list, g)| {
33 let edge_list_id = EdgeListId(edge_list);
34 match g {
35 MapModelGeometryConfig::FromVertices => {
36 GeometryModel::new_from_vertices(graph.clone(), edge_list_id)
37 }
38 MapModelGeometryConfig::FromLinestrings {
39 geometry_input_file,
40 } => GeometryModel::new_from_edges(
41 geometry_input_file,
42 edge_list_id,
43 graph.clone(),
44 ),
45 }
46 })
47 .collect::<Result<Vec<_>, _>>()?;
48 let queries_without_destinations = config.queries_without_destinations;
49 let tolerance = config.tolerance.as_ref().map(|t| t.to_uom());
50 let matching_type =
51 MatchingType::deserialize_matching_types(config.matching_type.as_ref())?;
52 let spatial_index_type = config.spatial_index_type.clone().unwrap_or_default();
53 let spatial_index =
54 SpatialIndex::build(&spatial_index_type, graph.clone(), &geometry, tolerance);
55
56 Ok(MapModel {
57 matching_type,
58 spatial_index,
59 geometry,
60 queries_without_destinations,
61 config,
62 })
63 }
64
65 pub fn get_linestring<'a>(
66 &'a self,
67 edge_list_id: &EdgeListId,
68 edge_id: &EdgeId,
69 ) -> Result<&'a LineString<f32>, MapError> {
70 let linestrings = self
71 .geometry
72 .get(edge_list_id.0)
73 .ok_or(MapError::MissingEdgeListId(*edge_list_id))?;
74 linestrings
75 .get(edge_id)
76 .ok_or(MapError::MissingEdgeId(*edge_list_id, *edge_id))
77 }
78
79 pub fn map_match(
80 &self,
81 query: &mut serde_json::Value,
82 si: &SearchInstance,
83 ) -> Result<(), MapError> {
84 self.matching_type.process_origin(query, si)?;
85 let result = self.matching_type.process_destination(query, si)?;
86 match result {
87 MapInputResult::NotFound if !self.queries_without_destinations => {
88 Err(MapError::DestinationsRequired(self.matching_type.clone()))
89 }
90 _ => Ok(()),
91 }
92 }
93}