flatgeobuf 6.0.1

FlatGeobuf for Rust
Documentation
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
use crate::feature_generated::*;
use crate::header_generated::{ColumnType, GeometryType};
use crate::packed_r_tree::NodeItem;
use byteorder::{ByteOrder, LittleEndian};
use geozero::error::{GeozeroError, Result};
use geozero::{ColumnValue, CoordDimensions, FeatureProcessor, GeomProcessor, PropertyProcessor};
use std::{mem::size_of, str};

/// FBG Feature writer.
pub struct FeatureWriter<'a> {
    dims: CoordDimensions,
    // Array of end index in flat coordinates per geometry part
    ends: Vec<u32>,
    // Flat x and y coordinate array (flat pairs)
    xy: Vec<f64>,
    // Flat z height array
    z: Vec<f64>,
    // Flat m measurement array
    m: Vec<f64>,
    // Flat t geodetic decimal year time array
    t: Vec<f64>,
    // Flat tm time nanosecond measurement array
    tm: Vec<u64>,
    // Type of geometry (only relevant for elements in heterogeneous collection types)
    type_: GeometryType,
    // Declared geometry type of dataset. Unknown type will be replaced when detect_type is set.
    pub(crate) dataset_type: GeometryType,
    // Detect geometry type when dataset_type is Unknown.
    detect_type: bool,
    // Convert single to multi geometries, if declared as multi type or Unknown
    promote_to_multi: bool,
    parts: Vec<flatbuffers::WIPOffset<Geometry<'a>>>,
    geom_state: GeomState,
    properties: Vec<u8>,
    fbb: flatbuffers::FlatBufferBuilder<'a>,
    pub(crate) bbox: NodeItem,
}

#[derive(PartialEq, Debug)]
enum GeomState {
    Normal,
    GeometryCollection,
    ForceMulti,
}

macro_rules! to_fb_vector {
    ( $self:ident, $items:ident ) => {
        if cfg!(target_endian = "big") {
            let mut iter = std::mem::take(&mut $self.$items).into_iter();
            $self.fbb.create_vector_from_iter(&mut iter)
        } else {
            let items = $self.fbb.create_vector(&$self.$items);
            $self.$items.truncate(0);
            items
        }
    };
}

impl<'a> FeatureWriter<'a> {
    pub fn new(
        dataset_type: GeometryType,
        detect_type: bool,
        promote_to_multi: bool,
    ) -> FeatureWriter<'a> {
        Self::with_dims(
            dataset_type,
            detect_type,
            promote_to_multi,
            CoordDimensions::default(),
        )
    }
    pub fn with_dims(
        dataset_type: GeometryType,
        detect_type: bool,
        promote_to_multi: bool,
        dims: CoordDimensions,
    ) -> FeatureWriter<'a> {
        FeatureWriter {
            dims,
            ends: Vec::new(),
            xy: Vec::new(),
            z: Vec::new(),
            m: Vec::new(),
            t: Vec::new(),
            tm: Vec::new(),
            type_: GeometryType::Unknown,
            dataset_type,
            detect_type,
            promote_to_multi,
            parts: Vec::new(),
            geom_state: GeomState::Normal,
            properties: Vec::new(),
            fbb: flatbuffers::FlatBufferBuilder::new(),
            bbox: NodeItem::create(0),
        }
    }
    fn set_type(&mut self, geometry_type: GeometryType) -> Result<()> {
        if geometry_type != self.dataset_type {
            match self.dataset_type {
                GeometryType::Unknown => {
                    let type_ = match geometry_type {
                        GeometryType::LineString if self.promote_to_multi => {
                            self.geom_state = GeomState::ForceMulti;
                            GeometryType::MultiLineString
                        }
                        GeometryType::Polygon if self.promote_to_multi => {
                            self.geom_state = GeomState::ForceMulti;
                            GeometryType::MultiPolygon
                        }
                        _ => geometry_type,
                    };
                    if self.detect_type {
                        if self.geom_state != GeomState::GeometryCollection
                            || type_ == GeometryType::GeometryCollection
                        {
                            // Replace with first detected type
                            self.dataset_type = type_;
                        }
                    } else {
                        self.type_ = type_;
                    }
                }
                GeometryType::GeometryCollection
                    if self.geom_state == GeomState::GeometryCollection =>
                {
                    // accept other geometry types within collection
                }
                GeometryType::MultiLineString
                    if self.promote_to_multi
                        && geometry_type == GeometryType::LineString
                        && self.geom_state != GeomState::GeometryCollection =>
                {
                    self.geom_state = GeomState::ForceMulti;
                }
                GeometryType::MultiPolygon
                    if self.promote_to_multi
                        && geometry_type == GeometryType::Polygon
                        && self.geom_state != GeomState::GeometryCollection =>
                {
                    self.geom_state = GeomState::ForceMulti;
                }
                _ => {
                    return Err(GeozeroError::Geometry(format!(
                        "Cannot mix geometry types - expected type `{:?}`, actual type `{geometry_type:?}`",
                        self.dataset_type
                    )));
                }
            }
            if self.geom_state == GeomState::GeometryCollection {
                // FlatBuffers size increases when type is set, so only when necessary.
                self.type_ = geometry_type;
            }
        }
        Ok(())
    }
    fn reset_bbox(&mut self) {
        if self.geom_state != GeomState::GeometryCollection {
            self.bbox = NodeItem::create(0);
        }
    }
    fn finish_part(&mut self) {
        let xy = Some(to_fb_vector!(self, xy));
        let ends = match self.ends.len() {
            0 => None,
            1 => {
                // Skip single ends to save FlatBuffers size
                self.ends.truncate(0);
                None
            }
            _ => Some(to_fb_vector!(self, ends)),
        };
        let z = if !self.z.is_empty() {
            Some(to_fb_vector!(self, z))
        } else {
            None
        };
        let m = if !self.m.is_empty() {
            Some(to_fb_vector!(self, m))
        } else {
            None
        };
        let t = if !self.t.is_empty() {
            Some(to_fb_vector!(self, t))
        } else {
            None
        };
        let tm = if !self.tm.is_empty() {
            Some(to_fb_vector!(self, tm))
        } else {
            None
        };
        let g = Geometry::create(
            &mut self.fbb,
            &GeometryArgs {
                xy,
                ends,
                z,
                m,
                t,
                tm,
                type_: self.type_,
                ..Default::default()
            },
        );
        self.parts.push(g);
    }
    pub(crate) fn finish_to_feature(&mut self) -> Vec<u8> {
        let g = if self.parts.is_empty() {
            self.finish_part();
            self.parts.pop().expect("push in finish_part")
        } else {
            let mut iter = std::mem::take(&mut self.parts).into_iter();
            let parts = self.fbb.create_vector_from_iter(&mut iter);
            Geometry::create(
                &mut self.fbb,
                &GeometryArgs {
                    type_: self.type_,
                    parts: Some(parts),
                    ..Default::default()
                },
            )
        };
        let properties = Some(self.fbb.create_vector(&self.properties));
        self.properties.truncate(0);
        let f = Feature::create(
            &mut self.fbb,
            &FeatureArgs {
                geometry: Some(g),
                properties,
                ..Default::default()
            },
        );
        self.fbb.finish_size_prefixed(f, None);
        let feature_buf = self.fbb.finished_data().to_vec();
        self.fbb.reset();
        feature_buf
    }
}

impl GeomProcessor for FeatureWriter<'_> {
    fn dimensions(&self) -> CoordDimensions {
        self.dims
    }
    fn xy(&mut self, x: f64, y: f64, _idx: usize) -> Result<()> {
        self.xy.push(x);
        self.xy.push(y);
        self.bbox.expand_xy(x, y);
        Ok(())
    }
    fn coordinate(
        &mut self,
        x: f64,
        y: f64,
        z: Option<f64>,
        m: Option<f64>,
        t: Option<f64>,
        tm: Option<u64>,
        _idx: usize,
    ) -> Result<()> {
        self.xy.push(x);
        self.xy.push(y);
        self.bbox.expand_xy(x, y);
        if let Some(v) = z {
            self.z.push(v);
        }
        if let Some(v) = m {
            self.m.push(v);
        }
        if let Some(v) = t {
            self.t.push(v);
        }
        if let Some(v) = tm {
            self.tm.push(v);
        }
        Ok(())
    }
    fn point_begin(&mut self, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::Point)?;
        self.reset_bbox();
        Ok(())
    }
    fn point_end(&mut self, _idx: usize) -> Result<()> {
        if self.geom_state == GeomState::GeometryCollection {
            self.finish_part();
        }
        Ok(())
    }
    fn multipoint_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::MultiPoint)?;
        self.reset_bbox();
        Ok(())
    }
    fn linestring_begin(&mut self, tagged: bool, size: usize, _idx: usize) -> Result<()> {
        if tagged {
            self.set_type(GeometryType::LineString)?;
            self.reset_bbox();
        }
        reserve_total(&mut self.xy, size * 2);
        Ok(())
    }
    fn linestring_end(&mut self, tagged: bool, _idx: usize) -> Result<()> {
        if !tagged || self.geom_state == GeomState::ForceMulti {
            self.ends.push(self.xy.len() as u32 / 2);
        }
        if self.geom_state == GeomState::GeometryCollection {
            self.finish_part();
        }
        if tagged && self.geom_state == GeomState::ForceMulti {
            self.geom_state = GeomState::Normal;
        }
        Ok(())
    }
    fn multilinestring_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::MultiLineString)?;
        self.reset_bbox();
        Ok(())
    }
    fn polygon_begin(&mut self, tagged: bool, size: usize, _idx: usize) -> Result<()> {
        if tagged {
            self.set_type(GeometryType::Polygon)?;
            self.reset_bbox();
        }
        reserve_total(&mut self.ends, size);
        Ok(())
    }
    fn polygon_end(&mut self, tagged: bool, _idx: usize) -> Result<()> {
        if !tagged
            || self.geom_state == GeomState::ForceMulti
            || self.geom_state == GeomState::GeometryCollection
        {
            self.finish_part();
        }
        if tagged && self.geom_state == GeomState::ForceMulti {
            self.geom_state = GeomState::Normal;
        }
        Ok(())
    }
    fn multipolygon_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::MultiPolygon)?;
        self.reset_bbox();
        Ok(())
    }
    fn geometrycollection_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::GeometryCollection)?;
        self.reset_bbox();
        self.geom_state = GeomState::GeometryCollection;
        Ok(())
    }
    fn geometrycollection_end(&mut self, _idx: usize) -> Result<()> {
        self.geom_state = GeomState::Normal;
        Ok(())
    }
    fn circularstring_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::CircularString)?;
        self.reset_bbox();
        Ok(())
    }
    fn compoundcurve_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::CompoundCurve)?;
        self.reset_bbox();
        Ok(())
    }
    fn curvepolygon_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::CurvePolygon)?;
        self.reset_bbox();
        Ok(())
    }
    fn multicurve_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::MultiCurve)?;
        self.reset_bbox();
        Ok(())
    }
    fn multisurface_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::MultiSurface)?;
        self.reset_bbox();
        Ok(())
    }
    fn triangle_begin(&mut self, tagged: bool, _size: usize, _idx: usize) -> Result<()> {
        if tagged {
            self.set_type(GeometryType::Triangle)?;
            self.reset_bbox();
        }
        Ok(())
    }
    fn polyhedralsurface_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::PolyhedralSurface)?;
        self.reset_bbox();
        Ok(())
    }
    fn tin_begin(&mut self, _size: usize, _idx: usize) -> Result<()> {
        self.set_type(GeometryType::TIN)?;
        self.reset_bbox();
        Ok(())
    }
}

fn reserve_total<T>(vec: &mut Vec<T>, capacity: usize) {
    if capacity > vec.capacity() {
        vec.reserve(capacity - vec.capacity());
    }
}

fn prop_size(colval: &ColumnValue) -> usize {
    match colval {
        ColumnValue::Byte(_) => size_of::<i8>(),
        ColumnValue::UByte(_) => size_of::<u8>(),
        ColumnValue::Bool(_) => size_of::<u8>(),
        ColumnValue::Short(_) => size_of::<i16>(),
        ColumnValue::UShort(_) => size_of::<u16>(),
        ColumnValue::Int(_) => size_of::<i32>(),
        ColumnValue::UInt(_) => size_of::<u32>(),
        ColumnValue::Long(_) => size_of::<i64>(),
        ColumnValue::ULong(_) => size_of::<u64>(),
        ColumnValue::Float(_) => size_of::<f32>(),
        ColumnValue::Double(_) => size_of::<f64>(),
        ColumnValue::String(v) | ColumnValue::Json(v) | ColumnValue::DateTime(v) => {
            size_of::<u32>() + v.len()
        }
        ColumnValue::Binary(v) => size_of::<u32>() + v.len(),
    }
}

pub(crate) fn prop_type(colval: &ColumnValue) -> ColumnType {
    match colval {
        ColumnValue::Byte(_) => ColumnType::Byte,
        ColumnValue::UByte(_) => ColumnType::UByte,
        ColumnValue::Bool(_) => ColumnType::Bool,
        ColumnValue::Short(_) => ColumnType::Short,
        ColumnValue::UShort(_) => ColumnType::UShort,
        ColumnValue::Int(_) => ColumnType::Int,
        ColumnValue::UInt(_) => ColumnType::UInt,
        ColumnValue::Long(_) => ColumnType::Long,
        ColumnValue::ULong(_) => ColumnType::ULong,
        ColumnValue::Float(_) => ColumnType::Float,
        ColumnValue::Double(_) => ColumnType::Double,
        ColumnValue::String(_) => ColumnType::String,
        ColumnValue::Json(_) => ColumnType::Json,
        ColumnValue::DateTime(_) => ColumnType::DateTime,
        ColumnValue::Binary(_) => ColumnType::Binary,
    }
}

impl PropertyProcessor for FeatureWriter<'_> {
    fn property(&mut self, i: usize, _colname: &str, colval: &ColumnValue) -> Result<bool> {
        let ofs = self.properties.len();
        self.properties
            .resize(ofs + size_of::<u16>() + prop_size(colval), 0);
        LittleEndian::write_u16(&mut self.properties[ofs..], i as u16);
        let prop = &mut self.properties[ofs + size_of::<u16>()..];
        match colval {
            ColumnValue::Byte(v) => prop[0] = *v as u8,
            ColumnValue::UByte(v) => prop[0] = *v,
            ColumnValue::Bool(v) => prop[0] = *v as u8,
            ColumnValue::Short(v) => LittleEndian::write_i16(prop, *v),
            ColumnValue::UShort(v) => LittleEndian::write_u16(prop, *v),
            ColumnValue::Int(v) => LittleEndian::write_i32(prop, *v),
            ColumnValue::UInt(v) => LittleEndian::write_u32(prop, *v),
            ColumnValue::Long(v) => LittleEndian::write_i64(prop, *v),
            ColumnValue::ULong(v) => LittleEndian::write_u64(prop, *v),
            ColumnValue::Float(v) => LittleEndian::write_f32(prop, *v),
            ColumnValue::Double(v) => LittleEndian::write_f64(prop, *v),
            ColumnValue::String(v) | ColumnValue::Json(v) | ColumnValue::DateTime(v) => {
                LittleEndian::write_u32(prop, v.len() as u32);
                prop[4..].copy_from_slice(v.as_bytes());
            }
            ColumnValue::Binary(v) => {
                LittleEndian::write_u32(prop, v.len() as u32);
                prop[4..].copy_from_slice(v);
            }
        };
        Ok(false)
    }
}

impl FeatureProcessor for FeatureWriter<'_> {}

#[cfg(test)]
mod test {
    use super::*;
    use crate::header_generated::*;
    use crate::FgbFeature;
    use geozero::geojson::{read_geojson_geom, GeoJson, GeoJsonWriter};
    use geozero::{FeatureAccess, GeozeroDatasource};

    fn header(geometry_type: GeometryType) -> Vec<u8> {
        let mut fbb = flatbuffers::FlatBufferBuilder::new();
        let col0 = ColumnArgs {
            name: Some(fbb.create_string("fid")),
            type_: ColumnType::ULong,
            ..Default::default()
        };
        let col0 = Column::create(&mut fbb, &col0);
        let col1 = ColumnArgs {
            name: Some(fbb.create_string("name")),
            type_: ColumnType::String,
            ..Default::default()
        };
        let col1 = Column::create(&mut fbb, &col1);
        let header_args = HeaderArgs {
            name: Some(fbb.create_string("countries")),
            geometry_type,
            columns: Some(fbb.create_vector(&[col0, col1])),
            features_count: 1,
            index_node_size: 0,
            ..Default::default()
        };

        let header = Header::create(&mut fbb, &header_args);
        fbb.finish_size_prefixed(header, None);
        fbb.finished_data().to_vec()
    }

    fn write_as_geojson(mut fgb_writer: FeatureWriter) -> Result<String> {
        let mut out: Vec<u8> = Vec::new();
        let feat = FgbFeature {
            header_buf: header(fgb_writer.dataset_type),
            feature_buf: fgb_writer.finish_to_feature(),
        };
        // dbg!(&feat.fbs_feature());
        feat.process(&mut GeoJsonWriter::new(&mut out), 0)?;
        Ok(String::from_utf8(out).unwrap())
    }

    fn json_to_fbg_to_json_n(
        geojson: &str,
        geometry_type: GeometryType,
        dims: CoordDimensions,
    ) -> Vec<u8> {
        let mut fgb_writer = FeatureWriter::with_dims(geometry_type, false, false, dims);
        assert!(dbg!(read_geojson_geom(&mut geojson.as_bytes(), &mut fgb_writer)).is_ok());
        let mut out: Vec<u8> = Vec::new();
        let f = FgbFeature {
            header_buf: header(geometry_type),
            feature_buf: fgb_writer.finish_to_feature(),
        };
        let mut json_writer = GeoJsonWriter::with_dims(&mut out, dims);
        dbg!(f
            .geometry()
            .unwrap()
            .process(&mut json_writer, geometry_type))
        .unwrap();
        out
    }

    fn json_to_fbg_to_json(geojson: &str, geometry_type: GeometryType) -> Vec<u8> {
        json_to_fbg_to_json_n(geojson, geometry_type, CoordDimensions::xy())
    }

    #[test]
    fn geometries() -> Result<()> {
        let geojson =
            r#"{"type": "Point", "coordinates": [2223639.4731508396,-15878634.348995442]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::Point)).unwrap(),
            geojson
        );

        let geojson = r#"{"type": "MultiPoint", "coordinates": [[1,1],[2,2]]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::MultiPoint)).unwrap(),
            geojson
        );

        let geojson = r#"{"type": "LineString", "coordinates": [[1875038.4476102313,-3269648.6879248763],[1874359.6415041967,-3270196.8129848638],[1874141.0428635243,-3270953.7840121365],[1874440.1778162003,-3271619.4315206874],[1876396.0598222911,-3274138.747656357],[1876442.0805243007,-3275052.60551469],[1874739.312657555,-3275457.333765534]]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::LineString)).unwrap(),
            r#"{"type": "LineString", "coordinates": [[1875038.447610231,-3269648.6879248763],[1874359.641504197,-3270196.812984864],[1874141.0428635243,-3270953.7840121365],[1874440.1778162003,-3271619.4315206874],[1876396.0598222911,-3274138.747656357],[1876442.0805243007,-3275052.60551469],[1874739.312657555,-3275457.333765534]]}"#
        );

        let geojson = r#"{"type": "MultiLineString", "coordinates": [[[-20037505.025679983,2692596.21474788],[-19924286.672913034,2692596.21474788],[-19812966.14702537,2692596.21474788],[-19701645.62113772,2692596.21474788],[-19590325.09525006,2692596.21474788],[-19479004.56936241,2692596.21474788],[-19367684.04347475,2692596.21474788],[-19256372.576874677,2692596.21474788],[-19145042.991699435,2692596.21474788],[-19033736.054743163,2692596.21474788],[-18922401.939924125,2692596.21474788],[-18811090.473324053,2692596.21474788],[-18699774.4770802,2692596.21474788],[-18588449.421548743,2692596.21474788],[-18477128.895661093,2692596.21474788],[-18365812.89941723,2692596.21474788],[-18254492.373529565,2692596.21474788],[-18143167.31799812,2692596.21474788],[-18031860.381041847,2692596.21474788],[-17920530.795866605,2692596.21474788],[-17809219.329266533,2692596.21474788],[-17697898.803378873,2692596.21474788],[-17586578.277491223,2692596.21474788],[-17475257.751603562,2692596.21474788],[-17363937.225715913,2692596.21474788],[-17252616.69982825,2692596.21474788],[-17141296.1739406,2692596.21474788],[-17029984.707340535,2692596.21474788],[-16918659.651809078,2692596.21474788],[-16807343.65556522,2692596.21474788],[-16696014.07038997,2692596.21474788],[-16584707.133433694,2692596.21474788],[-16473382.077902246,2692596.21474788],[-16362061.552014597,2692596.21474788],[-16250745.55577073,2692596.21474788],[-16139425.02988307,2692596.21474788],[-16028104.503995419,2692596.21474788],[-15916783.978107756,2692596.21474788],[-15805472.511507692,2692596.21474788],[-15694142.926332444,2692596.21474788],[-15582831.459732382,2692596.21474788],[-15471510.933844728,2692596.21474788],[-15360190.407957068,2692596.21474788],[-15248869.882069414,2692596.21474788],[-15137549.356181756,2692596.21474788],[-15026228.830294106,2692596.21474788],[-14914908.304406442,2692596.21474788],[-14803587.778518781,2692596.21474788],[-14692267.252631132,2692596.21474788],[-14580955.78603106,2692596.21474788],[-14469630.730499614,2692596.21474788],[-14358314.734255752,2692596.21474788],[-14246994.20836809,2692596.21474788],[-14135678.212124234,2692596.21474788],[-14024353.156592779,2692596.21474788],[-13913032.630705126,2692596.21474788],[-13801716.634461263,2692596.21474788],[-13690391.578929815,2692596.21474788],[-13579080.112329746,2692596.21474788],[-13467755.05679829,2692596.21474788],[-13356439.060554435,2692596.21474788],[-13245114.005022977,2692596.21474788],[-13133802.538422907,2692596.21474788],[-13022482.012535257,2692596.21474788],[-12911161.4866476,2692596.21474788],[-12799840.960759947,2692596.21474788],[-12688520.434872286,2692596.21474788],[-12577199.908984635,2692596.21474788],[-12465883.912740769,2692596.21474788],[-12354567.916496906,2692596.21474788],[-12243238.33132166,2692596.21474788],[-12131926.864721594,2692596.21474788],[-12020601.809190147,2692596.21474788],[-11909285.812946282,2692596.21474788],[-11797969.816702416,2692596.21474788],[-11686644.76117097,2692596.21474788],[-11575328.764927106,2692596.21474788],[-11464008.239039455,2692596.21474788],[-11352687.713151794,2692596.21474788],[-11241367.187264143,2692596.21474788],[-11130051.191020276,2692596.21474788],[-11018726.13548883,2692596.21474788],[-10907414.668888763,2692596.21474788],[-10796094.1430011,2692596.21474788],[-10684773.61711345,2692596.21474788],[-10573453.091225792,2692596.21474788],[-10462132.56533813,2692596.21474788],[-10350812.03945048,2692596.21474788],[-10239491.513562817,2692596.21474788],[-10128170.987675166,2692596.21474788],[-10016854.9914313,2692596.21474788],[-9905538.995187437,2692596.21474788],[-9794209.410012191,2692596.21474788],[-9682902.47305592,2692596.21474788],[-9571577.417524474,2692596.21474788],[-9460261.421280608,2692596.21474788],[-9348940.895392958,2692596.21474788],[-9237615.8398615,2692596.21474788],[-9126299.843617637,2692596.21474788],[-9014979.317729987,2692596.21474788],[-8903663.321486121,2692596.21474788],[-8792338.265954675,2692596.21474788],[-8681022.269710807,2692596.21474788],[-8569692.684535567,2692596.21474788],[-8458385.747579295,2692596.21474788],[-8347069.751335428,2692596.21474788],[-8235749.225447779,2692596.21474788],[-8124424.16991632,2692596.21474788],[-8013099.114384874,2692596.21474788],[-7901787.647784806,2692596.21474788],[-7790467.121897143,2692596.21474788],[-7679155.655297086,2692596.21474788],[-7567826.070121832,2692596.21474788],[-7456510.073877977,2692596.21474788],[-7345185.01834652,2692596.21474788],[-7233873.551746452,2692596.21474788],[-7122553.025858803,2692596.21474788],[-7011232.49997114,2692596.21474788],[-6899911.97408349,2692596.21474788],[-6788586.918552041,2692596.21474788],[-6677270.922308178,2692596.21474788],[-6565950.396420515,2692596.21474788],[-6454638.929820447,2692596.21474788],[-6343309.344645206,2692596.21474788],[-6231993.34840134,2692596.21474788],[-6120677.352157486,2692596.21474788],[-6009356.826269826,2692596.21474788],[-5898040.83002596,2692596.21474788],[-5786715.774494514,2692596.21474788],[-5675395.248606861,2692596.21474788],[-5564074.722719202,2692596.21474788],[-5452754.196831549,2692596.21474788],[-5341433.67094389,2692596.21474788],[-5230126.733987618,2692596.21474788],[-5118797.148812373,2692596.21474788],[-5007481.15256851,2692596.21474788],[-4896165.156324643,2692596.21474788],[-4784844.630436993,2692596.21474788],[-4673524.104549334,2692596.21474788],[-4562203.578661681,2692596.21474788],[-4450883.052774021,2692596.21474788],[-4339562.526886369,2692596.21474788],[-4228242.000998709,2692596.21474788],[-4116935.0640424383,2692596.21474788],[-4005600.9492233973,2692596.21474788],[-3894289.48262333,2692596.21474788],[-3782964.427091881,2692596.21474788],[-3671648.4308480173,2692596.21474788],[-3560327.904960355,2692596.21474788],[-3449011.908716501,2692596.21474788],[-3337691.382828842,2692596.21474788],[-3226366.327297393,2692596.21474788],[-3115050.3310535294,2692596.21474788],[-3003729.8051658766,2692596.21474788],[-2892418.338565809,2692596.21474788],[-2781088.7533905646,2692596.21474788],[-2669777.2867904967,2692596.21474788],[-2558456.7609028374,2692596.21474788],[-2447136.2350151846,2692596.21474788],[-2335815.7091275253,2692596.21474788],[-2224495.183239872,2692596.21474788],[-2113174.657352213,2692596.21474788],[-2001854.1314645505,2692596.21474788],[-1890533.6055769008,2692596.21474788],[-1779213.0796892412,2692596.21474788],[-1667901.6130891705,2692596.21474788],[-1556581.087201521,2692596.21474788],[-1445260.5613138585,2692596.21474788],[-1333940.0354262087,2692596.21474788],[-1222619.5095385492,2692596.21474788],[-1111298.9836508965,2692596.21474788],[-999978.457763237,2692596.21474788],[-888662.4615193801,2692596.21474788],[-777341.9356317207,2692596.21474788],[-666025.9393878573,2692596.21474788],[-554696.3542126124,2692596.21474788],[-443393.94690013694,2692596.21474788],[-332073.4210124745,2692596.21474788],[-220743.83583723273,2692596.21474788],[-109432.36923716537,2692596.21474788],[1897.2159380795622,2692596.21474788],[113226.80111332452,2692596.21474788],[224538.26771339186,2692596.21474788],[335876.91217622877,2692596.21474788],[447188.37877629616,2692596.21474788],[558499.8453763635,2692596.21474788],[669820.3712640165,2692596.21474788],[781140.8971516758,2692596.21474788],[892461.4230393288,2692596.21474788],[1003772.8896393961,2692596.21474788],[1115111.534102233,2692596.21474788],[1226404.882127126,2692596.21474788],[1337743.52658995,2692596.21474788],[1449064.0524776129,2692596.21474788],[1560384.5783652721,2692596.21474788],[1671696.04496533,2692596.21474788],[1783007.5115654003,2692596.21474788],[1894328.0374530598,2692596.21474788],[2005648.5633407128,2692596.21474788],[2116978.148515964,2692596.21474788],[2228289.6151160216,2692596.21474788],[2339619.2002912764,2692596.21474788],[2450930.666891334,2692596.21474788],[2562251.1927789967,2692596.21474788],[2673571.718666656,2692596.21474788],[2784901.303841901,2692596.21474788],[2896212.7704419685,2692596.21474788],[3007515.1777544436,2692596.21474788],[3118853.822217281,2692596.21474788],[3230165.2888173484,2692596.21474788],[3341494.8739925832,2692596.21474788],[3452797.2813050686,2692596.21474788],[3564135.9257678958,2692596.21474788],[3675438.333080381,2692596.21474788],[3786776.9775432083,2692596.21474788],[3898088.444143285,2692596.21474788],[4009399.9107433553,2692596.21474788],[4120720.4366310053,2692596.21474788],[4232040.962518668,2692596.21474788],[4343361.488406317,2692596.21474788],[4454672.9550063815,2692596.21474788],[4566011.599469221,2692596.21474788],[4677323.066069286,2692596.21474788],[4788643.591956948,2692596.21474788],[4899964.117844598,2692596.21474788],[5011284.643732261,2692596.21474788],[5122596.110332319,2692596.21474788],[5233907.576932389,2692596.21474788],[5345246.221395223,2692596.21474788],[5456548.628707701,2692596.21474788],[5567887.273170535,2692596.21474788],[5679189.680483013,2692596.21474788],[5790519.265658256,2692596.21474788],[5901830.732258332,2692596.21474788],[6013151.258145982,2692596.21474788],[6124471.784033645,2692596.21474788],[6235801.36920888,2692596.21474788],[6347112.835808957,2692596.21474788],[6458433.3616966065,2692596.21474788],[6569753.887584269,2692596.21474788],[6681074.413471919,2692596.21474788],[6792394.939359581,2692596.21474788],[6903706.405959652,2692596.21474788],[7015035.991134894,2692596.21474788],[7126356.517022544,2692596.21474788],[7237677.042910206,2692596.21474788],[7348988.509510271,2692596.21474788],[7460299.976110341,2692596.21474788],[7571620.501997991,2692596.21474788],[7682941.027885654,2692596.21474788],[7794261.5537733035,2692596.21474788],[7905573.020373374,2692596.21474788],[8016911.664836207,2692596.21474788],[8128223.131436277,2692596.21474788],[8239543.657323928,2692596.21474788],[8350864.18321159,2692596.21474788],[8462184.70909924,2692596.21474788],[8573496.175699318,2692596.21474788],[8684807.642299388,2692596.21474788],[8796146.286762215,2692596.21474788],[8907457.753362292,2692596.21474788],[9018787.338537533,2692596.21474788],[9130098.805137604,2692596.21474788],[9241419.331025254,2692596.21474788],[9352730.797625326,2692596.21474788],[9464069.442088157,2692596.21474788],[9575371.849400638,2692596.21474788],[9686701.434575878,2692596.21474788],[9798012.901175942,2692596.21474788],[9909333.427063597,2692596.21474788],[10020653.952951254,2692596.21474788],[10131965.419551326,2692596.21474788],[10243295.004726568,2692596.21474788],[10354606.471326638,2692596.21474788],[10465936.05650188,2692596.21474788],[10577256.58238953,2692596.21474788],[10688577.108277192,2692596.21474788],[10799888.574877262,2692596.21474788],[10911218.160052504,2692596.21474788],[11022520.567364983,2692596.21474788],[11133841.093252633,2692596.21474788],[11245179.737715466,2692596.21474788],[11356482.145027963,2692596.21474788],[11467811.730203198,2692596.21474788],[11579123.196803275,2692596.21474788],[11690443.722690927,2692596.21474788],[11801764.24857859,2692596.21474788],[11913093.833753832,2692596.21474788],[12024405.300353901,2692596.21474788],[12135707.707666373,2692596.21474788],[12247046.352129214,2692596.21474788],[12358357.818729272,2692596.21474788],[12469687.403904526,2692596.21474788],[12580998.870504584,2692596.21474788],[12692319.39639224,2692596.21474788],[12803630.862992309,2692596.21474788],[12914969.507455144,2692596.21474788],[13026280.9740552,2692596.21474788],[13137610.559230454,2692596.21474788],[13248912.966542935,2692596.21474788],[13360233.492430585,2692596.21474788],[13471554.018318245,2692596.21474788],[13582865.484918306,2692596.21474788],[13694204.129381137,2692596.21474788],[13805515.595981209,2692596.21474788],[13916836.121868871,2692596.21474788],[14028156.64775652,2692596.21474788],[14139477.173644185,2692596.21474788],[14250788.640244242,2692596.21474788],[14362127.284707077,2692596.21474788],[14473429.692019572,2692596.21474788],[14584741.158619631,2692596.21474788],[14696079.803082459,2692596.21474788],[14807382.210394945,2692596.21474788],[14918711.795570198,2692596.21474788],[15030023.262170255,2692596.21474788],[15141343.78805791,2692596.21474788],[15252664.313945567,2692596.21474788],[15364002.9584084,2692596.21474788],[15475305.365720881,2692596.21474788],[15586634.950896129,2692596.21474788],[15697946.417496186,2692596.21474788],[15809257.884096257,2692596.21474788],[15920587.4692715,2692596.21474788],[16031898.93587157,2692596.21474788],[16143228.52104681,2692596.21474788],[16254549.046934472,2692596.21474788],[16365869.572822122,2692596.21474788],[16477181.039422194,2692596.21474788],[16588510.624597436,2692596.21474788],[16699822.091197504,2692596.21474788],[16811151.676372748,2692596.21474788],[16922454.083685227,2692596.21474788],[17033765.550285302,2692596.21474788],[17145104.19474813,2692596.21474788],[17256415.661348205,2692596.21474788],[17367736.18723587,2692596.21474788],[17479056.71312352,2692596.21474788],[17590377.239011183,2692596.21474788],[17701688.70561124,2692596.21474788],[17813027.350074075,2692596.21474788],[17924338.816674147,2692596.21474788],[18035659.3425618,2692596.21474788],[18146979.868449457,2692596.21474788],[18258282.27576193,2692596.21474788],[18369611.86093717,2692596.21474788],[18480923.327537242,2692596.21474788],[18592261.97200008,2692596.21474788],[18703564.379312553,2692596.21474788],[18814903.023775388,2692596.21474788],[18926205.431087866,2692596.21474788],[19037535.01626311,2692596.21474788],[19148846.482863177,2692596.21474788],[19260167.00875084,2692596.21474788],[19371487.53463849,2692596.21474788],[19482799.001238555,2692596.21474788],[19594128.58641381,2692596.21474788],[19705449.112301473,2692596.21474788],[19816769.638189115,2692596.21474788],[19921404.409836456,2692596.21474788],[20037472.002420496,2692596.21474788]]]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::MultiLineString)).unwrap(),
            r#"{"type": "MultiLineString", "coordinates": [[[-20037505.025679983,2692596.21474788],[-19924286.672913034,2692596.21474788],[-19812966.14702537,2692596.21474788],[-19701645.62113772,2692596.21474788],[-19590325.09525006,2692596.21474788],[-19479004.56936241,2692596.21474788],[-19367684.04347475,2692596.21474788],[-19256372.576874677,2692596.21474788],[-19145042.991699435,2692596.21474788],[-19033736.054743163,2692596.21474788],[-18922401.939924125,2692596.21474788],[-18811090.473324053,2692596.21474788],[-18699774.4770802,2692596.21474788],[-18588449.421548743,2692596.21474788],[-18477128.895661093,2692596.21474788],[-18365812.89941723,2692596.21474788],[-18254492.373529565,2692596.21474788],[-18143167.31799812,2692596.21474788],[-18031860.381041847,2692596.21474788],[-17920530.795866605,2692596.21474788],[-17809219.329266533,2692596.21474788],[-17697898.803378873,2692596.21474788],[-17586578.277491223,2692596.21474788],[-17475257.751603562,2692596.21474788],[-17363937.225715913,2692596.21474788],[-17252616.69982825,2692596.21474788],[-17141296.1739406,2692596.21474788],[-17029984.707340535,2692596.21474788],[-16918659.651809078,2692596.21474788],[-16807343.65556522,2692596.21474788],[-16696014.07038997,2692596.21474788],[-16584707.133433694,2692596.21474788],[-16473382.077902246,2692596.21474788],[-16362061.552014597,2692596.21474788],[-16250745.55577073,2692596.21474788],[-16139425.02988307,2692596.21474788],[-16028104.50399542,2692596.21474788],[-15916783.978107756,2692596.21474788],[-15805472.511507692,2692596.21474788],[-15694142.926332444,2692596.21474788],[-15582831.459732382,2692596.21474788],[-15471510.933844728,2692596.21474788],[-15360190.407957068,2692596.21474788],[-15248869.882069414,2692596.21474788],[-15137549.356181756,2692596.21474788],[-15026228.830294106,2692596.21474788],[-14914908.304406442,2692596.21474788],[-14803587.77851878,2692596.21474788],[-14692267.252631132,2692596.21474788],[-14580955.78603106,2692596.21474788],[-14469630.730499614,2692596.21474788],[-14358314.734255752,2692596.21474788],[-14246994.20836809,2692596.21474788],[-14135678.212124234,2692596.21474788],[-14024353.15659278,2692596.21474788],[-13913032.630705126,2692596.21474788],[-13801716.634461263,2692596.21474788],[-13690391.578929815,2692596.21474788],[-13579080.112329746,2692596.21474788],[-13467755.05679829,2692596.21474788],[-13356439.060554435,2692596.21474788],[-13245114.005022977,2692596.21474788],[-13133802.538422909,2692596.21474788],[-13022482.012535255,2692596.21474788],[-12911161.4866476,2692596.21474788],[-12799840.960759947,2692596.21474788],[-12688520.434872286,2692596.21474788],[-12577199.908984637,2692596.21474788],[-12465883.912740769,2692596.21474788],[-12354567.916496906,2692596.21474788],[-12243238.33132166,2692596.21474788],[-12131926.864721594,2692596.21474788],[-12020601.809190148,2692596.21474788],[-11909285.812946282,2692596.21474788],[-11797969.816702416,2692596.21474788],[-11686644.76117097,2692596.21474788],[-11575328.764927106,2692596.21474788],[-11464008.239039456,2692596.21474788],[-11352687.713151794,2692596.21474788],[-11241367.187264144,2692596.21474788],[-11130051.191020276,2692596.21474788],[-11018726.13548883,2692596.21474788],[-10907414.668888764,2692596.21474788],[-10796094.1430011,2692596.21474788],[-10684773.61711345,2692596.21474788],[-10573453.091225792,2692596.21474788],[-10462132.56533813,2692596.21474788],[-10350812.03945048,2692596.21474788],[-10239491.513562815,2692596.21474788],[-10128170.987675166,2692596.21474788],[-10016854.9914313,2692596.21474788],[-9905538.995187435,2692596.21474788],[-9794209.410012191,2692596.21474788],[-9682902.47305592,2692596.21474788],[-9571577.417524474,2692596.21474788],[-9460261.421280608,2692596.21474788],[-9348940.895392958,2692596.21474788],[-9237615.8398615,2692596.21474788],[-9126299.843617637,2692596.21474788],[-9014979.317729987,2692596.21474788],[-8903663.321486121,2692596.21474788],[-8792338.265954675,2692596.21474788],[-8681022.269710807,2692596.21474788],[-8569692.684535567,2692596.21474788],[-8458385.747579295,2692596.21474788],[-8347069.751335428,2692596.21474788],[-8235749.225447779,2692596.21474788],[-8124424.16991632,2692596.21474788],[-8013099.114384874,2692596.21474788],[-7901787.647784806,2692596.21474788],[-7790467.121897143,2692596.21474788],[-7679155.655297086,2692596.21474788],[-7567826.070121832,2692596.21474788],[-7456510.073877977,2692596.21474788],[-7345185.01834652,2692596.21474788],[-7233873.551746452,2692596.21474788],[-7122553.025858803,2692596.21474788],[-7011232.49997114,2692596.21474788],[-6899911.97408349,2692596.21474788],[-6788586.918552041,2692596.21474788],[-6677270.922308178,2692596.21474788],[-6565950.396420515,2692596.21474788],[-6454638.929820447,2692596.21474788],[-6343309.344645206,2692596.21474788],[-6231993.34840134,2692596.21474788],[-6120677.352157486,2692596.21474788],[-6009356.826269826,2692596.21474788],[-5898040.83002596,2692596.21474788],[-5786715.774494514,2692596.21474788],[-5675395.248606861,2692596.21474788],[-5564074.722719202,2692596.21474788],[-5452754.196831549,2692596.21474788],[-5341433.67094389,2692596.21474788],[-5230126.733987618,2692596.21474788],[-5118797.148812373,2692596.21474788],[-5007481.15256851,2692596.21474788],[-4896165.156324643,2692596.21474788],[-4784844.630436993,2692596.21474788],[-4673524.104549334,2692596.21474788],[-4562203.578661681,2692596.21474788],[-4450883.052774021,2692596.21474788],[-4339562.526886369,2692596.21474788],[-4228242.000998709,2692596.21474788],[-4116935.0640424383,2692596.21474788],[-4005600.9492233978,2692596.21474788],[-3894289.48262333,2692596.21474788],[-3782964.427091881,2692596.21474788],[-3671648.430848018,2692596.21474788],[-3560327.904960355,2692596.21474788],[-3449011.908716501,2692596.21474788],[-3337691.382828842,2692596.21474788],[-3226366.327297393,2692596.21474788],[-3115050.3310535294,2692596.21474788],[-3003729.8051658766,2692596.21474788],[-2892418.338565809,2692596.21474788],[-2781088.7533905646,2692596.21474788],[-2669777.2867904967,2692596.21474788],[-2558456.7609028374,2692596.21474788],[-2447136.2350151846,2692596.21474788],[-2335815.7091275253,2692596.21474788],[-2224495.183239872,2692596.21474788],[-2113174.657352213,2692596.21474788],[-2001854.1314645505,2692596.21474788],[-1890533.6055769008,2692596.21474788],[-1779213.0796892412,2692596.21474788],[-1667901.6130891703,2692596.21474788],[-1556581.087201521,2692596.21474788],[-1445260.5613138585,2692596.21474788],[-1333940.0354262087,2692596.21474788],[-1222619.5095385492,2692596.21474788],[-1111298.9836508965,2692596.21474788],[-999978.457763237,2692596.21474788],[-888662.4615193801,2692596.21474788],[-777341.9356317207,2692596.21474788],[-666025.9393878573,2692596.21474788],[-554696.3542126124,2692596.21474788],[-443393.94690013694,2692596.21474788],[-332073.4210124745,2692596.21474788],[-220743.8358372327,2692596.21474788],[-109432.36923716536,2692596.21474788],[1897.2159380795624,2692596.21474788],[113226.80111332452,2692596.21474788],[224538.26771339183,2692596.21474788],[335876.91217622877,2692596.21474788],[447188.37877629616,2692596.21474788],[558499.8453763635,2692596.21474788],[669820.3712640165,2692596.21474788],[781140.8971516758,2692596.21474788],[892461.4230393288,2692596.21474788],[1003772.889639396,2692596.21474788],[1115111.534102233,2692596.21474788],[1226404.882127126,2692596.21474788],[1337743.52658995,2692596.21474788],[1449064.0524776129,2692596.21474788],[1560384.578365272,2692596.21474788],[1671696.04496533,2692596.21474788],[1783007.5115654003,2692596.21474788],[1894328.03745306,2692596.21474788],[2005648.5633407128,2692596.21474788],[2116978.148515964,2692596.21474788],[2228289.6151160216,2692596.21474788],[2339619.2002912764,2692596.21474788],[2450930.666891334,2692596.21474788],[2562251.1927789967,2692596.21474788],[2673571.718666656,2692596.21474788],[2784901.303841901,2692596.21474788],[2896212.7704419685,2692596.21474788],[3007515.1777544436,2692596.21474788],[3118853.822217281,2692596.21474788],[3230165.2888173484,2692596.21474788],[3341494.8739925832,2692596.21474788],[3452797.2813050686,2692596.21474788],[3564135.925767896,2692596.21474788],[3675438.333080381,2692596.21474788],[3786776.977543208,2692596.21474788],[3898088.444143285,2692596.21474788],[4009399.9107433553,2692596.21474788],[4120720.4366310057,2692596.21474788],[4232040.962518668,2692596.21474788],[4343361.488406317,2692596.21474788],[4454672.9550063815,2692596.21474788],[4566011.599469221,2692596.21474788],[4677323.066069286,2692596.21474788],[4788643.591956948,2692596.21474788],[4899964.117844598,2692596.21474788],[5011284.643732261,2692596.21474788],[5122596.110332319,2692596.21474788],[5233907.576932389,2692596.21474788],[5345246.221395223,2692596.21474788],[5456548.628707701,2692596.21474788],[5567887.273170535,2692596.21474788],[5679189.680483013,2692596.21474788],[5790519.265658256,2692596.21474788],[5901830.732258332,2692596.21474788],[6013151.258145982,2692596.21474788],[6124471.784033645,2692596.21474788],[6235801.36920888,2692596.21474788],[6347112.835808957,2692596.21474788],[6458433.3616966065,2692596.21474788],[6569753.887584269,2692596.21474788],[6681074.413471919,2692596.21474788],[6792394.939359581,2692596.21474788],[6903706.405959652,2692596.21474788],[7015035.991134894,2692596.21474788],[7126356.517022544,2692596.21474788],[7237677.042910206,2692596.21474788],[7348988.509510271,2692596.21474788],[7460299.976110341,2692596.21474788],[7571620.501997991,2692596.21474788],[7682941.027885654,2692596.21474788],[7794261.553773304,2692596.21474788],[7905573.020373374,2692596.21474788],[8016911.664836207,2692596.21474788],[8128223.131436277,2692596.21474788],[8239543.657323928,2692596.21474788],[8350864.18321159,2692596.21474788],[8462184.70909924,2692596.21474788],[8573496.175699318,2692596.21474788],[8684807.642299388,2692596.21474788],[8796146.286762215,2692596.21474788],[8907457.753362292,2692596.21474788],[9018787.338537533,2692596.21474788],[9130098.805137604,2692596.21474788],[9241419.331025254,2692596.21474788],[9352730.797625326,2692596.21474788],[9464069.442088155,2692596.21474788],[9575371.849400638,2692596.21474788],[9686701.434575878,2692596.21474788],[9798012.901175942,2692596.21474788],[9909333.427063596,2692596.21474788],[10020653.952951254,2692596.21474788],[10131965.419551326,2692596.21474788],[10243295.004726568,2692596.21474788],[10354606.471326638,2692596.21474788],[10465936.05650188,2692596.21474788],[10577256.58238953,2692596.21474788],[10688577.108277192,2692596.21474788],[10799888.574877262,2692596.21474788],[10911218.160052504,2692596.21474788],[11022520.567364983,2692596.21474788],[11133841.093252633,2692596.21474788],[11245179.737715466,2692596.21474788],[11356482.145027963,2692596.21474788],[11467811.730203198,2692596.21474788],[11579123.196803275,2692596.21474788],[11690443.722690929,2692596.21474788],[11801764.24857859,2692596.21474788],[11913093.833753832,2692596.21474788],[12024405.3003539,2692596.21474788],[12135707.707666373,2692596.21474788],[12247046.352129214,2692596.21474788],[12358357.818729272,2692596.21474788],[12469687.403904526,2692596.21474788],[12580998.870504584,2692596.21474788],[12692319.39639224,2692596.21474788],[12803630.862992307,2692596.21474788],[12914969.507455144,2692596.21474788],[13026280.9740552,2692596.21474788],[13137610.559230454,2692596.21474788],[13248912.966542937,2692596.21474788],[13360233.492430585,2692596.21474788],[13471554.018318243,2692596.21474788],[13582865.484918306,2692596.21474788],[13694204.129381135,2692596.21474788],[13805515.595981209,2692596.21474788],[13916836.121868871,2692596.21474788],[14028156.64775652,2692596.21474788],[14139477.173644183,2692596.21474788],[14250788.640244242,2692596.21474788],[14362127.284707077,2692596.21474788],[14473429.692019572,2692596.21474788],[14584741.158619631,2692596.21474788],[14696079.80308246,2692596.21474788],[14807382.210394943,2692596.21474788],[14918711.795570198,2692596.21474788],[15030023.262170255,2692596.21474788],[15141343.78805791,2692596.21474788],[15252664.313945567,2692596.21474788],[15364002.9584084,2692596.21474788],[15475305.36572088,2692596.21474788],[15586634.950896127,2692596.21474788],[15697946.417496186,2692596.21474788],[15809257.884096256,2692596.21474788],[15920587.4692715,2692596.21474788],[16031898.93587157,2692596.21474788],[16143228.52104681,2692596.21474788],[16254549.046934472,2692596.21474788],[16365869.572822122,2692596.21474788],[16477181.039422194,2692596.21474788],[16588510.624597436,2692596.21474788],[16699822.091197504,2692596.21474788],[16811151.676372748,2692596.21474788],[16922454.083685227,2692596.21474788],[17033765.550285302,2692596.21474788],[17145104.19474813,2692596.21474788],[17256415.661348205,2692596.21474788],[17367736.18723587,2692596.21474788],[17479056.71312352,2692596.21474788],[17590377.239011183,2692596.21474788],[17701688.70561124,2692596.21474788],[17813027.350074075,2692596.21474788],[17924338.816674147,2692596.21474788],[18035659.3425618,2692596.21474788],[18146979.868449457,2692596.21474788],[18258282.27576193,2692596.21474788],[18369611.86093717,2692596.21474788],[18480923.32753724,2692596.21474788],[18592261.97200008,2692596.21474788],[18703564.379312553,2692596.21474788],[18814903.023775388,2692596.21474788],[18926205.431087863,2692596.21474788],[19037535.01626311,2692596.21474788],[19148846.482863177,2692596.21474788],[19260167.00875084,2692596.21474788],[19371487.53463849,2692596.21474788],[19482799.001238555,2692596.21474788],[19594128.58641381,2692596.21474788],[19705449.112301473,2692596.21474788],[19816769.638189115,2692596.21474788],[19921404.409836456,2692596.21474788],[20037472.002420496,2692596.21474788]]]}"#
        );

        let geojson = r#"{"type": "Polygon", "coordinates": [[[0,0],[0,3],[3,3],[3,0],[0,0]],[[0.2,0.2],[0.2,2],[2,2],[2,0.2],[0.2,0.2]]]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::Polygon)).unwrap(),
            geojson
        );

        Ok(())
    }

    #[test]
    fn geometries3d() -> Result<()> {
        let geojson = r#"{"type": "LineString", "coordinates": [[1,1,10],[2,2,20]]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json_n(
                geojson,
                GeometryType::LineString,
                CoordDimensions::xyz()
            ))
            .unwrap(),
            geojson
        );
        Ok(())
    }

    #[test]
    fn multipolygon() -> Result<()> {
        let geojson = r#"{"type": "MultiPolygon", "coordinates": [[[[173.020375,-40.919052],[173.247234,-41.331999],[173.958405,-40.926701],[174.247587,-41.349155],[174.248517,-41.770008],[173.876447,-42.233184],[173.22274,-42.970038],[172.711246,-43.372288],[173.080113,-43.853344],[172.308584,-43.865694],[171.452925,-44.242519],[171.185138,-44.897104],[170.616697,-45.908929],[169.831422,-46.355775],[169.332331,-46.641235],[168.411354,-46.619945],[167.763745,-46.290197],[166.676886,-46.219917],[166.509144,-45.852705],[167.046424,-45.110941],[168.303763,-44.123973],[168.949409,-43.935819],[169.667815,-43.555326],[170.52492,-43.031688],[171.12509,-42.512754],[171.569714,-41.767424],[171.948709,-41.514417],[172.097227,-40.956104],[172.79858,-40.493962],[173.020375,-40.919052]]],[[[174.612009,-36.156397],[175.336616,-37.209098],[175.357596,-36.526194],[175.808887,-36.798942],[175.95849,-37.555382],[176.763195,-37.881253],[177.438813,-37.961248],[178.010354,-37.579825],[178.517094,-37.695373],[178.274731,-38.582813],[177.97046,-39.166343],[177.206993,-39.145776],[176.939981,-39.449736],[177.032946,-39.879943],[176.885824,-40.065978],[176.508017,-40.604808],[176.01244,-41.289624],[175.239567,-41.688308],[175.067898,-41.425895],[174.650973,-41.281821],[175.22763,-40.459236],[174.900157,-39.908933],[173.824047,-39.508854],[173.852262,-39.146602],[174.574802,-38.797683],[174.743474,-38.027808],[174.697017,-37.381129],[174.292028,-36.711092],[174.319004,-36.534824],[173.840997,-36.121981],[173.054171,-35.237125],[172.636005,-34.529107],[173.007042,-34.450662],[173.551298,-35.006183],[174.32939,-35.265496],[174.612009,-36.156397]]]]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::MultiPolygon)).unwrap(),
            geojson
        );

        // MultiPolygon with Multi-Ring Polygon
        let geojson = r#"{"type": "MultiPolygon", "coordinates": [[[[31.521001,-29.257387],[31.325561,-29.401978],[30.901763,-29.909957],[30.622813,-30.423776],[30.055716,-31.140269],[28.925553,-32.172041],[28.219756,-32.771953],[27.464608,-33.226964],[26.419452,-33.61495],[25.909664,-33.66704],[25.780628,-33.944646],[25.172862,-33.796851],[24.677853,-33.987176],[23.594043,-33.794474],[22.988189,-33.916431],[22.574157,-33.864083],[21.542799,-34.258839],[20.689053,-34.417175],[20.071261,-34.795137],[19.616405,-34.819166],[19.193278,-34.462599],[18.855315,-34.444306],[18.424643,-33.997873],[18.377411,-34.136521],[18.244499,-33.867752],[18.25008,-33.281431],[17.92519,-32.611291],[18.24791,-32.429131],[18.221762,-31.661633],[17.566918,-30.725721],[17.064416,-29.878641],[17.062918,-29.875954],[16.344977,-28.576705],[16.824017,-28.082162],[17.218929,-28.355943],[17.387497,-28.783514],[17.836152,-28.856378],[18.464899,-29.045462],[19.002127,-28.972443],[19.894734,-28.461105],[19.895768,-24.76779],[20.165726,-24.917962],[20.758609,-25.868136],[20.66647,-26.477453],[20.889609,-26.828543],[21.605896,-26.726534],[22.105969,-26.280256],[22.579532,-25.979448],[22.824271,-25.500459],[23.312097,-25.26869],[23.73357,-25.390129],[24.211267,-25.670216],[25.025171,-25.71967],[25.664666,-25.486816],[25.765849,-25.174845],[25.941652,-24.696373],[26.485753,-24.616327],[26.786407,-24.240691],[27.11941,-23.574323],[28.017236,-22.827754],[29.432188,-22.091313],[29.839037,-22.102216],[30.322883,-22.271612],[30.659865,-22.151567],[31.191409,-22.25151],[31.670398,-23.658969],[31.930589,-24.369417],[31.752408,-25.484284],[31.837778,-25.843332],[31.333158,-25.660191],[31.04408,-25.731452],[30.949667,-26.022649],[30.676609,-26.398078],[30.685962,-26.743845],[31.282773,-27.285879],[31.86806,-27.177927],[32.071665,-26.73382],[32.83012,-26.742192],[32.580265,-27.470158],[32.462133,-28.301011],[32.203389,-28.752405],[31.521001,-29.257387]],[[28.978263,-28.955597],[28.5417,-28.647502],[28.074338,-28.851469],[27.532511,-29.242711],[26.999262,-29.875954],[27.749397,-30.645106],[28.107205,-30.545732],[28.291069,-30.226217],[28.8484,-30.070051],[29.018415,-29.743766],[29.325166,-29.257387],[28.978263,-28.955597]]]]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::MultiPolygon)).unwrap(),
            geojson
        );

        Ok(())
    }

    #[test]
    fn collections() -> Result<()> {
        let geojson = r#"{"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [100.1,0.1]},{"type": "LineString", "coordinates": [[101.1,0.1],[102.1,1.1]]}]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(
                geojson,
                GeometryType::GeometryCollection
            ))
            .unwrap(),
            r#"{"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [100.1,0.1]},{"type": "LineString", "coordinates": [[101.1,0.1],[102.1,1.1]]}]}"#,
        );

        let mut geojson = GeoJson(
            r#"{"type": "Point", "coordinates": [2223639.4731508396,-15878634.348995442]}"#,
        );
        let mut fgb_writer = FeatureWriter::new(GeometryType::GeometryCollection, false, false);
        let result = geojson.process(&mut fgb_writer);
        assert_eq!(
            result.err().unwrap().to_string(),
            "processing geometry `Cannot mix geometry types - expected type `GeometryCollection`, actual type `Point``"
        );
        Ok(())
    }

    #[test]
    fn feature() -> Result<()> {
        let mut geojson = GeoJson(
            r#"{"type": "Feature", "properties": {"fid": 42, "name": "New Zealand"}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[173.020375,-40.919052],[173.247234,-41.331999],[173.958405,-40.926701],[174.247587,-41.349155],[174.248517,-41.770008],[173.876447,-42.233184],[173.22274,-42.970038],[172.711246,-43.372288],[173.080113,-43.853344],[172.308584,-43.865694],[171.452925,-44.242519],[171.185138,-44.897104],[170.616697,-45.908929],[169.831422,-46.355775],[169.332331,-46.641235],[168.411354,-46.619945],[167.763745,-46.290197],[166.676886,-46.219917],[166.509144,-45.852705],[167.046424,-45.110941],[168.303763,-44.123973],[168.949409,-43.935819],[169.667815,-43.555326],[170.52492,-43.031688],[171.12509,-42.512754],[171.569714,-41.767424],[171.948709,-41.514417],[172.097227,-40.956104],[172.79858,-40.493962],[173.020375,-40.919052]]],[[[174.612009,-36.156397],[175.336616,-37.209098],[175.357596,-36.526194],[175.808887,-36.798942],[175.95849,-37.555382],[176.763195,-37.881253],[177.438813,-37.961248],[178.010354,-37.579825],[178.517094,-37.695373],[178.274731,-38.582813],[177.97046,-39.166343],[177.206993,-39.145776],[176.939981,-39.449736],[177.032946,-39.879943],[176.885824,-40.065978],[176.508017,-40.604808],[176.01244,-41.289624],[175.239567,-41.688308],[175.067898,-41.425895],[174.650973,-41.281821],[175.22763,-40.459236],[174.900157,-39.908933],[173.824047,-39.508854],[173.852262,-39.146602],[174.574802,-38.797683],[174.743474,-38.027808],[174.697017,-37.381129],[174.292028,-36.711092],[174.319004,-36.534824],[173.840997,-36.121981],[173.054171,-35.237125],[172.636005,-34.529107],[173.007042,-34.450662],[173.551298,-35.006183],[174.32939,-35.265496],[174.612009,-36.156397]]]]}}"#,
        );
        let mut fgb_writer = FeatureWriter::new(GeometryType::Unknown, false, false);
        assert!(geojson.process(&mut fgb_writer).is_ok());
        let mut out: Vec<u8> = Vec::new();
        let feat = FgbFeature {
            header_buf: header(fgb_writer.dataset_type),
            feature_buf: fgb_writer.finish_to_feature(),
        };
        assert_eq!(
            fgb_writer.bbox,
            NodeItem {
                min_x: 166.509144,
                min_y: -46.641235,
                max_x: 178.517094,
                max_y: -34.450662,
                offset: 0
            }
        );
        feat.process(&mut GeoJsonWriter::new(&mut out), 0)?;
        assert_eq!(str::from_utf8(&out).unwrap(), geojson.0);

        Ok(())
    }

    #[test]
    fn type_detection() -> Result<()> {
        let single = r#"{"type": "Feature", "properties": {"fid": 0, "name": "Albania"}, "geometry": {"type": "Polygon", "coordinates": [[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]}}"#;
        let multi = r#"{"type": "Feature", "properties": {"fid": 0, "name": "Albania"}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]]}}"#;
        let mut geojson = GeoJson(single);

        let mut fgb_writer = FeatureWriter::new(GeometryType::Unknown, true, false);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(json, single);

        let mut fgb_writer = FeatureWriter::new(GeometryType::Unknown, true, true);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(json, multi);

        // GeometryCollection
        let mut geojson = GeoJson(
            r#"{"type": "Feature", "properties": {"fid": 0, "name": "Collection"}, "geometry": {"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [100.1,0.1]},{"type": "LineString", "coordinates": [[101.1,0.1],[102.1,1.1]]}]}}"#,
        );
        let mut fgb_writer = FeatureWriter::new(GeometryType::Unknown, true, false);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(
            json,
            r#"{"type": "Feature", "properties": {"fid": 0, "name": "Collection"}, "geometry": {"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [100.1,0.1]},{"type": "LineString", "coordinates": [[101.1,0.1],[102.1,1.1]]}]}}"#
        );
        Ok(())
    }

    #[test]
    fn promote_to_multi() -> Result<()> {
        let single = r#"{"type": "Feature", "properties": {"fid": 0, "name": "Albania"}, "geometry": {"type": "Polygon", "coordinates": [[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]}}"#;
        let multi = r#"{"type": "Feature", "properties": {"fid": 0, "name": "Albania"}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]]}}"#;
        let mut geojson = GeoJson(single);

        let mut fgb_writer = FeatureWriter::new(GeometryType::MultiPolygon, false, true);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(json, multi);

        let mut fgb_writer = FeatureWriter::new(GeometryType::MultiPolygon, false, false);
        let result = geojson.process(&mut fgb_writer);
        assert_eq!(
            result.err().unwrap().to_string(),
            "processing geometry `Cannot mix geometry types - expected type `MultiPolygon`, actual type `Polygon``"
        );

        let mut fgb_writer = FeatureWriter::new(GeometryType::Polygon, false, true);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(json, single);

        let mut fgb_writer = FeatureWriter::new(GeometryType::Polygon, false, false);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(json, single);

        let mut fgb_writer = FeatureWriter::new(GeometryType::Unknown, false, true);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(json, multi);

        let mut fgb_writer = FeatureWriter::new(GeometryType::Unknown, false, false);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        assert_eq!(json, single);

        // Don't promote within collection
        let single = r#"{"type": "Feature", "properties": {"fid": 0, "name": "Collection"}, "geometry": {"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [100.1,0.1]},{"type": "LineString", "coordinates": [[101.1,0.1],[102.1,1.1]]}]}}"#;
        let mut geojson = GeoJson(single);
        let mut fgb_writer = FeatureWriter::new(GeometryType::GeometryCollection, false, true);
        geojson.process(&mut fgb_writer).unwrap();
        let json = write_as_geojson(fgb_writer)?;
        // assert_eq!(json, single); // geozero JSON writer skips GeometryCollection
        assert_eq!(
            json,
            r#"{"type": "Feature", "properties": {"fid": 0, "name": "Collection"}, "geometry": {"type": "GeometryCollection", "geometries": [{"type": "Point", "coordinates": [100.1,0.1]},{"type": "LineString", "coordinates": [[101.1,0.1],[102.1,1.1]]}]}}"#
        );

        Ok(())
    }

    #[test]
    fn feature_collection() -> Result<()> {
        let geojson = r#"{"type": "FeatureCollection", "name": "countries", "features": [{"type": "Feature", "properties": {"id": "NZL", "name": "New Zealand"}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[173.020375,-40.919052],[173.247234,-41.331999],[173.958405,-40.926701],[174.247587,-41.349155],[174.248517,-41.770008],[173.876447,-42.233184],[173.22274,-42.970038],[172.711246,-43.372288],[173.080113,-43.853344],[172.308584,-43.865694],[171.452925,-44.242519],[171.185138,-44.897104],[170.616697,-45.908929],[169.831422,-46.355775],[169.332331,-46.641235],[168.411354,-46.619945],[167.763745,-46.290197],[166.676886,-46.219917],[166.509144,-45.852705],[167.046424,-45.110941],[168.303763,-44.123973],[168.949409,-43.935819],[169.667815,-43.555326],[170.52492,-43.031688],[171.12509,-42.512754],[171.569714,-41.767424],[171.948709,-41.514417],[172.097227,-40.956104],[172.79858,-40.493962],[173.020375,-40.919052]]],[[[174.612009,-36.156397],[175.336616,-37.209098],[175.357596,-36.526194],[175.808887,-36.798942],[175.95849,-37.555382],[176.763195,-37.881253],[177.438813,-37.961248],[178.010354,-37.579825],[178.517094,-37.695373],[178.274731,-38.582813],[177.97046,-39.166343],[177.206993,-39.145776],[176.939981,-39.449736],[177.032946,-39.879943],[176.885824,-40.065978],[176.508017,-40.604808],[176.01244,-41.289624],[175.239567,-41.688308],[175.067898,-41.425895],[174.650973,-41.281821],[175.22763,-40.459236],[174.900157,-39.908933],[173.824047,-39.508854],[173.852262,-39.146602],[174.574802,-38.797683],[174.743474,-38.027808],[174.697017,-37.381129],[174.292028,-36.711092],[174.319004,-36.534824],[173.840997,-36.121981],[173.054171,-35.237125],[172.636005,-34.529107],[173.007042,-34.450662],[173.551298,-35.006183],[174.32939,-35.265496],[174.612009,-36.156397]]]]}}]}"#;
        assert_eq!(
            str::from_utf8(&json_to_fbg_to_json(geojson, GeometryType::MultiPolygon)).unwrap(),
            r#"{"type": "MultiPolygon", "coordinates": [[[[173.020375,-40.919052],[173.247234,-41.331999],[173.958405,-40.926701],[174.247587,-41.349155],[174.248517,-41.770008],[173.876447,-42.233184],[173.22274,-42.970038],[172.711246,-43.372288],[173.080113,-43.853344],[172.308584,-43.865694],[171.452925,-44.242519],[171.185138,-44.897104],[170.616697,-45.908929],[169.831422,-46.355775],[169.332331,-46.641235],[168.411354,-46.619945],[167.763745,-46.290197],[166.676886,-46.219917],[166.509144,-45.852705],[167.046424,-45.110941],[168.303763,-44.123973],[168.949409,-43.935819],[169.667815,-43.555326],[170.52492,-43.031688],[171.12509,-42.512754],[171.569714,-41.767424],[171.948709,-41.514417],[172.097227,-40.956104],[172.79858,-40.493962],[173.020375,-40.919052]]],[[[174.612009,-36.156397],[175.336616,-37.209098],[175.357596,-36.526194],[175.808887,-36.798942],[175.95849,-37.555382],[176.763195,-37.881253],[177.438813,-37.961248],[178.010354,-37.579825],[178.517094,-37.695373],[178.274731,-38.582813],[177.97046,-39.166343],[177.206993,-39.145776],[176.939981,-39.449736],[177.032946,-39.879943],[176.885824,-40.065978],[176.508017,-40.604808],[176.01244,-41.289624],[175.239567,-41.688308],[175.067898,-41.425895],[174.650973,-41.281821],[175.22763,-40.459236],[174.900157,-39.908933],[173.824047,-39.508854],[173.852262,-39.146602],[174.574802,-38.797683],[174.743474,-38.027808],[174.697017,-37.381129],[174.292028,-36.711092],[174.319004,-36.534824],[173.840997,-36.121981],[173.054171,-35.237125],[172.636005,-34.529107],[173.007042,-34.450662],[173.551298,-35.006183],[174.32939,-35.265496],[174.612009,-36.156397]]]]}"#
        );
        Ok(())
    }
}