Skip to content

Commit

Permalink
Improve usability of library by changing how the types are exported
Browse files Browse the repository at this point in the history
Also updated documentation & other minor improvements
  • Loading branch information
Davichet-e committed Oct 18, 2024
1 parent 5eea8e0 commit 6520028
Show file tree
Hide file tree
Showing 37 changed files with 330 additions and 325 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "meos"
version = "0.1.3"
version = "0.2.0"
license-file = "LICENSE"
authors = ["David García Morillo <[email protected]>"]
repository = "https://github.com/MobilityDB/RustMEOS"
Expand Down
69 changes: 63 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
# Rust MEOS
# RustMEOS

Rust bindings for [meos](https://libmeos.org/) C API.
RustMEOS is a Rust library providing bindings for the [MEOS](https://libmeos.org/) 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.

The supported meos version is >= 1.2
It supports MEOS version >= 1.2

## Disclaimer
## Overview

The crate is still in alpha, this means it is not advised for production usage as some tests are still to be added. This project is checked with valgrind, but if you stumble on a crash feel free to open an issue explaining the problem.
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:

- **Tracking Movement:** Efficiently manage and analyze the movement of objects (e.g., vehicles, ships, animals) over time.
- **Spatiotemporal Queries:**:
- **Distance Calculations:** Compute the shortest distance between trajectories, which can be useful for determining when two moving objects were closest to each other.
- **Time-Weighted Averages:** Analyze time-dependent data, like averaging speeds or temperatures over a period.
- **Intersection Queries:** Check if a trajectory passes through specific points or regions, enabling location-based analysis of movement.

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`:

```toml
[dependencies]
meos = "0.1"
```
Ensure that the `meos` C library is installed on your system. Follow the installation instructions on the [MEOS website](https://github.com/MobilityDB/MobilityDB/?tab=readme-ov-file#requirements).

## Key Features

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

- **Temporal Geometric Points (`TGeomPoint`):** These represent geometric points that change over time (e.g., location data of moving objects).
- **Temporal Float (`TFloat`):** These store numeric values associated with time, such as speed or temperature over time.
- **Temporal Boolean (`TBool`):** Represents true/false values that vary over time, useful for tracking binary states such as whether an object is within a specific area at given times.

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](https://libmeos.org/documentation/datamodel/). 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 the examples in the `examples/` directory.
You can check more examples in the `examples/` directory.

### Constructing trajectories from text:

Expand All @@ -22,6 +50,35 @@ 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):

```rust
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

```rust
Expand Down
42 changes: 11 additions & 31 deletions examples/01_hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn main() {
// Convert results to MF-JSON

let instant_mfjson =
TGeomPoint::Instant(inst).as_mfjson(true, meos::temporal::JSONCVariant::Pretty, 6, "4326");
TGeomPoint::Instant(inst).as_mfjson(true, meos::JSONCVariant::Pretty, 6, "4326");
println!(
"\n\
--------------------\n\
Expand All @@ -48,12 +48,8 @@ fn main() {
instant_wkt, instant_mfjson
);

let seq_disc_mfjson = TGeomPoint::Sequence(seq_disc).as_mfjson(
true,
meos::temporal::JSONCVariant::Pretty,
6,
"4326",
);
let seq_disc_mfjson =
TGeomPoint::Sequence(seq_disc).as_mfjson(true, meos::JSONCVariant::Pretty, 6, "4326");
println!(
"\n\
-------------------------------------------------\n\
Expand All @@ -66,12 +62,8 @@ fn main() {
sequence_discrete_wkt, seq_disc_mfjson
);

let seq_linear_mfjson = TGeomPoint::Sequence(seq_linear).as_mfjson(
true,
meos::temporal::JSONCVariant::Pretty,
6,
"4326",
);
let seq_linear_mfjson =
TGeomPoint::Sequence(seq_linear).as_mfjson(true, meos::JSONCVariant::Pretty, 6, "4326");
println!(
"\n\
-----------------------------------------------\n\
Expand All @@ -84,12 +76,8 @@ fn main() {
sequence_linear_wkt, seq_linear_mfjson
);

let seq_step_mfjson = TGeomPoint::Sequence(seq_step).as_mfjson(
true,
meos::temporal::JSONCVariant::Pretty,
6,
"4326",
);
let seq_step_mfjson =
TGeomPoint::Sequence(seq_step).as_mfjson(true, meos::JSONCVariant::Pretty, 6, "4326");
println!(
"\n\
--------------------------------------------\n\
Expand All @@ -102,12 +90,8 @@ fn main() {
sequence_step_wkt, seq_step_mfjson
);

let ss_linear_mfjson = TGeomPoint::SequenceSet(ss_linear).as_mfjson(
true,
meos::temporal::JSONCVariant::Pretty,
6,
"4326",
);
let ss_linear_mfjson =
TGeomPoint::SequenceSet(ss_linear).as_mfjson(true, meos::JSONCVariant::Pretty, 6, "4326");
println!(
"\n\
---------------------------------------------------\n\
Expand All @@ -120,12 +104,8 @@ fn main() {
sequence_set_linear_wkt, ss_linear_mfjson
);

let ss_step_mfjson = TGeomPoint::SequenceSet(ss_step).as_mfjson(
true,
meos::temporal::JSONCVariant::Pretty,
6,
"4326",
);
let ss_step_mfjson =
TGeomPoint::SequenceSet(ss_step).as_mfjson(true, meos::JSONCVariant::Pretty, 6, "4326");
println!(
"\n\
------------------------------------------------\n\
Expand Down
3 changes: 1 addition & 2 deletions examples/02_ais_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use std::{

use chrono::{DateTime, NaiveDateTime, Utc};
use meos::{
meos_initialize,
temporal::{number::tfloat::TFloatInstant, point::tgeompoint::TGeomPoint},
meos_initialize, {TFloatInstant, TGeomPoint},
};

const MAX_LENGTH_HEADER: usize = 1024;
Expand Down
15 changes: 2 additions & 13 deletions examples/03_ais_assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,8 @@ use std::{

use chrono::{DateTime, NaiveDateTime, Utc};
use meos::{
meos_initialize,
temporal::{
number::{
tfloat::{TFloatInstant, TFloatSequence},
tnumber::TNumber,
},
point::{
tgeompoint::{TGeomPoint, TGeomPointInstant, TGeomPointSequence},
tpoint::TPointTrait,
},
temporal::Temporal,
tinstant::TInstant,
},
meos_initialize, TFloatInstant, TFloatSequence, TGeomPoint, TGeomPointInstant,
TGeomPointSequence, TInstant as _, TNumber as _, TPointTrait as _, Temporal as _,
};

const MAX_INSTANTS: usize = 50000;
Expand Down
20 changes: 4 additions & 16 deletions examples/ais_full_assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,8 @@ use std::{

use chrono::{DateTime, Utc};
use meos::{
meos_initialize,
temporal::{
number::{
tfloat::{TFloatInstant, TFloatSequence},
tnumber::TNumber,
},
point::{
tgeompoint::{TGeomPoint, TGeomPointInstant, TGeomPointSequence},
tpoint::TPointTrait,
},
temporal::Temporal,
tinstant::TInstant,
tsequence::TSequence,
},
meos_initialize, TFloatInstant, TFloatSequence, TGeomPoint, TGeomPointInstant,
TGeomPointSequence, TInstant, TNumber, TPointTrait, TSequence, Temporal,
};

// Constants
Expand Down Expand Up @@ -153,11 +141,11 @@ fn main() {
for trip in trips.iter_mut() {
trip.trip = Some(TSequence::new(
&trip.trip_instants.iter().collect::<Vec<_>>(),
meos::temporal::interpolation::TInterpolation::Linear,
meos::TInterpolation::Linear,
));
trip.sog = Some(TSequence::new(
&trip.sog_instants.iter().collect::<Vec<_>>(),
meos::temporal::interpolation::TInterpolation::Linear,
meos::TInterpolation::Linear,
));

println!(
Expand Down
2 changes: 1 addition & 1 deletion src/boxes/box.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use chrono::{DateTime, TimeDelta, TimeZone, Utc};

use crate::{
collections::{base::collection::Collection, datetime::tstz_span::TsTzSpan},
collections::{base::Collection, datetime::TsTzSpan},
WKBVariant,
};

Expand Down
10 changes: 7 additions & 3 deletions src/boxes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
pub mod r#box;
pub mod stbox;
pub mod tbox;
mod r#box;
mod stbox;
mod tbox;

pub use r#box::Box;
pub use stbox::STBox;
pub use tbox::TBox;
5 changes: 2 additions & 3 deletions src/boxes/stbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ use geos::{Geom, Geometry};
use crate::{
collections::{
base::{
collection::{impl_collection, Collection},
span::Span,
Span, {impl_collection, Collection},
},
datetime::tstz_span::TsTzSpan,
datetime::TsTzSpan,
},
errors::ParseError,
utils::{create_interval, from_meos_timestamp, to_meos_timestamp},
Expand Down
11 changes: 5 additions & 6 deletions src/boxes/tbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ use std::{
ptr,
};

use crate::temporal::temporal::Temporal;
use crate::temporal::Temporal;
use chrono::{DateTime, TimeDelta, TimeZone, Utc};

use crate::{
collections::{
base::{
collection::{impl_collection, Collection},
span::Span,
Span, {impl_collection, Collection},
},
datetime::tstz_span::TsTzSpan,
number::{float_span::FloatSpan, int_span::IntSpan, number_span::NumberSpan},
datetime::TsTzSpan,
number::{FloatSpan, IntSpan, NumberSpan},
},
errors::ParseError,
temporal::number::tfloat::TFloat,
temporal::TFloat,
utils::{create_interval, from_meos_timestamp, to_meos_timestamp},
WKBVariant,
};
Expand Down
13 changes: 10 additions & 3 deletions src/collections/base/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
pub mod collection;
pub mod span;
pub mod span_set;
mod collection;
pub(crate) use collection::impl_collection;
pub use collection::Collection;

mod span;
pub use span::Span;

mod span_set;
pub(crate) use span_set::impl_iterator;
pub use span_set::SpanSet;
4 changes: 1 addition & 3 deletions src/collections/datetime/date_span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use std::{
};

use chrono::{Datelike, NaiveDate, TimeDelta};
use collection::{impl_collection, Collection};
use span::Span;

use crate::{
collections::{base::*, datetime::DAYS_UNTIL_2000},
Expand Down Expand Up @@ -37,7 +35,7 @@ impl Collection for DateSpan {
}
}

impl span::Span for DateSpan {
impl Span for DateSpan {
type SubsetType = TimeDelta;
fn inner(&self) -> *const meos_sys::Span {
self._inner.as_ptr()
Expand Down
16 changes: 11 additions & 5 deletions src/collections/datetime/date_span_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ use std::ptr;
use chrono::Datelike;
use chrono::NaiveDate;
use chrono::TimeDelta;
use collection::{impl_collection, Collection};
use span::Span;
use span_set::impl_iterator;
use std::fmt::Debug;
use std::hash::Hash;
use std::ops::{BitAnd, BitOr};

use crate::collections::base::span_set::SpanSet;
use crate::collections::base::SpanSet;
use crate::collections::base::*;
use crate::errors::ParseError;
use crate::utils::from_interval;

use super::date_span::DateSpan;
use super::DAYS_UNTIL_2000;
Expand All @@ -37,7 +35,7 @@ impl Collection for DateSpanSet {
}
}

impl span_set::SpanSet for DateSpanSet {
impl SpanSet for DateSpanSet {
type SpanType = DateSpan;
type SubsetType = TimeDelta;
fn inner(&self) -> *const meos_sys::SpanSet {
Expand Down Expand Up @@ -246,6 +244,14 @@ impl span_set::SpanSet for DateSpanSet {
}
}

impl DateSpanSet {
pub fn duration(&self, ignore_gaps: bool) -> TimeDelta {
from_interval(unsafe {
meos_sys::datespanset_duration(self._inner.as_ptr(), ignore_gaps).read()
})
}
}

impl Clone for DateSpanSet {
fn clone(&self) -> DateSpanSet {
self.copy()
Expand Down
Loading

0 comments on commit 6520028

Please sign in to comment.