From 589b66e7c1b6a973ea48cb838d13d9c9a0032f85 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Mon, 25 Jul 2022 11:57:54 -0400 Subject: [PATCH] Copy tilesource instances to add styles Instead of reopening a tilesource when adding a style, copy the unstyled class and add the style information. --- large_image/cache_util/cache.py | 12 ++++++++++++ large_image/tilesource/base.py | 10 +++++++++- sources/gdal/large_image_source_gdal/__init__.py | 10 ++++++++++ sources/mapnik/large_image_source_mapnik/__init__.py | 4 +++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/large_image/cache_util/cache.py b/large_image/cache_util/cache.py index 8ae303a2c..706b452a9 100644 --- a/large_image/cache_util/cache.py +++ b/large_image/cache_util/cache.py @@ -1,3 +1,4 @@ +import copy import functools import threading @@ -193,6 +194,17 @@ def __call__(cls, *args, **kwargs): # noqa - N805 return result except KeyError: pass + # This conditionally copies a non-styled class and add a style. + if kwargs.get('style') and hasattr(cls, '_setStyle'): + subkwargs = kwargs.copy() + subkwargs.pop('style') + subresult = cls(*args, **subkwargs) + result = copy.copy(subresult) + result._setStyle(kwargs['style']) + result._classkey = key + with cacheLock: + cache[key] = result + return result try: instance = super().__call__(*args, **kwargs) except Exception as exc: diff --git a/large_image/tilesource/base.py b/large_image/tilesource/base.py index 72d2a2635..e9a1f17e4 100644 --- a/large_image/tilesource/base.py +++ b/large_image/tilesource/base.py @@ -127,7 +127,6 @@ def __init__(self, encoding='JPEG', jpegQuality=95, jpegSubsampling=0, self.sizeX = None self.sizeY = None self._styleLock = threading.RLock() - self._bandRanges = {} if encoding not in TileOutputMimeTypes: raise ValueError('Invalid encoding "%s"' % encoding) @@ -137,6 +136,15 @@ def __init__(self, encoding='JPEG', jpegQuality=95, jpegSubsampling=0, self.jpegSubsampling = int(jpegSubsampling) self.tiffCompression = tiffCompression self.edge = edge + self._setStyle(style) + + def _setStyle(self, style): + """ + Check and set the specified style from a json string or a dictionary. + + :param style: The new style. + """ + self._bandRanges = {} self._jsonstyle = style if style: if isinstance(style, dict): diff --git a/sources/gdal/large_image_source_gdal/__init__.py b/sources/gdal/large_image_source_gdal/__init__.py index c3aa721b0..23ec85ead 100644 --- a/sources/gdal/large_image_source_gdal/__init__.py +++ b/sources/gdal/large_image_source_gdal/__init__.py @@ -183,6 +183,16 @@ def __init__(self, path, projection=None, unitsPerPixel=None, **kwargs): self._getTileLock = threading.Lock() self._setDefaultStyle() + def _setStyle(self, style): + """ + Check and set the specified style from a json string or a dictionary. + + :param style: The new style. + """ + super()._setStyle(style) + if hasattr(self, '_getTileLock'): + self._setDefaultStyle() + def _getLargeImagePath(self): """Get GDAL-compatible image path. diff --git a/sources/mapnik/large_image_source_mapnik/__init__.py b/sources/mapnik/large_image_source_mapnik/__init__.py index 5a382d672..e3e9b0aa0 100644 --- a/sources/mapnik/large_image_source_mapnik/__init__.py +++ b/sources/mapnik/large_image_source_mapnik/__init__.py @@ -177,7 +177,9 @@ def _checkNetCDF(self): def _setDefaultStyle(self): """Don't inherit from GDAL tilesource.""" - pass + with self._getTileLock: + if hasattr(self, '_mapnikMap'): + del self._mapnikMap @staticmethod def interpolateMinMax(start, stop, count):