geoarrow_geojson/encoder/
point.rs1use std::io::Write;
2
3use arrow_json::Encoder;
4use geo_traits::{CoordTrait, PointTrait};
5use geoarrow_array::GeoArrowArrayAccessor;
6use geoarrow_array::array::PointArray;
7
8pub struct PointEncoder(PointArray);
10
11impl PointEncoder {
12 pub fn new(array: PointArray) -> Self {
13 Self(array)
14 }
15}
16
17impl Encoder for PointEncoder {
18 fn encode(&mut self, idx: usize, out: &mut Vec<u8>) {
19 let point = self.0.value(idx).unwrap();
20 encode_point(&point, out);
21 }
22}
23
24pub(crate) fn encode_point(point: &impl PointTrait<T = f64>, out: &mut Vec<u8>) {
25 out.extend(br#"{"type":"Point","coordinates":"#);
26 let coord = point
27 .coord()
28 .expect("POINT EMPTY not yet supported in GeoJSON writer");
29 encode_coord(&coord, out);
30 out.push(b'}');
31}
32
33pub(crate) fn encode_coord(coord: &impl CoordTrait<T = f64>, out: &mut Vec<u8>) {
34 out.push(b'[');
35 let dim_size = coord.dim().size();
36 for n in 0..dim_size {
37 write!(out, "{}", coord.nth_or_panic(n)).unwrap();
38 if n < dim_size - 1 {
39 out.push(b',');
40 }
41 }
42 out.push(b']');
43}
44
45#[cfg(test)]
46mod test {
47 use std::str::FromStr;
48
49 use geoarrow_array::test::point::array;
50 use geoarrow_schema::{CoordType, Dimension};
51
52 use super::*;
53
54 #[test]
55 fn encode_point() {
56 let mut encoder = PointEncoder::new(array(CoordType::Separated, Dimension::XY));
57
58 let mut out = vec![];
59 encoder.encode(0, &mut out);
60 let s = String::from_utf8(out).unwrap();
61 let expected = r#"{"type":"Point","coordinates":[30,10]}"#;
62 assert_eq!(s, expected);
63
64 geojson::Geometry::from_str(expected).expect("Should be valid GeoJSON");
65 }
66
67 #[test]
68 fn encode_point_xyz() {
69 let mut encoder = PointEncoder::new(array(CoordType::Separated, Dimension::XYZ));
70
71 let mut out = vec![];
72 encoder.encode(0, &mut out);
73 let s = String::from_utf8(out).unwrap();
74 let expected = r#"{"type":"Point","coordinates":[30,10,40]}"#;
75 assert_eq!(s, expected);
76
77 geojson::Geometry::from_str(expected).expect("Should be valid GeoJSON");
78 }
79}