MobilityDB / meos-rs

Rust bindings for MEOS
https://docs.rs/meos/
Other
7 stars 0 forks source link

meos-rs

github crates.io docs.rs

meos-rs is a Rust library providing bindings for the MEOS C library, designed for spatiotemporal data management and analysis. It enables handling of temporal and spatial data, making it ideal for applications that need to work with moving objects, trajectories, and time-varying geographical data.

It supports MEOS version >= 1.2

Overview

The primary goal of this library is to facilitate the creation and manipulation of temporal types, such as time-stamped geographic points, sequences, and numeric values. These temporal data structures can be used for various use cases including:

This library provides access to advanced spatiotemporal data handling capabilities of MEOS while maintaining Rust’s memory safety, concurrency, and performance benefits.

Installation

Add the following dependency to your Cargo.toml:

[dependencies]
meos = "0.2"

Ensure that the meos C library is installed on your system. Follow the installation instructions on the MEOS website.

Key Features

The library offers a range of temporal data types, including:

The type hierarchy is the following, the main types (TGeomPoint, TFloat, etc.) are enums that encapsulate the different kinds of temporal subtypes, Instant, Sequence, and SequenceSet, to learn more about these, refer to the meos documentation. Users can almost seamlessly use either the enums or the concrete structs (e.g. TGeomPointSequence). Some users may benefit from using the concrete structs since more concrete types can be inferred in some functions.

Usage example

You can check more examples in the examples/ directory.

Constructing trajectories from text:

use meos::{meos_initialize, TGeomPoint};

meos_initialize();

let trajectory: TGeomPoint = "[POINT(1 1)@2000-01-01 08:00, POINT(2 2)@2000-01-01 08:01]".parse().unwrap();

Constructing trajectories from a list of pairs (point, timestamp):

    use chrono::{DateTime, TimeZone, Utc};
    use geos::Geometry;
    use meos::{meos_initialize, TGeomPointSequence};

    meos_initialize();

    let geometries_with_time: Vec<(Geometry, DateTime<Utc>)> = vec![
        (
            Geometry::new_from_wkt("POINT(1 1)").unwrap(),
            Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(),
        ),
        (
            Geometry::new_from_wkt("POINT(3 2)").unwrap(),
            Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap(),
        ),
        (
            Geometry::new_from_wkt("POINT(3 3)").unwrap(),
            Utc.with_ymd_and_hms(2020, 1, 1, 0, 2, 0).unwrap(),
        ),
    ];

    let tpoint: TGeomPointSequence = geometries_with_time.into_iter().collect();

    println!("{tpoint:?}");

Get the shortest distance ever between two temporal points

use meos::{meos_initialize, TGeomPoint, TPointTrait};

meos_initialize();

let tpoint1: TGeomPoint =
    "[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-05)"
        .parse()
        .unwrap();
let tpoint2: TGeomPoint =
    "[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06)"
        .parse()
        .unwrap();

let distance = tpoint1.nearest_approach_distance(&tpoint2);
println!("{distance}"); // Prints 0.5

Check if a trajectory ever goes through a point (using geos)

use geos::Geometry;
use meos::{meos_initialize, TGeomPoint, Temporal};

meos_initialize();

let trajectory: TGeomPoint = "[Point(0 0 0)@2001-01-01, Point(2 2 2)@2001-01-05)"
    .parse()
    .unwrap();
let geom = Geometry::new_from_wkt("Point (1 1 1)").expect("Invalid geometry");

println!(
    "Does go through `geom`: {}",
    trajectory.ever_equal_than_value(geom).unwrap()
); // `true`

Multithreading

Right now it should only be used in single-threaded applications. In the foreseeable future this could change.

Build

This crate links dynamically to your system-installed meos. See sys/README.md for more information.

Contributing

Only a subset of meos has been implemented, feel free to add wrappers for missing features.

All added features needs to be tested and this being a C wrapper, valgrind runs on all examples/tests to check that no bugs / memory leaks are lurking.

Acknowledgments

This wrapper has been deeply influenced by the Rust wrapper of geos