extern crate geo_types;
extern crate num_traits;
use std::io;
use std::io::prelude::*;
use geo_types::*;
use num_traits::Float;
pub trait WKBReadExt {
fn read_wkb(&mut self) -> Result<Geometry<f64>, WKBReadError>;
}
impl<R: Read> WKBReadExt for R {
#[inline]
fn read_wkb(&mut self) -> Result<Geometry<f64>, WKBReadError>
{
wkb_to_geom(self)
}
}
pub trait WKBWriteExt {
fn write_wkb<T>(&mut self, g: &Geometry<T>) -> Result<(), WKBWriteError>
where
T: Into<f64>+Float;
}
impl<W: Write> WKBWriteExt for W {
fn write_wkb<T>(&mut self, g: &Geometry<T>) -> Result<(), WKBWriteError>
where
T: Into<f64>+Float,
{
write_geom_to_wkb(g, self)
}
}
#[derive(Debug)]
pub enum WKBReadError {
UnsupportedBigEndian,
WrongType,
IOError(io::Error),
}
impl From<io::Error> for WKBReadError {
fn from(err: io::Error) -> WKBReadError {
WKBReadError::IOError(err)
}
}
pub trait WKBAbleExt {
fn write_as_wkb(&self, w: &mut impl Write) -> Result<(), WKBWriteError>;
fn as_wkb_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
self.write_as_wkb(&mut bytes).unwrap();
bytes
}
fn read_from_wkb(r: &mut impl Read) -> Result<Self, WKBReadError> where Self: Sized;
}
impl WKBAbleExt for Geometry<f64>
{
fn write_as_wkb(&self, w: &mut impl Write) -> Result<(), WKBWriteError>
{
write_geom_to_wkb(self, w)
}
fn read_from_wkb(r: &mut impl Read) -> Result<Self, WKBReadError>
{
wkb_to_geom(r)
}
}
#[derive(Debug)]
pub enum WKBWriteError {
UnsupportedGeoTypeRect,
UnsupportedGeoTypeTriangle,
IOError(io::Error),
}
impl From<io::Error> for WKBWriteError {
fn from(err: io::Error) -> WKBWriteError {
WKBWriteError::IOError(err)
}
}
fn read_f64(mut rdr: impl Read) -> Result<f64, std::io::Error> {
let mut bytes = [0; 8];
rdr.read_exact(&mut bytes)?;
Ok(f64::from_le_bytes(bytes))
}
fn read_u32(mut rdr: impl Read) -> Result<u32, std::io::Error> {
let mut bytes = [0; 4];
rdr.read_exact(&mut bytes)?;
Ok(u32::from_le_bytes(bytes))
}
fn read_u8(mut rdr: impl Read) -> Result<u8, std::io::Error> {
let mut bytes = [0; 1];
rdr.read_exact(&mut bytes)?;
Ok(bytes[0])
}
fn read_point(mut wkb: impl Read) -> Result<Coordinate<f64>, WKBReadError> {
let x: f64 = read_f64(&mut wkb)?;
let y: f64 = read_f64(&mut wkb)?;
Ok(Coordinate { x, y })
}
fn write_point<W: Write, T: Into<f64> + Float>(
c: &Coordinate<T>,
out: &mut W,
) -> Result<(), WKBWriteError> {
out.write_all(&c.x.into().to_le_bytes())?;
out.write_all(&c.y.into().to_le_bytes())?;
Ok(())
}
fn read_many_points<I: Read>(mut wkb: I) -> Result<Vec<Coordinate<f64>>, WKBReadError> {
let num_points = read_u32(&mut wkb)? as usize;
let mut res: Vec<Coordinate<f64>> = Vec::with_capacity(num_points);
for _ in 0..num_points {
res.push(read_point(&mut wkb)?);
}
Ok(res)
}
fn write_many_points<W: Write, T: Into<f64> + Float>(
mp: &[Coordinate<T>],
mut out: &mut W,
) -> Result<(), WKBWriteError> {
out.write_all(&(mp.len() as u32).to_le_bytes())?;
for p in mp.iter() {
write_point(p, &mut out)?;
}
Ok(())
}
pub fn geom_to_wkb<T: Into<f64> + Float>(geom: &Geometry<T>) -> Result<Vec<u8>, WKBWriteError> {
let mut result: Vec<u8> = Vec::new();
write_geom_to_wkb(geom, &mut result)?;
Ok(result)
}
pub fn write_geom_to_wkb<W, T>(
geom: &Geometry<T>,
mut result: &mut W,
) -> Result<(), WKBWriteError>
where T: Into<f64>+Float,
W: Write + ?Sized,
{
result.write(&[1])?;
match geom {
&Geometry::Point(p) => {
result.write_all(&1_u32.to_le_bytes())?;
write_point(&p.0, &mut result)?;
}
&Geometry::LineString(ref ls) => {
result.write_all(&2_u32.to_le_bytes())?;
write_many_points(&ls.0, &mut result)?;
}
&Geometry::Line(ref l) => {
write_many_points(&[l.start, l.end], &mut result)?;
}
&Geometry::Polygon(ref p) => {
result.write_all(&(3_u32).to_le_bytes())?;
result.write_all(&(1 + p.interiors().len() as u32).to_le_bytes())?;
write_many_points(&p.exterior().0, &mut result)?;
for i in p.interiors().iter() {
write_many_points(&i.0, &mut result)?;
}
}
&Geometry::MultiPoint(ref mp) => {
result.write_all(&(4_u32).to_le_bytes())?;
write_many_points(
&mp.0.iter().map(|p| p.0).collect::<Vec<Coordinate<T>>>(),
&mut result,
)?;
}
&Geometry::MultiLineString(ref mls) => {
result.write_all(&(5_u32).to_le_bytes())?;
result.write_all(&(mls.0.len() as u32).to_le_bytes())?;
for ls in mls.0.iter() {
result.write(&[1])?;
result.write_all(&(2_u32).to_le_bytes())?;
write_many_points(&ls.0, &mut result)?;
}
}
&Geometry::MultiPolygon(ref mp) => {
result.write_all(&(6_u32).to_le_bytes())?;
result.write_all(&(mp.0.len() as u32).to_le_bytes())?;
for poly in mp.0.iter() {
result.write(&[1])?;
result.write_all(&(3_u32).to_le_bytes())?;
result.write_all(&(1 + poly.interiors().len() as u32).to_le_bytes())?;
write_many_points(&poly.exterior().0, &mut result)?;
for int in poly.interiors().iter() {
write_many_points(&int.0, &mut result)?;
}
}
}
&Geometry::GeometryCollection(ref gc) => {
result.write_all(&(7_u32).to_le_bytes())?;
result.write_all(&(gc.len() as u32).to_le_bytes())?;
for geom in gc.0.iter() {
write_geom_to_wkb(geom, result)?;
}
}
&Geometry::Rect(ref _rect) => {
return Err(WKBWriteError::UnsupportedGeoTypeRect);
}
&Geometry::Triangle(ref _t) => {
return Err(WKBWriteError::UnsupportedGeoTypeTriangle);
}
}
Ok(())
}
pub fn wkb_to_geom<R>(mut wkb: &mut R) -> Result<Geometry<f64>, WKBReadError>
where R: Read + ?Sized
{
match read_u8(&mut wkb)? {
0 => {
return Err(WKBReadError::UnsupportedBigEndian);
}
1 => {}
_ => panic!(),
};
match read_u32(&mut wkb)? {
1 => {
Ok(Geometry::Point(Point(read_point(&mut wkb)?)))
}
2 => {
let points = read_many_points(&mut wkb)?;
Ok(Geometry::LineString(LineString(points)))
}
3 => {
let num_rings = read_u32(&mut wkb)? as usize;
let exterior = read_many_points(&mut wkb)?;
let mut interiors = Vec::with_capacity(num_rings - 1);
for _ in 0..(num_rings - 1) {
interiors.push(LineString(read_many_points(&mut wkb)?));
}
Ok(Geometry::Polygon(Polygon::new(
LineString(exterior),
interiors,
)))
}
4 => {
let points = read_many_points(&mut wkb)?;
Ok(Geometry::MultiPoint(MultiPoint(
points.into_iter().map(Point).collect::<Vec<Point<f64>>>(),
)))
}
5 => {
let num_linestrings = read_u32(&mut wkb)? as usize;
let mut linestrings = Vec::with_capacity(num_linestrings);
for _ in 0..num_linestrings {
let linestring: LineString<f64> = match wkb_to_geom(wkb)? {
Geometry::LineString(l) => l,
_ => {
return Err(WKBReadError::WrongType);
}
};
linestrings.push(linestring);
}
Ok(Geometry::MultiLineString(MultiLineString(linestrings)))
}
6 => {
let num_polygons = read_u32(&mut wkb)? as usize;
let mut polygons = Vec::with_capacity(num_polygons);
for _ in 0..num_polygons {
let polygon: Polygon<f64> = match wkb_to_geom(wkb)? {
Geometry::Polygon(p) => p,
_ => {
return Err(WKBReadError::WrongType);
}
};
polygons.push(polygon);
}
Ok(Geometry::MultiPolygon(MultiPolygon(polygons)))
}
_ => unimplemented!(),
}
}
#[cfg(test)]
mod tests {
use super::*;
fn assert_two_f64(mut reader: &mut impl Read, a: impl Into<f64>, b: impl Into<f64>) {
assert_eq!(read_f64(&mut reader).unwrap(), a.into());
assert_eq!(read_f64(&mut reader).unwrap(), b.into());
}
fn write_two_f64<W: Write>(writer: &mut W, a: impl Into<f64>, b: impl Into<f64>) {
writer.write_all(&a.into().to_le_bytes()).unwrap();
writer.write_all(&b.into().to_le_bytes()).unwrap();
}
#[test]
fn point_to_wkb() {
let p: Geometry<f64> = Geometry::Point(Point::new(2., 4.));
let res = geom_to_wkb(&p).unwrap();
let mut res = res.as_slice();
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 1);
assert_two_f64(&mut res, 2, 4);
assert_eq!(
wkb_to_geom(&mut geom_to_wkb(&p).unwrap().as_slice()).unwrap(),
p
);
}
#[test]
fn wkb_to_point() {
let mut bytes = Vec::new();
bytes.write(&[1]).unwrap();
bytes.write_all(&(1_u32).to_le_bytes()).unwrap();
bytes.write_all(&(100f64).to_le_bytes()).unwrap();
bytes.write_all(&(-2f64).to_le_bytes()).unwrap();
let geom = wkb_to_geom(&mut bytes.as_slice()).unwrap();
if let Geometry::Point(p) = geom {
assert_eq!(p.x(), 100.);
assert_eq!(p.y(), -2.);
} else {
assert!(false);
}
assert_eq!(
geom_to_wkb(&wkb_to_geom(&mut bytes.as_slice()).unwrap()).unwrap(),
bytes
);
}
#[test]
fn linestring_to_wkb() {
let ls: LineString<f64> = vec![(0., 0.), (1., 0.), (1., 1.), (0., 1.), (0., 0.)].into();
let ls = Geometry::LineString(ls);
let res = geom_to_wkb(&ls).unwrap();
let mut res = res.as_slice();
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u32(&mut res).unwrap(), 5);
assert_two_f64(&mut res, 0, 0);
assert_two_f64(&mut res, 1, 0);
assert_two_f64(&mut res, 1, 1);
assert_two_f64(&mut res, 0, 1);
assert_two_f64(&mut res, 0, 0);
assert_eq!(
wkb_to_geom(&mut geom_to_wkb(&ls).unwrap().as_slice()).unwrap(),
ls
);
}
#[test]
fn wkb_to_linestring() {
let mut bytes = Vec::new();
bytes.write(&[1]).unwrap();
bytes.write_all(&(2_u32).to_le_bytes()).unwrap();
bytes.write_all(&(2_u32).to_le_bytes()).unwrap();
write_two_f64(&mut bytes, 0, 0);
write_two_f64(&mut bytes, 1000, 1000);
let geom = wkb_to_geom(&mut bytes.as_slice()).unwrap();
if let Geometry::LineString(ls) = geom {
assert_eq!(ls.0.len(), 2);
assert_eq!(ls.0[0].x, 0.);
assert_eq!(ls.0[0].y, 0.);
assert_eq!(ls.0[1].x, 1000.);
assert_eq!(ls.0[1].y, 1000.);
} else {
assert!(false);
}
assert_eq!(
geom_to_wkb(&wkb_to_geom(&mut bytes.as_slice()).unwrap()).unwrap(),
bytes
);
}
#[test]
fn polygon_to_wkb() {
let ls = vec![(0., 0.), (10., 0.), (10., 10.), (0., 10.), (0., 0.)].into();
let int = vec![(2., 2.), (2., 4.), (4., 4.), (4., 2.), (2., 2.)].into();
let p = Geometry::Polygon(Polygon::new(ls, vec![int]));
let res = geom_to_wkb(&p).unwrap();
let mut res = res.as_slice();
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 3);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u32(&mut res).unwrap(), 5);
assert_two_f64(&mut res, 0, 0);
assert_two_f64(&mut res, 10, 0);
assert_two_f64(&mut res, 10, 10);
assert_two_f64(&mut res, 0, 10);
assert_two_f64(&mut res, 0, 0);
assert_eq!(read_u32(&mut res).unwrap(), 5);
assert_two_f64(&mut res, 2, 2);
assert_two_f64(&mut res, 2, 4);
assert_two_f64(&mut res, 4, 4);
assert_two_f64(&mut res, 4, 2);
assert_two_f64(&mut res, 2, 2);
assert_eq!(
wkb_to_geom(&mut geom_to_wkb(&p).unwrap().as_slice()).unwrap(),
p
);
}
#[test]
fn wkb_to_polygon() {
let mut bytes = Vec::new();
bytes.write(&[1]).unwrap();
bytes.write_all(&(3_u32).to_le_bytes()).unwrap();
bytes.write_all(&(1_u32).to_le_bytes()).unwrap();
bytes.write_all(&(4_u32).to_le_bytes()).unwrap();
write_two_f64(&mut bytes, 0, 0);
write_two_f64(&mut bytes, 1, 0);
write_two_f64(&mut bytes, 0, 1);
write_two_f64(&mut bytes, 0, 0);
let geom = wkb_to_geom(&mut bytes.as_slice()).unwrap();
if let Geometry::Polygon(p) = geom {
assert_eq!(p.interiors().len(), 0);
assert_eq!(p.exterior().0.len(), 4);
assert_eq!(p.exterior().0[0], (0., 0.).into());
assert_eq!(p.exterior().0[1], (1., 0.).into());
assert_eq!(p.exterior().0[2], (0., 1.).into());
assert_eq!(p.exterior().0[3], (0., 0.).into());
} else {
assert!(false);
}
assert_eq!(
geom_to_wkb(&wkb_to_geom(&mut bytes.as_slice()).unwrap()).unwrap(),
bytes
);
}
#[test]
fn wkb_to_polygon_auto_closed() {
let mut bytes = Vec::new();
bytes.write(&[1]).unwrap();
bytes.write_all(&(3_u32).to_le_bytes()).unwrap();
bytes.write_all(&(1_u32).to_le_bytes()).unwrap();
bytes.write_all(&(3_u32).to_le_bytes()).unwrap();
write_two_f64(&mut bytes, 0, 0);
write_two_f64(&mut bytes, 1, 0);
write_two_f64(&mut bytes, 0, 1);
let geom = wkb_to_geom(&mut bytes.as_slice()).unwrap();
if let Geometry::Polygon(p) = geom {
assert_eq!(p.interiors().len(), 0);
assert_eq!(p.exterior().0[0], (0., 0.).into());
assert_eq!(p.exterior().0[1], (1., 0.).into());
assert_eq!(p.exterior().0[2], (0., 1.).into());
assert_eq!(p.exterior().0[3], (0., 0.).into());
assert_eq!(p.exterior().0.len(), 4);
} else {
assert!(false);
}
assert_ne!(
geom_to_wkb(&wkb_to_geom(&mut bytes.as_slice()).unwrap()).unwrap(),
bytes
);
}
#[test]
fn multipoint_to_wkb() {
let p: Geometry<f64> =
Geometry::MultiPoint(MultiPoint(vec![Point::new(0., 0.), Point::new(10., -2.)]));
let res = geom_to_wkb(&p).unwrap();
let mut res = res.as_slice();
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 4);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_two_f64(&mut res, 0, 0);
assert_two_f64(&mut res, 10, -2);
assert_eq!(
wkb_to_geom(&mut geom_to_wkb(&p).unwrap().as_slice()).unwrap(),
p
);
}
#[test]
fn wkb_to_multipoint() {
let mut bytes = Vec::new();
bytes.write(&[1]).unwrap();
bytes.write_all(&(4_u32).to_le_bytes()).unwrap();
bytes.write_all(&(1_u32).to_le_bytes()).unwrap();
write_two_f64(&mut bytes, 100, -2);
let geom = wkb_to_geom(&mut bytes.as_slice()).unwrap();
if let Geometry::MultiPoint(mp) = geom {
assert_eq!(mp.0.len(), 1);
assert_eq!(mp.0[0].x(), 100.);
assert_eq!(mp.0[0].y(), -2.);
} else {
assert!(false);
}
assert_eq!(
geom_to_wkb(&wkb_to_geom(&mut bytes.as_slice()).unwrap()).unwrap(),
bytes
);
}
#[test]
fn multilinestring_to_wkb() {
let ls = Geometry::MultiLineString(MultiLineString(vec![
vec![(0., 0.), (1., 1.)].into(),
vec![(10., 10.), (10., 11.)].into(),
]));
let res = geom_to_wkb(&ls).unwrap();
let mut res = res.as_slice();
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 5);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_two_f64(&mut res, 0, 0);
assert_two_f64(&mut res, 1, 1);
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_two_f64(&mut res, 10, 10);
assert_two_f64(&mut res, 10, 11);
assert_eq!(
wkb_to_geom(&mut geom_to_wkb(&ls).unwrap().as_slice()).unwrap(),
ls
);
}
#[test]
fn wkb_to_multilinestring() {
let mut bytes = Vec::new();
bytes.write(&[1]).unwrap();
bytes.write_all(&(5_u32).to_le_bytes()).unwrap();
bytes.write_all(&(1_u32).to_le_bytes()).unwrap();
bytes.write(&[1]).unwrap();
bytes.write_all(&(2_u32).to_le_bytes()).unwrap();
bytes.write_all(&(3_u32).to_le_bytes()).unwrap();
write_two_f64(&mut bytes, 0, 0);
write_two_f64(&mut bytes, 1, 0);
write_two_f64(&mut bytes, 0, 1);
let geom = wkb_to_geom(&mut bytes.as_slice()).unwrap();
if let Geometry::MultiLineString(mls) = geom {
assert_eq!(mls.0.len(), 1);
assert_eq!(mls.0[0].0.len(), 3);
assert_eq!(mls.0[0].0[0].x_y(), (0., 0.));
assert_eq!(mls.0[0].0[1].x_y(), (1., 0.));
assert_eq!(mls.0[0].0[2].x_y(), (0., 1.));
} else {
assert!(false);
}
assert_eq!(
geom_to_wkb(&wkb_to_geom(&mut bytes.as_slice()).unwrap()).unwrap(),
bytes
);
}
#[test]
fn multipolygon_to_wkb() {
let ls = vec![(0., 0.), (10., 0.), (10., 10.), (0., 10.), (0., 0.)].into();
let int = vec![(2., 2.), (2., 4.), (2., 2.)].into();
let p1 = Polygon::new(ls, vec![]);
let p2 = Polygon::new(int, vec![]);
let p = Geometry::MultiPolygon(MultiPolygon(vec![p1, p2]));
let res = geom_to_wkb(&p).unwrap();
let mut res = res.as_slice();
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 6);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 3);
assert_eq!(read_u32(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 5);
assert_two_f64(&mut res, 0, 0);
assert_two_f64(&mut res, 10, 0);
assert_two_f64(&mut res, 10, 10);
assert_two_f64(&mut res, 0, 10);
assert_two_f64(&mut res, 0, 0);
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 3);
assert_eq!(read_u32(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 3);
assert_two_f64(&mut res, 2, 2);
assert_two_f64(&mut res, 2, 4);
assert_two_f64(&mut res, 2, 2);
assert_eq!(
wkb_to_geom(&mut geom_to_wkb(&p).unwrap().as_slice()).unwrap(),
p
);
}
#[test]
fn postgis_wkb_to_multipolygon() {
let bytes: Vec<u8> = vec![
0x01, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
];
let geom = wkb_to_geom(&mut bytes.as_slice()).unwrap();
if let Geometry::MultiPolygon(mp) = geom {
assert_eq!(mp.0.len(), 2);
assert_eq!(mp.0[0].exterior().0.len(), 5);
assert_eq!(mp.0[0].exterior().0[0].x_y(), (0., 0.));
assert_eq!(mp.0[0].exterior().0[1].x_y(), (10., 0.));
assert_eq!(mp.0[0].exterior().0[2].x_y(), (10., 10.));
assert_eq!(mp.0[0].exterior().0[3].x_y(), (0., 10.));
assert_eq!(mp.0[0].exterior().0[4].x_y(), (0., 0.));
assert_eq!(mp.0[0].interiors().len(), 0);
assert_eq!(mp.0[1].exterior().0.len(), 4);
assert_eq!(mp.0[1].exterior().0[0].x_y(), (2., 2.));
assert_eq!(mp.0[1].exterior().0[1].x_y(), (2., 4.));
assert_eq!(mp.0[1].exterior().0[2].x_y(), (4., 2.));
assert_eq!(mp.0[1].exterior().0[0].x_y(), (2., 2.));
assert_eq!(mp.0[1].interiors().len(), 0);
} else {
assert!(false);
}
}
#[test]
fn geometrycollection_to_wkb() {
let p: Geometry<_> = Point::new(0., 0.).into();
let l: Geometry<_> = LineString(vec![(10., 0.).into(), (20., 0.).into()]).into();
let gc: Geometry<_> = Geometry::GeometryCollection(GeometryCollection(vec![p, l]));
let res = geom_to_wkb(&gc).unwrap();
let mut res = res.as_slice();
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 7);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 1);
assert_two_f64(&mut res, 0, 0);
assert_eq!(read_u8(&mut res).unwrap(), 1);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_eq!(read_u32(&mut res).unwrap(), 2);
assert_two_f64(&mut res, 10, 0);
assert_two_f64(&mut res, 20, 0);
}
#[test]
fn test_simple_multilinestring1() {
let wkb: Vec<u8> = vec![
1, 5, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 240, 63,
];
let geom = wkb_to_geom(&mut wkb.as_slice()).unwrap();
assert_eq!(
geom,
Geometry::MultiLineString(MultiLineString(vec![vec![(0., 0.), (1., 1.)].into(),]))
);
}
#[test]
fn test_simple_multilinestring2() {
let wkb: Vec<u8> = vec![
0x01, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
];
let geom = wkb_to_geom(&mut wkb.as_slice()).unwrap();
assert_eq!(
geom,
Geometry::MultiLineString(MultiLineString(vec![
vec![(0., 0.), (1., 1.)].into(),
vec![(2., 2.), (3., 2.)].into(),
]))
);
}
#[test]
fn bigendian_not_supported() {
let mut bytes = Vec::new();
bytes.write(&[0]).unwrap();
bytes.write_all(&1_u32.to_be_bytes()).unwrap();
let res = wkb_to_geom(&mut bytes.as_slice());
assert!(res.is_err());
}
}