valhalla_client/matrix.rs
1use crate::costing;
2use crate::shapes::ShapeFormat;
3pub use crate::DateTime;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7#[serde_with::skip_serializing_none]
8#[derive(Serialize, Default, Debug)]
9/// Matrix request
10pub struct Manifest {
11 pub(crate) targets: Vec<Location>,
12 pub(crate) sources: Vec<Location>,
13 #[serde(flatten)]
14 costing: costing::Costing,
15 id: Option<String>,
16 matrix_locations: Option<u32>,
17 date_time: Option<DateTime>,
18 verbose: Option<bool>,
19 shape_format: Option<ShapeFormat>,
20}
21impl Manifest {
22 /// Create a builder for the matrix request
23 pub fn builder() -> Self {
24 Default::default()
25 }
26 /// Sets the source and targets of the matrix
27 pub fn sources_to_targets(
28 mut self,
29 sources: impl IntoIterator<Item = Location>,
30 targets: impl IntoIterator<Item = Location>,
31 ) -> Self {
32 self.sources = sources.into_iter().collect();
33 self.targets = targets.into_iter().collect();
34 self
35 }
36 /// Configures the costing model
37 ///
38 /// Valhalla's routing service uses dynamic, run-time costing to generate the route path.
39 /// Can be configured with different settings depending on the costing model used.
40 ///
41 /// **Note:** multimodal costing is not supported for the time-distance matrix service at this time.
42 ///
43 /// Default: [`costing::Costing::Auto`]
44 pub fn costing(mut self, costing: costing::Costing) -> Self {
45 self.costing = costing;
46 self
47 }
48 /// Name your route request.
49 ///
50 /// If id is specified, the naming will be sent through to the response.
51 pub fn id(mut self, id: impl ToString) -> Self {
52 self.id = Some(id.to_string());
53 self
54 }
55 /// Sets the minimum number of locations that need to be found satisfying the request
56 ///
57 /// Allows a partial result to be returned.
58 ///
59 /// This is basically equivalent to:
60 /// > "find the closest or best N locations out of the full location set"
61 pub fn minimum_matrix_locations_count(mut self, count: u32) -> Self {
62 self.matrix_locations = Some(count);
63 self
64 }
65 /// Shortcut for configuring the arrival/departure date_time settings globally
66 /// instead of specifying it for each source/target.
67 ///
68 /// See [`Location::date_time`] if you want a more granular API.
69 /// Valhalla will translate this to setting the value on all `source` locations when
70 /// [`DateTime::from_current_departure_time`] or [`DateTime::from_departure_time`] is used and
71 /// on all `target` locations when [`DateTime::from_arrival_time`].
72 ///
73 /// **Note:**
74 /// There are important limitations to time awareness.
75 /// Due to algorithmic complexity, we disallow time-dependence for certain combinations
76 /// of date_time on locations:
77 /// - when there are more sources than `target`s:
78 /// - [`Location::date_time`] on any `source`
79 /// - using [`Self::date_time`] with [`DateTime::from_current_departure_time`] and [`DateTime::from_departure_time`]
80 /// - when there's more or equal amount of `target`s than/as `source`s
81 /// - [`Location::date_time`] on any `target`
82 /// - [`DateTime::from_arrival_time`]
83 pub fn date_time(mut self, date_time: DateTime) -> Self {
84 self.date_time = Some(date_time);
85 self
86 }
87 /// Modifies the verbosity of the output:
88 /// - `true` will output a flat list of objects for distances & durations explicitly specifying
89 /// the `source` & `target` indices.
90 /// - `false` will return more compact, nested row-major distances & durations arrays and
91 /// not echo `sources` and `targets`
92 ///
93 /// Default: `true`
94 pub fn verbose_output(mut self, verbose: bool) -> Self {
95 self.verbose = Some(verbose);
96 self
97 }
98 /// Specifies the [`ShapeFormat`] for the path shape of each connection.
99 pub fn shape_format(mut self, shape_format: ShapeFormat) -> Self {
100 self.shape_format = Some(shape_format);
101 self
102 }
103}
104
105#[serde_with::skip_serializing_none]
106#[derive(Serialize, Default, Clone, Copy, PartialEq, Debug)]
107/// Location of a point on the map
108pub struct Location {
109 lat: f32,
110 lon: f32,
111 #[serde(serialize_with = "super::serialize_naive_date_time_opt")]
112 date_time: Option<chrono::NaiveDateTime>,
113}
114impl From<super::Coordinate> for Location {
115 fn from((longitude, latitude): super::Coordinate) -> Self {
116 Self {
117 lat: latitude,
118 lon: longitude,
119 date_time: None,
120 }
121 }
122}
123impl Location {
124 /// Creates a new location from a longitude/latitude
125 pub fn new(longitude: f32, latitude: f32) -> Self {
126 Self::from((longitude, latitude))
127 }
128 /// Expected date/time for the user to be at the location in the local time zone of departure or arrival.
129 ///
130 /// Offers more granularity over setting time than the global [`Manifest::date_time`].
131 ///
132 /// **Note:**
133 /// This behaves differently for the matrix in comparison to the route API:
134 /// - If set on the sources and there's more targets than sources,
135 /// it will behave like a *"Specified departure time"* on the sources.
136 /// - If set on the targets and there's less targets than sources,
137 /// it will behave like a *"Specified arrival time"* on the targets.
138 ///
139 /// **Note:**
140 /// There are important limitations to time awareness.
141 /// Due to algorithmic complexity, we disallow time-dependence for certain combinations
142 /// of date_time on locations:
143 /// - when there are more sources than `target`s:
144 /// - [`Location::date_time`] on any `source`
145 /// - using [`Self::date_time`] with [`DateTime::from_current_departure_time`] and [`DateTime::from_departure_time`]
146 /// - when there's more or equal amount of `target`s than/as `source`s
147 /// - [`Location::date_time`] on any `target`
148 /// - [`DateTime::from_arrival_time`]
149 pub fn date_time(mut self, date_time: chrono::NaiveDateTime) -> Self {
150 self.date_time = Some(date_time);
151 self
152 }
153}
154
155/// [`Location`] which was configured in the input
156///
157/// Present only in `verbose` mode. Verbosity can be set via [`Manifest::verbose_output`]
158#[derive(Deserialize, Default, Clone, Copy, PartialEq, Debug)]
159pub struct VerboseLocation {
160 /// Latitude as defined in [`super::Coordinate`]
161 pub lat: f32,
162 /// Longitude as defined in [`super::Coordinate`]
163 pub lon: f32,
164 /// time configured via [`Location::date_time`]
165 pub date_time: Option<chrono::NaiveDateTime>,
166}
167
168impl From<Location> for VerboseLocation {
169 fn from(value: Location) -> Self {
170 Self {
171 lat: value.lat,
172 lon: value.lon,
173 date_time: value.date_time,
174 }
175 }
176}
177
178impl From<VerboseLocation> for Location {
179 fn from(value: VerboseLocation) -> Self {
180 Self {
181 lat: value.lat,
182 lon: value.lon,
183 date_time: value.date_time,
184 }
185 }
186}
187
188#[derive(Deserialize, Debug, Clone)]
189#[serde(untagged)]
190/// Response to the matrix request
191pub enum Response {
192 /// Returned in `verbose` mode.
193 ///
194 /// Verbosity can be set via [`Manifest::verbose_output`]
195 Verbose(VerboseResponse),
196 /// Returned in non-`verbose` mode.
197 ///
198 /// Verbosity can be set via [`Manifest::verbose_output`]
199 Concise(ConciseResponse),
200}
201#[derive(Deserialize, Debug, Clone)]
202/// Verbose response to the matrix request
203pub struct VerboseResponse {
204 /// Name of the route request.
205 ///
206 /// If id is specified via [`Manifest::id`] the naming will be sent through to the response.
207 pub id: Option<String>,
208 /// Algorithm used
209 pub algorithm: String,
210 /// Distance units for output.
211 ///
212 /// Possible unit types are miles via [`super::Units::Imperial`] and kilometers via [`super::Units::Metric`].
213 ///
214 /// Default: [`super::Units::Metric`]
215 pub units: super::Units,
216 /// This array may contain warning objects informing about deprecated request parameters, clamped values etc.
217 #[serde(default = "Vec::new")]
218 pub warnings: Vec<Value>,
219 /// The sources of the matrix
220 pub sources: Vec<VerboseLocation>,
221 /// The targets of the matrix
222 pub targets: Vec<VerboseLocation>,
223 /// A flat list of objects for distances & durations explicitly specifying the `source` & `target` indices.
224 ///
225 /// The arrays rows are:
226 /// - time and distance from the first source location to all target locations,
227 /// - time and distance from the second source location to all target locations,
228 /// - etc.
229 pub sources_to_targets: Vec<Vec<VerboseSourceToTarget>>,
230}
231#[derive(Deserialize, Debug, Clone)]
232/// Concise response to the matrix request
233pub struct ConciseResponse {
234 /// Name of the route request.
235 ///
236 /// If id is specified via [`Manifest::id`] the naming will be sent through to the response.
237 pub id: Option<String>,
238 /// Algorithm used
239 pub algorithm: String,
240 /// Distance units for output.
241 ///
242 /// Possible unit types are miles via [`super::Units::Imperial`] and kilometers via [`super::Units::Metric`].
243 ///
244 /// Default: [`super::Units::Metric`]
245 pub units: super::Units,
246 /// This array may contain warning objects informing about deprecated request parameters, clamped values etc.
247 #[serde(default = "Vec::new")]
248 pub warnings: Vec<Value>,
249 /// More compact, nested row-major distances & durations
250 ///
251 /// The arrays rows are:
252 /// - time and distance from the first source location to all target locations,
253 /// - time and distance from the second source location to all target locations,
254 /// - etc.
255 pub sources_to_targets: ConciseSourceToTargets,
256}
257
258#[derive(Deserialize, Debug, Clone)]
259/// Concise source to target
260pub struct ConciseSourceToTargets {
261 /// The computed time between each set of points.
262 ///
263 /// Time will always be `0` for
264 /// - the first element of the time-distance array for one_to_many,
265 /// - the last element in a many_to_one, and
266 /// - the first and last elements of a many_to_many
267 pub durations: Vec<Vec<u32>>,
268 /// The computed distance between each set of points.
269 ///
270 /// Distance will always be `0.00` for
271 /// - the first element of the time-distance array for one_to_many,
272 /// - the last element in a many_to_one, and
273 /// - the first and last elements of a many_to_many.
274 pub distances: Vec<Vec<f32>>,
275}
276
277#[derive(Deserialize, Debug, Clone)]
278/// Verbose source to target
279pub struct VerboseSourceToTarget {
280 /// The computed distance between each set of points.
281 ///
282 /// Distance will always be `0.00` for
283 /// - the first element of the time-distance array for one_to_many,
284 /// - the last element in a many_to_one, and
285 /// - the first and last elements of a many_to_many.
286 pub distance: f32,
287 /// The computed time between each set of points.
288 ///
289 /// Time will always be `0` for
290 /// - the first element of the time-distance array for one_to_many,
291 /// - the last element in a many_to_one, and
292 /// - the first and last elements of a many_to_many
293 pub time: u32,
294 /// The destination index into the locations array
295 pub from_index: usize,
296 /// The origin index into the locations array
297 pub to_index: usize,
298 /// Timezone of when a user will arrive at this location or has to depart from the start point.
299 ///
300 /// For information how to differentiate between departure/arrival time, please see [`Manifest::date_time`] or [`Location::date_time`].
301 ///
302 /// This field is included only if:
303 /// - valhalla is build with timezone support,
304 /// - the time is below the settings `max_timedep_distance_matrix` or `max_timedep_distance`
305 /// - departure/arrival time is unspecified via [`Manifest::date_time`] or [`Location::date_time`]
306 ///
307 /// Example: `"Europe/Berlin"`
308 pub time_zone_name: Option<String>,
309 /// Timezone of when a user will arrive at this location or has to depart from the start point.
310 ///
311 /// For information how to differentiate between departure/arrival time, please see [`Manifest::date_time`] or [`Location::date_time`].
312 ///
313 /// This field is included only if:
314 /// - valhalla is build with timezone support,
315 /// - the time is below the settings `max_timedep_distance_matrix` or `max_timedep_distance`
316 /// - departure/arrival time is unspecified via [`Manifest::date_time`] or [`Location::date_time`]
317 ///
318 /// Example: `"+01:00"`
319 pub time_zone_offset: Option<String>,
320 /// When a user will arrive at this location or has to depart from the start point.
321 ///
322 /// For information how to differentiate between departure/arrival time, please see [`Manifest::date_time`] or [`Location::date_time`].
323 ///
324 /// This field is included only if:
325 /// - the time is below the settings `max_timedep_distance_matrix` or `max_timedep_distance`
326 /// - departure/arrival time is unspecified via [`Manifest::date_time`] or [`Location::date_time`]
327 ///
328 /// Example: `"2024-11-07T15:26"`
329 pub date_time: Option<chrono::NaiveDateTime>,
330}