[Git][debian-gis-team/xcube-resampling][master] 4 commits: New upstream version 0.3.4
Antonio Valentino (@antonio.valentino)
gitlab at salsa.debian.org
Mon Jun 1 19:09:34 BST 2026
Antonio Valentino pushed to branch master at Debian GIS Project / xcube-resampling
Commits:
5cb073a6 by Antonio Valentino at 2026-06-01T17:59:07+00:00
New upstream version 0.3.4
- - - - -
bf66e6bf by Antonio Valentino at 2026-06-01T17:59:40+00:00
Update upstream source from tag 'upstream/0.3.4'
Update to upstream version '0.3.4'
with Debian dir ace9ac88328d0ec254ccf265c94ae27faaf6b2f5
- - - - -
1a520400 by Antonio Valentino at 2026-06-01T18:00:14+00:00
New upstream release
- - - - -
f9670801 by Antonio Valentino at 2026-06-01T18:05:54+00:00
Set distribution to unstable
- - - - -
11 changed files:
- CHANGES.md
- debian/changelog
- + docs/examples/resample_in_space.ipynb
- docs/examples/resample_in_space_large_example_reproject_dataset.ipynb
- examples/resample_in_space.ipynb
- examples/resample_in_space_large_example_reproject_dataset.ipynb
- mkdocs.yml
- tests/test_utils.py
- xcube_resampling/affine.py
- xcube_resampling/utils.py
- xcube_resampling/version.py
Changes:
=====================================
CHANGES.md
=====================================
@@ -1,3 +1,13 @@
+## Changes in 0.3.4
+
+- Added `utils.transform_resolution` to convert spatial resolution between coordinate
+ reference systems (CRS).
+
+## Changes in 0.3.3
+
+- Added function `utils.resolution_degrees_to_meters` to convert spatial resolution
+ from degrees to meters at a given geographic latitude.
+
## Changes in 0.3.2
- Change inconsistent license classifier in `pyproject.toml`
=====================================
debian/changelog
=====================================
@@ -1,9 +1,12 @@
-xcube-resampling (0.3.2-2) UNRELEASED; urgency=medium
+xcube-resampling (0.3.4-1) unstable; urgency=medium
- * Team upload.
+ [ Bas Couwenberg ]
* Bump Standards-Version to 4.7.4, no changes.
- -- Bas Couwenberg <sebastic at debian.org> Sat, 04 Apr 2026 10:25:10 +0200
+ [ Antonio Valentino ]
+ * New upstream release.
+
+ -- Antonio Valentino <antonio.valentino at tiscali.it> Mon, 01 Jun 2026 18:05:37 +0000
xcube-resampling (0.3.2-1) unstable; urgency=medium
=====================================
docs/examples/resample_in_space.ipynb
=====================================
The diff for this file was not included because it is too large.
=====================================
docs/examples/resample_in_space_large_example_reproject_dataset.ipynb
=====================================
@@ -4,9 +4,7 @@
"cell_type": "markdown",
"id": "62866d66-22db-4f13-b585-3310df862833",
"metadata": {},
- "source": [
- "# Reproject the ESA-CCI land cover map for Europe"
- ]
+ "source": "# Reprojection of ESA-CCI land cover map for Europe"
},
{
"cell_type": "markdown",
=====================================
examples/resample_in_space.ipynb
=====================================
@@ -4,7 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Demonstration of function `resample_in_space()`\n",
+ "# Demonstration of function resample_in_space()\n",
"\n",
"This notebook demonstrates the functionality of the `resample_in_space` function. We show how it can be used for three different purposes:\n",
"\n",
=====================================
examples/resample_in_space_large_example_reproject_dataset.ipynb
=====================================
@@ -4,9 +4,7 @@
"cell_type": "markdown",
"id": "62866d66-22db-4f13-b585-3310df862833",
"metadata": {},
- "source": [
- "# Reproject the ESA-CCI land cover map for Europe"
- ]
+ "source": "# Reprojection of ESA-CCI land cover map for Europe"
},
{
"cell_type": "markdown",
=====================================
mkdocs.yml
=====================================
@@ -12,6 +12,7 @@ nav:
- GridMapping instance: examples/grid_mapping.ipynb
- Affine Transformation: examples/affine.ipynb
- Rectification of a Sentinel-3 tile: examples/rectify_sentinel3.ipynb
+ - Demonstration of the function resample_in_space: examples/resample_in_space.ipynb
- Reprojection of large Land Cover Map: examples/resample_in_space_large_example_reproject_dataset.ipynb
- Python API: api.md
- About: about.md
=====================================
tests/test_utils.py
=====================================
@@ -28,7 +28,9 @@ from xcube_resampling.utils import (
get_spatial_coords,
get_utm_crs,
reproject_bbox,
+ resolution_degrees_to_meters,
resolution_meters_to_degrees,
+ transform_resolution,
)
from .sampledata import create_2x4x4_dataset_with_irregular_coords
@@ -417,9 +419,34 @@ class TestUtils(unittest.TestCase):
target = (-170, 0, -160, 10)
self.assertAlmostEqual(0.0, bbox_overlap(source, target))
+ def test_transform_resolution(self):
+ # EPSG:4326 → UTM (meters)
+ res = transform_resolution((3, 60), 1.0, "EPSG:4326", "EPSG:32631")
+ self.assertAlmostEqual(55777.9, res[0], places=1)
+ self.assertAlmostEqual(111376.2, res[1], places=1)
+
+ # UTM (meters) → EPSG:4326
+ res = transform_resolution(
+ (500_000, 6_651_411), 111376, "EPSG:32631", "EPSG:4326"
+ )
+ self.assertAlmostEqual(2.0, res[0], places=2)
+ self.assertAlmostEqual(1.0, res[1], places=2)
+
+ # UTM → UTM (same CRS, should remain ~unchanged in magnitude)
+ res = transform_resolution(
+ (500000, 0), (1000, 1000), "EPSG:32631", "EPSG:32631"
+ )
+ self.assertAlmostEqual(1000, res[0])
+ self.assertAlmostEqual(1000, res[1])
+
+ # US survey foot to meter
+ res = transform_resolution((0, 0), (1, 1), "EPSG:3561", "EPSG:32605")
+ self.assertAlmostEqual(0.30525, res[0], places=4)
+ self.assertAlmostEqual(0.30525, res[1], places=4)
+
def test_resolution_meters_to_degrees(self):
# 111320 m ≈ 1 degree at equator
- lat_deg, lon_deg = resolution_meters_to_degrees(111320, 0)
+ lon_deg, lat_deg = resolution_meters_to_degrees(111320, 0)
self.assertAlmostEqual(1.0, lat_deg, places=6)
self.assertAlmostEqual(1.0, lon_deg, places=6)
@@ -433,6 +460,22 @@ class TestUtils(unittest.TestCase):
self.assertAlmostEqual(1.0, lat_deg, places=6)
self.assertAlmostEqual(1.0 / 0.5, lon_deg, places=6) # 2 degrees
+ def test_resolution_degrees_to_meters(self):
+ # 111320 m ≈ 1 degree at equator
+ lon_deg, lat_deg = resolution_degrees_to_meters(1, 0)
+ self.assertAlmostEqual(111320, lat_deg, places=6)
+ self.assertAlmostEqual(111320, lon_deg, places=6)
+
+ # 222640 m ≈ 2 degrees latitude
+ lon_deg, lat_deg = resolution_degrees_to_meters((1, 2), 0)
+ self.assertAlmostEqual(222640, lat_deg, places=6)
+ self.assertAlmostEqual(111320, lon_deg, places=6)
+
+ # At 60 degrees latitude, longitude degrees shrink by cos(60°) = 0.5
+ lon_deg, lat_deg = resolution_degrees_to_meters(1, 60)
+ self.assertAlmostEqual(111320, lat_deg, places=6)
+ self.assertAlmostEqual(111320 * 0.5, lon_deg, places=6)
+
class TestClipDatasetByBBox(unittest.TestCase):
=====================================
xcube_resampling/affine.py
=====================================
@@ -22,7 +22,6 @@
import math
from collections.abc import Iterable, Sequence
-import dask
import dask.array as da
import numpy as np
import xarray as xr
=====================================
xcube_resampling/utils.py
=====================================
@@ -19,6 +19,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
+import warnings
from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence
from dataclasses import dataclass
@@ -313,6 +314,45 @@ def _split_bbox_antimeridian(bbox: Sequence[FloatInt]) -> Sequence[Sequence[Floa
return [bbox]
+def transform_resolution(
+ ref_point: tuple[FloatInt, FloatInt],
+ resolution: FloatInt | tuple[FloatInt, FloatInt],
+ src_crs: str | pyproj.CRS,
+ dst_crs: str | pyproj.CRS,
+) -> tuple[FloatInt, FloatInt]:
+ """Estimate local spatial resolution in the destination CRS using
+ finite differences.
+
+ Args:
+ ref_point: Reference point (easting, northing) in the source CRS.
+ resolution: Spatial resolution in the source CRS. Can be a single number
+ (applied equally to both axes) or a tuple `(x_res, y_res)`.
+ src_crs: Source coordinate reference system.
+ dst_crs: Destination coordinate reference system.
+
+ Returns:
+ tuple: Estimated local resolution in the destination CRS as `(x_res, y_res)`.
+ """
+ transformer = pyproj.Transformer.from_crs(src_crs, dst_crs, always_xy=True)
+ if not isinstance(resolution, tuple):
+ resolution = (resolution, resolution)
+
+ # reference point
+ x0, y0 = transformer.transform(*ref_point)
+
+ # step in x direction
+ x1, y1 = transformer.transform(ref_point[0] + resolution[0], ref_point[1])
+
+ # step in y direction
+ x2, y2 = transformer.transform(ref_point[0], ref_point[1] + resolution[1])
+
+ # Euclidean distances
+ res_x = np.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
+ res_y = np.sqrt((x2 - x0) ** 2 + (y2 - y0) ** 2)
+
+ return res_x, res_y
+
+
def resolution_meters_to_degrees(
resolution: FloatInt | tuple[FloatInt, FloatInt], latitude: FloatInt
) -> tuple[FloatInt, FloatInt]:
@@ -341,6 +381,33 @@ def resolution_meters_to_degrees(
)
+def resolution_degrees_to_meters(
+ resolution: FloatInt | tuple[FloatInt, FloatInt], latitude: FloatInt
+) -> tuple[FloatInt, FloatInt]:
+ """Convert spatial resolution from degrees to meters at a given geographic latitude.
+
+ Args:
+ resolution: Spatial resolution in degrees. Can be a single number
+ (applied equally to both axes) or a tuple ``(lon_res, lat_res)``.
+ latitude: Latitude in degrees at which to compute the longitude scaling.
+
+ Returns:
+ A tuple `(x_res, y_res)` giving the approximate spatial
+ resolution in degrees for the latitude and longitude directions.
+
+ Notes:
+ - 1 degree of latitude ≈ 111,320 meters (constant approximation).
+ - 1 degree of longitude ≈ 111,320 * cos(latitude) meters.
+
+ """
+ if not isinstance(resolution, tuple):
+ resolution = (resolution, resolution)
+ return (
+ resolution[0] * (111320 * np.cos(np.deg2rad(latitude))),
+ resolution[1] * 111320,
+ )
+
+
def normalize_grid_mapping(ds: xr.Dataset, gm: GridMapping) -> xr.Dataset:
"""
Normalize the grid mapping of a dataset to use a standard "spatial_ref" coordinate.
=====================================
xcube_resampling/version.py
=====================================
@@ -19,4 +19,4 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
-__version__ = "0.3.2"
+__version__ = "0.3.4"
View it on GitLab: https://salsa.debian.org/debian-gis-team/xcube-resampling/-/compare/320d348685bb5e6166a075fdcd7349523a2f9dea...f9670801ba99caa36baaa005b9aaed9b568a6c66
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/xcube-resampling/-/compare/320d348685bb5e6166a075fdcd7349523a2f9dea...f9670801ba99caa36baaa005b9aaed9b568a6c66
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260601/df87fb12/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list