From 1bf602fd8b33b35320db6282fde034d67b2eb0ce Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Thu, 29 Feb 2024 20:59:41 -0500 Subject: [PATCH] Pass formatter parameters to WKT writer --- geozero/src/wkt/mod.rs | 28 ++++++++++++++++++++-------- geozero/src/wkt/wkt_writer.rs | 15 ++++++++++++--- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/geozero/src/wkt/mod.rs b/geozero/src/wkt/mod.rs index 68cc4050..e48f820a 100644 --- a/geozero/src/wkt/mod.rs +++ b/geozero/src/wkt/mod.rs @@ -26,20 +26,21 @@ pub(crate) mod conversion { dialect: WktDialect, dims: CoordDimensions, srid: Option, + precision: Option, ) -> Result; } impl ToWkt for T { fn to_wkt(&self) -> Result { - self.to_wkt_with_opts(WktDialect::Wkt, CoordDimensions::default(), None) + self.to_wkt_with_opts(WktDialect::Wkt, CoordDimensions::default(), None, None) } fn to_ewkt(&self, srid: Option) -> Result { - self.to_wkt_with_opts(WktDialect::Ewkt, CoordDimensions::xyzm(), srid) + self.to_wkt_with_opts(WktDialect::Ewkt, CoordDimensions::xyzm(), srid, None) } fn to_wkt_ndim(&self, dims: CoordDimensions) -> Result { - self.to_wkt_with_opts(WktDialect::Wkt, dims, None) + self.to_wkt_with_opts(WktDialect::Wkt, dims, None, None) } fn to_wkt_with_opts( @@ -47,9 +48,10 @@ pub(crate) mod conversion { dialect: WktDialect, dims: CoordDimensions, srid: Option, + precision: Option, ) -> Result { let mut out: Vec = Vec::new(); - let mut writer = WktWriter::with_opts(&mut out, dialect, dims, srid); + let mut writer = WktWriter::with_opts(&mut out, dialect, dims, srid, precision); self.process_geom(&mut writer)?; String::from_utf8(out).map_err(|_| { crate::error::GeozeroError::Geometry("Invalid UTF-8 encoding".to_string()) @@ -82,8 +84,13 @@ mod wkb { impl FromWkb for Ewkt { fn from_wkb(rdr: &mut R, dialect: WkbDialect) -> Result { let mut out: Vec = Vec::new(); - let mut writer = - WktWriter::with_opts(&mut out, WktDialect::Ewkt, CoordDimensions::xyzm(), None); + let mut writer = WktWriter::with_opts( + &mut out, + WktDialect::Ewkt, + CoordDimensions::xyzm(), + None, + None, + ); crate::wkb::process_wkb_type_geom(rdr, &mut writer, dialect)?; let wkt = String::from_utf8(out).map_err(|_| { crate::error::GeozeroError::Geometry("Invalid UTF-8 encoding".to_string()) @@ -110,8 +117,13 @@ mod wkb { impl FromWkb for EwktString { fn from_wkb(rdr: &mut R, dialect: WkbDialect) -> Result { let mut out: Vec = Vec::new(); - let mut writer = - WktWriter::with_opts(&mut out, WktDialect::Ewkt, CoordDimensions::xyzm(), None); + let mut writer = WktWriter::with_opts( + &mut out, + WktDialect::Ewkt, + CoordDimensions::xyzm(), + None, + None, + ); crate::wkb::process_wkb_type_geom(rdr, &mut writer, dialect)?; let wkt = String::from_utf8(out).map_err(|_| { crate::error::GeozeroError::Geometry("Invalid UTF-8 encoding".to_string()) diff --git a/geozero/src/wkt/wkt_writer.rs b/geozero/src/wkt/wkt_writer.rs index a9fef61f..67f436d8 100644 --- a/geozero/src/wkt/wkt_writer.rs +++ b/geozero/src/wkt/wkt_writer.rs @@ -13,16 +13,17 @@ pub struct WktWriter { first_header: bool, /// Stack of in-progress geometry sizes geometry_sizes: Vec, + precision: Option, pub(crate) out: W, } impl WktWriter { pub fn new(out: W) -> Self { - Self::with_opts(out, WktDialect::Wkt, CoordDimensions::default(), None) + Self::with_opts(out, WktDialect::Wkt, CoordDimensions::default(), None, None) } pub fn with_dims(out: W, dims: CoordDimensions) -> Self { - Self::with_opts(out, WktDialect::Wkt, dims, None) + Self::with_opts(out, WktDialect::Wkt, dims, None, None) } pub fn with_opts( @@ -30,6 +31,7 @@ impl WktWriter { dialect: WktDialect, dims: CoordDimensions, srid: Option, + precision: Option, ) -> Self { Self { dims, @@ -37,6 +39,7 @@ impl WktWriter { dialect, first_header: true, geometry_sizes: vec![], + precision, out, } } @@ -101,7 +104,13 @@ impl GeomProcessor for WktWriter { if f64::is_nan(x) && f64::is_nan(y) { self.out.write_all(b"EMPTY")?; } else { - self.out.write_all(format!("{x} {y}").as_bytes())?; + let coord_string = if let Some(precision) = self.precision { + format!("{x:.precision$} {y:.precision$}") + } else { + format!("{x} {y}") + }; + + self.out.write_all(coord_string.as_bytes())?; } Ok(()) }