diff --git a/Cargo.toml b/Cargo.toml index 13a2ca6..08543b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,3 @@ [workspace] -members = [ - "lib", - "tests", -] - +resolver = "2" +members = ["lib", "tests"] diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 55bb18a..6db550e 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -2,7 +2,7 @@ name = "geo-booleanop" version = "0.3.2" authors = ["Bodo Junglas "] -edition = "2018" +edition = "2021" license = "MIT" repository = "https://github.com/21re/rust-geo-booleanop" description = "Rust implementation of the Martinez-Rueda Polygon Clipping Algorithm" @@ -12,8 +12,8 @@ keywords = ["gis", "geo", "geography", "geospatial"] [dependencies] geo-types = { version = "0.7", default-features = false } num-traits = "0.2" -robust = "0.2" -float_next_after = "0.1" +robust = "1.1" +float_next_after = "1.0" [dev-dependencies] rand = "0.8" diff --git a/lib/src/boolean/compare_segments.rs b/lib/src/boolean/compare_segments.rs index 6c40ec3..ce594ad 100644 --- a/lib/src/boolean/compare_segments.rs +++ b/lib/src/boolean/compare_segments.rs @@ -28,7 +28,7 @@ where "missing right-event in compare_segments" ); - if Rc::ptr_eq(&se1_l, &se2_l) { + if Rc::ptr_eq(se1_l, se2_l) { return Ordering::Equal; } @@ -36,7 +36,7 @@ where // SweepEvent w.r.t. the segment of the earlier/newer one. The logic is easier to // express by swapping them here according to their temporal order. In case we have // to swap, the result function must be inverted accordingly. - let (se_old_l, se_new_l, less_if) = if se1_l.is_before(&se2_l) { + let (se_old_l, se_new_l, less_if) = if se1_l.is_before(se2_l) { (se1_l, se2_l, helper::less_if as fn(bool) -> Ordering) } else { (se2_l, se1_l, helper::less_if_inversed as fn(bool) -> Ordering) @@ -112,7 +112,7 @@ mod test { use super::super::sweep_event::SweepEvent; use super::compare_segments; use crate::splay::SplaySet; - use geo_types::Coordinate; + use geo_types::Coord; use std::cmp::Ordering; use std::rc::{Rc, Weak}; @@ -148,7 +148,7 @@ mod test { ) -> (Rc>, Rc>) { let other = SweepEvent::new_rc( contour_id, - Coordinate { x: other_x, y: other_y }, + Coord { x: other_x, y: other_y }, false, Weak::new(), is_subject, @@ -156,7 +156,7 @@ mod test { ); let event = SweepEvent::new_rc( contour_id, - Coordinate { x, y }, + Coord { x, y }, true, Rc::downgrade(&other), is_subject, @@ -181,8 +181,8 @@ mod test { let min_other = tree.min().unwrap().get_other_event().unwrap(); let max_other = tree.max().unwrap().get_other_event().unwrap(); - assert_eq!(max_other.point, Coordinate { x: 2.0, y: 3.0 }); - assert_eq!(min_other.point, Coordinate { x: 1.0, y: 1.0 }); + assert_eq!(max_other.point, Coord { x: 2.0, y: 3.0 }); + assert_eq!(min_other.point, Coord { x: 1.0, y: 1.0 }); } #[test] @@ -198,8 +198,8 @@ mod test { let min_other = tree.min().unwrap().get_other_event().unwrap(); let max_other = tree.max().unwrap().get_other_event().unwrap(); - assert_eq!(min_other.point, Coordinate { x: 1.0, y: 1.0 }); - assert_eq!(max_other.point, Coordinate { x: 2.0, y: 3.0 }); + assert_eq!(min_other.point, Coord { x: 1.0, y: 1.0 }); + assert_eq!(max_other.point, Coord { x: 2.0, y: 3.0 }); } #[test] diff --git a/lib/src/boolean/compute_fields.rs b/lib/src/boolean/compute_fields.rs index 17df27b..a26f323 100644 --- a/lib/src/boolean/compute_fields.rs +++ b/lib/src/boolean/compute_fields.rs @@ -41,7 +41,7 @@ where let result_transition = if !in_result { ResultTransition::None } else { - determine_result_transition(&event, operation) + determine_result_transition(event, operation) }; event.set_result_transition(result_transition); diff --git a/lib/src/boolean/connect_edges.rs b/lib/src/boolean/connect_edges.rs index e43b3c3..ade2d02 100644 --- a/lib/src/boolean/connect_edges.rs +++ b/lib/src/boolean/connect_edges.rs @@ -1,6 +1,6 @@ use super::helper::Float; use super::sweep_event::{ResultTransition, SweepEvent}; -use geo_types::Coordinate; +use geo_types::Coord; use std::collections::HashSet; use std::rc::Rc; @@ -137,8 +137,8 @@ pub struct Contour where F: Float, { - /// Raw coordinates of contour - pub points: Vec>, + /// Raw Coords of contour + pub points: Vec>, /// Contour IDs of holes if any. pub hole_ids: Vec, /// Contour ID of parent if this contour is a hole. diff --git a/lib/src/boolean/divide_segment.rs b/lib/src/boolean/divide_segment.rs index aa98e1a..9ec97e2 100644 --- a/lib/src/boolean/divide_segment.rs +++ b/lib/src/boolean/divide_segment.rs @@ -1,13 +1,13 @@ use super::helper::Float; use super::sweep_event::SweepEvent; -use geo_types::Coordinate; +use geo_types::Coord; use std::collections::BinaryHeap; use std::rc::Rc; #[cfg(feature = "debug-booleanop")] use super::sweep_event::JsonDebug; -pub fn divide_segment(se_l: &Rc>, inter: Coordinate, queue: &mut BinaryHeap>>) +pub fn divide_segment(se_l: &Rc>, inter: Coord, queue: &mut BinaryHeap>>) where F: Float, { @@ -53,7 +53,7 @@ where se_l.contour_id, inter, false, - Rc::downgrade(&se_l), + Rc::downgrade(se_l), se_l.is_subject, true, ); @@ -92,7 +92,7 @@ mod test { use super::super::segment_intersection::{intersection, LineIntersection}; use super::super::sweep_event::SweepEvent; use super::*; - use geo_types::Coordinate; + use geo_types::Coord; use std::collections::BinaryHeap; use std::rc::{Rc, Weak}; @@ -105,13 +105,13 @@ mod test { ) -> (Rc>, Rc>) { let other = SweepEvent::new_rc( 0, - Coordinate { x: other_x, y: other_y }, + Coord { x: other_x, y: other_y }, false, Weak::new(), is_subject, true, ); - let event = SweepEvent::new_rc(0, Coordinate { x, y }, true, Rc::downgrade(&other), is_subject, true); + let event = SweepEvent::new_rc(0, Coord { x, y }, true, Rc::downgrade(&other), is_subject, true); (event, other) } diff --git a/lib/src/boolean/fill_queue.rs b/lib/src/boolean/fill_queue.rs index 9a715d6..e83444c 100644 --- a/lib/src/boolean/fill_queue.rs +++ b/lib/src/boolean/fill_queue.rs @@ -3,9 +3,9 @@ use geo_types::{LineString, Polygon}; use std::collections::BinaryHeap; use std::rc::{Rc, Weak}; +use super::helper::BoundingBox; use super::sweep_event::SweepEvent; use super::Operation; -use super::helper::BoundingBox; pub fn fill_queue( subject: &[Polygon], @@ -22,7 +22,7 @@ where for polygon in subject { contour_id += 1; - process_polygon(&polygon.exterior(), true, contour_id, &mut event_queue, sbbox, true); + process_polygon(polygon.exterior(), true, contour_id, &mut event_queue, sbbox, true); for interior in polygon.interiors() { process_polygon(interior, true, contour_id, &mut event_queue, sbbox, false); } @@ -33,14 +33,7 @@ where if exterior { contour_id += 1; } - process_polygon( - &polygon.exterior(), - false, - contour_id, - &mut event_queue, - cbbox, - exterior, - ); + process_polygon(polygon.exterior(), false, contour_id, &mut event_queue, cbbox, exterior); for interior in polygon.interiors() { process_polygon(interior, false, contour_id, &mut event_queue, cbbox, false); } @@ -94,13 +87,13 @@ fn process_polygon( #[cfg(test)] mod test { use super::*; - use geo_types::Coordinate; + use geo_types::Coord; use std::cmp::Ordering; use std::collections::BinaryHeap; use std::rc::{Rc, Weak}; fn make_simple(x: f64, y: f64, is_subject: bool) -> Rc> { - SweepEvent::new_rc(0, Coordinate { x, y }, false, Weak::new(), is_subject, true) + SweepEvent::new_rc(0, Coord { x, y }, false, Weak::new(), is_subject, true) } fn check_order_in_queue(first: Rc>, second: Rc>) { diff --git a/lib/src/boolean/helper.rs b/lib/src/boolean/helper.rs index 06681f3..23fdc72 100644 --- a/lib/src/boolean/helper.rs +++ b/lib/src/boolean/helper.rs @@ -1,5 +1,5 @@ use float_next_after::NextAfter as NextAfterFloat; -use geo_types::{Coordinate, CoordNum}; +use geo_types::{Coord, CoordNum}; use num_traits::Float as NumTraitsFloat; use std::cmp::Ordering; use std::fmt::{Debug, Display}; @@ -51,17 +51,17 @@ pub fn less_if_inversed(condition: bool) -> Ordering { } } -/// A bounded 2D quadrilateral whose area is defined by minimum and maximum `Coordinates`. +/// A bounded 2D quadrilateral whose area is defined by minimum and maximum `Coords`. /// /// A simple implementation copied from geo_types 0.4.0, because this version is a better /// fit for the needs of this crate than the newer ones. #[derive(PartialEq, Clone, Copy, Debug)] pub struct BoundingBox - where - T: CoordNum, +where + T: CoordNum, { - pub min: Coordinate, - pub max: Coordinate, + pub min: Coord, + pub max: Coord, } impl BoundingBox { @@ -78,10 +78,10 @@ impl BoundingBox { pub mod test { use super::Float; use float_next_after::NextAfter as NextAfterFloat; - use geo_types::Coordinate; + use geo_types::Coord; - pub fn xy, Y: Into>(x: X, y: Y) -> Coordinate { - Coordinate { + pub fn xy, Y: Into>(x: X, y: Y) -> Coord { + Coord { x: x.into(), y: y.into(), } diff --git a/lib/src/boolean/mod.rs b/lib/src/boolean/mod.rs index c8c25c8..04a9a0b 100644 --- a/lib/src/boolean/mod.rs +++ b/lib/src/boolean/mod.rs @@ -1,4 +1,4 @@ -use geo_types::{Coordinate, LineString, MultiPolygon, Polygon}; +use geo_types::{Coord, LineString, MultiPolygon, Polygon}; pub mod compare_segments; pub mod compute_fields; @@ -90,11 +90,11 @@ where F: Float, { let mut sbbox = BoundingBox { - min: Coordinate { + min: Coord { x: F::infinity(), y: F::infinity(), }, - max: Coordinate { + max: Coord { x: F::neg_infinity(), y: F::neg_infinity(), }, diff --git a/lib/src/boolean/possible_intersection.rs b/lib/src/boolean/possible_intersection.rs index f1623ab..b2f0a55 100644 --- a/lib/src/boolean/possible_intersection.rs +++ b/lib/src/boolean/possible_intersection.rs @@ -47,10 +47,10 @@ where } LineIntersection::Point(inter) => { if se1.point != inter && other1.point != inter { - divide_segment(&se1, inter, queue); + divide_segment(se1, inter, queue); } if se2.point != inter && other2.point != inter { - divide_segment(&se2, inter, queue); + divide_segment(se2, inter, queue); } 1 } diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index dabf0af..acb9d53 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -1,6 +1,6 @@ -use super::helper::Float; use super::helper::BoundingBox; -use geo_types::{Coordinate}; +use super::helper::Float; +use geo_types::Coord; #[derive(Debug, Clone, Copy, PartialEq)] pub enum LineIntersection @@ -8,17 +8,12 @@ where F: Float, { None, - Point(Coordinate), - Overlap(Coordinate, Coordinate), + Point(Coord), + Overlap(Coord, Coord), } #[inline] -fn get_intersection_bounding_box( - a1: Coordinate, - a2: Coordinate, - b1: Coordinate, - b2: Coordinate, -) -> Option> +fn get_intersection_bounding_box(a1: Coord, a2: Coord, b1: Coord, b2: Coord) -> Option> where F: Float, { @@ -32,11 +27,11 @@ where let interval_end_y = a_end_y.min(b_end_y); if interval_start_x <= interval_end_x && interval_start_y <= interval_end_y { Some(BoundingBox { - min: Coordinate { + min: Coord { x: interval_start_x, y: interval_start_y, }, - max: Coordinate { + max: Coord { x: interval_end_x, y: interval_end_y, }, @@ -47,11 +42,11 @@ where } #[inline] -fn constrain_to_bounding_box(p: Coordinate, bb: BoundingBox) -> Coordinate +fn constrain_to_bounding_box(p: Coord, bb: BoundingBox) -> Coord where F: Float, { - Coordinate { + Coord { x: if p.x < bb.min.x { bb.min.x } else if p.x > bb.max.x { @@ -69,12 +64,7 @@ where } } -pub fn intersection( - a1: Coordinate, - a2: Coordinate, - b1: Coordinate, - b2: Coordinate, -) -> LineIntersection +pub fn intersection(a1: Coord, a2: Coord, b1: Coord, b2: Coord) -> LineIntersection where F: Float, { @@ -93,25 +83,20 @@ where } } -fn intersection_impl( - a1: Coordinate, - a2: Coordinate, - b1: Coordinate, - b2: Coordinate, -) -> LineIntersection +fn intersection_impl(a1: Coord, a2: Coord, b1: Coord, b2: Coord) -> LineIntersection where F: Float, { // println!("{:?} {:?} {:?} {:?}", a1, a2, b1, b2); - let va = Coordinate { + let va = Coord { x: a2.x - a1.x, y: a2.y - a1.y, }; - let vb = Coordinate { + let vb = Coord { x: b2.x - b1.x, y: b2.y - b1.y, }; - let e = Coordinate { + let e = Coord { x: b1.x - a1.x, y: b1.y - a1.y, }; @@ -168,18 +153,18 @@ where LineIntersection::None } -fn mid_point(p: Coordinate, s: F, d: Coordinate) -> Coordinate +fn mid_point(p: Coord, s: F, d: Coord) -> Coord where F: Float, { - Coordinate { + Coord { x: p.x + s * d.x, y: p.y + s * d.y, } } #[inline] -fn cross_product(a: Coordinate, b: Coordinate) -> F +fn cross_product(a: Coord, b: Coord) -> F where F: Float, { @@ -187,7 +172,7 @@ where } #[inline] -fn dot_product(a: Coordinate, b: Coordinate) -> F +fn dot_product(a: Coord, b: Coord) -> F where F: Float, { @@ -199,7 +184,7 @@ mod test { use super::super::helper::test::xy; use super::*; - fn rect(min: Coordinate, max: Coordinate) -> BoundingBox { + fn rect(min: Coord, max: Coord) -> BoundingBox { BoundingBox { min, max } } diff --git a/lib/src/boolean/signed_area.rs b/lib/src/boolean/signed_area.rs index 75e7159..c862f78 100644 --- a/lib/src/boolean/signed_area.rs +++ b/lib/src/boolean/signed_area.rs @@ -1,28 +1,21 @@ use super::helper::Float; -use geo_types::Coordinate; -use robust::{orient2d, Coord}; +use geo_types::Coord; +use robust::{orient2d, Coord as RobustCoord}; #[inline] -pub fn coordinate_to_robust(p: Coordinate) -> Coord +pub fn coord_to_robust(p: Coord) -> RobustCoord where F: Float, { - Coord { - x: p.x, - y: p.y, - } + RobustCoord { x: p.x, y: p.y } } #[inline] -pub fn signed_area(p0: Coordinate, p1: Coordinate, p2: Coordinate) -> f64 +pub fn signed_area(p0: Coord, p1: Coord, p2: Coord) -> f64 where F: Float, { - orient2d( - coordinate_to_robust(p0), - coordinate_to_robust(p1), - coordinate_to_robust(p2), - ) + orient2d(coord_to_robust(p0), coord_to_robust(p1), coord_to_robust(p2)) } #[cfg(test)] diff --git a/lib/src/boolean/subdivide_segments.rs b/lib/src/boolean/subdivide_segments.rs index 28f392f..19530df 100644 --- a/lib/src/boolean/subdivide_segments.rs +++ b/lib/src/boolean/subdivide_segments.rs @@ -50,10 +50,10 @@ where { println!("{{\"seNextEvent\": {}}}", next.to_json_debug()); } - if possible_intersection(&event, &next, event_queue) == 2 { + if possible_intersection(&event, next, event_queue) == 2 { // Recompute fields for current segment and the one above (in bottom to top order) compute_fields(&event, maybe_prev, operation); - compute_fields(&next, Some(&event), operation); + compute_fields(next, Some(&event), operation); } } @@ -62,10 +62,10 @@ where { println!("{{\"sePrevEvent\": {}}}", prev.to_json_debug()); } - if possible_intersection(&prev, &event, event_queue) == 2 { - let maybe_prev_prev = sweep_line.prev(&prev); + if possible_intersection(prev, &event, event_queue) == 2 { + let maybe_prev_prev = sweep_line.prev(prev); // Recompute fields for current segment and the one below (in bottom to top order) - compute_fields(&prev, maybe_prev_prev, operation); + compute_fields(prev, maybe_prev_prev, operation); compute_fields(&event, Some(prev), operation); } } diff --git a/lib/src/boolean/sweep_event.rs b/lib/src/boolean/sweep_event.rs index 0e7c818..34fb544 100644 --- a/lib/src/boolean/sweep_event.rs +++ b/lib/src/boolean/sweep_event.rs @@ -1,5 +1,5 @@ use super::helper::Float; -use geo_types::Coordinate; +use geo_types::Coord; use std::cell::RefCell; use std::cmp::Ordering; use std::rc::{Rc, Weak}; @@ -45,7 +45,7 @@ where { mutable: RefCell>, pub contour_id: u32, - pub point: Coordinate, + pub point: Coord, pub is_subject: bool, pub is_exterior_ring: bool, } @@ -56,7 +56,7 @@ where { pub fn new_rc( contour_id: u32, - point: Coordinate, + point: Coord, left: bool, other_event: Weak>, is_subject: bool, @@ -160,7 +160,7 @@ where self.mutable.borrow_mut().output_contour_id = output_contour_id } - pub fn is_below(&self, p: Coordinate) -> bool { + pub fn is_below(&self, p: Coord) -> bool { if let Some(ref other_event) = self.get_other_event() { if self.is_left() { signed_area(self.point, other_event.point, p) > 0. @@ -172,7 +172,7 @@ where } } - pub fn is_above(&self, p: Coordinate) -> bool { + pub fn is_above(&self, p: Coord) -> bool { !self.is_below(p) } @@ -300,7 +300,7 @@ mod test { ) -> (Rc>, Rc>) { let other = SweepEvent::new_rc( contour_id, - Coordinate { x: other_x, y: other_y }, + Coord { x: other_x, y: other_y }, false, Weak::new(), is_subject, @@ -308,7 +308,7 @@ mod test { ); let event = SweepEvent::new_rc( contour_id, - Coordinate { x, y }, + Coord { x, y }, true, Rc::downgrade(&other), is_subject, diff --git a/lib/src/splay/mod.rs b/lib/src/splay/mod.rs index 39e63ba..c61e97d 100644 --- a/lib/src/splay/mod.rs +++ b/lib/src/splay/mod.rs @@ -197,14 +197,14 @@ mod test { match m.next(i) { Some((next, _)) => { assert!(*next > *i); - assert_eq!(m.prev(&next), Some((i, i))); + assert_eq!(m.prev(next), Some((i, i))); } None => assert_eq!(*i, max), } match m.prev(i) { Some((prev, _)) => { assert!(*prev < *i); - assert_eq!(m.next(&prev), Some((i, i))); + assert_eq!(m.next(prev), Some((i, i))); } None => assert_eq!(*i, min), } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 2355e1f..2ecad15 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -5,22 +5,24 @@ authors = ["Bodo Junglas "] edition = "2018" [dependencies] -geo-booleanop = { path = "../lib", features = [] } # add "debug-booleanop" for debugging -geo = "0.20" +geo-booleanop = { path = "../lib", features = [ + # add "debug-booleanop" for debugging +] } +geo = "0.26" # Note: It is crucial to enable arbitrary_precision on serde_json, otherwise # JSON parsing isn't exact. -geojson = { version = "0.22", features = ["geo-types"] } +geojson = { version = "0.24", features = ["geo-types"] } serde_json = { version = "1.0.44", features = ["arbitrary_precision"] } -clap = "2.3.3" +clap = "4.4" num-traits = "0.2" glob = "0.3" pretty_assertions = "1.2" rand = "0.8" [dev-dependencies] -criterion = "0.3" +criterion = "0.5" [[bench]] name = "benchmark" diff --git a/tests/benches/benchmark.rs b/tests/benches/benchmark.rs index 785353f..ded497d 100644 --- a/tests/benches/benchmark.rs +++ b/tests/benches/benchmark.rs @@ -53,13 +53,13 @@ fn benchmarks(c: &mut Criterion) { )); g.bench_function("random_triangles/xor", |b| b.iter_batched( - || generate_random_triangles_polygons(), + generate_random_triangles_polygons, |(p1, p2)| p1.xor(&p2), BatchSize::LargeInput, )); g.bench_function("grid/xor", |b| b.iter_batched( - || generate_grid_polygons(), + generate_grid_polygons, |(p1, p2)| p1.xor(&p2), BatchSize::LargeInput, )); @@ -74,7 +74,7 @@ fn benchmarks(c: &mut Criterion) { )); g.bench_function("circles_vs_rects/xor", |b| b.iter_batched( - || generate_circles_vs_rects(), + generate_circles_vs_rects, |(p1, p2)| p1.xor(&p2), BatchSize::LargeInput, )); diff --git a/tests/src/bin/run_generated_dataset.rs b/tests/src/bin/run_generated_dataset.rs index dbac7e5..7d1713d 100644 --- a/tests/src/bin/run_generated_dataset.rs +++ b/tests/src/bin/run_generated_dataset.rs @@ -3,8 +3,7 @@ //! provided by the data generators. //! -use clap::{App, AppSettings, Arg}; - +use clap::{Arg, Command}; use geo_booleanop_tests::compact_geojson::write_compact_geojson; use geo_booleanop_tests::data_generators::{ generate_circles_vs_rects, generate_grid_polygons, generate_random_triangles_polygons, @@ -13,15 +12,14 @@ use geo_booleanop_tests::helper::{apply_operation, convert_to_feature, plot_gene fn main() { #[rustfmt::skip] - let matches = App::new("Test case runner") - .setting(AppSettings::ArgRequiredElseHelp) - .arg(Arg::with_name("case") + let matches = Command::new("Test case runner") + .arg(Arg::new("case") .required(true) - .possible_values(&["grid", "circles_vs_rects", "random_triangles"]) + .value_parser(["grid", "circles_vs_rects", "random_triangles"]) .help("Input file")) .get_matches(); - let case = matches.value_of("case").unwrap().to_string(); + let case = matches.get_one::("case").unwrap(); let (a, b) = match case.as_ref() { "grid" => generate_grid_polygons(), "circles_vs_rects" => generate_circles_vs_rects(), diff --git a/tests/src/bin/run_single_test.rs b/tests/src/bin/run_single_test.rs index cca4c6d..bf9dcd2 100644 --- a/tests/src/bin/run_single_test.rs +++ b/tests/src/bin/run_single_test.rs @@ -2,7 +2,7 @@ //! This binary allows running a test case directly by specifying its path //! as argument. //! -use clap::{App, AppSettings, Arg}; +use clap::{Arg, Command}; use geojson::Feature; use geo_booleanop_tests::compact_geojson::write_compact_geojson; @@ -26,7 +26,7 @@ pub fn run_generic_test_case_with_extra_options(filename: &str, swap_ab: bool) { }; for feature in features.iter().skip(2) { - let op = extract_expected_result(&feature).op; + let op = extract_expected_result(feature).op; println!("Testing operation: {:?}", op); let result = apply_operation(&p1, &p2, op); @@ -39,19 +39,18 @@ pub fn run_generic_test_case_with_extra_options(filename: &str, swap_ab: bool) { fn main() { #[rustfmt::skip] - let matches = App::new("Test case runner") - .setting(AppSettings::ArgRequiredElseHelp) - .arg(Arg::with_name("file") + let matches = Command::new("Test case runner") + .arg(Arg::new("file") .required(true) .help("Input file")) - .arg(Arg::with_name("swap-ab") + .arg(Arg::new("swap-ab") .long("swap-ab") .help("Swap A/B input polygons")) .get_matches(); - let swap_ab = matches.is_present("swap-ab"); + let swap_ab = matches.get_flag("swap-ab"); - let filename_in = matches.value_of("file").unwrap().to_string(); + let filename_in = matches.get_one::("file").unwrap(); let filename_out = filename_in.clone() + ".generated"; fs::copy(&filename_in, &filename_out).expect("Failed to copy file."); diff --git a/tests/src/compact_geojson.rs b/tests/src/compact_geojson.rs index 3c0f9dd..8878fea 100644 --- a/tests/src/compact_geojson.rs +++ b/tests/src/compact_geojson.rs @@ -131,7 +131,7 @@ pub fn write_compact_geojson(features: &[Feature], filename: &str) { f.write_indented(0, "{\n"); f.write_indented(0, " \"features\": [\n"); for (i, feature) in features.iter().enumerate() { - write_feature(&feature, &mut f, i == features.len() - 1); + write_feature(feature, &mut f, i == features.len() - 1); } f.write_indented(0, " ],\n"); f.write_indented(0, " \"type\": \"FeatureCollection\"\n"); diff --git a/tests/src/data_generators.rs b/tests/src/data_generators.rs index a00efd4..287c53a 100644 --- a/tests/src/data_generators.rs +++ b/tests/src/data_generators.rs @@ -1,11 +1,11 @@ -use geo::{Coordinate, LineString, MultiPolygon, Polygon}; +use geo::{Coord, LineString, MultiPolygon, Polygon}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use super::helper::xy; -fn generate_rect_centered(center: Coordinate, w: f64, h: f64) -> Polygon { +fn generate_rect_centered(center: Coord, w: f64, h: f64) -> Polygon { let w_half = w / 2.0; let h_half = h / 2.0; Polygon::new( @@ -20,7 +20,7 @@ fn generate_rect_centered(center: Coordinate, w: f64, h: f64) -> Polygon, num_points: usize, r: f64) -> LineString { +fn generate_circle_ring(center: Coord, num_points: usize, r: f64) -> LineString { let mut coords = Vec::with_capacity(num_points); for i in 0..num_points { @@ -41,11 +41,7 @@ pub fn generate_grid(min: f64, max: f64, rect_size: f64, num_rects: i32) -> Mult let mut polygons = Vec::with_capacity((num_rects * num_rects) as usize); for x in &positions { for y in &positions { - polygons.push(generate_rect_centered( - Coordinate { x: *x, y: *y }, - rect_size, - rect_size, - )); + polygons.push(generate_rect_centered(Coord { x: *x, y: *y }, rect_size, rect_size)); } } @@ -53,7 +49,7 @@ pub fn generate_grid(min: f64, max: f64, rect_size: f64, num_rects: i32) -> Mult } pub fn generate_nested_circles( - center: Coordinate, + center: Coord, r_min: f64, r_max: f64, num_polys: usize, @@ -80,7 +76,7 @@ pub fn generate_nested_circles( } pub fn generate_nested_rects( - center: Coordinate, + center: Coord, width_min: f64, width_max: f64, num_polys: usize, @@ -109,7 +105,7 @@ pub fn generate_nested_rects( pub fn generate_random_triangles(num_polys: usize, seed: u64) -> MultiPolygon { let mut rng: StdRng = SeedableRng::seed_from_u64(seed); - let mut rand_coord = || Coordinate { + let mut rand_coord = || Coord { x: rng.gen_range(-1.0f64..1.0f64), y: rng.gen_range(-1.0f64..1.0f64), }; diff --git a/tests/src/fill_queue_test.rs b/tests/src/fill_queue_test.rs index 2d28b7c..db61799 100644 --- a/tests/src/fill_queue_test.rs +++ b/tests/src/fill_queue_test.rs @@ -1,8 +1,8 @@ use super::helper::fixture_shapes; -use geo::Coordinate; +use geo::Coord; use geo_booleanop::boolean::fill_queue::fill_queue; -use geo_booleanop::boolean::Operation; use geo_booleanop::boolean::BoundingBox; +use geo_booleanop::boolean::Operation; use num_traits::Float; use super::helper::xy; @@ -11,11 +11,11 @@ use super::helper::xy; fn test_two_polygons() { let (s, c) = fixture_shapes("two_shapes.geojson"); let mut sbbox = BoundingBox { - min: Coordinate { + min: Coord { x: f64::infinity(), y: f64::infinity(), }, - max: Coordinate { + max: Coord { x: f64::neg_infinity(), y: f64::neg_infinity(), }, diff --git a/tests/src/generic_test_cases.rs b/tests/src/generic_test_cases.rs index d1a3237..04b0ff4 100644 --- a/tests/src/generic_test_cases.rs +++ b/tests/src/generic_test_cases.rs @@ -51,7 +51,7 @@ fn run_generic_test_case(filename: &str, regenerate: bool) -> Vec { let mut failures = Vec::new(); for feature in features.iter().skip(2) { - let expected_result = extract_expected_result(&feature); + let expected_result = extract_expected_result(feature); let op = expected_result.op; let all_results = compute_all_results(&p1, &p2, op, expected_result.swap_ab_is_broken); @@ -79,7 +79,7 @@ fn run_generic_test_case(filename: &str, regenerate: bool) -> Vec { if regenerate { if let Result::Ok(result) = &all_results.first().expect("Need at least one result").1 { - let mut new_feature = convert_to_feature(&result, Some(op)); + let mut new_feature = convert_to_feature(result, Some(op)); new_feature.properties = feature.properties.clone(); // Copy existing properties to keep comments etc. output_features.push(new_feature); } @@ -99,7 +99,7 @@ fn test_generic_test_cases() { let test_cases: Vec<_> = glob("./fixtures/generic_test_cases/*.geojson") .expect("Failed to read glob pattern") .collect(); - assert!(test_cases.len() > 0, "Expected to find any test cases"); + assert!(!test_cases.is_empty(), "Expected to find any test cases"); let mut failures = Vec::new(); for entry in &test_cases { @@ -108,7 +108,7 @@ fn test_generic_test_cases() { } println!("\nFinished running {} test cases", test_cases.len()); - if failures.len() > 0 { + if !failures.is_empty() { println!("\nGeneric test case failures (see error details above):"); for failure in &failures { println!(" - {}", failure); diff --git a/tests/src/helper.rs b/tests/src/helper.rs index 023640d..5e78eda 100644 --- a/tests/src/helper.rs +++ b/tests/src/helper.rs @@ -1,6 +1,6 @@ use geo_booleanop::boolean::BooleanOp; -use geo::{Coordinate, MultiPolygon, Polygon}; +use geo::{Coord, MultiPolygon, Polygon}; use geojson::{Feature, GeoJson, Geometry, Value}; use serde_json::{json, Map}; @@ -16,8 +16,8 @@ use std::process::Command; // General geo / booleanop helpers // ---------------------------------------------------------------------------- -pub fn xy, Y: Into>(x: X, y: Y) -> Coordinate { - Coordinate { +pub fn xy, Y: Into>(x: X, y: Y) -> Coord { + Coord { x: x.into(), y: y.into(), } diff --git a/tests/src/possible_intersection_test.rs b/tests/src/possible_intersection_test.rs index 18e71f9..46fd1ac 100644 --- a/tests/src/possible_intersection_test.rs +++ b/tests/src/possible_intersection_test.rs @@ -1,19 +1,19 @@ use super::helper::fixture_shapes; -use geo::Coordinate; +use geo::Coord; use geo_booleanop::boolean::compare_segments::compare_segments; use geo_booleanop::boolean::fill_queue::fill_queue; use geo_booleanop::boolean::possible_intersection::possible_intersection; use geo_booleanop::boolean::subdivide_segments::subdivide; use geo_booleanop::boolean::sweep_event::SweepEvent; -use geo_booleanop::boolean::Operation; use geo_booleanop::boolean::BoundingBox; +use geo_booleanop::boolean::Operation; use geo_booleanop::splay::SplaySet; use num_traits::Float; use std::cmp::Ordering; use std::collections::BinaryHeap; use std::rc::{Rc, Weak}; -fn make_simple(a: Coordinate, b: Coordinate, is_subject: bool) -> (Rc>, Rc>) { +fn make_simple(a: Coord, b: Coord, is_subject: bool) -> (Rc>, Rc>) { let other = SweepEvent::new_rc(0, b, false, Weak::new(), is_subject, true); let event = SweepEvent::new_rc(0, a, true, Rc::downgrade(&other), is_subject, true); @@ -34,53 +34,53 @@ fn test_possible_intersection() { let mut e = q.pop().unwrap(); assert_eq!( e.point, - Coordinate { + Coord { x: 100.79403384562251, y: 233.41363754101192 } ); - assert_eq!(e.get_other_event().unwrap().point, Coordinate { x: 56.0, y: 181.0 }); + assert_eq!(e.get_other_event().unwrap().point, Coord { x: 56.0, y: 181.0 }); e = q.pop().unwrap(); assert_eq!( e.point, - Coordinate { + Coord { x: 100.79403384562251, y: 233.41363754101192 } ); - assert_eq!(e.get_other_event().unwrap().point, Coordinate { x: 16.0, y: 282.0 }); + assert_eq!(e.get_other_event().unwrap().point, Coord { x: 16.0, y: 282.0 }); e = q.pop().unwrap(); assert_eq!( e.point, - Coordinate { + Coord { x: 100.79403384562251, y: 233.41363754101192 } ); - assert_eq!(e.get_other_event().unwrap().point, Coordinate { x: 153.0, y: 203.5 }); + assert_eq!(e.get_other_event().unwrap().point, Coord { x: 153.0, y: 203.5 }); e = q.pop().unwrap(); assert_eq!( e.point, - Coordinate { + Coord { x: 100.79403384562251, y: 233.41363754101192 } ); - assert_eq!(e.get_other_event().unwrap().point, Coordinate { x: 153.0, y: 294.5 }); + assert_eq!(e.get_other_event().unwrap().point, Coord { x: 153.0, y: 294.5 }); } #[test] fn test_on_two_polygons() { let (s, c) = fixture_shapes("two_shapes.geojson"); let mut sbbox = BoundingBox { - min: Coordinate { + min: Coord { x: f64::infinity(), y: f64::infinity(), }, - max: Coordinate { + max: Coord { x: f64::neg_infinity(), y: f64::neg_infinity(), }, @@ -88,9 +88,9 @@ fn test_on_two_polygons() { let mut cbbox = sbbox; let mut q = fill_queue(&[s], &[c], &mut sbbox, &mut cbbox, Operation::Intersection); - let p0 = Coordinate { x: 16.0, y: 282.0 }; - let p1 = Coordinate { x: 298.0, y: 359.0 }; - let p2 = Coordinate { x: 156.0, y: 203.5 }; + let p0 = Coord { x: 16.0, y: 282.0 }; + let p1 = Coord { x: 298.0, y: 359.0 }; + let p2 = Coord { x: 156.0, y: 203.5 }; let te = SweepEvent::new_rc(0, p0, true, Weak::new(), true, true); let te2 = SweepEvent::new_rc(0, p1, false, Rc::downgrade(&te), false, true); @@ -117,21 +117,21 @@ fn test_on_two_polygons() { assert_eq!(left_segments.len(), 11); - let e = Coordinate:: { x: 16.0, y: 282.0 }; - let i = Coordinate:: { + let e = Coord:: { x: 16.0, y: 282.0 }; + let i = Coord:: { x: 100.79403384562252, y: 233.41363754101192, }; - let g = Coordinate:: { x: 298.0, y: 359.0 }; - let c = Coordinate:: { x: 153.0, y: 294.5 }; - let j = Coordinate:: { + let g = Coord:: { x: 298.0, y: 359.0 }; + let c = Coord:: { x: 153.0, y: 294.5 }; + let j = Coord:: { x: 203.36313843035356, y: 257.5101243166895, }; - let f = Coordinate:: { x: 153.0, y: 203.5 }; - let d = Coordinate:: { x: 56.0, y: 181.0 }; - let a = Coordinate:: { x: 108.5, y: 120.0 }; - let b = Coordinate:: { x: 241.5, y: 229.5 }; + let f = Coord:: { x: 153.0, y: 203.5 }; + let d = Coord:: { x: 56.0, y: 181.0 }; + let a = Coord:: { x: 108.5, y: 120.0 }; + let b = Coord:: { x: 241.5, y: 229.5 }; let intervals = &[ ("EI", e, i, false, true, false),