polygon-art/src/extensions/translate_ext.rs

88 lines
2.6 KiB
Rust

use geo::algorithm::bounding_rect::BoundingRect;
use geo::algorithm::translate::Translate;
use geo::{CoordinateType, LineString, MultiLineString, MultiPolygon, Polygon, Rect};
/// wrapper for BoundingRect because of the Output type
pub trait ExplicitBoundingRect<T>
where
T: CoordinateType,
{
fn bounding(&self) -> Option<Rect<T>>;
}
impl<T: CoordinateType> ExplicitBoundingRect<T> for Polygon<T> {
fn bounding(&self) -> Option<Rect<T>> {
self.bounding_rect()
}
}
impl<T: CoordinateType> ExplicitBoundingRect<T> for MultiPolygon<T> {
fn bounding(&self) -> Option<Rect<T>> {
self.bounding_rect()
}
}
impl<T: CoordinateType> ExplicitBoundingRect<T> for LineString<T> {
fn bounding(&self) -> Option<Rect<T>> {
self.bounding_rect()
}
}
impl<T: CoordinateType> ExplicitBoundingRect<T> for MultiLineString<T> {
fn bounding(&self) -> Option<Rect<T>> {
self.bounding_rect()
}
}
/// Translate Extensions
pub trait TranslateExt {
/// translate the object to it's center
fn translate_center(&self) -> Self;
/// translate the object to it's center on the x aches
fn translate_center_x(&self) -> Self;
/// translate the object to it's center on the y aches
fn translate_center_y(&self) -> Self;
/// translate the object, so it touches the y aches
fn translate_left(&self) -> Self;
/// translate the object, so it touches the x aches
fn translate_top(&self) -> Self;
}
impl<B> TranslateExt for B
where
B: ExplicitBoundingRect<f64> + Translate<f64>,
{
fn translate_center(&self) -> Self {
let option = self.bounding().unwrap();
let y_diff = option.max().y - option.min().y;
let y_shift = y_diff / 2.0;
let x_diff = option.max().x - option.min().x;
let x_shift = x_diff / 2.0;
self.translate(-(option.min().x + x_shift), -(option.min().y + y_shift))
}
fn translate_center_x(&self) -> Self {
let option = self.bounding().unwrap();
let x_diff = option.max().x - option.min().x;
let x_shift = x_diff / 2.0;
self.translate(-(option.min().x + x_shift), 0.0)
}
fn translate_center_y(&self) -> Self {
let option = self.bounding().unwrap();
let y_diff = option.max().y - option.min().y;
let y_shift = y_diff / 2.0;
self.translate(0.0, -(option.min().y + y_shift))
}
fn translate_left(&self) -> Self {
let bounding = self.bounding().unwrap();
self.translate(-bounding.min().x, 0.)
}
fn translate_top(&self) -> Self {
let bounding = self.bounding().unwrap();
self.translate(0., -bounding.min().y)
}
}