Skip to content

Commit

Permalink
feat: use our own Geometry struct
Browse files Browse the repository at this point in the history
  • Loading branch information
gadomski committed Jul 9, 2023
1 parent 061c8e8 commit ce8ec37
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 16 deletions.
1 change: 1 addition & 0 deletions stac-validate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ url = "2"

[dev-dependencies]
geojson = "0.24"
stac = { version = "0.5", path = "../stac", features = ["geo"] }
3 changes: 2 additions & 1 deletion stac-validate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ mod tests {
#[test]
fn item_with_geometry() {
let mut item = Item::new("an-id");
item.set_geometry(Geometry::new(Value::Point(vec![-105.1, 40.1])));
item.set_geometry(Geometry::new(Value::Point(vec![-105.1, 40.1])))
.unwrap();
item.validate().unwrap();
}

Expand Down
5 changes: 5 additions & 0 deletions stac/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added

- `geo` feature ([#178](https://github.com/gadomski/stac-rs/pull/178))

### Changed

- `Links::remove_relative_links` has the same vibe as `Links::remove_structural_links` ([#176](https://github.com/gadomski/stac-rs/pull/176))
- Use our own `Geometry` structure ([#178](https://github.com/gadomski/stac-rs/pull/178))

## [0.5.0] - 2023-06-27

Expand Down
5 changes: 3 additions & 2 deletions stac/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ keywords = ["geospatial", "stac", "metadata", "geo", "raster"]
categories = ["science", "data-structures"]

[features]
geo = ["dep:geo", "dep:geojson"]
reqwest = ["dep:reqwest"]

[dependencies]
chrono = "0.4"
geo = "0.25"
geojson = "0.24"
geo = { version = "0.25", optional = true }
geojson = { version = "0.24", optional = true }
reqwest = { version = "0.11", optional = true, features = ["json", "blocking"] }
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
Expand Down
32 changes: 31 additions & 1 deletion stac/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ Please see the [documentation](https://docs.rs/stac) for more usage examples.

## Features

There is one opt-in feature, `reqwest`, for blocking remote reads:
There are two opt-in features.

### reqwest

`reqwest` enables blocking remote reads:

```toml
[dependencies]
Expand All @@ -57,3 +61,29 @@ let err = stac::read::<stac::Item>(href).unwrap_err();
```

For non-blocking IO, use the [**stac-async**](https://crates.io/crates/stac-async) crate.

### geo

To use [geojson](https://docs.rs/geojson) and [geo](https://docs.rs/geo) to add some extra geo-enabled methods:

```toml
[dependencies]
stac = { version = "0.5", features = ["geo"] }
```

Then, you can set an item's geometry and bounding box at the same time:

```rust
use stac::Item;
use geojson::{Geometry, Value};

let geometry = Geometry::new(Value::Point(vec![
-105.1, 41.1,
]));
let mut item = Item::new("an-id");
#[cfg(feature = "geo")]
{
item.set_geometry(geometry).unwrap();
assert!(item.bbox.is_some());
}
```
43 changes: 32 additions & 11 deletions stac/src/item.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::{Asset, Assets, Error, Extensions, Href, Link, Links, Result, STAC_VERSION};
use chrono::Utc;
use geo::BoundingRect;
use geojson::Geometry;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::collections::HashMap;
Expand Down Expand Up @@ -83,6 +81,20 @@ pub struct Item {
href: Option<String>,
}

/// Additional metadata fields can be added to the GeoJSON Object Properties.
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct Geometry {
/// The geometry type.
pub r#type: String,

/// The other geometry attributes.
///
/// `GeometryCollection` doesn't have a `coordinates` member, so we must
/// capture everything in a flat, generic array.
#[serde(flatten)]
pub attributes: Map<String, Value>,
}

/// Additional metadata fields can be added to the GeoJSON Object Properties.
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct Properties {
Expand Down Expand Up @@ -178,18 +190,22 @@ impl Item {
/// item.set_geometry(Some(Geometry::new(Value::Point(vec![-105.1, 41.1]))));
/// assert_eq!(item.bbox.unwrap(), vec![-105.1, 41.1, -105.1, 41.1]);
/// ```
pub fn set_geometry(&mut self, geometry: impl Into<Option<Geometry>>) {
self.geometry = geometry.into();
self.bbox = self
.geometry
#[cfg(feature = "geo")]
pub fn set_geometry(&mut self, geometry: impl Into<Option<geojson::Geometry>>) -> Result<()> {
use geo::BoundingRect;

let geometry = geometry.into();
self.bbox = geometry
.as_ref()
.and_then(|geometry| geo::Geometry::try_from(geometry).ok())
.and_then(|geometry| geometry.bounding_rect())
.map(|rect| {
let min = rect.min();
let max = rect.max();
vec![min.x, min.y, max.x, max.y]
})
});
self.geometry = serde_json::from_value(serde_json::to_value(geometry)?)?;
Ok(())
}
}

Expand Down Expand Up @@ -263,7 +279,6 @@ where
mod tests {
use super::Item;
use crate::STAC_VERSION;
use geojson::Geometry;
use serde_json::Value;

#[test]
Expand Down Expand Up @@ -304,21 +319,27 @@ mod tests {
}

#[test]
#[cfg(feature = "geo")]
fn set_geometry_sets_bbox() {
use geojson::Geometry;
let mut item = Item::new("an-id");
item.set_geometry(Some(Geometry::new(geojson::Value::Point(vec![
-105.1, 41.1,
]))));
]))))
.unwrap();
assert_eq!(item.bbox, Some(vec![-105.1, 41.1, -105.1, 41.1]));
}

#[test]
#[cfg(feature = "geo")]
fn set_geometry_clears_bbox() {
use geojson::Geometry;
let mut item = Item::new("an-id");
item.set_geometry(Some(Geometry::new(geojson::Value::Point(vec![
-105.1, 41.1,
]))));
item.set_geometry(None);
]))))
.unwrap();
item.set_geometry(None).unwrap();
assert_eq!(item.bbox, None);
}

Expand Down
2 changes: 1 addition & 1 deletion stac/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub use {
extensions::Extensions,
href::{href_to_url, Href},
io::{read, read_json},
item::{Item, Properties, ITEM_TYPE},
item::{Geometry, Item, Properties, ITEM_TYPE},
item_collection::{ItemCollection, ITEM_COLLECTION_TYPE},
link::{Link, Links},
value::Value,
Expand Down

0 comments on commit ce8ec37

Please sign in to comment.