Skip to content

Commit

Permalink
Support parse POINTZ, POINTM and POINTZM
Browse files Browse the repository at this point in the history
  • Loading branch information
ariesdevil committed Feb 7, 2024
1 parent a5759db commit eed7f42
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
56 changes: 56 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,37 @@ where
let x = <Point<T> as FromTokens<T>>::from_tokens_with_parens(tokens);
x.map(|y| y.as_item())
}
w if w.eq_ignore_ascii_case("POINTZ") => {
let x = <Point<T> as FromTokens<T>>::from_tokens_with_parens(tokens)?;
if let Some(coord) = &x.0 {
if coord.z.is_none() {
return Err("POINTZ must have a z-coordinate.");
}
}
Ok(x.as_item())
}
w if w.eq_ignore_ascii_case("POINTM") => {
let mut x = <Point<T> as FromTokens<T>>::from_tokens_with_parens(tokens)?;
if let Some(coord) = &mut x.0 {
if coord.z.is_none() {
return Err("POINTM must have a linear referencing system.");
} else {
coord.m = coord.z.take();
}
}
Ok(x.as_item())
}
w if w.eq_ignore_ascii_case("POINTZM") => {
let x = <Point<T> as FromTokens<T>>::from_tokens_with_parens(tokens)?;
if let Some(coord) = &x.0 {
if coord.z.is_none() || coord.m.is_none() {
return Err(
"POINTZM must have z-coordinate and linear referencing system.",
);
}
}
Ok(x.as_item())
}
w if w.eq_ignore_ascii_case("LINESTRING") || w.eq_ignore_ascii_case("LINEARRING") => {
let x = <LineString<T> as FromTokens<T>>::from_tokens_with_parens(tokens);
x.map(|y| y.as_item())
Expand Down Expand Up @@ -360,6 +391,31 @@ mod tests {
);
}

#[test]
fn test_points() {
// point(x, y)
let wkt = <Wkt<f64>>::from_str("POINT (10 20.1)").ok().unwrap();
assert!(matches!(wkt.item, Geometry::Point(_)));

// point(x, y, z)
let wkt = <Wkt<f64>>::from_str("POINTZ (10 20.1 5)").ok().unwrap();
assert!(matches!(wkt.item, Geometry::Point(_)));

// point(x, y, m)
let wkt = <Wkt<f64>>::from_str("POINTM (10 20.1 80)").ok().unwrap();
match wkt.item {
Geometry::Point(p) => assert_eq!(
format!("{:?}", p),
"Point(Some(Coord { x: 10.0, y: 20.1, z: None, m: Some(80.0) }))"
),
_ => panic!("excepted to be parsed as a POINT"),
}

// point(x, y, z, m)
let wkt = <Wkt<f64>>::from_str("POINTZM (10 20.1 5 80)").ok().unwrap();
assert!(matches!(wkt.item, Geometry::Point(_)));
}

#[test]
fn support_jts_linearring() {
let wkt: Wkt<f64> = Wkt::from_str("linearring (10 20, 30 40)").ok().unwrap();
Expand Down
25 changes: 19 additions & 6 deletions src/types/coord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,25 @@ where
Some(Token::Number(n)) => n,
_ => return Err("Expected a number for the Y coordinate"),
};
Ok(Coord {
x,
y,
z: None,
m: None,
})

let mut z = None;
let mut m = None;

if let Some(Ok(Token::Number(_))) = tokens.peek() {
z = match tokens.next().transpose()? {
Some(Token::Number(n)) => Some(n),
_ => None,
};

if let Some(Ok(Token::Number(_))) = tokens.peek() {
m = match tokens.next().transpose()? {
Some(Token::Number(n)) => Some(n),
_ => None,
};
}
}

Ok(Coord { x, y, z, m })
}
}

Expand Down
1 change: 0 additions & 1 deletion src/types/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ mod tests {
<Wkt<f64>>::from_str("POINT ()").err().unwrap();
<Wkt<f64>>::from_str("POINT (10)").err().unwrap();
<Wkt<f64>>::from_str("POINT 10").err().unwrap();
<Wkt<f64>>::from_str("POINT (10 -20 40)").err().unwrap();
}

#[test]
Expand Down

0 comments on commit eed7f42

Please sign in to comment.