diff --git a/.github/workflows/build_pymeos_cffi.yml b/.github/workflows/build_pymeos_cffi.yml new file mode 100644 index 00000000..303b821d --- /dev/null +++ b/.github/workflows/build_pymeos_cffi.yml @@ -0,0 +1,222 @@ +name: Build PyMEOS CFFI + +on: + create: + tags: + - "pymeos-cffi-[0-9]+.[0-9]+.[0-9]+*" + +jobs: + build_sdist: + name: Build PyMEOS CFFI source distribution + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - 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 + run: | + python -m build -s + ls -l dist + + - uses: actions/upload-artifact@v4 + with: + name: pymeos_cffi-sdist + path: ./pymeos_cffi/dist/pymeos_cffi-*.tar.gz + + build_wheels: + 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_prefix: "/usr/local" + - os: macos-14 + ld_prefix: "/opt/homebrew" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - 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: 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' + run: | + git clone --depth 1 https://github.com/MobilityDB/MobilityDB + mkdir MobilityDB/build + cd MobilityDB/build + cmake .. -DMEOS=on + make -j + sudo make install + + - 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 + + - 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 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 + run: | + 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: + # 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_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 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 && + 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: pymeos_cffi-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: pymeos_cffi-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: pytest + + upload_pypi: + 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: + path: ./dist + merge-multiple: true + + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.TEST_PYPI_API_TOKEN }} + 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 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..92a2bc35 100644 --- a/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py +++ b/pymeos_cffi/pymeos_cffi/builder/build_pymeos.py @@ -1,5 +1,4 @@ -import platform -import sys +import os from cffi import FFI @@ -12,15 +11,13 @@ 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(): + paths = ["/usr/local/include", "/opt/homebrew/include"] + return [path for path in paths if os.path.exists(path)] ffibuilder.set_source( @@ -28,7 +25,8 @@ def get_library_dirs(): '#include "meos.h"\n' '#include "meos_catalog.h"\n' '#include "meos_internal.h"', libraries=["meos"], library_dirs=get_library_dirs(), -) # library name, for the linker + include_dirs=get_include_dirs(), +) 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..7dcd98b5 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,14 @@ 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: + proj_dir = os.path.join(os.path.dirname(__file__), "proj_data") + 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)""" 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/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/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", 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 8d234f42..7681da29 100644 --- a/pymeos_cffi/setup.py +++ b/pymeos_cffi/setup.py @@ -1,7 +1,37 @@ +import os +import shutil + from setuptools import setup + +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): + 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"], )