gistools/readers/gtfs/schedule/
mod.rs1mod agency;
3mod areas;
4mod attributions;
5mod booking_rules;
6mod calendar;
7mod calendar_dates;
8mod fare_attributes;
9mod fare_leg_join_rules;
10mod fare_leg_rules;
11mod fare_media;
12mod fare_products;
13mod fare_rules;
14mod fare_transfer_rules;
15mod feed_info;
16mod frequencies;
17mod levels;
18mod location_group_stops;
19mod location_groups;
20mod networks;
21mod pathways;
22mod route_networks;
23mod routes;
24mod shapes;
25mod stop_areas;
26mod stop_times;
27mod stops;
28mod timeframes;
29mod transfers;
30mod translations;
31mod trips;
32
33use crate::{
34 parsers::FeatureReader,
35 readers::json::{JSONCollectionReader, ToGisJSON},
36 util::iter_zip_folder,
37};
38pub use agency::*;
39use alloc::{collections::BTreeMap, string::String, vec, vec::Vec};
40pub use areas::*;
41pub use attributions::*;
42pub use booking_rules::*;
43pub use calendar::*;
44pub use calendar_dates::*;
45pub use fare_attributes::*;
46pub use fare_leg_join_rules::*;
47pub use fare_leg_rules::*;
48pub use fare_media::*;
49pub use fare_products::*;
50pub use fare_rules::*;
51pub use fare_transfer_rules::*;
52pub use feed_info::*;
53pub use frequencies::*;
54pub use levels::*;
55pub use location_group_stops::*;
56pub use location_groups::*;
57pub use networks::*;
58pub use pathways::*;
59pub use route_networks::*;
60pub use routes::*;
61use s2json::{MValue, MValueCompatible, Properties, VectorFeature};
62use serde::{Deserialize, Serialize};
63pub use shapes::*;
64pub use stop_areas::*;
65pub use stop_times::*;
66pub use stops::*;
67pub use timeframes::*;
68pub use transfers::*;
69pub use translations::*;
70pub use trips::*;
71
72#[derive(Debug, Clone, PartialEq)]
76pub struct Piece {
77 pub filename: String,
79 pub data: String,
81}
82
83#[derive(Debug, Default, Clone, PartialEq, MValueCompatible, Serialize, Deserialize)]
87pub struct GTFSLocationsProperties {
88 pub stop_name: String,
90 pub stop_desc: String,
92}
93
94#[derive(Debug, Default, Clone)]
135pub struct GTFSScheduleReader {
136 pub agencies: BTreeMap<String, GTFSAgency>,
138 pub areas: BTreeMap<String, GTFSArea>,
140 pub attributions: BTreeMap<String, GTFSAttribution>,
142 pub booking_rules: BTreeMap<String, GTFSBookingRule>,
144 pub calendar: Vec<GTFSCalendar>,
146 pub calendar_dates: BTreeMap<String, GTFSCalendarDate>,
148 pub fare_attributes: BTreeMap<String, GTFSFareAttribute>,
150 pub fare_leg_join_rules: Vec<GTFSFareLegJoinRule>,
152 pub fare_leg_rules: Vec<GTFSFareLegRule>,
154 pub fare_media: BTreeMap<String, GTFSFareMedia>,
156 pub fare_products: BTreeMap<String, GTFSFareProduct>,
158 pub fare_rules: Vec<GTFSFareRule>,
160 pub fare_transfer_rules: Vec<GTFSFareTransferRule>,
162 pub feed_info: BTreeMap<String, GTFSFeedInfo>,
164 pub frequencies: Vec<GTFSFrequency>,
166 pub levels: BTreeMap<String, GTFSLevel>,
168 pub location_groups: BTreeMap<String, GTFSLocationGroup>,
170 pub location_group_stops: Vec<GTFSLocationGroupStop>,
172 pub networks: BTreeMap<String, GTFSNetwork>,
174 pub pathways: BTreeMap<String, GTFSPathway>,
176 pub route_networks: Vec<GTFSRouteNetwork>,
178 pub routes: BTreeMap<String, GTFSRoute>,
180 pub shapes: BTreeMap<String, Vec<GTFSShape>>,
182 pub stop_areas: Vec<GTFSStopArea>,
184 pub stops: BTreeMap<String, GTFSStop>,
186 pub stop_times: Vec<GTFSStopTime>,
188 pub timeframes: BTreeMap<String, GTFSTimeframe>,
190 pub transfers: Vec<GTFSTransfer>,
192 pub translations: Vec<GTFSTranslation>,
194 pub trips: BTreeMap<String, GTFSTrip>,
196 pub geojson: Option<JSONCollectionReader>,
198}
199impl GTFSScheduleReader {
200 pub fn new(pieces: &[Piece]) -> Self {
202 let mut res = GTFSScheduleReader::default();
203
204 for Piece { filename, data } in pieces {
205 let stem = filename.split('.').next().unwrap_or("");
206 match stem {
207 "agency" => res.agencies = GTFSAgency::new(data),
208 "areas" => res.areas = GTFSArea::new(data),
209 "attributions" => res.attributions = GTFSAttribution::new(data),
210 "booking_rules" => res.booking_rules = GTFSBookingRule::new(data),
211 "calendar" => res.calendar = GTFSCalendar::new(data),
212 "calendar_dates" => res.calendar_dates = GTFSCalendarDate::new(data),
213 "fare_attributes" => res.fare_attributes = GTFSFareAttribute::new(data),
214 "fare_leg_join_rules" => res.fare_leg_join_rules = GTFSFareLegJoinRule::new(data),
215 "fare_leg_rules.txt" => res.fare_leg_rules = GTFSFareLegRule::new(data),
216 "fare_media" => res.fare_media = GTFSFareMedia::new(data),
217 "fare_products" => res.fare_products = GTFSFareProduct::new(data),
218 "fare_rules" => res.fare_rules = GTFSFareRule::new(data),
219 "fare_transfer_rules" => res.fare_transfer_rules = GTFSFareTransferRule::new(data),
220 "feed_info" => res.feed_info = GTFSFeedInfo::new(data),
221 "frequencies" => res.frequencies = GTFSFrequency::new(data),
222 "levels" => res.levels = GTFSLevel::new(data),
223 "location_groups" => res.location_groups = GTFSLocationGroup::new(data),
224 "location_group_stops" => {
225 res.location_group_stops = GTFSLocationGroupStop::new(data)
226 }
227 "networks" => res.networks = GTFSNetwork::new(data),
228 "pathways" => res.pathways = GTFSPathway::new(data),
229 "route_networks" => res.route_networks = GTFSRouteNetwork::new(data),
230 "routes" => res.routes = GTFSRoute::new(data),
231 "shapes" => res.shapes = GTFSShape::new(data),
232 "stop_areas" => res.stop_areas = GTFSStopArea::new(data),
233 "stops" => res.stops = GTFSStop::new(data),
234 "stop_times" => res.stop_times = GTFSStopTime::new(data),
235 "timeframes" => res.timeframes = GTFSTimeframe::new(data),
236 "transfers" => res.transfers = GTFSTransfer::new(data),
237 "translations" => res.translations = GTFSTranslation::new(data),
238 "trips" => res.trips = GTFSTrip::new(data),
239 "locations" => {
240 if let Ok(mut feature_collection) = data.as_str().to_feature_collection() {
241 res.geojson = Some(JSONCollectionReader::from(&mut feature_collection));
242 }
243 }
244 _ => {}
245 }
246 }
247
248 res
249 }
250
251 pub fn from_gzip(gzip_data: &[u8]) -> Self {
259 let mut pieces: Vec<Piece> = vec![];
260
261 for item in iter_zip_folder(gzip_data).unwrap() {
262 if let Ok(read_data) = (item.read)() {
263 pieces.push(Piece {
264 filename: item.filename,
265 data: String::from_utf8_lossy(&read_data).into(),
266 });
267 }
268 }
269
270 GTFSScheduleReader::new(&pieces)
271 }
272
273 #[cfg(feature = "std")]
275 pub fn from_folder(folder_path: &str) -> Self {
276 let mut pieces: Vec<Piece> = vec![];
277
278 for entry in std::fs::read_dir(folder_path).unwrap().flatten() {
279 if let Ok(read_data) = std::fs::read(entry.path()) {
280 pieces.push(Piece {
281 filename: entry.file_name().to_str().unwrap().into(),
282 data: String::from_utf8_lossy(&read_data).into(),
283 });
284 }
285 }
286
287 GTFSScheduleReader::new(&pieces)
288 }
289
290 pub fn collect_vector_features(&self) -> Vec<VectorFeature> {
292 let mut res = vec![];
293 for stop in self.stops.values() {
295 if let Some(feature) = stop.to_feature() {
296 res.push(feature);
297 }
298 }
299 if let Some(geojson) = &self.geojson {
301 for feature in geojson.iter() {
302 res.push(feature);
303 }
304 }
305 for shape in self.shapes.values() {
307 let gtfs_shapes: GTFSShapes = shape.into();
308 res.push(gtfs_shapes.into());
309 }
310
311 res
312 }
313}
314
315#[derive(Debug)]
317pub struct GTFSScheduleIterator {
318 features: Vec<VectorFeature>,
319 index: usize,
320}
321impl Iterator for GTFSScheduleIterator {
322 type Item = VectorFeature;
323
324 fn next(&mut self) -> Option<Self::Item> {
325 self.index += 1;
326 self.features.get(self.index - 1).cloned()
327 }
328}
329impl FeatureReader<(), Properties, MValue> for GTFSScheduleReader {
331 type FeatureIterator<'a> = GTFSScheduleIterator;
332
333 fn iter(&self) -> Self::FeatureIterator<'_> {
334 GTFSScheduleIterator { features: self.collect_vector_features(), index: 0 }
335 }
336
337 fn par_iter(&self, pool_size: usize, thread_id: usize) -> Self::FeatureIterator<'_> {
338 let start = self.collect_vector_features().len() * thread_id / pool_size;
339 let end = self.collect_vector_features().len() * (thread_id + 1) / pool_size;
340 let features = self.collect_vector_features()[start..end].to_vec();
341 GTFSScheduleIterator { features, index: 0 }
342 }
343}