1use std::{fs::File, path::PathBuf, str::FromStr};
18
19use geo_types::{LineString, MultiPolygon, Point, Polygon};
20use wkt::{TryFromWkt, WktFloat};
21
22pub const MULTIPOINT_WITH_EMPTY_CHILD_WKB: [u8; 30] = [
27 0x01, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f,
29];
30
31pub const MULTIPOINT_WITH_INFERRED_Z_DIMENSION_WKB: [u8; 38] = [
34 0x01, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xe9, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, ];
44
45pub const POINT_WITH_SRID_4326_EWKB: [u8; 25] = [
48 0x01, 0x01, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, ];
54
55pub const POINT_Z_WITH_SRID_3857_EWKB: [u8; 33] = [
58 0x01, 0x01, 0x00, 0x00, 0xa0, 0x11, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, ];
66
67pub const POINT_M_WITH_SRID_4326_EWKB: [u8; 33] = [
68 0x01, 0x01, 0x00, 0x00, 0x60, 0xe6, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, ];
75
76pub const POINT_ZM_WITH_SRID_4326_EWKB: [u8; 41] = [
78 0x01, 0x01, 0x00, 0x00, 0xe0, 0xe6, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, ];
87
88pub const LINESTRING_WITH_SRID_4326_EWKB: [u8; 45] = [
91 0x01, 0x02, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, ];
100
101pub const POLYGON_WITH_SRID_4326_EWKB: [u8; 81] = [
104 0x01, 0x03, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
118
119pub const MULTIPOINT_WITH_SRID_4326_EWKB: [u8; 55] = [
122 0x01, 0x04, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, ];
137
138pub const GEOMETRYCOLLECTION_POINT_WITH_SRID_4326_EWKB: [u8; 34] = [
141 0x01, 0x07, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, ];
151
152pub const GEOMETRYCOLLECTION_POINT_Z_WITH_SRID_4326_EWKB: [u8; 42] = [
155 0x01, 0x07, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, ];
166
167pub const GEOMETRYCOLLECTION_POINT_M_WITH_SRID_4326_EWKB: [u8; 42] = [
170 0x01, 0x07, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, ];
181
182pub const GEOMETRYCOLLECTION_POINT_ZM_WITH_SRID_4326_EWKB: [u8; 50] = [
185 0x01, 0x07, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, ];
197
198pub const POINT_EMPTY_WITH_SRID_4326_EWKB: [u8; 25] = [
201 0x01, 0x01, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, ];
207
208pub const GEOMETRYCOLLECTION_EMPTY_WITH_SRID_4326_EWKB: [u8; 13] = [
211 0x01, 0x07, 0x00, 0x00, 0x20, 0xe6, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
216
217pub fn louisiana<T>() -> LineString<T>
218where
219 T: WktFloat + Default + FromStr,
220{
221 line_string("louisiana.wkt")
222}
223
224pub fn baton_rouge<T>() -> Point<T>
225where
226 T: WktFloat + Default + FromStr,
227{
228 let x = T::from(-91.147385).unwrap();
229 let y = T::from(30.471165).unwrap();
230 Point::new(x, y)
231}
232
233pub fn east_baton_rouge<T>() -> Polygon<T>
234where
235 T: WktFloat + Default + FromStr,
236{
237 polygon("east_baton_rouge.wkt")
238}
239
240pub fn norway_main<T>() -> LineString<T>
241where
242 T: WktFloat + Default + FromStr,
243{
244 line_string("norway_main.wkt")
245}
246
247pub fn norway_concave_hull<T>() -> LineString<T>
248where
249 T: WktFloat + Default + FromStr,
250{
251 line_string("norway_concave_hull.wkt")
252}
253
254pub fn norway_convex_hull<T>() -> LineString<T>
255where
256 T: WktFloat + Default + FromStr,
257{
258 line_string("norway_convex_hull.wkt")
259}
260
261pub fn norway_nonconvex_hull<T>() -> LineString<T>
262where
263 T: WktFloat + Default + FromStr,
264{
265 line_string("norway_nonconvex_hull.wkt")
266}
267
268pub fn vw_orig<T>() -> LineString<T>
269where
270 T: WktFloat + Default + FromStr,
271{
272 line_string("vw_orig.wkt")
273}
274
275pub fn vw_simplified<T>() -> LineString<T>
276where
277 T: WktFloat + Default + FromStr,
278{
279 line_string("vw_simplified.wkt")
280}
281
282pub fn poly1<T>() -> LineString<T>
283where
284 T: WktFloat + Default + FromStr,
285{
286 line_string("poly1.wkt")
287}
288
289pub fn poly1_hull<T>() -> LineString<T>
290where
291 T: WktFloat + Default + FromStr,
292{
293 line_string("poly1_hull.wkt")
294}
295
296pub fn poly2<T>() -> LineString<T>
297where
298 T: WktFloat + Default + FromStr,
299{
300 line_string("poly2.wkt")
301}
302
303pub fn poly2_hull<T>() -> LineString<T>
304where
305 T: WktFloat + Default + FromStr,
306{
307 line_string("poly2_hull.wkt")
308}
309
310pub fn poly_in_ring<T>() -> LineString<T>
311where
312 T: WktFloat + Default + FromStr,
313{
314 line_string("poly_in_ring.wkt")
315}
316
317pub fn ring<T>() -> LineString<T>
318where
319 T: WktFloat + Default + FromStr,
320{
321 line_string("ring.wkt")
322}
323
324pub fn shell<T>() -> LineString<T>
325where
326 T: WktFloat + Default + FromStr,
327{
328 line_string("shell.wkt")
329}
330
331pub fn nl_zones<T>() -> MultiPolygon<T>
333where
334 T: WktFloat + Default + FromStr,
335{
336 multi_polygon("nl_zones.wkt")
337}
338
339pub fn nl_plots_wgs84<T>() -> MultiPolygon<T>
341where
342 T: WktFloat + Default + FromStr,
343{
344 multi_polygon("nl_plots.wkt")
345}
346
347pub fn nl_plots_epsg_28992<T>() -> MultiPolygon<T>
348where
349 T: WktFloat + Default + FromStr,
350{
351 multi_polygon("nl_plots_epsg_28992.wkt")
353}
354
355fn line_string<T>(name: &str) -> LineString<T>
356where
357 T: WktFloat + Default + FromStr,
358{
359 LineString::try_from_wkt_reader(file(name)).unwrap()
360}
361
362pub fn polygon<T>(name: &str) -> Polygon<T>
363where
364 T: WktFloat + Default + FromStr,
365{
366 Polygon::try_from_wkt_reader(file(name)).unwrap()
367}
368
369pub fn multi_polygon<T>(name: &str) -> MultiPolygon<T>
370where
371 T: WktFloat + Default + FromStr,
372{
373 MultiPolygon::try_from_wkt_reader(file(name)).unwrap()
374}
375
376pub fn file(name: &str) -> File {
377 let base = crate::data::sedona_testing_dir()
378 .expect("sedona-testing directory should resolve when accessing fixtures");
379
380 let mut path = PathBuf::from(base);
381 path.push("data");
382 path.push("wkts");
383 path.push("geo-test-fixtures");
384 path.push(name);
385
386 File::open(&path).unwrap_or_else(|_| panic!("Can't open file: {path:?}"))
387}
388
389#[cfg(test)]
390mod tests {
391 use super::*;
392
393 #[test]
394 fn norway_main_linestring_has_vertices() {
395 let ls = norway_main::<f64>();
396 assert!(
397 !ls.0.is_empty(),
398 "LineString loaded from norway_main.wkt should have vertices"
399 );
400
401 let first = ls.0.first().expect("expected at least one coordinate");
402 assert!(first.x.is_finite(), "first coordinate x should be finite");
403 assert!(first.y.is_finite(), "first coordinate y should be finite");
404 }
405
406 #[test]
407 fn nl_zones_multipolygon_not_empty() {
408 let mp = nl_zones::<f64>();
409 assert!(
410 !mp.0.is_empty(),
411 "MultiPolygon from nl_zones.wkt should contain polygons"
412 );
413
414 let polygon = mp.0.first().expect("expected at least one polygon");
415 assert!(
416 !polygon.exterior().0.is_empty(),
417 "polygon exterior ring should contain coordinates"
418 );
419 }
420}