Skip to content
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

Date collections and MEOS sync #30

Merged
merged 38 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5ac5d90
Start creating Date collections
Diviloper Dec 28, 2023
6e80eb1
Add date conversion functions
Diviloper Dec 29, 2023
52e3aab
Add files for new date collections
Diviloper Dec 29, 2023
7101d19
Merge branch 'develop' into date
Diviloper Dec 29, 2023
f0a7b10
Add DateSet
Diviloper Dec 30, 2023
ba96859
Add DateSpan
Diviloper Dec 31, 2023
bd4e93b
Add DateSpanSet
Diviloper Dec 31, 2023
a49e421
Add VSCode folders to .gitignore
Diviloper Jan 3, 2024
b95e0ff
Update .gitignores
Diviloper Jan 3, 2024
e752369
Update time collections tests
Diviloper Dec 31, 2023
8539323
Update from_base_time type annotations in tfloat and tpoint
Diviloper Dec 31, 2023
9eda840
Update pymeos_cffi enum with new date types
Diviloper Dec 31, 2023
cfd262b
Add new factory for Collection types
Diviloper Jan 3, 2024
807180a
Add polymorphic typings in base class instead of overriding the metho…
Diviloper Jan 3, 2024
879fa7b
Format
Diviloper Jan 3, 2024
6f904f6
Start adding test for date collections
Diviloper Jan 3, 2024
c4ec31e
Fix some dateset tests
Diviloper Jan 3, 2024
3497927
Remove override of to_spanset in favor of overloads in same class (ma…
Diviloper Jan 12, 2024
1f662ed
Sync pymeos_cffi with latest meos changes
Diviloper Jan 12, 2024
7898bd7
Update aggregators names
Diviloper Jan 12, 2024
0ba8c30
Update span to tbox constructor functions
Diviloper Jan 12, 2024
be52cc6
Update always and ever comparisons to use new API, as well as add tem…
Diviloper Jan 12, 2024
cac3091
Add string conversions to interpolation.
Diviloper Jan 12, 2024
dac9a68
Remove width function from base Span and update numspan width functio…
Diviloper Jan 12, 2024
ee481c7
Update distance functions to use updated API.
Diviloper Jan 12, 2024
ed74c11
Sync with MEOS:
Diviloper Jan 28, 2024
34d98d1
Fix TPoint to MFJSON tests
Diviloper Jan 28, 2024
8fbd147
Update speed and derivative tests that now raise an exception on error
Diviloper Jan 28, 2024
13936e5
Fix issue in tgeompoint speed test
Diviloper Jan 28, 2024
3c35eca
Fix shortest_line method
Diviloper Jan 28, 2024
e8776b8
Update temporal equality to new API
Diviloper Jan 28, 2024
351b94d
Sync last MEOS update
Diviloper Jan 28, 2024
65b8a08
Update pymeos_cffi build dockers
Diviloper Jan 28, 2024
58b905e
Minor update
Diviloper Jan 28, 2024
ba0f309
Update pymeos version and sync with pymeos_cffi
Diviloper Jan 28, 2024
46b3f16
Revert migration to specific temporal comparisons
Diviloper Feb 1, 2024
9703ed3
Sync with meos, use MobilityDB/MobilityDB to build package, and bump …
Diviloper Feb 3, 2024
5d97899
Run examples with new version
Diviloper Feb 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion pymeos/.gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
.idea
.vscode

.micromamba
d

build
dist
docs/_build

*.egg-info
.pytest_cache
*.pyc

sandbox.py

sandbox.py
coverage.xml
2 changes: 1 addition & 1 deletion pymeos/pymeos/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
MeosGeoJsonOutputError,
)

__version__ = "1.1.3b3"
__version__ = "1.1.3rc1"
__all__ = [
# initialization
"pymeos_initialize",
Expand Down
20 changes: 16 additions & 4 deletions pymeos/pymeos/aggregators/general_aggregators.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
from datetime import datetime
from typing import Union

from pymeos_cffi import *
from pymeos_cffi import (
timestamptz_tcount_transfn,
datetime_to_timestamptz,
tstzset_tcount_transfn,
temporal_tcount_transfn,
tstzspan_tcount_transfn,
tstzspanset_tcount_transfn,
temporal_extent_transfn,
timestamptz_extent_transfn,
set_extent_transfn,
span_extent_transfn,
spanset_extent_transfn,
)

from .aggregator import BaseAggregator
from ..boxes import Box
from ..collections import Time, TsTzSet, TsTzSpan, TsTzSpanSet
from ..main import TIntSeq, TIntSeqSet
from ..temporal import Temporal, TInterpolation
from ..collections import Time, TsTzSet, TsTzSpan, TsTzSpanSet


class TemporalInstantCountAggregator(
Expand All @@ -27,7 +39,7 @@ class TemporalInstantCountAggregator(
@classmethod
def _add(cls, state, temporal):
if isinstance(temporal, datetime):
state = timestamp_tcount_transfn(state, datetime_to_timestamptz(temporal))
state = timestamptz_tcount_transfn(state, datetime_to_timestamptz(temporal))
elif isinstance(temporal, TsTzSet):
state = tstzset_tcount_transfn(state, temporal._inner)
elif (
Expand Down Expand Up @@ -85,7 +97,7 @@ def _add(cls, state, temporal):
if isinstance(temporal, Temporal):
state = temporal_extent_transfn(state, temporal._inner)
elif isinstance(temporal, datetime):
state = timestamp_extent_transfn(state, datetime_to_timestamptz(temporal))
state = timestamptz_extent_transfn(state, datetime_to_timestamptz(temporal))
elif isinstance(temporal, TsTzSet):
state = set_extent_transfn(state, temporal._inner)
elif isinstance(temporal, TsTzSpan):
Expand Down
11 changes: 9 additions & 2 deletions pymeos/pymeos/aggregators/time_aggregators.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from datetime import datetime
from typing import Union

from pymeos_cffi import *
from pymeos_cffi import (
timestamptz_union_transfn,
datetime_to_timestamptz,
set_union_transfn,
set_union_finalfn,
union_spanset_span,
union_spanset_spanset,
)

from .aggregator import BaseAggregator
from ..collections import TsTzSet, TsTzSpan, TsTzSpanSet
Expand All @@ -21,7 +28,7 @@ class TimeInstantaneousUnionAggregator(
@classmethod
def _add(cls, state, temporal):
if isinstance(temporal, datetime):
state = timestamp_union_transfn(state, datetime_to_timestamptz(temporal))
state = timestamptz_union_transfn(state, datetime_to_timestamptz(temporal))
elif isinstance(temporal, TsTzSet):
state = set_union_transfn(state, temporal._inner)
else:
Expand Down
2 changes: 1 addition & 1 deletion pymeos/pymeos/boxes/stbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def from_geometry_time(
else:
raise TypeError(
f"Operation not supported with types "
"{geometry.__class__} and {time.__class__}"
f"{geometry.__class__} and {time.__class__}"
)
return STBox(_inner=result)

Expand Down
23 changes: 14 additions & 9 deletions pymeos/pymeos/boxes/tbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

from pymeos_cffi import *

from ..main import TNumber
from ..collections import *
from ..main import TNumber, TInt, TFloat


class TBox:
Expand Down Expand Up @@ -159,9 +159,9 @@ def from_value(value: Union[int, float, IntSpan, FloatSpan]) -> TBox:
elif isinstance(value, float):
result = float_to_tbox(value)
elif isinstance(value, IntSpan):
result = numspan_to_tbox(value._inner)
result = span_to_tbox(value._inner)
elif isinstance(value, FloatSpan):
result = numspan_to_tbox(value._inner)
result = span_to_tbox(value._inner)
else:
raise TypeError(f"Operation not supported with type {value.__class__}")
return TBox(_inner=result)
Expand All @@ -185,11 +185,11 @@ def from_time(time: Time) -> TBox:
if isinstance(time, datetime):
result = timestamptz_to_tbox(datetime_to_timestamptz(time))
elif isinstance(time, TsTzSet):
result = tstzset_to_tbox(time._inner)
result = set_to_tbox(time._inner)
elif isinstance(time, TsTzSpan):
result = tstzspan_to_tbox(time._inner)
result = span_to_tbox(time._inner)
elif isinstance(time, TsTzSpanSet):
result = tstzspanset_to_tbox(time._inner)
result = spanset_to_tbox(time._inner)
else:
raise TypeError(f"Operation not supported with type {time.__class__}")
return TBox(_inner=result)
Expand Down Expand Up @@ -1081,9 +1081,14 @@ def nearest_approach_distance(self, other: Union[TBox, TNumber]) -> float:
nad_tbox_tbox
"""
if isinstance(other, TBox):
return nad_tbox_tbox(self._inner, other._inner)
elif isinstance(other, TNumber):
return nad_tnumber_tbox(other._inner, self._inner)
if self._is_float():
return nad_tboxfloat_tboxfloat(self._inner, other._inner)
else:
return nad_tboxint_tboxint(self._inner, other._inner)
elif isinstance(other, TInt):
return nad_tint_tbox(other._inner, self._inner)
elif isinstance(other, TFloat):
return nad_tfloat_tbox(other._inner, self._inner)
else:
raise TypeError(f"Operation not supported with type {other.__class__}")

Expand Down
7 changes: 6 additions & 1 deletion pymeos/pymeos/collections/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
"Set",
"Span",
"SpanSet",
"TimeDate",
"date",
"DateSet",
"DateSpan",
"DateSpanSet",
"Time",
"datetime",
"TsTzSet",
"TsTzSpan",
"TsTzSpanSet",
"datetime",
"timedelta",
"TextSet",
"GeoSet",
Expand Down
12 changes: 4 additions & 8 deletions pymeos/pymeos/collections/base/collection.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Generic, TypeVar
from typing import Generic, TypeVar, Type

T = TypeVar("T")
Self = TypeVar("Self", bound="Set[Any]")
Self = TypeVar("Self")


class Collection(Generic[T], ABC):
Expand All @@ -29,10 +29,6 @@ def __contains__(self, item):
def overlaps(self, other) -> bool:
raise NotImplementedError()

# @abstractmethod
# def is_same(self, other) -> bool:
# raise NotImplementedError()

# ------------------------- Position Operations ---------------------------
@abstractmethod
def is_left(self, other) -> bool:
Expand All @@ -54,9 +50,9 @@ def is_right(self, other) -> bool:

# ------------------------- Database Operations ---------------------------
@classmethod
def read_from_cursor(cls, value, _=None):
def read_from_cursor(cls: Type[Self], value, _=None):
"""
Reads a :class:`STBox` from a database cursor. Used when automatically
Reads a :class:`Collection` from a database cursor. Used when automatically
loading objects from the database.
Users should use the class constructor instead.
"""
Expand Down
97 changes: 62 additions & 35 deletions pymeos/pymeos/collections/base/set.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Optional, Union, List
from typing import Optional, Union, List, overload
from typing import TypeVar, Type, Callable, Any, TYPE_CHECKING, Iterable

from pymeos_cffi import *
Expand All @@ -12,6 +12,9 @@
from .spanset import SpanSet
from .span import Span

from ..number import IntSet, IntSpan, IntSpanSet, FloatSet, FloatSpan, FloatSpanSet
from ..time import DateSet, DateSpan, DateSpanSet, TsTzSet, TsTzSpan, TsTzSpanSet

T = TypeVar("T")
Self = TypeVar("Self", bound="Set[Any]")

Expand Down Expand Up @@ -75,7 +78,9 @@ def from_wkb(cls: Type[Self], wkb: bytes) -> Self:
MEOS Functions:
set_from_wkb
"""
return cls(_inner=set_from_wkb(wkb))
from ...factory import _CollectionFactory

return _CollectionFactory.create_collection(set_from_wkb(wkb))

@classmethod
def from_hexwkb(cls: Type[Self], hexwkb: str) -> Self:
Expand All @@ -90,11 +95,13 @@ def from_hexwkb(cls: Type[Self], hexwkb: str) -> Self:
MEOS Functions:
set_from_hexwkb
"""
return cls(_inner=(set_from_hexwkb(hexwkb)))
from ...factory import _CollectionFactory

return _CollectionFactory.create_collection((set_from_hexwkb(hexwkb)))

# ------------------------- Output ----------------------------------------
@abstractmethod
def __str__(self):
def __str__(self) -> str:
"""
Return the string representation of the content of ``self``.

Expand All @@ -103,7 +110,7 @@ def __str__(self):
"""
raise NotImplementedError()

def __repr__(self):
def __repr__(self) -> str:
"""
Return the string representation of ``self``.

Expand Down Expand Up @@ -138,20 +145,22 @@ def as_hexwkb(self) -> str:
return set_as_hexwkb(self._inner, -1)[0]

# ------------------------- Conversions -----------------------------------
@abstractmethod
def to_spanset(self) -> SpanSet:
"""
Returns a SpanSet that contains a Span for each element in ``self``.
@overload
def to_span(self: Type[IntSet]) -> IntSpan:
...

Returns:
A new :class:`SpanSet` instance
@overload
def to_span(self: Type[FloatSet]) -> FloatSpan:
...

MEOS Functions:
set_to_spanset
"""
return set_to_spanset(self._inner)
@overload
def to_span(self: Type[TsTzSet]) -> TsTzSpan:
...

@overload
def to_span(self: Type[DateSet]) -> DateSpan:
...

@abstractmethod
def to_span(self) -> Span:
"""
Returns a span that encompasses ``self``.
Expand All @@ -162,7 +171,39 @@ def to_span(self) -> Span:
MEOS Functions:
set_span
"""
return set_span(self._inner)
from ...factory import _CollectionFactory

return _CollectionFactory.create_collection(set_span(self._inner))

@overload
def to_spanset(self: Type[IntSet]) -> IntSpanSet:
...

@overload
def to_spanset(self: Type[FloatSet]) -> FloatSpanSet:
...

@overload
def to_spanset(self: Type[TsTzSet]) -> TsTzSpanSet:
...

@overload
def to_spanset(self: Type[DateSet]) -> DateSpanSet:
...

def to_spanset(self) -> SpanSet:
"""
Returns a SpanSet that contains a Span for each element in ``self``.

Returns:
A new :class:`SpanSet` instance

MEOS Functions:
set_to_spanset
"""
from ...factory import _CollectionFactory

return _CollectionFactory.create_collection(set_to_spanset(self._inner))

# ------------------------- Accessors -------------------------------------

Expand Down Expand Up @@ -250,8 +291,7 @@ def is_contained_in(self, container) -> bool:
True if contained, False otherwise

MEOS Functions:
contained_span_span, contained_span_spanset, contained_set_set,
contained_spanset_spanset
contained_set_set
"""
if isinstance(container, Set):
return contained_set_set(self._inner, container._inner)
Expand Down Expand Up @@ -388,30 +428,17 @@ def is_right(self, other) -> bool:
raise TypeError(f"Operation not supported with type {other.__class__}")

# ------------------------- Distance Operations ---------------------------
def distance(self, other) -> float:
def distance(self, other):
"""
Returns the distance between ``self`` and ``other``.

Args:
other: object to compare with

Returns:
A :class:`float` instance

MEOS Functions:
distance_set_set, distance_span_span, distance_spanset_span
The distance metric in the appropriate format depending on the subclass.
"""
from .span import Span
from .spanset import SpanSet

if isinstance(other, Set):
return distance_set_set(self._inner, other._inner)
elif isinstance(other, Span):
return distance_span_span(set_span(self._inner), other._inner)
elif isinstance(other, SpanSet):
return distance_spanset_span(other._inner, set_span(self._inner))
else:
raise TypeError(f"Operation not supported with type {other.__class__}")
raise TypeError(f"Operation not supported with type {other.__class__}")

# ------------------------- Set Operations --------------------------------
@abstractmethod
Expand Down
Loading
Loading