aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOskari Timperi <oskari.timperi@iki.fi>2018-12-01 11:48:18 -0800
committerOskari Timperi <oskari.timperi@iki.fi>2018-12-01 11:53:14 -0800
commit2f8429643fd726d761851dd4348e428708ada589 (patch)
treee5e1a3e8cc349a5a5ec43e0b685cc9ed3908f850
parent11602ecb94ebc4928410d25023a92e4d2ad1fef3 (diff)
downloadplag-2f8429643fd726d761851dd4348e428708ada589.tar.gz
plag-2f8429643fd726d761851dd4348e428708ada589.zip
Support properties
-rw-r--r--src/main.rs64
1 files changed, 47 insertions, 17 deletions
diff --git a/src/main.rs b/src/main.rs
index a8eb363..96ad078 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -24,6 +24,7 @@ extern crate clap;
use std::path::Path;
use geojson::{Feature, GeoJson, Geometry, Value, FeatureCollection};
+use serde_json::{Map, to_value};
#[derive(Debug)]
enum Error {
@@ -122,12 +123,34 @@ fn get_longitude(reader: &exif::Reader) -> Result<f64> {
Ok(longitude)
}
-fn get_coordinates<P: AsRef<Path> + ?Sized>(filename: &P) -> Result<geo_types::Point<f64>> {
+enum Property {
+ Filename,
+}
+
+fn get_feature(filename: &Path, properties: &[Property]) -> Result<Feature> {
let file = std::fs::File::open(filename)?;
+
let reader = exif::Reader::new(&mut std::io::BufReader::new(&file))?;
+
let latitude = get_latitude(&reader)?;
let longitude = get_longitude(&reader)?;
- Ok((longitude, latitude).into())
+ let point: geo_types::Point<f64> = (longitude, latitude).into();
+
+ let mut props = Map::new();
+
+ for prop in properties {
+ match prop {
+ Property::Filename => props.insert("filename".to_string(), to_value(filename.file_name().unwrap().to_string_lossy()).unwrap()),
+ };
+ }
+
+ Ok(Feature {
+ bbox: None,
+ geometry: Some(Geometry::new(Value::from(&point))),
+ id: None,
+ properties: Some(props),
+ foreign_members: None,
+ })
}
fn main() {
@@ -138,6 +161,10 @@ fn main() {
.arg(clap::Arg::with_name("pretty")
.long("pretty")
.help("Output human-readable GeoJSON"))
+ .arg(clap::Arg::with_name("properties")
+ .long("properties")
+ .takes_value(true)
+ .use_delimiter(true))
.arg(clap::Arg::with_name("files")
.required(true)
.multiple(true)
@@ -147,26 +174,29 @@ fn main() {
// "files" is a required argument. Should be quite safe to unwrap.
let files = matches.values_of_os("files").unwrap();
+ let mut valid_properties = Vec::new();
+ if let Some(requested_properties) = matches.values_of("properties") {
+ for prop in requested_properties {
+ match prop {
+ "filename" => valid_properties.push(Property::Filename),
+ _ => {
+ eprintln!("unknown property: {}", prop);
+ std::process::exit(1);
+ }
+ }
+ }
+ }
+
let features: Vec<_> = files.into_iter()
- .map(|path| (path, get_coordinates(&path)))
- .filter_map(|x| {
- match x {
- (_, Ok(coord)) => Some(coord),
- (path, Err(err)) => {
- eprintln!("{}: {}", path.to_string_lossy(), err);
+ .filter_map(|path| {
+ match get_feature(Path::new(path), &valid_properties) {
+ Ok(feature) => Some(feature),
+ Err(error) => {
+ eprintln!("{}: {}", path.to_string_lossy(), error);
None
}
}
})
- .map(|point| {
- Feature {
- bbox: None,
- geometry: Some(Geometry::new(Value::from(&point))),
- id: None,
- properties: None,
- foreign_members: None,
- }
- })
.collect();
let collection = FeatureCollection {