1pub mod csv;
3pub mod gbfs;
5pub mod geotiff;
7pub mod gpx;
9pub mod grib2;
11pub mod gtfs;
13pub mod json;
15pub mod las;
17pub mod nadgrid;
19pub mod netcdf;
21pub mod osm;
23pub mod pmtiles;
25pub mod s2tiles;
27pub mod shapefile;
29#[cfg(feature = "std")]
31pub mod tile;
32pub mod wkt;
34
35#[cfg(feature = "std")]
36use crate::parsers::FileReader;
37use crate::parsers::{BufferReader, FeatureReader, Reader};
38use alloc::{boxed::Box, collections::BTreeMap, string::String, vec, vec::Vec};
39use core::fmt::Debug;
40pub use csv::*;
41pub use gbfs::*;
42pub use geotiff::*;
43pub use gpx::*;
44pub use grib2::*;
45pub use gtfs::*;
46pub use json::*;
47pub use las::*;
48pub use nadgrid::*;
49pub use netcdf::*;
50pub use osm::*;
51pub use pmtiles::*;
52use s2json::{MValue, Properties, VectorFeature};
53pub use s2tiles::*;
54use serde::{Deserialize, Serialize};
55pub use shapefile::*;
56#[cfg(feature = "std")]
57use std::path::Path;
58#[cfg(feature = "std")]
59pub use tile::*;
60pub use wkt::*;
61
62#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
64#[serde(rename_all = "lowercase")]
65pub enum ReaderType {
66 CSV,
68 GeoTIFF,
70 GPX,
72 GRIB2,
74 GTFS,
76 JSON,
78 JSONLD,
80 JSONSQ,
82 LAS,
84 LAZ,
86 NADGrid,
88 NetCDF,
90 OSM,
92 Shapefile,
94 Tile,
96 WKT,
98}
99impl From<&str> for ReaderType {
100 fn from(value: &str) -> Self {
101 match value {
102 "csv" => ReaderType::CSV,
103 "geotiff" | "tif" | "tiff" | "geotif" => ReaderType::GeoTIFF,
104 "gpx" => ReaderType::GPX,
105 "grib2" | "grib" => ReaderType::GRIB2,
106 "gtfs" => ReaderType::GTFS,
107 "json" | "geojson" | "s2json" => ReaderType::JSON,
108 "jsonld" | "geojsonld" | "s2jsonld" | "json-ld" | "geojson-ld" | "s2json-ld" => {
109 ReaderType::JSONLD
110 }
111 "jsonsq" | "geojsonseq" | "geojsonsq" | "s2jsonseq" | "s2jsonsq" | "json-seq"
112 | "json-sq" | "geojson-seq" | "geojson-sq" | "s2json-seq" | "s2json-sq" => {
113 ReaderType::JSONSQ
114 }
115 "las" => ReaderType::LAS,
116 "laz" => ReaderType::LAZ,
117 "nadgrid" | "nad" | "gsb" => ReaderType::NADGrid,
118 "netcdf" | "nc4" | "cdf" | "nc" => ReaderType::NetCDF,
119 "osm" | "pbf" => ReaderType::OSM,
120 "shapefile" | "shp" | "zip" => ReaderType::Shapefile,
121 "wkt" => ReaderType::WKT,
122 _ => ReaderType::Tile,
123 }
124 }
125}
126
127#[derive(Debug, Clone)]
193pub enum GISReader<T: Reader + Debug> {
194 CSV(Box<CSVReader<T, Properties>>),
196 GeoTIFF(Box<GeoTIFFReader<T>>),
198 GPX(Box<GPXReader>),
200 GRIB2(Box<GRIB2Reader>),
202 GTFS(Box<GTFSScheduleReader>),
204 JSON(Box<JSONReader<T, (), Properties, MValue>>),
206 JSONLD(Box<NewLineDelimitedJSONReader<T, (), Properties, MValue>>),
208 JSONSQ(Box<SequenceJSONReader<T, (), Properties, MValue>>),
210 LAS(Box<LASReader<T>>),
212 LAZ(Box<LAZReader<T>>),
214 NADGrid(Box<NadGridReader<T>>),
216 NetCDF(Box<NetCDFReader<T>>),
218 OSM(Box<OSMLocalReader<T>>),
220 Shapefile(Box<ShapeFileReader<T, Properties>>),
222 WKT(Box<WKTGeometryReader>),
226}
227impl<T: Reader + Debug> GISReader<T> {
228 pub fn get_type(&self) -> ReaderType {
230 match self {
231 GISReader::CSV(_) => ReaderType::CSV,
232 GISReader::GeoTIFF(_) => ReaderType::GeoTIFF,
233 GISReader::GPX(_) => ReaderType::GPX,
234 GISReader::GRIB2(_) => ReaderType::GRIB2,
235 GISReader::GTFS(_) => ReaderType::GTFS,
236 GISReader::JSON(_) => ReaderType::JSON,
237 GISReader::JSONLD(_) => ReaderType::JSONLD,
238 GISReader::JSONSQ(_) => ReaderType::JSONSQ,
239 GISReader::LAS(_) => ReaderType::LAS,
240 GISReader::LAZ(_) => ReaderType::LAZ,
241 GISReader::NADGrid(_) => ReaderType::NADGrid,
242 GISReader::NetCDF(_) => ReaderType::NetCDF,
243 GISReader::OSM(_) => ReaderType::OSM,
244 GISReader::Shapefile(_) => ReaderType::Shapefile,
245 GISReader::WKT(_) => ReaderType::WKT,
247 }
248 }
249}
250impl GISReader<BufferReader> {
251 pub fn from_buffer(
263 data: Vec<u8>,
264 file_type: ReaderType,
265 epsg_codes: Option<BTreeMap<String, String>>,
266 ) -> GISReader<BufferReader> {
267 let buffer = BufferReader::new(data);
268 let epsg_codes = epsg_codes.unwrap_or_default();
269 match file_type {
270 ReaderType::CSV => GISReader::CSV(CSVReader::new(buffer, None).into()),
271 ReaderType::GeoTIFF => GISReader::GeoTIFF(
272 GeoTIFFReader::new(buffer, Some(GeoTIFFOptions { epsg_codes })).into(),
273 ),
274 ReaderType::GPX => {
275 let input_str = buffer.parse_string(None, None);
276 GISReader::GPX(GPXReader::new(&input_str).into())
277 }
278 ReaderType::GRIB2 => GISReader::GRIB2(GRIB2Reader::new(buffer.into(), vec![]).into()),
279 ReaderType::GTFS => {
280 GISReader::GTFS(GTFSScheduleReader::from_gzip(&buffer.slice(None, None)).into())
281 }
282 ReaderType::JSON => GISReader::JSON(JSONReader::new(buffer).into()),
283 ReaderType::JSONLD => {
284 GISReader::JSONLD(NewLineDelimitedJSONReader::new(buffer, None).into())
285 }
286 ReaderType::JSONSQ => GISReader::JSONSQ(SequenceJSONReader::new(buffer).into()),
287 ReaderType::LAS => GISReader::LAS(
288 LASReader::new(
289 buffer,
290 Some(LASReaderOptions { epsg_codes, dont_transform: false }),
291 )
292 .into(),
293 ),
294 ReaderType::LAZ => GISReader::LAZ(
295 LAZReader::new(
296 buffer,
297 Some(LASReaderOptions { epsg_codes, dont_transform: false }),
298 )
299 .into(),
300 ),
301 ReaderType::NADGrid => {
302 GISReader::NADGrid(NadGridReader::new("default".into(), buffer).into())
303 }
304 ReaderType::NetCDF => GISReader::NetCDF(NetCDFReader::new(buffer, None).into()),
305 ReaderType::OSM => {
306 let mut osm = OSMLocalReader::new(buffer, None);
307 osm.parse_blocks();
308 GISReader::OSM(osm.into())
309 }
310 ReaderType::Shapefile => GISReader::Shapefile(
311 shapefile_from_gzip(&buffer.slice(None, None), epsg_codes).into(),
312 ),
313 ReaderType::WKT => {
314 let input_str = buffer.parse_string(None, None);
315 GISReader::WKT(WKTGeometryReader::new(input_str).into())
316 }
317 _ => panic!("Unsupported file type: {file_type:?}"),
318 }
319 }
320}
321#[cfg(feature = "std")]
322impl GISReader<FileReader> {
323 #[cfg(feature = "std")]
335 pub fn from_path<P: AsRef<Path>>(
336 file: P,
337 file_type: Option<ReaderType>,
338 epsg_codes: Option<BTreeMap<String, String>>,
339 ) -> GISReader<FileReader> {
340 use crate::readers::file::shapefile_from_path;
341 use std::{ffi::OsStr, fs};
342
343 let path = file.as_ref().to_path_buf();
344 let path_ending = path.extension().and_then(OsStr::to_str).unwrap_or("");
345 let file_type: ReaderType = file_type.unwrap_or(path_ending.into());
346 let epsg_codes = epsg_codes.unwrap_or_default();
347 match file_type {
348 ReaderType::CSV => {
349 GISReader::CSV(CSVReader::new(FileReader::new(file).unwrap(), None).into())
350 }
351 ReaderType::GeoTIFF => GISReader::GeoTIFF(
352 GeoTIFFReader::new(
353 FileReader::new(file).unwrap(),
354 Some(GeoTIFFOptions { epsg_codes }),
355 )
356 .into(),
357 ),
358 ReaderType::GPX => {
359 GISReader::GPX(GPXReader::new(&fs::read_to_string(file).unwrap()).into())
360 }
361 ReaderType::GRIB2 => GISReader::GRIB2(
362 GRIB2Reader::new(FileReader::new(file).unwrap().into(), vec![]).into(),
363 ),
364 ReaderType::GTFS => {
365 GISReader::GTFS(GTFSScheduleReader::from_gzip(&fs::read(file).unwrap()).into())
366 }
367 ReaderType::JSON => {
368 GISReader::JSON(JSONReader::new(FileReader::new(file).unwrap()).into())
369 }
370 ReaderType::JSONLD => GISReader::JSONLD(
371 NewLineDelimitedJSONReader::new(FileReader::new(file).unwrap(), None).into(),
372 ),
373 ReaderType::JSONSQ => {
374 GISReader::JSONSQ(SequenceJSONReader::new(FileReader::new(file).unwrap()).into())
375 }
376 ReaderType::LAS => GISReader::LAS(
377 LASReader::new(
378 FileReader::new(file).unwrap(),
379 Some(LASReaderOptions { epsg_codes, dont_transform: false }),
380 )
381 .into(),
382 ),
383 ReaderType::LAZ => GISReader::LAZ(
384 LAZReader::new(
385 FileReader::new(file).unwrap(),
386 Some(LASReaderOptions { epsg_codes, dont_transform: false }),
387 )
388 .into(),
389 ),
390 ReaderType::NADGrid => GISReader::NADGrid(
391 NadGridReader::new("default".into(), FileReader::new(file).unwrap()).into(),
392 ),
393 ReaderType::NetCDF => {
394 GISReader::NetCDF(NetCDFReader::new(FileReader::new(file).unwrap(), None).into())
395 }
396 ReaderType::OSM => {
397 let mut osm = OSMLocalReader::new(FileReader::new(file).unwrap(), None);
398 osm.parse_blocks();
399 GISReader::OSM(osm.into())
400 }
401 ReaderType::Shapefile => {
402 if path_ending == "zip" {
404 unimplemented!("Shapefile from zip not implemented yet")
405 } else {
406 GISReader::Shapefile(shapefile_from_path(file, epsg_codes).into())
407 }
408 }
409 ReaderType::WKT => {
410 let input_str = fs::read_to_string(file).unwrap();
411 GISReader::WKT(WKTGeometryReader::new(input_str).into())
412 }
413 _ => panic!("Unsupported file type: {file_type:?}"),
414 }
415 }
416}
417
418#[derive(Debug)]
420pub enum GISIterator<'a, T: Reader + Debug> {
421 CSV(CSVIterator<'a, T, Properties>),
423 GeoTIFF(GeoTIFFIterator<'a, T>),
425 GPX(GPXIterator<'a>),
427 GRIB2(GRIB2Iterator<'a>),
429 GTFS(GTFSScheduleIterator),
431 JSON(JSONIterator<'a, T, (), Properties, MValue>),
433 JSONLD(NewLineDelimitedJSONIterator<'a, T, (), Properties, MValue>),
435 JSONSQ(SequenceJSONIterator<'a, T, (), Properties, MValue>),
437 LAS(LASIterator<'a, T>),
439 LAZ(LAZIterator<'a, T>),
441 NADGrid(NadGridIterator<'a, T>),
443 NetCDF(CDFIterator<'a, T>),
445 OSM(OSMLocalReaderIter<'a, T>),
447 Shapefile(ShapefileIterator<'a, T, Properties>),
449 WKT(WKTIterator<'a>),
451}
452impl<'a, T: Reader + Debug> Iterator for GISIterator<'a, T> {
453 type Item = VectorFeature<(), Properties, MValue>;
454
455 fn next(&mut self) -> Option<Self::Item> {
456 match self {
457 GISIterator::CSV(iterator) => iterator.next().map(|f| f.to_m_vector_feature(|_| None)),
458 GISIterator::GeoTIFF(iterator) => {
459 iterator.next().map(|f| f.to_m_vector_feature(|_| None))
460 }
461 GISIterator::GPX(iterator) => iterator.next().map(|f| f.to_m_vector_feature(|_| None)),
462 GISIterator::GRIB2(iterator) => {
463 iterator.next().map(|f| f.to_m_vector_feature(|_| None))
464 }
465 GISIterator::GTFS(iterator) => iterator.next(),
466 GISIterator::JSON(iterator) => iterator.next(),
467 GISIterator::JSONLD(iterator) => iterator.next(),
468 GISIterator::JSONSQ(iterator) => iterator.next(),
469 GISIterator::LAS(iterator) => iterator.next().map(|f| f.to_m_vector_feature(|_| None)),
470 GISIterator::LAZ(iterator) => iterator.next().map(|f| f.to_m_vector_feature(|_| None)),
471 GISIterator::NADGrid(iterator) => iterator.next().map(|f| VectorFeature {
472 _type: f._type,
473 id: f.id,
474 face: f.face,
475 properties: f.properties,
476 geometry: f.geometry,
477 metadata: None,
478 }),
479 GISIterator::NetCDF(iterator) => iterator.next(),
480 GISIterator::OSM(iterator) => iterator.next().map(|f| VectorFeature {
481 _type: f._type,
482 id: f.id,
483 face: f.face,
484 properties: f.properties,
485 geometry: f.geometry,
486 metadata: None,
487 }),
488 GISIterator::Shapefile(iterator) => iterator.next(),
489 GISIterator::WKT(iterator) => iterator.next(),
490 }
491 }
492}
493impl<T: Reader + Debug> FeatureReader<(), Properties, MValue> for GISReader<T> {
494 type FeatureIterator<'a>
495 = GISIterator<'a, T>
496 where
497 T: 'a;
498
499 fn iter(&self) -> Self::FeatureIterator<'_> {
500 match self {
501 GISReader::CSV(reader) => GISIterator::CSV(reader.iter()),
502 GISReader::GeoTIFF(reader) => GISIterator::GeoTIFF(reader.iter()),
503 GISReader::GPX(reader) => GISIterator::GPX(reader.iter()),
504 GISReader::GRIB2(reader) => GISIterator::GRIB2(reader.iter()),
505 GISReader::GTFS(reader) => GISIterator::GTFS(reader.iter()),
506 GISReader::JSON(reader) => GISIterator::JSON(reader.iter()),
507 GISReader::JSONLD(reader) => GISIterator::JSONLD(reader.iter()),
508 GISReader::JSONSQ(reader) => GISIterator::JSONSQ(reader.iter()),
509 GISReader::LAS(reader) => GISIterator::LAS(reader.iter()),
510 GISReader::LAZ(reader) => GISIterator::LAZ(reader.iter()),
511 GISReader::NADGrid(reader) => GISIterator::NADGrid(reader.iter()),
512 GISReader::NetCDF(reader) => GISIterator::NetCDF(reader.iter()),
513 GISReader::OSM(reader) => GISIterator::OSM(reader.iter()),
514 GISReader::Shapefile(reader) => GISIterator::Shapefile(reader.iter()),
515 GISReader::WKT(reader) => GISIterator::WKT(reader.iter()),
516 }
517 }
518
519 fn par_iter(&self, pool_size: usize, thread_id: usize) -> Self::FeatureIterator<'_> {
520 match self {
521 GISReader::CSV(reader) => GISIterator::CSV(reader.par_iter(pool_size, thread_id)),
522 GISReader::GeoTIFF(reader) => {
523 GISIterator::GeoTIFF(reader.par_iter(pool_size, thread_id))
524 }
525 GISReader::GPX(reader) => GISIterator::GPX(reader.par_iter(pool_size, thread_id)),
526 GISReader::GRIB2(reader) => GISIterator::GRIB2(reader.par_iter(pool_size, thread_id)),
527 GISReader::GTFS(reader) => GISIterator::GTFS(reader.par_iter(pool_size, thread_id)),
528 GISReader::JSON(reader) => GISIterator::JSON(reader.par_iter(pool_size, thread_id)),
529 GISReader::JSONLD(reader) => GISIterator::JSONLD(reader.par_iter(pool_size, thread_id)),
530 GISReader::JSONSQ(reader) => GISIterator::JSONSQ(reader.par_iter(pool_size, thread_id)),
531 GISReader::LAS(reader) => GISIterator::LAS(reader.par_iter(pool_size, thread_id)),
532 GISReader::LAZ(reader) => GISIterator::LAZ(reader.par_iter(pool_size, thread_id)),
533 GISReader::NADGrid(reader) => {
534 GISIterator::NADGrid(reader.par_iter(pool_size, thread_id))
535 }
536 GISReader::NetCDF(reader) => GISIterator::NetCDF(reader.par_iter(pool_size, thread_id)),
537 GISReader::OSM(reader) => GISIterator::OSM(reader.par_iter(pool_size, thread_id)),
538 GISReader::Shapefile(reader) => {
539 GISIterator::Shapefile(reader.par_iter(pool_size, thread_id))
540 }
541 GISReader::WKT(reader) => GISIterator::WKT(reader.par_iter(pool_size, thread_id)),
542 }
543 }
544}