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