From 423e97081fe3f8f3e6518778a044a5cbe962840c Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Wed, 19 Feb 2020 22:59:28 +0100 Subject: [PATCH 01/21] added various debug code --- lib/src/boolean/connect_edges.rs | 75 +++++++++++++++++++++++- lib/src/boolean/divide_segment.rs | 6 +- lib/src/boolean/possible_intersection.rs | 18 +++++- lib/src/boolean/segment_intersection.rs | 46 +++++++++++++++ lib/src/boolean/subdivide_segments.rs | 22 ++++++- lib/src/boolean/sweep_event.rs | 29 +++++++++ 6 files changed, 189 insertions(+), 7 deletions(-) diff --git a/lib/src/boolean/connect_edges.rs b/lib/src/boolean/connect_edges.rs index 0c537b7..386b5d2 100644 --- a/lib/src/boolean/connect_edges.rs +++ b/lib/src/boolean/connect_edges.rs @@ -10,6 +10,31 @@ where { let mut result_events: Vec>> = Vec::new(); + for (pos, event) in sorted_events.iter().enumerate() { + event.set_other_pos(pos as i32) + } + for (i, r) in sorted_events.iter().enumerate() { + println!("pos {:3} linked to {:3} {} {:?} => {:?} {:?}", + i, + r.get_other_event().map(|o| o.get_other_pos()).unwrap(), + if r.is_left() { "L" } else { "R" }, + r.point, + r.get_other_event().map(|o| o.point).unwrap(), + r.get_result_transition(), + ); + } + + ///* + for (pos, event) in sorted_events.iter().enumerate() { + event.set_other_pos(-999); + } + for (pos, event) in sorted_events.iter().enumerate() { + if event.is_in_result() { + //assert_eq!(event.get_other_event().unwrap().get_other_pos(), -999); + } + } + //*/ + for event in sorted_events { if (event.is_left() && event.is_in_result()) || (!event.is_left() && event.get_other_event().map(|o| o.is_in_result()).unwrap_or(false)) @@ -34,7 +59,7 @@ where event.set_other_pos(pos as i32) } for event in &result_events { - if event.is_left() { + if !event.is_left() { if let Some(other) = event.get_other_event() { let (a, b) = (event.get_other_pos(), other.get_other_pos()); event.set_other_pos(b); @@ -43,9 +68,53 @@ where } } + for r in &result_events { + println!("{:?}", r); + debug_assert!(r.get_other_event().is_some()); + } + + for (i, r) in result_events.iter().enumerate() { + println!("pos {:3} linked to {:3} {} {:?} => {:?}", + i, + r.get_other_pos(), + if r.is_left() { "L" } else { "R" }, + r.point, + r.get_other_event().map(|o| o.point).unwrap(), + ); + } + result_events } +// csv generator +use std::fs::File; +use std::io::Write; +fn debug_print_results(events: &[Rc>]) +where + F: Float, +{ + let mut writer = File::create("debug.csv").unwrap(); + writeln!(&mut writer, + "index;x;y;other_x;other_y;lr;result_transition;in_out;other_in_out;is_subject;is_exterior_ring;prev_in_result" + ).expect("Failed to write to file"); + for (i, evt) in events.iter().enumerate() { + writeln!(&mut writer, "{i};{x:?};{y:?};{other_x:?};{other_y:?};{lr};{transition:?};{in_out};{other_in_out};{subject};{exterior_ring};{prev_in_result:?}", + i=i, + x=evt.point.x, + y=evt.point.y, + other_x=evt.get_other_event().unwrap().point.x, + other_y=evt.get_other_event().unwrap().point.y, + lr=if evt.is_left() { "L" } else { "R" }, + transition=evt.get_result_transition(), + in_out=evt.is_in_out(), + other_in_out=evt.is_other_in_out(), + subject=evt.is_subject, + exterior_ring=evt.is_exterior_ring, + prev_in_result=evt.get_prev_in_result().map(|o| format!("{:?}", o.point)), + ).expect("Failed to write to file"); + } +} + fn next_pos(pos: i32, result_events: &[Rc>], processed: &HashSet, orig_pos: i32) -> i32 where @@ -163,6 +232,7 @@ fn mark_as_processed(processed: &mut HashSet, result_events: &[Rc> = Vec::new(); let mut processed: HashSet = HashSet::new(); @@ -214,7 +285,7 @@ where pos = next_pos(pos, &result_events, &processed, orig_pos); // pos advancement (B) - if pos == orig_pos { + if pos == orig_pos || pos == -1 { break; } } diff --git a/lib/src/boolean/divide_segment.rs b/lib/src/boolean/divide_segment.rs index 89dc3ae..387562d 100644 --- a/lib/src/boolean/divide_segment.rs +++ b/lib/src/boolean/divide_segment.rs @@ -8,6 +8,8 @@ pub fn divide_segment(se: &Rc>, inter: Coordinate, queue: &m where F: Float, { + debug_assert!(se.is_left()); + println!("dividing segment {:?} {:?} {:?}", se.point, inter, se.get_other_event().unwrap().point); let other_event = match se.get_other_event() { Some(other_event) => other_event, None => return, @@ -24,7 +26,9 @@ where ); if l < other_event { - se.set_left(true); + println!("l < other_event {:?} {:?} {:?}", l.point, other_event.point, l < other_event); + se.get_other_event().unwrap().set_left(true); + //se.set_left(true); l.set_left(false); } diff --git a/lib/src/boolean/possible_intersection.rs b/lib/src/boolean/possible_intersection.rs index 49d167c..f03b1cb 100644 --- a/lib/src/boolean/possible_intersection.rs +++ b/lib/src/boolean/possible_intersection.rs @@ -18,10 +18,23 @@ where _ => return 0, }; - match intersection(se1.point, other1.point, se2.point, other2.point) { + let inter = intersection(se1.point, other1.point, se2.point, other2.point); + println!("Intersection: {:?}", inter); + match inter { + LineIntersection::Point(inter) => { + println!("{{\"intersection\": {{\"x\": {}, \"y\": {}}}}}", inter.x, inter.y); + }, + _ => {} + } + match inter { LineIntersection::None => 0, // No intersection - LineIntersection::Point(_) if se1.point == se2.point && other1.point == other2.point => 0, // the line segments intersect at an endpoint of both line segments + LineIntersection::Point(_) if se1.point == se2.point && other1.point == other2.point => + { + println!(" => line segments intersect at an endpoint of both line segments"); + 0 + }, // the line segments intersect at an endpoint of both line segments LineIntersection::Point(inter) => { + println!(" => point intersection"); if se1.point != inter && other1.point != inter { divide_segment(&se1, inter, queue) } @@ -32,6 +45,7 @@ where } LineIntersection::Overlap(_, _) if se1.is_subject == se2.is_subject => 0, // The line segments associated to se1 and se2 overlap LineIntersection::Overlap(_, _) => { + println!(" => overlap"); let mut events = Vec::new(); let mut left_coincide = false; let mut right_coincide = false; diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index 0dafe58..4c20844 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -20,6 +20,49 @@ pub fn intersection( where F: Float, { + let inter = intersection_impl(a1, a2, b1, b2); + match inter { + LineIntersection::Point(mut p) => { + let a_min_x = a1.x.min(a2.x); + let a_max_x = a1.x.max(a2.x); + let a_min_y = a1.y.min(a2.y); + let a_max_y = a1.y.max(a2.y); + let b_min_x = b1.x.min(b2.x); + let b_max_x = b1.x.max(b2.x); + let b_min_y = b1.y.min(b2.y); + let b_max_y = b1.y.max(b2.y); + let min_x = a_min_x.max(b_min_x); + let max_x = a_max_x.min(b_max_x); + let min_y = a_min_y.max(b_min_y); + let max_y = a_max_y.min(b_max_y); + if p.x < min_x { + p.x = min_x; + } + if p.x < max_x { + p.x = max_x; + } + if p.y < min_y { + p.y = min_y; + } + if p.y < max_y { + p.y = max_y; + } + LineIntersection::Point(p) + }, + _ => inter + } +} + +fn intersection_impl( + a1: Coordinate, + a2: Coordinate, + b1: Coordinate, + b2: Coordinate, +) -> LineIntersection +where + F: Float, +{ + println!("{:?} {:?} {:?} {:?}", a1, a2, b1, b2); let va = Coordinate { x: a2.x - a1.x, y: a2.y - a1.y, @@ -47,12 +90,15 @@ where } if s == F::zero() || s == F::one() { + println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(a1, s, va)); } if t == F::zero() || t == F::one() { + println!("t = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(b1, t, vb)); } + println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(a1, s, va)); } diff --git a/lib/src/boolean/subdivide_segments.rs b/lib/src/boolean/subdivide_segments.rs index cc96d7d..16abfb8 100644 --- a/lib/src/boolean/subdivide_segments.rs +++ b/lib/src/boolean/subdivide_segments.rs @@ -1,7 +1,7 @@ use super::compare_segments::compare_segments; use super::compute_fields::compute_fields; use super::possible_intersection::possible_intersection; -use super::sweep_event::SweepEvent; +use super::sweep_event::{SweepEvent, JsonDebug}; use super::Operation; use crate::splay::SplaySet; use geo_types::Rect; @@ -23,8 +23,12 @@ where let rightbound = sbbox.max.x.min(cbbox.max.x); while let Some(event) = event_queue.pop() { + println!(""); + println!("size event queue begin iter: {}", event_queue.len()); + println!("{{\"processEvent\": {}}}", event.to_json_debug()); sorted_events.push(event.clone()); + println!("{} {}", event.point.x, rightbound); if operation == Operation::Intersection && event.point.x > rightbound || operation == Operation::Difference && event.point.x > sbbox.max.x { @@ -40,16 +44,19 @@ where compute_fields(&event, maybe_prev, operation); if let Some(next) = maybe_next { + println!("{{\"seNextEvent\": {}}}", next.to_json_debug()); if possible_intersection(&event, &next, event_queue) == 2 { + println!("Intersection with next"); compute_fields(&event, maybe_prev, operation); compute_fields(&event, Some(next), operation); } } if let Some(prev) = maybe_prev { + println!("{{\"sePrevEvent\": {}}}", prev.to_json_debug()); if possible_intersection(&prev, &event, event_queue) == 2 { let maybe_prev_prev = sweep_line.prev(&prev); - + println!("Intersection with prev"); compute_fields(&prev, maybe_prev_prev, operation); compute_fields(&event, Some(prev), operation); } @@ -60,12 +67,23 @@ where let maybe_next = sweep_line.next(&other_event).cloned(); if let (Some(prev), Some(next)) = (maybe_prev, maybe_next) { + println!("Possible post intersection"); + println!("{{\"sePostNextEvent\": {}}}", next.to_json_debug()); + println!("{{\"sePostPrevEvent\": {}}}", prev.to_json_debug()); possible_intersection(&prev, &next, event_queue); } + println!("{{\"removing\": {}}}", other_event.to_json_debug()); sweep_line.remove(&other_event); } } + + println!("size event queue end iter: {}", event_queue.len()); + + //let s: Vec = &sweep_line.into_iter().map(|e| e.to_json_debug()).collect(); + //let s = s.join(", "); + //println!("{{\"sweepLineState\": {{{}}}}}", s); + } sorted_events diff --git a/lib/src/boolean/sweep_event.rs b/lib/src/boolean/sweep_event.rs index 2d13d69..3f7157d 100644 --- a/lib/src/boolean/sweep_event.rs +++ b/lib/src/boolean/sweep_event.rs @@ -239,6 +239,35 @@ where } } + +pub trait JsonDebug { + fn to_json_debug(&self) -> String; + fn to_json_debug_short(&self) -> String; +} + +impl JsonDebug for Rc::> +where + F: Float, +{ + fn to_json_debug(&self) -> String { + format!( + "{{\"self\": {}, \"other\": {}}}", + self.to_json_debug_short(), + self.get_other_event().unwrap().to_json_debug_short(), + ) + } + + fn to_json_debug_short(&self) -> String { + format!( + "{{\"addr\": \"{:p}\", \"point\": {{\"x\": {}, \"y\": {}}}, \"type\": \"{}\"}}", + *self, + self.point.x, + self.point.y, + if self.is_left() { "L" } else { "R" }, + ) + } +} + #[cfg(test)] mod test { use super::super::helper::test::xy; From 197f781c3bea4cf46c4605578e080d1b7662abc6 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 07:58:56 +0100 Subject: [PATCH 02/21] introduced bounding box for intersection test --- lib/src/boolean/divide_segment.rs | 2 +- lib/src/boolean/segment_intersection.rs | 122 ++++++++++++++++++------ 2 files changed, 92 insertions(+), 32 deletions(-) diff --git a/lib/src/boolean/divide_segment.rs b/lib/src/boolean/divide_segment.rs index dc18e99..4f20f6c 100644 --- a/lib/src/boolean/divide_segment.rs +++ b/lib/src/boolean/divide_segment.rs @@ -69,7 +69,7 @@ mod test { } #[test] - fn devide_segments() { + fn divide_segments() { let (se1, other1) = make_simple(0.0, 0.0, 5.0, 5.0, true); let (se2, other2) = make_simple(0.0, 5.0, 5.0, 0.0, false); let mut queue = BinaryHeap::new(); diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index 50d3d06..69d98b7 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -1,5 +1,5 @@ use super::helper::Float; -use geo_types::Coordinate; +use geo_types::{Coordinate, Rect}; #[derive(Debug, Clone, Copy, PartialEq)] pub enum LineIntersection @@ -11,6 +11,57 @@ where Overlap(Coordinate, Coordinate), } +#[inline] +fn get_intersection_bounding_box( + a1: Coordinate, + a2: Coordinate, + b1: Coordinate, + b2: Coordinate, +) -> Option> +where + F: Float, +{ + let a_min_x = a1.x.min(a2.x); + let a_max_x = a1.x.max(a2.x); + let a_min_y = a1.y.min(a2.y); + let a_max_y = a1.y.max(a2.y); + let b_min_x = b1.x.min(b2.x); + let b_max_x = b1.x.max(b2.x); + let b_min_y = b1.y.min(b2.y); + let b_max_y = b1.y.max(b2.y); + let min_x = a_min_x.max(b_min_x); + let max_x = a_max_x.min(b_max_x); + let min_y = a_min_y.max(b_min_y); + let max_y = a_max_y.min(b_max_y); + Some(Rect{ + min: Coordinate{x: min_x, y: min_y}, + max: Coordinate{x: max_x, y: max_y}, + }) +} + +#[inline] +fn constrain_to_bounding_box(p: Coordinate, bb: Rect) -> Coordinate +where + F: Float, +{ + Coordinate{ + x: if p.x < bb.min.x { + bb.min.x + } else if p.x > bb.max.x { + bb.max.x + } else { + p.x + }, + y: if p.y < bb.min.y { + bb.min.y + } else if p.y > bb.max.y { + bb.max.y + } else { + p.y + }, + } +} + pub fn intersection( a1: Coordinate, a2: Coordinate, @@ -20,36 +71,17 @@ pub fn intersection( where F: Float, { - let inter = intersection_impl(a1, a2, b1, b2); - match inter { - LineIntersection::Point(mut p) => { - let a_min_x = a1.x.min(a2.x); - let a_max_x = a1.x.max(a2.x); - let a_min_y = a1.y.min(a2.y); - let a_max_y = a1.y.max(a2.y); - let b_min_x = b1.x.min(b2.x); - let b_max_x = b1.x.max(b2.x); - let b_min_y = b1.y.min(b2.y); - let b_max_y = b1.y.max(b2.y); - let min_x = a_min_x.max(b_min_x); - let max_x = a_max_x.min(b_max_x); - let min_y = a_min_y.max(b_min_y); - let max_y = a_max_y.min(b_max_y); - if p.x < min_x { - p.x = min_x; - } - if p.x < max_x { - p.x = max_x; - } - if p.y < min_y { - p.y = min_y; - } - if p.y < max_y { - p.y = max_y; - } - LineIntersection::Point(p) - }, - _ => inter + let bb = get_intersection_bounding_box(a1, a2, b1, b2); + if let Some(bb) = bb { + let inter = intersection_impl(a1, a2, b1, b2); + match inter { + LineIntersection::Point(p) => { + LineIntersection::Point(constrain_to_bounding_box(p, bb)) + }, + _ => inter + } + } else { + LineIntersection::None } } @@ -162,6 +194,34 @@ mod test { use super::super::helper::test::xy; use super::*; + #[test] + fn test_get_intersection_bounding_box() { + assert_eq!( + get_intersection_bounding_box(xy(0, 0), xy(2, 2), xy(1, 1), xy(3, 3)), + Some(Rect{min: xy(1, 1), max: xy(2, 2)}), + ); + assert_eq!( + get_intersection_bounding_box(xy(-1, 0), xy(1, 0), xy(0, -1), xy(0, 1)), + Some(Rect{min: xy(0, 0), max: xy(0, 0)}), + ); + assert_eq!( + get_intersection_bounding_box(xy(0, 0), xy(1, 1), xy(2, 0), xy(3, 1)), + None, + ); + assert_eq!( + get_intersection_bounding_box(xy(3, 0), xy(2, 1), xy(1, 0), xy(0, 1)), + None, + ); + assert_eq!( + get_intersection_bounding_box(xy(0, 0), xy(1, 1), xy(0, 2), xy(1, 3)), + None, + ); + assert_eq!( + get_intersection_bounding_box(xy(0, 3), xy(1, 2), xy(0, 1), xy(1, 0)), + None, + ); + } + #[test] fn test_intersection() { assert_eq!( From 2a732048096ba73f318f963774953df726590dc8 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 08:09:50 +0100 Subject: [PATCH 03/21] improved bounding box implementation --- lib/src/boolean/segment_intersection.rs | 48 ++++++++++++++++--------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index 69d98b7..79d6f0a 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -21,22 +21,38 @@ fn get_intersection_bounding_box( where F: Float, { - let a_min_x = a1.x.min(a2.x); - let a_max_x = a1.x.max(a2.x); - let a_min_y = a1.y.min(a2.y); - let a_max_y = a1.y.max(a2.y); - let b_min_x = b1.x.min(b2.x); - let b_max_x = b1.x.max(b2.x); - let b_min_y = b1.y.min(b2.y); - let b_max_y = b1.y.max(b2.y); - let min_x = a_min_x.max(b_min_x); - let max_x = a_max_x.min(b_max_x); - let min_y = a_min_y.max(b_min_y); - let max_y = a_max_y.min(b_max_y); - Some(Rect{ - min: Coordinate{x: min_x, y: min_y}, - max: Coordinate{x: max_x, y: max_y}, - }) + let (a_start_x, a_end_x) = if a1.x < a2.x { + (a1.x, a2.x) + } else { + (a2.x, a1.x) + }; + let (a_start_y, a_end_y) = if a1.y < a2.y { + (a1.y, a2.y) + } else { + (a2.y, a1.y) + }; + let (b_start_x, b_end_x) = if b1.x < b2.x { + (b1.x, b2.x) + } else { + (b2.x, b1.x) + }; + let (b_start_y, b_end_y) = if b1.y < b2.y { + (b1.y, b2.y) + } else { + (b2.y, b1.y) + }; + let interval_start_x = a_start_x.max(b_start_x); + let interval_start_y = a_start_y.max(b_start_y); + let interval_end_x = a_end_x.min(b_end_x); + 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(Rect{ + min: Coordinate{x: interval_start_x, y: interval_start_y}, + max: Coordinate{x: interval_end_x, y: interval_end_y}, + }) + } else { + None + } } #[inline] From 16f5931bfc21abddb89bcb6ada6f7e390af8fc21 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 20:17:02 +0100 Subject: [PATCH 04/21] added test for constrain to box --- lib/src/boolean/segment_intersection.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index 79d6f0a..d207f52 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -238,6 +238,26 @@ mod test { ); } + #[test] + fn test_constrain_to_bounding_box() { + assert_eq!( + constrain_to_bounding_box(xy(100, 0), Rect{min: xy(-1, -1), max: xy(1, 1)}), + xy(1, 0), + ); + assert_eq!( + constrain_to_bounding_box(xy(-100, 0), Rect{min: xy(-1, -1), max: xy(1, 1)}), + xy(-1, 0), + ); + assert_eq!( + constrain_to_bounding_box(xy(0, 100), Rect{min: xy(-1, -1), max: xy(1, 1)}), + xy(0, 1), + ); + assert_eq!( + constrain_to_bounding_box(xy(0, -100), Rect{min: xy(-1, -1), max: xy(1, 1)}), + xy(0, -1), + ); + } + #[test] fn test_intersection() { assert_eq!( From b22f2fd8ab9b4a780f597ed4cb5028edf5739111 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 22:28:52 +0100 Subject: [PATCH 05/21] first working fix for ulp slopes --- Cargo.lock | 10 + lib/Cargo.toml | 1 + lib/src/boolean/connect_edges.rs | 5 +- lib/src/boolean/divide_segment.rs | 15 +- lib/src/boolean/helper.rs | 38 +- lib/src/boolean/sweep_event.rs | 10 + .../generic_test_cases/issue76.geojson | 15 +- .../generic_test_cases/issue99.geojson | 58 ++ .../vertical_ulp_slopes1.geojson | 792 ++++++++++++++++++ 9 files changed, 929 insertions(+), 15 deletions(-) create mode 100644 tests/fixtures/generic_test_cases/issue99.geojson create mode 100644 tests/fixtures/generic_test_cases/vertical_ulp_slopes1.geojson diff --git a/Cargo.lock b/Cargo.lock index de30397..3e98cf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,6 +77,14 @@ dependencies = [ "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "float_extras" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -97,6 +105,7 @@ dependencies = [ name = "geo-booleanop" version = "0.2.0" dependencies = [ + "float_extras 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "geo-types 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -362,6 +371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" +"checksum float_extras 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b22b70f8649ea2315955f1a36d964b0e4da482dfaa5f0d04df0d1fb7c338ab7a" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum geo 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "89ce8faa25a6f5ce8ea98faa95247d66377a843408eb4418332ec37de96850b0" "checksum geo-types 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "866e8f6dbd2218b05ea8a25daa1bfac32b0515fe7e0a37cb6a7b9ed0ed82a07e" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 431e54e..d836db5 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -13,6 +13,7 @@ keywords = ["gis", "geo", "geography", "geospatial"] geo-types = { version = "0.4", default-features = false } num-traits = "0.2" robust = "0.1" +float_extras = "0.1" [dev-dependencies] rand = "0.3" diff --git a/lib/src/boolean/connect_edges.rs b/lib/src/boolean/connect_edges.rs index 3fd9f67..f429b89 100644 --- a/lib/src/boolean/connect_edges.rs +++ b/lib/src/boolean/connect_edges.rs @@ -59,7 +59,7 @@ where event.set_other_pos(pos as i32) } for event in &result_events { - if !event.is_left() { + if event.is_left() { if let Some(other) = event.get_other_event() { let (a, b) = (event.get_other_pos(), other.get_other_pos()); event.set_other_pos(b); @@ -234,7 +234,6 @@ fn mark_as_processed(processed: &mut HashSet, result_events: &[Rc other_event, None => return, }; + let mut inter = inter; + if inter.x == se.point.x && inter.y < se.point.y { + //println!("ZZZ incrementing x {} => {}", inter.x, inter.x.nextafter(true)); + inter.x = inter.x.nextafter(true); + } + let r = SweepEvent::new_rc(se.contour_id, inter, false, Rc::downgrade(&se), se.is_subject, true); let l = SweepEvent::new_rc( se.contour_id, @@ -25,10 +32,10 @@ where true, ); - if l < other_event { - println!("l < other_event {:?} {:?} {:?}", l.point, other_event.point, l < other_event); + debug_assert!(r.is_after(se)); + if l.is_after(&other_event) { + //println!("XXX l > other_event {:?} < {:?}", l.point, other_event.point); se.get_other_event().unwrap().set_left(true); - //se.set_left(true); l.set_left(false); } diff --git a/lib/src/boolean/helper.rs b/lib/src/boolean/helper.rs index 1b7930e..c10ae98 100644 --- a/lib/src/boolean/helper.rs +++ b/lib/src/boolean/helper.rs @@ -1,9 +1,43 @@ +use float_extras::f64::nextafter; use num_traits::Float as NumTraitsFloat; use std::cmp::Ordering; use std::fmt::{Debug, Display}; -pub trait Float: NumTraitsFloat + Debug + Display {} -impl Float for T {} + +pub trait Float: NumTraitsFloat + Debug + Display + NextAfter + Into {} + +impl> Float for T {} + +pub trait NextAfter: NumTraitsFloat { + fn nextafter(self, up: bool) -> Self; + fn nextafter_steps(self, steps: i32) -> Self; + + fn ulp(self) -> Self { + if self > Self::zero() { + self.nextafter(true) - self + } else { + self.nextafter(false) - self + } + } +} + +impl NextAfter for f64 { + fn nextafter(self, up: bool) -> Self { + if up { + nextafter(self, std::f64::INFINITY) + } else { + nextafter(self, std::f64::NEG_INFINITY) + } + } + + fn nextafter_steps(self, steps: i32) -> Self { + let mut x = self; + for _ in 0..steps.abs() { + x = x.nextafter(steps > 0); + } + x + } +} #[inline] pub fn less_if(condition: bool) -> Ordering { diff --git a/lib/src/boolean/sweep_event.rs b/lib/src/boolean/sweep_event.rs index f8646bb..32eb90e 100644 --- a/lib/src/boolean/sweep_event.rs +++ b/lib/src/boolean/sweep_event.rs @@ -178,6 +178,16 @@ where None => false, } } + + /// Helper function to avoid confusion by inverted ordering + pub fn is_before(&self, other: &SweepEvent) -> bool { + self > other + } + + /// Helper function to avoid confusion by inverted ordering + pub fn is_after(&self, other: &SweepEvent) -> bool { + self < other + } } impl PartialEq for SweepEvent diff --git a/tests/fixtures/generic_test_cases/issue76.geojson b/tests/fixtures/generic_test_cases/issue76.geojson index 4ec9a14..ccad810 100644 --- a/tests/fixtures/generic_test_cases/issue76.geojson +++ b/tests/fixtures/generic_test_cases/issue76.geojson @@ -35,11 +35,12 @@ "coordinates": [ [ [ - [-19.3046867422006, -126.63400219275148], [-19.3046867422006, -107.63400219275148], - [10.695313257799395, -107.63400219275148], + [-19.304686742200598, -126.63400219275148], [10.695313257799395, -126.63400219275148], - [-19.3046867422006, -126.63400219275148] + [10.695313257799397, -126.63400219275148], + [10.695313257799395, -107.63400219275148], + [-19.3046867422006, -107.63400219275148] ] ] ], @@ -58,9 +59,10 @@ [ [-96.66033269728321, -126.63400219275148], [-19.3046867422006, -126.63400219275148], + [-19.304686742200598, -126.63400219275148], [-19.304686742200587, -357.48241878255635], [10.695313257799413, -357.48241878255635], - [10.695313257799395, -126.63400219275148], + [10.695313257799397, -126.63400219275148], [13.370917302716792, -126.63400219275148], [13.370917302716792, -107.63400219275148], [10.695313257799395, -107.63400219275148], @@ -94,11 +96,12 @@ ], [ [ - [-19.3046867422006, -126.63400219275148], + [-19.304686742200598, -126.63400219275148], [-19.304686742200587, -357.48241878255635], [10.695313257799413, -357.48241878255635], + [10.695313257799397, -126.63400219275148], [10.695313257799395, -126.63400219275148], - [-19.3046867422006, -126.63400219275148] + [-19.304686742200598, -126.63400219275148] ] ] ], diff --git a/tests/fixtures/generic_test_cases/issue99.geojson b/tests/fixtures/generic_test_cases/issue99.geojson new file mode 100644 index 0000000..630b772 --- /dev/null +++ b/tests/fixtures/generic_test_cases/issue99.geojson @@ -0,0 +1,58 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [-530, -530], + [-530, 530], + [530, 530], + [530, -530], + [-530, -530] + ] + ], + "type": "Polygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [1.2500125250252, -531], + [-98, -531], + [-98, 531], + [1.250012525025, 531], + [1.2500125250252, -531] + ] + ], + "type": "Polygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-98, -530], + [1.2500125250252, -530], + [1.2500125250250003, 530], + [1.250012525025, 530], + [-98, 530], + [-98, -530] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "intersection" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/tests/fixtures/generic_test_cases/vertical_ulp_slopes1.geojson b/tests/fixtures/generic_test_cases/vertical_ulp_slopes1.geojson new file mode 100644 index 0000000..13bb6d6 --- /dev/null +++ b/tests/fixtures/generic_test_cases/vertical_ulp_slopes1.geojson @@ -0,0 +1,792 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [-1, -2], + [-1.0000000000000002, 2], + [-0.8823529411764707, 2], + [-0.8823529411764706, -2], + [-1, -2] + ] + ], + [ + [ + [-0.7647058823529411, -2], + [-0.7647058823529412, 2], + [-0.6470588235294118, 2], + [-0.6470588235294118, -2], + [-0.7647058823529411, -2] + ] + ], + [ + [ + [-0.5294117647058824, -2], + [-0.5294117647058825, 2], + [-0.41176470588235287, 2], + [-0.4117647058823529, -2], + [-0.5294117647058824, -2] + ] + ], + [ + [ + [-0.2941176470588236, -2], + [-0.2941176470588236, 2], + [-0.17647058823529418, 2], + [-0.17647058823529416, -2], + [-0.2941176470588236, -2] + ] + ], + [ + [ + [-0.05882352941176472, -2], + [-0.05882352941176472, 2], + [0.05882352941176472, 2], + [0.05882352941176472, -2], + [-0.05882352941176472, -2] + ] + ], + [ + [ + [0.17647058823529416, -2], + [0.17647058823529416, 2], + [0.29411764705882365, 2], + [0.2941176470588236, -2], + [0.17647058823529416, -2] + ] + ], + [ + [ + [0.4117647058823528, -2], + [0.41176470588235287, 2], + [0.5294117647058821, 2], + [0.5294117647058822, -2], + [0.4117647058823528, -2] + ] + ], + [ + [ + [0.6470588235294117, -2], + [0.6470588235294118, 2], + [0.7647058823529411, 2], + [0.7647058823529411, -2], + [0.6470588235294117, -2] + ] + ], + [ + [ + [0.8823529411764706, -2], + [0.8823529411764707, 2], + [1.0000000000000002, 2], + [1, -2], + [0.8823529411764706, -2] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-2, -1], + [2, -1.0000000000000002], + [2, -0.8823529411764707], + [-2, -0.8823529411764706], + [-2, -1] + ] + ], + [ + [ + [-2, -0.7647058823529411], + [2, -0.7647058823529412], + [2, -0.6470588235294118], + [-2, -0.6470588235294118], + [-2, -0.7647058823529411] + ] + ], + [ + [ + [-2, -0.5294117647058824], + [2, -0.5294117647058825], + [2, -0.41176470588235287], + [-2, -0.4117647058823529], + [-2, -0.5294117647058824] + ] + ], + [ + [ + [-2, -0.2941176470588236], + [2, -0.2941176470588236], + [2, -0.17647058823529418], + [-2, -0.17647058823529416], + [-2, -0.2941176470588236] + ] + ], + [ + [ + [-2, -0.05882352941176472], + [2, -0.05882352941176472], + [2, 0.05882352941176472], + [-2, 0.05882352941176472], + [-2, -0.05882352941176472] + ] + ], + [ + [ + [-2, 0.17647058823529416], + [2, 0.17647058823529416], + [2, 0.29411764705882365], + [-2, 0.2941176470588236], + [-2, 0.17647058823529416] + ] + ], + [ + [ + [-2, 0.4117647058823528], + [2, 0.41176470588235287], + [2, 0.5294117647058821], + [-2, 0.5294117647058822], + [-2, 0.4117647058823528] + ] + ], + [ + [ + [-2, 0.6470588235294117], + [2, 0.6470588235294118], + [2, 0.7647058823529411], + [-2, 0.7647058823529411], + [-2, 0.6470588235294117] + ] + ], + [ + [ + [-2, 0.8823529411764706], + [2, 0.8823529411764707], + [2, 1.0000000000000002], + [-2, 1], + [-2, 0.8823529411764706] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-2, -1], + [-1, -1], + [-1, -2], + [-0.8823529411764706, -2], + [-0.8823529411764706, -1], + [-0.7647058823529411, -1], + [-0.7647058823529411, -2], + [-0.6470588235294118, -2], + [-0.6470588235294118, -1], + [-0.5294117647058824, -1], + [-0.5294117647058824, -2], + [-0.4117647058823529, -2], + [-0.4117647058823529, -1], + [-0.2941176470588236, -1], + [-0.2941176470588236, -2], + [-0.17647058823529416, -2], + [-0.17647058823529416, -1], + [-0.05882352941176472, -1], + [-0.05882352941176472, -2], + [0.05882352941176472, -2], + [0.05882352941176472, -1], + [0.17647058823529416, -1], + [0.17647058823529416, -2], + [0.2941176470588236, -2], + [0.2941176470588236, -1], + [0.4117647058823528, -1], + [0.4117647058823528, -2], + [0.5294117647058822, -2], + [0.5294117647058822, -1], + [0.6470588235294117, -1], + [0.6470588235294117, -2], + [0.7647058823529411, -2], + [0.7647058823529411, -1], + [0.8823529411764706, -1], + [0.8823529411764706, -2], + [1, -2], + [1, -1], + [2, -1.0000000000000002], + [2, -0.8823529411764707], + [1, -0.8823529411764706], + [1, -0.7647058823529411], + [2, -0.7647058823529412], + [2, -0.6470588235294118], + [1, -0.6470588235294118], + [1, -0.5294117647058824], + [2, -0.5294117647058825], + [2, -0.41176470588235287], + [1, -0.4117647058823529], + [1, -0.2941176470588236], + [2, -0.2941176470588236], + [2, -0.17647058823529418], + [1, -0.17647058823529416], + [1, -0.05882352941176472], + [2, -0.05882352941176472], + [2, 0.05882352941176472], + [1, 0.05882352941176472], + [1, 0.17647058823529416], + [2, 0.17647058823529416], + [2, 0.29411764705882365], + [1, 0.2941176470588236], + [1, 0.4117647058823528], + [2, 0.41176470588235287], + [2, 0.5294117647058821], + [1, 0.5294117647058822], + [1, 0.6470588235294117], + [2, 0.6470588235294118], + [2, 0.7647058823529411], + [1, 0.7647058823529411], + [1, 0.8823529411764706], + [2, 0.8823529411764707], + [2, 1.0000000000000002], + [1, 1], + [1.0000000000000002, 2], + [0.8823529411764707, 2], + [0.8823529411764706, 1], + [0.7647058823529411, 1], + [0.7647058823529411, 2], + [0.6470588235294118, 2], + [0.6470588235294117, 1], + [0.5294117647058822, 1], + [0.5294117647058821, 2], + [0.41176470588235287, 2], + [0.4117647058823528, 1], + [0.2941176470588236, 1], + [0.29411764705882365, 2], + [0.17647058823529416, 2], + [0.17647058823529416, 1], + [0.05882352941176472, 1], + [0.05882352941176472, 2], + [-0.05882352941176472, 2], + [-0.05882352941176472, 1], + [-0.17647058823529416, 1], + [-0.17647058823529418, 2], + [-0.2941176470588236, 2], + [-0.2941176470588236, 1], + [-0.4117647058823529, 1], + [-0.41176470588235287, 2], + [-0.5294117647058825, 2], + [-0.5294117647058824, 1], + [-0.5294117647058825, 1], + [-0.6470588235294118, 1], + [-0.6470588235294118, 2], + [-0.7647058823529412, 2], + [-0.7647058823529411, 1], + [-0.7647058823529412, 1], + [-0.8823529411764706, 1], + [-0.8823529411764707, 2], + [-1.0000000000000002, 2], + [-1, 1], + [-1.0000000000000002, 1], + [-2, 1], + [-2, 0.8823529411764706], + [-1, 0.8823529411764706], + [-1, 0.7647058823529411], + [-2, 0.7647058823529411], + [-2, 0.6470588235294117], + [-1, 0.6470588235294117], + [-1, 0.5294117647058822], + [-2, 0.5294117647058822], + [-2, 0.4117647058823528], + [-1, 0.4117647058823528], + [-1, 0.2941176470588236], + [-2, 0.2941176470588236], + [-2, 0.17647058823529416], + [-1, 0.17647058823529416], + [-1, 0.05882352941176472], + [-2, 0.05882352941176472], + [-2, -0.05882352941176472], + [-1, -0.05882352941176472], + [-1, -0.17647058823529416], + [-2, -0.17647058823529416], + [-2, -0.2941176470588236], + [-1, -0.2941176470588236], + [-1, -0.4117647058823529], + [-2, -0.4117647058823529], + [-2, -0.5294117647058824], + [-1, -0.5294117647058824], + [-1, -0.6470588235294118], + [-2, -0.6470588235294118], + [-2, -0.7647058823529411], + [-1, -0.7647058823529411], + [-1, -0.8823529411764706], + [-2, -0.8823529411764706], + [-2, -1] + ], + [ + [-0.8823529411764706, -0.8823529411764706], + [-0.7647058823529411, -0.8823529411764706], + [-0.7647058823529411, -0.7647058823529411], + [-0.8823529411764706, -0.7647058823529411], + [-0.8823529411764706, -0.8823529411764706] + ], + [ + [-0.8823529411764706, -0.6470588235294118], + [-0.7647058823529411, -0.6470588235294118], + [-0.7647058823529411, -0.5294117647058824], + [-0.8823529411764706, -0.5294117647058824], + [-0.8823529411764706, -0.6470588235294118] + ], + [ + [-0.8823529411764706, -0.4117647058823529], + [-0.7647058823529411, -0.4117647058823529], + [-0.7647058823529411, -0.2941176470588236], + [-0.8823529411764706, -0.2941176470588236], + [-0.8823529411764706, -0.4117647058823529] + ], + [ + [-0.8823529411764706, -0.17647058823529416], + [-0.7647058823529411, -0.17647058823529416], + [-0.7647058823529411, -0.05882352941176472], + [-0.8823529411764706, -0.05882352941176472], + [-0.8823529411764706, -0.17647058823529416] + ], + [ + [-0.8823529411764706, 0.05882352941176472], + [-0.7647058823529411, 0.05882352941176472], + [-0.7647058823529411, 0.17647058823529416], + [-0.8823529411764706, 0.17647058823529416], + [-0.8823529411764706, 0.05882352941176472] + ], + [ + [-0.8823529411764706, 0.2941176470588236], + [-0.7647058823529411, 0.2941176470588236], + [-0.7647058823529411, 0.4117647058823528], + [-0.8823529411764706, 0.4117647058823528], + [-0.8823529411764706, 0.2941176470588236] + ], + [ + [-0.8823529411764706, 0.5294117647058822], + [-0.7647058823529411, 0.5294117647058822], + [-0.7647058823529411, 0.6470588235294117], + [-0.8823529411764706, 0.6470588235294117], + [-0.8823529411764706, 0.5294117647058822] + ], + [ + [-0.8823529411764706, 0.7647058823529411], + [-0.7647058823529411, 0.7647058823529411], + [-0.7647058823529411, 0.8823529411764706], + [-0.8823529411764706, 0.8823529411764706], + [-0.8823529411764706, 0.7647058823529411] + ], + [ + [-0.6470588235294118, -0.8823529411764706], + [-0.5294117647058824, -0.8823529411764706], + [-0.5294117647058824, -0.7647058823529411], + [-0.6470588235294118, -0.7647058823529411], + [-0.6470588235294118, -0.8823529411764706] + ], + [ + [-0.6470588235294118, -0.6470588235294118], + [-0.5294117647058824, -0.6470588235294118], + [-0.5294117647058824, -0.5294117647058824], + [-0.6470588235294118, -0.5294117647058824], + [-0.6470588235294118, -0.6470588235294118] + ], + [ + [-0.6470588235294118, -0.4117647058823529], + [-0.5294117647058824, -0.4117647058823529], + [-0.5294117647058824, -0.2941176470588236], + [-0.6470588235294118, -0.2941176470588236], + [-0.6470588235294118, -0.4117647058823529] + ], + [ + [-0.6470588235294118, -0.17647058823529416], + [-0.5294117647058824, -0.17647058823529416], + [-0.5294117647058824, -0.05882352941176472], + [-0.6470588235294118, -0.05882352941176472], + [-0.6470588235294118, -0.17647058823529416] + ], + [ + [-0.6470588235294118, 0.05882352941176472], + [-0.5294117647058824, 0.05882352941176472], + [-0.5294117647058824, 0.17647058823529416], + [-0.6470588235294118, 0.17647058823529416], + [-0.6470588235294118, 0.05882352941176472] + ], + [ + [-0.6470588235294118, 0.2941176470588236], + [-0.5294117647058824, 0.2941176470588236], + [-0.5294117647058824, 0.4117647058823528], + [-0.6470588235294118, 0.4117647058823528], + [-0.6470588235294118, 0.2941176470588236] + ], + [ + [-0.6470588235294118, 0.5294117647058822], + [-0.5294117647058824, 0.5294117647058822], + [-0.5294117647058824, 0.6470588235294117], + [-0.6470588235294118, 0.6470588235294117], + [-0.6470588235294118, 0.5294117647058822] + ], + [ + [-0.6470588235294118, 0.7647058823529411], + [-0.5294117647058824, 0.7647058823529411], + [-0.5294117647058824, 0.8823529411764706], + [-0.6470588235294118, 0.8823529411764706], + [-0.6470588235294118, 0.7647058823529411] + ], + [ + [-0.4117647058823529, -0.8823529411764706], + [-0.2941176470588236, -0.8823529411764706], + [-0.2941176470588236, -0.7647058823529411], + [-0.4117647058823529, -0.7647058823529411], + [-0.4117647058823529, -0.8823529411764706] + ], + [ + [-0.4117647058823529, -0.6470588235294118], + [-0.2941176470588236, -0.6470588235294118], + [-0.2941176470588236, -0.5294117647058824], + [-0.4117647058823529, -0.5294117647058824], + [-0.4117647058823529, -0.6470588235294118] + ], + [ + [-0.4117647058823529, -0.4117647058823529], + [-0.2941176470588236, -0.4117647058823529], + [-0.2941176470588236, -0.2941176470588236], + [-0.4117647058823529, -0.2941176470588236], + [-0.4117647058823529, -0.4117647058823529] + ], + [ + [-0.4117647058823529, -0.17647058823529416], + [-0.2941176470588236, -0.17647058823529416], + [-0.2941176470588236, -0.05882352941176472], + [-0.4117647058823529, -0.05882352941176472], + [-0.4117647058823529, -0.17647058823529416] + ], + [ + [-0.4117647058823529, 0.05882352941176472], + [-0.2941176470588236, 0.05882352941176472], + [-0.2941176470588236, 0.17647058823529416], + [-0.4117647058823529, 0.17647058823529416], + [-0.4117647058823529, 0.05882352941176472] + ], + [ + [-0.4117647058823529, 0.2941176470588236], + [-0.2941176470588236, 0.2941176470588236], + [-0.2941176470588236, 0.4117647058823528], + [-0.4117647058823529, 0.4117647058823528], + [-0.4117647058823529, 0.2941176470588236] + ], + [ + [-0.4117647058823529, 0.5294117647058822], + [-0.2941176470588236, 0.5294117647058822], + [-0.2941176470588236, 0.6470588235294117], + [-0.4117647058823529, 0.6470588235294117], + [-0.4117647058823529, 0.5294117647058822] + ], + [ + [-0.4117647058823529, 0.7647058823529411], + [-0.2941176470588236, 0.7647058823529411], + [-0.2941176470588236, 0.8823529411764706], + [-0.4117647058823529, 0.8823529411764706], + [-0.4117647058823529, 0.7647058823529411] + ], + [ + [-0.17647058823529416, -0.8823529411764706], + [-0.05882352941176472, -0.8823529411764706], + [-0.05882352941176472, -0.7647058823529411], + [-0.17647058823529416, -0.7647058823529411], + [-0.17647058823529416, -0.8823529411764706] + ], + [ + [-0.17647058823529416, -0.6470588235294118], + [-0.05882352941176472, -0.6470588235294118], + [-0.05882352941176472, -0.5294117647058824], + [-0.17647058823529416, -0.5294117647058824], + [-0.17647058823529416, -0.6470588235294118] + ], + [ + [-0.17647058823529416, -0.4117647058823529], + [-0.05882352941176472, -0.4117647058823529], + [-0.05882352941176472, -0.2941176470588236], + [-0.17647058823529416, -0.2941176470588236], + [-0.17647058823529416, -0.4117647058823529] + ], + [ + [-0.17647058823529416, -0.17647058823529416], + [-0.05882352941176472, -0.17647058823529416], + [-0.05882352941176472, -0.05882352941176472], + [-0.17647058823529416, -0.05882352941176472], + [-0.17647058823529416, -0.17647058823529416] + ], + [ + [-0.17647058823529416, 0.05882352941176472], + [-0.05882352941176472, 0.05882352941176472], + [-0.05882352941176472, 0.17647058823529416], + [-0.17647058823529416, 0.17647058823529416], + [-0.17647058823529416, 0.05882352941176472] + ], + [ + [-0.17647058823529416, 0.2941176470588236], + [-0.05882352941176472, 0.2941176470588236], + [-0.05882352941176472, 0.4117647058823528], + [-0.17647058823529416, 0.4117647058823528], + [-0.17647058823529416, 0.2941176470588236] + ], + [ + [-0.17647058823529416, 0.5294117647058822], + [-0.05882352941176472, 0.5294117647058822], + [-0.05882352941176472, 0.6470588235294117], + [-0.17647058823529416, 0.6470588235294117], + [-0.17647058823529416, 0.5294117647058822] + ], + [ + [-0.17647058823529416, 0.7647058823529411], + [-0.05882352941176472, 0.7647058823529411], + [-0.05882352941176472, 0.8823529411764706], + [-0.17647058823529416, 0.8823529411764706], + [-0.17647058823529416, 0.7647058823529411] + ], + [ + [0.05882352941176472, -0.8823529411764706], + [0.17647058823529416, -0.8823529411764706], + [0.17647058823529416, -0.7647058823529411], + [0.05882352941176472, -0.7647058823529411], + [0.05882352941176472, -0.8823529411764706] + ], + [ + [0.05882352941176472, -0.6470588235294118], + [0.17647058823529416, -0.6470588235294118], + [0.17647058823529416, -0.5294117647058824], + [0.05882352941176472, -0.5294117647058824], + [0.05882352941176472, -0.6470588235294118] + ], + [ + [0.05882352941176472, -0.4117647058823529], + [0.17647058823529416, -0.4117647058823529], + [0.17647058823529416, -0.2941176470588236], + [0.05882352941176472, -0.2941176470588236], + [0.05882352941176472, -0.4117647058823529] + ], + [ + [0.05882352941176472, -0.17647058823529416], + [0.17647058823529416, -0.17647058823529416], + [0.17647058823529416, -0.05882352941176472], + [0.05882352941176472, -0.05882352941176472], + [0.05882352941176472, -0.17647058823529416] + ], + [ + [0.05882352941176472, 0.05882352941176472], + [0.17647058823529416, 0.05882352941176472], + [0.17647058823529416, 0.17647058823529416], + [0.05882352941176472, 0.17647058823529416], + [0.05882352941176472, 0.05882352941176472] + ], + [ + [0.05882352941176472, 0.2941176470588236], + [0.17647058823529416, 0.2941176470588236], + [0.17647058823529416, 0.4117647058823528], + [0.05882352941176472, 0.4117647058823528], + [0.05882352941176472, 0.2941176470588236] + ], + [ + [0.05882352941176472, 0.5294117647058822], + [0.17647058823529416, 0.5294117647058822], + [0.17647058823529416, 0.6470588235294117], + [0.05882352941176472, 0.6470588235294117], + [0.05882352941176472, 0.5294117647058822] + ], + [ + [0.05882352941176472, 0.7647058823529411], + [0.17647058823529416, 0.7647058823529411], + [0.17647058823529416, 0.8823529411764706], + [0.05882352941176472, 0.8823529411764706], + [0.05882352941176472, 0.7647058823529411] + ], + [ + [0.2941176470588236, -0.8823529411764706], + [0.4117647058823528, -0.8823529411764706], + [0.4117647058823528, -0.7647058823529411], + [0.2941176470588236, -0.7647058823529411], + [0.2941176470588236, -0.8823529411764706] + ], + [ + [0.2941176470588236, -0.6470588235294118], + [0.4117647058823528, -0.6470588235294118], + [0.4117647058823528, -0.5294117647058824], + [0.2941176470588236, -0.5294117647058824], + [0.2941176470588236, -0.6470588235294118] + ], + [ + [0.2941176470588236, -0.4117647058823529], + [0.4117647058823528, -0.4117647058823529], + [0.4117647058823528, -0.2941176470588236], + [0.2941176470588236, -0.2941176470588236], + [0.2941176470588236, -0.4117647058823529] + ], + [ + [0.2941176470588236, -0.17647058823529416], + [0.4117647058823528, -0.17647058823529416], + [0.4117647058823528, -0.05882352941176472], + [0.2941176470588236, -0.05882352941176472], + [0.2941176470588236, -0.17647058823529416] + ], + [ + [0.2941176470588236, 0.05882352941176472], + [0.4117647058823528, 0.05882352941176472], + [0.4117647058823528, 0.17647058823529416], + [0.2941176470588236, 0.17647058823529416], + [0.2941176470588236, 0.05882352941176472] + ], + [ + [0.2941176470588236, 0.2941176470588236], + [0.4117647058823528, 0.2941176470588236], + [0.4117647058823528, 0.4117647058823528], + [0.2941176470588236, 0.4117647058823528], + [0.2941176470588236, 0.2941176470588236] + ], + [ + [0.2941176470588236, 0.5294117647058822], + [0.4117647058823528, 0.5294117647058822], + [0.4117647058823528, 0.6470588235294117], + [0.2941176470588236, 0.6470588235294117], + [0.2941176470588236, 0.5294117647058822] + ], + [ + [0.2941176470588236, 0.7647058823529411], + [0.4117647058823528, 0.7647058823529411], + [0.4117647058823528, 0.8823529411764706], + [0.2941176470588236, 0.8823529411764706], + [0.2941176470588236, 0.7647058823529411] + ], + [ + [0.5294117647058822, -0.8823529411764706], + [0.6470588235294117, -0.8823529411764706], + [0.6470588235294117, -0.7647058823529411], + [0.5294117647058822, -0.7647058823529411], + [0.5294117647058822, -0.8823529411764706] + ], + [ + [0.5294117647058822, -0.6470588235294118], + [0.6470588235294117, -0.6470588235294118], + [0.6470588235294117, -0.5294117647058824], + [0.5294117647058822, -0.5294117647058824], + [0.5294117647058822, -0.6470588235294118] + ], + [ + [0.5294117647058822, -0.4117647058823529], + [0.6470588235294117, -0.4117647058823529], + [0.6470588235294117, -0.2941176470588236], + [0.5294117647058822, -0.2941176470588236], + [0.5294117647058822, -0.4117647058823529] + ], + [ + [0.5294117647058822, -0.17647058823529416], + [0.6470588235294117, -0.17647058823529416], + [0.6470588235294117, -0.05882352941176472], + [0.5294117647058822, -0.05882352941176472], + [0.5294117647058822, -0.17647058823529416] + ], + [ + [0.5294117647058822, 0.05882352941176472], + [0.6470588235294117, 0.05882352941176472], + [0.6470588235294117, 0.17647058823529416], + [0.5294117647058822, 0.17647058823529416], + [0.5294117647058822, 0.05882352941176472] + ], + [ + [0.5294117647058822, 0.2941176470588236], + [0.6470588235294117, 0.2941176470588236], + [0.6470588235294117, 0.4117647058823528], + [0.5294117647058822, 0.4117647058823528], + [0.5294117647058822, 0.2941176470588236] + ], + [ + [0.5294117647058822, 0.5294117647058822], + [0.6470588235294117, 0.5294117647058822], + [0.6470588235294117, 0.6470588235294117], + [0.5294117647058822, 0.6470588235294117], + [0.5294117647058822, 0.5294117647058822] + ], + [ + [0.5294117647058822, 0.7647058823529411], + [0.6470588235294117, 0.7647058823529411], + [0.6470588235294117, 0.8823529411764706], + [0.5294117647058822, 0.8823529411764706], + [0.5294117647058822, 0.7647058823529411] + ], + [ + [0.7647058823529411, -0.8823529411764706], + [0.8823529411764706, -0.8823529411764706], + [0.8823529411764706, -0.7647058823529411], + [0.7647058823529411, -0.7647058823529411], + [0.7647058823529411, -0.8823529411764706] + ], + [ + [0.7647058823529411, -0.6470588235294118], + [0.8823529411764706, -0.6470588235294118], + [0.8823529411764706, -0.5294117647058824], + [0.7647058823529411, -0.5294117647058824], + [0.7647058823529411, -0.6470588235294118] + ], + [ + [0.7647058823529411, -0.4117647058823529], + [0.8823529411764706, -0.4117647058823529], + [0.8823529411764706, -0.2941176470588236], + [0.7647058823529411, -0.2941176470588236], + [0.7647058823529411, -0.4117647058823529] + ], + [ + [0.7647058823529411, -0.17647058823529416], + [0.8823529411764706, -0.17647058823529416], + [0.8823529411764706, -0.05882352941176472], + [0.7647058823529411, -0.05882352941176472], + [0.7647058823529411, -0.17647058823529416] + ], + [ + [0.7647058823529411, 0.05882352941176472], + [0.8823529411764706, 0.05882352941176472], + [0.8823529411764706, 0.17647058823529416], + [0.7647058823529411, 0.17647058823529416], + [0.7647058823529411, 0.05882352941176472] + ], + [ + [0.7647058823529411, 0.2941176470588236], + [0.8823529411764706, 0.2941176470588236], + [0.8823529411764706, 0.4117647058823528], + [0.7647058823529411, 0.4117647058823528], + [0.7647058823529411, 0.2941176470588236] + ], + [ + [0.7647058823529411, 0.5294117647058822], + [0.8823529411764706, 0.5294117647058822], + [0.8823529411764706, 0.6470588235294117], + [0.7647058823529411, 0.6470588235294117], + [0.7647058823529411, 0.5294117647058822] + ], + [ + [0.7647058823529411, 0.7647058823529411], + [0.8823529411764706, 0.7647058823529411], + [0.8823529411764706, 0.8823529411764706], + [0.7647058823529411, 0.8823529411764706], + [0.7647058823529411, 0.7647058823529411] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} From c3144340b4e341a5b87431e93e74c9a0ce8d4e41 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 22:46:41 +0100 Subject: [PATCH 06/21] switched from using nextafter from float_extras to direct libc usage to allow for f32 --- Cargo.lock | 11 +---------- lib/Cargo.toml | 2 +- lib/src/boolean/helper.rs | 33 ++++++++++++++++----------------- lib/src/boolean/signed_area.rs | 4 ++-- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e98cf7..b31c67f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,14 +77,6 @@ dependencies = [ "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "float_extras" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -105,8 +97,8 @@ dependencies = [ name = "geo-booleanop" version = "0.2.0" dependencies = [ - "float_extras 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "geo-types 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "robust 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -371,7 +363,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" -"checksum float_extras 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b22b70f8649ea2315955f1a36d964b0e4da482dfaa5f0d04df0d1fb7c338ab7a" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum geo 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "89ce8faa25a6f5ce8ea98faa95247d66377a843408eb4418332ec37de96850b0" "checksum geo-types 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "866e8f6dbd2218b05ea8a25daa1bfac32b0515fe7e0a37cb6a7b9ed0ed82a07e" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index d836db5..263a2fc 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["gis", "geo", "geography", "geospatial"] geo-types = { version = "0.4", default-features = false } num-traits = "0.2" robust = "0.1" -float_extras = "0.1" +libc = "0.2" [dev-dependencies] rand = "0.3" diff --git a/lib/src/boolean/helper.rs b/lib/src/boolean/helper.rs index c10ae98..3d0167f 100644 --- a/lib/src/boolean/helper.rs +++ b/lib/src/boolean/helper.rs @@ -1,8 +1,14 @@ -use float_extras::f64::nextafter; use num_traits::Float as NumTraitsFloat; use std::cmp::Ordering; use std::fmt::{Debug, Display}; +use libc::{c_double, c_float}; +use std::{f32, f64}; +#[link_name = "m"] +extern "C" { + pub fn nextafter(x: c_double, y: c_double) -> c_double; + pub fn nextafterf(x: c_float, y: c_float) -> c_float; +} pub trait Float: NumTraitsFloat + Debug + Display + NextAfter + Into {} @@ -10,32 +16,25 @@ impl> Float for T {} pub trait NextAfter: NumTraitsFloat { fn nextafter(self, up: bool) -> Self; - fn nextafter_steps(self, steps: i32) -> Self; - - fn ulp(self) -> Self { - if self > Self::zero() { - self.nextafter(true) - self - } else { - self.nextafter(false) - self - } - } } impl NextAfter for f64 { fn nextafter(self, up: bool) -> Self { if up { - nextafter(self, std::f64::INFINITY) + unsafe { nextafter(self, std::f64::INFINITY) } } else { - nextafter(self, std::f64::NEG_INFINITY) + unsafe { nextafter(self, std::f64::NEG_INFINITY) } } } +} - fn nextafter_steps(self, steps: i32) -> Self { - let mut x = self; - for _ in 0..steps.abs() { - x = x.nextafter(steps > 0); +impl NextAfter for f32 { + fn nextafter(self, up: bool) -> Self { + if up { + unsafe { nextafterf(self, std::f32::INFINITY) } + } else { + unsafe { nextafterf(self, std::f32::NEG_INFINITY) } } - x } } diff --git a/lib/src/boolean/signed_area.rs b/lib/src/boolean/signed_area.rs index 8e6bc49..cbb39a5 100644 --- a/lib/src/boolean/signed_area.rs +++ b/lib/src/boolean/signed_area.rs @@ -8,8 +8,8 @@ where F: Float, { Coord { - x: p.x.to_f64().unwrap(), - y: p.y.to_f64().unwrap(), + x: p.x.into(), + y: p.y.into(), } } From 4b43ecb47ba3385cc9276a83bf2a91f59cb9071f Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 23:17:03 +0100 Subject: [PATCH 07/21] added benchmark --- .gitignore | 2 +- Cargo.lock | 520 +++++++++++++++++++++++++++++++++++++ tests/Cargo.toml | 7 + tests/benches/benchmark.rs | 20 ++ tests/src/helper.rs | 11 +- 5 files changed, 556 insertions(+), 4 deletions(-) create mode 100644 tests/benches/benchmark.rs diff --git a/.gitignore b/.gitignore index 35eb536..c97b0ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/target +target/ **/*.rs.b *.iml diff --git a/Cargo.lock b/Cargo.lock index b31c67f..43b495a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,26 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "anyhow" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "autocfg" version = "1.0.0" @@ -33,6 +53,40 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bstr" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bumpalo" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cast" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cc" version = "1.0.50" @@ -43,6 +97,110 @@ name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "clap" +version = "2.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "criterion" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "criterion-plot" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "csv" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bstr 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ctor" version = "0.1.12" @@ -57,6 +215,11 @@ name = "difference" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "failure" version = "0.1.6" @@ -108,6 +271,7 @@ dependencies = [ name = "geo-booleanop-tests" version = "0.2.0" dependencies = [ + "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "geo 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "geo-booleanop 0.2.0", "geojson 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -142,6 +306,14 @@ name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hermit-abi" version = "0.1.6" @@ -150,16 +322,67 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "js-sys" +version = "0.3.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memoffset" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nom" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.2.11" @@ -177,6 +400,11 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "oorandom" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "output_vt100" version = "0.1.2" @@ -190,6 +418,17 @@ name = "pdqselect" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "plotters" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pretty_assertions" version = "0.6.1" @@ -251,6 +490,28 @@ name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rayon" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -259,6 +520,27 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-automata" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "robust" version = "0.1.2" @@ -279,16 +561,60 @@ name = "rustc-demangle" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ryu" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "serde" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "serde_derive" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" version = "1.0.44" @@ -299,6 +625,11 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sourcefile" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "syn" version = "1.0.14" @@ -320,6 +651,14 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "threadpool" version = "1.7.1" @@ -328,11 +667,129 @@ dependencies = [ "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tinytemplate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.58" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wasm-bindgen-webidl" +version = "0.2.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "web-sys" +version = "0.3.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "weedle" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.3.8" @@ -347,6 +804,14 @@ name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -354,13 +819,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" +"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum bstr 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" +"checksum bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" +"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1" +"checksum criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545" +"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" +"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" +"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" +"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" +"checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" +"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" "checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" @@ -368,13 +851,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum geo-types 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "866e8f6dbd2218b05ea8a25daa1bfac32b0515fe7e0a37cb6a7b9ed0ed82a07e" "checksum geojson 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22b37e57c7f498be81360116a489ebad0b133557e87d8b4f82d51bebd1c3ef9e" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" +"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53445de381a1f436797497c61d851644d0e8e88e6140f22872ad33a704933978" +"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" +"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" +"checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405" "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" "checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" +"checksum plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" @@ -382,17 +875,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" +"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" +"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" "checksum robust 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "222155e5550abd9100afdcdefbd08aa1b856d226b60e327044ec21b1ece2f78e" "checksum rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "120bfe4837befb82c5a637a5a8c490a27d25524ac19fffec5b4e555ca6e36ee8" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" +"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" "checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" +"checksum tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a" +"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" +"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" +"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" +"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" +"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" +"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" +"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" +"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/tests/Cargo.toml b/tests/Cargo.toml index cae7451..ca5e40e 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -16,3 +16,10 @@ serde_json = { version = "1.0.44", features = ["arbitrary_precision"] } num-traits = "0.2" glob = "0.3" pretty_assertions = "0.6" + +[dev-dependencies] +criterion = "0.3" + +[[bench]] +name = "benchmark" +harness = false diff --git a/tests/benches/benchmark.rs b/tests/benches/benchmark.rs new file mode 100644 index 0000000..b88528e --- /dev/null +++ b/tests/benches/benchmark.rs @@ -0,0 +1,20 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion, BatchSize}; + +use geo_booleanop::boolean::BooleanOp; +use geo_booleanop_tests::helper::load_test_case; + + +fn basics(c: &mut Criterion) { + c.bench_function("multiply", |b| b.iter_batched( + || load_test_case("fixtures/generic_test_cases/issue96.geojson"), + |(_, p1, p2)| p1.union(&p2), + BatchSize::LargeInput, + )); +} + + +criterion_group!( + benches, + basics, +); +criterion_main!(benches); diff --git a/tests/src/helper.rs b/tests/src/helper.rs index fa1d4ba..d890909 100644 --- a/tests/src/helper.rs +++ b/tests/src/helper.rs @@ -135,9 +135,7 @@ fn extract_expected_result(feature: &Feature) -> ExpectedResult { } } -pub fn run_generic_test_case(filename: &str, regenerate: bool) { - println!("\n *** Running test case: {}", filename); - +pub fn load_test_case(filename: &str) -> (Vec, MultiPolygon, MultiPolygon) { let original_geojson = load_fixture_from_path(filename); let features = match original_geojson { GeoJson::FeatureCollection(collection) => collection.features, @@ -146,6 +144,13 @@ pub fn run_generic_test_case(filename: &str, regenerate: bool) { assert!(features.len() >= 2); let p1 = extract_multi_polygon(&features[0]); let p2 = extract_multi_polygon(&features[1]); + (features, p1, p2) +} + +pub fn run_generic_test_case(filename: &str, regenerate: bool) { + println!("\n *** Running test case: {}", filename); + + let (features, p1, p2) = load_test_case(filename); let mut output_features: Vec = vec![features[0].clone(), features[1].clone()]; From afcec98e5a755879eee3136dc89d54a7d34f2573 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 23:41:20 +0100 Subject: [PATCH 08/21] added checkerboard test case --- .../generic_test_cases/checkerboard1.geojson | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/fixtures/generic_test_cases/checkerboard1.geojson diff --git a/tests/fixtures/generic_test_cases/checkerboard1.geojson b/tests/fixtures/generic_test_cases/checkerboard1.geojson new file mode 100644 index 0000000..0975d51 --- /dev/null +++ b/tests/fixtures/generic_test_cases/checkerboard1.geojson @@ -0,0 +1,33 @@ + +{ + "features": [ + { + "geometry": { + "coordinates": [[[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]], [[[0, 2], [0, 3], [1, 3], [1, 2], [0, 2]]], [[[1, 1], [1, 2], [2, 2], [2, 1], [1, 1]]], [[[2, 0], [2, 1], [3, 1], [3, 0], [2, 0]]], [[[2, 2], [2, 3], [3, 3], [3, 2], [2, 2]]]], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [[[[0, 1], [0, 2], [1, 2], [1, 1], [0, 1]]], [[[1, 0], [1, 1], [2, 1], [2, 0], [1, 0]]], [[[1, 2], [1, 3], [2, 3], [2, 2], [1, 2]]], [[[2, 1], [2, 2], [3, 2], [3, 1], [2, 1]]]], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} From ae3d20aa0b8600b99e0692289a1d2057b64804d9 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Thu, 20 Feb 2020 23:41:31 +0100 Subject: [PATCH 09/21] improved benchmarks --- lib/src/boolean/connect_edges.rs | 8 +++++--- lib/src/boolean/possible_intersection.rs | 10 ++++----- lib/src/boolean/segment_intersection.rs | 8 ++++---- lib/src/boolean/subdivide_segments.rs | 26 ++++++++++++------------ tests/benches/benchmark.rs | 21 +++++++++++-------- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/lib/src/boolean/connect_edges.rs b/lib/src/boolean/connect_edges.rs index f429b89..b7448dc 100644 --- a/lib/src/boolean/connect_edges.rs +++ b/lib/src/boolean/connect_edges.rs @@ -13,6 +13,7 @@ where for (pos, event) in sorted_events.iter().enumerate() { event.set_other_pos(pos as i32) } + /* for (i, r) in sorted_events.iter().enumerate() { println!("pos {:3} linked to {:3} {} {:?} => {:?} {:?}", i, @@ -24,7 +25,6 @@ where ); } - ///* for (pos, event) in sorted_events.iter().enumerate() { event.set_other_pos(-999); } @@ -33,7 +33,7 @@ where //assert_eq!(event.get_other_event().unwrap().get_other_pos(), -999); } } - //*/ + */ for event in sorted_events { if (event.is_left() && event.is_in_result()) @@ -68,6 +68,7 @@ where } } + /* for r in &result_events { println!("{:?}", r); debug_assert!(r.get_other_event().is_some()); @@ -82,6 +83,7 @@ where r.get_other_event().map(|o| o.point).unwrap(), ); } + */ result_events } @@ -243,7 +245,7 @@ where F: Float, { let result_events = order_events(sorted_events); - debug_print_results(&result_events); + // debug_print_results(&result_events); let mut contours: Vec> = Vec::new(); let mut processed: HashSet = HashSet::new(); diff --git a/lib/src/boolean/possible_intersection.rs b/lib/src/boolean/possible_intersection.rs index d189b96..61f32d4 100644 --- a/lib/src/boolean/possible_intersection.rs +++ b/lib/src/boolean/possible_intersection.rs @@ -19,10 +19,10 @@ where }; let inter = intersection(se1.point, other1.point, se2.point, other2.point); - println!("Intersection: {:?}", inter); + //println!("Intersection: {:?}", inter); match inter { LineIntersection::Point(inter) => { - println!("{{\"intersection\": {{\"x\": {}, \"y\": {}}}}}", inter.x, inter.y); + //println!("{{\"intersection\": {{\"x\": {}, \"y\": {}}}}}", inter.x, inter.y); }, _ => {} } @@ -30,11 +30,11 @@ where LineIntersection::None => 0, // No intersection LineIntersection::Point(_) if se1.point == se2.point && other1.point == other2.point => { - println!(" => line segments intersect at an endpoint of both line segments"); + //println!(" => line segments intersect at an endpoint of both line segments"); 0 }, // the line segments intersect at an endpoint of both line segments LineIntersection::Point(inter) => { - println!(" => point intersection"); + //println!(" => point intersection"); if se1.point != inter && other1.point != inter { divide_segment(&se1, inter, queue) } @@ -45,7 +45,7 @@ where } LineIntersection::Overlap(_, _) if se1.is_subject == se2.is_subject => 0, // The line segments associated to se1 and se2 overlap LineIntersection::Overlap(_, _) => { - println!(" => overlap"); + //println!(" => overlap"); let mut events = Vec::new(); let mut left_coincide = false; let mut right_coincide = false; diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index d207f52..a946447 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -110,7 +110,7 @@ fn intersection_impl( where F: Float, { - println!("{:?} {:?} {:?} {:?}", a1, a2, b1, b2); + //println!("{:?} {:?} {:?} {:?}", a1, a2, b1, b2); let va = Coordinate { x: a2.x - a1.x, y: a2.y - a1.y, @@ -138,15 +138,15 @@ where } if s == F::zero() || s == F::one() { - println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); + //println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(a1, s, va)); } if t == F::zero() || t == F::one() { - println!("t = {:?} => {:?}", s, mid_point(a1, s, va)); + //println!("t = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(b1, t, vb)); } - println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); + //println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(a1, s, va)); } diff --git a/lib/src/boolean/subdivide_segments.rs b/lib/src/boolean/subdivide_segments.rs index 702de10..3569a2a 100644 --- a/lib/src/boolean/subdivide_segments.rs +++ b/lib/src/boolean/subdivide_segments.rs @@ -23,12 +23,12 @@ where let rightbound = sbbox.max.x.min(cbbox.max.x); while let Some(event) = event_queue.pop() { - println!(""); - println!("size event queue begin iter: {}", event_queue.len()); - println!("{{\"processEvent\": {}}}", event.to_json_debug()); + //println!(""); + //println!("size event queue begin iter: {}", event_queue.len()); + //println!("{{\"processEvent\": {}}}", event.to_json_debug()); sorted_events.push(event.clone()); - println!("{} {}", event.point.x, rightbound); + //println!("{} {}", event.point.x, rightbound); if operation == Operation::Intersection && event.point.x > rightbound || operation == Operation::Difference && event.point.x > sbbox.max.x { @@ -44,19 +44,19 @@ where compute_fields(&event, maybe_prev, operation); if let Some(next) = maybe_next { - println!("{{\"seNextEvent\": {}}}", next.to_json_debug()); + //println!("{{\"seNextEvent\": {}}}", next.to_json_debug()); if possible_intersection(&event, &next, event_queue) == 2 { - println!("Intersection with next"); + //println!("Intersection with next"); compute_fields(&event, maybe_prev, operation); compute_fields(&event, Some(next), operation); } } if let Some(prev) = maybe_prev { - println!("{{\"sePrevEvent\": {}}}", prev.to_json_debug()); + //println!("{{\"sePrevEvent\": {}}}", prev.to_json_debug()); if possible_intersection(&prev, &event, event_queue) == 2 { let maybe_prev_prev = sweep_line.prev(&prev); - println!("Intersection with prev"); + //println!("Intersection with prev"); compute_fields(&prev, maybe_prev_prev, operation); compute_fields(&event, Some(prev), operation); } @@ -67,18 +67,18 @@ where let maybe_next = sweep_line.next(&other_event).cloned(); if let (Some(prev), Some(next)) = (maybe_prev, maybe_next) { - println!("Possible post intersection"); - println!("{{\"sePostNextEvent\": {}}}", next.to_json_debug()); - println!("{{\"sePostPrevEvent\": {}}}", prev.to_json_debug()); + //println!("Possible post intersection"); + //println!("{{\"sePostNextEvent\": {}}}", next.to_json_debug()); + //println!("{{\"sePostPrevEvent\": {}}}", prev.to_json_debug()); possible_intersection(&prev, &next, event_queue); } - println!("{{\"removing\": {}}}", other_event.to_json_debug()); + //println!("{{\"removing\": {}}}", other_event.to_json_debug()); sweep_line.remove(&other_event); } } - println!("size event queue end iter: {}", event_queue.len()); + // println!("size event queue end iter: {}", event_queue.len()); //let s: Vec = &sweep_line.into_iter().map(|e| e.to_json_debug()).collect(); //let s = s.join(", "); diff --git a/tests/benches/benchmark.rs b/tests/benches/benchmark.rs index b88528e..94cc830 100644 --- a/tests/benches/benchmark.rs +++ b/tests/benches/benchmark.rs @@ -1,20 +1,25 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion, BatchSize}; +use criterion::{criterion_group, criterion_main, Criterion}; use geo_booleanop::boolean::BooleanOp; use geo_booleanop_tests::helper::load_test_case; +fn benchmarks(c: &mut Criterion) { + let (_, p1, p2) = load_test_case("fixtures/generic_test_cases/issue96.geojson"); + c.bench_function("issue96 - intersection", |b| b.iter( + || p1.intersection(&p2), + )); + c.bench_function("issue96 - union", |b| b.iter( + || p1.union(&p2), + )); -fn basics(c: &mut Criterion) { - c.bench_function("multiply", |b| b.iter_batched( - || load_test_case("fixtures/generic_test_cases/issue96.geojson"), - |(_, p1, p2)| p1.union(&p2), - BatchSize::LargeInput, + let (_, p1, p2) = load_test_case("fixtures/generic_test_cases/checkerboard1.geojson"); + c.bench_function("checkerboard1 - union", |b| b.iter( + || p1.union(&p2), )); } - criterion_group!( benches, - basics, + benchmarks, ); criterion_main!(benches); From 468471de5bfab126c2a58eb6f8d26eacd797f5e6 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Fri, 21 Feb 2020 08:34:38 +0100 Subject: [PATCH 10/21] updated test fixture --- .../generic_test_cases/checkerboard1.geojson | 107 +++++++++++++++++- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/tests/fixtures/generic_test_cases/checkerboard1.geojson b/tests/fixtures/generic_test_cases/checkerboard1.geojson index 0975d51..9c55a5a 100644 --- a/tests/fixtures/generic_test_cases/checkerboard1.geojson +++ b/tests/fixtures/generic_test_cases/checkerboard1.geojson @@ -1,9 +1,54 @@ - { "features": [ { "geometry": { - "coordinates": [[[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]], [[[0, 2], [0, 3], [1, 3], [1, 2], [0, 2]]], [[[1, 1], [1, 2], [2, 2], [2, 1], [1, 1]]], [[[2, 0], [2, 1], [3, 1], [3, 0], [2, 0]]], [[[2, 2], [2, 3], [3, 3], [3, 2], [2, 2]]]], + "coordinates": [ + [ + [ + [0, 0], + [0, 1], + [1, 1], + [1, 0], + [0, 0] + ] + ], + [ + [ + [0, 2], + [0, 3], + [1, 3], + [1, 2], + [0, 2] + ] + ], + [ + [ + [1, 1], + [1, 2], + [2, 2], + [2, 1], + [1, 1] + ] + ], + [ + [ + [2, 0], + [2, 1], + [3, 1], + [3, 0], + [2, 0] + ] + ], + [ + [ + [2, 2], + [2, 3], + [3, 3], + [3, 2], + [2, 2] + ] + ] + ], "type": "MultiPolygon" }, "properties": {}, @@ -11,7 +56,44 @@ }, { "geometry": { - "coordinates": [[[[0, 1], [0, 2], [1, 2], [1, 1], [0, 1]]], [[[1, 0], [1, 1], [2, 1], [2, 0], [1, 0]]], [[[1, 2], [1, 3], [2, 3], [2, 2], [1, 2]]], [[[2, 1], [2, 2], [3, 2], [3, 1], [2, 1]]]], + "coordinates": [ + [ + [ + [0, 1], + [0, 2], + [1, 2], + [1, 1], + [0, 1] + ] + ], + [ + [ + [1, 0], + [1, 1], + [2, 1], + [2, 0], + [1, 0] + ] + ], + [ + [ + [1, 2], + [1, 3], + [2, 3], + [2, 2], + [1, 2] + ] + ], + [ + [ + [2, 1], + [2, 2], + [3, 2], + [3, 1], + [2, 1] + ] + ] + ], "type": "MultiPolygon" }, "properties": {}, @@ -20,6 +102,23 @@ { "geometry": { "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [2, 0], + [3, 0], + [3, 1], + [3, 2], + [3, 3], + [2, 3], + [1, 3], + [0, 3], + [0, 2], + [0, 1], + [0, 0] + ] + ] ], "type": "MultiPolygon" }, @@ -29,5 +128,5 @@ "type": "Feature" } ], - "type": "FeatureCollection" + "type": "FeatureCollection" } From c9762f62aad6fdcf834ad0c51bf1b73a225066da Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Fri, 21 Feb 2020 08:34:50 +0100 Subject: [PATCH 11/21] improved test syntax --- lib/src/boolean/segment_intersection.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index a946447..17a3ee5 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -210,6 +210,10 @@ mod test { use super::super::helper::test::xy; use super::*; + fn rect(min: Coordinate, max: Coordinate) -> Rect { + Rect { min, max } + } + #[test] fn test_get_intersection_bounding_box() { assert_eq!( @@ -241,19 +245,19 @@ mod test { #[test] fn test_constrain_to_bounding_box() { assert_eq!( - constrain_to_bounding_box(xy(100, 0), Rect{min: xy(-1, -1), max: xy(1, 1)}), + constrain_to_bounding_box(xy(100, 0), rect(xy(-1, -1), xy(1, 1))), xy(1, 0), ); assert_eq!( - constrain_to_bounding_box(xy(-100, 0), Rect{min: xy(-1, -1), max: xy(1, 1)}), + constrain_to_bounding_box(xy(-100, 0), rect(xy(-1, -1), xy(1, 1))), xy(-1, 0), ); assert_eq!( - constrain_to_bounding_box(xy(0, 100), Rect{min: xy(-1, -1), max: xy(1, 1)}), + constrain_to_bounding_box(xy(0, 100), rect(xy(-1, -1), xy(1, 1))), xy(0, 1), ); assert_eq!( - constrain_to_bounding_box(xy(0, -100), Rect{min: xy(-1, -1), max: xy(1, 1)}), + constrain_to_bounding_box(xy(0, -100), rect(xy(-1, -1), xy(1, 1))), xy(0, -1), ); } From 766c2c2527b84c2aca00cb2bc7147c876feb9d6d Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Fri, 21 Feb 2020 08:36:23 +0100 Subject: [PATCH 12/21] applied cargo fmt --- lib/src/boolean/connect_edges.rs | 7 +-- lib/src/boolean/helper.rs | 2 +- lib/src/boolean/possible_intersection.rs | 7 ++- lib/src/boolean/segment_intersection.rs | 54 +++++++++++------------- lib/src/boolean/subdivide_segments.rs | 3 +- lib/src/boolean/sweep_event.rs | 3 +- tests/benches/benchmark.rs | 6 +-- 7 files changed, 36 insertions(+), 46 deletions(-) diff --git a/lib/src/boolean/connect_edges.rs b/lib/src/boolean/connect_edges.rs index b7448dc..2ce0b50 100644 --- a/lib/src/boolean/connect_edges.rs +++ b/lib/src/boolean/connect_edges.rs @@ -96,9 +96,11 @@ where F: Float, { let mut writer = File::create("debug.csv").unwrap(); - writeln!(&mut writer, + writeln!( + &mut writer, "index;x;y;other_x;other_y;lr;result_transition;in_out;other_in_out;is_subject;is_exterior_ring;prev_in_result" - ).expect("Failed to write to file"); + ) + .expect("Failed to write to file"); for (i, evt) in events.iter().enumerate() { writeln!(&mut writer, "{i};{x:?};{y:?};{other_x:?};{other_y:?};{lr};{transition:?};{in_out};{other_in_out};{subject};{exterior_ring};{prev_in_result:?}", i=i, @@ -117,7 +119,6 @@ where } } - fn next_pos(pos: i32, result_events: &[Rc>], processed: &HashSet, orig_pos: i32) -> i32 where F: Float, diff --git a/lib/src/boolean/helper.rs b/lib/src/boolean/helper.rs index 3d0167f..479f41b 100644 --- a/lib/src/boolean/helper.rs +++ b/lib/src/boolean/helper.rs @@ -1,7 +1,7 @@ +use libc::{c_double, c_float}; use num_traits::Float as NumTraitsFloat; use std::cmp::Ordering; use std::fmt::{Debug, Display}; -use libc::{c_double, c_float}; use std::{f32, f64}; #[link_name = "m"] diff --git a/lib/src/boolean/possible_intersection.rs b/lib/src/boolean/possible_intersection.rs index 61f32d4..2d9ba54 100644 --- a/lib/src/boolean/possible_intersection.rs +++ b/lib/src/boolean/possible_intersection.rs @@ -23,16 +23,15 @@ where match inter { LineIntersection::Point(inter) => { //println!("{{\"intersection\": {{\"x\": {}, \"y\": {}}}}}", inter.x, inter.y); - }, + } _ => {} } match inter { LineIntersection::None => 0, // No intersection - LineIntersection::Point(_) if se1.point == se2.point && other1.point == other2.point => - { + LineIntersection::Point(_) if se1.point == se2.point && other1.point == other2.point => { //println!(" => line segments intersect at an endpoint of both line segments"); 0 - }, // the line segments intersect at an endpoint of both line segments + } // the line segments intersect at an endpoint of both line segments LineIntersection::Point(inter) => { //println!(" => point intersection"); if se1.point != inter && other1.point != inter { diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index 17a3ee5..92bb9ac 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -21,34 +21,24 @@ fn get_intersection_bounding_box( where F: Float, { - let (a_start_x, a_end_x) = if a1.x < a2.x { - (a1.x, a2.x) - } else { - (a2.x, a1.x) - }; - let (a_start_y, a_end_y) = if a1.y < a2.y { - (a1.y, a2.y) - } else { - (a2.y, a1.y) - }; - let (b_start_x, b_end_x) = if b1.x < b2.x { - (b1.x, b2.x) - } else { - (b2.x, b1.x) - }; - let (b_start_y, b_end_y) = if b1.y < b2.y { - (b1.y, b2.y) - } else { - (b2.y, b1.y) - }; + let (a_start_x, a_end_x) = if a1.x < a2.x { (a1.x, a2.x) } else { (a2.x, a1.x) }; + let (a_start_y, a_end_y) = if a1.y < a2.y { (a1.y, a2.y) } else { (a2.y, a1.y) }; + let (b_start_x, b_end_x) = if b1.x < b2.x { (b1.x, b2.x) } else { (b2.x, b1.x) }; + let (b_start_y, b_end_y) = if b1.y < b2.y { (b1.y, b2.y) } else { (b2.y, b1.y) }; let interval_start_x = a_start_x.max(b_start_x); let interval_start_y = a_start_y.max(b_start_y); let interval_end_x = a_end_x.min(b_end_x); 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(Rect{ - min: Coordinate{x: interval_start_x, y: interval_start_y}, - max: Coordinate{x: interval_end_x, y: interval_end_y}, + Some(Rect { + min: Coordinate { + x: interval_start_x, + y: interval_start_y, + }, + max: Coordinate { + x: interval_end_x, + y: interval_end_y, + }, }) } else { None @@ -60,7 +50,7 @@ fn constrain_to_bounding_box(p: Coordinate, bb: Rect) -> Coordinate where F: Float, { - Coordinate{ + Coordinate { x: if p.x < bb.min.x { bb.min.x } else if p.x > bb.max.x { @@ -91,10 +81,8 @@ where if let Some(bb) = bb { let inter = intersection_impl(a1, a2, b1, b2); match inter { - LineIntersection::Point(p) => { - LineIntersection::Point(constrain_to_bounding_box(p, bb)) - }, - _ => inter + LineIntersection::Point(p) => LineIntersection::Point(constrain_to_bounding_box(p, bb)), + _ => inter, } } else { LineIntersection::None @@ -218,11 +206,17 @@ mod test { fn test_get_intersection_bounding_box() { assert_eq!( get_intersection_bounding_box(xy(0, 0), xy(2, 2), xy(1, 1), xy(3, 3)), - Some(Rect{min: xy(1, 1), max: xy(2, 2)}), + Some(Rect { + min: xy(1, 1), + max: xy(2, 2) + }), ); assert_eq!( get_intersection_bounding_box(xy(-1, 0), xy(1, 0), xy(0, -1), xy(0, 1)), - Some(Rect{min: xy(0, 0), max: xy(0, 0)}), + Some(Rect { + min: xy(0, 0), + max: xy(0, 0) + }), ); assert_eq!( get_intersection_bounding_box(xy(0, 0), xy(1, 1), xy(2, 0), xy(3, 1)), diff --git a/lib/src/boolean/subdivide_segments.rs b/lib/src/boolean/subdivide_segments.rs index 3569a2a..5f3f286 100644 --- a/lib/src/boolean/subdivide_segments.rs +++ b/lib/src/boolean/subdivide_segments.rs @@ -2,7 +2,7 @@ use super::compare_segments::compare_segments; use super::compute_fields::compute_fields; use super::helper::Float; use super::possible_intersection::possible_intersection; -use super::sweep_event::{SweepEvent, JsonDebug}; +use super::sweep_event::{JsonDebug, SweepEvent}; use super::Operation; use crate::splay::SplaySet; use geo_types::Rect; @@ -83,7 +83,6 @@ where //let s: Vec = &sweep_line.into_iter().map(|e| e.to_json_debug()).collect(); //let s = s.join(", "); //println!("{{\"sweepLineState\": {{{}}}}}", s); - } sorted_events diff --git a/lib/src/boolean/sweep_event.rs b/lib/src/boolean/sweep_event.rs index 32eb90e..e0a21b2 100644 --- a/lib/src/boolean/sweep_event.rs +++ b/lib/src/boolean/sweep_event.rs @@ -249,13 +249,12 @@ where } } - pub trait JsonDebug { fn to_json_debug(&self) -> String; fn to_json_debug_short(&self) -> String; } -impl JsonDebug for Rc::> +impl JsonDebug for Rc> where F: Float, { diff --git a/tests/benches/benchmark.rs b/tests/benches/benchmark.rs index 94cc830..dca80bc 100644 --- a/tests/benches/benchmark.rs +++ b/tests/benches/benchmark.rs @@ -3,6 +3,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use geo_booleanop::boolean::BooleanOp; use geo_booleanop_tests::helper::load_test_case; +#[rustfmt::skip] fn benchmarks(c: &mut Criterion) { let (_, p1, p2) = load_test_case("fixtures/generic_test_cases/issue96.geojson"); c.bench_function("issue96 - intersection", |b| b.iter( @@ -18,8 +19,5 @@ fn benchmarks(c: &mut Criterion) { )); } -criterion_group!( - benches, - benchmarks, -); +criterion_group!(benches, benchmarks,); criterion_main!(benches); From 656cdc7004cdbb0b20bb333fcdfd49ec8b7ea1b9 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Fri, 21 Feb 2020 22:34:13 +0100 Subject: [PATCH 13/21] added many rects test case --- .../generic_test_cases/many_rects.geojson | 560 ++++++++++++++++++ 1 file changed, 560 insertions(+) create mode 100644 tests/fixtures/generic_test_cases/many_rects.geojson diff --git a/tests/fixtures/generic_test_cases/many_rects.geojson b/tests/fixtures/generic_test_cases/many_rects.geojson new file mode 100644 index 0000000..9948719 --- /dev/null +++ b/tests/fixtures/generic_test_cases/many_rects.geojson @@ -0,0 +1,560 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [-26.597314681745367, 29.529910098954016], + [-26.597314681745367, 54.06661431069178], + [-6.593883437225022, 54.06661431069178], + [-6.593883437225022, 29.529910098954016], + [-26.597314681745367, 29.529910098954016] + ] + ], + [ + [ + [-83.44272500724244, -96.71569195188616], + [-83.44272500724244, -68.73837787557538], + [-57.85491866591232, -68.73837787557538], + [-57.85491866591232, -96.71569195188616], + [-83.44272500724244, -96.71569195188616] + ] + ], + [ + [ + [-36.93442286991544, -12.514945705280006], + [-36.93442286991544, 24.051264516720806], + [-4.358587437816595, 24.051264516720806], + [-4.358587437816595, -12.514945705280006], + [-36.93442286991544, -12.514945705280006] + ] + ], + [ + [ + [-69.52036395166542, 55.56647462551305], + [-69.52036395166542, 86.03430117615798], + [-48.69873615572762, 86.03430117615798], + [-48.69873615572762, 55.56647462551305], + [-69.52036395166542, 55.56647462551305] + ] + ], + [ + [ + [45.44755106271869, 73.26747590883977], + [45.44755106271869, 108.35367781626813], + [74.85027640749597, 108.35367781626813], + [74.85027640749597, 73.26747590883977], + [45.44755106271869, 73.26747590883977] + ] + ], + [ + [ + [71.1997493208433, -8.099677470487537], + [71.1997493208433, 27.011213703860506], + [111.95606273935749, 27.011213703860506], + [111.95606273935749, -8.099677470487537], + [71.1997493208433, -8.099677470487537] + ] + ], + [ + [ + [83.56555790033286, 27.79394094919555], + [83.56555790033286, 63.83979075693396], + [111.978877662265, 63.83979075693396], + [111.978877662265, 27.79394094919555], + [83.56555790033286, 27.79394094919555] + ] + ], + [ + [ + [-102.98373123086805, -24.82550699042416], + [-102.98373123086805, 13.207637781577468], + [-55.72586613807517, 13.207637781577468], + [-55.72586613807517, -24.82550699042416], + [-102.98373123086805, -24.82550699042416] + ] + ], + [ + [ + [-52.735436650784706, -94.17681857044283], + [-52.735436650784706, -63.70378120829001], + [-32.15442791467579, -63.70378120829001], + [-32.15442791467579, -94.17681857044283], + [-52.735436650784706, -94.17681857044283] + ] + ], + [ + [ + [-75.04797418919327, -57.691106302310956], + [-75.04797418919327, -29.51707073634968], + [-40.30077941078312, -29.51707073634968], + [-40.30077941078312, -57.691106302310956], + [-75.04797418919327, -57.691106302310956] + ] + ], + [ + [ + [-4.016061955146654, -91.15066041915193], + [-4.016061955146654, -51.814701965288705], + [33.66310415195187, -51.814701965288705], + [33.66310415195187, -91.15066041915193], + [-4.016061955146654, -91.15066041915193] + ] + ], + [ + [ + [64.23953453216444, -51.33679783115546], + [64.23953453216444, -9.184646503856357], + [106.7638976262491, -9.184646503856357], + [106.7638976262491, -51.33679783115546], + [64.23953453216444, -51.33679783115546] + ] + ], + [ + [ + [20.967109969388986, 0.09680516121828475], + [20.967109969388986, 36.06033363612498], + [44.40948915799024, 36.06033363612498], + [44.40948915799024, 0.09680516121828475], + [20.967109969388986, 0.09680516121828475] + ] + ], + [ + [ + [-106.4485705523528, -108.45096863850183], + [-106.4485705523528, -84.33320530414423], + [-85.59937591172897, -84.33320530414423], + [-85.59937591172897, -108.45096863850183], + [-106.4485705523528, -108.45096863850183] + ] + ], + [ + [ + [-2.3151794376090713, -45.151781938887446], + [-2.3151794376090713, -5.707542188521462], + [34.213267135927836, -5.707542188521462], + [34.213267135927836, -45.151781938887446], + [-2.3151794376090713, -45.151781938887446] + ] + ], + [ + [ + [-9.01538973255993, 73.97217771960979], + [-9.01538973255993, 98.9110456371768], + [18.8835133820534, 98.9110456371768], + [18.8835133820534, 73.97217771960979], + [-9.01538973255993, 73.97217771960979] + ] + ], + [ + [ + [-118.1017710127214, 79.36875753240436], + [-118.1017710127214, 112.00077431109719], + [-73.28830687759941, 112.00077431109719], + [-73.28830687759941, 79.36875753240436], + [-118.1017710127214, 79.36875753240436] + ] + ], + [ + [ + [46.77720768399456, 6.103330208969805], + [46.77720768399456, 33.21487449009308], + [68.39448584620715, 33.21487449009308], + [68.39448584620715, 6.103330208969805], + [46.77720768399456, 6.103330208969805] + ] + ], + [ + [ + [38.36947132888091, -114.06168503676605], + [38.36947132888091, -71.53217500734846], + [81.47663336553032, -71.53217500734846], + [81.47663336553032, -114.06168503676605], + [38.36947132888091, -114.06168503676605] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-31.045956739779893, -111.34458952369589], + [-31.045956739779893, -76.5698164662411], + [5.443917596581382, -76.5698164662411], + [5.443917596581382, -111.34458952369589], + [-31.045956739779893, -111.34458952369589] + ] + ], + [ + [ + [-28.996169093069835, -53.22210029448514], + [-28.996169093069835, -20.863306288657544], + [-2.856710071934561, -20.863306288657544], + [-2.856710071934561, -53.22210029448514], + [-28.996169093069835, -53.22210029448514] + ] + ], + [ + [ + [-85.85060891571703, -19.064402964100815], + [-85.85060891571703, 15.482222237853016], + [-60.31741294630957, 15.482222237853016], + [-60.31741294630957, -19.064402964100815], + [-85.85060891571703, -19.064402964100815] + ] + ], + [ + [ + [48.09663624753574, -12.347314678750358], + [48.09663624753574, 21.545789756747578], + [93.49348080825979, 21.545789756747578], + [93.49348080825979, -12.347314678750358], + [48.09663624753574, -12.347314678750358] + ] + ], + [ + [ + [10.502794242704738, -19.189422656428057], + [10.502794242704738, 14.192517910628567], + [45.65989584326121, 14.192517910628567], + [45.65989584326121, -19.189422656428057], + [10.502794242704738, -19.189422656428057] + ] + ], + [ + [ + [-11.042287702690274, 79.51702155484796], + [-11.042287702690274, 108.91156779119486], + [25.28395710175279, 108.91156779119486], + [25.28395710175279, 79.51702155484796], + [-11.042287702690274, 79.51702155484796] + ] + ], + [ + [ + [-56.74471785295343, -5.871809418608157], + [-56.74471785295343, 20.162739276914227], + [-26.045989419270658, 20.162739276914227], + [-26.045989419270658, -5.871809418608157], + [-56.74471785295343, -5.871809418608157] + ] + ], + [ + [ + [79.88326004851928, -88.07172259961536], + [79.88326004851928, -62.74587902594], + [109.28101590141068, -62.74587902594], + [109.28101590141068, -88.07172259961536], + [79.88326004851928, -88.07172259961536] + ] + ], + [ + [ + [32.56788256521246, -94.44082653981461], + [32.56788256521246, -50.17540896918061], + [78.63538135817483, -50.17540896918061], + [78.63538135817483, -94.44082653981461], + [32.56788256521246, -94.44082653981461] + ] + ], + [ + [ + [-4.105611440486628, 27.104716774312433], + [-4.105611440486628, 53.591291416671595], + [23.26872347663729, 53.591291416671595], + [23.26872347663729, 27.104716774312433], + [-4.105611440486628, 27.104716774312433] + ] + ], + [ + [ + [-88.03712103176164, -64.628545335233], + [-88.03712103176164, -35.0343989017954], + [-67.72961984977391, -35.0343989017954], + [-67.72961984977391, -64.628545335233], + [-88.03712103176164, -64.628545335233] + ] + ], + [ + [ + [58.28960182150006, 84.22016638529041], + [58.28960182150006, 108.43496145027315], + [79.7556444083806, 108.43496145027315], + [79.7556444083806, 84.22016638529041], + [58.28960182150006, 84.22016638529041] + ] + ], + [ + [ + [-65.39863188614781, 30.466657576177056], + [-65.39863188614781, 52.23893745910868], + [-42.77175661611412, 52.23893745910868], + [-42.77175661611412, 30.466657576177056], + [-65.39863188614781, 30.466657576177056] + ] + ], + [ + [ + [37.975900373468406, 31.06938599432022], + [37.975900373468406, 72.96228118156726], + [73.05926294874506, 72.96228118156726], + [73.05926294874506, 31.06938599432022], + [37.975900373468406, 31.06938599432022] + ] + ], + [ + [ + [-122.41708468736738, -106.4917844893181], + [-122.41708468736738, -70.85295786271888], + [-74.20356988110473, -70.85295786271888], + [-74.20356988110473, -106.4917844893181], + [-122.41708468736738, -106.4917844893181] + ] + ], + [ + [ + [-73.29285791589336, 61.93253055100797], + [-73.29285791589336, 99.79650168158152], + [-26.193973401222905, 99.79650168158152], + [-26.193973401222905, 61.93253055100797], + [-73.29285791589336, 61.93253055100797] + ] + ], + [ + [ + [0.8314432196819013, -61.25643804419643], + [0.8314432196819013, -33.18029135087673], + [28.293471886460807, -33.18029135087673], + [28.293471886460807, -61.25643804419643], + [0.8314432196819013, -61.25643804419643] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-122.41708468736738, -106.4917844893181], + [-106.4485705523528, -106.4917844893181], + [-106.4485705523528, -108.45096863850183], + [-85.59937591172897, -108.45096863850183], + [-85.59937591172897, -106.4917844893181], + [-74.20356988110473, -106.4917844893181], + [-74.20356988110473, -96.71569195188616], + [-57.85491866591232, -96.71569195188616], + [-57.85491866591232, -68.73837787557538], + [-83.44272500724244, -68.73837787557538], + [-83.44272500724244, -70.85295786271888], + [-122.41708468736738, -70.85295786271888], + [-122.41708468736738, -106.4917844893181] + ] + ], + [ + [ + [-118.1017710127214, 79.36875753240436], + [-73.29285791589336, 79.36875753240436], + [-73.29285791589336, 61.93253055100797], + [-69.52036395166542, 61.93253055100797], + [-69.52036395166542, 55.56647462551305], + [-48.69873615572762, 55.56647462551305], + [-48.69873615572762, 61.93253055100797], + [-26.193973401222905, 61.93253055100797], + [-26.193973401222905, 99.79650168158152], + [-73.28830687759941, 99.79650168158152], + [-73.28830687759941, 112.00077431109719], + [-118.1017710127214, 112.00077431109719], + [-118.1017710127214, 79.36875753240436] + ] + ], + [ + [ + [-102.98373123086805, -24.82550699042416], + [-55.72586613807517, -24.82550699042416], + [-55.72586613807517, -5.871809418608157], + [-36.93442286991544, -5.871809418608157], + [-36.93442286991544, -12.514945705280006], + [-4.358587437816595, -12.514945705280006], + [-4.358587437816595, 24.051264516720806], + [-36.93442286991544, 24.051264516720806], + [-36.93442286991544, 20.162739276914227], + [-56.74471785295343, 20.162739276914227], + [-56.74471785295343, 13.207637781577468], + [-60.31741294630957, 13.207637781577468], + [-60.31741294630957, 15.482222237853016], + [-85.85060891571703, 15.482222237853016], + [-85.85060891571703, 13.207637781577468], + [-102.98373123086805, 13.207637781577468], + [-102.98373123086805, -24.82550699042416] + ] + ], + [ + [ + [-88.03712103176164, -64.628545335233], + [-67.72961984977391, -64.628545335233], + [-67.72961984977391, -57.691106302310956], + [-40.30077941078312, -57.691106302310956], + [-40.30077941078312, -29.51707073634968], + [-75.04797418919327, -29.51707073634968], + [-75.04797418919327, -35.0343989017954], + [-88.03712103176164, -35.0343989017954], + [-88.03712103176164, -64.628545335233] + ] + ], + [ + [ + [-65.39863188614781, 30.466657576177056], + [-42.77175661611412, 30.466657576177056], + [-42.77175661611412, 52.23893745910868], + [-65.39863188614781, 52.23893745910868], + [-65.39863188614781, 30.466657576177056] + ] + ], + [ + [ + [-52.735436650784706, -94.17681857044283], + [-32.15442791467579, -94.17681857044283], + [-32.15442791467579, -63.70378120829001], + [-52.735436650784706, -63.70378120829001], + [-52.735436650784706, -94.17681857044283] + ] + ], + [ + [ + [-31.045956739779893, -111.34458952369589], + [5.443917596581382, -111.34458952369589], + [5.443917596581382, -91.15066041915193], + [32.56788256521246, -91.15066041915193], + [32.56788256521246, -94.44082653981461], + [38.36947132888091, -94.44082653981461], + [38.36947132888091, -114.06168503676605], + [81.47663336553032, -114.06168503676605], + [81.47663336553032, -88.07172259961536], + [109.28101590141068, -88.07172259961536], + [109.28101590141068, -62.74587902594], + [79.88326004851928, -62.74587902594], + [79.88326004851928, -71.53217500734846], + [78.63538135817483, -71.53217500734846], + [78.63538135817483, -51.33679783115546], + [106.7638976262491, -51.33679783115546], + [106.7638976262491, -9.184646503856357], + [93.49348080825979, -9.184646503856357], + [93.49348080825979, -8.099677470487537], + [111.95606273935749, -8.099677470487537], + [111.95606273935749, 27.011213703860506], + [71.1997493208433, 27.011213703860506], + [71.1997493208433, 21.545789756747578], + [68.39448584620715, 21.545789756747578], + [68.39448584620715, 31.06938599432022], + [73.05926294874506, 31.06938599432022], + [73.05926294874506, 72.96228118156726], + [37.975900373468406, 72.96228118156726], + [37.975900373468406, 36.06033363612498], + [23.26872347663729, 36.06033363612498], + [23.26872347663729, 53.591291416671595], + [-4.105611440486628, 53.591291416671595], + [-4.105611440486628, 27.104716774312433], + [20.967109969388986, 27.104716774312433], + [20.967109969388986, 14.192517910628567], + [10.502794242704738, 14.192517910628567], + [10.502794242704738, -5.707542188521462], + [-2.3151794376090713, -5.707542188521462], + [-2.3151794376090713, -45.151781938887446], + [0.8314432196819013, -45.151781938887446], + [0.8314432196819013, -51.814701965288705], + [-2.856710071934561, -51.814701965288705], + [-2.856710071934561, -20.863306288657544], + [-28.996169093069835, -20.863306288657544], + [-28.996169093069835, -53.22210029448514], + [-4.016061955146654, -53.22210029448514], + [-4.016061955146654, -76.5698164662411], + [-31.045956739779893, -76.5698164662411], + [-31.045956739779893, -111.34458952369589] + ], + [ + [28.293471886460807, -51.814701965288705], + [32.56788256521246, -51.814701965288705], + [32.56788256521246, -50.17540896918061], + [64.23953453216444, -50.17540896918061], + [64.23953453216444, -12.347314678750358], + [48.09663624753574, -12.347314678750358], + [48.09663624753574, 6.103330208969805], + [46.77720768399456, 6.103330208969805], + [46.77720768399456, 31.06938599432022], + [44.40948915799024, 31.06938599432022], + [44.40948915799024, 14.192517910628567], + [45.65989584326121, 14.192517910628567], + [45.65989584326121, -19.189422656428057], + [34.213267135927836, -19.189422656428057], + [34.213267135927836, -45.151781938887446], + [28.293471886460807, -45.151781938887446], + [28.293471886460807, -51.814701965288705] + ] + ], + [ + [ + [-26.597314681745367, 29.529910098954016], + [-6.593883437225022, 29.529910098954016], + [-6.593883437225022, 54.06661431069178], + [-26.597314681745367, 54.06661431069178], + [-26.597314681745367, 29.529910098954016] + ] + ], + [ + [ + [-11.042287702690274, 79.51702155484796], + [-9.01538973255993, 79.51702155484796], + [-9.01538973255993, 73.97217771960979], + [18.8835133820534, 73.97217771960979], + [18.8835133820534, 79.51702155484796], + [25.28395710175279, 79.51702155484796], + [25.28395710175279, 108.91156779119486], + [-11.042287702690274, 108.91156779119486], + [-11.042287702690274, 79.51702155484796] + ] + ], + [ + [ + [45.44755106271869, 73.26747590883977], + [74.85027640749597, 73.26747590883977], + [74.85027640749597, 84.22016638529041], + [79.7556444083806, 84.22016638529041], + [79.7556444083806, 108.43496145027315], + [58.28960182150006, 108.43496145027315], + [58.28960182150006, 108.35367781626813], + [45.44755106271869, 108.35367781626813], + [45.44755106271869, 73.26747590883977] + ] + ], + [ + [ + [83.56555790033286, 27.79394094919555], + [111.978877662265, 27.79394094919555], + [111.978877662265, 63.83979075693396], + [83.56555790033286, 63.83979075693396], + [83.56555790033286, 27.79394094919555] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} From 302a5e647980a0c1de0b7a22b58b9498b2f60893 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Fri, 21 Feb 2020 23:51:32 +0100 Subject: [PATCH 14/21] more benchmarks; better test cases --- lib/src/boolean/segment_intersection.rs | 12 ++++++++---- tests/benches/benchmark.rs | 9 +++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index 92bb9ac..465edd0 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -98,7 +98,7 @@ fn intersection_impl( where F: Float, { - //println!("{:?} {:?} {:?} {:?}", a1, a2, b1, b2); + // println!("{:?} {:?} {:?} {:?}", a1, a2, b1, b2); let va = Coordinate { x: a2.x - a1.x, y: a2.y - a1.y, @@ -117,24 +117,23 @@ where if sqr_kross > F::zero() { let s = cross_product(e, vb) / kross; + // println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); if s < F::zero() || s > F::one() { return LineIntersection::None; } let t = cross_product(e, va) / kross; + // println!("t = {:?} => {:?}", t, mid_point(b1, t, va)); if t < F::zero() || t > F::one() { return LineIntersection::None; } if s == F::zero() || s == F::one() { - //println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(a1, s, va)); } if t == F::zero() || t == F::one() { - //println!("t = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(b1, t, vb)); } - //println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); return LineIntersection::Point(mid_point(a1, s, va)); } @@ -340,5 +339,10 @@ mod test { intersection(xy(0, 0.5), xy(1, 1.5), xy(0, 1), xy(1, 0)), LineIntersection::Point(xy(0.25, 0.75)) ); + + assert_eq!( + intersection(xy(0, 0), xy(1, 0), xy(1, -1), xy(2, 1)), + LineIntersection::None + ); } } diff --git a/tests/benches/benchmark.rs b/tests/benches/benchmark.rs index dca80bc..56a40a6 100644 --- a/tests/benches/benchmark.rs +++ b/tests/benches/benchmark.rs @@ -5,16 +5,17 @@ use geo_booleanop_tests::helper::load_test_case; #[rustfmt::skip] fn benchmarks(c: &mut Criterion) { + let (_, p1, p2) = load_test_case("fixtures/generic_test_cases/issue96.geojson"); - c.bench_function("issue96 - intersection", |b| b.iter( + c.bench_function("issue96 / intersection", |b| b.iter( || p1.intersection(&p2), )); - c.bench_function("issue96 - union", |b| b.iter( + c.bench_function("issue96 / union", |b| b.iter( || p1.union(&p2), )); - let (_, p1, p2) = load_test_case("fixtures/generic_test_cases/checkerboard1.geojson"); - c.bench_function("checkerboard1 - union", |b| b.iter( + let (_, p1, p2) = load_test_case("fixtures/generic_test_cases/many_rects.geojson"); + c.bench_function("many_rects / union", |b| b.iter( || p1.union(&p2), )); } From a07f95eba7e2be8556f464189a5273eb1192bab3 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sat, 22 Feb 2020 10:06:55 +0100 Subject: [PATCH 15/21] documented rational behind new divide logic --- lib/src/boolean/divide_segment.rs | 63 ++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/lib/src/boolean/divide_segment.rs b/lib/src/boolean/divide_segment.rs index f3e548c..904d65f 100644 --- a/lib/src/boolean/divide_segment.rs +++ b/lib/src/boolean/divide_segment.rs @@ -4,43 +4,78 @@ use geo_types::Coordinate; use std::collections::BinaryHeap; use std::rc::Rc; -pub fn divide_segment(se: &Rc>, inter: Coordinate, queue: &mut BinaryHeap>>) +pub fn divide_segment(se_l: &Rc>, inter: Coordinate, queue: &mut BinaryHeap>>) where F: Float, { - debug_assert!(se.is_left()); + debug_assert!(se_l.is_left()); //println!("dividing segment {:?} {:?} {:?}", se.point, inter, se.get_other_event().unwrap().point); - let other_event = match se.get_other_event() { - Some(other_event) => other_event, + let se_r = match se_l.get_other_event() { + Some(se) => se, None => return, }; + // The idea is to divide the segment based on the given `inter` coordinate as follows: + // + // (se_l)--------(r)(l)--------(se_r) + // + // Under normal circumstances the resulting events satisfy the conditions: + // + // se_l is before r, and l is before se_r. + // + // Since the intersection point computation is bounded to the interval [se_l.x, se_r.x] + // it is impossible for r/l to fall outside the interval. This leaves the corner cases: + // + // 1. r.x == se_l.x and r.y < se_l.y: This corresponds to the case where the first + // sub-segment becomes a perfectly vertical line. The problem is that vertical + // segments always have to be processed from bottom to top consistencly. The + // theoretically correct event order would be r first (bottom), se_l later (top). + // However, se_l is the event just being processed, so there is no (easy) way of + // processing r before se_l. The easiest solution to the problem is to avoid it, + // by incrementing inter.x by one ULP. + // 2. l.x == se_r.x and l.y > se_r.y: This corresponds to the case where the second + // sub-segment becomes a perfectly vertical line, and because of the bottom-to-top + // convention for vertical segment, the order of l and se_r must be swapped. + // In this case swapping is not a problem, because both events are in the future. + // + // See also: https://github.com/21re/rust-geo-booleanop/pull/11 + + // Prevent from corner case 1 let mut inter = inter; - if inter.x == se.point.x && inter.y < se.point.y { + if inter.x == se_l.point.x && inter.y < se_l.point.y { //println!("ZZZ incrementing x {} => {}", inter.x, inter.x.nextafter(true)); inter.x = inter.x.nextafter(true); } - let r = SweepEvent::new_rc(se.contour_id, inter, false, Rc::downgrade(&se), se.is_subject, true); + let r = SweepEvent::new_rc( + se_l.contour_id, + inter, + false, + Rc::downgrade(&se_l), + se_l.is_subject, + true, + ); let l = SweepEvent::new_rc( - se.contour_id, + se_l.contour_id, inter, true, - Rc::downgrade(&other_event), - se.is_subject, + Rc::downgrade(&se_r), + se_l.is_subject, true, ); - debug_assert!(r.is_after(se)); - if l.is_after(&other_event) { + // Corner case 1 should be impossible + debug_assert!(se_l.is_before(&r)); + // Corner case 2 can be accounted for by swapping l / se_r + if !l.is_before(&se_r) { //println!("XXX l > other_event {:?} < {:?}", l.point, other_event.point); - se.get_other_event().unwrap().set_left(true); + se_r.set_left(true); l.set_left(false); } - other_event.set_other_event(&l); - se.set_other_event(&r); + se_l.set_other_event(&r); + se_r.set_other_event(&l); queue.push(l); queue.push(r); From acc8c6b6903795b8b956a164634cafb479abf5c5 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sat, 22 Feb 2020 10:26:43 +0100 Subject: [PATCH 16/21] taken care of more cargo clippy findings --- lib/src/boolean/helper.rs | 14 ++++++++++++++ lib/src/boolean/possible_intersection.rs | 8 ++++---- lib/src/boolean/signed_area.rs | 8 +------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/src/boolean/helper.rs b/lib/src/boolean/helper.rs index 479f41b..295896e 100644 --- a/lib/src/boolean/helper.rs +++ b/lib/src/boolean/helper.rs @@ -49,6 +49,7 @@ pub fn less_if(condition: bool) -> Ordering { #[cfg(test)] pub mod test { + use super::Float; use geo_types::Coordinate; pub fn xy, Y: Into>(x: X, y: Y) -> Coordinate { @@ -57,4 +58,17 @@ pub mod test { y: y.into(), } } + + #[test] + fn test_float_type_trait() { + fn dummy(x: T) -> T + where + T: Float, + { + x + } + + assert_eq!(dummy(0_f32), 0_f32); + assert_eq!(dummy(0_f64), 0_f64); + } } diff --git a/lib/src/boolean/possible_intersection.rs b/lib/src/boolean/possible_intersection.rs index 2d9ba54..6c63d66 100644 --- a/lib/src/boolean/possible_intersection.rs +++ b/lib/src/boolean/possible_intersection.rs @@ -62,11 +62,11 @@ where if other1.point == other2.point { right_coincide = true } else if other1 < other2 { - events.push((other2.clone(), se2.clone())); - events.push((other1.clone(), se1.clone())); + events.push((other2, se2.clone())); + events.push((other1, se1.clone())); } else { - events.push((other1.clone(), se1.clone())); - events.push((other2.clone(), se2.clone())); + events.push((other1, se1.clone())); + events.push((other2, se2.clone())); } if left_coincide { diff --git a/lib/src/boolean/signed_area.rs b/lib/src/boolean/signed_area.rs index cbb39a5..b8a901d 100644 --- a/lib/src/boolean/signed_area.rs +++ b/lib/src/boolean/signed_area.rs @@ -23,13 +23,7 @@ where coordinate_to_robust(p1), coordinate_to_robust(p2), ); - if res > 0f64 { - F::one() - } else if res < 0f64 { - -F::one() - } else { - F::zero() - } + F::from(res).unwrap() } #[cfg(test)] From c757d8a7575736a0faf7a89895bb6445af487c09 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sat, 22 Feb 2020 10:41:42 +0100 Subject: [PATCH 17/21] improved test --- lib/src/boolean/helper.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/boolean/helper.rs b/lib/src/boolean/helper.rs index 295896e..f438770 100644 --- a/lib/src/boolean/helper.rs +++ b/lib/src/boolean/helper.rs @@ -49,7 +49,7 @@ pub fn less_if(condition: bool) -> Ordering { #[cfg(test)] pub mod test { - use super::Float; + use super::{nextafter, nextafterf, Float}; use geo_types::Coordinate; pub fn xy, Y: Into>(x: X, y: Y) -> Coordinate { @@ -65,10 +65,10 @@ pub mod test { where T: Float, { - x + x.nextafter(true) } - assert_eq!(dummy(0_f32), 0_f32); - assert_eq!(dummy(0_f64), 0_f64); + assert_eq!(dummy(0_f64), unsafe { nextafter(0_f64, std::f64::INFINITY) }); + assert_eq!(dummy(0_f32), unsafe { nextafterf(0_f32, std::f32::INFINITY) }); } } From 1bab9a3a631de8fc035530a9a5e0176d7527a86f Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sat, 22 Feb 2020 10:46:10 +0100 Subject: [PATCH 18/21] applied point constraining to overlap as well --- lib/src/boolean/segment_intersection.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index 465edd0..daf237f 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -81,8 +81,11 @@ where if let Some(bb) = bb { let inter = intersection_impl(a1, a2, b1, b2); match inter { + LineIntersection::None => LineIntersection::None, LineIntersection::Point(p) => LineIntersection::Point(constrain_to_bounding_box(p, bb)), - _ => inter, + LineIntersection::Overlap(p1, p2) => { + LineIntersection::Overlap(constrain_to_bounding_box(p1, bb), constrain_to_bounding_box(p2, bb)) + } } } else { LineIntersection::None From abba71b9b88d3860048b9dbc3d3cdc28a7e6d1b0 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sat, 22 Feb 2020 11:37:51 +0100 Subject: [PATCH 19/21] added alternative ulp slope test case --- .../generic_test_cases/issue76.geojson | 6 +- .../vertical_ulp_slopes2.geojson | 792 ++++++++++++++++++ 2 files changed, 795 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/generic_test_cases/vertical_ulp_slopes2.geojson diff --git a/tests/fixtures/generic_test_cases/issue76.geojson b/tests/fixtures/generic_test_cases/issue76.geojson index ccad810..e937ad8 100644 --- a/tests/fixtures/generic_test_cases/issue76.geojson +++ b/tests/fixtures/generic_test_cases/issue76.geojson @@ -47,7 +47,7 @@ "type": "MultiPolygon" }, "properties": { - "comment": "This test case is also a bit dubious, because the input polygons aren't closed. For intersection that seems to be okay, ...", + "comment": "This test case is a bit dubious, because the input polygons aren't closed, but it seems to work nevertheless.", "operation": "intersection" }, "type": "Feature" @@ -77,7 +77,7 @@ "type": "MultiPolygon" }, "properties": { - "comment": "... but for union it is broken ...", + "comment": "This test case is a bit dubious, because the input polygons aren't closed, but it seems to work nevertheless.", "operation": "union" }, "type": "Feature" @@ -108,7 +108,7 @@ "type": "MultiPolygon" }, "properties": { - "comment": "... and for diff as well", + "comment": "This test case is a bit dubious, because the input polygons aren't closed, but it seems to work nevertheless.", "operation": "diff" }, "type": "Feature" diff --git a/tests/fixtures/generic_test_cases/vertical_ulp_slopes2.geojson b/tests/fixtures/generic_test_cases/vertical_ulp_slopes2.geojson new file mode 100644 index 0000000..74673a9 --- /dev/null +++ b/tests/fixtures/generic_test_cases/vertical_ulp_slopes2.geojson @@ -0,0 +1,792 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [-1, -2.0256020391431986], + [-1.0000000000000002, 1.8103704927311566], + [-0.8823529411764707, 2.0198649911514837], + [-0.8823529411764706, -2.0258710429526894], + [-1, -2.0256020391431986] + ] + ], + [ + [ + [-0.7647058823529411, -2.0318528791650046], + [-0.7647058823529412, 1.9321339284015497], + [-0.6470588235294118, 1.881859453615137], + [-0.6470588235294118, -1.9522916134597346], + [-0.7647058823529411, -2.0318528791650046] + ] + ], + [ + [ + [-0.5294117647058824, -2.080138130530191], + [-0.5294117647058825, 1.9067309100411467], + [-0.41176470588235287, 2.048453533107718], + [-0.4117647058823529, -1.9883431622891843], + [-0.5294117647058824, -2.080138130530191] + ] + ], + [ + [ + [-0.2941176470588236, -2.1461680218620267], + [-0.2941176470588236, 2.0054312485062984], + [-0.17647058823529418, 1.8737759462587662], + [-0.17647058823529416, -1.8858659408733307], + [-0.2941176470588236, -2.1461680218620267] + ] + ], + [ + [ + [-0.05882352941176472, -1.8584098829442044], + [-0.05882352941176472, 1.9976947349527712], + [0.05882352941176472, 2.1386245941429873], + [0.05882352941176472, -2.1681418091963756], + [-0.05882352941176472, -1.8584098829442044] + ] + ], + [ + [ + [0.17647058823529416, -1.9979015639513185], + [0.17647058823529416, 1.8261146017547512], + [0.29411764705882365, 1.9712489310389558], + [0.2941176470588236, -2.161387633735755], + [0.17647058823529416, -1.9979015639513185] + ] + ], + [ + [ + [0.4117647058823528, -2.149136011319489], + [0.41176470588235287, 2.0386981235914385], + [0.5294117647058821, 1.8904048002416944], + [0.5294117647058822, -2.1572217262760067], + [0.4117647058823528, -2.149136011319489] + ] + ], + [ + [ + [0.6470588235294117, -2.1118775171717763], + [0.6470588235294118, 1.9399305140013197], + [0.7647058823529411, 1.98711499383292], + [0.7647058823529411, -2.119302709494014], + [0.6470588235294117, -2.1118775171717763] + ] + ], + [ + [ + [0.8823529411764706, -1.943837309914034], + [0.8823529411764707, 1.9932279342207007], + [1.0000000000000002, 2.0020946880074195], + [1, -2.045242939552576], + [0.8823529411764706, -1.943837309914034] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-1.8825450182233692, -1], + [2.0320016715511224, -1.0000000000000002], + [1.8649194394009254, -0.8823529411764707], + [-1.9196990613571376, -0.8823529411764706], + [-1.8825450182233692, -1] + ] + ], + [ + [ + [-1.814179567964298, -0.7647058823529411], + [2.0000033444680865, -0.7647058823529412], + [2.155808025578458, -0.6470588235294118], + [-2.063354538931556, -0.6470588235294118], + [-1.814179567964298, -0.7647058823529411] + ] + ], + [ + [ + [-1.9731423489489164, -0.5294117647058824], + [1.971018385318444, -0.5294117647058825], + [1.9746989052107196, -0.41176470588235287], + [-1.8893763260011598, -0.4117647058823529], + [-1.9731423489489164, -0.5294117647058824] + ] + ], + [ + [ + [-1.9857583306009374, -0.2941176470588236], + [2.1814968907779466, -0.2941176470588236], + [2.017683264059241, -0.17647058823529418], + [-2.16716203108999, -0.17647058823529416], + [-1.9857583306009374, -0.2941176470588236] + ] + ], + [ + [ + [-2.053463039329992, -0.05882352941176472], + [2.1403402016018007, -0.05882352941176472], + [1.9625100172191803, 0.05882352941176472], + [-2.1891190536420604, 0.05882352941176472], + [-2.053463039329992, -0.05882352941176472] + ] + ], + [ + [ + [-2.1011291044010587, 0.17647058823529416], + [1.8268577482947819, 0.17647058823529416], + [2.197540804568509, 0.29411764705882365], + [-1.8117678746491306, 0.2941176470588236], + [-2.1011291044010587, 0.17647058823529416] + ] + ], + [ + [ + [-1.8798966595469653, 0.4117647058823528], + [2.040726848562187, 0.41176470588235287], + [2.1059839441806725, 0.5294117647058821], + [-2.132309821366329, 0.5294117647058822], + [-1.8798966595469653, 0.4117647058823528] + ] + ], + [ + [ + [-2.082790707272224, 0.6470588235294117], + [2.0096267501201455, 0.6470588235294118], + [1.9426497124491036, 0.7647058823529411], + [-2.18172841390184, 0.7647058823529411], + [-2.082790707272224, 0.6470588235294117] + ] + ], + [ + [ + [-1.8067386218571149, 0.8823529411764706], + [1.9765419677419387, 0.8823529411764707], + [2.001600175751661, 1.0000000000000002], + [-2.0705834729861206, 1], + [-1.8067386218571149, 0.8823529411764706] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-2.1891190536420604, 0.05882352941176472], + [-2.053463039329992, -0.05882352941176472], + [-1, -0.05882352941176472], + [-1, -0.17647058823529416], + [-2.16716203108999, -0.17647058823529416], + [-1.9857583306009374, -0.2941176470588236], + [-1, -0.2941176470588236], + [-1, -0.4117647058823529], + [-1.8893763260011598, -0.4117647058823529], + [-1.9731423489489164, -0.5294117647058824], + [-1, -0.5294117647058824], + [-1, -0.6470588235294118], + [-2.063354538931556, -0.6470588235294118], + [-1.814179567964298, -0.7647058823529411], + [-1, -0.7647058823529411], + [-1, -0.8823529411764706], + [-1.9196990613571376, -0.8823529411764706], + [-1.8825450182233692, -1], + [-1, -1], + [-1, -2.0256020391431986], + [-0.8823529411764706, -2.0258710429526894], + [-0.8823529411764706, -1], + [-0.7647058823529411, -1], + [-0.7647058823529411, -2.0318528791650046], + [-0.6470588235294118, -1.9522916134597346], + [-0.6470588235294118, -1], + [-0.5294117647058824, -1], + [-0.5294117647058824, -2.080138130530191], + [-0.4117647058823529, -1.9883431622891843], + [-0.4117647058823529, -1], + [-0.2941176470588236, -1], + [-0.2941176470588236, -2.1461680218620267], + [-0.17647058823529416, -1.8858659408733307], + [-0.17647058823529416, -1], + [-0.05882352941176472, -1], + [-0.05882352941176472, -1.8584098829442044], + [0.05882352941176472, -2.1681418091963756], + [0.05882352941176472, -1], + [0.17647058823529416, -1], + [0.17647058823529416, -1.9979015639513185], + [0.2941176470588236, -2.161387633735755], + [0.2941176470588236, -1.0000000000000002], + [0.4117647058823528, -1.0000000000000002], + [0.4117647058823528, -2.149136011319489], + [0.5294117647058822, -2.1572217262760067], + [0.5294117647058822, -1.0000000000000002], + [0.6470588235294117, -1.0000000000000002], + [0.6470588235294117, -2.1118775171717763], + [0.7647058823529411, -2.119302709494014], + [0.7647058823529411, -1.0000000000000002], + [0.8823529411764706, -1.0000000000000002], + [0.8823529411764706, -1.943837309914034], + [1, -2.045242939552576], + [1, -1.0000000000000002], + [2.0320016715511224, -1.0000000000000002], + [1.8649194394009254, -0.8823529411764707], + [1, -0.8823529411764706], + [1, -0.7647058823529411], + [2.0000033444680865, -0.7647058823529412], + [2.155808025578458, -0.6470588235294118], + [1, -0.6470588235294118], + [1, -0.5294117647058824], + [1.971018385318444, -0.5294117647058825], + [1.9746989052107196, -0.41176470588235287], + [1, -0.4117647058823529], + [1, -0.2941176470588236], + [2.1814968907779466, -0.2941176470588236], + [2.017683264059241, -0.17647058823529418], + [1, -0.17647058823529416], + [1, -0.05882352941176472], + [2.1403402016018007, -0.05882352941176472], + [1.9625100172191803, 0.05882352941176472], + [1, 0.05882352941176472], + [1, 0.17647058823529416], + [1.8268577482947819, 0.17647058823529416], + [2.197540804568509, 0.29411764705882365], + [1, 0.2941176470588236], + [1, 0.4117647058823528], + [2.040726848562187, 0.41176470588235287], + [2.1059839441806725, 0.5294117647058821], + [1, 0.5294117647058822], + [1, 0.6470588235294117], + [2.0096267501201455, 0.6470588235294118], + [1.9426497124491036, 0.7647058823529411], + [1, 0.7647058823529411], + [1, 0.8823529411764706], + [1.9765419677419387, 0.8823529411764707], + [2.001600175751661, 1.0000000000000002], + [1, 1], + [1.0000000000000002, 2.0020946880074195], + [0.8823529411764707, 1.9932279342207007], + [0.8823529411764706, 1], + [0.7647058823529411, 1], + [0.7647058823529411, 1.98711499383292], + [0.6470588235294118, 1.9399305140013197], + [0.6470588235294117, 1], + [0.5294117647058822, 1], + [0.5294117647058821, 1.8904048002416944], + [0.41176470588235287, 2.0386981235914385], + [0.4117647058823528, 1], + [0.2941176470588236, 1], + [0.29411764705882365, 1.9712489310389558], + [0.17647058823529416, 1.8261146017547512], + [0.17647058823529416, 1], + [0.05882352941176472, 1], + [0.05882352941176472, 2.1386245941429873], + [-0.05882352941176472, 1.9976947349527712], + [-0.05882352941176472, 1], + [-0.17647058823529416, 1], + [-0.17647058823529418, 1.8737759462587662], + [-0.2941176470588236, 2.0054312485062984], + [-0.2941176470588236, 1], + [-0.4117647058823529, 1], + [-0.41176470588235287, 2.048453533107718], + [-0.5294117647058825, 1.9067309100411467], + [-0.5294117647058824, 1], + [-0.5294117647058825, 1], + [-0.6470588235294118, 1], + [-0.6470588235294118, 1.881859453615137], + [-0.7647058823529412, 1.9321339284015497], + [-0.7647058823529411, 1], + [-0.7647058823529412, 1], + [-0.8823529411764706, 1], + [-0.8823529411764707, 2.0198649911514837], + [-1.0000000000000002, 1.8103704927311566], + [-1, 1], + [-1.0000000000000002, 1], + [-2.0705834729861206, 1], + [-1.8067386218571149, 0.8823529411764706], + [-1, 0.8823529411764706], + [-1, 0.7647058823529411], + [-2.18172841390184, 0.7647058823529411], + [-2.082790707272224, 0.6470588235294117], + [-1, 0.6470588235294117], + [-1, 0.5294117647058822], + [-2.132309821366329, 0.5294117647058822], + [-1.8798966595469653, 0.4117647058823528], + [-1, 0.4117647058823528], + [-1, 0.2941176470588236], + [-1.8117678746491306, 0.2941176470588236], + [-2.1011291044010587, 0.17647058823529416], + [-1, 0.17647058823529416], + [-1, 0.05882352941176472], + [-2.1891190536420604, 0.05882352941176472] + ], + [ + [-0.8823529411764706, -0.8823529411764706], + [-0.7647058823529411, -0.8823529411764706], + [-0.7647058823529411, -0.7647058823529411], + [-0.8823529411764706, -0.7647058823529411], + [-0.8823529411764706, -0.8823529411764706] + ], + [ + [-0.8823529411764706, -0.6470588235294118], + [-0.7647058823529411, -0.6470588235294118], + [-0.7647058823529411, -0.5294117647058824], + [-0.8823529411764706, -0.5294117647058824], + [-0.8823529411764706, -0.6470588235294118] + ], + [ + [-0.8823529411764706, -0.4117647058823529], + [-0.7647058823529411, -0.4117647058823529], + [-0.7647058823529411, -0.2941176470588236], + [-0.8823529411764706, -0.2941176470588236], + [-0.8823529411764706, -0.4117647058823529] + ], + [ + [-0.8823529411764706, -0.17647058823529416], + [-0.7647058823529411, -0.17647058823529416], + [-0.7647058823529411, -0.05882352941176472], + [-0.8823529411764706, -0.05882352941176472], + [-0.8823529411764706, -0.17647058823529416] + ], + [ + [-0.8823529411764706, 0.05882352941176472], + [-0.7647058823529411, 0.05882352941176472], + [-0.7647058823529411, 0.17647058823529416], + [-0.8823529411764706, 0.17647058823529416], + [-0.8823529411764706, 0.05882352941176472] + ], + [ + [-0.8823529411764706, 0.2941176470588236], + [-0.7647058823529411, 0.2941176470588236], + [-0.7647058823529411, 0.4117647058823528], + [-0.8823529411764706, 0.4117647058823528], + [-0.8823529411764706, 0.2941176470588236] + ], + [ + [-0.8823529411764706, 0.5294117647058822], + [-0.7647058823529411, 0.5294117647058822], + [-0.7647058823529411, 0.6470588235294117], + [-0.8823529411764706, 0.6470588235294117], + [-0.8823529411764706, 0.5294117647058822] + ], + [ + [-0.8823529411764706, 0.7647058823529411], + [-0.7647058823529411, 0.7647058823529411], + [-0.7647058823529411, 0.8823529411764706], + [-0.8823529411764706, 0.8823529411764706], + [-0.8823529411764706, 0.7647058823529411] + ], + [ + [-0.6470588235294118, -0.8823529411764706], + [-0.5294117647058824, -0.8823529411764706], + [-0.5294117647058824, -0.7647058823529411], + [-0.6470588235294118, -0.7647058823529411], + [-0.6470588235294118, -0.8823529411764706] + ], + [ + [-0.6470588235294118, -0.6470588235294118], + [-0.5294117647058824, -0.6470588235294118], + [-0.5294117647058824, -0.5294117647058824], + [-0.6470588235294118, -0.5294117647058824], + [-0.6470588235294118, -0.6470588235294118] + ], + [ + [-0.6470588235294118, -0.4117647058823529], + [-0.5294117647058824, -0.4117647058823529], + [-0.5294117647058824, -0.2941176470588236], + [-0.6470588235294118, -0.2941176470588236], + [-0.6470588235294118, -0.4117647058823529] + ], + [ + [-0.6470588235294118, -0.17647058823529416], + [-0.5294117647058824, -0.17647058823529416], + [-0.5294117647058824, -0.05882352941176472], + [-0.6470588235294118, -0.05882352941176472], + [-0.6470588235294118, -0.17647058823529416] + ], + [ + [-0.6470588235294118, 0.05882352941176472], + [-0.5294117647058824, 0.05882352941176472], + [-0.5294117647058824, 0.17647058823529416], + [-0.6470588235294118, 0.17647058823529416], + [-0.6470588235294118, 0.05882352941176472] + ], + [ + [-0.6470588235294118, 0.2941176470588236], + [-0.5294117647058824, 0.2941176470588236], + [-0.5294117647058824, 0.4117647058823528], + [-0.6470588235294118, 0.4117647058823528], + [-0.6470588235294118, 0.2941176470588236] + ], + [ + [-0.6470588235294118, 0.5294117647058822], + [-0.5294117647058824, 0.5294117647058822], + [-0.5294117647058824, 0.6470588235294117], + [-0.6470588235294118, 0.6470588235294117], + [-0.6470588235294118, 0.5294117647058822] + ], + [ + [-0.6470588235294118, 0.7647058823529411], + [-0.5294117647058824, 0.7647058823529411], + [-0.5294117647058824, 0.8823529411764706], + [-0.6470588235294118, 0.8823529411764706], + [-0.6470588235294118, 0.7647058823529411] + ], + [ + [-0.4117647058823529, -0.8823529411764706], + [-0.2941176470588236, -0.8823529411764706], + [-0.2941176470588236, -0.7647058823529411], + [-0.4117647058823529, -0.7647058823529411], + [-0.4117647058823529, -0.8823529411764706] + ], + [ + [-0.4117647058823529, -0.6470588235294118], + [-0.2941176470588236, -0.6470588235294118], + [-0.2941176470588236, -0.5294117647058824], + [-0.4117647058823529, -0.5294117647058824], + [-0.4117647058823529, -0.6470588235294118] + ], + [ + [-0.4117647058823529, -0.4117647058823529], + [-0.2941176470588236, -0.4117647058823529], + [-0.2941176470588236, -0.2941176470588236], + [-0.4117647058823529, -0.2941176470588236], + [-0.4117647058823529, -0.4117647058823529] + ], + [ + [-0.4117647058823529, -0.17647058823529416], + [-0.2941176470588236, -0.17647058823529416], + [-0.2941176470588236, -0.05882352941176472], + [-0.4117647058823529, -0.05882352941176472], + [-0.4117647058823529, -0.17647058823529416] + ], + [ + [-0.4117647058823529, 0.05882352941176472], + [-0.2941176470588236, 0.05882352941176472], + [-0.2941176470588236, 0.17647058823529416], + [-0.4117647058823529, 0.17647058823529416], + [-0.4117647058823529, 0.05882352941176472] + ], + [ + [-0.4117647058823529, 0.2941176470588236], + [-0.2941176470588236, 0.2941176470588236], + [-0.2941176470588236, 0.4117647058823528], + [-0.4117647058823529, 0.4117647058823528], + [-0.4117647058823529, 0.2941176470588236] + ], + [ + [-0.4117647058823529, 0.5294117647058822], + [-0.2941176470588236, 0.5294117647058822], + [-0.2941176470588236, 0.6470588235294117], + [-0.4117647058823529, 0.6470588235294117], + [-0.4117647058823529, 0.5294117647058822] + ], + [ + [-0.4117647058823529, 0.7647058823529411], + [-0.2941176470588236, 0.7647058823529411], + [-0.2941176470588236, 0.8823529411764706], + [-0.4117647058823529, 0.8823529411764706], + [-0.4117647058823529, 0.7647058823529411] + ], + [ + [-0.17647058823529416, -0.8823529411764706], + [-0.05882352941176472, -0.8823529411764706], + [-0.05882352941176472, -0.7647058823529411], + [-0.17647058823529416, -0.7647058823529411], + [-0.17647058823529416, -0.8823529411764706] + ], + [ + [-0.17647058823529416, -0.6470588235294118], + [-0.05882352941176472, -0.6470588235294118], + [-0.05882352941176472, -0.5294117647058824], + [-0.17647058823529416, -0.5294117647058824], + [-0.17647058823529416, -0.6470588235294118] + ], + [ + [-0.17647058823529416, -0.4117647058823529], + [-0.05882352941176472, -0.4117647058823529], + [-0.05882352941176472, -0.2941176470588236], + [-0.17647058823529416, -0.2941176470588236], + [-0.17647058823529416, -0.4117647058823529] + ], + [ + [-0.17647058823529416, -0.17647058823529416], + [-0.05882352941176472, -0.17647058823529416], + [-0.05882352941176472, -0.05882352941176472], + [-0.17647058823529416, -0.05882352941176472], + [-0.17647058823529416, -0.17647058823529416] + ], + [ + [-0.17647058823529416, 0.05882352941176472], + [-0.05882352941176472, 0.05882352941176472], + [-0.05882352941176472, 0.17647058823529416], + [-0.17647058823529416, 0.17647058823529416], + [-0.17647058823529416, 0.05882352941176472] + ], + [ + [-0.17647058823529416, 0.2941176470588236], + [-0.05882352941176472, 0.2941176470588236], + [-0.05882352941176472, 0.4117647058823528], + [-0.17647058823529416, 0.4117647058823528], + [-0.17647058823529416, 0.2941176470588236] + ], + [ + [-0.17647058823529416, 0.5294117647058822], + [-0.05882352941176472, 0.5294117647058822], + [-0.05882352941176472, 0.6470588235294117], + [-0.17647058823529416, 0.6470588235294117], + [-0.17647058823529416, 0.5294117647058822] + ], + [ + [-0.17647058823529416, 0.7647058823529411], + [-0.05882352941176472, 0.7647058823529411], + [-0.05882352941176472, 0.8823529411764706], + [-0.17647058823529416, 0.8823529411764706], + [-0.17647058823529416, 0.7647058823529411] + ], + [ + [0.05882352941176472, -0.8823529411764706], + [0.17647058823529416, -0.8823529411764706], + [0.17647058823529416, -0.7647058823529411], + [0.05882352941176472, -0.7647058823529411], + [0.05882352941176472, -0.8823529411764706] + ], + [ + [0.05882352941176472, -0.6470588235294118], + [0.17647058823529416, -0.6470588235294118], + [0.17647058823529416, -0.5294117647058824], + [0.05882352941176472, -0.5294117647058824], + [0.05882352941176472, -0.6470588235294118] + ], + [ + [0.05882352941176472, -0.4117647058823529], + [0.17647058823529416, -0.4117647058823529], + [0.17647058823529416, -0.2941176470588236], + [0.05882352941176472, -0.2941176470588236], + [0.05882352941176472, -0.4117647058823529] + ], + [ + [0.05882352941176472, -0.17647058823529416], + [0.17647058823529416, -0.17647058823529416], + [0.17647058823529416, -0.05882352941176472], + [0.05882352941176472, -0.05882352941176472], + [0.05882352941176472, -0.17647058823529416] + ], + [ + [0.05882352941176472, 0.05882352941176472], + [0.17647058823529416, 0.05882352941176472], + [0.17647058823529416, 0.17647058823529416], + [0.05882352941176472, 0.17647058823529416], + [0.05882352941176472, 0.05882352941176472] + ], + [ + [0.05882352941176472, 0.2941176470588236], + [0.17647058823529416, 0.2941176470588236], + [0.17647058823529416, 0.4117647058823528], + [0.05882352941176472, 0.4117647058823528], + [0.05882352941176472, 0.2941176470588236] + ], + [ + [0.05882352941176472, 0.5294117647058822], + [0.17647058823529416, 0.5294117647058822], + [0.17647058823529416, 0.6470588235294117], + [0.05882352941176472, 0.6470588235294117], + [0.05882352941176472, 0.5294117647058822] + ], + [ + [0.05882352941176472, 0.7647058823529411], + [0.17647058823529416, 0.7647058823529411], + [0.17647058823529416, 0.8823529411764706], + [0.05882352941176472, 0.8823529411764706], + [0.05882352941176472, 0.7647058823529411] + ], + [ + [0.2941176470588236, -0.8823529411764706], + [0.4117647058823528, -0.8823529411764706], + [0.4117647058823528, -0.7647058823529411], + [0.2941176470588236, -0.7647058823529411], + [0.2941176470588236, -0.8823529411764706] + ], + [ + [0.2941176470588236, -0.6470588235294118], + [0.4117647058823528, -0.6470588235294118], + [0.4117647058823528, -0.5294117647058824], + [0.2941176470588236, -0.5294117647058824], + [0.2941176470588236, -0.6470588235294118] + ], + [ + [0.2941176470588236, -0.4117647058823529], + [0.4117647058823528, -0.4117647058823529], + [0.4117647058823528, -0.2941176470588236], + [0.2941176470588236, -0.2941176470588236], + [0.2941176470588236, -0.4117647058823529] + ], + [ + [0.2941176470588236, -0.17647058823529416], + [0.4117647058823528, -0.17647058823529416], + [0.4117647058823528, -0.05882352941176472], + [0.2941176470588236, -0.05882352941176472], + [0.2941176470588236, -0.17647058823529416] + ], + [ + [0.2941176470588236, 0.05882352941176472], + [0.4117647058823528, 0.05882352941176472], + [0.4117647058823528, 0.17647058823529416], + [0.2941176470588236, 0.17647058823529416], + [0.2941176470588236, 0.05882352941176472] + ], + [ + [0.2941176470588236, 0.2941176470588236], + [0.4117647058823528, 0.2941176470588236], + [0.4117647058823528, 0.4117647058823528], + [0.2941176470588236, 0.4117647058823528], + [0.2941176470588236, 0.2941176470588236] + ], + [ + [0.2941176470588236, 0.5294117647058822], + [0.4117647058823528, 0.5294117647058822], + [0.4117647058823528, 0.6470588235294117], + [0.2941176470588236, 0.6470588235294117], + [0.2941176470588236, 0.5294117647058822] + ], + [ + [0.2941176470588236, 0.7647058823529411], + [0.4117647058823528, 0.7647058823529411], + [0.4117647058823528, 0.8823529411764706], + [0.2941176470588236, 0.8823529411764706], + [0.2941176470588236, 0.7647058823529411] + ], + [ + [0.5294117647058822, -0.8823529411764706], + [0.6470588235294117, -0.8823529411764706], + [0.6470588235294117, -0.7647058823529411], + [0.5294117647058822, -0.7647058823529411], + [0.5294117647058822, -0.8823529411764706] + ], + [ + [0.5294117647058822, -0.6470588235294118], + [0.6470588235294117, -0.6470588235294118], + [0.6470588235294117, -0.5294117647058824], + [0.5294117647058822, -0.5294117647058824], + [0.5294117647058822, -0.6470588235294118] + ], + [ + [0.5294117647058822, -0.4117647058823529], + [0.6470588235294117, -0.4117647058823529], + [0.6470588235294117, -0.2941176470588236], + [0.5294117647058822, -0.2941176470588236], + [0.5294117647058822, -0.4117647058823529] + ], + [ + [0.5294117647058822, -0.17647058823529416], + [0.6470588235294117, -0.17647058823529416], + [0.6470588235294117, -0.05882352941176472], + [0.5294117647058822, -0.05882352941176472], + [0.5294117647058822, -0.17647058823529416] + ], + [ + [0.5294117647058822, 0.05882352941176472], + [0.6470588235294117, 0.05882352941176472], + [0.6470588235294117, 0.17647058823529416], + [0.5294117647058822, 0.17647058823529416], + [0.5294117647058822, 0.05882352941176472] + ], + [ + [0.5294117647058822, 0.2941176470588236], + [0.6470588235294117, 0.2941176470588236], + [0.6470588235294117, 0.4117647058823528], + [0.5294117647058822, 0.4117647058823528], + [0.5294117647058822, 0.2941176470588236] + ], + [ + [0.5294117647058822, 0.5294117647058822], + [0.6470588235294117, 0.5294117647058822], + [0.6470588235294117, 0.6470588235294117], + [0.5294117647058822, 0.6470588235294117], + [0.5294117647058822, 0.5294117647058822] + ], + [ + [0.5294117647058822, 0.7647058823529411], + [0.6470588235294117, 0.7647058823529411], + [0.6470588235294117, 0.8823529411764706], + [0.5294117647058822, 0.8823529411764706], + [0.5294117647058822, 0.7647058823529411] + ], + [ + [0.7647058823529411, -0.8823529411764706], + [0.8823529411764706, -0.8823529411764706], + [0.8823529411764706, -0.7647058823529411], + [0.7647058823529411, -0.7647058823529411], + [0.7647058823529411, -0.8823529411764706] + ], + [ + [0.7647058823529411, -0.6470588235294118], + [0.8823529411764706, -0.6470588235294118], + [0.8823529411764706, -0.5294117647058824], + [0.7647058823529411, -0.5294117647058824], + [0.7647058823529411, -0.6470588235294118] + ], + [ + [0.7647058823529411, -0.4117647058823529], + [0.8823529411764706, -0.4117647058823529], + [0.8823529411764706, -0.2941176470588236], + [0.7647058823529411, -0.2941176470588236], + [0.7647058823529411, -0.4117647058823529] + ], + [ + [0.7647058823529411, -0.17647058823529416], + [0.8823529411764706, -0.17647058823529416], + [0.8823529411764706, -0.05882352941176472], + [0.7647058823529411, -0.05882352941176472], + [0.7647058823529411, -0.17647058823529416] + ], + [ + [0.7647058823529411, 0.05882352941176472], + [0.8823529411764706, 0.05882352941176472], + [0.8823529411764706, 0.17647058823529416], + [0.7647058823529411, 0.17647058823529416], + [0.7647058823529411, 0.05882352941176472] + ], + [ + [0.7647058823529411, 0.2941176470588236], + [0.8823529411764706, 0.2941176470588236], + [0.8823529411764706, 0.4117647058823528], + [0.7647058823529411, 0.4117647058823528], + [0.7647058823529411, 0.2941176470588236] + ], + [ + [0.7647058823529411, 0.5294117647058822], + [0.8823529411764706, 0.5294117647058822], + [0.8823529411764706, 0.6470588235294117], + [0.7647058823529411, 0.6470588235294117], + [0.7647058823529411, 0.5294117647058822] + ], + [ + [0.7647058823529411, 0.7647058823529411], + [0.8823529411764706, 0.7647058823529411], + [0.8823529411764706, 0.8823529411764706], + [0.7647058823529411, 0.8823529411764706], + [0.7647058823529411, 0.7647058823529411] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} From ef0bfc611577514eb1df76b5da0e143bbf52136d Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sat, 22 Feb 2020 11:42:15 +0100 Subject: [PATCH 20/21] removed debug code --- lib/src/boolean/connect_edges.rs | 74 ------------------------ lib/src/boolean/divide_segment.rs | 3 - lib/src/boolean/possible_intersection.rs | 17 +----- lib/src/boolean/segment_intersection.rs | 2 - lib/src/boolean/subdivide_segments.rs | 21 +------ lib/src/boolean/sweep_event.rs | 28 --------- 6 files changed, 4 insertions(+), 141 deletions(-) diff --git a/lib/src/boolean/connect_edges.rs b/lib/src/boolean/connect_edges.rs index 2ce0b50..c5bb8a8 100644 --- a/lib/src/boolean/connect_edges.rs +++ b/lib/src/boolean/connect_edges.rs @@ -10,31 +10,6 @@ where { let mut result_events: Vec>> = Vec::new(); - for (pos, event) in sorted_events.iter().enumerate() { - event.set_other_pos(pos as i32) - } - /* - for (i, r) in sorted_events.iter().enumerate() { - println!("pos {:3} linked to {:3} {} {:?} => {:?} {:?}", - i, - r.get_other_event().map(|o| o.get_other_pos()).unwrap(), - if r.is_left() { "L" } else { "R" }, - r.point, - r.get_other_event().map(|o| o.point).unwrap(), - r.get_result_transition(), - ); - } - - for (pos, event) in sorted_events.iter().enumerate() { - event.set_other_pos(-999); - } - for (pos, event) in sorted_events.iter().enumerate() { - if event.is_in_result() { - //assert_eq!(event.get_other_event().unwrap().get_other_pos(), -999); - } - } - */ - for event in sorted_events { if (event.is_left() && event.is_in_result()) || (!event.is_left() && event.get_other_event().map(|o| o.is_in_result()).unwrap_or(false)) @@ -68,57 +43,9 @@ where } } - /* - for r in &result_events { - println!("{:?}", r); - debug_assert!(r.get_other_event().is_some()); - } - - for (i, r) in result_events.iter().enumerate() { - println!("pos {:3} linked to {:3} {} {:?} => {:?}", - i, - r.get_other_pos(), - if r.is_left() { "L" } else { "R" }, - r.point, - r.get_other_event().map(|o| o.point).unwrap(), - ); - } - */ - result_events } -// csv generator -use std::fs::File; -use std::io::Write; -fn debug_print_results(events: &[Rc>]) -where - F: Float, -{ - let mut writer = File::create("debug.csv").unwrap(); - writeln!( - &mut writer, - "index;x;y;other_x;other_y;lr;result_transition;in_out;other_in_out;is_subject;is_exterior_ring;prev_in_result" - ) - .expect("Failed to write to file"); - for (i, evt) in events.iter().enumerate() { - writeln!(&mut writer, "{i};{x:?};{y:?};{other_x:?};{other_y:?};{lr};{transition:?};{in_out};{other_in_out};{subject};{exterior_ring};{prev_in_result:?}", - i=i, - x=evt.point.x, - y=evt.point.y, - other_x=evt.get_other_event().unwrap().point.x, - other_y=evt.get_other_event().unwrap().point.y, - lr=if evt.is_left() { "L" } else { "R" }, - transition=evt.get_result_transition(), - in_out=evt.is_in_out(), - other_in_out=evt.is_other_in_out(), - subject=evt.is_subject, - exterior_ring=evt.is_exterior_ring, - prev_in_result=evt.get_prev_in_result().map(|o| format!("{:?}", o.point)), - ).expect("Failed to write to file"); - } -} - fn next_pos(pos: i32, result_events: &[Rc>], processed: &HashSet, orig_pos: i32) -> i32 where F: Float, @@ -246,7 +173,6 @@ where F: Float, { let result_events = order_events(sorted_events); - // debug_print_results(&result_events); let mut contours: Vec> = Vec::new(); let mut processed: HashSet = HashSet::new(); diff --git a/lib/src/boolean/divide_segment.rs b/lib/src/boolean/divide_segment.rs index 904d65f..3fae9f3 100644 --- a/lib/src/boolean/divide_segment.rs +++ b/lib/src/boolean/divide_segment.rs @@ -9,7 +9,6 @@ where F: Float, { debug_assert!(se_l.is_left()); - //println!("dividing segment {:?} {:?} {:?}", se.point, inter, se.get_other_event().unwrap().point); let se_r = match se_l.get_other_event() { Some(se) => se, @@ -44,7 +43,6 @@ where // Prevent from corner case 1 let mut inter = inter; if inter.x == se_l.point.x && inter.y < se_l.point.y { - //println!("ZZZ incrementing x {} => {}", inter.x, inter.x.nextafter(true)); inter.x = inter.x.nextafter(true); } @@ -69,7 +67,6 @@ where debug_assert!(se_l.is_before(&r)); // Corner case 2 can be accounted for by swapping l / se_r if !l.is_before(&se_r) { - //println!("XXX l > other_event {:?} < {:?}", l.point, other_event.point); se_r.set_left(true); l.set_left(false); } diff --git a/lib/src/boolean/possible_intersection.rs b/lib/src/boolean/possible_intersection.rs index 6c63d66..12247a7 100644 --- a/lib/src/boolean/possible_intersection.rs +++ b/lib/src/boolean/possible_intersection.rs @@ -18,22 +18,10 @@ where _ => return 0, }; - let inter = intersection(se1.point, other1.point, se2.point, other2.point); - //println!("Intersection: {:?}", inter); - match inter { - LineIntersection::Point(inter) => { - //println!("{{\"intersection\": {{\"x\": {}, \"y\": {}}}}}", inter.x, inter.y); - } - _ => {} - } - match inter { + match intersection(se1.point, other1.point, se2.point, other2.point) { LineIntersection::None => 0, // No intersection - LineIntersection::Point(_) if se1.point == se2.point && other1.point == other2.point => { - //println!(" => line segments intersect at an endpoint of both line segments"); - 0 - } // the line segments intersect at an endpoint of both line segments + LineIntersection::Point(_) if se1.point == se2.point && other1.point == other2.point => 0, // the line segments intersect at an endpoint of both line segments LineIntersection::Point(inter) => { - //println!(" => point intersection"); if se1.point != inter && other1.point != inter { divide_segment(&se1, inter, queue) } @@ -44,7 +32,6 @@ where } LineIntersection::Overlap(_, _) if se1.is_subject == se2.is_subject => 0, // The line segments associated to se1 and se2 overlap LineIntersection::Overlap(_, _) => { - //println!(" => overlap"); let mut events = Vec::new(); let mut left_coincide = false; let mut right_coincide = false; diff --git a/lib/src/boolean/segment_intersection.rs b/lib/src/boolean/segment_intersection.rs index daf237f..af54c78 100644 --- a/lib/src/boolean/segment_intersection.rs +++ b/lib/src/boolean/segment_intersection.rs @@ -120,12 +120,10 @@ where if sqr_kross > F::zero() { let s = cross_product(e, vb) / kross; - // println!("s = {:?} => {:?}", s, mid_point(a1, s, va)); if s < F::zero() || s > F::one() { return LineIntersection::None; } let t = cross_product(e, va) / kross; - // println!("t = {:?} => {:?}", t, mid_point(b1, t, va)); if t < F::zero() || t > F::one() { return LineIntersection::None; } diff --git a/lib/src/boolean/subdivide_segments.rs b/lib/src/boolean/subdivide_segments.rs index 5f3f286..3cf435a 100644 --- a/lib/src/boolean/subdivide_segments.rs +++ b/lib/src/boolean/subdivide_segments.rs @@ -2,7 +2,7 @@ use super::compare_segments::compare_segments; use super::compute_fields::compute_fields; use super::helper::Float; use super::possible_intersection::possible_intersection; -use super::sweep_event::{JsonDebug, SweepEvent}; +use super::sweep_event::SweepEvent; use super::Operation; use crate::splay::SplaySet; use geo_types::Rect; @@ -23,12 +23,8 @@ where let rightbound = sbbox.max.x.min(cbbox.max.x); while let Some(event) = event_queue.pop() { - //println!(""); - //println!("size event queue begin iter: {}", event_queue.len()); - //println!("{{\"processEvent\": {}}}", event.to_json_debug()); sorted_events.push(event.clone()); - //println!("{} {}", event.point.x, rightbound); if operation == Operation::Intersection && event.point.x > rightbound || operation == Operation::Difference && event.point.x > sbbox.max.x { @@ -44,19 +40,16 @@ where compute_fields(&event, maybe_prev, operation); if let Some(next) = maybe_next { - //println!("{{\"seNextEvent\": {}}}", next.to_json_debug()); if possible_intersection(&event, &next, event_queue) == 2 { - //println!("Intersection with next"); compute_fields(&event, maybe_prev, operation); compute_fields(&event, Some(next), operation); } } if let Some(prev) = maybe_prev { - //println!("{{\"sePrevEvent\": {}}}", prev.to_json_debug()); if possible_intersection(&prev, &event, event_queue) == 2 { let maybe_prev_prev = sweep_line.prev(&prev); - //println!("Intersection with prev"); + compute_fields(&prev, maybe_prev_prev, operation); compute_fields(&event, Some(prev), operation); } @@ -67,22 +60,12 @@ where let maybe_next = sweep_line.next(&other_event).cloned(); if let (Some(prev), Some(next)) = (maybe_prev, maybe_next) { - //println!("Possible post intersection"); - //println!("{{\"sePostNextEvent\": {}}}", next.to_json_debug()); - //println!("{{\"sePostPrevEvent\": {}}}", prev.to_json_debug()); possible_intersection(&prev, &next, event_queue); } - //println!("{{\"removing\": {}}}", other_event.to_json_debug()); sweep_line.remove(&other_event); } } - - // println!("size event queue end iter: {}", event_queue.len()); - - //let s: Vec = &sweep_line.into_iter().map(|e| e.to_json_debug()).collect(); - //let s = s.join(", "); - //println!("{{\"sweepLineState\": {{{}}}}}", s); } sorted_events diff --git a/lib/src/boolean/sweep_event.rs b/lib/src/boolean/sweep_event.rs index e0a21b2..deef876 100644 --- a/lib/src/boolean/sweep_event.rs +++ b/lib/src/boolean/sweep_event.rs @@ -249,34 +249,6 @@ where } } -pub trait JsonDebug { - fn to_json_debug(&self) -> String; - fn to_json_debug_short(&self) -> String; -} - -impl JsonDebug for Rc> -where - F: Float, -{ - fn to_json_debug(&self) -> String { - format!( - "{{\"self\": {}, \"other\": {}}}", - self.to_json_debug_short(), - self.get_other_event().unwrap().to_json_debug_short(), - ) - } - - fn to_json_debug_short(&self) -> String { - format!( - "{{\"addr\": \"{:p}\", \"point\": {{\"x\": {}, \"y\": {}}}, \"type\": \"{}\"}}", - *self, - self.point.x, - self.point.y, - if self.is_left() { "L" } else { "R" }, - ) - } -} - #[cfg(test)] mod test { use super::super::helper::test::xy; From 1a81c9292fb4a0e96e64793d4e9331dd43268973 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sun, 23 Feb 2020 16:26:08 +0100 Subject: [PATCH 21/21] simplified signature of signed_area --- lib/src/boolean/compare_segments.rs | 4 ++-- lib/src/boolean/signed_area.rs | 7 +++---- lib/src/boolean/sweep_event.rs | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/src/boolean/compare_segments.rs b/lib/src/boolean/compare_segments.rs index b5954ef..c382872 100644 --- a/lib/src/boolean/compare_segments.rs +++ b/lib/src/boolean/compare_segments.rs @@ -15,8 +15,8 @@ where } if let (Some(other1), Some(other2)) = (le1.get_other_event(), le2.get_other_event()) { - if signed_area(le1.point, other1.point, le2.point) != F::zero() - || signed_area(le1.point, other1.point, other2.point) != F::zero() + if signed_area(le1.point, other1.point, le2.point) != 0. + || signed_area(le1.point, other1.point, other2.point) != 0. { if le1.point == le2.point { return less_if(le1.is_below(other2.point)); diff --git a/lib/src/boolean/signed_area.rs b/lib/src/boolean/signed_area.rs index b8a901d..eb29a88 100644 --- a/lib/src/boolean/signed_area.rs +++ b/lib/src/boolean/signed_area.rs @@ -14,16 +14,15 @@ where } #[inline] -pub fn signed_area(p0: Coordinate, p1: Coordinate, p2: Coordinate) -> F +pub fn signed_area(p0: Coordinate, p1: Coordinate, p2: Coordinate) -> f64 where F: Float, { - let res = orient2d( + orient2d( coordinate_to_robust(p0), coordinate_to_robust(p1), coordinate_to_robust(p2), - ); - F::from(res).unwrap() + ) } #[cfg(test)] diff --git a/lib/src/boolean/sweep_event.rs b/lib/src/boolean/sweep_event.rs index deef876..e3cf79d 100644 --- a/lib/src/boolean/sweep_event.rs +++ b/lib/src/boolean/sweep_event.rs @@ -159,9 +159,9 @@ where pub fn is_below(&self, p: Coordinate) -> bool { if let Some(ref other_event) = self.get_other_event() { if self.is_left() { - signed_area(self.point, other_event.point, p) > F::zero() + signed_area(self.point, other_event.point, p) > 0. } else { - signed_area(other_event.point, self.point, p) > F::zero() + signed_area(other_event.point, self.point, p) > 0. } } else { false @@ -240,7 +240,7 @@ where } if let (Some(other1), Some(other2)) = (self.get_other_event(), other.get_other_event()) { - if signed_area(p1, other1.point, other2.point) != F::zero() { + if signed_area(p1, other1.point, other2.point) != 0. { return less_if(!self.is_below(other2.point)); } }