New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to write a vector of polygons? #161
Comments
Related question: how can the result be made to print with 'pretty' GeoJSON formatting? Sure it's possible but not quite sure how even after reading some of the docs here: https://docs.rs/geojson/0.22.0/geojson/#writing |
serde_json has a to_string_pretty() method (https://docs.serde.rs/serde_json/fn.to_string_pretty.html) so you should be able to do to_string_pretty(&geojson). See here for indentation options: https://stackoverflow.com/a/49087292 |
Thanks for the comments and links, very useful. Happy to say that the pretty json printing is working 🎉 Unfortunately when it does print, the geojson specific elements like the use geo::Point;
use serde_json::to_string_pretty;
use zonebuilder::clockboard;
use zonebuilder::Params;
fn main() {
let polygon_list = clockboard(Point::new(0.0, 0.0), Params::default());
// This works but only restults in 1 polygon:
let geojson_list = geojson::Value::from(&polygon_list[0]);
println!("{}", geojson_list);
// This fails - cannot handle more than 1 polygon it seems and there's no unwrap method I can see:
// let geojson_list = geojson::Value::from(&polygon_list);
// println!("{}", geojson_list);
// serde json version gives: [ [ [ 1.0, 0.0 ], (no 'geo')
let result = serde_json::to_string_pretty(&geojson_list);
println!("{}", result.unwrap());
// Trying to get it working with json to_string_pretty:
// let geojson_unwrapped = polygon_list.unwrap()
// println!("{}", geojson_unwrapped);
} And here's the result showing the 2 types of output:
|
Update, the following produces a better result, but this is not valid GeoJSON: fn main() {
let polygon_list = clockboard(Point::new(0.0, 0.0), Params::default());
// See https://github.com/georust/geojson/issues/161 for details
let result = serde_json::to_string_pretty(&polygon_list);
println!("{}", result.unwrap());
} cargo run
Compiling zonebuilder v0.1.0 (/home/robin/github-orgs/zonebuilders/zonebuilder-rust)
warning: unused import: `serde_json::to_string_pretty`
--> src/main.rs:2:5
|
2 | use serde_json::to_string_pretty;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
Finished dev [unoptimized + debuginfo] target(s) in 0.40s
Running `target/debug/zonebuilder`
[
{
"exterior": [
{
"x": 1.0,
"y": 0.0
},
{
"x": 0.866025,
"y": 0.499999
},
... |
And trying to convert it into a geojson object first also fails:
With the following message:
Guess: I need to iterate over each polygon, e.g. with a for loop. Wonder if there is another solution. Apologies for all the comments/questions and thanks in advance for the support! |
Good news: I've succeeded in writing a vector polygons, but using the brute force approach of a for loop and no prettified GeoJSON output. fn main() {
let polygon_list = clockboard(Point::new(0.0, 0.0), Params::default());
// Attempt to print pretty json - not outputting valid json currently
// See https://github.com/georust/geojson/issues/161 for details
// let geojson_list = geojson::Value::from(&polygon_list[0]);
// let result = serde_json::to_string_pretty(&geojson_list);
// println!("{}", result.unwrap());
// Brute force approach: for loop
for polygon in polygon_list {
let result = geojson::Value::from(&polygon);
println!("{}", result);
}
} |
The reason that this is somewhat convoluted is because GeoJSON uses nested values: a There's a relatively close correspondence between
In our case, we have First, we need to convert those into
Anyway, on to the code:
The iterator is a bit like a Now that we have a
Again, note that there are some fields we're leaving blank here by using We're now (finally!) ready to build a
…which we can borrow to produce a pretty-printed string:
Which we can print / dump / etc:
|
Fantastic, many thanks @urschrei. I was just about to write another comment explaining that it almost worked but failed at the last hurdle but, remembering something about |
Issue is closed! As a quick follow-up and as an exercise in reproducibility please try to reproduce the following to check it works. git clone https://github.com/zonebuilders/zonebuilder-rust.git
cd zonebuilder-rust
git checkout circles
Run the CLI: cargo run > circle.geojson
Take a look at the output: head -c 80 circle.geojson
Then read in the GeoJSON file with another tool, e.g. R: circle = sf::read_sf("circle.geojson")
plot(circle) |
162: Provide additional conversions from `Geometry` and `Value` to `Feature` r=michaelkirk a=urschrei While addressing #161, I once again had the feeling that this crate can be made of papercuts sometimes. Based on the assumption that one of the primary uses of GeoJSON as a format is the production of `FeatureCollection` objects, this PR provides some additional conversions from `Value` enum members and `Geometry` objects to `Feature` objects. <s>I'm also considering an additional `From` impl to construct a `FeatureCollection` from a `geo_types::GeometryCollection`</s> Done! Co-authored-by: Stephan Hügel <shugel@tcd.ie>
Heads-up @urschrei and @michaelkirk you'll be pleased to see, this fix is incorporated in the zonebuilder repo (in a branch at least): https://github.com/zonebuilders/zonebuilder-rust/pull/22/files |
Thanks @Robinlovelace! We've just now published these changes to crates.io, so you could update your Cargo.toml to use |
Thanks Michael, |
Apologies if I'm missing something obvious but I'm working on a project to try to learn Rust and cannot see how to save a list of polygons.
A single polygon works fine with the following code:
Which outputs
And so does the next feature when the relevant line is set to:
But the following fails:
With the following error message:
Context: zonebuilders/zonebuilder-rust#18
The text was updated successfully, but these errors were encountered: