gistools/readers/shapefile/
file.rs1use super::{
2 DataBaseFile, Definition, ShapeFileReader, shapefile_from_gzip as shapefile_from_gzip_local,
3};
4use crate::{
5 parsers::{BufferReader, FileReader},
6 proj::Transformer,
7};
8use s2json::MValueCompatible;
9use std::{
10 collections::BTreeMap,
11 fs::{File, exists},
12 io::Read,
13 path::Path,
14 string::String,
15};
16
17pub fn shapefile_from_path<I: AsRef<Path>, P: MValueCompatible>(
44 input: I,
45 epsg_codes: BTreeMap<String, String>,
46) -> ShapeFileReader<FileReader, P> {
47 let path = input.as_ref().to_path_buf();
48 let stem = path.with_extension(""); let path_str: String = stem.to_string_lossy().into();
50 let shp = path_str.clone() + ".shp";
51 let dbf_str = path_str.clone() + ".dbf";
52 let prj_str = path_str.clone() + ".prj";
53 let cpg_str = path_str.clone() + ".cpg";
54
55 if exists(&shp).is_err() {
56 panic!("Shapefile does not exist");
57 }
58 let dbf: Option<String> = if exists(&dbf_str).is_ok() { Some(dbf_str) } else { None };
59 let prj: Option<String> = if exists(&prj_str).is_ok() { Some(prj_str) } else { None };
60 let cpg: Option<String> = if exists(&cpg_str).is_ok() { Some(cpg_str) } else { None };
61 let definition = Definition { shp, dbf, prj, cpg };
62
63 shapefile_from_definition(definition, epsg_codes)
64}
65
66pub fn shapefile_from_definition<P: MValueCompatible>(
71 def: Definition,
72 epsg_codes: BTreeMap<String, String>,
73) -> ShapeFileReader<FileReader, P> {
74 let Definition { shp, dbf, cpg, prj } = def;
75 let mut database_file = None;
76 let mut encoding = None;
77 let mut transform = None;
78 if let Some(cpg) = cpg {
79 let mut file = File::open(cpg).unwrap();
81 let mut input_str: String = String::new();
82 let _ = file.read_to_string(&mut input_str);
83 if !input_str.is_empty() {
84 encoding = Some(input_str);
85 }
86 }
87 if let Some(prj) = prj {
89 let mut transformer = Transformer::new();
90 for (code, value) in epsg_codes.iter() {
91 transformer.insert_epsg_code(code.clone(), value.clone());
92 }
93 let pr_str = std::fs::read_to_string(prj).unwrap();
94 transformer.set_source(pr_str);
95 transform = Some(transformer);
96 }
97 if let Some(dbf) = dbf {
99 database_file = Some(DataBaseFile::new(FileReader::from(dbf), encoding));
100 }
101
102 ShapeFileReader::new(FileReader::from(shp), database_file, transform)
103}
104
105pub fn shapefile_from_gzip<P: MValueCompatible>(
110 input: &str,
111 epsg_codes: BTreeMap<String, String>,
112) -> ShapeFileReader<BufferReader, P> {
113 let data = std::fs::read(input).unwrap();
114
115 shapefile_from_gzip_local(&data, epsg_codes)
116}