Skip to content

Reconsider design of core structures #32

@frewsxcv

Description

@frewsxcv

Right now, it's possible to model this with the current design:

LineString(vec![
    Coord { x: 1, y: 1, None, None },
    Coord { x: 1, y: 1, Some(1), None },
])

...which translates to something like:

LINESTRING ( 1 1, 1 1 1 )

...which doesn't make any sense since the first item has two dimensions but the second item has three dimensions.

We can change the core structures to a different design to enforce all items having the same dimensions:

(Keep in mind, this design is not final and is just a rought draft)

pub trait Dimension {
    fn from_quad(x: f64, y: f64, z: Option<f64>, m: Option<f64>) -> Self;

    fn to_quad(&self) -> (f64, f64, Option<f64>, Option<f64>);
}

pub struct Xy(f64, f64);
impl Dimension for Xy {
    fn from_quad(x: f64, y: f64, _: Option<f64>, _: Option<f64>) -> Self {
        Xy(x, y)
    }

    fn to_quad(&self) -> (f64, f64, Option<f64>, Option<f64>) {
        (self.0, self.1, None, None)
    }
}

pub struct Xyz(f64, f64, f64);
impl Dimension for Xyz {
    fn from_quad(x: f64, y: f64, z: Option<f64>, _: Option<f64>) -> Self {
        Xyz(x, y, z.unwrap())
    }

    fn to_quad(&self) -> (f64, f64, Option<f64>, Option<f64>) {
        (self.0, self.1, Some(self.2), None)
    }
}

pub struct Xym(f64, f64, f64);
impl Dimension for Xym {
    fn from_quad(x: f64, y: f64, _: Option<f64>, m: Option<f64>) -> Self {
        Xym(x, y, m.unwrap())
    }

    fn to_quad(&self) -> (f64, f64, Option<f64>, Option<f64>) {
        (self.0, self.1, None, Some(self.2))
    }
}

pub struct Xyzm(f64, f64, f64, f64);
impl Dimension for Xyzm {
    fn from_quad(x: f64, y: f64, z: Option<f64>, m: Option<f64>) -> Self {
        Xyzm(x, y, z.unwrap(), m.unwrap())
    }

    fn to_quad(&self) -> (f64, f64, Option<f64>, Option<f64>) {
        (self.0, self.1, Some(self.2), Some(self.3))
    }
}

// Concrete types

pub enum Point<D: Dimension> {
    Empty,
    Value(D),
}

pub enum LineString<D: Dimension> {
    Empty,
    Value(Vec<D>),
}

pub enum Geometry<D: Dimension> {
    Empty,
    Point(Point<D>),
    LineString(LineString<D>),
    // ...
    GeometryCollection(Vec<Geometry<D>>),
}

playpen

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions