From 4a4d79a6f29a59dbaa506154421f3cc98e665f26 Mon Sep 17 00:00:00 2001 From: Kristin Cowalcijk Date: Wed, 8 Oct 2025 12:43:22 +0800 Subject: [PATCH 1/2] Update sedona-testing submodule to latest main --- submodules/sedona-testing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/sedona-testing b/submodules/sedona-testing index 5073f740..c7bc17d7 160000 --- a/submodules/sedona-testing +++ b/submodules/sedona-testing @@ -1 +1 @@ -Subproject commit 5073f7405a6aa2b8eb326da94356802dca956a6a +Subproject commit c7bc17d7109fc628959eb2850d4cfce3d483b1ee From 46b85ad224a186cc36a35479d8e9f232b466c273 Mon Sep 17 00:00:00 2001 From: Kristin Cowalcijk Date: Wed, 8 Oct 2025 15:02:27 +0800 Subject: [PATCH 2/2] Add more geometry fixtures for testing sedona-geo-generic-alg (will be added later) --- rust/sedona-testing/src/fixtures.rs | 210 ++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) diff --git a/rust/sedona-testing/src/fixtures.rs b/rust/sedona-testing/src/fixtures.rs index 502bfaec..13011bf8 100644 --- a/rust/sedona-testing/src/fixtures.rs +++ b/rust/sedona-testing/src/fixtures.rs @@ -14,6 +14,11 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +use std::{fs::File, path::PathBuf, str::FromStr}; + +use geo_types::{LineString, MultiPolygon, Point, Polygon}; +use wkt::{TryFromWkt, WktFloat}; + /// A well-known binary blob of MULTIPOINT (EMPTY) /// /// The wkt crate's parser rejects this; however, it's a corner case that may show @@ -22,3 +27,208 @@ pub const MULTIPOINT_WITH_EMPTY_CHILD_WKB: [u8; 30] = [ 0x01, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, ]; + +pub fn louisiana() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("louisiana.wkt") +} + +pub fn baton_rouge() -> Point +where + T: WktFloat + Default + FromStr, +{ + let x = T::from(-91.147385).unwrap(); + let y = T::from(30.471165).unwrap(); + Point::new(x, y) +} + +pub fn east_baton_rouge() -> Polygon +where + T: WktFloat + Default + FromStr, +{ + polygon("east_baton_rouge.wkt") +} + +pub fn norway_main() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("norway_main.wkt") +} + +pub fn norway_concave_hull() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("norway_concave_hull.wkt") +} + +pub fn norway_convex_hull() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("norway_convex_hull.wkt") +} + +pub fn norway_nonconvex_hull() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("norway_nonconvex_hull.wkt") +} + +pub fn vw_orig() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("vw_orig.wkt") +} + +pub fn vw_simplified() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("vw_simplified.wkt") +} + +pub fn poly1() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("poly1.wkt") +} + +pub fn poly1_hull() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("poly1_hull.wkt") +} + +pub fn poly2() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("poly2.wkt") +} + +pub fn poly2_hull() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("poly2_hull.wkt") +} + +pub fn poly_in_ring() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("poly_in_ring.wkt") +} + +pub fn ring() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("ring.wkt") +} + +pub fn shell() -> LineString +where + T: WktFloat + Default + FromStr, +{ + line_string("shell.wkt") +} + +// From https://geodata.nationaalgeoregister.nl/kadastralekaart/wfs/v4_0?request=GetFeature&service=WFS&srsName=EPSG:4326&typeName=kadastralekaartv4:perceel&version=2.0.0&outputFormat=json&bbox=165593,480993,166125,481552 +pub fn nl_zones() -> MultiPolygon +where + T: WktFloat + Default + FromStr, +{ + multi_polygon("nl_zones.wkt") +} + +// From https://afnemers.ruimtelijkeplannen.nl/afnemers/services?request=GetFeature&service=WFS&srsName=EPSG:4326&typeName=Enkelbestemming&version=2.0.0&bbox=165618,480983,166149,481542"; +pub fn nl_plots_wgs84() -> MultiPolygon +where + T: WktFloat + Default + FromStr, +{ + multi_polygon("nl_plots.wkt") +} + +pub fn nl_plots_epsg_28992() -> MultiPolygon +where + T: WktFloat + Default + FromStr, +{ + // https://epsg.io/28992 + multi_polygon("nl_plots_epsg_28992.wkt") +} + +fn line_string(name: &str) -> LineString +where + T: WktFloat + Default + FromStr, +{ + LineString::try_from_wkt_reader(file(name)).unwrap() +} + +pub fn polygon(name: &str) -> Polygon +where + T: WktFloat + Default + FromStr, +{ + Polygon::try_from_wkt_reader(file(name)).unwrap() +} + +pub fn multi_polygon(name: &str) -> MultiPolygon +where + T: WktFloat + Default + FromStr, +{ + MultiPolygon::try_from_wkt_reader(file(name)).unwrap() +} + +pub fn file(name: &str) -> File { + let base = crate::data::sedona_testing_dir() + .expect("sedona-testing directory should resolve when accessing fixtures"); + + let mut path = PathBuf::from(base); + path.push("data"); + path.push("wkts"); + path.push("geo-test-fixtures"); + path.push(name); + + File::open(&path).unwrap_or_else(|_| panic!("Can't open file: {path:?}")) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn norway_main_linestring_has_vertices() { + let ls = norway_main::(); + assert!( + !ls.0.is_empty(), + "LineString loaded from norway_main.wkt should have vertices" + ); + + let first = ls.0.first().expect("expected at least one coordinate"); + assert!(first.x.is_finite(), "first coordinate x should be finite"); + assert!(first.y.is_finite(), "first coordinate y should be finite"); + } + + #[test] + fn nl_zones_multipolygon_not_empty() { + let mp = nl_zones::(); + assert!( + !mp.0.is_empty(), + "MultiPolygon from nl_zones.wkt should contain polygons" + ); + + let polygon = mp.0.first().expect("expected at least one polygon"); + assert!( + !polygon.exterior().0.is_empty(), + "polygon exterior ring should contain coordinates" + ); + } +}