geojson/conversion/mod.rs
1// Copyright 2015 The GeoRust Developers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use geo_types::CoordFloat;
16
17use crate::geojson::GeoJson;
18
19use crate::Result;
20use std::convert::TryFrom;
21
22#[cfg(test)]
23macro_rules! assert_almost_eq {
24 ($x:expr, $y:expr, $epsilon:expr) => {{
25 use num_traits::Zero;
26 let a = $x.abs();
27 let b = $y.abs();
28 let delta = (a - b).abs();
29
30 if a.is_infinite() || a.is_nan() || b.is_infinite() || b.is_nan() {
31 panic!(
32 "Assertion failed: Non comparable value ({} = {}, {} = {})",
33 stringify!($x),
34 $x,
35 stringify!($y),
36 $y
37 );
38 } else if a.is_zero() || b.is_zero() {
39 if delta > $epsilon {
40 panic!(
41 "Assertion failed: ({} = {}, {} = {}, delta = {})",
42 stringify!($x),
43 $x,
44 stringify!($y),
45 $y,
46 delta / b
47 );
48 }
49 } else {
50 let normalized_delta = delta / b;
51 if normalized_delta > $epsilon {
52 panic!(
53 "Assertion failed: ({} = {}, {} = {}, delta = {})",
54 stringify!($x),
55 $x,
56 stringify!($y),
57 $y,
58 normalized_delta
59 );
60 }
61 }
62 }};
63}
64
65macro_rules! try_from_owned_value {
66 ($to:ty) => {
67 #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))]
68 impl<T: CoordFloat> TryFrom<geometry::Value> for $to {
69 type Error = Error;
70
71 fn try_from(value: geometry::Value) -> Result<Self> {
72 (&value).try_into()
73 }
74 }
75 };
76}
77
78pub(crate) mod from_geo_types;
79pub(crate) mod to_geo_types;
80
81/// A shortcut for producing `geo_types` [GeometryCollection](../geo_types/struct.GeometryCollection.html) objects
82/// from arbitrary valid GeoJSON input.
83///
84/// This function is primarily intended for easy processing of GeoJSON `FeatureCollection`
85/// objects using the `geo` crate, and sacrifices a little performance for convenience.
86/// # Example
87///
88/// ```
89/// use geo_types::{Geometry, GeometryCollection, Point};
90/// #[allow(deprecated)]
91/// use geojson::{quick_collection, GeoJson};
92///
93/// let geojson_str = r#"
94/// {
95/// "type": "FeatureCollection",
96/// "features": [
97/// {
98/// "type": "Feature",
99/// "properties": {},
100/// "geometry": {
101/// "type": "Point",
102/// "coordinates": [-1.0, 2.0]
103/// }
104/// }
105/// ]
106/// }
107/// "#;
108/// let geojson = geojson_str.parse::<GeoJson>().unwrap();
109/// // Turn the GeoJSON string into a geo_types GeometryCollection
110/// #[allow(deprecated)]
111/// let mut collection: GeometryCollection<f64> = quick_collection(&geojson).unwrap();
112/// assert_eq!(collection[0], Geometry::Point(Point::new(-1.0, 2.0)))
113/// ```
114#[deprecated(
115 since = "0.24.1",
116 note = "use `geo_types::GeometryCollection::try_from(&geojson)` instead"
117)]
118#[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))]
119pub fn quick_collection<T>(gj: &GeoJson) -> Result<geo_types::GeometryCollection<T>>
120where
121 T: CoordFloat,
122{
123 geo_types::GeometryCollection::try_from(gj)
124}