Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/doc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
beautifulsoup4
shapely
geopandas
pyinterp<2026.2.0
pyinterp>=2026.4.0
dask
- name: Install package (for autodoc)
shell: bash -l {0}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
pyftpdlib
shapely
geopandas
pyinterp<2026.2.0
pyinterp>=2026.4.0
dask
- name: Install python dependencies
shell: bash -el {0}
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
pyftpdlib
shapely
geopandas
pyinterp<2026.2.0
pyinterp>=2026.4.0
dask
- name: Install python dependencies
shell: bash -el {0}
Expand Down
28 changes: 14 additions & 14 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ How to install

.. code:: bash

conda install files_collections shapely geopandas pyinterp dask numba -c conda-forge
conda install files_collections shapely geopandas 'pyinterp>=2026.4.0' dask numba -c conda-forge

This will install a set of dependencies similar to
``python -m pip install files-collections[geo]``
Expand Down Expand Up @@ -66,19 +66,19 @@ These optional dependencies and their associated functionalities are listed
below.


+--------------+-----------------------------------------------------------------------------------------+
| Dependency | Description |
+==============+=========================================================================================+
| `dask`_ | Activate ``map()`` method in collections, Enable parallel file reading |
+--------------+-----------------------------------------------------------------------------------------+
| `geopandas`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method |
+--------------+-----------------------------------------------------------------------------------------+
| `numba`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method |
+--------------+-----------------------------------------------------------------------------------------+
| `pyinterp`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method |
+--------------+-----------------------------------------------------------------------------------------+
| `shapely`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method |
+--------------+-----------------------------------------------------------------------------------------+
+--------------+-----------------------------------------------------------------------------------------+-------------+
| Dependency | Description | Version |
+==============+=========================================================================================+=============+
| `dask`_ | Activate ``map()`` method in collections, Enable parallel file reading | |
+--------------+-----------------------------------------------------------------------------------------+-------------+
| `geopandas`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method | |
+--------------+-----------------------------------------------------------------------------------------+-------------+
| `numba`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method | |
+--------------+-----------------------------------------------------------------------------------------+-------------+
| `pyinterp`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method | >= 2026.4.0 |
+--------------+-----------------------------------------------------------------------------------------+-------------+
| `shapely`_ | Enable geometry intersection, introduce the ``bbox`` argument in the ``query()`` method | |
+--------------+-----------------------------------------------------------------------------------------+-------------+

.. _dask: https://www.dask.org/
.. _geopandas: https://geopandas.org/en/stable/
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Repository='https://github.com/robin-cls/fcollections'

[project.optional-dependencies]
testing = ["pytest", "pytest-cov", "sympy", "beautifulsoup4", "pyftpdlib", "pyasynchat"]
geo = ["shapely", "geopandas", "pyinterp<2026.2.0", "dask", "numba"]
geo = ["shapely", "geopandas", "pyinterp>=2026.4.0", "dask", "numba"]
doc = ["cartopy", "matplotlib", "sphinx", "sphinx-copybutton", "sphinx-design",
"sphinx-book-theme", "myst-nb"]

Expand All @@ -69,5 +69,5 @@ filterwarnings = [
"error",
# Can be safely ignored according to
# https://github.com/Unidata/netcdf4-python/issues/1354
"ignore:numpy\\.ndarray size changed"
"ignore:numpy\\.ndarray size changed",
]
19 changes: 9 additions & 10 deletions src/fcollections/geometry/_box.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import numpy as np
import pyinterp as pyi
import pyinterp.geodetic as pyi_geod
import pyinterp.geohash as pyi_geoh
import pyinterp.geometry.geographic as pyi_geom


def expand_box(box: pyi_geod.Box, precision: int) -> pyi_geod.Box:
def expand_box(box: pyi_geom.Box, precision: int) -> pyi_geom.Box:
"""Expand a geohash box with a given precision.

The method looks for the geohashes of the input box's corners with a given
Expand All @@ -12,24 +13,24 @@ def expand_box(box: pyi_geod.Box, precision: int) -> pyi_geod.Box:

Parameters
----------
box: pyinterp.geodetic.Box
box: geographic.Box
the box to expand
precision: int
the precision to expand the box to

Returns
-------
a pyinterp.geodetic.Box expanded to a lower precision
a geographic.Box expanded to a lower precision
"""
geohashes = pyi_geoh.encode(
[box.min_corner.lon, box.max_corner.lon],
[box.min_corner.lat, box.max_corner.lat],
np.array([box.min_corner.lon, box.max_corner.lon]),
np.array([box.min_corner.lat, box.max_corner.lat]),
precision=precision,
)

min_lon, min_lat, max_lon, max_lat = (None,) * 4
for g in geohashes:
box = pyi.GeoHash.from_string(g).bounding_box()
box = pyi_geoh.GeoHash.from_string(g.decode()).bounding_box()
min_lon = (
min(box.min_corner.lon, min_lon)
if min_lon is not None
Expand All @@ -50,6 +51,4 @@ def expand_box(box: pyi_geod.Box, precision: int) -> pyi_geod.Box:
if max_lat is not None
else box.max_corner.lat
)
return pyi_geod.Box(
pyi_geod.Point(min_lon, min_lat), pyi_geod.Point(max_lon, max_lat)
)
return pyi_geom.Box(min_corner=(min_lon, min_lat), max_corner=(max_lon, max_lat))
9 changes: 6 additions & 3 deletions src/fcollections/geometry/_distances.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Adapts the distance computation to multiple data shapes."""

import numpy as np
from pyinterp.geodetic import Spheroid, coordinate_distances
from pyinterp.geometry.geographic import MultiPoint, Spheroid
from pyinterp.geometry.geographic.algorithms import for_each_point_pairwise_distance

from fcollections.utilities.reshape import slice_along_axis

Expand Down Expand Up @@ -94,8 +95,10 @@ def _spheroid_distances_along_axis(
lat1 = slice_along_axis(latitudes, axis, slice(1, None))

# Compute distance on ellipsoid
return coordinate_distances(
lon0.ravel(), lat0.ravel(), lon1.ravel(), lat1.ravel(), wgs=wgs
return for_each_point_pairwise_distance(
MultiPoint(lon0.ravel(), lat0.ravel()),
MultiPoint(lon1.ravel(), lat1.ravel()),
spheroid=wgs,
).reshape(lon0.shape)


Expand Down
2 changes: 1 addition & 1 deletion src/fcollections/geometry/_track_orientation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import typing as tp

import numpy as np
from pyinterp.geodetic import Spheroid
from pyinterp.geometry.geographic import Spheroid

from fcollections.utilities.reshape import slice_along_axis

Expand Down
6 changes: 3 additions & 3 deletions tests/geometry/test_box.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pyinterp.geodetic as pyi_geod
import pyinterp.geometry.geographic as pyi_geom
import pytest

from fcollections.geometry import expand_box
Expand All @@ -18,8 +18,8 @@ def test_expand_box(
expected: tuple[tuple[float, float], tuple[float, float]],
):
"""Test box expansion with a given precision."""
box = pyi_geod.Box(pyi_geod.Point(*box[0]), pyi_geod.Point(*box[1]))
expected = pyi_geod.Box(pyi_geod.Point(*expected[0]), pyi_geod.Point(*expected[1]))
box = pyi_geom.Box(min_corner=box[0], max_corner=box[1])
expected = pyi_geom.Box(min_corner=expected[0], max_corner=expected[1])

actual = expand_box(box, precision=3)
assert (
Expand Down
Loading