Skip to content

Commit

Permalink
GeoJsonSeq formater
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartlynn committed May 16, 2024
1 parent 30a9f74 commit 1278f1e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 19 deletions.
10 changes: 7 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use clap::{Args, Parser, Subcommand};
use enum_dispatch::enum_dispatch;
use popgetter::{
data_request_spec::{BBox, DataRequestSpec, MetricSpec, RegionSpec},
formatters::{CSVFormatter, GeoJSONFormatter, OutputFormatter, OutputGenerator}, Popgetter
formatters::{CSVFormatter, GeoJSONFormatter, GeoJSONSeqFormatter, OutputFormatter, OutputGenerator}, Popgetter
};
use serde::{Deserialize, Serialize};
use std::{fs::File, str::FromStr};
Expand All @@ -16,6 +16,7 @@ use strum_macros::EnumString;
#[strum(ascii_case_insensitive)]
pub enum OutputFormat {
GeoJSON,
GeoJSONSeq,
Csv,
GeoParquet,
FlatGeobuf,
Expand Down Expand Up @@ -56,13 +57,16 @@ impl RunCommand for DataCommand {
let data_request = DataRequestSpec::from(self);
let mut results = popgetter.get_data_request(&data_request).await?;

let formatter = match(&self.output_format){
let formatter = match &self.output_format{
OutputFormat::GeoJSON=>{
OutputFormatter::GeoJSON(GeoJSONFormatter::default())
OutputFormatter::GeoJSON(GeoJSONFormatter)
},
OutputFormat::Csv=>{
OutputFormatter::Csv(CSVFormatter::default())
},
OutputFormat::GeoJSONSeq=>{
OutputFormatter::GeoJSONSeq(GeoJSONSeqFormatter)
},
_=>todo!("output format not implemented")
};

Expand Down
45 changes: 29 additions & 16 deletions src/formatters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,19 @@ fn any_value_to_json(value: &AnyValue) -> Result<Value> {

/// Trait to define different output generators. Defines two
/// functions, format which generates a serialized string of the
/// DataFrame and save which generates a file with the generated
/// `DataFrame` and save which generates a file with the generated
/// file
#[enum_dispatch]
pub trait OutputGenerator {
fn format(&self, df: &mut DataFrame) -> Result<String>;
fn save(&self, writer: &mut impl Write, df: &mut DataFrame) -> Result<()>;
fn format(&self, df: &mut DataFrame) -> Result<String> {
// Just creating an empty vec to store the buffered output
let mut data: Vec<u8> = vec![0; 200];
let mut buff = Cursor::new(&mut data);
self.save(&mut buff, df)?;

Ok(String::from_utf8(data)?)
}
}

/// Enum of OutputFormatters one for each potential
Expand All @@ -66,12 +73,27 @@ pub enum OutputFormatter {
pub struct GeoJSONSeqFormatter;

impl OutputGenerator for GeoJSONSeqFormatter {
fn format(&self, df: &mut DataFrame) -> Result<String> {
Ok("Test".into())
}

fn save(&self, writer: &mut impl Write, df: &mut DataFrame) -> Result<()> {
let output = self.format(df)?;
let geometry_col = df.column("geometry")?;
let other_cols = df.drop("geometry")?;
for (idx, geom) in geometry_col.str()?.into_iter().enumerate() {
if let Some(wkt_str) = geom {
let geom: Geometry<f64> = Geometry::try_from_wkt_str(wkt_str).unwrap();
let mut properties = serde_json::Map::new();
for col in other_cols.get_columns() {
let val = any_value_to_json(&col.get(idx)?)?;
properties.insert(col.name().to_string(), val);
}
let feature = geojson::Feature {
bbox: None,
geometry: Some(geojson::Geometry::from(&geom)),
id: None,
properties: Some(properties),
foreign_members: None,
};
writeln!(writer, "{feature}")?;
}
}
Ok(())
}
}
Expand All @@ -94,15 +116,6 @@ pub struct CSVFormatter {
}

impl OutputGenerator for CSVFormatter {
fn format(&self, df: &mut DataFrame) -> Result<String> {
// Just creating an empty vec to store the buffered output
let mut data: Vec<u8> = vec![0; 200];
let mut buff = Cursor::new(&mut data);
self.save(&mut buff, df)?;

Ok(String::from_utf8(data)?)
}

fn save(&self, writer: &mut impl Write, df: &mut DataFrame) -> Result<()> {
CsvWriter::new(writer).finish(df)?;
Ok(())
Expand Down

0 comments on commit 1278f1e

Please sign in to comment.