@@ -5,29 +5,43 @@ For example to convert a GeoJSON file into CSV data:
55
66qsv geoconvert file.geojson geojson csv
77
8+ To convert a CSV file into GeoJSON data, specify the WKT geometry column with the --geometry flag:
9+
10+ qsv geoconvert file.csv csv geojson --geometry geometry
11+
812Usage:
913 qsv geoconvert [options] (<input>) (<input-format>) (<output-format>)
1014 qsv geoconvert --help
1115
1216geoconvert REQUIRED arguments:
1317 <input> The spatial file to convert. Does not support stdin.
14- <input-format> Valid values are "geojson" and "shp "
18+ <input-format> Valid values are "geojson", "shp", and "csv "
1519 <output-format> Valid values are:
16- - For GeoJSON input: "csv" and "svg"
17- - For SHP input: "csv" and "geojson"
20+ - For GeoJSON input: "csv", "svg", and "geojsonl"
21+ - For SHP input: "csv", "geojson", and "geojsonl"
22+ - For CSV input: "geojson", "geojsonl", and "svg"
23+
24+ geoconvert options:
25+ REQUIRED FOR CSV INPUT:
26+ -g, --geometry <geometry> The name of the column that has WKT geometry.
1827
1928Common options:
20- -h, --help Display this message
21- -o, --output <file> Write output to <file> instead of stdout.
29+ -h, --help Display this message
30+ -o, --output <file> Write output to <file> instead of stdout.
2231"# ;
2332
2433use std:: {
2534 fs:: File ,
26- io:: { self , BufWriter , Write } ,
35+ io:: { self , BufReader , BufWriter , Write } ,
2736 path:: Path ,
2837} ;
2938
30- use geozero:: { ProcessToCsv , ProcessToSvg , csv:: CsvWriter , geojson:: GeoJsonWriter } ;
39+ use geozero:: {
40+ GeozeroDatasource ,
41+ csv:: CsvWriter ,
42+ geojson:: { GeoJsonLineWriter , GeoJsonWriter } ,
43+ svg:: SvgWriter ,
44+ } ;
3145use serde:: Deserialize ;
3246
3347use crate :: { CliError , CliResult , util} ;
@@ -37,7 +51,9 @@ use crate::{CliError, CliResult, util};
3751#[ serde( rename_all = "lowercase" ) ]
3852enum InputFormat {
3953 Geojson ,
54+ // Geojsonl,
4055 Shp ,
56+ Csv ,
4157}
4258
4359/// Supported output formats for spatial data conversion
@@ -47,13 +63,15 @@ enum OutputFormat {
4763 Csv ,
4864 Svg ,
4965 Geojson ,
66+ Geojsonl ,
5067}
5168
5269#[ derive( Deserialize ) ]
5370struct Args {
5471 arg_input : Option < String > ,
5572 arg_input_format : InputFormat ,
5673 arg_output_format : OutputFormat ,
74+ flag_geometry : Option < String > ,
5775 flag_output : Option < String > ,
5876}
5977
@@ -93,43 +111,121 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
93111 } else {
94112 Box :: new ( BufWriter :: new ( stdout. lock ( ) ) )
95113 } ;
96-
114+ let mut buf_reader = BufReader :: new ( File :: open ( & input_path) ?) ;
115+ // let mut buf_reader = if let Some(input_path) = args.arg_input {
116+ // if input_path == "-" {
117+ // BufReader::new(std::io::stdin())
118+ // }
119+ // } else {
120+ // BufReader::new(std::io::stdin())
121+ // };
97122 // Construct a spatial geometry based on the input format
98- let output_string = match args. arg_input_format {
123+ match args. arg_input_format {
99124 InputFormat :: Geojson => {
100- let input_string = std:: fs:: read_to_string ( & input_path) ?;
101- let mut geometry = geozero:: geojson:: GeoJson ( & input_string) ;
125+ let mut geometry = geozero:: geojson:: GeoJsonReader ( & mut buf_reader) ;
102126 match args. arg_output_format {
103- OutputFormat :: Csv => geometry. to_csv ( ) ?,
104- OutputFormat :: Svg => geometry. to_svg ( ) ?,
127+ OutputFormat :: Csv => {
128+ let mut processor = CsvWriter :: new ( & mut wtr) ;
129+ geometry. process ( & mut processor) ?
130+ } ,
131+ OutputFormat :: Svg => {
132+ let mut processor = SvgWriter :: new ( & mut wtr, false ) ;
133+ geometry. process ( & mut processor) ?
134+ } ,
135+ OutputFormat :: Geojsonl => {
136+ let mut processor = GeoJsonLineWriter :: new ( & mut wtr) ;
137+ geometry. process ( & mut processor) ?
138+ } ,
105139 OutputFormat :: Geojson => {
106140 return fail_clierror ! ( "Converting GeoJSON to GeoJSON is not supported" ) ;
107141 } ,
108- }
142+ } ;
109143 } ,
144+ // InputFormat::Geojsonl => {
145+ // let mut geometry = geozero::geojson::GeoJsonLineReader::new(&mut buf_reader);
146+ // match args.arg_output_format {
147+ // OutputFormat::Csv => {
148+ // let mut processor = CsvWriter::new(&mut wtr);
149+ // geometry.process(&mut processor)?
150+ // },
151+ // OutputFormat::Svg => {
152+ // let mut processor = SvgWriter::new(&mut wtr, false);
153+ // geometry.process(&mut processor)?
154+ // },
155+ // OutputFormat::Geojson => {
156+ // let mut processor = GeoJsonWriter::new(&mut wtr);
157+ // geometry.process(&mut processor)?
158+ // },
159+ // OutputFormat::Geojsonl => {
160+ // return fail_clierror!("Converting GeoJSON Lines to GeoJSON Lines is not
161+ // supported"); }
162+ // };
163+ // },
110164 InputFormat :: Shp => {
111- let reader = geozero:: shp:: ShpReader :: from_path ( & input_path)
112- . map_err ( |e| CliError :: Other ( format ! ( "Failed to read SHP file: {e}" ) ) ) ?;
113- match args. arg_output_format {
165+ let mut reader = geozero:: shp:: ShpReader :: new ( & mut buf_reader) ?;
166+ let mut input_reader = BufReader :: new ( File :: open ( input_path. replace ( ".shp" , ".shx" ) ) ?) ;
167+ let mut dbf_reader = BufReader :: new ( File :: open ( input_path. replace ( ".shp" , ".dbf" ) ) ?) ;
168+ reader. add_index_source ( & mut input_reader) ?;
169+ reader. add_dbf_source ( & mut dbf_reader) ?;
170+ let output_string = match args. arg_output_format {
114171 OutputFormat :: Geojson => {
115172 let mut json: Vec < u8 > = Vec :: new ( ) ;
116- reader. iter_features ( & mut GeoJsonWriter :: new ( & mut json) ) ?;
173+ let _ = reader
174+ . iter_features ( & mut GeoJsonWriter :: new ( & mut json) ) ?
175+ . collect :: < Vec < _ > > ( ) ;
176+ String :: from_utf8 ( json)
177+ . map_err ( |e| CliError :: Other ( format ! ( "Invalid UTF-8 in output: {e}" ) ) ) ?
178+ } ,
179+ OutputFormat :: Geojsonl => {
180+ let mut json: Vec < u8 > = Vec :: new ( ) ;
181+ let _ = reader
182+ . iter_features ( & mut GeoJsonLineWriter :: new ( & mut json) ) ?
183+ . collect :: < Vec < _ > > ( ) ;
117184 String :: from_utf8 ( json)
118185 . map_err ( |e| CliError :: Other ( format ! ( "Invalid UTF-8 in output: {e}" ) ) ) ?
119186 } ,
120187 OutputFormat :: Csv => {
121188 let mut csv: Vec < u8 > = Vec :: new ( ) ;
122- reader. iter_features ( & mut CsvWriter :: new ( & mut csv) ) ?;
189+ let _ = reader
190+ . iter_features ( & mut CsvWriter :: new ( & mut csv) ) ?
191+ . collect :: < Vec < _ > > ( ) ;
123192 String :: from_utf8 ( csv)
124193 . map_err ( |e| CliError :: Other ( format ! ( "Invalid UTF-8 in output: {e}" ) ) ) ?
125194 } ,
126195 OutputFormat :: Svg => {
127196 return fail_clierror ! ( "Converting SHP to SVG is not supported" ) ;
128197 } ,
198+ } ;
199+ wtr. write_all ( output_string. as_bytes ( ) ) ?;
200+ } ,
201+ InputFormat :: Csv => {
202+ if let Some ( geometry_col) = args. flag_geometry {
203+ let mut csv = geozero:: csv:: CsvReader :: new ( & geometry_col, buf_reader) ;
204+ match args. arg_output_format {
205+ OutputFormat :: Geojson => {
206+ let mut processor = GeoJsonWriter :: new ( & mut wtr) ;
207+ csv. process ( & mut processor) ?;
208+ } ,
209+ OutputFormat :: Geojsonl => {
210+ let mut processor = GeoJsonLineWriter :: new ( & mut wtr) ;
211+ csv. process ( & mut processor) ?
212+ } ,
213+ OutputFormat :: Svg => {
214+ let mut processor = SvgWriter :: new ( & mut wtr, false ) ;
215+ csv. process ( & mut processor) ?;
216+ } ,
217+ OutputFormat :: Csv => {
218+ return fail_clierror ! ( "Converting CSV to CSV is not supported" ) ;
219+ } ,
220+ } ;
221+ } else {
222+ return fail_clierror ! (
223+ "Please specify a geometry column with the --geometry option"
224+ ) ;
129225 }
130226 } ,
131227 } ;
132228
133- wtr. write_all ( output_string. as_bytes ( ) ) ?;
229+ // wtr.write_all(output_string.as_bytes())?;
134230 Ok ( wtr. flush ( ) ?)
135231}
0 commit comments