Skip to content

Commit 97a93af

Browse files
committed
fix: proper wrapping of multiply wrapped images
1 parent 2bec997 commit 97a93af

File tree

3 files changed

+87
-33
lines changed

3 files changed

+87
-33
lines changed

eoxserver/render/browse/objects.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def from_file(cls, filename, env=None, raster_styles=None):
151151
class GeneratedBrowse(Browse):
152152
def __init__(self, name, band_expressions, ranges, nodata_values,
153153
fields_and_coverages, field_list, footprint, raster_styles,
154-
variables, show_out_of_bounds_data=False,
154+
variables, show_out_of_bounds_data=False, env=None
155155
):
156156
self._name = name
157157
self._band_expressions = band_expressions
@@ -163,6 +163,7 @@ def __init__(self, name, band_expressions, ranges, nodata_values,
163163
self._raster_styles = raster_styles
164164
self._variables = variables
165165
self._show_out_of_bounds_data = show_out_of_bounds_data
166+
self._env = env or {}
166167

167168
@property
168169
def name(self):
@@ -244,6 +245,17 @@ def from_coverage_models(cls, band_expressions, ranges, nodata_values,
244245
for field_name, coverages in fields_and_coverage_models.items()
245246
}
246247

248+
env = None
249+
250+
for coverage_models in fields_and_coverage_models.values():
251+
for coverage_model in coverage_models:
252+
arraydata_item = coverage_model.arraydata_items.first()
253+
if arraydata_item:
254+
env = get_vsi_env(arraydata_item.storage)
255+
break
256+
if env:
257+
break
258+
247259
return cls(
248260
product_model.identifier,
249261
band_expressions,
@@ -259,6 +271,7 @@ def from_coverage_models(cls, band_expressions, ranges, nodata_values,
259271
raster_styles,
260272
variables,
261273
show_out_of_bounds_data,
274+
env,
262275
)
263276

264277

eoxserver/render/mapserver/factories.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,13 @@
6363
from eoxserver.render.colors import BASE_COLORS, COLOR_SCALES, OFFSITE_COLORS
6464
from eoxserver.resources.coverages import crss
6565
from eoxserver.resources.coverages.dateline import (
66-
extent_crosses_dateline, wrap_extent_around_dateline
66+
extent_crosses_dateline,
67+
get_extent_wrappings,
6768
)
6869
from eoxserver.processing.gdal import reftools
6970

7071
import logging
72+
7173
logger = logging.getLogger(__name__)
7274

7375

@@ -366,14 +368,16 @@ def make_browse_layer_generator(self, map_obj, browses, map_,
366368
creation_info, reset_info = (None, None)
367369

368370
layer_objs = _create_raster_layer_objs(
369-
map_obj, browse.extent, browse.spatial_reference,
370-
creation_info.filename if creation_info else '',
371-
filename_generator, {}
371+
map_obj,
372+
browse.extent,
373+
browse.spatial_reference,
374+
creation_info.filename if creation_info else "",
375+
filename_generator,
376+
browse.env,
372377
)
373378

374379
for layer_obj in layer_objs:
375380
if creation_info:
376-
layer_obj.data = creation_info.filename
377381
if creation_info.env:
378382
ms.set_env(map_obj, creation_info.env, True)
379383

@@ -479,8 +483,13 @@ def make_browse_layer_generator(self, map_obj, browses, map_,
479483

480484
elif isinstance(browse, Browse):
481485
layer_objs = _create_raster_layer_objs(
482-
map_obj, browse.extent, browse.spatial_reference,
483-
browse.filename, filename_generator, browse.env, browse.mode,
486+
map_obj,
487+
browse.extent,
488+
browse.spatial_reference,
489+
browse.filename,
490+
filename_generator,
491+
browse.env,
492+
browse.mode,
484493
)
485494
ms.set_env(map_obj, browse.env, True)
486495
elif browse is None:
@@ -828,32 +837,31 @@ def _create_raster_layer_objs(map_obj, extent, sr, data, filename_generator, env
828837
if resample:
829838
layer_obj.setProcessingKey('RESAMPLE', resample)
830839

840+
layers = [layer_obj]
831841
if extent and sr.srid and extent_crosses_dateline(extent, sr.srid):
832-
wrapped_extent = wrap_extent_around_dateline(extent, sr.srid)
833-
834-
wrapped_layer_obj = ms.layerObj(map_obj)
835-
wrapped_layer_obj.type = ms.MS_LAYER_RASTER
836-
wrapped_layer_obj.status = ms.MS_ON
837-
838-
wrapped_data = filename_generator.generate()
839-
with gdal.config_env(env):
840-
vrt.with_extent(data, wrapped_extent, wrapped_data)
841-
wrapped_layer_obj.data = wrapped_data
842-
# assumption that RGBA already has transparency in alpha band
843-
if browse_mode != BROWSE_MODE_RGBA:
844-
wrapped_layer_obj.offsite = ms.colorObj(0, 0, 0)
845-
846-
wrapped_layer_obj.metadata.set("ows_srs", short_epsg)
847-
wrapped_layer_obj.metadata.set("wms_srs", short_epsg)
848-
wrapped_layer_obj.setProjection(sr.proj)
849-
850-
wrapped_layer_obj.setExtent(*wrapped_extent)
851-
wrapped_layer_obj.metadata.set(
852-
"wms_extent", "%f %f %f %f" % wrapped_extent
853-
)
854-
return [layer_obj, wrapped_layer_obj]
855-
else:
856-
return [layer_obj]
842+
for wrapped_extent in get_extent_wrappings(extent, sr.srid):
843+
wrapped_layer_obj = ms.layerObj(map_obj)
844+
wrapped_layer_obj.type = ms.MS_LAYER_RASTER
845+
wrapped_layer_obj.status = ms.MS_ON
846+
847+
wrapped_data = filename_generator.generate()
848+
with gdal.config_env(env):
849+
vrt.with_extent(data, wrapped_extent, wrapped_data)
850+
wrapped_layer_obj.data = wrapped_data
851+
852+
# assumption that RGBA already has transparency in alpha band
853+
if browse_mode != BROWSE_MODE_RGBA:
854+
wrapped_layer_obj.offsite = ms.colorObj(0, 0, 0)
855+
856+
wrapped_layer_obj.metadata.set("ows_srs", short_epsg)
857+
wrapped_layer_obj.metadata.set("wms_srs", short_epsg)
858+
wrapped_layer_obj.setProjection(sr.proj)
859+
860+
wrapped_layer_obj.setExtent(*wrapped_extent)
861+
wrapped_layer_obj.metadata.set("wms_extent", "%f %f %f %f" % wrapped_extent)
862+
layers.append(wrapped_layer_obj)
863+
864+
return layers
857865

858866

859867
def _create_polygon_layer(map_obj):

eoxserver/resources/coverages/dateline.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
from osgeo import ogr
3131
from osgeo import osr
3232

33+
from eoxserver.resources.coverages.crss import crs_bounds
34+
3335

3436
EXTENT_EPSG_4326 = ogr.CreateGeometryFromWkt(
3537
'POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90))'
@@ -93,3 +95,34 @@ def wrap_extent_around_dateline(extent, srid=4326):
9395
"%d. Supported are SRIDs %s." %
9496
(srid, ", ".join(str(v) for v in CRS_WIDTH.keys()))
9597
)
98+
99+
100+
def get_extent_wrappings(extent, srid=4326):
101+
""" Returns a list of extents covering the dateline if the given extent
102+
crosses the dateline. Otherwise a list containing only the given extent
103+
is returned.
104+
"""
105+
106+
crs_minx, _, crs_maxx, _ = crs_bounds(srid)
107+
crs_width = crs_maxx - crs_minx
108+
109+
extents = []
110+
working_extent = extent
111+
while True:
112+
working_extent = (working_extent[0] - crs_width, working_extent[1],
113+
working_extent[2] - crs_width, working_extent[3])
114+
if working_extent[2] > crs_minx:
115+
extents.append(working_extent)
116+
else:
117+
break
118+
119+
working_extent = extent
120+
while True:
121+
working_extent = (working_extent[0] + crs_width, working_extent[1],
122+
working_extent[2] + crs_width, working_extent[3])
123+
if working_extent[0] < crs_maxx:
124+
extents.append(working_extent)
125+
else:
126+
break
127+
128+
return extents

0 commit comments

Comments
 (0)