geobuf/
lib.rs

1//! ```
2//! use geobuf::{decode, encode};
3//! use serde_json;
4//!
5//! let original_geojson = serde_json::from_str(r#"{"type": "Point", "coordinates": [100.0, 0.0]}"#).unwrap();
6//! let geobuf = encode::Encoder::encode(&original_geojson, 6, 2).unwrap();
7//! let geojson = decode::Decoder::decode(&geobuf).unwrap();
8//! assert_eq!(original_geojson, geojson);
9//! ```
10pub mod decode;
11pub mod encode;
12pub mod geobuf_pb;
13#[cfg(feature = "wasm")]
14pub mod wasm;
15
16#[cfg(test)]
17mod tests {
18    use std::fs::File;
19    use std::io::BufReader;
20
21    use serde_json::Value as JSONValue;
22
23    use super::decode::Decoder;
24    use super::encode::Encoder;
25
26    const DIM: u32 = 2;
27    const PRECISION: u32 = 6;
28    const P: f64 = 1000000.0;
29
30    fn compare_coordinates(coords1: &Vec<JSONValue>, coords2: &Vec<JSONValue>) {
31        for (idx, coord1) in coords1.iter().enumerate() {
32            let coord2 = &coords2[idx];
33            if coord1.is_array() {
34                compare_coordinates(&coord1.as_array().unwrap(), &coord2.as_array().unwrap());
35            } else if coord1.is_f64() || coord1.is_i64() || coord1.is_u64() {
36                let c1 = (coord1.as_f64().unwrap() * P).round() / P;
37                let c2 = (coord2.as_f64().unwrap() * P).round() / P;
38                assert_eq!(c1, c2);
39            }
40        }
41    }
42
43    fn compare_geojsons(obj1: &JSONValue, obj2: &JSONValue) {
44        if obj1.is_object() {
45            for (k, v1) in obj1.as_object().unwrap() {
46                let v2 = &obj2[k];
47                if k == "coordinates" {
48                    compare_coordinates(&obj1[k].as_array().unwrap(), &obj2[k].as_array().unwrap());
49                } else if v1.is_array() || v1.is_object() {
50                    compare_geojsons(v1, v2);
51                } else {
52                    assert_eq!(v1, v2);
53                }
54            }
55        } else if obj1.is_array() {
56            for (idx, v1) in obj1.as_array().unwrap().iter().enumerate() {
57                let v2 = &obj2[idx];
58                if v1.is_array() || v1.is_object() {
59                    compare_geojsons(v1, v2);
60                } else {
61                    assert_eq!(v1, v2);
62                }
63            }
64        } else {
65            assert_eq!(obj1, obj2);
66        };
67    }
68
69    fn test_geojson(file_path: &str) {
70        let file = File::open(file_path).unwrap();
71        let buff_reader = BufReader::new(file);
72        let original_geojson = serde_json::from_reader(buff_reader).unwrap();
73
74        let data = Encoder::encode(&original_geojson, PRECISION, DIM).unwrap();
75        let geojson = Decoder::decode(&data).unwrap();
76
77        compare_geojsons(&original_geojson, &geojson);
78    }
79
80    #[test]
81    fn test_feature() {
82        test_geojson("fixtures/feature.json");
83    }
84
85    #[test]
86    fn test_featurecollection() {
87        test_geojson("fixtures/featurecollection.json");
88    }
89
90    #[test]
91    fn test_geobuf_js_issue_62() {
92        test_geojson("fixtures/geobuf-js-issue-62.json");
93    }
94
95    #[test]
96    fn test_geometrycollection() {
97        test_geojson("fixtures/geometrycollection.json");
98    }
99
100    #[test]
101    fn test_linestring() {
102        test_geojson("fixtures/linestring.json");
103    }
104
105    #[test]
106    fn test_multilinestring() {
107        test_geojson("fixtures/multilinestring.json");
108    }
109
110    #[test]
111    fn test_multipoint() {
112        test_geojson("fixtures/multipoint.json");
113    }
114
115    #[test]
116    fn test_multipolygon() {
117        test_geojson("fixtures/multipolygon.json");
118    }
119
120    #[test]
121    fn test_point() {
122        test_geojson("fixtures/point.json");
123    }
124
125    #[test]
126    fn test_polygon() {
127        test_geojson("fixtures/polygon.json");
128    }
129
130    #[test]
131    fn test_precision() {
132        test_geojson("fixtures/precision.json");
133    }
134
135    #[test]
136    fn test_props() {
137        test_geojson("fixtures/props.json");
138    }
139
140    #[test]
141    fn test_single_multipoly() {
142        test_geojson("fixtures/single-multipoly.json");
143    }
144
145    #[test]
146    fn test_singlemultipolygon() {
147        test_geojson("fixtures/singlemultipolygon.json");
148    }
149
150    #[test]
151    fn test_us_states() {
152        test_geojson("fixtures/us-states.json");
153    }
154}