Skip to content
Commits on Source (6)
exclude: '^$'
fail_fast: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.3
hooks:
- id: flake8
additional_dependencies: [flake8-docstrings, flake8-debugger, flake8-bugbear]
## Version v1.14.0 (2019/12/22)
### Issues Closed
* [Issue 242](https://github.com/pytroll/pyresample/issues/242) - AreaDefinition.get_lonlats ignores dtype option ([PR 243](https://github.com/pytroll/pyresample/pull/243))
* [Issue 233](https://github.com/pytroll/pyresample/issues/233) - get_neighbour_info can not handle SwathDefinitions with lat lon of type integers ([PR 235](https://github.com/pytroll/pyresample/pull/235))
* [Issue 229](https://github.com/pytroll/pyresample/issues/229) - Update old documentation on easy quicklook display (stop using rainbow color map!) ([PR 230](https://github.com/pytroll/pyresample/pull/230))
* [Issue 228](https://github.com/pytroll/pyresample/issues/228) - Area definition boundaries where space pixels are excluded
In this release 4 issues were closed.
### Pull Requests Merged
#### Bugs fixed
* [PR 245](https://github.com/pytroll/pyresample/pull/245) - Remove pyximports from gradient search
* [PR 243](https://github.com/pytroll/pyresample/pull/243) - Respect dtype when get_lonlats provide dask array ([242](https://github.com/pytroll/pyresample/issues/242))
* [PR 241](https://github.com/pytroll/pyresample/pull/241) - Fix typo in ImageContainerQuick and ImageContainerNearest docs
* [PR 236](https://github.com/pytroll/pyresample/pull/236) - Fix compatibility with pyproj 2.4.2
* [PR 227](https://github.com/pytroll/pyresample/pull/227) - Fix EWA resampling hanging when geolocation had a lot of NaNs
* [PR 224](https://github.com/pytroll/pyresample/pull/224) - Fix deprecation warning for abc classes
#### Features added
* [PR 230](https://github.com/pytroll/pyresample/pull/230) - No rainbow update documentation ([229](https://github.com/pytroll/pyresample/issues/229))
* [PR 225](https://github.com/pytroll/pyresample/pull/225) - Add smarter default radius_of_influence to XArrayResamplerNN resampling
* [PR 222](https://github.com/pytroll/pyresample/pull/222) - Make the uniform shape computation more effective for dask arrays
* [PR 191](https://github.com/pytroll/pyresample/pull/191) - Implement gradient search resampling method
#### Documentation changes
* [PR 241](https://github.com/pytroll/pyresample/pull/241) - Fix typo in ImageContainerQuick and ImageContainerNearest docs
* [PR 238](https://github.com/pytroll/pyresample/pull/238) - Update load_area docstring to mention that multiple files are allowed
* [PR 230](https://github.com/pytroll/pyresample/pull/230) - No rainbow update documentation ([229](https://github.com/pytroll/pyresample/issues/229))
In this release 13 pull requests were closed.
## Version 1.13.2 (2019/10/08)
### Issues Closed
......
[![Build Status](https://travis-ci.org/pytroll/pyresample.svg?branch=master)](https://travis-ci.org/pytroll/pyresample)
[![Build status](https://ci.appveyor.com/api/projects/status/a34o4utf8dqjsob1/branch/master?svg=true)](https://ci.appveyor.com/project/pytroll/pyresample/branch/master)
[![codebeat badge](https://codebeat.co/badges/2b9f14bc-758c-4fe1-967d-85b11e934983)](https://codebeat.co/projects/github-com-pytroll-pyresample-master)
[![Coverage Status](https://coveralls.io/repos/github/pytroll/pyresample/badge.svg?branch=master)](https://coveralls.io/github/pytroll/pyresample?branch=master)
Pyresample
----------
Pyresample is a python package for resampling geospatial image data. It is the
primary method for resampling in the [SatPy](https://github.com/pytroll/satpy)
primary method for resampling in the [Satpy](https://github.com/pytroll/satpy)
library, but can also be used as a standalone library. Resampling or
reprojection is the process of mapping input geolocated data points to a
new target geographic projection and area.
......
pyresample (1.14.0-1) unstable; urgency=medium
* New upstream release.
* Update debian/copyright file.
* debian/patches:
- drop 0007-Fix-pyproj-inf.patch: applied upstream
- refresh remaining patches
-- Antonio Valentino <antonio.valentino@tiscali.it> Mon, 23 Dec 2019 09:36:58 +0000
pyresample (1.13.2-2) unstable; urgency=medium
* Drop Provides: ${python3:Provides}.
......
......@@ -4,11 +4,12 @@ Source: https://github.com/pytroll/pyresample
Files: *
Copyright: 2015-2019, Pyresample developers
2014-2018, PyTroll Developers
2014-2019, PyTroll Developers
2010-2016, Esben S. Nielsen <esn@dmi.dk>
2010-2016, Thomas Lavergne <t.lavergne@met.no>
2010, 2014-2016, Adam Dybbroe
2010, 2013-2015, 2017, Martin Raspaud <martin.raspaud@smhi.se>
2010, 2013-2015, 2019, Martin Raspaud <martin.raspaud@smhi.se>
2013-2019, Leon Majewski <leon.majewski@bom.gov.au>
License: LGPL-3+
Files: versioneer.py
......@@ -19,10 +20,19 @@ Files: pyresample/bilinear/__init__.py
Copyright: 2017 Panu Lahtinen <panu.lahtinen@fmi.fi>
License: GPL-3+
Files: pyresample/image.py
Copyright: 2010-2015, Esben S. Nielsen <esn@dmi.dk>
License: GPL-3+
Files: pyresample/gradient/_gradient_search.pyx
Copyright: 2013-2019, Martin Raspaud <martin.raspaud@smhi.se>
Leon Majewski <leon.majewski@bom.gov.au>
License: GPL-3+
Files: pyresample/ewa/*
pyresample/test/test_ewa_*
pyresample/test/utils.py
Copyright: 2016 David Hoese <david.hoese@ssec.wisc.edu>
Copyright: 2016-2019 David Hoese <david.hoese@ssec.wisc.edu>
License: GPL-3+
Files: debian/*
......
......@@ -21,10 +21,10 @@ index 063264d..620e665 100644
YSIZE: 480
AREA_EXTENT: (-20037508.342789244, -10018754.171394622, 20037508.342789244, 10018754.171394622)
diff --git a/pyresample/test/test_geometry.py b/pyresample/test/test_geometry.py
index b982b03..34621ff 100644
index 295951f..7ecb008 100644
--- a/pyresample/test/test_geometry.py
+++ b/pyresample/test/test_geometry.py
@@ -560,7 +560,7 @@ class Test(unittest.TestCase):
@@ -559,7 +559,7 @@ class Test(unittest.TestCase):
swath_def = geometry.SwathDefinition(lons, lats)
filter_area = geometry.AreaDefinition('test', 'test', 'test',
{'proj': 'eqc', 'lon_0': 0.0,
......@@ -33,7 +33,7 @@ index b982b03..34621ff 100644
8, 8,
(-20037508.34, -10018754.17, 20037508.34, 10018754.17))
filter = np.array([[1, 1, 1, 1, 0, 0, 0, 0],
@@ -585,7 +585,7 @@ class Test(unittest.TestCase):
@@ -584,7 +584,7 @@ class Test(unittest.TestCase):
data = np.array([1, 2, 3, 4])
filter_area = geometry.AreaDefinition('test', 'test', 'test',
{'proj': 'eqc', 'lon_0': 0.0,
......@@ -42,7 +42,7 @@ index b982b03..34621ff 100644
8, 8,
(-20037508.34, -10018754.17, 20037508.34, 10018754.17))
filter = np.array([[1, 1, 1, 1, 0, 0, 0, 0],
@@ -620,7 +620,7 @@ class Test(unittest.TestCase):
@@ -619,7 +619,7 @@ class Test(unittest.TestCase):
data = np.dstack((data1, data2, data3))
filter_area = geometry.AreaDefinition('test', 'test', 'test',
{'proj': 'eqc', 'lon_0': 0.0,
......@@ -51,7 +51,7 @@ index b982b03..34621ff 100644
8, 8,
(-20037508.34, -10018754.17, 20037508.34, 10018754.17))
filter = np.array([[1, 1, 1, 1, 0, 0, 0, 0],
@@ -689,7 +689,7 @@ class Test(unittest.TestCase):
@@ -688,7 +688,7 @@ class Test(unittest.TestCase):
def test_latlong_area(self):
area_def = geometry.AreaDefinition('', '', '',
......
......@@ -9,7 +9,7 @@ Subject: Skip dask-related tests if dask is not available
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/pyresample/test/test_geometry.py b/pyresample/test/test_geometry.py
index 34621ff..2349ae6 100644
index 7ecb008..23f5df9 100644
--- a/pyresample/test/test_geometry.py
+++ b/pyresample/test/test_geometry.py
@@ -9,7 +9,8 @@ import numpy as np
......@@ -33,16 +33,16 @@ index 34621ff..2349ae6 100644
+
class Test(unittest.TestCase):
@@ -835,6 +841,7 @@ class Test(unittest.TestCase):
"""Unit testing the geometry and geo_filter modules."""
@@ -834,6 +840,7 @@ class Test(unittest.TestCase):
np.array([-675286.976033, -682358.043845, -689429.111657, -696500.179469,
-703571.247281]))
+ @unittest.skipIf(not dask, 'dask not available')
def test_get_proj_coords_dask(self):
"""Test get_proj_coords usage with dask arrays."""
from pyresample import utils
@@ -1473,6 +1480,8 @@ class TestSwathDefinition(unittest.TestCase):
from pyresample import get_area_def
@@ -1556,6 +1563,8 @@ class TestSwathDefinition(unittest.TestCase):
assert_np_dict_allclose(res.proj_dict, proj_dict)
self.assertEqual(res.shape, (6, 3))
......@@ -51,21 +51,21 @@ index 34621ff..2349ae6 100644
def test_aggregation(self):
"""Test aggregation on SwathDefinitions."""
if (sys.version_info < (3, 0)):
@@ -1490,6 +1499,7 @@ class TestSwathDefinition(unittest.TestCase):
np.testing.assert_allclose(res.lons, [[179, -179]])
np.testing.assert_allclose(res.lats, [[0.5, 0.5]], atol=2e-5)
@@ -1579,6 +1588,7 @@ class TestSwathDefinition(unittest.TestCase):
self.assertAlmostEqual(res.lons.resolution, window_size * resolution)
self.assertAlmostEqual(res.lats.resolution, window_size * resolution)
+ @unittest.skipIf(not dask, 'dask not available')
def test_striding(self):
"""Test striding."""
import dask.array as da
diff --git a/pyresample/test/test_kd_tree.py b/pyresample/test/test_kd_tree.py
index b3ef1a2..30108ca 100644
index c089a6a..01ae510 100644
--- a/pyresample/test/test_kd_tree.py
+++ b/pyresample/test/test_kd_tree.py
@@ -14,6 +14,11 @@ if sys.version_info < (2, 7):
else:
import unittest
@@ -17,6 +17,11 @@ except ImportError:
# python 2.7
import mock
+try:
+ import dask.array as da
......@@ -75,7 +75,7 @@ index b3ef1a2..30108ca 100644
class Test(unittest.TestCase):
@@ -696,6 +701,7 @@ class Test(unittest.TestCase):
@@ -713,6 +718,7 @@ class Test(unittest.TestCase):
self.assertTrue(np.array_equal(fill_mask, expected_fill_mask))
......@@ -84,10 +84,10 @@ index b3ef1a2..30108ca 100644
"""Test the XArrayResamplerNN class."""
diff --git a/setup.py b/setup.py
index abb8217..063d6d0 100644
index cf334e1..4d22fa2 100644
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,7 @@ else:
@@ -40,7 +40,7 @@ else:
setup_requires = ['numpy>=1.10.0,<1.17.0']
requirements.append('numpy>=1.10.0,<1.17.0')
......
......@@ -9,7 +9,7 @@ Subject: Make xarray optional for testing
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/pyresample/test/test_geometry.py b/pyresample/test/test_geometry.py
index 2349ae6..c30c392 100644
index 23f5df9..4ac94d5 100644
--- a/pyresample/test/test_geometry.py
+++ b/pyresample/test/test_geometry.py
@@ -24,6 +24,11 @@ if sys.version_info < (2, 7):
......@@ -24,7 +24,7 @@ index 2349ae6..c30c392 100644
try:
import dask
except ImportError:
@@ -1362,6 +1367,7 @@ class TestSwathDefinition(unittest.TestCase):
@@ -1445,6 +1450,7 @@ class TestSwathDefinition(unittest.TestCase):
self.assertFalse(
swath_def == swath_def2, 'swath_defs are not expected to be equal')
......@@ -32,7 +32,7 @@ index 2349ae6..c30c392 100644
def test_compute_omerc_params(self):
"""Test omerc parameters computation."""
lats = np.array([[85.23900604248047, 62.256004333496094, 35.58000183105469],
@@ -1433,6 +1439,7 @@ class TestSwathDefinition(unittest.TestCase):
@@ -1516,6 +1522,7 @@ class TestSwathDefinition(unittest.TestCase):
np.testing.assert_allclose(lats, [80., 80., 80., 80., 80., 80., 80.,
80., 80., 80., 80., 80.])
......@@ -40,7 +40,7 @@ index 2349ae6..c30c392 100644
def test_compute_optimal_bb(self):
"""Test computing the bb area."""
from pyresample.utils import is_pyproj2
@@ -1480,6 +1487,7 @@ class TestSwathDefinition(unittest.TestCase):
@@ -1563,6 +1570,7 @@ class TestSwathDefinition(unittest.TestCase):
assert_np_dict_allclose(res.proj_dict, proj_dict)
self.assertEqual(res.shape, (6, 3))
......@@ -48,15 +48,15 @@ index 2349ae6..c30c392 100644
@unittest.skipIf(not hasattr(DataArray, 'coarsen'), 'DataArray.coarsen not available')
@unittest.skipIf(not dask, 'dask not available')
def test_aggregation(self):
@@ -1499,6 +1507,7 @@ class TestSwathDefinition(unittest.TestCase):
np.testing.assert_allclose(res.lons, [[179, -179]])
np.testing.assert_allclose(res.lats, [[0.5, 0.5]], atol=2e-5)
@@ -1588,6 +1596,7 @@ class TestSwathDefinition(unittest.TestCase):
self.assertAlmostEqual(res.lons.resolution, window_size * resolution)
self.assertAlmostEqual(res.lats.resolution, window_size * resolution)
+ @unittest.skipIf(xarray is None, 'xarray is not available')
@unittest.skipIf(not dask, 'dask not available')
def test_striding(self):
"""Test striding."""
@@ -1825,6 +1834,7 @@ class TestDynamicAreaDefinition(unittest.TestCase):
@@ -1935,6 +1944,7 @@ class TestDynamicAreaDefinition(unittest.TestCase):
self.assertEqual(result.width, 395)
self.assertEqual(result.height, 539)
......@@ -65,12 +65,12 @@ index 2349ae6..c30c392 100644
"""Test freezing the area with bounding box computation."""
area = geometry.DynamicAreaDefinition('test_area', 'A test area', {'proj': 'omerc'},
diff --git a/pyresample/test/test_kd_tree.py b/pyresample/test/test_kd_tree.py
index 30108ca..1dc8f74 100644
index 01ae510..e97f525 100644
--- a/pyresample/test/test_kd_tree.py
+++ b/pyresample/test/test_kd_tree.py
@@ -14,6 +14,11 @@ if sys.version_info < (2, 7):
else:
import unittest
@@ -17,6 +17,11 @@ except ImportError:
# python 2.7
import mock
+try:
+ import xarray as xr
......@@ -80,7 +80,7 @@ index 30108ca..1dc8f74 100644
try:
import dask.array as da
except ImportError:
@@ -701,6 +706,7 @@ class Test(unittest.TestCase):
@@ -718,6 +723,7 @@ class Test(unittest.TestCase):
self.assertTrue(np.array_equal(fill_mask, expected_fill_mask))
......@@ -89,10 +89,10 @@ index 30108ca..1dc8f74 100644
class TestXArrayResamplerNN(unittest.TestCase):
"""Test the XArrayResamplerNN class."""
diff --git a/setup.py b/setup.py
index 063d6d0..b377068 100644
index 4d22fa2..fe55f55 100644
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,7 @@ else:
@@ -40,7 +40,7 @@ else:
setup_requires = ['numpy>=1.10.0,<1.17.0']
requirements.append('numpy>=1.10.0,<1.17.0')
......
......@@ -9,10 +9,10 @@ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=939022
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyresample/test/test_plot.py b/pyresample/test/test_plot.py
index 0ea4fa3..bc446e3 100644
index 7ca299a..36a1bed 100644
--- a/pyresample/test/test_plot.py
+++ b/pyresample/test/test_plot.py
@@ -29,7 +29,7 @@ except ImportError:
@@ -40,7 +40,7 @@ except ImportError:
try:
from mpl_toolkits.basemap import Basemap
......
......@@ -7,14 +7,14 @@ Subject: Skip test on deprecatet basemap
1 file changed, 1 insertion(+)
diff --git a/pyresample/test/test_plot.py b/pyresample/test/test_plot.py
index bc446e3..02728cd 100644
index 36a1bed..2ded738 100644
--- a/pyresample/test/test_plot.py
+++ b/pyresample/test/test_plot.py
@@ -57,6 +57,7 @@ class Test(unittest.TestCase):
@@ -83,6 +83,7 @@ class Test(unittest.TestCase):
self.assertAlmostEqual(b, 6356752.3142451793,
msg='Failed to get semi-minor axis of ellipsis')
+ @unittest.skip('deprecated interface')
@unittest.skipIf(Basemap is None, "basemap is not available")
def test_area_def2basemap(self):
from pyresample import plot
"""Test the area to Basemap object conversion function."""
From: Antonio Valentino <antonio.valentino@tiscali.it>
Date: Tue, 3 Dec 2019 07:10:43 +0000
Subject: Fix pyproj inf
See https://github.com/pytroll/pyresample/pull/236 and
https://github.com/pytroll/pyresample/issues/237.
---
pyresample/ewa/__init__.py | 4 ++--
pyresample/ewa/_ll2cr.pyx | 4 ++--
pyresample/geometry.py | 17 ++++++++++-------
pyresample/grid.py | 2 +-
pyresample/kd_tree.py | 12 +++++++-----
pyresample/spherical_geometry.py | 2 +-
pyresample/test/test_geometry.py | 22 +++++++++++-----------
pyresample/test/test_spherical.py | 6 +++---
pyresample/test/test_utils.py | 8 ++++----
pyresample/test/utils.py | 2 +-
10 files changed, 42 insertions(+), 37 deletions(-)
diff --git a/pyresample/ewa/__init__.py b/pyresample/ewa/__init__.py
index d6c1195..62f3f11 100644
--- a/pyresample/ewa/__init__.py
+++ b/pyresample/ewa/__init__.py
@@ -119,8 +119,8 @@ def ll2cr(swath_def, area_def, fill=np.nan, copy=True):
cw = area_def.pixel_size_x
# cell height must be negative for this to work as expected
ch = -abs(area_def.pixel_size_y)
- w = area_def.x_size
- h = area_def.y_size
+ w = area_def.width
+ h = area_def.height
ox = area_def.area_extent[0] + cw / 2.
oy = area_def.area_extent[3] + ch / 2.
swath_points_in_grid = _ll2cr.ll2cr_static(lons, lats, fill,
diff --git a/pyresample/ewa/_ll2cr.pyx b/pyresample/ewa/_ll2cr.pyx
index 883613a..34ef568 100644
--- a/pyresample/ewa/_ll2cr.pyx
+++ b/pyresample/ewa/_ll2cr.pyx
@@ -159,13 +159,13 @@ def ll2cr_dynamic(numpy.ndarray[cr_dtype, ndim=2] lon_arr, numpy.ndarray[cr_dtyp
continue
elif x_tmp < xmin or npy_isnan(xmin):
xmin = x_tmp
- elif x_tmp > xmax or npy_isnan(xmax) or xmax == 1e30:
+ elif x_tmp > xmax or npy_isnan(xmax) or xmax >= 1e30:
# Note: technically 2 valid points are required to get here if there are a lot of NaNs
xmax = x_tmp
if y_tmp < ymin or npy_isnan(ymin):
ymin = y_tmp
- elif y_tmp > ymax or npy_isnan(ymax) or ymax == 1e30:
+ elif y_tmp > ymax or npy_isnan(ymax) or ymax >= 1e30:
# Note: technically 2 valid points are required to get here if there are a lot of NaNs
ymax = y_tmp
diff --git a/pyresample/geometry.py b/pyresample/geometry.py
index 697e4ed..9ed645b 100644
--- a/pyresample/geometry.py
+++ b/pyresample/geometry.py
@@ -935,7 +935,7 @@ class DynamicAreaDefinition(object):
def invproj(data_x, data_y, proj_dict):
"""Perform inverse projection."""
# XXX: does pyproj copy arrays? What can we do so it doesn't?
- target_proj = Proj(**proj_dict)
+ target_proj = Proj(proj_dict)
return np.dstack(target_proj(data_x, data_y, inverse=True))
@@ -1591,7 +1591,7 @@ class AreaDefinition(BaseDefinition):
"""
lon, lat = self.get_lonlats(nprocs=None, data_slice=(row, col))
- return np.asscalar(lon), np.asscalar(lat)
+ return lon.item(), lat.item()
@staticmethod
def _do_rotation(xspan, yspan, rot_deg=0):
@@ -1803,18 +1803,19 @@ class AreaDefinition(BaseDefinition):
raise ValueError("Can't specify 'nprocs' and 'chunks' at the same time")
# Proj.4 definition of target area projection
+ proj_def = self.crs if hasattr(self, 'crs') else self.proj_dict
if hasattr(target_x, 'chunks'):
# we are using dask arrays, map blocks to th
from dask.array import map_blocks
res = map_blocks(invproj, target_x, target_y,
chunks=(target_x.chunks[0], target_x.chunks[1], 2),
- new_axis=[2], proj_dict=self.proj_dict)
+ new_axis=[2], proj_dict=proj_def)
return res[:, :, 0], res[:, :, 1]
if nprocs > 1:
- target_proj = Proj_MP(**self.proj_dict)
+ target_proj = Proj_MP(proj_def)
else:
- target_proj = Proj(**self.proj_dict)
+ target_proj = Proj(proj_def)
# Get corresponding longitude and latitude values
lons, lats = target_proj(target_x, target_y, inverse=True, nprocs=nprocs)
@@ -1841,10 +1842,12 @@ class AreaDefinition(BaseDefinition):
raise NotImplementedError('Only AreaDefinitions can be used')
# Intersection only required for two different projections
- if area_to_cover.proj_str == self.proj_str:
+ proj_def_to_cover = area_to_cover.crs if hasattr(area_to_cover, 'crs') else area_to_cover.proj_str
+ proj_def = self.crs if hasattr(self, 'crs') else self.proj_str
+ if proj_def_to_cover == proj_def:
logger.debug('Projections for data and slice areas are'
' identical: %s',
- area_to_cover.proj_dict.get('proj', area_to_cover.proj_dict.get('init')))
+ proj_def_to_cover)
# Get xy coordinates
llx, lly, urx, ury = area_to_cover.area_extent
x, y = self.get_xy_from_proj_coords([llx, urx], [lly, ury])
diff --git a/pyresample/grid.py b/pyresample/grid.py
index 05afb1e..3b21203 100644
--- a/pyresample/grid.py
+++ b/pyresample/grid.py
@@ -210,7 +210,7 @@ def get_resampled_image(target_area_def, source_area_def, source_image_data,
# Calculate number of segments if needed
if segments is None:
- rows = target_area_def.y_size
+ rows = target_area_def.height
cut_off = 500
if rows > cut_off:
segments = int(rows / cut_off)
diff --git a/pyresample/kd_tree.py b/pyresample/kd_tree.py
index c45c499..c3b0136 100644
--- a/pyresample/kd_tree.py
+++ b/pyresample/kd_tree.py
@@ -430,7 +430,7 @@ def _get_valid_input_index(source_geo_def,
source_lons, source_lats,
radius_of_influence)
- if (isinstance(valid_input_index, np.ma.core.MaskedArray)):
+ if isinstance(valid_input_index, np.ma.core.MaskedArray):
# Make sure valid_input_index is not a masked array
valid_input_index = valid_input_index.filled(False)
@@ -1003,7 +1003,7 @@ class XArrayResamplerNN(object):
def _create_resample_kdtree(self, chunks=CHUNK_SIZE):
"""Set up kd tree on input"""
- source_lons, source_lats = self.source_geo_def.get_lonlats_dask(
+ source_lons, source_lats = self.source_geo_def.get_lonlats(
chunks=chunks)
valid_input_idx = ((source_lons >= -180) & (source_lons <= 180) &
(source_lats <= 90) & (source_lats >= -90))
@@ -1058,7 +1058,8 @@ class XArrayResamplerNN(object):
self.valid_input_index = valid_input_idx
self.delayed_kdtree = resample_kdtree
- target_lons, target_lats = self.target_geo_def.get_lonlats_dask()
+ # TODO: Add 'chunks' keyword argument to this method and use it
+ target_lons, target_lats = self.target_geo_def.get_lonlats(chunks=CHUNK_SIZE)
valid_output_idx = ((target_lons >= -180) & (target_lons <= 180) &
(target_lats <= 90) & (target_lats >= -90))
@@ -1094,7 +1095,7 @@ class XArrayResamplerNN(object):
and/or pykdtree.
Args:
- data (dask.array.Array): Source data pixels to sample
+ data (xarray.DataArray): Source data pixels to sample
fill_value (float): Output fill value when no source data is
near the target pixel. When omitted, if the input data is an
integer array then the maximum value for that integer type is
@@ -1147,7 +1148,8 @@ class XArrayResamplerNN(object):
coords = {c: c_var for c, c_var in data.coords.items()
if not contain_coords(c_var, src_geo_dims + dst_geo_dims)}
try:
- coord_x, coord_y = self.target_geo_def.get_proj_vectors_dask()
+ # TODO: Add 'chunks' kwarg
+ coord_x, coord_y = self.target_geo_def.get_proj_vectors(chunks=CHUNK_SIZE)
coords['y'] = coord_y
coords['x'] = coord_x
except AttributeError:
diff --git a/pyresample/spherical_geometry.py b/pyresample/spherical_geometry.py
index 091c6d7..4e8eac7 100644
--- a/pyresample/spherical_geometry.py
+++ b/pyresample/spherical_geometry.py
@@ -24,7 +24,7 @@ import numpy as np
import warnings
warnings.warn("This module will be removed in pyresample 2.0, please use the "
- "`pyresample.spherical` module functions and classe instead.",
+ "`pyresample.spherical` module functions and class instead.",
DeprecationWarning)
try:
diff --git a/pyresample/test/test_geometry.py b/pyresample/test/test_geometry.py
index c30c392..d516cbb 100644
--- a/pyresample/test/test_geometry.py
+++ b/pyresample/test/test_geometry.py
@@ -849,7 +849,7 @@ class Test(unittest.TestCase):
@unittest.skipIf(not dask, 'dask not available')
def test_get_proj_coords_dask(self):
"""Test get_proj_coords usage with dask arrays."""
- from pyresample import utils
+ from pyresample import get_area_def
area_id = 'test'
area_name = 'Test area with 2x2 pixels'
proj_id = 'test'
@@ -857,9 +857,9 @@ class Test(unittest.TestCase):
y_size = 10
area_extent = [1000000, 0, 1050000, 50000]
proj_dict = {"proj": 'laea', 'lat_0': '60', 'lon_0': '0', 'a': '6371228.0', 'units': 'm'}
- area_def = utils.get_area_def(area_id, area_name, proj_id, proj_dict, x_size, y_size, area_extent)
+ area_def = get_area_def(area_id, area_name, proj_id, proj_dict, x_size, y_size, area_extent)
- xcoord, ycoord = area_def.get_proj_coords_dask()
+ xcoord, ycoord = area_def.get_proj_coords(chunks=4096)
xcoord = xcoord.compute()
ycoord = ycoord.compute()
self.assertTrue(np.allclose(xcoord[0, :],
@@ -1588,7 +1588,7 @@ class TestStackedAreaDefinition(unittest.TestCase):
(5567747.7409681147, 2787374.2399544837,
-1000.3358822065015, 2323311.9002169576))
- self.assertEqual(adef.y_size, 4 * 464)
+ self.assertEqual(adef.height, 4 * 464)
self.assertIsInstance(adef.squeeze(), geometry.StackedAreaDefinition)
adef2 = geometry.StackedAreaDefinition()
@@ -1600,7 +1600,7 @@ class TestStackedAreaDefinition(unittest.TestCase):
(5567747.7409681147, 2787374.2399544837,
-1000.3358822065015, 2323311.9002169576))
- self.assertEqual(adef2.y_size, 4 * 464)
+ self.assertEqual(adef2.height, 4 * 464)
def test_get_lonlats(self):
"""Test get_lonlats on StackedAreaDefinition."""
@@ -1659,12 +1659,12 @@ class TestStackedAreaDefinition(unittest.TestCase):
"""Fail appending areas."""
area1 = MagicMock()
area1.proj_dict = {"proj": 'A'}
- area1.x_size = 4
- area1.y_size = 5
+ area1.width = 4
+ area1.height = 5
area2 = MagicMock()
area2.proj_dict = {'proj': 'B'}
- area2.x_size = 4
- area2.y_size = 6
+ area2.width = 4
+ area2.height = 6
# res = combine_area_extents_vertical(area1, area2)
self.assertRaises(IncompatibleAreas,
concatenate_area_defs, area1, area2)
@@ -1851,8 +1851,8 @@ class TestDynamicAreaDefinition(unittest.TestCase):
np.testing.assert_allclose(result.area_extent,
[-336277.698941, 5513145.392745,
192456.651909, 7749649.63914])
- self.assertEqual(result.x_size, 4)
- self.assertEqual(result.y_size, 18)
+ self.assertEqual(result.width, 4)
+ self.assertEqual(result.height, 18)
# Test for properties and shape usage in freeze.
area = geometry.DynamicAreaDefinition('test_area', 'A test area', {'proj': 'merc'},
width=4, height=18)
diff --git a/pyresample/test/test_spherical.py b/pyresample/test/test_spherical.py
index bd7513f..f9aba63 100644
--- a/pyresample/test/test_spherical.py
+++ b/pyresample/test/test_spherical.py
@@ -37,7 +37,7 @@ class TestSCoordinate(unittest.TestCase):
"""Test Vincenty formula
"""
d = SCoordinate(0, 0).distance(SCoordinate(1, 1))
- self.assertEquals(d, 1.2745557823062943)
+ self.assertEqual(d, 1.2745557823062943)
def test_hdistance(self):
"""Test Haversine formula
@@ -185,7 +185,7 @@ class TestArc(unittest.TestCase):
lon, lat = arc1.intersection(arc2)
self.assertTrue(np.allclose(np.rad2deg(lon), 5))
- self.assertEquals(np.rad2deg(lat).round(7), round(5.0575148968282093, 7))
+ self.assertEqual(np.rad2deg(lat).round(7), round(5.0575148968282093, 7))
arc1 = Arc(SCoordinate(0, 0),
SCoordinate(np.deg2rad(10), np.deg2rad(10)))
@@ -202,7 +202,7 @@ class TestArc(unittest.TestCase):
np.deg2rad(50.935830837274324)))
inter = SCoordinate(np.deg2rad(20.165957021925202),
np.deg2rad(46.177022633103398))
- self.assertEquals(arc1.intersection(arc2), inter)
+ self.assertEqual(arc1.intersection(arc2), inter)
arc1 = Arc(SCoordinate(np.deg2rad(-2.4982818108326734),
np.deg2rad(48.596644847869655)),
diff --git a/pyresample/test/test_utils.py b/pyresample/test/test_utils.py
index 209e6c2..93104a4 100644
--- a/pyresample/test/test_utils.py
+++ b/pyresample/test/test_utils.py
@@ -324,10 +324,10 @@ class TestMisc(unittest.TestCase):
def test_unicode_proj4_string(self):
"""Test that unicode is accepted for area creation.
"""
- from pyresample import utils
- utils.get_area_def(u"eurol", u"eurol", u"bla",
- u'+proj=stere +a=6378273 +b=6356889.44891 +lat_0=90 +lat_ts=70 +lon_0=-45',
- 1000, 1000, (-1000, -1000, 1000, 1000))
+ from pyresample import get_area_def
+ get_area_def(u"eurol", u"eurol", u"bla",
+ u'+proj=stere +a=6378273 +b=6356889.44891 +lat_0=90 +lat_ts=70 +lon_0=-45',
+ 1000, 1000, (-1000, -1000, 1000, 1000))
def test_proj4_radius_parameters_provided(self):
"""Test proj4_radius_parameters with a/b."""
diff --git a/pyresample/test/utils.py b/pyresample/test/utils.py
index 74f7a21..7704004 100644
--- a/pyresample/test/utils.py
+++ b/pyresample/test/utils.py
@@ -107,7 +107,7 @@ def treat_deprecations_as_exceptions():
warnings.filterwarnings(
"ignore",
r"This module will be removed in pyresample 2\.0\, please use the"
- r"\`pyresample.spherical\` module functions and classe instead\.",
+ r"\`pyresample.spherical\` module functions and class instead\.",
DeprecationWarning)
if sys.version_info[:2] >= (3, 5):
......@@ -4,4 +4,3 @@
0004-Detect-broken-basemap.patch
0005-Comapt-with-dask-1.0.patch
0006-Skip-test-on-deprecatet-basemap.patch
0007-Fix-pyproj-inf.patch
......@@ -139,7 +139,7 @@ The full list of constructor arguments:
**ImageContainerQuick**:
* image_data : Dataset. Masked arrays can be used.
* image_data : Geometry definition.
* geo_def : Geometry definition.
* fill_value (optional) : Fill value for undefined pixels. Defaults to 0. If set to **None** they will be masked out.
* nprocs (optional) : Number of processor cores to use. Defaults to 1.
* segments (optional) : Number of segments to split resampling in. Defaults to auto estimation.
......@@ -147,7 +147,7 @@ The full list of constructor arguments:
**ImageContainerNearest**:
* image_data : Dataset. Masked arrays can be used.
* image_data : Geometry definition.
* geo_def : Geometry definition.
* radius_of_influence : Cut off radius in meters when considering neighbour pixels.
* epsilon (optional) : The distance to a found value is guaranteed to be no further than (1 + eps) times the distance to the correct neighbour.
* fill_value (optional) : Fill value for undefined pixels. Defaults to 0. If set to **None** they will be masked out.
......
......@@ -3,8 +3,7 @@
Plotting with pyresample and Cartopy
====================================
Pyresample supports basic integration with Cartopy
(http://scitools.org.uk/cartopy/).
Pyresample supports basic integration with Cartopy_.
Displaying data quickly
-----------------------
......@@ -15,6 +14,24 @@ of a dataset for a specified AreaDefinition. The function
**Example usage:**
In this simple example below we use GCOM-W1 AMSR-2 data loaded using Satpy_. Of
course Satpy_ facilitates the handling of these data in an even easier way, but
the below example can be useful if you have some data that are yet not
supported by Satpy_. All you need are a set of geo-referenced values
(longitudes and latitudes and corresponding geophysical values).
First we read in the data with Satpy_:
>>> from satpy.scene import Scene
>>> from glob import glob
>>> SCENE_FILES = glob("./GW1AM2_20191122????_156*h5")
>>> scn = Scene(reader='amsr2_l1b', filenames=SCENE_FILES)
>>> scn.load(["btemp_36.5v"])
>>> lons, lats = scn["btemp_36.5v"].area.get_lonlats()
>>> tb37v = scn["btemp_36.5v"].data.compute()
Data for this example can be downloaded from zenodo_.
.. doctest::
>>> import numpy as np
......@@ -23,47 +40,60 @@ of a dataset for a specified AreaDefinition. The function
>>> lons = np.zeros(1000)
>>> lats = np.arange(-80, -90, -0.01)
>>> tb37v = np.arange(1000)
>>> area_def = load_area('areas.cfg', 'ease_sh')
>>> area_def = load_area('areas.yaml', 'ease_sh')
>>> swath_def = SwathDefinition(lons, lats)
>>> result = resample_nearest(swath_def, tb37v, area_def,
... radius_of_influence=20000, fill_value=None)
>>> save_quicklook('tb37v_quick.png', area_def, result, label='Tb 37v (K)')
Assuming **lons**, **lats** and **tb37v** are initialized with real data the result might look something like this:
Assuming **lons**, **lats** and **tb37v** are initialized with real data (as in
the above Satpy_ example) the result might look something like this:
.. image:: _static/images/tb37v_quick.png
The data passed to the functions is a 2D array matching the AreaDefinition.
The Plate Carree projection
+++++++++++++++++++++++++++
The Plate Carree projection (regular lon/lat grid) is named **eqc** in Proj.4 and **cyl** in Basemap. pyresample uses the Proj.4 name.
Assuming the file **areas.cfg** has the following area definition:
The Plate Carree projection (regular lon/lat grid) is named **eqc** in
Proj.4. Pyresample uses the Proj.4 naming.
Assuming the file **areas.yaml** has the following area definition:
.. code-block:: bash
REGION: pc_world {
NAME: Plate Carree world map
PCS_ID: pc_world
PCS_DEF: proj=eqc
XSIZE: 640
YSIZE: 480
AREA_EXTENT: (-20037508.34, -10018754.17, 20037508.34, 10018754.17)
};
pc_world:
description: Plate Carree world map
projection:
proj: eqc
ellps: WGS84
shape:
height: 480
width: 640
area_extent:
lower_left_xy: [-20037508.34, -10018754.17]
upper_right_xy: [20037508.34, 10018754.17]
**Example usage:**
.. doctest::
>>> import numpy as np
>>> from pyresample import load_area, save_quicklook, SwathDefinition
>>> from pyresample.kd_tree import resample_nearest
>>> lons = np.zeros(1000)
>>> lats = np.arange(-80, -90, -0.01)
>>> tb37v = np.arange(1000)
>>> area_def = load_area('areas.cfg', 'pc_world')
>>> area_def = load_area('areas.yaml', 'pc_world')
>>> swath_def = SwathDefinition(lons, lats)
>>> result = resample_nearest(swath_def, tb37v, area_def, radius_of_influence=20000, fill_value=None)
>>> save_quicklook('tb37v_pc.png', area_def, result, num_meridians=0, num_parallels=0, label='Tb 37v (K)')
>>> save_quicklook('tb37v_pc.png', area_def, result, num_meridians=None, num_parallels=None, label='Tb 37v (K)')
Assuming **lons**, **lats** and **tb37v** are initialized with real data (like
above we use AMSR-2 data in this example) the result might look something like
this:
Assuming **lons**, **lats** and **tb37v** are initialized with real data the result might look something like this:
.. image:: _static/images/tb37v_pc.png
......@@ -72,34 +102,44 @@ The Globe projections
From v0.7.12 pyresample can use the geos, ortho and nsper projections with
Basemap. Starting with v1.9.0 quicklooks are now generated with Cartopy which
should also work with these projections. Assuming the file **areas.cfg** has
should also work with these projections. Assuming the file **areas.yaml** has
the following area definition for an ortho projection area:
.. code-block:: bash
REGION: ortho {
NAME: Ortho globe
PCS_ID: ortho_globe
PCS_DEF: proj=ortho, a=6370997.0, lon_0=40, lat_0=-40
XSIZE: 640
YSIZE: 480
AREA_EXTENT: (-10000000, -10000000, 10000000, 10000000)
};
ortho:
description: Ortho globe
projection:
proj: ortho
lon_0: 40.
lat_0: -40.
a: 6370997.0
shape:
height: 480
width: 640
area_extent:
lower_left_xy: [-10000000, -10000000]
upper_right_xy: [10000000, 10000000]
**Example usage:**
.. doctest::
>>> import numpy as np
>>> from pyresample import load_area, save_quicklook, SwathDefinition
>>> from pyresample.kd_tree import resample_nearest
>>> lons = np.zeros(1000)
>>> lats = np.arange(-80, -90, -0.01)
>>> tb37v = np.arange(1000)
>>> area_def = load_area('areas.cfg', 'ortho')
>>> area_def = load_area('areas.yaml', 'ortho')
>>> swath_def = SwathDefinition(lons, lats)
>>> result = resample_nearest(swath_def, tb37v, area_def, radius_of_influence=20000, fill_value=None)
>>> save_quicklook('tb37v_ortho.png', area_def, result, num_meridians=0, num_parallels=0, label='Tb 37v (K)')
>>> save_quicklook('tb37v_ortho.png', area_def, result, num_meridians=None, num_parallels=None, label='Tb 37v (K)')
Assuming **lons**, **lats** and **tb37v** are initialized with real data, like
in the above examples, the result might look something like this:
Assuming **lons**, **lats** and **tb37v** are initialized with real data the result might look something like this:
.. image:: _static/images/tb37v_ortho.png
......@@ -107,24 +147,31 @@ Getting a Cartopy CRS
---------------------
To make more advanced plots than the preconfigured quicklooks Cartopy can be
used to work with mapped data alongside matplotlib. The below code is based
on
`this <http://scitools.org.uk/cartopy/docs/v0.16/gallery/geostationary.html>`_
Cartopy example. Pyresample allows any `AreaDefinition` to be converted to a
Cartopy CRS as long as Cartopy can represent the projection. Once an
AreaDefinition is converted to a CRS object it can be used like any other
Cartopy CRS object.
used to work with mapped data alongside matplotlib. The below code is based on
this `Cartopy gallery example`_. Pyresample allows any `AreaDefinition` to be
converted to a Cartopy CRS as long as Cartopy can represent the
projection. Once an `AreaDefinition` is converted to a CRS object it can be
used like any other Cartopy CRS object.
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from pyresample import load_area, save_quicklook, SwathDefinition
>>> from pyresample import load_area, SwathDefinition
>>> from pyresample.kd_tree import resample_nearest
>>> from pyresample.geometry import AreaDefinition
>>> lons = np.zeros(1000)
>>> lats = np.arange(-80, -90, -0.01)
>>> i04_data = np.arange(1000)
>>> tb37v = np.arange(1000)
>>> swath_def = SwathDefinition(lons, lats)
>>> area_def = swath_def.compute_optimal_bb_area({'proj': 'lcc', 'lon_0': -95., 'lat_0': 25., 'lat_1': 25., 'lat_2': 25.})
>>> result = resample_nearest(swath_def, i04_data, area_def,
>>> area_id = 'alaska'
>>> description = 'Alaska Lambert Equal Area grid'
>>> proj_id = 'alaska'
>>> projection = {'proj': 'stere', 'lat_0': 62., 'lon_0': -152.5, 'ellps': 'WGS84', 'units': 'm'}
>>> width = 2019
>>> height = 1463
>>> area_extent = (-757214.993104, -485904.321517, 757214.993104, 611533.818622)
>>> area_def = AreaDefinition(area_id, description, proj_id, projection,
... width, height, area_extent)
>>> result = resample_nearest(swath_def, tb37v, area_def,
... radius_of_influence=20000, fill_value=None)
>>> crs = area_def.to_cartopy_crs()
>>> ax = plt.axes(projection=crs)
......@@ -132,12 +179,12 @@ Cartopy CRS object.
>>> ax.set_global()
>>> plt.imshow(result, transform=crs, extent=crs.bounds, origin='upper')
>>> plt.colorbar()
>>> plt.savefig('viirs_i04_cartopy.png')
>>> plt.savefig('amsr2_tb37v_cartopy.png')
Assuming **lons**, **lats**, and **i04_data** are initialized with real data
the result might look something like this:
.. image:: _static/images/viirs_i04_cartopy.png
.. image:: _static/images/amsr2_tb37v_cartopy.png
Getting a Basemap object
------------------------
......@@ -159,19 +206,66 @@ AreaDefinition using the **plot.area_def2basemap(area_def, **kwargs)** function.
>>> lons = np.zeros(1000)
>>> lats = np.arange(-80, -90, -0.01)
>>> tb37v = np.arange(1000)
>>> area_def = load_area('areas.cfg', 'ease_sh')
>>> area_def = load_area('areas.yaml', 'ease_sh')
>>> swath_def = SwathDefinition(lons, lats)
>>> result = resample_nearest(swath_def, tb37v, area_def,
... radius_of_influence=20000, fill_value=None)
>>> bmap = area_def2basemap(area_def)
>>> bmng = bmap.bluemarble()
>>> col = bmap.imshow(result, origin='upper')
>>> col = bmap.imshow(result, origin='upper', cmap='RdBu_r')
>>> plt.savefig('tb37v_bmng.png', bbox_inches='tight')
Assuming **lons**, **lats** and **tb37v** are initialized with real data the result might look something like this:
Assuming **lons**, **lats** and **tb37v** are initialized with real data as in
the previous examples the result might look something like this:
.. image:: _static/images/tb37v_bmng.png
Any keyword arguments (not concerning the projection) passed to **plot.area_def2basemap** will be passed
directly to the Basemap initialization.
Any keyword arguments (not concerning the projection) passed to
**plot.area_def2basemap** will be passed directly to the Basemap
initialization.
For more information on how to plot with Basemap please refer to the Basemap
and matplotlib documentation.
Adding background maps with Cartopy
-----------------------------------
As mentioned in the above warning Cartopy should be used rather than Basemap as
the latter is not maintained anymore.
The above image can be generated using Cartopy instead by utilizing the method
`to_cartopy_crs` of the `AreaDefinition` object.
**Example usage:**
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from pyresample import load_area, save_quicklook, area_def2basemap, SwathDefinition
>>> from pyresample.kd_tree import resample_nearest
>>> lons = np.zeros(1000)
>>> lats = np.arange(-80, -90, -0.01)
>>> tb37v = np.arange(1000)
>>> area_def = load_area('areas.yaml', 'ease_sh')
>>> swath_def = SwathDefinition(lons, lats)
>>> result = resample_nearest(swath_def, tb37v, area_def,
... radius_of_influence=20000, fill_value=None)
>>> import matplotlib.pyplot as plt
>>> crs = area_def.to_cartopy_crs()
>>> ax = plt.axes(projection=crs)
>>> ax.background_img(name='BM')
>>> plt.imshow(result, transform=crs, extent=crs.bounds, origin='upper', cmap='RdBu_r')
>>> plt.savefig('tb37v_bmng.png', bbox_inches='tight')
For more information on how to plot with Basemap please refer to the Basemap and matplotlib documentation.
The above provides you have the Bluemarble background data available in the
Cartopy standard place or in a directory pointed to by the environment
parameter `CARTOPY_USER_BACKGROUNDS`.
With real data (same AMSR-2 as above) this might look like this:
.. image:: _static/images/tb37v_bmng_cartopy.png
.. _Satpy: http://www.github.com/pytroll/satpy
.. _zenodo: https://doi.org/10.5281/zenodo.3553696
.. _`Cartopy gallery example`: http://scitools.org.uk/cartopy/docs/v0.16/gallery/geostationary.html
.. _Cartopy: http://scitools.org.uk/cartopy/