Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Don't panic when parsing invalid WKB (#74).
- Fix CI by removing georust container & fix clippy lint (#78)
- Remove trait wrappers to work around Rust 1.90 compiler regression (#77)
- Add lint warning for missing docs #80
- Remove unnecessary `unwrap`s #79
- Expose `Dimension` publicly #82
Expand Down
126 changes: 31 additions & 95 deletions src/writer/line.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,18 @@
use std::io::Write;

use geo_traits::{
GeometryTrait, LineStringTrait, LineTrait, UnimplementedGeometryCollection, UnimplementedLine,
UnimplementedMultiLineString, UnimplementedMultiPoint, UnimplementedMultiPolygon,
UnimplementedPoint, UnimplementedPolygon, UnimplementedRect, UnimplementedTriangle,
};

use crate::common::WkbType;
use crate::error::WkbResult;
use crate::writer::{line_string_wkb_size, write_line_string, WriteOptions};

/// A wrapper around an impl LineTrait to provide LineStringTrait
struct LineWrapper<'a, G: LineTrait<T = f64>>(&'a G);

impl<'a, G: LineTrait<T = f64>> LineStringTrait for LineWrapper<'a, G> {
type CoordType<'b>
= G::CoordType<'a>
where
G: 'b,
Self: 'b;

fn num_coords(&self) -> usize {
2
}

unsafe fn coord_unchecked(&self, i: usize) -> Self::CoordType<'_> {
match i {
0 => self.0.start(),
1 => self.0.end(),
_ => unreachable!(),
}
}
}
use crate::writer::coord::write_coord;
use crate::writer::WriteOptions;
use crate::Endianness;
use byteorder::{BigEndian, ByteOrder, LittleEndian, WriteBytesExt};
use geo_traits::LineTrait;
use std::io::Write;

/// The number of bytes this Line will take up when encoded as WKB
pub fn line_wkb_size(geom: &impl LineTrait<T = f64>) -> usize {
line_string_wkb_size(&LineWrapper(geom))
let header = 1 + 4 + 4;
let each_coord = geom.dim().size() * 8;
let all_coords = 2 * each_coord;
header + all_coords
}

/// Write a Line geometry to a Writer encoded as WKB
Expand All @@ -43,71 +21,29 @@ pub fn write_line(
geom: &impl LineTrait<T = f64>,
options: &WriteOptions,
) -> WkbResult<()> {
write_line_string(writer, &LineWrapper(geom), options)
// Byte order
writer.write_u8(options.endianness.into()).unwrap();

// Content
match options.endianness {
Endianness::LittleEndian => write_line_content::<LittleEndian>(writer, geom),
Endianness::BigEndian => write_line_content::<BigEndian>(writer, geom),
}
}

impl<G: LineTrait<T = f64>> GeometryTrait for LineWrapper<'_, G> {
type T = f64;
type PointType<'b>
= UnimplementedPoint<f64>
where
Self: 'b;
type LineStringType<'b>
= Self
where
Self: 'b;
type PolygonType<'b>
= UnimplementedPolygon<f64>
where
Self: 'b;
type MultiPointType<'b>
= UnimplementedMultiPoint<f64>
where
Self: 'b;
type MultiLineStringType<'b>
= UnimplementedMultiLineString<f64>
where
Self: 'b;
type MultiPolygonType<'b>
= UnimplementedMultiPolygon<f64>
where
Self: 'b;
type GeometryCollectionType<'b>
= UnimplementedGeometryCollection<f64>
where
Self: 'b;
type RectType<'b>
= UnimplementedRect<f64>
where
Self: 'b;
type LineType<'b>
= UnimplementedLine<f64>
where
Self: 'b;
type TriangleType<'b>
= UnimplementedTriangle<f64>
where
Self: 'b;
fn write_line_content<B: ByteOrder>(
writer: &mut impl Write,
geom: &impl LineTrait<T = f64>,
) -> WkbResult<()> {
let wkb_type = WkbType::LineString(geom.dim().try_into()?);
writer.write_u32::<B>(wkb_type.into())?;

fn dim(&self) -> geo_traits::Dimensions {
self.0.dim()
}
// numPoints
writer.write_u32::<B>(2).unwrap();

fn as_type(
&self,
) -> geo_traits::GeometryType<
'_,
Self::PointType<'_>,
Self::LineStringType<'_>,
Self::PolygonType<'_>,
Self::MultiPointType<'_>,
Self::MultiLineStringType<'_>,
Self::MultiPolygonType<'_>,
Self::GeometryCollectionType<'_>,
Self::RectType<'_>,
Self::TriangleType<'_>,
Self::LineType<'_>,
> {
geo_traits::GeometryType::LineString(self)
for coord in geom.coords() {
write_coord::<B>(writer, &coord)?;
}

Ok(())
}
Loading
Loading