https://github.com/mthh/contour-isobands-rs
Compute isobands and contour polygons (using marching squares algorithm).
https://github.com/mthh/contour-isobands-rs
contour isobands isolines rust
Last synced: about 1 month ago
JSON representation
Compute isobands and contour polygons (using marching squares algorithm).
- Host: GitHub
- URL: https://github.com/mthh/contour-isobands-rs
- Owner: mthh
- License: agpl-3.0
- Created: 2023-02-24T17:33:03.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-03-28T12:22:52.000Z (about 1 year ago)
- Last Synced: 2025-03-27T12:23:54.586Z (about 2 months ago)
- Topics: contour, isobands, isolines, rust
- Language: Rust
- Homepage: https://crates.io/crates/contour-isobands
- Size: 999 KB
- Stars: 20
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Contour-isobands-rs
[](https://github.com/mthh/contour-isobands-rs/actions/workflows/build_test_ubuntu.yml)
[](https://docs.rs/contour-isobands/)Compute isobands *(i.e. contour polygons which enclose all the points of a grid included
between two given values)* by applying marching squares to an array of values.
## Usage
### Basics
Add the following to your `Cargo.toml`:
```toml
[dependencies]
contour-isobands = "0.4.3"
```Then, you can use the `ContourBuilder` to compute isobands:
```rust
use contour_isobands::{ContourBuilder, Band};let values = vec![
1., 1., 1., 1., 1., 1., 1.,
1., 5., 5., 5., 5., 5., 1.,
1., 5., 15., 15., 15., 5., 1.,
1., 5., 10., 10., 10., 5., 1.,
1., 5., 5., 5., 5., 5., 1.,
1., 1., 1., 1., 1., 1., 1.,
];// These intervals will compute 3 bands:
// - the first one will contain all points between 1 (included) and 5 (excluded)
// - the second one will contain all points between 5 (included) and 7 (excluded)
// - the third one will contain all points between 7 (included) and 15 (included)
let intervals = vec![1., 5., 7., 15.];let result: Vec = ContourBuilder::new(7, 6)
.use_quad_tree(true)
.contours(&values, &intervals)?;assert_eq!(result.len(), 3);
```The result is a vector of `Band` structs, each one containing a geometry (`MultiPolygon`) and the minimum and maximum values of the band.
Note that you can specify the coordinates of the grid and the distance between points (on x- and y-axis)
using the `x_origin`, `y_origin`, `x_step` and `y_step` parameters of the `ContourBuilder` constructor :```rust
let result: Vec = ContourBuilder::new(7, 6)
.x_origin(-6.144721)
.y_origin(51.781713)
.x_step(0.118759)
.y_step(-0.089932)
.use_quad_tree(true)
.contours(&values, &intervals)?;
```### `geojson` feature
Each `Band` struct contains a geometry (`MultiPolygon`) and the minimum and maximum values of the band.
It can be serialized to geojson using the `geojson` feature:```toml
[dependencies]
contour-isobands = { version = "0.4.3", features = ["geojson"] }
``````rust
use contour_isobands::{ContourBuilder, Band};
use geojson::{Feature, FeatureCollection};let values = vec![
1., 1., 1., 1., 1., 1., 1.,
1., 5., 5., 5., 5., 5., 1.,
1., 5., 15., 15., 15., 5., 1.,
1., 5., 10., 10., 10., 5., 1.,
1., 5., 5., 5., 5., 5., 1.,
1., 1., 1., 1., 1., 1., 1.,
];let intervals = vec![1., 5., 7., 15.];
let result = ContourBuilder::new(7, 6)
.use_quad_tree(true)
.contours(&values, &intervals)?;
let features = result.iter()
.map(|band| band.to_geojson())
.collect::>();let geojson_string = GeoJson::from(
FeatureCollection {
bbox: None,
features,
foreign_members: None,
}).to_string();
```Note that the polygons exterior rings are oriented in the counter-clockwise direction,
while the interior rings are oriented in the clockwise direction
(in accordance with the GeoJSON RFC 7946 specification).### `parallel` feature
```toml
[dependencies]
contour-isobands = { version = "0.4.3", features = ["parallel"] }
```The `parallel` feature enables the use of the `rayon` crate to parallelize the computation of the isobands.
By enabling this feature, the `ContourBuilder` struct exposes a `par_contours` method :```rust
let result: Vec = ContourBuilder::new(7, 6)
.x_origin(-6.144721)
.y_origin(51.781713)
.x_step(0.118759)
.y_step(-0.089932)
.use_quad_tree(true)
.par_contours(&values, &intervals)?;
```Note that you can still use the `contours` method if you don't want
to use parallelism (indeed, on small grids, the overhead of parallelism can be higher than the gain).## WASM demo
A demo of this crate, compiled to WebAssembly, is available on [https://mthh.github.io/contour-wasm/](https://mthh.github.io/contour-wasm/).
## Difference with the [contour](https://crates.io/crates/contour) crate (from [`mthh/contour-rs`](https://github.com/mthh/contour-rs) repository)
The [contour](https://crates.io/crates/contour) crate computes isolines
(cf. [wikipedia:Marching_squares](https://en.wikipedia.org/wiki/Marching_squares)) and
use them to compute their corresponding contour polygons *(i.e. polygons that contain all points above the threshold defined
for a given isoline)* and isobands *(i.e. contour polygons that contain all points between
a minimum and a maximum bound)*.
This `contour-isobands-rs` is dedicated to isobands, also uses marching squares
(cf. [wikipedia:Marching_squares#Isobands](https://en.wikipedia.org/wiki/Marching_squares#Isobands))
but uses a slightly different implementation for the disambiguation of saddle points.
It also offers parallel computation of isobands using the `rayon` crate, which can be beneficial
when computing isobands on large grids and with many thresholds.## Licence
Since this is mostly a port of [https://github.com/RaumZeit/MarchingSquares.js](https://github.com/RaumZeit/MarchingSquares.js) which is licenced under the Affero General Public License v3.0, this project is also licenced under the Affero General Public License v3.0.
See the [LICENSE](LICENSE) file for details.