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 authored and michaelkirk committed Jun 21, 2024
1 parent a5759db commit 2f1f44f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 7 deletions.
80 changes: 80 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,35 @@ 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 an m-coordinate.");
} 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 both a z- and m-coordinate");
}
}
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 +389,57 @@ mod tests {
);
}

#[test]
fn test_points() {
// point(x, y)
let wkt = <Wkt<f64>>::from_str("POINT (10 20.1)").ok().unwrap();
match wkt.item {
Geometry::Point(Point(Some(coord))) => {
assert_eq!(coord.x, 10.0);
assert_eq!(coord.y, 20.1);
assert_eq!(coord.z, None);
assert_eq!(coord.m, None);
}
_ => panic!("excepted to be parsed as a POINT"),
}

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

// point(x, y, m)
let wkt = <Wkt<f64>>::from_str("POINTM (10 20.1 80)").ok().unwrap();
match wkt.item {
Geometry::Point(Point(Some(coord))) => {
assert_eq!(coord.x, 10.0);
assert_eq!(coord.y, 20.1);
assert_eq!(coord.z, None);
assert_eq!(coord.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();
match wkt.item {
Geometry::Point(Point(Some(coord))) => {
assert_eq!(coord.x, 10.0);
assert_eq!(coord.y, 20.1);
assert_eq!(coord.z, Some(5.0));
assert_eq!(coord.m, Some(80.0));
}
_ => panic!("excepted to be parsed as a 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 2f1f44f

Please sign in to comment.