use crate::util::fs::{fs_utils, read_utils};
use geo::{LineString, Point};
use kdam::{Bar, BarExt};
use std::path::Path;
use wkt::TryFromWkt;
pub fn read_linestring_text_file(file: &Path) -> Result<Box<[LineString<f32>]>, std::io::Error> {
let is_gzip = fs_utils::is_gzip(file);
let count = fs_utils::line_count(file, is_gzip)?;
let mut pb = Bar::builder()
.total(count)
.animation("fillup")
.desc("geometry file")
.build()
.map_err(|s| std::io::Error::new(std::io::ErrorKind::Interrupted, s.as_str()))?;
let cb = Box::new(|| {
let _ = pb.update(1);
});
let geoms: Box<[LineString<f32>]> =
read_utils::read_raw_file(file, parse_linestring, Some(cb))?;
Ok(geoms)
}
pub fn concat_linestrings(linestrings: Vec<&LineString<f32>>) -> LineString<f32> {
let all_points = linestrings
.iter()
.flat_map(|ls| ls.points())
.collect::<Vec<Point<f32>>>();
LineString::from_iter(all_points)
}
pub fn parse_linestring(_idx: usize, row: String) -> Result<LineString<f32>, std::io::Error> {
let geom: LineString<f32> = LineString::try_from_wkt_str(row.as_str()).map_err(|e| {
let msg = format!(
"failure decoding LineString from lookup table. source: {}; error: {}",
row, e
);
std::io::Error::new(std::io::ErrorKind::InvalidData, msg)
})?;
Ok(geom)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_concat_linstrings() {
let line1 = LineString::from(vec![
Point::from((0.0, 0.0)),
Point::from((1.0, 1.0)),
Point::from((2.0, 2.0)),
]);
let line2 = LineString::from(vec![
Point::from((3.0, 3.0)),
Point::from((4.0, 4.0)),
Point::from((5.0, 5.0)),
]);
let line3 = LineString::from(vec![
Point::from((6.0, 6.0)),
Point::from((7.0, 7.0)),
Point::from((8.0, 8.0)),
]);
let result = concat_linestrings(vec![&line1, &line2, &line3]);
assert_eq!(result.points().len(), 9);
let points = result.into_points();
assert_eq!(points[0], Point::from((0.0, 0.0)));
assert_eq!(points[8], Point::from((8.0, 8.0)));
}
}