Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing GetLegendGraphic operation #500

Merged
merged 25 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
838f422
Implementing GetLegendGraphic operation
constantinius Nov 23, 2021
ef693e8
Merge branch 'master' into getlegendgraphic
baloola Jan 25, 2022
eef3296
fixing a bug in legend label
baloola Jan 26, 2022
a957527
Merge branch 'master' into getlegendgraphic
baloola May 11, 2022
b002d06
adding 'limit' variable
baloola May 11, 2022
4bb0b52
uncomment WMSBaseGetFeatureInfoHandler
baloola May 11, 2022
8ebae89
Merge branch 'master' into getlegendgraphic
baloola Oct 5, 2022
37a3327
separate getOutputFormat creation
baloola Oct 10, 2022
f0f09c1
fix map preparation
baloola Oct 19, 2022
75d0a1a
Merge branch 'master' into getlegendgraphic
baloola Oct 20, 2022
7d56d16
fix a missing argument
baloola Oct 20, 2022
2c1e713
adding 2 tests cases for GetLegendGraphics
baloola Oct 20, 2022
6a099c3
fixing typos
baloola Oct 20, 2022
2d4ecbd
fix another typo
baloola Oct 20, 2022
c58a215
fix the second legend graphics test
baloola Oct 20, 2022
8a2b84a
fix a test typo
baloola Oct 21, 2022
07205b4
Merge branch 'master' into getlegendgraphic
baloola Oct 24, 2022
308d452
fixing WMSBaseGetCapabilitiesHandler query
baloola Oct 24, 2022
d259852
fix a typo in DescribeEOCoverageSetHandler
baloola Oct 24, 2022
586fe04
re-do the fix in WCS20DescribeEOCoverageSetHandler
baloola Oct 24, 2022
e661195
Merge branch 'master' into getlegendgraphic
baloola Nov 12, 2024
c61ab2d
fix some bugs
baloola Nov 12, 2024
cd2eb82
fix(getlegendgraphics): wrong call to `_create_raster_layer_objs`
constantinius Nov 12, 2024
0ec023a
add test + return range on collection level
baloola Nov 27, 2024
e0ba431
basic inclusion of GetLegendGraphic in GetCapabilities
baloola Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 23 additions & 1 deletion autotest/autotest_services/tests/wms/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,26 @@ def testBandStatistics(self):
array1 = np.array(exp_band.ReadAsArray()).flatten()
array2 = np.array(res_band.ReadAsArray()).flatten()
regress_result = linregress(array1,array2)
self.assertGreaterEqual(regress_result.rvalue, 0.9)
self.assertGreaterEqual(regress_result.rvalue, 0.9)

@tag('wms', 'wms13')
class WMS13GetLegendTestCase(testbase.RasterTestCase):
layers = []
styles = []
frmt = "image/png"

def getFileExtension(self, part=None):
try:
return format_to_extension[self.frmt]
except KeyError:
return testbase.mimetypes.guess_extension(self.frmt, False)[1:]

def getRequest(self):
params = "service=WMS&request=GetMap&version=1.1.1&" \
"layers=%s&styles=%s&format=%s" % (
",".join(self.layers), ",".join(self.styles), self.frmt
)
if self.httpHeaders is None:
return (params, "kvp")
else:
return (params, "kvp", self.httpHeaders)
30 changes: 29 additions & 1 deletion autotest/autotest_services/tests/wms/test_v13.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,37 @@ def getRequest(self):
#===============================================================================
# Legend Graphic
#===============================================================================
class WMS13GetLegendGraphicTestCase(wmsbase.WMS13GetLegendTestCase):
""" Test a GetLegendGraphic request for a dataset with an associated style. """

# currently disabled because of segfaults in MapServer
def getRequest(self):
params = "service=WMS&version=1.3.0&request=GetLegendGraphic&format=image/png&layer=ASA_WSM_1PNDPA20050331_075939_000000552036_00035_16121_0775"
return params, "kvp"

def getFileExtension(self, file_type):
return "png"

class WMS13GetLegendGraphicTestCaseCOllectionLevel(wmsbase.WMS13GetLegendTestCase):
""" Test a GetLegendGraphic request on Collection level. """

def getRequest(self):
params = "service=WMS&version=1.3.0&request=GetLegendGraphic&format=image/png&layer=MER_FRS_1P_reduced"
return params, "kvp"

def getFileExtension(self, file_type):
return "png"

class WMS13GetLegendGraphicStyledTestCase(wmsbase.WMS13GetLegendTestCase):
""" Test a GetLegendGraphic request for a dataset with an associated style. """

def getRequest(self):
params = "service=WMS&version=1.3.0&request=GetLegendGraphic&format=image/png&layer=ASA_WSM_1PNDPA20050331_075939_000000552036_00035_16121_0775&style=earth"
return params, "kvp"

def getFileExtension(self, file_type):
return "png"

# currently disabled because of segfaults in MapServer

class WMS13GetLegendGraphicDatasetStyledTestCase(testbase.RasterTestCase):
""" Test a GetLegendGraphic request for a dataset with an associated style. """
Expand Down
4 changes: 4 additions & 0 deletions eoxserver/render/map/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@
DEFAULT_EOXS_MAP_RENDERER = (
"eoxserver.render.mapserver.map_renderer.MapserverMapRenderer"
)

DEFAULT_EOXS_LEGEND_RENDERER = (
"eoxserver.render.mapserver.map_renderer.MapserverMapRenderer"
)
24 changes: 24 additions & 0 deletions eoxserver/render/map/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,30 @@ def __repr__(self):
)


class Legend(object):
def __init__(self, layer, width, height, format):
self._layer = layer
self._width = width
self._height = height
self._format = format

@property
def layer(self):
return self._layer

@property
def width(self):
return self._width

@property
def height(self):
return self._height

@property
def format(self):
return self._format


class LayerDescription(object):
""" Abstract layer description
"""
Expand Down
18 changes: 17 additions & 1 deletion eoxserver/render/map/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@
from django.conf import settings
from django.utils.module_loading import import_string

from eoxserver.render.map.config import DEFAULT_EOXS_MAP_RENDERER
from eoxserver.render.map.config import (
DEFAULT_EOXS_MAP_RENDERER, DEFAULT_EOXS_LEGEND_RENDERER
)


MAP_RENDERER = None
LEGEND_RENDERER = None


def get_map_renderer():
Expand All @@ -44,3 +47,16 @@ def get_map_renderer():
MAP_RENDERER = import_string(specifier)()

return MAP_RENDERER


def get_legend_renderer():
global LEGEND_RENDERER
if LEGEND_RENDERER is None:
specifier = getattr(
settings, 'EOXS_LEGEND_RENDERER', DEFAULT_EOXS_LEGEND_RENDERER
)

LEGEND_RENDERER = import_string(specifier)()

return LEGEND_RENDERER

68 changes: 50 additions & 18 deletions eoxserver/render/mapserver/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def create(self, map_obj, layer: CoveragesLayer):
shape_obj = ms.shapeObj.fromWKT(coverage.footprint.wkt)
outlines_layer_obj.addFeature(shape_obj)

class_obj = _create_geometry_class(vector_style)
class_obj = _create_geometry_class(vector_style, name='outlines')
outlines_layer_obj.insertClass(class_obj)

return coverage_layers
Expand Down Expand Up @@ -361,17 +361,20 @@ def make_browse_layer_generator(self, map_obj, browses, map_,
)
layer_objs = _create_raster_layer_objs(
map_obj, browse.extent, browse.spatial_reference,
creation_info.filename, filename_generator, creation_info.env, browse.mode,
creation_info.filename if creation_info else '',
filename_generator, {}
)

for layer_obj in layer_objs:
if creation_info.env:
ms.set_env(map_obj, creation_info.env, True)
if creation_info:
layer_obj.data = creation_info.filename
if creation_info.env:
ms.set_env(map_obj, creation_info.env, True)

if creation_info.bands:
layer_obj.setProcessingKey('BANDS', ','.join(
str(band) for band in creation_info.bands
))
if creation_info.bands:
layer_obj.setProcessingKey('BANDS', ','.join(
str(band) for band in creation_info.bands
))

if reset_info:
sr = osr.SpatialReference(map_.crs)
Expand Down Expand Up @@ -411,16 +414,18 @@ def make_browse_layer_generator(self, map_obj, browses, map_,
)
for i, (field, field_range, nodata_value) in browse_iter:
if ranges:
if len(ranges) == 1:
range_ = ranges[0]
else:
range_ = ranges[i - 1]
elif field_range != (None, None):
range_ = field_range
browse_range = ranges[0]
elif browse.ranges[0] != (None, None):
browse_range = browse.ranges[0]
else:
range_ = _get_range(field)
browse_range = _get_range(field)

for layer_obj in layer_objs:
_create_raster_style(
style or "blackwhite", layer_obj,
browse_range[0], browse_range[1],
browse.nodata_values
)
# NOTE: Only works if browsetype nodata is lower than browse_type_min by at least 1
if browse.show_out_of_bounds_data:
# final LUT for min,max 200,700 and nodata=0 should look like:
Expand Down Expand Up @@ -450,6 +455,27 @@ def make_browse_layer_generator(self, map_obj, browses, map_,
"%s,%s" % tuple(range_)
)

else:
browse_iter = enumerate(
zip(browse.field_list, browse.ranges), start=1
)
for i, (field, field_range) in browse_iter:
if ranges:
if len(ranges) == 1:
range_ = ranges[0]
else:
range_ = ranges[i - 1]
elif field_range != (None, None):
range_ = field_range
else:
range_ = _get_range(field)

for layer_obj in layer_objs:
layer_obj.setProcessingKey(
"SCALE_%d" % i,
"%s,%s" % tuple(range_)
)

elif isinstance(browse, Browse):
layer_objs = _create_raster_layer_objs(
map_obj, browse.extent, browse.spatial_reference,
Expand Down Expand Up @@ -525,7 +551,7 @@ def create(self, map_obj, layer):
shape_obj = ms.shapeObj.fromWKT(browse.footprint.wkt)
outlines_layer_obj.addFeature(shape_obj)

class_obj = _create_geometry_class(vector_style)
class_obj = _create_geometry_class(vector_style, name='outlines')
outlines_layer_obj.insertClass(class_obj)

return filename_generator
Expand Down Expand Up @@ -655,7 +681,8 @@ def create(self, map_obj, layer):
layer_obj.addFeature(shape_obj)

class_obj = _create_geometry_class(
layer.style or 'red', fill_opacity=layer.fill
layer.style or 'red', fill_opacity=layer.fill,
name='outlines',
)
layer_obj.insertClass(class_obj)

Expand Down Expand Up @@ -841,8 +868,10 @@ def _create_polygon_layer(map_obj):


def _create_geometry_class(color_name, background_color_name=None,
fill_opacity=None):
fill_opacity=None, name=None):
cls_obj = ms.classObj()
if name is not None:
cls_obj.name = name
outline_style_obj = ms.styleObj()

try:
Expand Down Expand Up @@ -1001,6 +1030,9 @@ def _create_raster_style_ramp(raster_style, layer, minvalue=0, maxvalue=255,
(minvalue + next_perc * interval)
))
cls.group = name
cls.name = "%s - %s" % (
(minvalue + prev_perc * interval),
(minvalue + next_perc * interval))

style = ms.styleObj()
style.mincolor = ms.colorObj(*prev_color)
Expand Down
Loading