geoarrow_geojson/encoder/
rect.rs1use std::io::Write;
2
3use arrow_json::Encoder;
4use geo_traits::{CoordTrait, RectTrait};
5use geoarrow_array::GeoArrowArrayAccessor;
6use geoarrow_array::array::RectArray;
7
8pub struct RectEncoder(RectArray);
10
11impl RectEncoder {
12 pub fn new(array: RectArray) -> Self {
13 Self(array)
14 }
15}
16
17impl Encoder for RectEncoder {
18 fn encode(&mut self, idx: usize, out: &mut Vec<u8>) {
19 let rect = self.0.value(idx).unwrap();
20 encode_rect(&rect, out);
21 }
22}
23
24pub(crate) fn encode_rect(rect: &impl RectTrait<T = f64>, out: &mut Vec<u8>) {
25 out.extend(br#"{"type":"Polygon","coordinates":["#);
26
27 let min_coord = rect.min();
29 let max_coord = rect.max();
30
31 out.push(b'[');
33
34 out.push(b'[');
36 write!(out, "{}", min_coord.x()).unwrap();
37 out.push(b',');
38 write!(out, "{}", min_coord.y()).unwrap();
39 out.push(b']');
40 out.push(b',');
41
42 out.push(b'[');
44 write!(out, "{}", min_coord.x()).unwrap();
45 out.push(b',');
46 write!(out, "{}", max_coord.y()).unwrap();
47 out.push(b']');
48 out.push(b',');
49
50 out.push(b'[');
52 write!(out, "{}", max_coord.x()).unwrap();
53 out.push(b',');
54 write!(out, "{}", max_coord.y()).unwrap();
55 out.push(b']');
56 out.push(b',');
57
58 out.push(b'[');
60 write!(out, "{}", max_coord.x()).unwrap();
61 out.push(b',');
62 write!(out, "{}", min_coord.y()).unwrap();
63 out.push(b']');
64 out.push(b',');
65
66 out.push(b'[');
68 write!(out, "{}", min_coord.x()).unwrap();
69 out.push(b',');
70 write!(out, "{}", min_coord.y()).unwrap();
71 out.push(b']');
72
73 out.push(b']'); out.push(b']'); out.push(b'}'); }
77
78#[cfg(test)]
79mod test {
80 use std::str::FromStr;
81
82 use geo_types::{Rect, coord};
83 use geoarrow_array::builder::RectBuilder;
84 use geoarrow_schema::{BoxType, Dimension};
85
86 use super::*;
87
88 #[test]
89 fn encode_rect() {
90 let geoms = [Rect::new(
92 coord! { x: 10., y: 20. },
93 coord! { x: 30., y: 10. },
94 )];
95 let typ = BoxType::new(Dimension::XY, Default::default());
96 let array = RectBuilder::from_rects(geoms.iter(), typ).finish();
97
98 let mut encoder = RectEncoder::new(array);
99
100 let mut out = vec![];
101 encoder.encode(0, &mut out);
102 let s = String::from_utf8(out).unwrap();
103 let expected =
105 r#"{"type":"Polygon","coordinates":[[[10,10],[10,20],[30,20],[30,10],[10,10]]]}"#;
106 assert_eq!(s, expected);
107
108 geojson::Geometry::from_str(expected).expect("Should be valid GeoJSON");
109 }
110}