1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//! This package provides two traits for (Multi)Polygon: repair and merge
//!
//! When running repair, it will try its best to produce a (Multi)Polygon
//! that meets OGC standards. Some very invalid polygons still fail, but
//! most come through as valid with very little change.
//!
//! The join trait for MultiPolygon will merge all of its Polygons
//! into a single valid Polygon. This may involve a union or the
//! creation of a small bridge between the closes points of non-overlapping
//! Polygons.
//!
mod close_poly;
mod dedup_poly_point;
mod fix_intersecting_rings;
mod fix_point_touching_ring_line;
mod fix_self_intersecting_ring;
pub mod join;
pub mod repair;

use float_next_after::NextAfter;
use geo_booleanop::boolean::Float;
use geo_types::Coordinate;
use std::fmt;

pub trait GeoRepairFloat:
    Float
    + NextAfter<Self>
    + fmt::Display
    + num_traits::cast::FromPrimitive
    + std::iter::Sum
    + num_traits::Signed
{
}
impl<
        T: Float
            + NextAfter<T>
            + fmt::Display
            + num_traits::cast::FromPrimitive
            + std::iter::Sum
            + num_traits::Signed,
    > GeoRepairFloat for T
{
}

fn shift_point<T: GeoRepairFloat>(coord: &Coordinate<T>, x_dir: T, y_dir: T) -> Coordinate<T> {
    // Put some distance between the submitted coord and the output (2 steps seems enough)
    Coordinate {
        x: coord.x.next_after(x_dir).next_after(x_dir),
        y: coord.y.next_after(y_dir).next_after(y_dir),
    }
}