Skip to content

Commit 990ad56

Browse files
bors[bot]urschrei
andauthored
Merge #136
136: Add conversions from Line, Triangle, Rect and GeometryCollection r=michaelkirk a=urschrei Closes #133 Co-authored-by: Stephan Hügel <shugel@tcd.ie>
2 parents 1996487 + 24ace6b commit 990ad56

File tree

2 files changed

+136
-2
lines changed

2 files changed

+136
-2
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Add more granular errors
66
* `GeoJsonUnknownType` has been split into `NotAFeature` and `EmptyType`
77
* Add additional Value context to errors where possible
8+
* Add conversions from Geo-Types Line, Triangle, Rect and GeometryCollection
89

910
## 0.19.0
1011

src/conversion/from_geo_types.rs

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,42 @@ where
4646
}
4747
}
4848

49+
#[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))]
50+
impl<'a, T> From<&'a geo_types::Line<T>> for geometry::Value
51+
where
52+
T: Float,
53+
{
54+
fn from(line: &geo_types::Line<T>) -> Self {
55+
let coords = create_from_line_type(line);
56+
57+
geometry::Value::LineString(coords)
58+
}
59+
}
60+
61+
#[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))]
62+
impl<'a, T> From<&'a geo_types::Triangle<T>> for geometry::Value
63+
where
64+
T: Float,
65+
{
66+
fn from(triangle: &geo_types::Triangle<T>) -> Self {
67+
let coords = create_from_triangle_type(triangle);
68+
69+
geometry::Value::Polygon(coords)
70+
}
71+
}
72+
73+
#[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))]
74+
impl<'a, T> From<&'a geo_types::Rect<T>> for geometry::Value
75+
where
76+
T: Float,
77+
{
78+
fn from(rect: &geo_types::Rect<T>) -> Self {
79+
let coords = create_from_rect_type(rect);
80+
81+
geometry::Value::Polygon(coords)
82+
}
83+
}
84+
4985
#[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))]
5086
impl<'a, T> From<&'a geo_types::MultiLineString<T>> for geometry::Value
5187
where
@@ -108,14 +144,17 @@ where
108144
geo_types::Geometry::Point(ref point) => geometry::Value::from(point),
109145
geo_types::Geometry::MultiPoint(ref multi_point) => geometry::Value::from(multi_point),
110146
geo_types::Geometry::LineString(ref line_string) => geometry::Value::from(line_string),
147+
geo_types::Geometry::Line(ref line) => geometry::Value::from(line),
148+
geo_types::Geometry::Triangle(ref triangle) => geometry::Value::from(triangle),
149+
geo_types::Geometry::Rect(ref rect) => geometry::Value::from(rect),
150+
geo_types::Geometry::GeometryCollection(ref gc) => geometry::Value::from(gc),
111151
geo_types::Geometry::MultiLineString(ref multi_line_string) => {
112152
geometry::Value::from(multi_line_string)
113153
}
114154
geo_types::Geometry::Polygon(ref polygon) => geometry::Value::from(polygon),
115155
geo_types::Geometry::MultiPolygon(ref multi_polygon) => {
116156
geometry::Value::from(multi_polygon)
117157
}
118-
_ => panic!("GeometryCollection not allowed"),
119158
}
120159
}
121160
}
@@ -140,6 +179,30 @@ where
140179
.collect()
141180
}
142181

182+
fn create_from_line_type<T>(line_string: &geo_types::Line<T>) -> LineStringType
183+
where
184+
T: Float,
185+
{
186+
vec![
187+
create_point_type(&line_string.start_point()),
188+
create_point_type(&line_string.end_point()),
189+
]
190+
}
191+
192+
fn create_from_triangle_type<T>(triangle: &geo_types::Triangle<T>) -> PolygonType
193+
where
194+
T: Float,
195+
{
196+
create_polygon_type(&triangle.to_polygon())
197+
}
198+
199+
fn create_from_rect_type<T>(rect: &geo_types::Rect<T>) -> PolygonType
200+
where
201+
T: Float,
202+
{
203+
create_polygon_type(&rect.to_polygon())
204+
}
205+
143206
fn create_multi_line_string_type<T>(
144207
multi_line_string: &geo_types::MultiLineString<T>,
145208
) -> Vec<LineStringType>
@@ -189,7 +252,8 @@ mod tests {
189252
use crate::{Geometry, Value};
190253
use geo_types;
191254
use geo_types::{
192-
GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon,
255+
Coordinate, GeometryCollection, Line, LineString, MultiLineString, MultiPoint,
256+
MultiPolygon, Point, Polygon, Rect, Triangle,
193257
};
194258

195259
#[test]
@@ -253,6 +317,75 @@ mod tests {
253317
}
254318
}
255319

320+
#[test]
321+
fn geo_line_conversion_test() {
322+
let p1 = Point::new(40.02f64, 116.34f64);
323+
let p2 = Point::new(13.02f64, 24.34f64);
324+
325+
let geo_line = Line::new(p1, p2);
326+
let geojson_line_point = Value::from(&geo_line);
327+
328+
if let Value::LineString(c) = geojson_line_point {
329+
assert_almost_eq!(p1.x(), c[0][0], 1e-6);
330+
assert_almost_eq!(p1.y(), c[0][1], 1e-6);
331+
assert_almost_eq!(p2.x(), c[1][0], 1e-6);
332+
assert_almost_eq!(p2.y(), c[1][1], 1e-6);
333+
} else {
334+
panic!("Not valid geometry {:?}", geojson_line_point);
335+
}
336+
}
337+
338+
#[test]
339+
fn geo_triangle_conversion_test() {
340+
let c1 = Coordinate { x: 0., y: 0. };
341+
let c2 = Coordinate { x: 10., y: 20. };
342+
let c3 = Coordinate { x: 20., y: -10. };
343+
344+
let triangle = Triangle(c1, c2, c3);
345+
346+
let geojson_polygon = Value::from(&triangle);
347+
348+
// Geo-types Polygon construction introduces an extra vertex: let's check it!
349+
if let Value::Polygon(c) = geojson_polygon {
350+
assert_almost_eq!(c1.x as f64, c[0][0][0], 1e-6);
351+
assert_almost_eq!(c1.y as f64, c[0][0][1], 1e-6);
352+
assert_almost_eq!(c2.x as f64, c[0][1][0], 1e-6);
353+
assert_almost_eq!(c2.y as f64, c[0][1][1], 1e-6);
354+
assert_almost_eq!(c3.x as f64, c[0][2][0], 1e-6);
355+
assert_almost_eq!(c3.y as f64, c[0][2][1], 1e-6);
356+
assert_almost_eq!(c1.x as f64, c[0][3][0], 1e-6);
357+
assert_almost_eq!(c1.y as f64, c[0][3][1], 1e-6);
358+
} else {
359+
panic!("Not valid geometry {:?}", geojson_polygon);
360+
}
361+
}
362+
363+
#[test]
364+
fn geo_rect_conversion_test() {
365+
let c1 = Coordinate { x: 0., y: 0. };
366+
let c2 = Coordinate { x: 10., y: 20. };
367+
368+
let rect = Rect::new(c1, c2);
369+
370+
let geojson_polygon = Value::from(&rect);
371+
372+
// Geo-types Polygon construction introduces an extra vertex: let's check it!
373+
if let Value::Polygon(c) = geojson_polygon {
374+
assert_almost_eq!(c1.x as f64, c[0][0][0], 1e-6);
375+
assert_almost_eq!(c1.y as f64, c[0][0][1], 1e-6);
376+
assert_almost_eq!(c1.x as f64, c[0][1][0], 1e-6);
377+
assert_almost_eq!(c2.y as f64, c[0][1][1], 1e-6);
378+
assert_almost_eq!(c2.x as f64, c[0][2][0], 1e-6);
379+
assert_almost_eq!(c2.y as f64, c[0][2][1], 1e-6);
380+
assert_almost_eq!(c2.x as f64, c[0][3][0], 1e-6);
381+
assert_almost_eq!(c1.y as f64, c[0][3][1], 1e-6);
382+
assert_almost_eq!(c1.x as f64, c[0][4][0], 1e-6);
383+
assert_almost_eq!(c1.y as f64, c[0][4][1], 1e-6);
384+
} else {
385+
panic!("Not valid geometry {:?}", geojson_polygon);
386+
}
387+
}
388+
256389
#[test]
257390
fn geo_multi_line_string_conversion_test() {
258391
let p1 = Point::new(40.02f64, 116.34f64);

0 commit comments

Comments
 (0)