From a1596bbf6527ba67882a7166394dd6489e2ebf40 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 3 Sep 2024 13:16:46 -0400 Subject: [PATCH 1/6] Fix writing WKT with z/m dimensions --- geozero/src/wkt/wkt_writer.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/geozero/src/wkt/wkt_writer.rs b/geozero/src/wkt/wkt_writer.rs index a9fef61f..1b075970 100644 --- a/geozero/src/wkt/wkt_writer.rs +++ b/geozero/src/wkt/wkt_writer.rs @@ -63,6 +63,13 @@ impl WktWriter { if tagged { self.out.write_all(tag)?; } + if is_z(self.dims) { + self.out.write_all(b" Z")?; + } else if is_m(self.dims) { + self.out.write_all(b" M")?; + } else if is_zm(self.dims) { + self.out.write_all(b" ZM")?; + } self.geometry_sizes.push(size); if size == 0 { if tagged { @@ -235,13 +242,26 @@ impl PropertyProcessor for WktWriter {} impl FeatureProcessor for WktWriter {} +fn is_z(dims: CoordDimensions) -> bool { + dims.z && !dims.m +} + +fn is_m(dims: CoordDimensions) -> bool { + dims.m && !dims.z +} + +fn is_zm(dims: CoordDimensions) -> bool { + dims.z && dims.m +} + #[cfg(test)] mod test { #[cfg(feature = "with-wkb")] use crate::wkb::{FromWkb, WkbDialect}; #[cfg(feature = "with-wkb")] use crate::wkt::Ewkt; - use crate::ToWkt; + use crate::wkt::{Wkt, WktWriter}; + use crate::{CoordDimensions, GeozeroGeometry, ToWkt}; #[test] #[cfg(feature = "with-geo")] @@ -259,4 +279,17 @@ mod test { let ewkt = Ewkt::from_wkb(&mut cursor, WkbDialect::Ewkb).unwrap(); assert_eq!(ewkt.0, "SRID=4326;MULTIPOINT(10 -20 100,0 -0.5 101)") } + + #[test] + fn read_write_wkt_point_z() { + let s = "POINT Z(40 10 50)"; + let wkt = Wkt(s); + + let out = vec![]; + let mut writer = WktWriter::with_dims(out, CoordDimensions::xyz()); + wkt.process_geom(&mut writer).unwrap(); + + let out = String::from_utf8(writer.out).unwrap(); + assert_eq!(s, out.as_str()); + } } From 77901b766559e60ab4d4d27e7a701a201771362e Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 3 Sep 2024 13:28:29 -0400 Subject: [PATCH 2/6] fix tests --- geozero/src/geojson/geojson_reader.rs | 2 +- geozero/src/wkt/mod.rs | 2 +- geozero/src/wkt/wkt_writer.rs | 12 +++++------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/geozero/src/geojson/geojson_reader.rs b/geozero/src/geojson/geojson_reader.rs index 5e6d1c3e..59c68435 100644 --- a/geozero/src/geojson/geojson_reader.rs +++ b/geozero/src/geojson/geojson_reader.rs @@ -321,7 +321,7 @@ mod test { let mut out = WktWriter::with_dims(&mut wkt_data, CoordDimensions::xyz()); assert!(read_geojson_geom(&mut geojson.as_bytes(), &mut out).is_ok()); let wkt = std::str::from_utf8(&wkt_data).unwrap(); - assert_eq!(wkt, "LINESTRING(1 1 10,2 2 20)"); + assert_eq!(wkt, "LINESTRING Z(1 1 10,2 2 20)"); let geojson = r#"{"type": "LineString", "coordinates": [[1,1],[2,2]]}"#; let mut wkt_data: Vec = Vec::new(); diff --git a/geozero/src/wkt/mod.rs b/geozero/src/wkt/mod.rs index 68cc4050..cd44f6db 100644 --- a/geozero/src/wkt/mod.rs +++ b/geozero/src/wkt/mod.rs @@ -35,7 +35,7 @@ pub(crate) mod conversion { } 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::xy(), srid) } fn to_wkt_ndim(&self, dims: CoordDimensions) -> Result { diff --git a/geozero/src/wkt/wkt_writer.rs b/geozero/src/wkt/wkt_writer.rs index 1b075970..5e8fd411 100644 --- a/geozero/src/wkt/wkt_writer.rs +++ b/geozero/src/wkt/wkt_writer.rs @@ -260,8 +260,8 @@ mod test { use crate::wkb::{FromWkb, WkbDialect}; #[cfg(feature = "with-wkb")] use crate::wkt::Ewkt; - use crate::wkt::{Wkt, WktWriter}; - use crate::{CoordDimensions, GeozeroGeometry, ToWkt}; + use crate::wkt::{Wkt, WktDialect}; + use crate::{CoordDimensions, ToWkt}; #[test] #[cfg(feature = "with-geo")] @@ -285,11 +285,9 @@ mod test { let s = "POINT Z(40 10 50)"; let wkt = Wkt(s); - let out = vec![]; - let mut writer = WktWriter::with_dims(out, CoordDimensions::xyz()); - wkt.process_geom(&mut writer).unwrap(); - - let out = String::from_utf8(writer.out).unwrap(); + let out = wkt + .to_wkt_with_opts(WktDialect::Wkt, CoordDimensions::xyz(), None) + .unwrap(); assert_eq!(s, out.as_str()); } } From 7d1867f44e6e6d548cdb203ab0389fe910dc20a1 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 3 Sep 2024 13:32:27 -0400 Subject: [PATCH 3/6] fix test --- geozero/src/geojson/geojson_reader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geozero/src/geojson/geojson_reader.rs b/geozero/src/geojson/geojson_reader.rs index 59c68435..81f322c5 100644 --- a/geozero/src/geojson/geojson_reader.rs +++ b/geozero/src/geojson/geojson_reader.rs @@ -328,7 +328,7 @@ mod test { let mut out = WktWriter::with_dims(&mut wkt_data, CoordDimensions::xyz()); assert!(read_geojson_geom(&mut geojson.as_bytes(), &mut out).is_ok()); let wkt = std::str::from_utf8(&wkt_data).unwrap(); - assert_eq!(wkt, "LINESTRING(1 1,2 2)"); + assert_eq!(wkt, "LINESTRING Z(1 1,2 2)"); Ok(()) } From ef9a3f2e1e89305510578a2ea062bb8db2363fa2 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 3 Sep 2024 13:33:27 -0400 Subject: [PATCH 4/6] fix test? --- geozero/src/geojson/geojson_reader.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geozero/src/geojson/geojson_reader.rs b/geozero/src/geojson/geojson_reader.rs index 81f322c5..469b19f9 100644 --- a/geozero/src/geojson/geojson_reader.rs +++ b/geozero/src/geojson/geojson_reader.rs @@ -325,10 +325,10 @@ mod test { let geojson = r#"{"type": "LineString", "coordinates": [[1,1],[2,2]]}"#; let mut wkt_data: Vec = Vec::new(); - let mut out = WktWriter::with_dims(&mut wkt_data, CoordDimensions::xyz()); + let mut out = WktWriter::with_dims(&mut wkt_data, CoordDimensions::xy()); assert!(read_geojson_geom(&mut geojson.as_bytes(), &mut out).is_ok()); let wkt = std::str::from_utf8(&wkt_data).unwrap(); - assert_eq!(wkt, "LINESTRING Z(1 1,2 2)"); + assert_eq!(wkt, "LINESTRING(1 1,2 2)"); Ok(()) } From d0d7c8a910818f9486f592fbd6fb5354c5067528 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 3 Sep 2024 13:43:05 -0400 Subject: [PATCH 5/6] fix test --- geozero/src/wkt/wkt_writer.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/geozero/src/wkt/wkt_writer.rs b/geozero/src/wkt/wkt_writer.rs index 5e8fd411..f78a4c80 100644 --- a/geozero/src/wkt/wkt_writer.rs +++ b/geozero/src/wkt/wkt_writer.rs @@ -257,9 +257,7 @@ fn is_zm(dims: CoordDimensions) -> bool { #[cfg(test)] mod test { #[cfg(feature = "with-wkb")] - use crate::wkb::{FromWkb, WkbDialect}; - #[cfg(feature = "with-wkb")] - use crate::wkt::Ewkt; + use crate::wkb::Ewkb; use crate::wkt::{Wkt, WktDialect}; use crate::{CoordDimensions, ToWkt}; @@ -275,9 +273,10 @@ mod test { #[cfg(feature = "with-wkb")] fn from_wkb() { let blob = hex::decode("01040000A0E6100000020000000101000080000000000000244000000000000034C0000000000000594001010000800000000000000000000000000000E0BF0000000000405940").unwrap(); - let mut cursor = std::io::Cursor::new(blob); - let ewkt = Ewkt::from_wkb(&mut cursor, WkbDialect::Ewkb).unwrap(); - assert_eq!(ewkt.0, "SRID=4326;MULTIPOINT(10 -20 100,0 -0.5 101)") + let ewkt = Ewkb(blob) + .to_wkt_with_opts(WktDialect::Ewkt, CoordDimensions::xyz(), Some(4326)) + .unwrap(); + assert_eq!(ewkt, "SRID=4326;MULTIPOINT Z(10 -20 100,0 -0.5 101)") } #[test] @@ -285,9 +284,7 @@ mod test { let s = "POINT Z(40 10 50)"; let wkt = Wkt(s); - let out = wkt - .to_wkt_with_opts(WktDialect::Wkt, CoordDimensions::xyz(), None) - .unwrap(); + let out = wkt.to_wkt_ndim(CoordDimensions::xyz()).unwrap(); assert_eq!(s, out.as_str()); } } From fd258edd87cbdf0998144e39066a7932fc239786 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 3 Sep 2024 13:51:46 -0400 Subject: [PATCH 6/6] fix more tests --- geozero/src/gdal/gdal_reader.rs | 2 +- geozero/src/geos/geos_reader.rs | 2 +- geozero/src/wkb/wkb_reader.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/geozero/src/gdal/gdal_reader.rs b/geozero/src/gdal/gdal_reader.rs index d1e705e7..8c2fb5f2 100644 --- a/geozero/src/gdal/gdal_reader.rs +++ b/geozero/src/gdal/gdal_reader.rs @@ -288,7 +288,7 @@ mod test { #[test] fn line_3d() { - let wkt = "LINESTRING(1 1 10,2 2 20)"; + let wkt = "LINESTRING Z(1 1 10,2 2 20)"; let geo = Geometry::from_wkt(wkt).unwrap(); assert_eq!( geo.to_wkt_ndim(CoordDimensions { diff --git a/geozero/src/geos/geos_reader.rs b/geozero/src/geos/geos_reader.rs index f5befc34..43c9b7e7 100644 --- a/geozero/src/geos/geos_reader.rs +++ b/geozero/src/geos/geos_reader.rs @@ -216,7 +216,7 @@ mod test { #[test] fn line_geom_3d() { - let wkt = "LINESTRING(1 1 10,2 2 20)"; + let wkt = "LINESTRING Z(1 1 10,2 2 20)"; let ggeom = GGeometry::new_from_wkt(wkt).unwrap(); let mut wkt_data: Vec = Vec::new(); diff --git a/geozero/src/wkb/wkb_reader.rs b/geozero/src/wkb/wkb_reader.rs index 2bcce744..ccc5a9d0 100644 --- a/geozero/src/wkb/wkb_reader.rs +++ b/geozero/src/wkb/wkb_reader.rs @@ -650,7 +650,7 @@ mod test { assert!(process_ewkb_geom(&mut ewkb.as_slice(), &mut writer).is_ok()); assert_eq!( std::str::from_utf8(&wkt_data).unwrap(), - "POINT(10 -20 100 1)" + "POINT ZM(10 -20 100 1)" ); // SELECT 'SRID=4326;MULTIPOINT ((10 -20 100), (0 -0.5 101))'::geometry @@ -697,7 +697,7 @@ mod test { // SELECT 'SRID=4326;MULTIPOINT (10 -20 100, 0 -0.5 101)'::geometry assert_eq!( &ewkb_to_wkt("01040000A0E6100000020000000101000080000000000000244000000000000034C0000000000000594001010000800000000000000000000000000000E0BF0000000000405940", true), - "MULTIPOINT(10 -20 100,0 -0.5 101)" + "MULTIPOINT Z(10 -20 100,0 -0.5 101)" //OGR: MULTIPOINT ((10 -20 100),(0 -0.5 101)) ); @@ -776,7 +776,7 @@ mod test { // SELECT 'POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)))'::geometry assert_eq!( &ewkb_to_wkt("010F000080060000000103000080010000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000010300008001000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000000001030000800100000005000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000001030000800100000005000000000000000000F03F000000000000F03F0000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F0000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F03F0000000000000000010300008001000000050000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F00000000000000000000000000000000000000000000F03F00000000000000000103000080010000000500000000000000000000000000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F0000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000000000000000F03F", true), - "POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)))" + "POLYHEDRALSURFACE Z(((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)))" ); // SELECT 'TIN(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 1 0,0 0 0)))'::geometry assert_eq!( @@ -832,7 +832,7 @@ mod test { assert!(process_spatialite_geom(&mut ewkb.as_slice(), &mut writer).is_ok()); assert_eq!( std::str::from_utf8(&wkt_data).unwrap(), - "POINT(10 -20 100 1)" + "POINT ZM(10 -20 100 1)" ); // SELECT HEX(TinyPointEncode(ST_GeomFromText('POINTZM(10 -20 100 1)', 4326)));