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
//! Expose [`ToGeo::to_geom`]

use anyhow::{Context, Result as AnyResult};
use clap::{Parser, ValueEnum};
use geojson::Feature;
use h3o::{geom::ToGeo, CellIndex};
use kml::Kml;

/// Converts indexes to (multi)polygon.
///
/// All indexes must have the same resolution.
#[derive(Parser, Debug)]
pub struct Args {
    /// Cell index.
    #[arg(short, long)]
    index: Option<CellIndex>,

    /// Output format.
    #[arg(short, long, value_enum, default_value_t = Format::Geojson)]
    format: Format,

    /// Prettify the output (GeoJSON only)
    #[arg(short, long, default_value_t = false)]
    pretty: bool,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
enum Format {
    Geojson,
    Kml,
}

/// Run the `cellToPolygon` command.
pub fn run(args: &Args) -> AnyResult<()> {
    let indexes = crate::utils::get_cell_indexes(args.index)
        .collect::<AnyResult<Vec<_>>>()?;

    match args.format {
        Format::Geojson => {
            let geometry = indexes.to_geojson().context("compute GeoJSON")?;
            let feature = Feature {
                bbox: None,
                geometry: Some(geometry),
                id: None,
                properties: None,
                foreign_members: None,
            };
            crate::json::print(&feature, args.pretty)?;
        }
        Format::Kml => {
            let style_id = "lineStyle1";
            let style = kml::types::Style {
                id: Some(style_id.to_owned()),
                line: Some(kml::types::LineStyle {
                    id: Some("lineStyle2".to_owned()),
                    color: "ff0000ff".to_owned(),
                    width: 2.,
                    ..kml::types::LineStyle::default()
                }),
                ..kml::types::Style::default()
            };

            let elements = vec![
                Kml::Style(style),
                crate::kml::polygons(
                    indexes.to_geom(true).context("compute polygons")?,
                    style_id,
                ),
            ];

            crate::kml::print_document(
                "H3 Geometry".to_owned(),
                "Generated by cellToPolygon".to_owned(),
                elements,
            )?;
        }
    }

    Ok(())
}