Skip to content

Commit 95a9f0e

Browse files
committed
feat: use FeatureIterator to stream geojson for perf
1 parent 2fce1a9 commit 95a9f0e

File tree

3 files changed

+37
-19
lines changed

3 files changed

+37
-19
lines changed

Cargo.lock

+18-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ exclude = [".github/*", "img/*", "fixtures/*"]
1414
[dependencies]
1515
geo = "0.19"
1616
geo-types = { version = "0.7", features = ["rstar"] }
17-
geojson = { version = "0.22", features = ["geo-types"] }
17+
geojson = { version = "0.22.3", features = ["geo-types"] }
1818
num-traits = "0.2"
1919
rstar = "0.9"
2020
anyhow = "1.0"
@@ -27,7 +27,7 @@ topojson = "0.5"
2727
float-cmp = "0.9"
2828
wkt = "0.10"
2929
polyline = "0.9"
30-
kml = "0.4"
30+
kml = "0.4.2"
3131

3232
[[bin]]
3333
name = "echomap"

src/main.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::convert::{TryFrom, TryInto};
22
use std::fs;
3-
use std::io::{self, Read};
3+
use std::io::{self, BufReader, Read};
44
use std::str::FromStr;
55

66
use anyhow::{self, Context, Result};
77
use clap::{Arg, Command};
88
use console::Term;
99
use geo::{Geometry, Point};
10-
use geojson::{self, GeoJson};
10+
use geojson::{self, FeatureIterator, GeoJson};
1111
use indicatif::ProgressBar;
1212
use kml::{quick_collection, Kml};
1313
use polyline::decode_polyline;
@@ -113,14 +113,20 @@ pub fn process_geojson(gj: GeoJson, simplification: f64, is_area: bool) -> Vec<G
113113
}
114114

115115
fn handle_geojson(
116-
input_str: String,
116+
file_path: &str,
117117
simplification: f64,
118118
is_area: bool,
119119
) -> Result<Vec<GridGeom<f64>>> {
120-
let gj: GeoJson = input_str
121-
.parse::<GeoJson>()
122-
.context("Unable to parse GeoJSON")?;
123-
Ok(process_geojson(gj, simplification, is_area))
120+
Ok(match file_path {
121+
"-" => FeatureIterator::new(BufReader::new(io::stdin()))
122+
.filter_map(|f| f.ok())
123+
.flat_map(|f| process_geojson(GeoJson::Feature(f), simplification, is_area))
124+
.collect(),
125+
_ => FeatureIterator::new(BufReader::new(fs::File::open(file_path)?))
126+
.filter_map(|f| f.ok())
127+
.flat_map(|f| process_geojson(GeoJson::Feature(f), simplification, is_area))
128+
.collect(),
129+
})
124130
}
125131

126132
fn handle_topojson(
@@ -316,7 +322,7 @@ fn main() -> Result<()> {
316322

317323
let geoms: Vec<GridGeom<f64>> = match file_format {
318324
InputFormat::GeoJson => handle_geojson(
319-
read_input_to_string(matches.value_of("INPUT").unwrap())?,
325+
matches.value_of("INPUT").unwrap(),
320326
simplification,
321327
matches.is_present("area"),
322328
),
@@ -379,10 +385,10 @@ mod test {
379385

380386
#[test]
381387
fn test_handle_geojson() {
382-
let input_str = include_str!("../fixtures/input.geojson").to_string();
383-
let outlines = handle_geojson(input_str.clone(), 0., false).unwrap();
388+
let file_path = "../fixtures/input.geojson";
389+
let outlines = handle_geojson(file_path, 0., false).unwrap();
384390
let lines = outlines.iter().filter(|g| matches!(g, GridGeom::Line(_)));
385-
let areas = handle_geojson(input_str, 0., true).unwrap();
391+
let areas = handle_geojson(file_path, 0., true).unwrap();
386392
let poly = areas.iter().filter(|g| matches!(g, GridGeom::Polygon(_)));
387393
assert_eq!(outlines.len(), 14);
388394
assert_eq!(lines.count(), 13);

0 commit comments

Comments
 (0)