1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use geo_types::GeometryCollection;
use geojson::{Error, GeoJson};
use num_traits::{Float, Num, NumCast};
use std::str::FromStr;
#[cfg(test)]
mod tests;
pub fn from_str<T>(s: &str) -> Result<GeometryCollection<T>, Error>
where
T: Num + NumCast + PartialOrd + Copy + Float,
{
let geojson = GeoJson::from_str(s)?;
Ok(match geojson {
GeoJson::Feature(feature) => conversion::from_feature(feature),
GeoJson::FeatureCollection(feature_collection) => {
conversion::from_feature_collection(feature_collection)
}
GeoJson::Geometry(geometry) => conversion::from_geometry(geometry),
})
}
pub mod conversion {
use geo_types::{
GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon,
};
use geojson::{Feature, FeatureCollection, Geometry, Value};
use num_traits::{Float, Num, NumCast};
use std::convert::TryInto;
pub fn from_feature<T>(feature: Feature) -> GeometryCollection<T>
where
T: Num + NumCast + PartialOrd + Copy + Float,
{
feature
.geometry
.map(from_geometry)
.unwrap_or_else(GeometryCollection::new)
}
pub fn from_feature_collection<T>(
feature_collection: FeatureCollection,
) -> GeometryCollection<T>
where
T: Num + NumCast + PartialOrd + Copy + Float,
{
feature_collection
.features
.into_iter()
.flat_map(from_feature)
.collect()
}
pub fn from_geometry<T>(geometry: Geometry) -> GeometryCollection<T>
where
T: Num + NumCast + PartialOrd + Copy + Float,
{
from_value(geometry.value)
}
pub fn from_value<T>(value: Value) -> GeometryCollection<T>
where
T: Num + NumCast + PartialOrd + Copy + Float,
{
match value {
Value::Point(_) => TryInto::<Point<T>>::try_into(value)
.map(|value| GeometryCollection(vec![value.into()])),
Value::MultiPoint(_) => TryInto::<MultiPoint<T>>::try_into(value)
.map(|value| GeometryCollection(vec![value.into()])),
Value::LineString(_) => TryInto::<LineString<T>>::try_into(value)
.map(|value| GeometryCollection(vec![value.into()])),
Value::MultiLineString(_) => TryInto::<MultiLineString<T>>::try_into(value)
.map(|value| GeometryCollection(vec![value.into()])),
Value::Polygon(_) => TryInto::<Polygon<T>>::try_into(value)
.map(|value| GeometryCollection(vec![value.into()])),
Value::MultiPolygon(_) => TryInto::<MultiPolygon<T>>::try_into(value)
.map(|value| GeometryCollection(vec![value.into()])),
Value::GeometryCollection(geometry_collection) => Ok(geometry_collection
.into_iter()
.flat_map(from_geometry)
.collect()),
}
.unwrap_or_else(|_| GeometryCollection::new())
}
}