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/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.11", "3.12", "3.13", "3.14"]

steps:
- name: Checkout repository
Expand Down
11 changes: 6 additions & 5 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
Expand All @@ -14,26 +13,28 @@ on:

permissions:
contents: read
id-token: write

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build

- name: Build package
run: python -m build

- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://upload.pypi.org/legacy/
password: ${{ secrets.PYPI_API_TOKEN }}
repository-url: https://upload.pypi.org/legacy/
32 changes: 23 additions & 9 deletions rasters/clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,33 @@
from typing import Union, TYPE_CHECKING

import numpy as np
from geopandas.array import GeometryArray # Import GeometryArray for type checking
from shapely.geometry import box # Import for bounding box clipping

if TYPE_CHECKING:
from .raster import Raster

def clip(a: Union[Raster, np.ndarray], a_min, a_max, out=None, **kwargs) -> Union[Raster, np.ndarray]:
"""
Clips the values of an array or Raster to a specified range.
Clips the values of an array, Raster, or GeometryArray to a specified range.

This function limits the values in the input array or Raster to fall within the
range defined by `a_min` and `a_max`. Values below `a_min` are set to `a_min`,
and values above `a_max` are set to `a_max`.
This function limits the values in the input array, Raster, or GeometryArray to fall within the
range defined by `a_min` and `a_max`. For arrays, values below `a_min` are set to `a_min`,
and values above `a_max` are set to `a_max`. For GeometryArray, geometries are clipped to
the bounding box defined by `a_min` and `a_max`.

Args:
a (Union[Raster, np.ndarray]): The input array or Raster to clip.
a_min (float, optional): The minimum value to clip to. If None, no minimum clipping is performed.
a_max (float, optional): The maximum value to clip to. If None, no maximum clipping is performed.
a (Union[Raster, np.ndarray, GeometryArray]): The input data to clip.
a_min (float, optional): The minimum value or bounding box limit. If None, no minimum clipping is performed.
a_max (float, optional): The maximum value or bounding box limit. If None, no maximum clipping is performed.
out (np.ndarray, optional): An optional output array to store the result.
Must be the same shape and dtype as `a`.
**kwargs: Additional keyword arguments passed to np.clip (currently unused).

Returns:
Union[Raster, np.ndarray]: The clipped array or Raster. If `a` is a Raster, a new
Union[Raster, np.ndarray, GeometryArray]: The clipped data. If `a` is a Raster, a new
Raster object with the clipped data is returned.
Otherwise, a NumPy array is returned.
Otherwise, a NumPy array or GeometryArray is returned.
"""
from .raster import Raster # Import here to avoid circular dependency

Expand All @@ -35,6 +38,17 @@ def clip(a: Union[Raster, np.ndarray], a_min, a_max, out=None, **kwargs) -> Unio

result = a # Initialize result with the input data

if isinstance(result, GeometryArray):
if a_min is None or a_max is None:
raise ValueError("Both a_min and a_max must be specified for GeometryArray clipping.")

# Create a bounding box from a_min and a_max
bbox = box(a_min[0], a_min[1], a_max[0], a_max[1])

# Clip each geometry to the bounding box
result = GeometryArray([geom.intersection(bbox) for geom in result])
return result

if a_min is not None:
result = np.where(result < a_min, a_min, result) # Clip values below a_min
if a_max is not None:
Expand Down
Loading