mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 00:12:55 +03:00
79 lines
2.6 KiB
Rust
79 lines
2.6 KiB
Rust
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
use geom;
|
|
use map_model;
|
|
use quick_xml::events::Event;
|
|
use quick_xml::reader::Reader;
|
|
use std::fs::File;
|
|
use std::{f64, io};
|
|
|
|
pub fn load(
|
|
path: &String,
|
|
b: &geom::Bounds,
|
|
) -> Result<Vec<map_model::raw_data::Parcel>, io::Error> {
|
|
println!("Opening {}", path);
|
|
let f = File::open(path).unwrap();
|
|
let mut reader = Reader::from_reader(io::BufReader::new(f));
|
|
reader.trim_text(true);
|
|
|
|
let mut parcels = Vec::new();
|
|
let mut buf = Vec::new();
|
|
let mut last_progress_byte = 0;
|
|
loop {
|
|
if reader.buffer_position() - last_progress_byte >= 1024 * 1024 * 10 {
|
|
last_progress_byte = reader.buffer_position();
|
|
println!(
|
|
"Processed {} MB of {}",
|
|
last_progress_byte / (1024 * 1024),
|
|
path
|
|
);
|
|
}
|
|
match reader.read_event(&mut buf) {
|
|
Ok(Event::Text(e)) => {
|
|
let text = e.unescape_and_decode(&reader).unwrap();
|
|
// We can be incredibly lazy here and just interpret all text as coordinates. The
|
|
// other metadata for each placemark doesn't look useful yet. We do have to
|
|
// interpret parsing failures appropriately though...
|
|
if text.contains(" ") {
|
|
let mut ok = true;
|
|
let mut parcel = map_model::raw_data::Parcel { points: Vec::new() };
|
|
for pt in text.split(" ") {
|
|
if let Some((lon, lat)) = parse_pt(pt) {
|
|
if b.contains(lon, lat) {
|
|
parcel.points.push(geom::LonLat::new(lon, lat));
|
|
} else {
|
|
ok = false;
|
|
}
|
|
} else {
|
|
ok = false;
|
|
}
|
|
}
|
|
if ok {
|
|
parcels.push(parcel);
|
|
}
|
|
}
|
|
}
|
|
Ok(Event::Eof) => break,
|
|
Err(e) => panic!(
|
|
"XML error at position {}: {:?}",
|
|
reader.buffer_position(),
|
|
e
|
|
),
|
|
_ => (),
|
|
}
|
|
buf.clear();
|
|
}
|
|
return Ok(parcels);
|
|
}
|
|
|
|
fn parse_pt(input: &str) -> Option<(f64, f64)> {
|
|
let coords: Vec<&str> = input.split(",").collect();
|
|
if coords.len() != 2 {
|
|
return None;
|
|
}
|
|
return match (coords[0].parse::<f64>(), coords[1].parse::<f64>()) {
|
|
(Ok(lon), Ok(lat)) => Some((lon, lat)),
|
|
_ => None,
|
|
};
|
|
}
|