From efb751395c230d0779968e1c95b88f0342f08032 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Tue, 6 Jul 2021 10:35:39 -0400 Subject: [PATCH] Improve proj init string handling. --- CHANGELOG.md | 6 +++++- sources/gdal/large_image_source_gdal/__init__.py | 11 ++++++----- sources/mapnik/large_image_source_mapnik/__init__.py | 12 +++++++++++- test/test_source_gdal.py | 6 +++--- test/test_source_mapnik.py | 6 +++--- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1014e3809..0c2fc09ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,13 @@ # Change Log -## Unreleased +## Version 1.6.2 ### Improvements - Better reporting of memcached cache (#613) +- Better handle whether proj string need the +init prefix (#620) + +### Changes +- Avoid a bad version of Pillow (#619) ## Version 1.6.1 diff --git a/sources/gdal/large_image_source_gdal/__init__.py b/sources/gdal/large_image_source_gdal/__init__.py index cf26c1f39..e8c66cc41 100644 --- a/sources/gdal/large_image_source_gdal/__init__.py +++ b/sources/gdal/large_image_source_gdal/__init__.py @@ -59,6 +59,7 @@ ProjUnitsAcrossLevel0_MaxSize = 100 InitPrefix = '+init=' +NeededInitPrefix = '' if int(pyproj.proj_version_str.split('.')[0]) >= 6 else InitPrefix class GDALFileTileSource(FileTileSource, metaclass=LruCacheMetaclass): @@ -117,7 +118,7 @@ def __init__(self, path, projection=None, unitsPerPixel=None, **kwargs): self.tileHeight = self.tileSize self._projection = projection if projection and projection.lower().startswith('epsg:'): - projection = InitPrefix + projection.lower() + projection = NeededInitPrefix + projection.lower() if projection and not isinstance(projection, bytes): projection = projection.encode('utf8') self.projection = projection @@ -288,7 +289,7 @@ def _initWithProjection(self, unitsPerPixel=None): """ Initialize aspects of the class when a projection is set. """ - inProj = self._proj4Proj(InitPrefix + 'epsg:4326') + inProj = self._proj4Proj(NeededInitPrefix + 'epsg:4326') # Since we already converted to bytes decoding is safe here outProj = self._proj4Proj(self.projection) if outProj.crs.is_geographic: @@ -362,7 +363,7 @@ def getProj4String(self): wkt = self.dataset.GetProjection() if not wkt: if hasattr(self, '_netcdf') or self._getDriver() in {'NITF'}: - return InitPrefix + 'epsg:4326' + return NeededInitPrefix + 'epsg:4326' return proj = osr.SpatialReference() proj.ImportFromWkt(wkt) @@ -375,7 +376,7 @@ def getPixelSizeInMeters(self): :returns: the pixel size in meters or None. """ - bounds = self.getBounds(InitPrefix + 'epsg:4326') + bounds = self.getBounds(NeededInitPrefix + 'epsg:4326') if not bounds: return geod = pyproj.Geod(ellps='WGS84') @@ -739,7 +740,7 @@ def _proj4Proj(proj): if proj.lower().startswith('proj4:'): proj = proj.split(':', 1)[1] if proj.lower().startswith('epsg:'): - proj = InitPrefix + proj.lower() + proj = NeededInitPrefix + proj.lower() try: if proj.startswith(InitPrefix) and int(pyproj.proj_version_str.split('.')[0]) >= 6: proj = proj[len(InitPrefix):] diff --git a/sources/mapnik/large_image_source_mapnik/__init__.py b/sources/mapnik/large_image_source_mapnik/__init__.py index 110834276..81c4bade9 100644 --- a/sources/mapnik/large_image_source_mapnik/__init__.py +++ b/sources/mapnik/large_image_source_mapnik/__init__.py @@ -36,6 +36,14 @@ mapnik.logger.set_severity(mapnik.severity_type.Debug) +try: + mapnik.Projection('epsg:3857') + NeededInitPrefix = '' +except RuntimeError: + mapnik.Projection(InitPrefix + 'epsg:3857') + NeededInitPrefix = InitPrefix + + class MapnikFileTileSource(GDALFileTileSource, metaclass=LruCacheMetaclass): """ Provides tile access to geospatial files. @@ -120,6 +128,8 @@ def __init__(self, path, projection=None, unitsPerPixel=None, **kwargs): projections that are not latlong (is_geographic is False) must specify unitsPerPixel. """ + if projection and projection.lower().startswith('epsg'): + projection = NeededInitPrefix + projection.lower() super().__init__( path, projection=projection, unitsPerPixel=unitsPerPixel, **kwargs) @@ -156,7 +166,7 @@ def _checkNetCDF(self): } if not len(datasets): try: - self.getBounds(InitPrefix + 'epsg:3857') + self.getBounds(NeededInitPrefix + 'epsg:3857') except RuntimeError: self._bounds.clear() del self._netcdf diff --git a/test/test_source_gdal.py b/test/test_source_gdal.py index 5c6a4a761..6b3ba2a71 100644 --- a/test/test_source_gdal.py +++ b/test/test_source_gdal.py @@ -83,7 +83,7 @@ def testTileFromGeotiffs(): assert tileMetadata['bounds']['xmin'] == pytest.approx(-13184900, 1) assert tileMetadata['bounds']['ymax'] == pytest.approx(4059661, 1) assert tileMetadata['bounds']['ymin'] == pytest.approx(3777034, 1) - assert tileMetadata['bounds']['srs'] == '+init=epsg:3857' + assert tileMetadata['bounds']['srs'] == 'epsg:3857' assert tileMetadata['geospatial'] source = large_image_source_gdal.open( @@ -316,7 +316,7 @@ def testPalettizedGeotiff(): assert tileMetadata['bounds']['xmin'] == pytest.approx(-8909162, 1) assert tileMetadata['bounds']['ymax'] == pytest.approx(5755717, 1) assert tileMetadata['bounds']['ymin'] == pytest.approx(4876273, 1) - assert tileMetadata['bounds']['srs'] == '+init=epsg:3857' + assert tileMetadata['bounds']['srs'] == 'epsg:3857' assert tileMetadata['geospatial'] image = source.getTile(37, 46, 7) image = PIL.Image.open(io.BytesIO(image)) @@ -372,7 +372,7 @@ def testGCPProjection(): assert tileMetadata['bounds']['xmin'] == pytest.approx(-10871650, 1) assert tileMetadata['bounds']['ymax'] == pytest.approx(3949393, 1) assert tileMetadata['bounds']['ymin'] == pytest.approx(3899358, 1) - assert tileMetadata['bounds']['srs'] == '+init=epsg:3857' + assert tileMetadata['bounds']['srs'] == 'epsg:3857' assert tileMetadata['geospatial'] diff --git a/test/test_source_mapnik.py b/test/test_source_mapnik.py index 6c27c87d5..f868e1e33 100644 --- a/test/test_source_mapnik.py +++ b/test/test_source_mapnik.py @@ -82,7 +82,7 @@ def testTileFromGeotiffs(): assert tileMetadata['bounds']['xmin'] == pytest.approx(-13184900, 1) assert tileMetadata['bounds']['ymax'] == pytest.approx(4059661, 1) assert tileMetadata['bounds']['ymin'] == pytest.approx(3777034, 1) - assert tileMetadata['bounds']['srs'] == '+init=epsg:3857' + assert tileMetadata['bounds']['srs'] in ('+init=epsg:3857', 'epsg:3857') assert tileMetadata['geospatial'] source = large_image_source_mapnik.open( @@ -344,7 +344,7 @@ def testTileFromNetCDF(): assert tileMetadata['sizeX'] == 93 assert tileMetadata['sizeY'] == 65 assert tileMetadata['levels'] == 1 - assert tileMetadata['bounds']['srs'].strip() == '+init=epsg:4326' + assert tileMetadata['bounds']['srs'].strip() == 'epsg:4326' assert tileMetadata['geospatial'] # Getting the metadata with a specified projection will be different @@ -357,7 +357,7 @@ def testTileFromNetCDF(): assert tileMetadata['sizeX'] == 512 assert tileMetadata['sizeY'] == 512 assert tileMetadata['levels'] == 2 - assert tileMetadata['bounds']['srs'] == '+init=epsg:3857' + assert tileMetadata['bounds']['srs'] in ('+init=epsg:3857', 'epsg:3857') assert tileMetadata['geospatial']