diff --git a/.github/workflows/basemap-data-hires.yml b/.github/workflows/basemap-data-hires.yml index a17c75bef..a33ddb149 100644 --- a/.github/workflows/basemap-data-hires.yml +++ b/.github/workflows/basemap-data-hires.yml @@ -27,10 +27,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Upload checkout - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: checkout path: . @@ -43,11 +43,11 @@ jobs: max-parallel: 1 needs: checkout runs-on: ubuntu-latest - container: "pylegacy/python:${{ matrix.python-version }}-debian-9" + container: "pylegacy/python:${{ matrix.python-version }}-debian-10" steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . @@ -59,7 +59,7 @@ jobs: pip wheel -w dist --no-deps dist/*.zip - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: artifacts-build path: ${{ env.PKGDIR }}/dist @@ -69,22 +69,22 @@ jobs: matrix: python-version: ["2.6", "2.7", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8", - "3.9", "3.10", "3.11"] + "3.9", "3.10", "3.11", "3.12"] max-parallel: 3 fail-fast: false needs: build runs-on: ubuntu-latest - container: "pylegacy/python:${{ matrix.python-version }}-debian-9" + container: "pylegacy/python:${{ matrix.python-version }}-debian-10" steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifacts-build path: ${{ env.PKGDIR }}/dist @@ -106,12 +106,12 @@ jobs: if: startsWith(github.event.ref, 'refs/tags/v') needs: test runs-on: ubuntu-latest - container: "pylegacy/python:${{ matrix.python-version }}-debian-9" + container: "pylegacy/python:${{ matrix.python-version }}-debian-10" environment: PyPI steps: - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifacts-build path: ${{ env.PKGDIR }}/dist diff --git a/.github/workflows/basemap-data.yml b/.github/workflows/basemap-data.yml index 60fabb8ad..629213f31 100644 --- a/.github/workflows/basemap-data.yml +++ b/.github/workflows/basemap-data.yml @@ -27,10 +27,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Upload checkout - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: checkout path: . @@ -43,11 +43,11 @@ jobs: max-parallel: 1 needs: checkout runs-on: ubuntu-latest - container: "pylegacy/python:${{ matrix.python-version }}-debian-9" + container: "pylegacy/python:${{ matrix.python-version }}-debian-10" steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . @@ -59,7 +59,7 @@ jobs: pip wheel -w dist --no-deps dist/*.zip - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: artifacts-build path: ${{ env.PKGDIR }}/dist @@ -69,22 +69,22 @@ jobs: matrix: python-version: ["2.6", "2.7", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8", - "3.9", "3.10", "3.11"] + "3.9", "3.10", "3.11", "3.12"] max-parallel: 3 fail-fast: false needs: build runs-on: ubuntu-latest - container: "pylegacy/python:${{ matrix.python-version }}-debian-9" + container: "pylegacy/python:${{ matrix.python-version }}-debian-10" steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifacts-build path: ${{ env.PKGDIR }}/dist @@ -106,12 +106,12 @@ jobs: if: startsWith(github.event.ref, 'refs/tags/v') needs: test runs-on: ubuntu-latest - container: "pylegacy/python:${{ matrix.python-version }}-debian-9" + container: "pylegacy/python:${{ matrix.python-version }}-debian-10" environment: PyPI steps: - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifacts-build path: ${{ env.PKGDIR }}/dist diff --git a/.github/workflows/basemap-for-manylinux.yml b/.github/workflows/basemap-for-manylinux.yml index 35243d8a5..cdd577b17 100644 --- a/.github/workflows/basemap-for-manylinux.yml +++ b/.github/workflows/basemap-for-manylinux.yml @@ -311,7 +311,7 @@ jobs: name: Upload test artifacts uses: actions/upload-artifact@v1 with: - name: test + name: artifacts-test path: ${{ env.PKGDIR }}/.coverage.${{ matrix.python-version }} coverage: @@ -326,7 +326,7 @@ jobs: name: Download test artifacts uses: actions/download-artifact@v1 with: - name: test + name: artifacts-test path: ${{ env.PKGDIR }} - name: Install test requirements @@ -344,7 +344,7 @@ jobs: name: Upload coverage artifacts uses: actions/upload-artifact@v1 with: - name: coverage + name: artifacts-coverage path: ${{ env.PKGDIR }}/htmlcov docs: @@ -383,13 +383,13 @@ jobs: name: Upload docs artifacts uses: actions/upload-artifact@v1 with: - name: docs + name: artifacts-docs path: ${{ env.PKGDIR }}/public - name: Upload github-pages artifact - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v3 with: - name: github-pages + name: artifacts-github-pages path: ${{ env.PKGDIR }}/public pages: @@ -404,7 +404,7 @@ jobs: id-token: write steps: - name: Deploy github-pages - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v3 id: deployment upload: diff --git a/.github/workflows/basemap-for-windows.yml b/.github/workflows/basemap-for-windows.yml index 69b23d645..92eb337fc 100644 --- a/.github/workflows/basemap-for-windows.yml +++ b/.github/workflows/basemap-for-windows.yml @@ -29,10 +29,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Upload checkout - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: checkout path: . @@ -49,7 +49,7 @@ jobs: steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . @@ -109,7 +109,7 @@ jobs: steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . @@ -121,7 +121,7 @@ jobs: toolset: ${{ matrix.msvc-toolset }} - name: Set CMake - uses: jwlawson/actions-setup-cmake@v1.13 + uses: jwlawson/actions-setup-cmake@v2.0 with: cmake-version: "3.24.2" - @@ -137,7 +137,7 @@ jobs: python -c "import utils; utils.GeosLibrary('3.6.5').build('extern', toolset='${{ matrix.msvc-toolset }}', njobs=16)" - name: Upload GEOS artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: artifacts-geos-${{ matrix.arch }}-msvc${{ matrix.msvc-toolset }} path: ${{ env.PKGDIR }}/extern @@ -156,7 +156,7 @@ jobs: steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . @@ -198,7 +198,7 @@ jobs: toolset: ${{ env.msvc-toolset }} - name: Download GEOS artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifacts-geos-${{ matrix.arch }}-msvc${{ env.msvc-toolset }} path: ${{ env.PKGDIR }}/extern @@ -212,7 +212,7 @@ jobs: python -m pip wheel -w dist --no-deps (Get-Item dist/*.zip) - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }} path: ${{ env.PKGDIR }}/dist @@ -235,13 +235,13 @@ jobs: steps: - name: Download checkout - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: checkout path: . - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }} path: ${{ env.PKGDIR }}/dist @@ -269,16 +269,16 @@ jobs: name: Test package run: | cd ${{ env.PKGDIR }} - $env:COVERAGE_FILE = ".coverage.${{ matrix.python-version }}" + $env:COVERAGE_FILE = ".coverage.${{ matrix.arch }}.${{ matrix.python-version }}" python -m pytest ` --cov="mpl_toolkits.basemap" --cov-report=term ` --ignore=dist --ignore=build - name: Upload test artifacts - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: - name: test - path: ${{ env.PKGDIR }}/.coverage.${{ matrix.python-version }} + name: artifacts-test-${{ matrix.arch }}-${{ matrix.python-version }} + path: ${{ env.PKGDIR }}/.coverage.${{ matrix.arch }}.${{ matrix.python-version }} upload: strategy: @@ -301,7 +301,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }} path: ${{ env.PKGDIR }}/dist diff --git a/CHANGELOG.md b/CHANGELOG.md index bf6bec7e2..d9bdc4fa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,21 @@ https://keepachangelog.com/en/1.0.0/ https://semver.org/spec/v2.0.0.html +## [1.4.1] - 2024-02-15 + +### Changed +- Update workflow actions to use NodeJS 20: + - Update base actions from v3 to v4 when possible (`actions/checkout`, + `actions/upload-artifact` and `actions/download-artifact`). + - Update `jwlawson/actions-setup-cmake` from v1.13 to v2.0. +- Update base image for `basemap-data` and `basemap-data-hires` + GitHub workflows to use Debian 10. + +### Fixed +- Set recursive exclusion for `.DS_Store` folders in `MANIFEST.in`. +- Fix broken implementation and docstrings of `Basemap.arcgisimage` + method (PR [#598] by @nitram96). + ## [1.4.0] - 2024-01-09 ### Added @@ -20,7 +35,8 @@ https://semver.org/spec/v2.0.0.html [#447] and [#574]). - Renewed documentation, with fixes for the broken links and examples, an improved section on the installation process, and without the - deprecation/sunsetting section (solves issues [#527] and [#568]). + deprecation/sunsetting section (solves issues [#438], [#471], [#527] + and [#568]). - Optional argument `encoding_errors` for `Basemap.readshapefile` method (PR [#554] by @guziy, implements request [#552]). - Optional argument `cachedir` for `Basemap.arcgisimage` method to allow @@ -1080,6 +1096,8 @@ https://semver.org/spec/v2.0.0.html - Fix glitches in drawing of parallels and meridians. +[#598]: +https://github.com/matplotlib/basemap/pull/598 [#595]: https://github.com/matplotlib/basemap/pull/595 [#594]: @@ -1194,6 +1212,8 @@ https://github.com/matplotlib/basemap/issues/487 https://github.com/matplotlib/basemap/issues/481 [#476]: https://github.com/matplotlib/basemap/pull/476 +[#471]: +https://github.com/matplotlib/basemap/issues/471 [#463]: https://github.com/matplotlib/basemap/issues/463 [#461]: @@ -1208,6 +1228,8 @@ https://github.com/matplotlib/basemap/issues/445 https://github.com/matplotlib/basemap/issues/444 [#443]: https://github.com/matplotlib/basemap/issues/443 +[#438]: +https://github.com/matplotlib/basemap/issues/438 [#437]: https://github.com/matplotlib/basemap/issues/437 [#436]: @@ -1230,7 +1252,9 @@ https://github.com/matplotlib/basemap/issues/228 https://github.com/matplotlib/basemap/issues/179 [Unreleased]: -https://github.com/matplotlib/basemap/compare/v1.4.0...develop +https://github.com/matplotlib/basemap/compare/v1.4.1...develop +[1.4.1]: +https://github.com/matplotlib/basemap/compare/v1.4.0...v1.4.1 [1.4.0]: https://github.com/matplotlib/basemap/compare/v1.3.9...v1.4.0 [1.3.9]: diff --git a/README.md b/README.md index 0f6c19781..21b98ad39 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,9 @@ python -m pip install basemap-data python -m pip install basemap-data-hires ``` -Precompiled `basemap` binary wheels for Windows and GNU/Linux are also -available in PyPI (architectures x86 and x64, Python 2.7 and 3.5+): +Precompiled `basemap` binary wheels for Windows and GNU/Linux +(architectures x86 and x64, Python 2.7 and 3.5+) as well as for MacOS +(architectures x64 and arm64, Python 3.9+) are also available in PyPI: ```sh python -m pip install basemap ``` diff --git a/packages/basemap/MANIFEST.in b/packages/basemap/MANIFEST.in index 0ea74f384..93b419369 100644 --- a/packages/basemap/MANIFEST.in +++ b/packages/basemap/MANIFEST.in @@ -4,5 +4,6 @@ recursive-exclude doc/build * recursive-include test * recursive-include utils *.py recursive-exclude **/__pycache__ * +recursive-exclude **/.DS_Store * exclude **/*.pyc exclude **/.gitkeep diff --git a/packages/basemap/README.md b/packages/basemap/README.md index 622e56303..be631e774 100644 --- a/packages/basemap/README.md +++ b/packages/basemap/README.md @@ -45,6 +45,6 @@ https://spdx.org/licenses/LGPL-2.1-only.html https://spdx.org/licenses/MIT.html [`LICENSE`]: -https://github.com/matplotlib/basemap/blob/v1.4.0/packages/basemap/LICENSE +https://github.com/matplotlib/basemap/blob/v1.4.1/packages/basemap/LICENSE [`LICENSE.geos`]: -https://github.com/matplotlib/basemap/blob/v1.4.0/packages/basemap/LICENSE.geos +https://github.com/matplotlib/basemap/blob/v1.4.1/packages/basemap/LICENSE.geos diff --git a/packages/basemap/requirements-doc.txt b/packages/basemap/requirements-doc.txt index 229abc2ac..385d1e158 100644 --- a/packages/basemap/requirements-doc.txt +++ b/packages/basemap/requirements-doc.txt @@ -2,5 +2,5 @@ sphinx >= 5.3, < 7.2; python_version >= "3.8" furo >= 2022.4.7, < 2023.9.11; python_version >= "3.8" scipy >= 1.2, < 1.12; python_version >= "3.5" -netCDF4 >= 1.5.6, < 1.7.0; python_version >= "3.6" cftime >= 1.4.0, < 1.7.0; python_version >= "3.6" +netCDF4 >= 1.5.6, < 1.7.0; python_version >= "3.6" diff --git a/packages/basemap/src/_geoslib.pyx b/packages/basemap/src/_geoslib.pyx index f91dd333b..1e2ced532 100644 --- a/packages/basemap/src/_geoslib.pyx +++ b/packages/basemap/src/_geoslib.pyx @@ -2,7 +2,7 @@ import sys import numpy cimport numpy as cnp -__version__ = "1.4.0" +__version__ = "1.4.1" # Need some Python C-API functions for strings. diff --git a/packages/basemap/src/mpl_toolkits/basemap/__init__.py b/packages/basemap/src/mpl_toolkits/basemap/__init__.py index e1ce7afc6..651a2dd5a 100644 --- a/packages/basemap/src/mpl_toolkits/basemap/__init__.py +++ b/packages/basemap/src/mpl_toolkits/basemap/__init__.py @@ -48,7 +48,7 @@ from . proj import Proj -__version__ = "1.4.0" +__version__ = "1.4.1" # basemap data files now installed in lib/matplotlib/toolkits/basemap/data # check to see if environment variable BASEMAPDATA set to a directory, @@ -4257,45 +4257,56 @@ def pil_to_array(*args, **kwargs): im,c = self._cliplimb(ax,im) return im - def arcgisimage(self,server='http://server.arcgisonline.com/ArcGIS',\ - service='World_Imagery',xpixels=400,ypixels=None,\ - dpi=96,cachedir=None,verbose=False,**kwargs): - """ - Retrieve an image using the ArcGIS Server REST API and display it on - the map. In order to use this method, the Basemap instance must be - created using the ``epsg`` keyword to define the map projection, unless - the ``cyl`` projection is used (in which case the epsg code 4326 is - assumed). + def arcgisimage(self, server="http://server.arcgisonline.com/ArcGIS", + service="World_Imagery", xpixels=400, ypixels=None, + dpi=96, cachedir=None, verbose=False, **kwargs): + r"""Display background image using ArcGIS Server REST API. - .. tabularcolumns:: |l|L| + In order to use this method, the :class:`Basemap` instance + must be created using the ``epsg`` keyword to define the + map projection, unless the "cyl" projection is used (in + which case the EPSG code 4326 is assumed). - ============== ==================================================== - Keywords Description - ============== ==================================================== - server web map server URL (default - http://server.arcgisonline.com/ArcGIS). - service service (image type) hosted on server (default - 'World_Imagery', which is NASA 'Blue Marble' - image). - xpixels requested number of image pixels in x-direction - (default 400). - ypixels requested number of image pixels in y-direction. - Default (None) is to infer the number from - from xpixels and the aspect ratio of the - map projection region. - dpi The device resolution of the exported image (dots per - inch, default 96). - cachedir An optional directory to use as cache folder for the retrieved images. - verbose if True, print URL used to retrieve image (default - False). - ============== ==================================================== + Parameters + ---------- - Extra keyword ``ax`` can be used to override the default axis instance. + server : str, optional + base URL of the web map server - returns a matplotlib.image.AxesImage instance. + service : str, optional + service (image type) hosted by the server + + xpixels : int, optional + requested number of image pixels in the `x`-direction + + ypixels : int, optional + requested number of image pixels in the `y`-direction; + if not given, it is inferred from ``xpixels`` and the + aspect ratio of the map projection region + + dpi : int, optional + device resolution of the exported image + + cachedir : str, optional + if given, directory to use as cache folder for the images + retrieved from the server + + verbose : bool, optional + if True, print debugging information + + \**kwargs : dict, optional + keyword-only arguments; currently, only ``ax`` is supported + to override the default :class:`matplotlib.axes.Axes` + instance + + Returns + ------- + + aximg : matplotlib.image.AxesImage + image axes instance """ - # fix PIL import on some versions of OSX and scipy + # Fix PIL import on some versions of OSX and scipy. try: from PIL import Image except ImportError: @@ -4305,70 +4316,71 @@ def arcgisimage(self,server='http://server.arcgisonline.com/ArcGIS',\ raise ImportError("arcgisimage method requires PIL " "(http://pillow.readthedocs.io)") - if not hasattr(self,'epsg'): + if not hasattr(self, "epsg"): raise ValueError("the Basemap instance must be created using " "an EPSG code (http://spatialreference.org) " "in order to use the wmsmap method") - ax = kwargs.pop('ax', None) or self._check_ax() - # find the x,y values at the corner points. + + ax = kwargs.pop("ax", None) or self._check_ax() + + # Find the `(x, y)` values at the corner points. with warnings.catch_warnings(): warnings.simplefilter("ignore", category=FutureWarning) p = pyproj.Proj(init="epsg:%s" % self.epsg, preserve_units=True) - xmin,ymin = p(self.llcrnrlon,self.llcrnrlat) - xmax,ymax = p(self.urcrnrlon,self.urcrnrlat) + xmin, ymin = p(self.llcrnrlon, self.llcrnrlat) + xmax, ymax = p(self.urcrnrlon, self.urcrnrlat) if self.projection in _cylproj: - Dateline =\ - _geoslib.Point(self(180.,0.5*(self.llcrnrlat+self.urcrnrlat))) - hasDateline = Dateline.within(self._boundarypolyxy) - if hasDateline: + dateline = _geoslib.Point(self(180., 0.5 * (self.llcrnrlat + self.urcrnrlat))) + if dateline.within(self._boundarypolyxy): raise ValueError("arcgisimage cannot handle images that cross " "the dateline for cylindrical projections") - # ypixels not given, find by scaling xpixels by the map aspect ratio. + + # If ypixels is not given, compute it with xpixels and aspect ratio. if ypixels is None: - ypixels = int(self.aspect*xpixels) - # construct a URL using the ArcGIS Server REST API. - basemap_url = \ -"%s/rest/services/%s/MapServer/export?\ -bbox=%s,%s,%s,%s&\ -bboxSR=%s&\ -imageSR=%s&\ -size=%s,%s&\ -dpi=%s&\ -format=png32&\ -transparent=true&\ -f=image" %\ -(server,service,xmin,ymin,xmax,ymax,self.epsg,self.epsg,xpixels,ypixels,dpi) - # print URL? - if verbose: print(basemap_url) - - if cachedir != None: + ypixels = int(self.aspect * xpixels) + + # Construct a URL using the ArcGIS Server REST API. + basemap_url = "".join([ + "%s/rest/services/%s/MapServer/export?", + "bbox=%s,%s,%s,%s&", + "bboxSR=%s&", + "imageSR=%s&", + "size=%s,%s&", + "dpi=%s&", + "format=png32&", + "transparent=true&", + "f=image", + ]) % (server, service, xmin, ymin, xmax, ymax, self.epsg, self.epsg, xpixels, ypixels, dpi) + + # Print URL in verbose mode. + if verbose: # pragma: no cover + print(basemap_url) + + # Try to return fast if cache is enabled. + if cachedir is not None: # Generate a filename for the cached file. - filename = "%s-bbox-%s-%s-%s-%s-bboxsr%s-imagesr%s-size-%s-%s-dpi%s.png" %\ - (service,xmin,ymin,xmax,ymax,self.epsg,self.epsg,xpixels,ypixels,dpi) - - # Check if the cache directory exists, if not create it. - if not os.path.exists(cachedir): - os.makedirs(cachedir) - - # Check if the image is already in the cachedir folder. - cache_path = cachedir + filename - - if os.path.isfile(cache_path) and verbose: - print('Image already in cache') + filename = "%s-bbox-%s-%s-%s-%s-bboxsr%s-imagesr%s-size-%s-%s-dpi%s.png" % \ + (service, xmin, ymin, xmax, ymax, self.epsg, self.epsg, xpixels, ypixels, dpi) + # Return fast if the image is already in the cache. + cache_path = os.path.join(cachedir, filename) + if os.path.isfile(cache_path): + if verbose: # pragma: no cover + print("Image already in cache") img = Image.open(cache_path) - return basemap.imshow(img, ax=ax, origin='upper') + return self.imshow(img, ax=ax, origin="upper") - # Retrieve image from remote server. + # Retrieve image from the remote server. import contextlib conn = urlopen(basemap_url) with contextlib.closing(conn): img = Image.open(conn) # Save to cache if requested. - if cachedir != None: + if cachedir is not None: + # Check if the cache directory exists, if not create it. + if not os.path.exists(cachedir): + os.makedirs(cachedir) img.save(cache_path) - - # Return AxesImage instance. - return self.imshow(img, ax=ax, origin='upper') + return self.imshow(img, ax=ax, origin="upper") def wmsimage(self,server,\ xpixels=400,ypixels=None,\ diff --git a/packages/basemap/test/mpl_toolkits/basemap/test_Basemap.py b/packages/basemap/test/mpl_toolkits/basemap/test_Basemap.py index 2565c1569..6a94d291f 100644 --- a/packages/basemap/test/mpl_toolkits/basemap/test_Basemap.py +++ b/packages/basemap/test/mpl_toolkits/basemap/test_Basemap.py @@ -1,5 +1,8 @@ """Import test for the :mod:`mpl_toolkits.basemap.Basemap` class.""" +import os +import shutil +import tempfile import datetime as dt try: import unittest2 as unittest @@ -145,6 +148,49 @@ def test_arcgisimage_with_cyl(self, axs=None, axslen0=10): axs_children = axs_obj.get_children() self.assertEqual(len(axs_children), axslen0 + 1) + @unittest.skipIf(PIL is None, reason="pillow unavailable") + def test_arcgisimage_with_cyl_using_cache(self, existing=False, axs=None, axslen0=10): + """Test showing an ArcGIS image as background.""" + + axs_obj = plt.gca() if axs is None else axs + axs_children = axs_obj.get_children() + self.assertEqual(len(axs_children), axslen0) + + bmap = Basemap(ax=axs, projection="cyl", resolution=None, + llcrnrlon=-90, llcrnrlat=30, + urcrnrlon=-60, urcrnrlat=60) + + # Create cache directory string and check it is empty. + tmpdir = tempfile.mkdtemp(prefix="tmp-basemap-cachedir-") + cachedir = tmpdir if existing else os.path.join(tmpdir, "cachedir") + if os.path.isdir(cachedir): + self.assertEqual(len(os.listdir(cachedir)), 0) + + try: + # Check that the first call populates the cache. + img = bmap.arcgisimage(verbose=False, cachedir=cachedir) + self.assertEqual(len(os.listdir(cachedir)), 1) + # Check output properties after the first call. + self.assertIsInstance(img, AxesImage) + axs_children = axs_obj.get_children() + self.assertEqual(len(axs_children), axslen0 + 1) + # Check that the second call does not update the cache. + img = bmap.arcgisimage(verbose=False, cachedir=cachedir) + self.assertEqual(len(os.listdir(cachedir)), 1) + # Check output properties after the second call. + self.assertIsInstance(img, AxesImage) + axs_children = axs_obj.get_children() + self.assertEqual(len(axs_children), axslen0 + 2) + finally: + if os.path.isdir(tmpdir): + shutil.rmtree(tmpdir) + + @unittest.skipIf(PIL is None, reason="pillow unavailable") + def test_arcgisimage_with_cyl_using_cache_already_existing(self): + """Test showing an ArcGIS image as background.""" + + self.test_arcgisimage_with_cyl_using_cache(existing=True) + def _test_basemap_data_warpimage(self, method, axs=None, axslen0=10): """Test drawing a map background from :mod:`basemap_data`."""