Skip to content

Commit abcd140

Browse files
authored
chore: Add test geometry fixtures ported from the geo-test-fixtures crate in georust/geo (#193)
This is part of the forked dependency elimination plan: #165. We'll maintain our generic geo algorithms refactored from georust/geo, the test fixtures for checking the correctness of our refactored implementation is also needed. Unfortunately, geo-test-fixtures is not published to crates.io, so we have to copy it to our own projects to use them. The WKT files were already committed to the apache/sedona-testing repository (see apache/sedona-testing#9), which is a submodule of sedona-db. We add fixtures for loading the WKT files in the submodule to sedona-testing. These newly added fixtures will be used by future PRs.
1 parent 11fefbd commit abcd140

File tree

2 files changed

+211
-1
lines changed

2 files changed

+211
-1
lines changed

rust/sedona-testing/src/fixtures.rs

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
// KIND, either express or implied. See the License for the
1515
// specific language governing permissions and limitations
1616
// under the License.
17+
use std::{fs::File, path::PathBuf, str::FromStr};
18+
19+
use geo_types::{LineString, MultiPolygon, Point, Polygon};
20+
use wkt::{TryFromWkt, WktFloat};
21+
1722
/// A well-known binary blob of MULTIPOINT (EMPTY)
1823
///
1924
/// 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] = [
2227
0x01, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
2328
0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f,
2429
];
30+
31+
pub fn louisiana<T>() -> LineString<T>
32+
where
33+
T: WktFloat + Default + FromStr,
34+
{
35+
line_string("louisiana.wkt")
36+
}
37+
38+
pub fn baton_rouge<T>() -> Point<T>
39+
where
40+
T: WktFloat + Default + FromStr,
41+
{
42+
let x = T::from(-91.147385).unwrap();
43+
let y = T::from(30.471165).unwrap();
44+
Point::new(x, y)
45+
}
46+
47+
pub fn east_baton_rouge<T>() -> Polygon<T>
48+
where
49+
T: WktFloat + Default + FromStr,
50+
{
51+
polygon("east_baton_rouge.wkt")
52+
}
53+
54+
pub fn norway_main<T>() -> LineString<T>
55+
where
56+
T: WktFloat + Default + FromStr,
57+
{
58+
line_string("norway_main.wkt")
59+
}
60+
61+
pub fn norway_concave_hull<T>() -> LineString<T>
62+
where
63+
T: WktFloat + Default + FromStr,
64+
{
65+
line_string("norway_concave_hull.wkt")
66+
}
67+
68+
pub fn norway_convex_hull<T>() -> LineString<T>
69+
where
70+
T: WktFloat + Default + FromStr,
71+
{
72+
line_string("norway_convex_hull.wkt")
73+
}
74+
75+
pub fn norway_nonconvex_hull<T>() -> LineString<T>
76+
where
77+
T: WktFloat + Default + FromStr,
78+
{
79+
line_string("norway_nonconvex_hull.wkt")
80+
}
81+
82+
pub fn vw_orig<T>() -> LineString<T>
83+
where
84+
T: WktFloat + Default + FromStr,
85+
{
86+
line_string("vw_orig.wkt")
87+
}
88+
89+
pub fn vw_simplified<T>() -> LineString<T>
90+
where
91+
T: WktFloat + Default + FromStr,
92+
{
93+
line_string("vw_simplified.wkt")
94+
}
95+
96+
pub fn poly1<T>() -> LineString<T>
97+
where
98+
T: WktFloat + Default + FromStr,
99+
{
100+
line_string("poly1.wkt")
101+
}
102+
103+
pub fn poly1_hull<T>() -> LineString<T>
104+
where
105+
T: WktFloat + Default + FromStr,
106+
{
107+
line_string("poly1_hull.wkt")
108+
}
109+
110+
pub fn poly2<T>() -> LineString<T>
111+
where
112+
T: WktFloat + Default + FromStr,
113+
{
114+
line_string("poly2.wkt")
115+
}
116+
117+
pub fn poly2_hull<T>() -> LineString<T>
118+
where
119+
T: WktFloat + Default + FromStr,
120+
{
121+
line_string("poly2_hull.wkt")
122+
}
123+
124+
pub fn poly_in_ring<T>() -> LineString<T>
125+
where
126+
T: WktFloat + Default + FromStr,
127+
{
128+
line_string("poly_in_ring.wkt")
129+
}
130+
131+
pub fn ring<T>() -> LineString<T>
132+
where
133+
T: WktFloat + Default + FromStr,
134+
{
135+
line_string("ring.wkt")
136+
}
137+
138+
pub fn shell<T>() -> LineString<T>
139+
where
140+
T: WktFloat + Default + FromStr,
141+
{
142+
line_string("shell.wkt")
143+
}
144+
145+
// 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
146+
pub fn nl_zones<T>() -> MultiPolygon<T>
147+
where
148+
T: WktFloat + Default + FromStr,
149+
{
150+
multi_polygon("nl_zones.wkt")
151+
}
152+
153+
// 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";
154+
pub fn nl_plots_wgs84<T>() -> MultiPolygon<T>
155+
where
156+
T: WktFloat + Default + FromStr,
157+
{
158+
multi_polygon("nl_plots.wkt")
159+
}
160+
161+
pub fn nl_plots_epsg_28992<T>() -> MultiPolygon<T>
162+
where
163+
T: WktFloat + Default + FromStr,
164+
{
165+
// https://epsg.io/28992
166+
multi_polygon("nl_plots_epsg_28992.wkt")
167+
}
168+
169+
fn line_string<T>(name: &str) -> LineString<T>
170+
where
171+
T: WktFloat + Default + FromStr,
172+
{
173+
LineString::try_from_wkt_reader(file(name)).unwrap()
174+
}
175+
176+
pub fn polygon<T>(name: &str) -> Polygon<T>
177+
where
178+
T: WktFloat + Default + FromStr,
179+
{
180+
Polygon::try_from_wkt_reader(file(name)).unwrap()
181+
}
182+
183+
pub fn multi_polygon<T>(name: &str) -> MultiPolygon<T>
184+
where
185+
T: WktFloat + Default + FromStr,
186+
{
187+
MultiPolygon::try_from_wkt_reader(file(name)).unwrap()
188+
}
189+
190+
pub fn file(name: &str) -> File {
191+
let base = crate::data::sedona_testing_dir()
192+
.expect("sedona-testing directory should resolve when accessing fixtures");
193+
194+
let mut path = PathBuf::from(base);
195+
path.push("data");
196+
path.push("wkts");
197+
path.push("geo-test-fixtures");
198+
path.push(name);
199+
200+
File::open(&path).unwrap_or_else(|_| panic!("Can't open file: {path:?}"))
201+
}
202+
203+
#[cfg(test)]
204+
mod tests {
205+
use super::*;
206+
207+
#[test]
208+
fn norway_main_linestring_has_vertices() {
209+
let ls = norway_main::<f64>();
210+
assert!(
211+
!ls.0.is_empty(),
212+
"LineString loaded from norway_main.wkt should have vertices"
213+
);
214+
215+
let first = ls.0.first().expect("expected at least one coordinate");
216+
assert!(first.x.is_finite(), "first coordinate x should be finite");
217+
assert!(first.y.is_finite(), "first coordinate y should be finite");
218+
}
219+
220+
#[test]
221+
fn nl_zones_multipolygon_not_empty() {
222+
let mp = nl_zones::<f64>();
223+
assert!(
224+
!mp.0.is_empty(),
225+
"MultiPolygon from nl_zones.wkt should contain polygons"
226+
);
227+
228+
let polygon = mp.0.first().expect("expected at least one polygon");
229+
assert!(
230+
!polygon.exterior().0.is_empty(),
231+
"polygon exterior ring should contain coordinates"
232+
);
233+
}
234+
}

0 commit comments

Comments
 (0)