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