From 73f5c5c7b9d2a57adfb668b4b8385939e3c82cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Div=C3=AD?= <43449526+Diviloper@users.noreply.github.com> Date: Sun, 7 Apr 2024 23:13:01 +0200 Subject: [PATCH 01/36] Extend testing workflow to test on mac (intel and arm) (#42) * Add testing on MacOS (intel and m1) * Add filters to avoid running tests when only docs are updated * Skip python 3.8 and 3.9 for arm macos due to issue with runners. Update brew reinstall to avoid brew issue in intel macos * Update defined symbol search to take into account that symbols in macOS have and underscore prepended * Set DYLD_LIBRARY_PATH * Add rounding in srid transformation tests to account for floating point precision differences * Move is_ever_disjoint to TGeomPoint for comparisons with base geometries. Remove corresponding tests of TGeogPoint --- .github/workflows/test.yml | 70 +- pymeos/pymeos/main/tpoint.py | 46 +- pymeos/tests/main/tgeogpoint_test.py | 1886 +++++++++-------- pymeos/tests/main/tgeompoint_test.py | 47 + pymeos_cffi/pymeos_cffi/__init__.py | 2 +- .../pymeos_cffi/builder/build_header.py | 10 +- .../pymeos_cffi/builder/build_pymeos.py | 13 + pymeos_cffi/pymeos_cffi/builder/meos.h | 5 +- .../pymeos_cffi/builder/templates/init.py | 2 +- 9 files changed, 1121 insertions(+), 960 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f2ccb34e..65456aec 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,56 +3,102 @@ name: Test PyMEOS on: push: branches: [ "develop", "master" ] + paths-ignore: + - "docs/**" + - ".readthedocs.yml" + - "README.md" pull_request: branches: [ "develop", "master" ] + paths-ignore: + - "docs/**" + - ".readthedocs.yml" + - "README.md" jobs: - build: - - runs-on: ubuntu-22.04 + test: + name: Test PyMEOS - Python ${{ matrix.python-version }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] + os: [ ubuntu-latest, macos-13, macos-14 ] + exclude: + # Necessary due to issue with macOS runners. See + # https://github.com/actions/setup-python/issues/808 + # Can be removed once this PR is merged: + # https://github.com/actions/python-versions/pull/259 + - os: macos-14 + python-version: "3.8" + - os: macos-14 + python-version: "3.9" + include: + - ld_path: "/usr/local/lib" + - os: macos-14 + ld_path: "/opt/homebrew/lib" steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@latest + - name: Get dependencies from apt (cache) + uses: awalsh128/cache-apt-pkgs-action@latest + if: runner.os == 'Linux' with: packages: build-essential cmake postgresql-server-dev-14 libproj-dev libjson-c-dev libgsl-dev libgeos-dev version: 1.0 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - name: Update brew + if: matrix.os == 'macos-13' + # Necessary to avoid issue with macOS runners. See + # https://github.com/actions/runner-images/issues/4020 + run: | + brew reinstall python@3.12 || brew link --overwrite python@3.12 + brew reinstall python@3.11 || brew link --overwrite python@3.11 + brew update + + - name: Get dependencies from homebrew (cache) + uses: tecolicom/actions-use-homebrew-tools@v1 + if: runner.os == 'macOS' with: - python-version: ${{ matrix.python-version }} - cache: "pip" + tools: cmake libpq proj json-c gsl geos - - name: Install MEOS + - name: Fetch MEOS sources env: BRANCH_NAME: ${{ github.base_ref || github.ref_name }} run: | git clone --branch ${{ env.BRANCH_NAME }} --depth 1 https://github.com/MobilityDB/MobilityDB + + - name: Install MEOS + run: | mkdir MobilityDB/build cd MobilityDB/build cmake .. -DMEOS=on make -j sudo make install + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + - name: Install python dependencies run: | python -m pip install --upgrade pip pip install -r pymeos_cffi/dev-requirements.txt pip install -r pymeos/dev-requirements.txt + - name: Install pymeos_cffi run: | cd pymeos_cffi python ./pymeos_cffi/builder/build_header.py python ./pymeos_cffi/builder/build_pymeos_functions.py pip install . - cd .. + - name: Test PyMEOS with pytest run: | - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_path }} + export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} cd pymeos pytest diff --git a/pymeos/pymeos/main/tpoint.py b/pymeos/pymeos/main/tpoint.py index 031a2a20..48291bd3 100644 --- a/pymeos/pymeos/main/tpoint.py +++ b/pymeos/pymeos/main/tpoint.py @@ -51,7 +51,7 @@ class TPoint(Temporal[shp.Point, TG, TI, TS, TSS], TSimplifiable, ABC): Abstract class for temporal points. """ - _projection_cache: dict[tuple[int, int], 'LWPROJ'] = {} + _projection_cache: dict[tuple[int, int], "LWPROJ"] = {} # ------------------------- Constructors ---------------------------------- def __init__(self, _inner) -> None: @@ -502,9 +502,10 @@ def transform(self: Self, srid: int) -> Self: MEOS Functions: tpoint_transform """ - if (self.srid(), srid) not in self._projection_cache: - self._projection_cache[(self.srid(), srid)] = lwproj_transform(self.srid(), srid) - result = tpoint_transform_pj(self._inner, srid, self._projection_cache[(self.srid(), srid)]) + srids = (self.srid(), srid) + if srids not in self._projection_cache: + self._projection_cache[srids] = lwproj_transform(*srids) + result = tpoint_transform_pj(self._inner, srid, self._projection_cache[srids]) return Temporal._factory(result) # ------------------------- Restrictions ---------------------------------- @@ -774,7 +775,7 @@ def is_ever_contained_in(self, container: Union[shpb.BaseGeometry, STBox]) -> bo raise TypeError(f"Operation not supported with type {container.__class__}") return result == 1 - def is_ever_disjoint(self, other: Union[shpb.BaseGeometry, TPoint, STBox]) -> bool: + def is_ever_disjoint(self, other: TPoint) -> bool: """ Returns whether the temporal point is ever disjoint from `other`. @@ -789,12 +790,7 @@ def is_ever_disjoint(self, other: Union[shpb.BaseGeometry, TPoint, STBox]) -> bo """ from ..boxes import STBox - if isinstance(other, shpb.BaseGeometry): - gs = geo_to_gserialized(other, isinstance(self, TGeogPoint)) - result = edisjoint_tpoint_geo(self._inner, gs) - elif isinstance(other, STBox): - result = edisjoint_tpoint_geo(self._inner, stbox_to_geo(other._inner)) - elif isinstance(other, TPoint): + if isinstance(other, TPoint): result = edisjoint_tpoint_tpoint(self._inner, other._inner) else: raise TypeError(f"Operation not supported with type {other.__class__}") @@ -1651,6 +1647,34 @@ def never_not_equal(self, value: Union[shpb.BaseGeometry, TGeomPoint]) -> bool: """ return not self.ever_not_equal(value) + def is_ever_disjoint( + self, other: Union[shpb.BaseGeometry, TGeomPoint, STBox] + ) -> bool: + """ + Returns whether the temporal point is ever disjoint from `other`. + + Args: + other: An object to check for disjointness with. + + Returns: + A :class:`bool` indicating whether the temporal point is ever disjoint from `other`. + + MEOS Functions: + edisjoint_tpoint_geo, edisjoint_tpoint_tpoint + """ + from ..boxes import STBox + + if isinstance(other, shpb.BaseGeometry): + gs = geo_to_gserialized(other, isinstance(self, TGeogPoint)) + result = edisjoint_tpoint_geo(self._inner, gs) + elif isinstance(other, STBox): + result = edisjoint_tpoint_geo(self._inner, stbox_to_geo(other._inner)) + elif isinstance(other, TGeomPoint): + result = edisjoint_tpoint_tpoint(self._inner, other._inner) + else: + raise TypeError(f"Operation not supported with type {other.__class__}") + return result == 1 + # ------------------------- Temporal Comparisons -------------------------- def temporal_equal(self, other: Union[shp.Point, TGeomPoint]) -> TBool: """ diff --git a/pymeos/tests/main/tgeogpoint_test.py b/pymeos/tests/main/tgeogpoint_test.py index e39fe515..1818c74e 100644 --- a/pymeos/tests/main/tgeogpoint_test.py +++ b/pymeos/tests/main/tgeogpoint_test.py @@ -54,29 +54,27 @@ class TestTGeogPointConstructors(TestTGeogPoint): "source, type, interpolation", [ ( - TGeogPointInst("Point(1.5 1.5)@2019-09-01"), - TGeogPointInst, - TInterpolation.NONE, + TGeogPointInst("Point(1.5 1.5)@2019-09-01"), + TGeogPointInst, + TInterpolation.NONE, ), ( - TGeogPointSeq( - "{Point(1.5 1.5)@2019-09-01, Point(2.5 2.5)@2019-09-02}"), - TGeogPointSeq, - TInterpolation.DISCRETE, + TGeogPointSeq("{Point(1.5 1.5)@2019-09-01, Point(2.5 2.5)@2019-09-02}"), + TGeogPointSeq, + TInterpolation.DISCRETE, ), ( - TGeogPointSeq( - "[Point(1.5 1.5)@2019-09-01, Point(2.5 2.5)@2019-09-02]"), - TGeogPointSeq, - TInterpolation.LINEAR, + TGeogPointSeq("[Point(1.5 1.5)@2019-09-01, Point(2.5 2.5)@2019-09-02]"), + TGeogPointSeq, + TInterpolation.LINEAR, ), ( - TGeogPointSeqSet( - "{[Point(1.5 1.5)@2019-09-01, Point(2.5 2.5)@2019-09-02]," - "[Point(1.5 1.5)@2019-09-03, Point(1.5 1.5)@2019-09-05]}" - ), - TGeogPointSeqSet, - TInterpolation.LINEAR, + TGeogPointSeqSet( + "{[Point(1.5 1.5)@2019-09-01, Point(2.5 2.5)@2019-09-02]," + "[Point(1.5 1.5)@2019-09-03, Point(1.5 1.5)@2019-09-05]}" + ), + TGeogPointSeqSet, + TInterpolation.LINEAR, ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -93,19 +91,19 @@ def test_from_base_constructor(self, source, type, interpolation): [ (datetime(2000, 1, 1), TGeogPointInst, TInterpolation.NONE), ( - TsTzSet("{2019-09-01, 2019-09-02}"), - TGeogPointSeq, - TInterpolation.DISCRETE, + TsTzSet("{2019-09-01, 2019-09-02}"), + TGeogPointSeq, + TInterpolation.DISCRETE, ), ( - TsTzSpan("[2019-09-01, 2019-09-02]"), - TGeogPointSeq, - TInterpolation.LINEAR, + TsTzSpan("[2019-09-01, 2019-09-02]"), + TGeogPointSeq, + TInterpolation.LINEAR, ), ( - TsTzSpanSet("{[2019-09-01, 2019-09-02],[2019-09-03, 2019-09-05]}"), - TGeogPointSeqSet, - TInterpolation.LINEAR, + TsTzSpanSet("{[2019-09-01, 2019-09-02],[2019-09-03, 2019-09-05]}"), + TGeogPointSeqSet, + TInterpolation.LINEAR, ), ], ids=["Instant", "Sequence", "Discrete Sequence", "SequenceSet"], @@ -121,29 +119,29 @@ def test_from_base_time_constructor(self, source, type, interpolation): "source, type, interpolation, expected", [ ( - "Point(1 1)@2019-09-01", - TGeogPointInst, - TInterpolation.NONE, - "POINT(1 1)@2019-09-01 00:00:00+00", + "Point(1 1)@2019-09-01", + TGeogPointInst, + TInterpolation.NONE, + "POINT(1 1)@2019-09-01 00:00:00+00", ), ( - "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}", - TGeogPointSeq, - TInterpolation.DISCRETE, - "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00}", + "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}", + TGeogPointSeq, + TInterpolation.DISCRETE, + "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00}", ), ( - "[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]", - TGeogPointSeq, - TInterpolation.LINEAR, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00]", + "[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]", + TGeogPointSeq, + TInterpolation.LINEAR, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00]", ), ( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}", - TGeogPointSeqSet, - TInterpolation.LINEAR, - "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " - "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]}", + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}", + TGeogPointSeqSet, + TInterpolation.LINEAR, + "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " + "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]}", ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -158,16 +156,16 @@ def test_string_constructor(self, source, type, interpolation, expected): "source, type, expected", [ ( - "[Point(1 1)@2019-09-01, Point(1.249919068145015 1.250040436011492)@2019-09-02, Point(2 2)@2019-09-05]", - TGeogPointSeq, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-05 00:00:00+00]", + "[Point(1 1)@2019-09-01, Point(1.249919068145015 1.250040436011492)@2019-09-02, Point(2 2)@2019-09-05]", + TGeogPointSeq, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-05 00:00:00+00]", ), ( - "{[Point(1 1)@2019-09-01, POINT(1.249919068145015 1.250040436011492)@2019-09-02, Point(2 2)@2019-09-05]," - "[Point(1 1)@2019-09-07, Point(1 1)@2019-09-08, Point(1 1)@2019-09-09]}", - TGeogPointSeqSet, - "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-05 00:00:00+00], " - "[POINT(1 1)@2019-09-07 00:00:00+00, POINT(1 1)@2019-09-09 00:00:00+00]}", + "{[Point(1 1)@2019-09-01, POINT(1.249919068145015 1.250040436011492)@2019-09-02, Point(2 2)@2019-09-05]," + "[Point(1 1)@2019-09-07, Point(1 1)@2019-09-08, Point(1 1)@2019-09-09]}", + TGeogPointSeqSet, + "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-05 00:00:00+00], " + "[POINT(1 1)@2019-09-07 00:00:00+00, POINT(1 1)@2019-09-09 00:00:00+00]}", ), ], ids=["Sequence", "SequenceSet"], @@ -195,78 +193,78 @@ def test_value_timestamp_instant_constructor(self, value, timestamp): "list, interpolation, normalize, expected", [ ( - ["Point(1 1)@2019-09-01", "Point(2 2)@2019-09-03"], - TInterpolation.DISCRETE, - False, - "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00}", + ["Point(1 1)@2019-09-01", "Point(2 2)@2019-09-03"], + TInterpolation.DISCRETE, + False, + "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00}", ), ( - ["Point(1 1)@2019-09-01", "Point(2 2)@2019-09-03"], - TInterpolation.LINEAR, - False, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", + ["Point(1 1)@2019-09-01", "Point(2 2)@2019-09-03"], + TInterpolation.LINEAR, + False, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", ), ( - [ - TGeogPointInst("Point(1 1)@2019-09-01"), - TGeogPointInst("Point(2 2)@2019-09-03"), - ], - TInterpolation.DISCRETE, - False, - "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00}", + [ + TGeogPointInst("Point(1 1)@2019-09-01"), + TGeogPointInst("Point(2 2)@2019-09-03"), + ], + TInterpolation.DISCRETE, + False, + "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00}", ), ( - [ - TGeogPointInst("Point(1 1)@2019-09-01"), - TGeogPointInst("Point(2 2)@2019-09-03"), - ], - TInterpolation.LINEAR, - False, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", + [ + TGeogPointInst("Point(1 1)@2019-09-01"), + TGeogPointInst("Point(2 2)@2019-09-03"), + ], + TInterpolation.LINEAR, + False, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", ), ( - ["Point(1 1)@2019-09-01", TGeogPointInst("Point(2 2)@2019-09-03")], - TInterpolation.DISCRETE, - False, - "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00}", + ["Point(1 1)@2019-09-01", TGeogPointInst("Point(2 2)@2019-09-03")], + TInterpolation.DISCRETE, + False, + "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00}", ), ( - ["Point(1 1)@2019-09-01", TGeogPointInst("Point(2 2)@2019-09-03")], - TInterpolation.LINEAR, - False, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", + ["Point(1 1)@2019-09-01", TGeogPointInst("Point(2 2)@2019-09-03")], + TInterpolation.LINEAR, + False, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", ), ( - [ - "Point(1 1)@2019-09-01", - "Point(1.499885736561676 1.500057091479197)@2019-09-02", - "Point(2 2)@2019-09-03", - ], - TInterpolation.LINEAR, - True, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", + [ + "Point(1 1)@2019-09-01", + "Point(1.499885736561676 1.500057091479197)@2019-09-02", + "Point(2 2)@2019-09-03", + ], + TInterpolation.LINEAR, + True, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", ), ( - [ - TGeogPointInst("Point(1 1)@2019-09-01"), - TGeogPointInst( - "Point(1.499885736561676 1.500057091479197)@2019-09-02" - ), - TGeogPointInst("Point(2 2)@2019-09-03"), - ], - TInterpolation.LINEAR, - True, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", + [ + TGeogPointInst("Point(1 1)@2019-09-01"), + TGeogPointInst( + "Point(1.499885736561676 1.500057091479197)@2019-09-02" + ), + TGeogPointInst("Point(2 2)@2019-09-03"), + ], + TInterpolation.LINEAR, + True, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", ), ( - [ - "Point(1 1)@2019-09-01", - "Point(1.499885736561676 1.500057091479197)@2019-09-02", - TGeogPointInst("Point(2 2)@2019-09-03"), - ], - TInterpolation.LINEAR, - True, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", + [ + "Point(1 1)@2019-09-01", + "Point(1.499885736561676 1.500057091479197)@2019-09-02", + TGeogPointInst("Point(2 2)@2019-09-03"), + ], + TInterpolation.LINEAR, + True, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-03 00:00:00+00]", ), ], ids=[ @@ -282,7 +280,7 @@ def test_value_timestamp_instant_constructor(self, value, timestamp): ], ) def test_instant_list_sequence_constructor( - self, list, interpolation, normalize, expected + self, list, interpolation, normalize, expected ): tps = TGeogPointSeq( instant_list=list, @@ -352,17 +350,17 @@ class TestTGeogPointOutputs(TestTGeogPoint): [ (tpi, "POINT(1 1)@2019-09-01 00:00:00+00"), ( - tpds, - "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00}", + tpds, + "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00}", ), ( - tps, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00]", + tps, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00]", ), ( - tpss, - "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " - "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]}", + tpss, + "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " + "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]}", ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -375,17 +373,17 @@ def test_str(self, temporal, expected): [ (tpi, "TGeogPointInst(POINT(1 1)@2019-09-01 00:00:00+00)"), ( - tpds, - "TGeogPointSeq({POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00})", + tpds, + "TGeogPointSeq({POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00})", ), ( - tps, - "TGeogPointSeq([POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00])", + tps, + "TGeogPointSeq([POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00])", ), ( - tpss, - "TGeogPointSeqSet({[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " - "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]})", + tpss, + "TGeogPointSeqSet({[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " + "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]})", ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -398,17 +396,17 @@ def test_repr(self, temporal, expected): [ (tpi, "POINT(1 1)@2019-09-01 00:00:00+00"), ( - tpds, - "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00}", + tpds, + "{POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00}", ), ( - tps, - "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00]", + tps, + "[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00]", ), ( - tpss, - "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " - "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]}", + tpss, + "{[POINT(1 1)@2019-09-01 00:00:00+00, POINT(2 2)@2019-09-02 00:00:00+00], " + "[POINT(1 1)@2019-09-03 00:00:00+00, POINT(1 1)@2019-09-05 00:00:00+00]}", ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -421,20 +419,20 @@ def test_as_wkt(self, temporal, expected): [ (tpi, "01290061E6100000000000000000F03F000000000000F03F00A01E4E71340200"), ( - tpds, - "01290066E61000000200000003000000000000F03F000000000000F03F00A01E4E71340200" - "000000000000004000000000000000400000F66B85340200", + tpds, + "01290066E61000000200000003000000000000F03F000000000000F03F00A01E4E71340200" + "000000000000004000000000000000400000F66B85340200", ), ( - tps, - "0129006EE61000000200000003000000000000F03F000000000000F03F00A01E4E71340200" - "000000000000004000000000000000400000F66B85340200", + tps, + "0129006EE61000000200000003000000000000F03F000000000000F03F00A01E4E71340200" + "000000000000004000000000000000400000F66B85340200", ), ( - tpss, - "0129006FE6100000020000000200000003000000000000F03F000000000000F03F00A01E4E71340200" - "000000000000004000000000000000400000F66B853402000200000003000000000000F03F000000000" - "000F03F0060CD8999340200000000000000F03F000000000000F03F00207CC5C1340200", + tpss, + "0129006FE6100000020000000200000003000000000000F03F000000000000F03F00A01E4E71340200" + "000000000000004000000000000000400000F66B853402000200000003000000000000F03F000000000" + "000F03F0060CD8999340200000000000000F03F000000000000F03F00207CC5C1340200", ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -446,175 +444,175 @@ def test_as_hexwkb(self, temporal, expected): "temporal, expected", [ ( - tpi, - "{\n" - ' "type": "MovingPoint",\n' - ' "bbox": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 1,\n" - " 1\n" - " ]\n" - " ],\n" - ' "period": {\n' - ' "begin": "2019-09-01T00:00:00+00",\n' - ' "end": "2019-09-01T00:00:00+00",\n' - ' "lower_inc": true,\n' - ' "upper_inc": true\n' - " },\n" - ' "coordinates": [\n' - " [\n" - " 1,\n" - " 1\n" - " ]\n" - " ],\n" - ' "datetimes": [\n' - ' "2019-09-01T00:00:00+00"\n' - " ],\n" - ' "interpolation": "None"\n' - "}", - ), - ( - tpds, - "{\n" - ' "type": "MovingPoint",\n' - ' "bbox": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 2,\n" - " 2\n" - " ]\n" - " ],\n" - ' "period": {\n' - ' "begin": "2019-09-01T00:00:00+00",\n' - ' "end": "2019-09-02T00:00:00+00",\n' - ' "lower_inc": true,\n' - ' "upper_inc": true\n' - " },\n" - ' "coordinates": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 2,\n" - " 2\n" - " ]\n" - " ],\n" - ' "datetimes": [\n' - ' "2019-09-01T00:00:00+00",\n' - ' "2019-09-02T00:00:00+00"\n' - " ],\n" - ' "lower_inc": true,\n' - ' "upper_inc": true,\n' - ' "interpolation": "Discrete"\n' - "}", - ), - ( - tps, - "{\n" - ' "type": "MovingPoint",\n' - ' "bbox": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 2,\n" - " 2\n" - " ]\n" - " ],\n" - ' "period": {\n' - ' "begin": "2019-09-01T00:00:00+00",\n' - ' "end": "2019-09-02T00:00:00+00",\n' - ' "lower_inc": true,\n' - ' "upper_inc": true\n' - " },\n" - ' "coordinates": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 2,\n" - " 2\n" - " ]\n" - " ],\n" - ' "datetimes": [\n' - ' "2019-09-01T00:00:00+00",\n' - ' "2019-09-02T00:00:00+00"\n' - " ],\n" - ' "lower_inc": true,\n' - ' "upper_inc": true,\n' - ' "interpolation": "Linear"\n' - "}", - ), - ( - tpss, - "{\n" - ' "type": "MovingPoint",\n' - ' "bbox": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 2,\n" - " 2\n" - " ]\n" - " ],\n" - ' "period": {\n' - ' "begin": "2019-09-01T00:00:00+00",\n' - ' "end": "2019-09-05T00:00:00+00",\n' - ' "lower_inc": true,\n' - ' "upper_inc": true\n' - " },\n" - ' "sequences": [\n' - " {\n" - ' "coordinates": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 2,\n" - " 2\n" - " ]\n" - " ],\n" - ' "datetimes": [\n' - ' "2019-09-01T00:00:00+00",\n' - ' "2019-09-02T00:00:00+00"\n' - " ],\n" - ' "lower_inc": true,\n' - ' "upper_inc": true\n' - " },\n" - " {\n" - ' "coordinates": [\n' - " [\n" - " 1,\n" - " 1\n" - " ],\n" - " [\n" - " 1,\n" - " 1\n" - " ]\n" - " ],\n" - ' "datetimes": [\n' - ' "2019-09-03T00:00:00+00",\n' - ' "2019-09-05T00:00:00+00"\n' - " ],\n" - ' "lower_inc": true,\n' - ' "upper_inc": true\n' - " }\n" - " ],\n" - ' "interpolation": "Linear"\n' - "}", + tpi, + "{\n" + ' "type": "MovingPoint",\n' + ' "bbox": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 1,\n" + " 1\n" + " ]\n" + " ],\n" + ' "period": {\n' + ' "begin": "2019-09-01T00:00:00+00",\n' + ' "end": "2019-09-01T00:00:00+00",\n' + ' "lower_inc": true,\n' + ' "upper_inc": true\n' + " },\n" + ' "coordinates": [\n' + " [\n" + " 1,\n" + " 1\n" + " ]\n" + " ],\n" + ' "datetimes": [\n' + ' "2019-09-01T00:00:00+00"\n' + " ],\n" + ' "interpolation": "None"\n' + "}", + ), + ( + tpds, + "{\n" + ' "type": "MovingPoint",\n' + ' "bbox": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 2,\n" + " 2\n" + " ]\n" + " ],\n" + ' "period": {\n' + ' "begin": "2019-09-01T00:00:00+00",\n' + ' "end": "2019-09-02T00:00:00+00",\n' + ' "lower_inc": true,\n' + ' "upper_inc": true\n' + " },\n" + ' "coordinates": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 2,\n" + " 2\n" + " ]\n" + " ],\n" + ' "datetimes": [\n' + ' "2019-09-01T00:00:00+00",\n' + ' "2019-09-02T00:00:00+00"\n' + " ],\n" + ' "lower_inc": true,\n' + ' "upper_inc": true,\n' + ' "interpolation": "Discrete"\n' + "}", + ), + ( + tps, + "{\n" + ' "type": "MovingPoint",\n' + ' "bbox": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 2,\n" + " 2\n" + " ]\n" + " ],\n" + ' "period": {\n' + ' "begin": "2019-09-01T00:00:00+00",\n' + ' "end": "2019-09-02T00:00:00+00",\n' + ' "lower_inc": true,\n' + ' "upper_inc": true\n' + " },\n" + ' "coordinates": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 2,\n" + " 2\n" + " ]\n" + " ],\n" + ' "datetimes": [\n' + ' "2019-09-01T00:00:00+00",\n' + ' "2019-09-02T00:00:00+00"\n' + " ],\n" + ' "lower_inc": true,\n' + ' "upper_inc": true,\n' + ' "interpolation": "Linear"\n' + "}", + ), + ( + tpss, + "{\n" + ' "type": "MovingPoint",\n' + ' "bbox": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 2,\n" + " 2\n" + " ]\n" + " ],\n" + ' "period": {\n' + ' "begin": "2019-09-01T00:00:00+00",\n' + ' "end": "2019-09-05T00:00:00+00",\n' + ' "lower_inc": true,\n' + ' "upper_inc": true\n' + " },\n" + ' "sequences": [\n' + " {\n" + ' "coordinates": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 2,\n" + " 2\n" + " ]\n" + " ],\n" + ' "datetimes": [\n' + ' "2019-09-01T00:00:00+00",\n' + ' "2019-09-02T00:00:00+00"\n' + " ],\n" + ' "lower_inc": true,\n' + ' "upper_inc": true\n' + " },\n" + " {\n" + ' "coordinates": [\n' + " [\n" + " 1,\n" + " 1\n" + " ],\n" + " [\n" + " 1,\n" + " 1\n" + " ]\n" + " ],\n" + ' "datetimes": [\n' + ' "2019-09-03T00:00:00+00",\n' + ' "2019-09-05T00:00:00+00"\n' + " ],\n" + ' "lower_inc": true,\n' + ' "upper_inc": true\n' + " }\n" + " ],\n" + ' "interpolation": "Linear"\n' + "}", ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -872,13 +870,13 @@ def test_instant_n(self, temporal, n, expected): (tpds, [tpi, TGeogPointInst("Point(2 2)@2019-09-02")]), (tps, [tpi, TGeogPointInst("Point(2 2)@2019-09-02")]), ( - tpss, - [ - tpi, - TGeogPointInst("Point(2 2)@2019-09-02"), - TGeogPointInst("Point(1 1)@2019-09-03"), - TGeogPointInst("Point(1 1)@2019-09-05"), - ], + tpss, + [ + tpi, + TGeogPointInst("Point(2 2)@2019-09-02"), + TGeogPointInst("Point(1 1)@2019-09-03"), + TGeogPointInst("Point(1 1)@2019-09-05"), + ], ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -943,27 +941,27 @@ def test_timestamp_n(self, temporal, n, expected): [ (tpi, [datetime(year=2019, month=9, day=1, tzinfo=timezone.utc)]), ( - tpds, - [ - datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), - datetime(year=2019, month=9, day=2, tzinfo=timezone.utc), - ], + tpds, + [ + datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), + datetime(year=2019, month=9, day=2, tzinfo=timezone.utc), + ], ), ( - tps, - [ - datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), - datetime(year=2019, month=9, day=2, tzinfo=timezone.utc), - ], + tps, + [ + datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), + datetime(year=2019, month=9, day=2, tzinfo=timezone.utc), + ], ), ( - tpss, - [ - datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), - datetime(year=2019, month=9, day=2, tzinfo=timezone.utc), - datetime(year=2019, month=9, day=3, tzinfo=timezone.utc), - datetime(year=2019, month=9, day=5, tzinfo=timezone.utc), - ], + tpss, + [ + datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), + datetime(year=2019, month=9, day=2, tzinfo=timezone.utc), + datetime(year=2019, month=9, day=3, tzinfo=timezone.utc), + datetime(year=2019, month=9, day=5, tzinfo=timezone.utc), + ], ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -975,19 +973,19 @@ def test_timestamps(self, temporal, expected): "temporal, expected", [ ( - tpds, - [ - TGeogPointSeq("[Point(1 1)@2019-09-01]"), - TGeogPointSeq("[Point(2 2)@2019-09-02]"), - ], + tpds, + [ + TGeogPointSeq("[Point(1 1)@2019-09-01]"), + TGeogPointSeq("[Point(2 2)@2019-09-02]"), + ], ), (tps, [TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]")]), ( - tpss, - [ - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), - TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), - ], + tpss, + [ + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), + TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), + ], ), ], ids=["Discrete Sequence", "Sequence", "SequenceSet"], @@ -1076,11 +1074,11 @@ def test_length(self, temporal, expected): (tpds, TFloatSeq("{0@2019-09-01, 0@2019-09-02}")), (tps, TFloatSeq("[0@2019-09-01, 156876.1494@2019-09-02]")), ( - tpss, - TFloatSeqSet( - "{[0@2019-09-01, 156876.1494@2019-09-02]," - "[156876.1494@2019-09-03, 156876.1494@2019-09-05]}" - ), + tpss, + TFloatSeqSet( + "{[0@2019-09-01, 156876.1494@2019-09-02]," + "[156876.1494@2019-09-03, 156876.1494@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1093,11 +1091,11 @@ def test_cumulative_length(self, temporal, expected): [ (tps, TFloatSeq("Interp=Step;[1.8157@2019-09-01, 1.8157@2019-09-02]")), ( - tpss, - TFloatSeqSet( - "Interp=Step;{[1.8157@2019-09-01, 1.8157@2019-09-02]," - "[0@2019-09-03, 0@2019-09-05]}" - ), + tpss, + TFloatSeqSet( + "Interp=Step;{[1.8157@2019-09-01, 1.8157@2019-09-02]," + "[0@2019-09-03, 0@2019-09-05]}" + ), ), ], ids=["Sequence", "SequenceSet"], @@ -1124,10 +1122,10 @@ def test_speed_without_linear_interpolation_throws(self, temporal): (tpds, TFloatSeq("{1@2019-09-01, 2@2019-09-02}")), (tps, TFloatSeq("[1@2019-09-01, 2@2019-09-02]")), ( - tpss, - TFloatSeqSet( - "{[1@2019-09-01, 2@2019-09-02]," "[1@2019-09-03, 1@2019-09-05]}" - ), + tpss, + TFloatSeqSet( + "{[1@2019-09-01, 2@2019-09-02]," "[1@2019-09-03, 1@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1143,10 +1141,10 @@ def test_x_y(self, temporal, expected): (tpds3d, TFloatSeq("{1@2019-09-01, 2@2019-09-02}")), (tps3d, TFloatSeq("[1@2019-09-01, 2@2019-09-02]")), ( - tpss3d, - TFloatSeqSet( - "{[1@2019-09-01, 2@2019-09-02]," "[1@2019-09-03, 1@2019-09-05]}" - ), + tpss3d, + TFloatSeqSet( + "{[1@2019-09-01, 2@2019-09-02]," "[1@2019-09-03, 1@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1202,11 +1200,11 @@ def test_has_z(self, temporal, expected): (tpds, []), (tps, [STBox("GEODSTBOX XT(((1,1),(2,2)),[2019-09-01, 2019-09-02])")]), ( - tpss, - [ - STBox("GEODSTBOX XT(((1,1),(2,2)),[2019-09-01, 2019-09-02])"), - STBox("GEODSTBOX XT(((1,1),(1,1)),[2019-09-03, 2019-09-05])"), - ], + tpss, + [ + STBox("GEODSTBOX XT(((1,1),(2,2)),[2019-09-01, 2019-09-02])"), + STBox("GEODSTBOX XT(((1,1),(1,1)),[2019-09-03, 2019-09-05])"), + ], ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1234,19 +1232,19 @@ def test_is_simple(self, temporal, expected): (tpds, TFloatSeq("{0.7846@2019-09-01,0.7846@2019-09-02}")), (tps, TFloatSeq("[0.7846@2019-09-01,0.7846@2019-09-02]")), ( - tpss, - TFloatSeqSet( - "{[0.7846@2019-09-01,0.7846@2019-09-02]," - "[0.7846@2019-09-03,0.7846@2019-09-05]}" - ), + tpss, + TFloatSeqSet( + "{[0.7846@2019-09-01,0.7846@2019-09-02]," + "[0.7846@2019-09-03,0.7846@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], ) def test_bearing(self, temporal, expected): assert ( - temporal.bearing(shapely.set_srid(shapely.Point(3, 3), 4326)).round(4) - == expected + temporal.bearing(shapely.set_srid(shapely.Point(3, 3), 4326)).round(4) + == expected ) @pytest.mark.parametrize( @@ -1315,16 +1313,24 @@ class TestTGeogPointConversions(TestTGeogPoint): "temporal, expected", [ (tpi, TGeomPointInst("SRID=4326;Point(1 1)@2019-09-01")), - (tpds, - TGeomPointSeq("SRID=4326;{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}")), - (tps, - TGeomPointSeq("SRID=4326;[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]")), - ( - tpss, - TGeomPointSeqSet( - "SRID=4326;{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]," - "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + ( + tpds, + TGeomPointSeq( + "SRID=4326;{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}" + ), + ), + ( + tps, + TGeomPointSeq( + "SRID=4326;[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]" + ), + ), + ( + tpss, + TGeomPointSeqSet( + "SRID=4326;{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]," + "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1373,25 +1379,24 @@ def test_to_instant(self, temporal, expected): "temporal, interpolation, expected", [ ( - TGeogPointInst("Point(1 1)@2019-09-01"), - TInterpolation.LINEAR, - TGeogPointSeq("[Point(1 1)@2019-09-01]"), + TGeogPointInst("Point(1 1)@2019-09-01"), + TInterpolation.LINEAR, + TGeogPointSeq("[Point(1 1)@2019-09-01]"), ), ( - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), - TInterpolation.DISCRETE, - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), + TInterpolation.DISCRETE, + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), ), ( - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), - TInterpolation.LINEAR, - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), + TInterpolation.LINEAR, + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), ), ( - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), - TInterpolation.LINEAR, - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), + TGeogPointSeqSet("{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + TInterpolation.LINEAR, + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1405,28 +1410,24 @@ def test_to_sequence(self, temporal, interpolation, expected): "temporal, interpolation, expected", [ ( - TGeogPointInst("Point(1 1)@2019-09-01"), - TInterpolation.LINEAR, - TGeogPointSeqSet("{[Point(1 1)@2019-09-01]}"), + TGeogPointInst("Point(1 1)@2019-09-01"), + TInterpolation.LINEAR, + TGeogPointSeqSet("{[Point(1 1)@2019-09-01]}"), ), ( - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), - TInterpolation.LINEAR, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01], [Point(2 2)@2019-09-02]}"), + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), + TInterpolation.LINEAR, + TGeogPointSeqSet("{[Point(1 1)@2019-09-01], [Point(2 2)@2019-09-02]}"), ), ( - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), - TInterpolation.LINEAR, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), + TInterpolation.LINEAR, + TGeogPointSeqSet("{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), ( - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), - TInterpolation.LINEAR, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + TGeogPointSeqSet("{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + TInterpolation.LINEAR, + TGeogPointSeqSet("{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1443,58 +1444,57 @@ def test_to_sequenceset(self, temporal, interpolation, expected): (tpds, TInterpolation.DISCRETE, tpds), (tps_d, TInterpolation.DISCRETE, TGeogPointSeq("{Point(1 1)@2019-09-01}")), ( - tpss_d, - TInterpolation.DISCRETE, - TGeogPointSeq("{Point(1 1)@2019-09-01,Point(2 2)@2019-09-03}"), + tpss_d, + TInterpolation.DISCRETE, + TGeogPointSeq("{Point(1 1)@2019-09-01,Point(2 2)@2019-09-03}"), ), ( - tpi, - TInterpolation.STEPWISE, - TGeogPointSeq("Interp=Step;[Point(1 1)@2019-09-01]"), + tpi, + TInterpolation.STEPWISE, + TGeogPointSeq("Interp=Step;[Point(1 1)@2019-09-01]"), ), ( - tpds, - TInterpolation.STEPWISE, - TGeogPointSeqSet( - "Interp=Step;{[Point(1 1)@2019-09-01], [Point(2 2)@2019-09-02]}" - ), + tpds, + TInterpolation.STEPWISE, + TGeogPointSeqSet( + "Interp=Step;{[Point(1 1)@2019-09-01], [Point(2 2)@2019-09-02]}" + ), ), ( - tps_s, - TInterpolation.STEPWISE, - TGeogPointSeq( - "Interp=Step;[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]" - ), + tps_s, + TInterpolation.STEPWISE, + TGeogPointSeq( + "Interp=Step;[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]" + ), ), ( - tpss_s, - TInterpolation.STEPWISE, - TGeogPointSeqSet( - "Interp=Step;{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," - "[Point(2 2)@2019-09-03, Point(2 2)@2019-09-05]}" - ), + tpss_s, + TInterpolation.STEPWISE, + TGeogPointSeqSet( + "Interp=Step;{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," + "[Point(2 2)@2019-09-03, Point(2 2)@2019-09-05]}" + ), ), (tpi, TInterpolation.LINEAR, TGeogPointSeq("[Point(1 1)@2019-09-01]")), ( - tpds, - TInterpolation.LINEAR, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01], [Point(2 2)@2019-09-02]}"), + tpds, + TInterpolation.LINEAR, + TGeogPointSeqSet("{[Point(1 1)@2019-09-01], [Point(2 2)@2019-09-02]}"), ), ( - tps_l, - TInterpolation.LINEAR, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02), [Point(2 2)@2019-09-02]}" - ), + tps_l, + TInterpolation.LINEAR, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02), [Point(2 2)@2019-09-02]}" + ), ), ( - tpss_l, - TInterpolation.LINEAR, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02)," - "[Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss_l, + TInterpolation.LINEAR, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02)," + "[Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ], ids=[ @@ -1522,87 +1522,87 @@ def test_set_interpolation(self, temporal, interpolation, expected): (tpi, timedelta(days=-4), TGeogPointInst("Point(1 1)@2019-08-28")), (tpi, timedelta(hours=2), TGeogPointInst("Point(1 1)@2019-09-01 02:00:00")), ( - tpi, - timedelta(hours=-2), - TGeogPointInst("Point(1 1)@2019-08-31 22:00:00"), + tpi, + timedelta(hours=-2), + TGeogPointInst("Point(1 1)@2019-08-31 22:00:00"), ), ( - tpds, - timedelta(days=4), - TGeogPointSeq("{Point(1 1)@2019-09-05, Point(2 2)@2019-09-06}"), + tpds, + timedelta(days=4), + TGeogPointSeq("{Point(1 1)@2019-09-05, Point(2 2)@2019-09-06}"), ), ( - tpds, - timedelta(days=-4), - TGeogPointSeq("{Point(1 1)@2019-08-28, Point(2 2)@2019-08-29}"), + tpds, + timedelta(days=-4), + TGeogPointSeq("{Point(1 1)@2019-08-28, Point(2 2)@2019-08-29}"), ), ( - tpds, - timedelta(hours=2), - TGeogPointSeq( - "{Point(1 1)@2019-09-01 02:00:00, Point(2 2)@2019-09-02 02:00:00}" - ), + tpds, + timedelta(hours=2), + TGeogPointSeq( + "{Point(1 1)@2019-09-01 02:00:00, Point(2 2)@2019-09-02 02:00:00}" + ), ), ( - tpds, - timedelta(hours=-2), - TGeogPointSeq( - "{Point(1 1)@2019-08-31 22:00:00, Point(2 2)@2019-09-01 22:00:00}" - ), + tpds, + timedelta(hours=-2), + TGeogPointSeq( + "{Point(1 1)@2019-08-31 22:00:00, Point(2 2)@2019-09-01 22:00:00}" + ), ), ( - tps, - timedelta(days=4), - TGeogPointSeq("[Point(1 1)@2019-09-05, Point(2 2)@2019-09-06]"), + tps, + timedelta(days=4), + TGeogPointSeq("[Point(1 1)@2019-09-05, Point(2 2)@2019-09-06]"), ), ( - tps, - timedelta(days=-4), - TGeogPointSeq("[Point(1 1)@2019-08-28, Point(2 2)@2019-08-29]"), + tps, + timedelta(days=-4), + TGeogPointSeq("[Point(1 1)@2019-08-28, Point(2 2)@2019-08-29]"), ), ( - tps, - timedelta(hours=2), - TGeogPointSeq( - "[Point(1 1)@2019-09-01 02:00:00, Point(2 2)@2019-09-02 02:00:00]" - ), + tps, + timedelta(hours=2), + TGeogPointSeq( + "[Point(1 1)@2019-09-01 02:00:00, Point(2 2)@2019-09-02 02:00:00]" + ), ), ( - tps, - timedelta(hours=-2), - TGeogPointSeq( - "[Point(1 1)@2019-08-31 22:00:00, Point(2 2)@2019-09-01 22:00:00]" - ), + tps, + timedelta(hours=-2), + TGeogPointSeq( + "[Point(1 1)@2019-08-31 22:00:00, Point(2 2)@2019-09-01 22:00:00]" + ), ), ( - tpss, - timedelta(days=4), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-05, Point(2 2)@2019-09-06],[Point(1 1)@2019-09-07, Point(1 1)@2019-09-09]}" - ), + tpss, + timedelta(days=4), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-05, Point(2 2)@2019-09-06],[Point(1 1)@2019-09-07, Point(1 1)@2019-09-09]}" + ), ), ( - tpss, - timedelta(days=-4), - TGeogPointSeqSet( - "{[Point(1 1)@2019-08-28, Point(2 2)@2019-08-29],[Point(1 1)@2019-08-30, Point(1 1)@2019-09-01]}" - ), + tpss, + timedelta(days=-4), + TGeogPointSeqSet( + "{[Point(1 1)@2019-08-28, Point(2 2)@2019-08-29],[Point(1 1)@2019-08-30, Point(1 1)@2019-09-01]}" + ), ), ( - tpss, - timedelta(hours=2), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01 02:00:00, Point(2 2)@2019-09-02 02:00:00]," - "[Point(1 1)@2019-09-03 02:00:00, Point(1 1)@2019-09-05 02:00:00]}" - ), + tpss, + timedelta(hours=2), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01 02:00:00, Point(2 2)@2019-09-02 02:00:00]," + "[Point(1 1)@2019-09-03 02:00:00, Point(1 1)@2019-09-05 02:00:00]}" + ), ), ( - tpss, - timedelta(hours=-2), - TGeogPointSeqSet( - "{[Point(1 1)@2019-08-31 22:00:00, Point(2 2)@2019-09-01 22:00:00]," - "[Point(1 1)@2019-09-02 22:00:00, Point(1 1)@2019-09-04 22:00:00]}" - ), + tpss, + timedelta(hours=-2), + TGeogPointSeqSet( + "{[Point(1 1)@2019-08-31 22:00:00, Point(2 2)@2019-09-01 22:00:00]," + "[Point(1 1)@2019-09-02 22:00:00, Point(1 1)@2019-09-04 22:00:00]}" + ), ), ], ids=[ @@ -1633,43 +1633,43 @@ def test_shift_time(self, tpoint, delta, expected): (tpi, timedelta(days=4), TGeogPointInst("Point(1 1)@2019-09-01")), (tpi, timedelta(hours=2), TGeogPointInst("Point(1 1)@2019-09-01")), ( - tpds, - timedelta(days=4), - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-05}"), + tpds, + timedelta(days=4), + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-05}"), ), ( - tpds, - timedelta(hours=2), - TGeogPointSeq( - "{Point(1 1)@2019-09-01 00:00:00, Point(2 2)@2019-09-01 02:00:00}" - ), + tpds, + timedelta(hours=2), + TGeogPointSeq( + "{Point(1 1)@2019-09-01 00:00:00, Point(2 2)@2019-09-01 02:00:00}" + ), ), ( - tps, - timedelta(days=4), - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-05]"), + tps, + timedelta(days=4), + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-05]"), ), ( - tps, - timedelta(hours=2), - TGeogPointSeq( - "[Point(1 1)@2019-09-01 00:00:00, Point(2 2)@2019-09-01 02:00:00]" - ), + tps, + timedelta(hours=2), + TGeogPointSeq( + "[Point(1 1)@2019-09-01 00:00:00, Point(2 2)@2019-09-01 02:00:00]" + ), ), ( - tpss, - timedelta(days=4), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + timedelta(days=4), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ( - tpss, - timedelta(hours=2), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01 00:00:00, Point(2 2)@2019-09-01 00:30:00]," - "[Point(1 1)@2019-09-01 01:00:00, Point(1 1)@2019-09-01 02:00:00]}" - ), + tpss, + timedelta(hours=2), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01 00:00:00, Point(2 2)@2019-09-01 00:30:00]," + "[Point(1 1)@2019-09-01 01:00:00, Point(1 1)@2019-09-01 02:00:00]}" + ), ), ], ids=[ @@ -1701,31 +1701,31 @@ def test_shift_scale_time(self): (tpi, timedelta(hours=12), TGeogPointInst("Point(1 1)@2019-09-01")), (tpds, timedelta(days=4), TGeogPointSeq("{Point(1 1)@2019-09-01}")), ( - tpds, - timedelta(hours=12), - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), + tpds, + timedelta(hours=12), + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), ), (tps, timedelta(days=4), TGeogPointSeq("{Point(1 1)@2019-09-01}")), ( - tps, - timedelta(hours=12), - TGeogPointSeq( - "{Point(1 1)@2019-09-01, Point(1.5 1.5)@2019-09-01 12:00:00, Point(2 2)@2019-09-02}" - ), + tps, + timedelta(hours=12), + TGeogPointSeq( + "{Point(1 1)@2019-09-01, Point(1.5 1.5)@2019-09-01 12:00:00, Point(2 2)@2019-09-02}" + ), ), ( - tpss, - timedelta(days=4), - TGeogPointSeq("{Point(1 1)@2019-09-01,Point(1 1)@2019-09-05}"), + tpss, + timedelta(days=4), + TGeogPointSeq("{Point(1 1)@2019-09-01,Point(1 1)@2019-09-05}"), ), ( - tpss, - timedelta(hours=12), - TGeogPointSeq( - "{Point(1 1)@2019-09-01, Point(1.5 1.5)@2019-09-01 12:00:00," - "Point(2 2)@2019-09-02, Point(1 1)@2019-09-03, Point(1 1)@2019-09-03 12:00:00, " - "Point(1 1)@2019-09-04, Point(1 1)@2019-09-04 12:00:00, Point(1 1)@2019-09-05}" - ), + tpss, + timedelta(hours=12), + TGeogPointSeq( + "{Point(1 1)@2019-09-01, Point(1.5 1.5)@2019-09-01 12:00:00," + "Point(2 2)@2019-09-02, Point(1 1)@2019-09-03, Point(1 1)@2019-09-03 12:00:00, " + "Point(1 1)@2019-09-04, Point(1 1)@2019-09-04 12:00:00, Point(1 1)@2019-09-05}" + ), ), ], ids=[ @@ -1749,9 +1749,9 @@ def test_temporal_sample(self, tpoint, delta, expected): (tps, timedelta(hours=12), None), (tpss, timedelta(days=4), None), ( - tpss, - timedelta(hours=12), - TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), + tpss, + timedelta(hours=12), + TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), ), ], ids=[ @@ -1768,44 +1768,101 @@ def test_stops(self, tpoint, delta, expected): "temporal, expected", [ ( - TGeogPointInst("Point(1.123456789 1.123456789)@2019-09-01"), - TGeogPointInst("Point(1.12 1.12)@2019-09-01"), + TGeogPointInst("Point(1.123456789 1.123456789)@2019-09-01"), + TGeogPointInst("Point(1.12 1.12)@2019-09-01"), ), ( - TGeogPointSeq( - "{Point(1.123456789 1.123456789)@2019-09-01," - "Point(2.123456789 2.123456789)@2019-09-02}" - ), - TGeogPointSeq( - "{Point(1.12 1.12)@2019-09-01,Point(2.12 2.12)@2019-09-02}" - ), + TGeogPointSeq( + "{Point(1.123456789 1.123456789)@2019-09-01," + "Point(2.123456789 2.123456789)@2019-09-02}" + ), + TGeogPointSeq( + "{Point(1.12 1.12)@2019-09-01,Point(2.12 2.12)@2019-09-02}" + ), ), ( - TGeogPointSeq( - "[Point(1.123456789 1.123456789)@2019-09-01," - "Point(2.123456789 2.123456789)@2019-09-02]" - ), - TGeogPointSeq( - "[Point(1.12 1.12)@2019-09-01,Point(2.12 2.12)@2019-09-02]" - ), + TGeogPointSeq( + "[Point(1.123456789 1.123456789)@2019-09-01," + "Point(2.123456789 2.123456789)@2019-09-02]" + ), + TGeogPointSeq( + "[Point(1.12 1.12)@2019-09-01,Point(2.12 2.12)@2019-09-02]" + ), ), ( - TGeogPointSeqSet( - "{[Point(1.123456789 1.123456789)@2019-09-01," - "Point(2.123456789 2.123456789)@2019-09-02]," - "[Point(1.123456789 1.123456789)@2019-09-03," - "Point(1.123456789 1.123456789)@2019-09-05]}" - ), - TGeogPointSeq( - "{[Point(1.12 1.12)@2019-09-01,Point(2.12 2.12)@2019-09-02]," - "[Point(1.12 1.12)@2019-09-03,Point(1.12 1.12)@2019-09-05]}" - ), + TGeogPointSeqSet( + "{[Point(1.123456789 1.123456789)@2019-09-01," + "Point(2.123456789 2.123456789)@2019-09-02]," + "[Point(1.123456789 1.123456789)@2019-09-03," + "Point(1.123456789 1.123456789)@2019-09-05]}" + ), + TGeogPointSeq( + "{[Point(1.12 1.12)@2019-09-01,Point(2.12 2.12)@2019-09-02]," + "[Point(1.12 1.12)@2019-09-03,Point(1.12 1.12)@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], ) def test_round(self, temporal, expected): - assert temporal.round(max_decimals=2) + assert temporal.round(max_decimals=2) == expected + + @pytest.mark.parametrize( + "temporal, expected", + [ + ( + TGeogPointInst("Point(42.84979 42.38153)@2019-09-01"), + TGeogPointInst( + "SRID=8426;" + "Point(42.84979 42.38153)@2019-09-01" + ), + ), + ( + TGeogPointSeq( + "{Point(42.84979 42.38153)@2019-09-01," + "Point(44.31646 41.77403)@2019-09-02}" + ), + TGeogPointSeq( + "SRID=8426;" + "{Point(42.84979 42.38153)@2019-09-01," + "Point(44.31646 41.77403)@2019-09-02}" + ), + ), + ( + TGeogPointSeq( + "[Point(42.84979 42.38153)@2019-09-01," + "Point(44.31646 41.77403)@2019-09-02]" + ), + TGeogPointSeq( + "SRID=8426;" + "[Point(42.84979 42.38153)@2019-09-01," + "Point(44.31646 41.77403)@2019-09-02]" + ), + ), + ( + TGeogPointSeqSet( + "{[Point(42.84979 42.38153)@2019-09-01," + "Point(44.31646 41.77403)@2019-09-02]," + "[Point(42.28948 41.83545)@2019-09-03," + "Point(44.24505 41.53187)@2019-09-05]}" + ), + TGeogPointSeq( + "SRID=8426;" + "{[Point(42.84979 42.38153)@2019-09-01," + "Point(44.31646 41.77403)@2019-09-02]," + "[Point(42.28948 41.83545)@2019-09-03," + "Point(44.24505 41.53187)@2019-09-05]}" + ), + ), + ], + ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], + ) + def test_transform(self, temporal, expected): + srid = 8426 + transformed = temporal.transform(srid) + + assert transformed.round(5) == expected.round(5) + assert transformed.srid() == srid class TestTGeogPointModifications(TestTGeogPoint): @@ -1820,30 +1877,30 @@ class TestTGeogPointModifications(TestTGeogPoint): "temporal, sequence, expected", [ ( - tpi, - TGeogPointSeq("{Point(1 1)@2019-09-03}"), - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-03}"), + tpi, + TGeogPointSeq("{Point(1 1)@2019-09-03}"), + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-03}"), ), ( - tpds, - TGeogPointSeq("{Point(1 1)@2019-09-03}"), - TGeogPointSeq( - "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03}" - ), + tpds, + TGeogPointSeq("{Point(1 1)@2019-09-03}"), + TGeogPointSeq( + "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03}" + ), ), ( - tps, - TGeogPointSeq("[Point(1 1)@2019-09-03]"), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03]}" - ), + tps, + TGeogPointSeq("[Point(1 1)@2019-09-03]"), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03]}" + ), ), ( - tpss, - TGeogPointSeq("[Point(1 1)@2019-09-06]"), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05],[Point(1 1)@2019-09-06]}" - ), + tpss, + TGeogPointSeq("[Point(1 1)@2019-09-06]"), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05],[Point(1 1)@2019-09-06]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1855,28 +1912,28 @@ def test_insert(self, temporal, sequence, expected): "temporal, instant, expected", [ ( - tpi, - TGeogPointInst("Point(2 2)@2019-09-01"), - TGeogPointInst("Point(2 2)@2019-09-01"), + tpi, + TGeogPointInst("Point(2 2)@2019-09-01"), + TGeogPointInst("Point(2 2)@2019-09-01"), ), ( - tpds, - TGeogPointInst("Point(2 2)@2019-09-01"), - TGeogPointSeq("{Point(2 2)@2019-09-01, Point(2 2)@2019-09-02}"), + tpds, + TGeogPointInst("Point(2 2)@2019-09-01"), + TGeogPointSeq("{Point(2 2)@2019-09-01, Point(2 2)@2019-09-02}"), ), ( - tps, - TGeogPointInst("Point(2 2)@2019-09-01"), - TGeogPointSeqSet( - "{[Point(2 2)@2019-09-01], (Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}" - ), + tps, + TGeogPointInst("Point(2 2)@2019-09-01"), + TGeogPointSeqSet( + "{[Point(2 2)@2019-09-01], (Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}" + ), ), ( - tpss, - TGeogPointInst("Point(2 2)@2019-09-01"), - TGeogPointSeqSet( - "{[Point(2 2)@2019-09-01], (Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + TGeogPointInst("Point(2 2)@2019-09-01"), + TGeogPointSeqSet( + "{[Point(2 2)@2019-09-01], (Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1890,22 +1947,21 @@ def test_update(self, temporal, instant, expected): (tpi, datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), None), (tpi, datetime(year=2019, month=9, day=2, tzinfo=timezone.utc), tpi), ( - tpds, - datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), - TGeogPointSeq("{Point(2 2)@2019-09-02}"), + tpds, + datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), + TGeogPointSeq("{Point(2 2)@2019-09-02}"), ), ( - tps, - datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + tps, + datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), + TGeogPointSeqSet("{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), ( - tpss, - datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + datetime(year=2019, month=9, day=1, tzinfo=timezone.utc), + TGeogPointSeqSet( + "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ], ids=[ @@ -1923,30 +1979,30 @@ def test_delete(self, temporal, time, expected): "temporal, instant, expected", [ ( - tpi, - TGeogPointInst("Point(1 1)@2019-09-02"), - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]"), + tpi, + TGeogPointInst("Point(1 1)@2019-09-02"), + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]"), ), ( - tpds, - TGeogPointInst("Point(1 1)@2019-09-03"), - TGeogPointSeq( - "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03}" - ), + tpds, + TGeogPointInst("Point(1 1)@2019-09-03"), + TGeogPointSeq( + "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03}" + ), ), ( - tps, - TGeogPointInst("Point(1 1)@2019-09-03"), - TGeogPointSeq( - "[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03]" - ), + tps, + TGeogPointInst("Point(1 1)@2019-09-03"), + TGeogPointSeq( + "[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03]" + ), ), ( - tpss, - TGeogPointInst("Point(1 1)@2019-09-06"), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-06]}" - ), + tpss, + TGeogPointInst("Point(1 1)@2019-09-06"), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-06]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -1958,25 +2014,25 @@ def test_append_instant(self, temporal, instant, expected): "temporal, sequence, expected", [ ( - tpds, - TGeogPointSeq("{Point(1 1)@2019-09-03}"), - TGeogPointSeq( - "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03}" - ), + tpds, + TGeogPointSeq("{Point(1 1)@2019-09-03}"), + TGeogPointSeq( + "{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02, Point(1 1)@2019-09-03}" + ), ), ( - tps, - TGeogPointSeq("[Point(1 1)@2019-09-03]"), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02], [Point(1 1)@2019-09-03]}" - ), + tps, + TGeogPointSeq("[Point(1 1)@2019-09-03]"), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02], [Point(1 1)@2019-09-03]}" + ), ), ( - tpss, - TGeogPointSeq("[Point(1 1)@2019-09-06]"), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05],[Point(1 1)@2019-09-06]}" - ), + tpss, + TGeogPointSeq("[Point(1 1)@2019-09-06]"), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05],[Point(1 1)@2019-09-06]}" + ), ), ], ids=["Discrete Sequence", "Sequence", "SequenceSet"], @@ -2006,86 +2062,85 @@ class TestTGeogPointRestrictors(TestTGeogPoint): (tpi, tstzspan, TGeogPointInst("Point(1 1)@2019-09-01")), (tpi, tstzspan_set, TGeogPointInst("Point(1 1)@2019-09-01")), ( - tpi, - shapely.set_srid(shapely.Point(1, 1), 4326), - TGeogPointInst("Point(1 1)@2019-09-01"), + tpi, + shapely.set_srid(shapely.Point(1, 1), 4326), + TGeogPointInst("Point(1 1)@2019-09-01"), ), (tpi, shapely.set_srid(shapely.Point(2, 2), 4326), None), (tpds, timestamp, TGeogPointSeq("{Point(1 1)@2019-09-01}")), (tpds, timestamp_set, TGeogPointSeq("{Point(1 1)@2019-09-01}")), ( - tpds, - tstzspan, - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), + tpds, + tstzspan, + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), ), ( - tpds, - tstzspan_set, - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), + tpds, + tstzspan_set, + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}"), ), ( - tpds, - shapely.set_srid(shapely.Point(1, 1), 4326), - TGeogPointSeq("{Point(1 1)@2019-09-01}"), + tpds, + shapely.set_srid(shapely.Point(1, 1), 4326), + TGeogPointSeq("{Point(1 1)@2019-09-01}"), ), ( - tpds, - shapely.set_srid(shapely.Point(2, 2), 4326), - TGeogPointSeq("{Point(2 2)@2019-09-02}"), + tpds, + shapely.set_srid(shapely.Point(2, 2), 4326), + TGeogPointSeq("{Point(2 2)@2019-09-02}"), ), (tps, timestamp, TGeogPointSeq("[Point(1 1)@2019-09-01]")), (tps, timestamp_set, TGeogPointSeq("{Point(1 1)@2019-09-01}")), ( - tps, - tstzspan, - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), + tps, + tstzspan, + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), ), ( - tps, - tstzspan_set, - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), + tps, + tstzspan_set, + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]"), ), ( - tps, - shapely.set_srid(shapely.Point(1, 1), 4326), - TGeogPointSeq("[Point(1 1)@2019-09-01]"), + tps, + shapely.set_srid(shapely.Point(1, 1), 4326), + TGeogPointSeq("[Point(1 1)@2019-09-01]"), ), ( - tps, - shapely.set_srid(shapely.Point(2, 2), 4326), - TGeogPointSeq("[Point(2 2)@2019-09-02]"), + tps, + shapely.set_srid(shapely.Point(2, 2), 4326), + TGeogPointSeq("[Point(2 2)@2019-09-02]"), ), (tpss, timestamp, TGeogPointSeqSet("[Point(1 1)@2019-09-01]")), ( - tpss, - timestamp_set, - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-03}"), + tpss, + timestamp_set, + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-03}"), ), ( - tpss, - tstzspan, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + tpss, + tstzspan, + TGeogPointSeqSet("{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), ( - tpss, - tstzspan_set, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]," - "[Point(1 1)@2019-09-03,Point(1 1)@2019-09-05]}" - ), + tpss, + tstzspan_set, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]," + "[Point(1 1)@2019-09-03,Point(1 1)@2019-09-05]}" + ), ), ( - tpss, - shapely.set_srid(shapely.Point(1, 1), 4326), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + shapely.set_srid(shapely.Point(1, 1), 4326), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ( - tpss, - shapely.set_srid(shapely.Point(2, 2), 4326), - TGeogPointSeqSet("{[Point(2 2)@2019-09-02]}"), + tpss, + shapely.set_srid(shapely.Point(2, 2), 4326), + TGeogPointSeqSet("{[Point(2 2)@2019-09-02]}"), ), ], ids=[ @@ -2127,83 +2182,77 @@ def test_at(self, temporal, restrictor, expected): (tpi, tstzspan_set, None), (tpi, shapely.set_srid(shapely.Point(1, 1), 4326), None), ( - tpi, - shapely.set_srid(shapely.Point(2, 2), 4326), - TGeogPointInst("Point(1 1)@2019-09-01"), + tpi, + shapely.set_srid(shapely.Point(2, 2), 4326), + TGeogPointInst("Point(1 1)@2019-09-01"), ), (tpds, timestamp, TGeogPointSeq("{Point(2 2)@2019-09-02}")), (tpds, timestamp_set, TGeogPointSeq("{Point(2 2)@2019-09-02}")), (tpds, tstzspan, None), (tpds, tstzspan_set, None), ( - tpds, - shapely.set_srid(shapely.Point(1, 1), 4326), - TGeogPointSeq("{Point(2 2)@2019-09-02}"), + tpds, + shapely.set_srid(shapely.Point(1, 1), 4326), + TGeogPointSeq("{Point(2 2)@2019-09-02}"), ), ( - tpds, - shapely.set_srid(shapely.Point(2, 2), 4326), - TGeogPointSeq("{Point(1 1)@2019-09-01}"), + tpds, + shapely.set_srid(shapely.Point(2, 2), 4326), + TGeogPointSeq("{Point(1 1)@2019-09-01}"), ), ( - tps, - timestamp, - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + tps, + timestamp, + TGeogPointSeqSet("{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), ( - tps, - timestamp_set, - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + tps, + timestamp_set, + TGeogPointSeqSet("{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), (tps, tstzspan, None), (tps, tstzspan_set, None), ( - tps, - shapely.set_srid(shapely.Point(1, 1), 4326), - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + tps, + shapely.set_srid(shapely.Point(1, 1), 4326), + TGeogPointSeqSet("{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), ( - tps, - shapely.set_srid(shapely.Point(2, 2), 4326), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02)}"), + tps, + shapely.set_srid(shapely.Point(2, 2), 4326), + TGeogPointSeqSet("{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02)}"), ), ( - tpss, - timestamp, - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + timestamp, + TGeogPointSeqSet( + "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ( - tpss, - timestamp_set, - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],(Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + timestamp_set, + TGeogPointSeqSet( + "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02],(Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ( - tpss, - tstzspan, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}"), + tpss, + tstzspan, + TGeogPointSeqSet("{[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}"), ), (tpss, tstzspan_set, None), ( - tpss, - shapely.set_srid(shapely.Point(1, 1), 4326), - TGeogPointSeqSet( - "{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), + tpss, + shapely.set_srid(shapely.Point(1, 1), 4326), + TGeogPointSeqSet("{(Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]}"), ), ( - tpss, - shapely.set_srid(shapely.Point(2, 2), 4326), - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02),[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + shapely.set_srid(shapely.Point(2, 2), 4326), + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02),[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ], ids=[ @@ -2293,9 +2342,8 @@ def test_minus(self, temporal, restrictor, expected): ) def test_at_minus(self, temporal, restrictor): assert ( - TGeogPoint.from_merge(temporal.at(restrictor), - temporal.minus(restrictor)) - == temporal + TGeogPoint.from_merge(temporal.at(restrictor), temporal.minus(restrictor)) + == temporal ) @pytest.mark.parametrize( @@ -2305,12 +2353,10 @@ def test_at_minus(self, temporal, restrictor): ) def test_at_minus_min_max(self, temporal): assert ( - TGeogPoint.from_merge(temporal.at_min(), - temporal.minus_min()) == temporal + TGeogPoint.from_merge(temporal.at_min(), temporal.minus_min()) == temporal ) assert ( - TGeogPoint.from_merge(temporal.at_max(), - temporal.minus_max()) == temporal + TGeogPoint.from_merge(temporal.at_max(), temporal.minus_max()) == temporal ) @@ -2335,31 +2381,13 @@ class TestTGeogPointEverSpatialOperations(TestTGeogPoint): def test_temporal_ever_contained_withindist_intersects(self, temporal, expected): assert temporal.is_ever_within_distance(Point(1, 1), 1) == expected assert ( - temporal.is_ever_within_distance( - TGeogPointInst("Point(1 1)@2019-09-01"), 1) - == expected + temporal.is_ever_within_distance(TGeogPointInst("Point(1 1)@2019-09-01"), 1) + == expected ) assert temporal.ever_intersects(Point(1, 1)) == expected assert ( - temporal.ever_intersects(TGeogPointInst("Point(1 1)@2019-09-01")) - == expected - ) - - @pytest.mark.parametrize( - "temporal, expected", - [ - (tpi, True), - (tpds, True), - (tps, True), - (tpss, True), - ], - ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], - ) - def test_temporal_ever_disjoint(self, temporal, expected): - assert temporal.is_ever_disjoint(Point(3, 3)) == expected - assert ( - temporal.is_ever_disjoint(TGeogPointInst("Point(3 3)@2019-09-01")) - == expected + temporal.ever_intersects(TGeogPointInst("Point(1 1)@2019-09-01")) + == expected ) @@ -2377,17 +2405,17 @@ class TestTGeogPointTemporalSpatialOperations(TestTGeogPoint): (tpi, TBoolInst("True@2019-09-01")), (tpds, TBoolSeq("{True@2019-09-01, False@2019-09-02}")), ( - tps, - TBoolSeqSet( - "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02]}" - ), + tps, + TBoolSeqSet( + "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02]}" + ), ), ( - tpss, - TBoolSeqSet( - "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02]," - "[True@2019-09-03, True@2019-09-05]}" - ), + tpss, + TBoolSeqSet( + "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02]," + "[True@2019-09-03, True@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -2404,11 +2432,11 @@ def test_temporal_intersects_disjoint(self, temporal, expected): (tpds, TBoolSeq("{False@2019-09-01, False@2019-09-02}")), (tps, TBoolSeqSet("[False@2019-09-01, False@2019-09-02]")), ( - tpss, - TBoolSeqSet( - "{[False@2019-09-01, False@2019-09-02]," - "[False@2019-09-03, False@2019-09-05]}" - ), + tpss, + TBoolSeqSet( + "{[False@2019-09-01, False@2019-09-02]," + "[False@2019-09-03, False@2019-09-05]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -2423,38 +2451,38 @@ def test_temporal_touches(self, temporal, expected): (tpds, Point(1, 1), TBoolSeq("{True@2019-09-01, True@2019-09-02}")), (tps, Point(1, 1), TBoolSeqSet("{[True@2019-09-01, True@2019-09-02]}")), ( - tpss, - Point(1, 1), - TBoolSeqSet( - "{[True@2019-09-01, True@2019-09-02]," - "[True@2019-09-03, True@2019-09-05]}" - ), + tpss, + Point(1, 1), + TBoolSeqSet( + "{[True@2019-09-01, True@2019-09-02]," + "[True@2019-09-03, True@2019-09-05]}" + ), ), ( - tpi, - TGeogPointInst("Point(1 1)@2019-09-01"), - TBoolInst("True@2019-09-01"), + tpi, + TGeogPointInst("Point(1 1)@2019-09-01"), + TBoolInst("True@2019-09-01"), ), ( - tpds, - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}"), - TBoolSeq("{True@2019-09-01, False@2019-09-02}"), + tpds, + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}"), + TBoolSeq("{True@2019-09-01, False@2019-09-02}"), ), ( - tps, - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]"), - TBoolSeqSet("{[True@2019-09-01, True@2019-09-02]}"), + tps, + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]"), + TBoolSeqSet("{[True@2019-09-01, True@2019-09-02]}"), ), ( - tpss, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," - "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), - TBoolSeqSet( - "{[True@2019-09-01, True@2019-09-02]," - "[True@2019-09-03, True@2019-09-05]}" - ), + tpss, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," + "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), + TBoolSeqSet( + "{[True@2019-09-01, True@2019-09-02]," + "[True@2019-09-03, True@2019-09-05]}" + ), ), ], ids=[ @@ -2487,53 +2515,53 @@ class TestTGeogPointDistanceOperations(TestTGeogPoint): (tpds, Point(1, 1), TFloatSeq("{0@2019-09-01, 156876.149@2019-09-02}")), (tps, Point(1, 1), TFloatSeq("[0@2019-09-01, 156876.149@2019-09-02]")), ( - tpss, - Point(1, 1), - TFloatSeqSet( - "{[0@2019-09-01, 156876.149@2019-09-02]," - "[0@2019-09-03, 0@2019-09-05]}" - ), + tpss, + Point(1, 1), + TFloatSeqSet( + "{[0@2019-09-01, 156876.149@2019-09-02]," + "[0@2019-09-03, 0@2019-09-05]}" + ), ), (tpi, STBox("GEODSTBOX X((1,1),(1,1))"), TFloatInst("0@2019-09-01")), ( - tpds, - STBox("GEODSTBOX X((1,1),(1,1))"), - TFloatSeq("{0@2019-09-01, 156876.149@2019-09-02}"), + tpds, + STBox("GEODSTBOX X((1,1),(1,1))"), + TFloatSeq("{0@2019-09-01, 156876.149@2019-09-02}"), ), ( - tps, - STBox("GEODSTBOX X((1,1),(1,1))"), - TFloatSeq("[0@2019-09-01, 156876.149@2019-09-02]"), + tps, + STBox("GEODSTBOX X((1,1),(1,1))"), + TFloatSeq("[0@2019-09-01, 156876.149@2019-09-02]"), ), ( - tpss, - STBox("GEODSTBOX X((1,1),(1,1))"), - TFloatSeqSet( - "{[0@2019-09-01, 156876.149@2019-09-02]," - "[0@2019-09-03, 0@2019-09-05]}" - ), + tpss, + STBox("GEODSTBOX X((1,1),(1,1))"), + TFloatSeqSet( + "{[0@2019-09-01, 156876.149@2019-09-02]," + "[0@2019-09-03, 0@2019-09-05]}" + ), ), (tpi, TGeogPointInst("Point(1 1)@2019-09-01"), TFloatInst("0@2019-09-01")), ( - tpds, - TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}"), - TFloatSeq("{0@2019-09-01, 156876.149@2019-09-02}"), + tpds, + TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}"), + TFloatSeq("{0@2019-09-01, 156876.149@2019-09-02}"), ), ( - tps, - TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]"), - TFloatSeq("[0@2019-09-01, 156876.149@2019-09-02]"), + tps, + TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]"), + TFloatSeq("[0@2019-09-01, 156876.149@2019-09-02]"), ), ( - tpss, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," - "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), - TFloatSeqSet( - "{[0@2019-09-01, 156876.149@2019-09-02]," - "[0@2019-09-03, 0@2019-09-05]}" - ), + tpss, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," + "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), + TFloatSeqSet( + "{[0@2019-09-01, 156876.149@2019-09-02]," + "[0@2019-09-03, 0@2019-09-05]}" + ), ), ], ids=[ @@ -2566,11 +2594,11 @@ def test_distance(self, temporal, argument, expected): (tpds, TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}")), (tps, TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]")), ( - tpss, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," - "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," + "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ], ids=[ @@ -2600,11 +2628,11 @@ def test_nearest_approach_instant(self, temporal, argument): (tpds, TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}")), (tps, TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]")), ( - tpss, - TGeogPointSeqSet( - "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," - "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" - ), + tpss, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," + "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), ), ], ids=[ @@ -2686,11 +2714,11 @@ class TestTGeogPointSplitOperations(TestTGeogPoint): (tpds, [TGeogPointSeq("{Point(1 1)@2019-09-01, Point(2 2)@2019-09-02}")]), (tps, [TGeogPointSeq("[Point(1 1)@2019-09-01, Point(2 2)@2019-09-02]")]), ( - tpss, - [ - TGeogPointSeq("[Point(1 1)@2019-09-01,Point(2 2)@2019-09-02]"), - TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), - ], + tpss, + [ + TGeogPointSeq("[Point(1 1)@2019-09-01,Point(2 2)@2019-09-02]"), + TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), + ], ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -2703,29 +2731,29 @@ def test_time_split(self, temporal, expected): [ (tpi, [TGeogPointInst("Point(1 1)@2019-09-01")]), ( - tpds, - [ - TGeogPointSeq("{Point(1 1)@2019-09-01}"), - TGeogPointSeq("{Point(2 2)@2019-09-02}"), - ], + tpds, + [ + TGeogPointSeq("{Point(1 1)@2019-09-01}"), + TGeogPointSeq("{Point(2 2)@2019-09-02}"), + ], ), ( - tps, - [ - TGeogPointSeq( - "[Point(1 1)@2019-09-01, Point(1.5 1.5)@2019-09-01 12:00:00+00)" - ), - TGeogPointSeq( - "[Point(1.5 1.5)@2019-09-01 12:00:00+00, Point(2 2)@2019-09-02]" - ), - ], + tps, + [ + TGeogPointSeq( + "[Point(1 1)@2019-09-01, Point(1.5 1.5)@2019-09-01 12:00:00+00)" + ), + TGeogPointSeq( + "[Point(1.5 1.5)@2019-09-01 12:00:00+00, Point(2 2)@2019-09-02]" + ), + ], ), ( - tpss, - [ - TGeogPointSeq("[Point(1 1)@2019-09-01,Point(2 2)@2019-09-02]"), - TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), - ], + tpss, + [ + TGeogPointSeq("[Point(1 1)@2019-09-01,Point(2 2)@2019-09-02]"), + TGeogPointSeq("[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]"), + ], ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -2843,18 +2871,18 @@ class TestTGeogPointTemporalComparisons(TestTGeogPoint): (tpi, TBoolInst("False@2019-09-01")), (tpds, TBoolSeq("{False@2019-09-01, False@2019-09-02}")), ( - tps, - TBoolSeqSet( - "{[False@2019-09-01, True@2019-09-01 12:00:00+00]," - "(False@2019-09-01 12:00:00+00, False@2019-09-02]}" - ), + tps, + TBoolSeqSet( + "{[False@2019-09-01, True@2019-09-01 12:00:00+00]," + "(False@2019-09-01 12:00:00+00, False@2019-09-02]}" + ), ), ( - tpss, - TBoolSeqSet( - "{[False@2019-09-01, True@2019-09-01 12:00:00+00]," - "(False@2019-09-01 12:00:00+00, False@2019-09-02],[True@2019-09-03]}" - ), + tpss, + TBoolSeqSet( + "{[False@2019-09-01, True@2019-09-01 12:00:00+00]," + "(False@2019-09-01 12:00:00+00, False@2019-09-02],[True@2019-09-03]}" + ), ), ], ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], @@ -2867,50 +2895,50 @@ def test_temporal_equal_temporal(self, temporal, expected): "temporal, argument, expected", [ ( - tpi, - shapely.set_srid(shapely.Point(1, 1), 4326), - TBoolInst("True@2019-09-01"), + tpi, + shapely.set_srid(shapely.Point(1, 1), 4326), + TBoolInst("True@2019-09-01"), ), ( - tpds, - shapely.set_srid(shapely.Point(1, 1), 4326), - TBoolSeq("{True@2019-09-01, False@2019-09-02}"), + tpds, + shapely.set_srid(shapely.Point(1, 1), 4326), + TBoolSeq("{True@2019-09-01, False@2019-09-02}"), ), ( - tps, - shapely.set_srid(shapely.Point(1, 1), 4326), - TBoolSeqSet( - "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02]}" - ), + tps, + shapely.set_srid(shapely.Point(1, 1), 4326), + TBoolSeqSet( + "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02]}" + ), ), ( - tpss, - shapely.set_srid(shapely.Point(1, 1), 4326), - TBoolSeqSet( - "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02],[True@2019-09-03, True@2019-09-05]}" - ), + tpss, + shapely.set_srid(shapely.Point(1, 1), 4326), + TBoolSeqSet( + "{[True@2019-09-01], (False@2019-09-01, False@2019-09-02],[True@2019-09-03, True@2019-09-05]}" + ), ), ( - tpi, - shapely.set_srid(shapely.Point(2, 2), 4326), - TBoolInst("False@2019-09-01"), + tpi, + shapely.set_srid(shapely.Point(2, 2), 4326), + TBoolInst("False@2019-09-01"), ), ( - tpds, - shapely.set_srid(shapely.Point(2, 2), 4326), - TBoolSeq("{False@2019-09-01, True@2019-09-02}"), + tpds, + shapely.set_srid(shapely.Point(2, 2), 4326), + TBoolSeq("{False@2019-09-01, True@2019-09-02}"), ), ( - tps, - shapely.set_srid(shapely.Point(2, 2), 4326), - TBoolSeq("[False@2019-09-01, True@2019-09-02]"), + tps, + shapely.set_srid(shapely.Point(2, 2), 4326), + TBoolSeq("[False@2019-09-01, True@2019-09-02]"), ), ( - tpss, - shapely.set_srid(shapely.Point(2, 2), 4326), - TBoolSeqSet( - "{[False@2019-09-01, True@2019-09-02],[False@2019-09-03, False@2019-09-05]}" - ), + tpss, + shapely.set_srid(shapely.Point(2, 2), 4326), + TBoolSeqSet( + "{[False@2019-09-01, True@2019-09-02],[False@2019-09-03, False@2019-09-05]}" + ), ), ], ids=[ diff --git a/pymeos/tests/main/tgeompoint_test.py b/pymeos/tests/main/tgeompoint_test.py index 0ae0cc5a..68952793 100644 --- a/pymeos/tests/main/tgeompoint_test.py +++ b/pymeos/tests/main/tgeompoint_test.py @@ -1904,6 +1904,53 @@ def test_make_simple(self, temporal, expected): def test_expand(self, temporal, expected): assert temporal.expand(2) == expected + @pytest.mark.parametrize( + "temporal, expected", + [ + ( + TGeomPointInst("SRID=4326;Point(2.05455 41.62840)@2019-09-01"), + TGeomPointInst( + "SRID=2062;Point(1077794.3091235077 796037.0089003219)@2019-09-01"), + ), + ( + TGeomPointSeq( + "SRID=4326;{Point(2.05455 41.62840)@2019-09-01," + "Point(1.63164 41.41622)@2019-09-02}" + ), + TGeomPointSeq( + "SRID=2062;{Point(1077794.3091235077 796037.0089003219)@2019-09-01,Point(1044050.9767668848 770349.6009306419)@2019-09-02}" + ), + ), + ( + TGeomPointSeq( + "SRID=4326;[Point(2.05455 41.62840)@2019-09-01," + "Point(1.63164 41.41622)@2019-09-02]" + ), + TGeomPointSeq( + "SRID=2062;[Point(1077794.3091235077 796037.0089003219)@2019-09-01,Point(1044050.9767668848 770349.6009306419)@2019-09-02]" + ), + ), + ( + TGeomPointSeqSet( + "SRID=4326;{[Point(2.05455 41.62840)@2019-09-01," + "Point(1.63164 41.41622)@2019-09-02]," + "[Point(1.74064 41.48158)@2019-09-03," + "Point(2.54287 41.70331)@2019-09-05]}" + ), + TGeomPointSeq( + "SRID=2062;{[Point(1077794.3091235077 796037.0089003219)@2019-09-01,Point(1044050.9767668848 770349.6009306419)@2019-09-02]," + "[Point(1052698.1755408798 778137.4310070301)@2019-09-03,Point(1117783.9536644723 807058.9808454381)@2019-09-05]}" + ), + ), + ], + ids=["Instant", "Discrete Sequence", "Sequence", "SequenceSet"], + ) + def test_transform(self, temporal, expected): + srid = 2062 + transformed = temporal.transform(srid) + + assert transformed.round(5) == expected.round(5) + assert transformed.srid() == srid class TestTGeomPointModifications(TestTGeomPoint): tpi = TGeomPointInst("Point(1 1)@2019-09-01") diff --git a/pymeos_cffi/pymeos_cffi/__init__.py b/pymeos_cffi/pymeos_cffi/__init__.py index 150b8071..847cff76 100644 --- a/pymeos_cffi/pymeos_cffi/__init__.py +++ b/pymeos_cffi/pymeos_cffi/__init__.py @@ -2,7 +2,7 @@ from .enums import * from .errors import * -__version__ = "1.1.0" +__version__ = "1.1.1" __all__ = [ # Exceptions "MeosException", diff --git a/pymeos_cffi/pymeos_cffi/builder/build_header.py b/pymeos_cffi/pymeos_cffi/builder/build_header.py index c7885a9a..de092f11 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_header.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_header.py @@ -7,7 +7,7 @@ def get_defined_functions(library_path): - result = subprocess.check_output(["nm", "-gD", library_path]) + result = subprocess.check_output(["nm", "-g", library_path]) output = result.decode("utf-8") lines = output.splitlines() defined = {line.split(" ")[-1] for line in lines if " T " in line} @@ -20,7 +20,9 @@ def remove_undefined_functions(content, so_path): def remove_if_not_defined(m): function = m.group(0).split("(")[0].strip().split(" ")[-1].strip("*") - if function in defined: + if function in defined or ( + sys.platform == "darwin" and ("_" + function) in defined + ): for t in undefined_types: if t in m.group(0): print(f"Removing function due to undefined type {t}: {function}") @@ -37,7 +39,7 @@ def remove_if_not_defined(m): def remove_repeated_functions( - content: str, seen_functions: set + content: str, seen_functions: set ) -> Tuple[str, Set[str]]: def remove_if_repeated(m): function = m.group(0).replace("\n", "").strip() @@ -105,7 +107,7 @@ def main(include_dir, so_path=None, destination_path="pymeos_cffi/builder/meos.h if sys.platform == "linux": main("/usr/local/include", "/usr/local/lib/libmeos.so") elif sys.platform == "darwin": - if platform.processor() == 'arm': + if platform.processor() == "arm": main("/opt/homebrew/include", "/opt/homebrew/lib/libmeos.dylib") else: main("/usr/local/include", "/usr/local/lib/libmeos.dylib") diff --git a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py index 9757b22a..0ffb0d4e 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py @@ -23,11 +23,24 @@ def get_library_dirs(): raise NotImplementedError("Unsupported platform") +def get_include_dirs(): + if sys.platform == "linux": + return ["/usr/local/include"] + elif sys.platform == "darwin": + if platform.processor() == "arm": + return ["/opt/homebrew/include"] + else: + return ["/usr/local/include"] + else: + raise NotImplementedError("Unsupported platform") + + ffibuilder.set_source( "_meos_cffi", '#include "meos.h"\n' '#include "meos_catalog.h"\n' '#include "meos_internal.h"', libraries=["meos"], library_dirs=get_library_dirs(), + include_dirs=get_include_dirs(), ) # library name, for the linker if __name__ == "__main__": # not when running with setuptools diff --git a/pymeos_cffi/pymeos_cffi/builder/meos.h b/pymeos_cffi/pymeos_cffi/builder/meos.h index b22df1fc..8c44f8ad 100644 --- a/pymeos_cffi/pymeos_cffi/builder/meos.h +++ b/pymeos_cffi/pymeos_cffi/builder/meos.h @@ -428,6 +428,7 @@ typedef enum INTERSECTS = 0, CONTAINS = 1, TOUCHES = 2, + COVERS = 3, } spatialRel; typedef struct @@ -544,9 +545,9 @@ extern int meos_errno_reset(void); typedef void (*error_handler_fn)(int, int, char *); -extern void meos_initialize_timezone(const char *name); +/* extern void meos_initialize_timezone(const char *name); (undefined) */ extern void meos_initialize_error_handler(error_handler_fn err_handler); -extern void meos_finalize_timezone(void); +/* extern void meos_finalize_timezone(void); (undefined) */ extern bool meos_set_datestyle(char *newval, void *extra); extern bool meos_set_intervalstyle(char *newval, int extra); diff --git a/pymeos_cffi/pymeos_cffi/builder/templates/init.py b/pymeos_cffi/pymeos_cffi/builder/templates/init.py index e07acbb9..49f146eb 100644 --- a/pymeos_cffi/pymeos_cffi/builder/templates/init.py +++ b/pymeos_cffi/pymeos_cffi/builder/templates/init.py @@ -2,7 +2,7 @@ from .enums import * from .errors import * -__version__ = "1.1.0" +__version__ = "1.1.1" __all__ = [ # Exceptions "MeosException", From bf30011bc907cff86972fb83a0287be809c4c816 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 18:48:06 +0200 Subject: [PATCH 02/36] Add pymeos cffi build workflow --- .github/workflows/build_pymeos_cffi.yml | 79 +++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/build_pymeos_cffi.yml diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml new file mode 100644 index 00000000..99749ebe --- /dev/null +++ b/.github/workflows/build_pymeos_cffi.yml @@ -0,0 +1,79 @@ +name: Build PyMEOS CFFI + +on: + push: + branches: + - build-actions + create: + tags: + - "pymeos-cffi-[0-9]+.[0-9]+.[0-9]+*" + +jobs: + build: + name: Build PyMEOS CFFI for ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, macos-13, macos-14 ] + include: + - ld_path: "/usr/local/lib" + - os: macos-14 + ld_path: "/opt/homebrew/lib" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Get dependencies from apt (cache) + uses: awalsh128/cache-apt-pkgs-action@latest + if: runner.os == 'Linux' + with: + packages: build-essential cmake postgresql-server-dev-14 libproj-dev libjson-c-dev libgsl-dev libgeos-dev + version: 1.0 + + - name: Update brew + if: matrix.os == 'macos-13' + # Necessary to avoid issue with macOS runners. See + # https://github.com/actions/runner-images/issues/4020 + run: | + brew reinstall python@3.12 || brew link --overwrite python@3.12 + brew reinstall python@3.11 || brew link --overwrite python@3.11 + brew update + + - name: Get dependencies from homebrew (cache) + uses: tecolicom/actions-use-homebrew-tools@v1 + if: runner.os == 'macOS' + with: + tools: cmake libpq proj json-c gsl geos + + - name: Fetch MEOS sources + env: + BRANCH_NAME: ${{ github.base_ref || github.ref_name }} + run: | + git clone --branch ${{ env.BRANCH_NAME }} --depth 1 https://github.com/MobilityDB/MobilityDB + + - name: Install MEOS + run: | + mkdir MobilityDB/build + cd MobilityDB/build + cmake .. -DMEOS=on + make -j + sudo make install + + # Used to host cibuildwheel + - uses: actions/setup-python@v3 + + - name: Install cibuildwheel + run: python -m pip install cibuildwheel==2.17.0 + + - name: Build wheels + run: python -m cibuildwheel --output-dir wheelhouse + # to supply options, put them in 'env', like: + env: + CIBW_TEST_COMMAND: "from pymeos_cffi import meos_initialize, meos_finalize; meos_initialize('UTC'); meos_finalize()" + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl From e1035b6f895f5d4c51c6cabb7ade73caaf5cdb36 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 18:49:43 +0200 Subject: [PATCH 03/36] Always get meos sources from default branch --- .github/workflows/build_pymeos_cffi.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 99749ebe..7a68305e 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -48,10 +48,8 @@ jobs: tools: cmake libpq proj json-c gsl geos - name: Fetch MEOS sources - env: - BRANCH_NAME: ${{ github.base_ref || github.ref_name }} run: | - git clone --branch ${{ env.BRANCH_NAME }} --depth 1 https://github.com/MobilityDB/MobilityDB + git clone --depth 1 https://github.com/MobilityDB/MobilityDB - name: Install MEOS run: | From a21adfcec2c83f11a39cf6c4197a72f61b116db0 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 18:52:58 +0200 Subject: [PATCH 04/36] Set working directory of wheel build step --- .github/workflows/build_pymeos_cffi.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 7a68305e..4c15b3d1 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -66,6 +66,7 @@ jobs: run: python -m pip install cibuildwheel==2.17.0 - name: Build wheels + working-directory: pymeos_cffi run: python -m cibuildwheel --output-dir wheelhouse # to supply options, put them in 'env', like: env: From e210b3c18077c87f82b7bee71208891469c481b2 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 18:56:12 +0200 Subject: [PATCH 05/36] Add ld_path to exports before building wheels --- .github/workflows/build_pymeos_cffi.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 4c15b3d1..915c10f0 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -67,7 +67,10 @@ jobs: - name: Build wheels working-directory: pymeos_cffi - run: python -m cibuildwheel --output-dir wheelhouse + run: | + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_path }} + export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} + python -m cibuildwheel --output-dir wheelhouse # to supply options, put them in 'env', like: env: CIBW_TEST_COMMAND: "from pymeos_cffi import meos_initialize, meos_finalize; meos_initialize('UTC'); meos_finalize()" From 845f80069c56c9625282b7b35e9b8b4daf914f66 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:13:33 +0200 Subject: [PATCH 06/36] Install meos in linux wheel build container --- .github/workflows/build_pymeos_cffi.yml | 52 ++++++++++++++++++------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 915c10f0..ec11d0b7 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -9,7 +9,28 @@ on: - "pymeos-cffi-[0-9]+.[0-9]+.[0-9]+*" jobs: - build: + build_sdist: + name: Build PyMEOS CFFI source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + name: Install Python + with: + python-version: 3.8 + + - name: Check metadata + run: "python setup.py check" + - name: Build sdist + run: | + python setup.py sdist + ls -l dist + + - uses: actions/upload-artifact@v4 + with: + path: ./dist/pymeos_cffi-*.tar.gz + + build_wheels: name: Build PyMEOS CFFI for ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: @@ -22,16 +43,6 @@ jobs: ld_path: "/opt/homebrew/lib" steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Get dependencies from apt (cache) - uses: awalsh128/cache-apt-pkgs-action@latest - if: runner.os == 'Linux' - with: - packages: build-essential cmake postgresql-server-dev-14 libproj-dev libjson-c-dev libgsl-dev libgeos-dev - version: 1.0 - - name: Update brew if: matrix.os == 'macos-13' # Necessary to avoid issue with macOS runners. See @@ -48,10 +59,12 @@ jobs: tools: cmake libpq proj json-c gsl geos - name: Fetch MEOS sources + if: runner.os == 'macOS' run: | git clone --depth 1 https://github.com/MobilityDB/MobilityDB - name: Install MEOS + if: runner.os == 'macOS' run: | mkdir MobilityDB/build cd MobilityDB/build @@ -59,8 +72,8 @@ jobs: make -j sudo make install - # Used to host cibuildwheel - - uses: actions/setup-python@v3 + - name: Setup Python + uses: actions/setup-python@v5 - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.17.0 @@ -71,8 +84,19 @@ jobs: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_path }} export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} python -m cibuildwheel --output-dir wheelhouse - # to supply options, put them in 'env', like: env: + CIBW_BEFORE_ALL_LINUX: " + yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm + yum -y update + yum -y install gcc gcc-c++ make cmake postgresql13-devel proj81-devel json-c-devel geos39-devel gsl-devel + git clone https://github.com/MobilityDB/MobilityDB + mkdir MobilityDB/build + cd MobilityDB/build + cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=/usr/proj81/include/ -DPROJ_LIBRARIES=/usr/proj81/lib/libproj.so + make -j + make install + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib + " CIBW_TEST_COMMAND: "from pymeos_cffi import meos_initialize, meos_finalize; meos_initialize('UTC'); meos_finalize()" - uses: actions/upload-artifact@v4 From b11f880a9e80315405f2839f42b1be10b045c9e0 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:15:10 +0200 Subject: [PATCH 07/36] Set working directory of build_sdist steps --- .github/workflows/build_pymeos_cffi.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index ec11d0b7..07c13de5 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -20,8 +20,10 @@ jobs: python-version: 3.8 - name: Check metadata + working-directory: pymeos_cffi run: "python setup.py check" - name: Build sdist + working-directory: pymeos_cffi run: | python setup.py sdist ls -l dist @@ -101,5 +103,5 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + name: cibw-wheels-${{ matrix.os }} path: ./wheelhouse/*.whl From 30e2d7ba9c63c1c509aa4be211bf1654e9131863 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:19:30 +0200 Subject: [PATCH 08/36] Add checkout in build_wheels --- .github/workflows/build_pymeos_cffi.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 07c13de5..d9b67c3a 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -13,7 +13,9 @@ jobs: name: Build PyMEOS CFFI source distribution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 + - uses: actions/setup-python@v5 name: Install Python with: @@ -22,6 +24,7 @@ jobs: - name: Check metadata working-directory: pymeos_cffi run: "python setup.py check" + - name: Build sdist working-directory: pymeos_cffi run: | @@ -45,6 +48,9 @@ jobs: ld_path: "/opt/homebrew/lib" steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Update brew if: matrix.os == 'macos-13' # Necessary to avoid issue with macOS runners. See From 74dd8b6e42cb9a91043127ec44a09f69d6dc46a4 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:45:42 +0200 Subject: [PATCH 09/36] Fix cibw linux script --- .github/workflows/build_pymeos_cffi.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index d9b67c3a..24a709fd 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -95,15 +95,15 @@ jobs: env: CIBW_BEFORE_ALL_LINUX: " yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm - yum -y update - yum -y install gcc gcc-c++ make cmake postgresql13-devel proj81-devel json-c-devel geos39-devel gsl-devel - git clone https://github.com/MobilityDB/MobilityDB - mkdir MobilityDB/build - cd MobilityDB/build - cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=/usr/proj81/include/ -DPROJ_LIBRARIES=/usr/proj81/lib/libproj.so - make -j - make install - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib + && yum -y update + && yum -y install gcc gcc-c++ make cmake postgresql13-devel proj81-devel json-c-devel geos39-devel gsl-devel + && git clone https://github.com/MobilityDB/MobilityDB + && mkdir MobilityDB/build + && cd MobilityDB/build + && cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=/usr/proj81/include/ -DPROJ_LIBRARIES=/usr/proj81/lib/libproj.so + && make -j + && make install + && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib " CIBW_TEST_COMMAND: "from pymeos_cffi import meos_initialize, meos_finalize; meos_initialize('UTC'); meos_finalize()" From f98a9402a4f1844116a1b0eb27c90399adc9ec2e Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:49:26 +0200 Subject: [PATCH 10/36] Fix test command --- .github/workflows/build_pymeos_cffi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 24a709fd..c4b56cd1 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -105,7 +105,7 @@ jobs: && make install && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib " - CIBW_TEST_COMMAND: "from pymeos_cffi import meos_initialize, meos_finalize; meos_initialize('UTC'); meos_finalize()" + CIBW_TEST_COMMAND: "python -c \"from pymeos_cffi import meos_initialize, meos_finalize; meos_initialize('UTC'); meos_finalize()\"" - uses: actions/upload-artifact@v4 with: From 19fb8a729287c4f031dfaa5311537d1799d6b284 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:51:39 +0200 Subject: [PATCH 11/36] Add log in sdist --- .github/workflows/build_pymeos_cffi.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index c4b56cd1..1fd3ef46 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -28,6 +28,8 @@ jobs: - name: Build sdist working-directory: pymeos_cffi run: | + pwd + ls -l python setup.py sdist ls -l dist From 31177b8bb1d5c6c687887ce8201e31a748d1f02f Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:54:43 +0200 Subject: [PATCH 12/36] Use proper build command for sdist --- .github/workflows/build_pymeos_cffi.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 1fd3ef46..61991ac9 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -21,16 +21,10 @@ jobs: with: python-version: 3.8 - - name: Check metadata - working-directory: pymeos_cffi - run: "python setup.py check" - - name: Build sdist working-directory: pymeos_cffi run: | - pwd - ls -l - python setup.py sdist + python -m build -s ls -l dist - uses: actions/upload-artifact@v4 From 908e588f26ad30b5e2a0fd9e17c13a4763d2482e Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 19:58:31 +0200 Subject: [PATCH 13/36] Install build module --- .github/workflows/build_pymeos_cffi.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 61991ac9..1db5ce14 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -16,10 +16,16 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - name: Install Python + - name: Install Python + uses: actions/setup-python@v5 with: python-version: 3.8 + cache: "pip" + + - name: Setup pip + run: | + python -m pip install --upgrade pip + python -m pip install build - name: Build sdist working-directory: pymeos_cffi From b4430c128c5b36548e9e1437da01de79b67282c1 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 20:02:09 +0200 Subject: [PATCH 14/36] Fix artifact path for sdist --- .github/workflows/build_pymeos_cffi.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 1db5ce14..2d0917c9 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -35,9 +35,10 @@ jobs: - uses: actions/upload-artifact@v4 with: - path: ./dist/pymeos_cffi-*.tar.gz + path: ./pymeos_cffi/dist/pymeos_cffi-*.tar.gz build_wheels: + if: false name: Build PyMEOS CFFI for ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: From c0384dbf3b247491834ec5b2078898ef0321e20f Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 20:38:10 +0200 Subject: [PATCH 15/36] Fix wheel artifact folder --- .github/workflows/build_pymeos_cffi.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 2d0917c9..8018f8c0 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -38,7 +38,6 @@ jobs: path: ./pymeos_cffi/dist/pymeos_cffi-*.tar.gz build_wheels: - if: false name: Build PyMEOS CFFI for ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: @@ -113,4 +112,4 @@ jobs: - uses: actions/upload-artifact@v4 with: name: cibw-wheels-${{ matrix.os }} - path: ./wheelhouse/*.whl + path: ./pymeos_cffi/wheelhouse/*.whl From bd5b30e5584a2ec6f3585218162ad97a47c3a5ed Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 20:45:34 +0200 Subject: [PATCH 16/36] Skip PyPy builds on linux --- .github/workflows/build_pymeos_cffi.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 8018f8c0..826c03fb 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -95,6 +95,7 @@ jobs: export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} python -m cibuildwheel --output-dir wheelhouse env: + CIBW_SKIP: "pp*-manylinux*" # Disable PyPy builds on Linux since shapely has no built distributions for them CIBW_BEFORE_ALL_LINUX: " yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm && yum -y update From 1f8514ad310a672ae22d66c30eebe2b366dd21f5 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 20:52:03 +0200 Subject: [PATCH 17/36] Add logs --- .github/workflows/build_pymeos_cffi.yml | 3 ++- pymeos_cffi/pymeos_cffi/builder/build_pymeos.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 826c03fb..b303d383 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -43,7 +43,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ ubuntu-latest, macos-13, macos-14 ] +# os: [ ubuntu-latest, macos-13, macos-14 ] + os: [ macos-14 ] include: - ld_path: "/usr/local/lib" - os: macos-14 diff --git a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py index 0ffb0d4e..10e997ab 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py @@ -43,5 +43,8 @@ def get_include_dirs(): include_dirs=get_include_dirs(), ) # library name, for the linker +print(f"get_library_dirs: {get_library_dirs()}") +print(f"get_include_dirs: {get_include_dirs()}") + if __name__ == "__main__": # not when running with setuptools ffibuilder.compile(verbose=True) From d700f1b46e3413c5f30f0329a5ab4d9c05bbe95a Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 20:55:52 +0200 Subject: [PATCH 18/36] Update library and include dir functions to check for existence of paths rather than os and architecture --- .github/workflows/build_pymeos_cffi.yml | 3 +- .../pymeos_cffi/builder/build_pymeos.py | 32 +++++++------------ 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index b303d383..826c03fb 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -43,8 +43,7 @@ jobs: strategy: fail-fast: false matrix: -# os: [ ubuntu-latest, macos-13, macos-14 ] - os: [ macos-14 ] + os: [ ubuntu-latest, macos-13, macos-14 ] include: - ld_path: "/usr/local/lib" - os: macos-14 diff --git a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py index 10e997ab..0f3e235e 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py @@ -1,3 +1,4 @@ +import os import platform import sys @@ -12,27 +13,19 @@ def get_library_dirs(): - if sys.platform == "linux": - return ["/usr/local/lib"] - elif sys.platform == "darwin": - if platform.processor() == "arm": - return ["/opt/homebrew/lib"] - else: - return ["/usr/local/lib"] - else: - raise NotImplementedError("Unsupported platform") + paths = [ + "/usr/local/lib", + "/opt/homebrew/lib" + ] + return [path for path in paths if os.path.exists(path)] def get_include_dirs(): - if sys.platform == "linux": - return ["/usr/local/include"] - elif sys.platform == "darwin": - if platform.processor() == "arm": - return ["/opt/homebrew/include"] - else: - return ["/usr/local/include"] - else: - raise NotImplementedError("Unsupported platform") + paths = [ + "/usr/local/include", + "/opt/homebrew/include" + ] + return [path for path in paths if os.path.exists(path)] ffibuilder.set_source( @@ -43,8 +36,5 @@ def get_include_dirs(): include_dirs=get_include_dirs(), ) # library name, for the linker -print(f"get_library_dirs: {get_library_dirs()}") -print(f"get_include_dirs: {get_include_dirs()}") - if __name__ == "__main__": # not when running with setuptools ffibuilder.compile(verbose=True) From 5596e2632c880b980406a6cf31e7c0f5648f52ff Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:07:44 +0200 Subject: [PATCH 19/36] Merge macOS MEOS steps. --- .github/workflows/build_pymeos_cffi.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 826c03fb..d3671062 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -68,14 +68,10 @@ jobs: with: tools: cmake libpq proj json-c gsl geos - - name: Fetch MEOS sources - if: runner.os == 'macOS' - run: | - git clone --depth 1 https://github.com/MobilityDB/MobilityDB - - name: Install MEOS if: runner.os == 'macOS' run: | + git clone --depth 1 https://github.com/MobilityDB/MobilityDB mkdir MobilityDB/build cd MobilityDB/build cmake .. -DMEOS=on @@ -96,6 +92,7 @@ jobs: python -m cibuildwheel --output-dir wheelhouse env: CIBW_SKIP: "pp*-manylinux*" # Disable PyPy builds on Linux since shapely has no built distributions for them + CIBW_ARCHS_LINUX: "x86_64 aarch64" CIBW_BEFORE_ALL_LINUX: " yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm && yum -y update From 7f4c02285c1a461b9325bc48f04d1cc853a9fd9f Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:08:09 +0200 Subject: [PATCH 20/36] Add QEMU to compile for aarch64 --- .github/workflows/build_pymeos_cffi.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index d3671062..4622fe7f 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -78,6 +78,10 @@ jobs: make -j sudo make install + - name: Set up QEMU + if: runner.os == 'Linux' + uses: docker/setup-qemu-action@v2 + - name: Setup Python uses: actions/setup-python@v5 From f4632ee1d038e241561cd6655897f32872688362 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:08:59 +0200 Subject: [PATCH 21/36] Add wheel testing job --- .github/workflows/build_pymeos_cffi.yml | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 4622fe7f..bf566d48 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -115,3 +115,51 @@ jobs: with: name: cibw-wheels-${{ matrix.os }} path: ./pymeos_cffi/wheelhouse/*.whl + + test_wheels: + name: Test PyMEOS CFFI wheel - Python ${{ matrix.python-version }} on ${{ matrix.os }} + needs: build_wheels + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] + os: [ ubuntu-latest, macos-13, macos-14 ] + exclude: + # Necessary due to issue with macOS runners. See + # https://github.com/actions/setup-python/issues/808 + # Can be removed once this PR is merged: + # https://github.com/actions/python-versions/pull/259 + - os: macos-14 + python-version: "3.8" + - os: macos-14 + python-version: "3.9" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download wheels + uses: actions/download-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }} + path: ./pymeos_cffi_wheels + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + + - name: Install PyMEOS dependencies + run: | + python -m pip install --upgrade pip + pip install -f ./pymeos_cffi_wheels pymeos_cffi + pip install -r pymeos/dev-requirements.txt + + - name: Test PyMEOS with pytest + working-directory: pymeos + run: | + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_path }} + export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} + pytest From 9e8f88daec8f87ccf9693d606ed6612128cb41b6 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:09:47 +0200 Subject: [PATCH 22/36] Remove LD exports from pytest step --- .github/workflows/build_pymeos_cffi.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index bf566d48..a527dc19 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -159,7 +159,4 @@ jobs: - name: Test PyMEOS with pytest working-directory: pymeos - run: | - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_path }} - export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} - pytest + run: pytest From 0e3632b6ac97b320c76eb743d283dcc6e8ee66bd Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:23:17 +0200 Subject: [PATCH 23/36] Add upload to pypi job --- .github/workflows/build_pymeos_cffi.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index a527dc19..9fbb91ce 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -160,3 +160,20 @@ jobs: - name: Test PyMEOS with pytest working-directory: pymeos run: pytest + + upload_pypi: + name: Upload to PyPI + needs: [ test_wheels, build_sdist ] + runs-on: ubuntu-22.04 + steps: + - uses: actions/download-artifact@v4 + with: + path: ./dist + merge-multiple: true + + - uses: pypa/gh-action-pypi-publish@v1 + with: + user: __token__ + password: ${{ secrets.TEST_PYPI_API_TOKEN }} + repository_url: https://test.pypi.org/legacy/ + skip_existing: true From 11884cca27e20f9900ca9f265dee1ec91e13fccd Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:23:39 +0200 Subject: [PATCH 24/36] Remove aarch64 for linux --- .github/workflows/build_pymeos_cffi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 9fbb91ce..10258f83 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -96,7 +96,7 @@ jobs: python -m cibuildwheel --output-dir wheelhouse env: CIBW_SKIP: "pp*-manylinux*" # Disable PyPy builds on Linux since shapely has no built distributions for them - CIBW_ARCHS_LINUX: "x86_64 aarch64" + CIBW_ARCHS_LINUX: "x86_64" CIBW_BEFORE_ALL_LINUX: " yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm && yum -y update From 27d78387bf80cd6534e31bfc0140e2b85c441119 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:31:12 +0200 Subject: [PATCH 25/36] Create GitHub Release job --- .github/workflows/build_pymeos_cffi.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 10258f83..802ad61c 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -177,3 +177,18 @@ jobs: password: ${{ secrets.TEST_PYPI_API_TOKEN }} repository_url: https://test.pypi.org/legacy/ skip_existing: true + + create_release: + name: Create GitHub Release + needs: [ test_wheels, build_sdist ] + runs-on: ubuntu-22.04 + steps: + - uses: actions/download-artifact@v4 + with: + path: ./dist + merge-multiple: true + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: ./dist/* \ No newline at end of file From 379e987d768e4b0826794022366313ac56085965 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:35:08 +0200 Subject: [PATCH 26/36] Disable musllinux builds --- .github/workflows/build_pymeos_cffi.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 802ad61c..989bebf2 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -95,7 +95,10 @@ jobs: export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} python -m cibuildwheel --output-dir wheelhouse env: - CIBW_SKIP: "pp*-manylinux*" # Disable PyPy builds on Linux since shapely has no built distributions for them + # Disable PyPy builds on Linux since shapely has no built distributions for them + # Disable builds on musllinux + # Disable builds in linux architectures other than x86_64 + CIBW_SKIP: "pp*-manylinux* *musllinux*" CIBW_ARCHS_LINUX: "x86_64" CIBW_BEFORE_ALL_LINUX: " yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm From 64cd3a8d893300ef145000e2fcecbb1af8572774 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Fri, 12 Apr 2024 22:41:44 +0200 Subject: [PATCH 27/36] Remove QEMU since no cross-compilation is being done anymore --- .github/workflows/build_pymeos_cffi.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 989bebf2..651c8a36 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -78,10 +78,6 @@ jobs: make -j sudo make install - - name: Set up QEMU - if: runner.os == 'Linux' - uses: docker/setup-qemu-action@v2 - - name: Setup Python uses: actions/setup-python@v5 From aa711ea4101a1f9592a3a2431eca8258a8c4089d Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 09:39:45 +0200 Subject: [PATCH 28/36] Copy PROJ data in setup.py when PACKAGE_DATA is set to be able to generate self-contained wheels --- pymeos_cffi/setup.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pymeos_cffi/setup.py b/pymeos_cffi/setup.py index 8d234f42..1eb8675e 100644 --- a/pymeos_cffi/setup.py +++ b/pymeos_cffi/setup.py @@ -1,7 +1,36 @@ +import os +import shutil + from setuptools import setup + +def copy_data_tree(source, destination): + try: + shutil.rmtree(destination) + except OSError: + pass + shutil.copytree(source, destination) + + +package_data = [] + +# Conditionally copy PROJ DATA to make self-contained wheels +if os.environ.get("PACKAGE_DATA"): + projdatadir = os.environ.get( + "PROJ_DATA", os.environ.get("PROJ_LIB", "/usr/local/share/proj") + ) + if os.path.exists(projdatadir): + copy_data_tree(projdatadir, "pymeos_cffi/proj_data") + else: + raise FileNotFoundError( + f"PROJ data directory not found at {projdatadir}. " + f"Unable to generate self-contained wheel." + ) + package_data.append("proj_data/*") + setup( packages=["pymeos_cffi", "pymeos_cffi.builder"], setup_requires=["cffi"], + package_data={"pymeos_cffi": package_data}, cffi_modules=["pymeos_cffi/builder/build_pymeos.py:ffibuilder"], ) From ecf6cab88782410c1463bc74b62c880892e57297 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 09:40:28 +0200 Subject: [PATCH 29/36] Pin PROJ versions and set necessary env variables to add proj data to built wheels --- .github/workflows/build_pymeos_cffi.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 651c8a36..b87b525b 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -45,9 +45,18 @@ jobs: matrix: os: [ ubuntu-latest, macos-13, macos-14 ] include: - - ld_path: "/usr/local/lib" + - os: ubuntu-latest + ld_path: "/usr/local/lib" + proj_package: "proj81" + proj_dir: "/usr/proj81" # PROJ 8.1 latest available in manylinux2014 images + - os: macos-13 + ld_path: "/usr/local/lib" + proj_package: "proj@9.4.0" + proj_dir: "/usr/local/Cellar/proj/9.4.0" - os: macos-14 ld_path: "/opt/homebrew/lib" + proj_package: "proj@9.4.0" + proj_dir: "opt/homebrew/Cellar/proj/9.4.0" steps: - name: Checkout @@ -66,7 +75,7 @@ jobs: uses: tecolicom/actions-use-homebrew-tools@v1 if: runner.os == 'macOS' with: - tools: cmake libpq proj json-c gsl geos + tools: cmake libpq ${{ matrix.proj_package }} json-c gsl geos - name: Install MEOS if: runner.os == 'macOS' @@ -89,6 +98,8 @@ jobs: run: | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_path }} export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} + export PROJ_DATA=${{ matrix.proj_dir }}/share/proj + export PACKAGE_DATA=1 python -m cibuildwheel --output-dir wheelhouse env: # Disable PyPy builds on Linux since shapely has no built distributions for them @@ -99,11 +110,13 @@ jobs: CIBW_BEFORE_ALL_LINUX: " yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm && yum -y update - && yum -y install gcc gcc-c++ make cmake postgresql13-devel proj81-devel json-c-devel geos39-devel gsl-devel + && yum -y install gcc gcc-c++ make cmake postgresql13-devel ${{ matrix.proj_package }}-devel json-c-devel geos39-devel gsl-devel + && export PROJ_DATA=${{ matrix.proj_dir }}/share/proj + && export PACKAGE_DATA=1 && git clone https://github.com/MobilityDB/MobilityDB && mkdir MobilityDB/build && cd MobilityDB/build - && cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=/usr/proj81/include/ -DPROJ_LIBRARIES=/usr/proj81/lib/libproj.so + && cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=${{ matrix.proj_dir }}/include/ -DPROJ_LIBRARIES=${{ matrix.proj_dir }}/lib/libproj.so && make -j && make install && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib From 14459f2dbe31e84f557b354ffbd146319a0fa289 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 09:47:33 +0200 Subject: [PATCH 30/36] Set PROJ_DATA and PROJ_LIB in meos_initialize if they are undefined Set PROJ_DATA env variables before build wheels step Update PROJ data copy to ignore .tif and .txt files Rename artifacts Fix PROJ_DATA prefix in arm osx Set proj_version dynamically --- .github/workflows/build_pymeos_cffi.yml | 72 +++++++++++-------- .../pymeos_cffi/builder/build_pymeos.py | 14 +--- .../build_pymeos_functions_modifiers.py | 7 ++ .../builder/templates/functions.py | 2 + pymeos_cffi/pymeos_cffi/functions.py | 8 +++ pymeos_cffi/setup.py | 19 ++--- 6 files changed, 71 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index b87b525b..490b6308 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -4,6 +4,7 @@ on: push: branches: - build-actions + - fix-proj-pinning create: tags: - "pymeos-cffi-[0-9]+.[0-9]+.[0-9]+*" @@ -35,6 +36,7 @@ jobs: - uses: actions/upload-artifact@v4 with: + name: pymeos_cffi-sdist path: ./pymeos_cffi/dist/pymeos_cffi-*.tar.gz build_wheels: @@ -45,18 +47,9 @@ jobs: matrix: os: [ ubuntu-latest, macos-13, macos-14 ] include: - - os: ubuntu-latest - ld_path: "/usr/local/lib" - proj_package: "proj81" - proj_dir: "/usr/proj81" # PROJ 8.1 latest available in manylinux2014 images - - os: macos-13 - ld_path: "/usr/local/lib" - proj_package: "proj@9.4.0" - proj_dir: "/usr/local/Cellar/proj/9.4.0" + - ld_prefix: "/usr/local" - os: macos-14 - ld_path: "/opt/homebrew/lib" - proj_package: "proj@9.4.0" - proj_dir: "opt/homebrew/Cellar/proj/9.4.0" + ld_prefix: "/opt/homebrew" steps: - name: Checkout @@ -75,7 +68,15 @@ jobs: uses: tecolicom/actions-use-homebrew-tools@v1 if: runner.os == 'macOS' with: - tools: cmake libpq ${{ matrix.proj_package }} json-c gsl geos + tools: cmake libpq proj json-c gsl geos + + - name: Get PROJ version + id: proj_version + if: runner.os == 'macOS' + run: | + proj_version=$(brew list --versions proj) + proj_version=${proj_version#* } + echo "proj_version=$proj_version" >> $GITHUB_OUTPUT - name: Install MEOS if: runner.os == 'macOS' @@ -93,12 +94,23 @@ jobs: - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.17.0 + - name: Set PROJ_DATA (macOS) + if: runner.os == 'macOS' + run: | + PROJ_DATA=${{ matrix.ld_prefix }}/Cellar/proj/${{ steps.proj_version.outputs.proj_version }}/share/proj + echo "PROJ_DATA=$PROJ_DATA" >> $GITHUB_ENV + + - name: Set PROJ_DATA (Linux) + if: runner.os == 'Linux' + run: | + PROJ_DATA=/usr/proj81/share/proj + echo "PROJ_DATA=$PROJ_DATA" >> $GITHUB_ENV + - name: Build wheels working-directory: pymeos_cffi run: | - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_path }} - export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_path }} - export PROJ_DATA=${{ matrix.proj_dir }}/share/proj + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ matrix.ld_prefix }}/lib + export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${{ matrix.ld_prefix }}/lib export PACKAGE_DATA=1 python -m cibuildwheel --output-dir wheelhouse env: @@ -107,25 +119,23 @@ jobs: # Disable builds in linux architectures other than x86_64 CIBW_SKIP: "pp*-manylinux* *musllinux*" CIBW_ARCHS_LINUX: "x86_64" - CIBW_BEFORE_ALL_LINUX: " - yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm - && yum -y update - && yum -y install gcc gcc-c++ make cmake postgresql13-devel ${{ matrix.proj_package }}-devel json-c-devel geos39-devel gsl-devel - && export PROJ_DATA=${{ matrix.proj_dir }}/share/proj - && export PACKAGE_DATA=1 - && git clone https://github.com/MobilityDB/MobilityDB - && mkdir MobilityDB/build - && cd MobilityDB/build - && cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=${{ matrix.proj_dir }}/include/ -DPROJ_LIBRARIES=${{ matrix.proj_dir }}/lib/libproj.so - && make -j - && make install - && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib - " + CIBW_ENVIRONMENT_PASS_LINUX: PACKAGE_DATA LD_LIBRARY_PATH PROJ_DATA + CIBW_BEFORE_ALL_LINUX: > + yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm && + yum -y update && + yum -y install gcc gcc-c++ make cmake postgresql13-devel proj81-devel json-c-devel geos39-devel gsl-devel && + git clone https://github.com/MobilityDB/MobilityDB && + mkdir MobilityDB/build && + cd MobilityDB/build && + cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=/usr/proj81/include/ -DPROJ_LIBRARIES=/usr/proj81/lib/libproj.so && + make -j && + make install + CIBW_TEST_COMMAND: "python -c \"from pymeos_cffi import meos_initialize, meos_finalize; meos_initialize('UTC'); meos_finalize()\"" - uses: actions/upload-artifact@v4 with: - name: cibw-wheels-${{ matrix.os }} + name: pymeos_cffi-wheels-${{ matrix.os }} path: ./pymeos_cffi/wheelhouse/*.whl test_wheels: @@ -154,7 +164,7 @@ jobs: - name: Download wheels uses: actions/download-artifact@v4 with: - name: cibw-wheels-${{ matrix.os }} + name: pymeos_cffi-wheels-${{ matrix.os }} path: ./pymeos_cffi_wheels - name: Set up Python ${{ matrix.python-version }} diff --git a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py index 0f3e235e..92a2bc35 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py @@ -1,6 +1,4 @@ import os -import platform -import sys from cffi import FFI @@ -13,18 +11,12 @@ def get_library_dirs(): - paths = [ - "/usr/local/lib", - "/opt/homebrew/lib" - ] + paths = ["/usr/local/lib", "/opt/homebrew/lib"] return [path for path in paths if os.path.exists(path)] def get_include_dirs(): - paths = [ - "/usr/local/include", - "/opt/homebrew/include" - ] + paths = ["/usr/local/include", "/opt/homebrew/include"] return [path for path in paths if os.path.exists(path)] @@ -34,7 +26,7 @@ def get_include_dirs(): libraries=["meos"], library_dirs=get_library_dirs(), include_dirs=get_include_dirs(), -) # library name, for the linker +) if __name__ == "__main__": # not when running with setuptools ffibuilder.compile(verbose=True) diff --git a/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py b/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py index 2cf1093e..82c7b2c1 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py @@ -42,6 +42,13 @@ def textset_make_modifier(function: str) -> str: def meos_initialize_modifier(_: str) -> str: return """def meos_initialize(tz_str: "Optional[str]") -> None: + + if "PROJ_DATA" not in os.environ and "PROJ_LIB" not in os.environ: + # Assume we are in a wheel and the PROJ data is in the package + proj_dir = os.path.join(os.path.dirname(__file__), "proj_data") + os.environ["PROJ_DATA"] = proj_dir + os.environ["PROJ_LIB"] = proj_dir + tz_str_converted = tz_str.encode('utf-8') if tz_str is not None else _ffi.NULL _lib.meos_initialize(tz_str_converted, _lib.py_error_handler)""" diff --git a/pymeos_cffi/pymeos_cffi/builder/templates/functions.py b/pymeos_cffi/pymeos_cffi/builder/templates/functions.py index 992dfd74..e79c4f88 100644 --- a/pymeos_cffi/pymeos_cffi/builder/templates/functions.py +++ b/pymeos_cffi/pymeos_cffi/builder/templates/functions.py @@ -1,4 +1,6 @@ import logging +import os + from datetime import datetime, timedelta, date from typing import Any, Tuple, Optional, List diff --git a/pymeos_cffi/pymeos_cffi/functions.py b/pymeos_cffi/pymeos_cffi/functions.py index c50e0ff5..4151409a 100644 --- a/pymeos_cffi/pymeos_cffi/functions.py +++ b/pymeos_cffi/pymeos_cffi/functions.py @@ -1,4 +1,6 @@ import logging +import os + from datetime import datetime, timedelta, date from typing import Any, Tuple, Optional, List @@ -203,6 +205,12 @@ def meos_get_intervalstyle() -> str: def meos_initialize(tz_str: "Optional[str]") -> None: + if "PROJ_DATA" not in os.environ and "PROJ_LIB" not in os.environ: + # Assume we are in a wheel and the PROJ data is in the package + proj_dir = os.path.join(os.path.dirname(__file__), "proj_data") + os.environ["PROJ_DATA"] = proj_dir + os.environ["PROJ_LIB"] = proj_dir + tz_str_converted = tz_str.encode("utf-8") if tz_str is not None else _ffi.NULL _lib.meos_initialize(tz_str_converted, _lib.py_error_handler) diff --git a/pymeos_cffi/setup.py b/pymeos_cffi/setup.py index 1eb8675e..7681da29 100644 --- a/pymeos_cffi/setup.py +++ b/pymeos_cffi/setup.py @@ -4,33 +4,34 @@ from setuptools import setup -def copy_data_tree(source, destination): - try: - shutil.rmtree(destination) - except OSError: - pass - shutil.copytree(source, destination) - - package_data = [] # Conditionally copy PROJ DATA to make self-contained wheels if os.environ.get("PACKAGE_DATA"): + print("Copying PROJ data to package data") projdatadir = os.environ.get( "PROJ_DATA", os.environ.get("PROJ_LIB", "/usr/local/share/proj") ) if os.path.exists(projdatadir): - copy_data_tree(projdatadir, "pymeos_cffi/proj_data") + shutil.rmtree("pymeos_cffi/proj_data", ignore_errors=True) + shutil.copytree( + projdatadir, + "pymeos_cffi/proj_data", + ignore=shutil.ignore_patterns("*.txt", "*.tif"), + ) # Don't copy .tiff files and their related .txt files else: raise FileNotFoundError( f"PROJ data directory not found at {projdatadir}. " f"Unable to generate self-contained wheel." ) package_data.append("proj_data/*") +else: + print("Not copying PROJ data to package data") setup( packages=["pymeos_cffi", "pymeos_cffi.builder"], setup_requires=["cffi"], + include_package_data=True, package_data={"pymeos_cffi": package_data}, cffi_modules=["pymeos_cffi/builder/build_pymeos.py:ffibuilder"], ) From 3aa841124a84374a23a45ecf13ba259a473857fc Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 16:18:26 +0200 Subject: [PATCH 31/36] Build json-c from sources to get version 0.17 instead of default version 0.11 --- .github/workflows/build_pymeos_cffi.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 490b6308..1f80a469 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -123,8 +123,14 @@ jobs: CIBW_BEFORE_ALL_LINUX: > yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm && yum -y update && - yum -y install gcc gcc-c++ make cmake postgresql13-devel proj81-devel json-c-devel geos39-devel gsl-devel && - git clone https://github.com/MobilityDB/MobilityDB && + yum -y install gcc gcc-c++ make cmake postgresql13-devel proj81-devel geos39-devel gsl-devel && + git clone --branch json-c-0.17 --depth 1 https://github.com/json-c/json-c && + mkdir json-c-build && + cd json-c-build && + cmake ../json-c && + make && + make install && + git clone --depth 1 https://github.com/MobilityDB/MobilityDB && mkdir MobilityDB/build && cd MobilityDB/build && cmake .. -DMEOS=on -DGEOS_INCLUDE_DIR=/usr/geos39/include/ -DGEOS_LIBRARY=/usr/geos39/lib64/libgeos_c.so -DGEOS_CONFIG=/usr/geos39/bin/geos-config -DPROJ_INCLUDE_DIRS=/usr/proj81/include/ -DPROJ_LIBRARIES=/usr/proj81/lib/libproj.so && From b6e18a799c14d0cd0860ba761765e1013f37808c Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 16:28:32 +0200 Subject: [PATCH 32/36] Add json-c path to env for linux --- .github/workflows/build_pymeos_cffi.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 1f80a469..21c3d342 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -100,11 +100,12 @@ jobs: PROJ_DATA=${{ matrix.ld_prefix }}/Cellar/proj/${{ steps.proj_version.outputs.proj_version }}/share/proj echo "PROJ_DATA=$PROJ_DATA" >> $GITHUB_ENV - - name: Set PROJ_DATA (Linux) + - name: Set PROJ_DATA and JSON-C path (Linux) if: runner.os == 'Linux' run: | PROJ_DATA=/usr/proj81/share/proj echo "PROJ_DATA=$PROJ_DATA" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64" >> $GITHUB_ENV - name: Build wheels working-directory: pymeos_cffi From 49fc7f5bd4144122a778979b4d01e9424a4df36c Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 16:58:21 +0200 Subject: [PATCH 33/36] Fix pypi publish action name --- .github/workflows/build_pymeos_cffi.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 21c3d342..6eaf8b2d 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -1,10 +1,6 @@ name: Build PyMEOS CFFI on: - push: - branches: - - build-actions - - fix-proj-pinning create: tags: - "pymeos-cffi-[0-9]+.[0-9]+.[0-9]+*" @@ -200,7 +196,7 @@ jobs: path: ./dist merge-multiple: true - - uses: pypa/gh-action-pypi-publish@v1 + - uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.TEST_PYPI_API_TOKEN }} From d5d71ec7ec96aaf36e3d2ea74e51c05d8e54870e Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 21:23:18 +0200 Subject: [PATCH 34/36] Only set PROJ_DATA if proj_data folder exists (only whould exist on a wheel) --- .../builder/build_pymeos_functions_modifiers.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py b/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py index 82c7b2c1..7dcd98b5 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_pymeos_functions_modifiers.py @@ -44,10 +44,11 @@ def meos_initialize_modifier(_: str) -> str: return """def meos_initialize(tz_str: "Optional[str]") -> None: if "PROJ_DATA" not in os.environ and "PROJ_LIB" not in os.environ: - # Assume we are in a wheel and the PROJ data is in the package proj_dir = os.path.join(os.path.dirname(__file__), "proj_data") - os.environ["PROJ_DATA"] = proj_dir - os.environ["PROJ_LIB"] = proj_dir + if os.path.exists(proj_dir): + # Assume we are in a wheel and the PROJ data is in the package + os.environ["PROJ_DATA"] = proj_dir + os.environ["PROJ_LIB"] = proj_dir tz_str_converted = tz_str.encode('utf-8') if tz_str is not None else _ffi.NULL _lib.meos_initialize(tz_str_converted, _lib.py_error_handler)""" From aabf94d0c4181696bfff1869cd0bdabdb1483cd7 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Sat, 13 Apr 2024 22:14:00 +0200 Subject: [PATCH 35/36] Use real pypi server to make build releases --- .github/workflows/build_pymeos_cffi.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 6eaf8b2d..309843ab 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -86,6 +86,9 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 + with: + python-version: 3.8 + cache: "pip" - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.17.0 @@ -200,7 +203,6 @@ jobs: with: user: __token__ password: ${{ secrets.TEST_PYPI_API_TOKEN }} - repository_url: https://test.pypi.org/legacy/ skip_existing: true create_release: From e0e3d79d91632f156d97f81818d2a2cc224e1995 Mon Sep 17 00:00:00 2001 From: Diviloper Date: Mon, 15 Apr 2024 18:50:35 +0200 Subject: [PATCH 36/36] Run PyPI step only on MobilityDB/PyMEOS repo --- .github/workflows/build_pymeos_cffi.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml index 309843ab..303b821d 100644 --- a/.github/workflows/build_pymeos_cffi.yml +++ b/.github/workflows/build_pymeos_cffi.yml @@ -193,6 +193,7 @@ jobs: name: Upload to PyPI needs: [ test_wheels, build_sdist ] runs-on: ubuntu-22.04 + if: github.repository == 'MobilityDB/PyMEOS' steps: - uses: actions/download-artifact@v4 with: