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

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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.
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 @@ -154,4 +154,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)
20 changes: 19 additions & 1 deletion autotest/autotest_services/tests/wms/test_v13.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,27 @@ 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 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 @@ -370,6 +370,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

94 changes: 51 additions & 43 deletions eoxserver/render/mapserver/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def create(self, map_obj, layer):
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 @@ -349,18 +349,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.filename if creation_info else '',
filename_generator
)

for layer_obj in layer_objs:
layer_obj.data = creation_info.filename
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 All @@ -377,43 +379,43 @@ def make_browse_layer_generator(self, map_obj, browses, map_,
layer_obj.setMetaData("wms_srs", short_epsg)
layer_obj.setProjection(sr.proj)

if browse.mode == BROWSE_MODE_GRAYSCALE:
field = browse.field_list[0]
if ranges:
browse_range = ranges[0]
elif browse.ranges[0] != (None, None):
browse_range = browse.ranges[0]
else:
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
)

else:
browse_iter = enumerate(
zip(browse.field_list, browse.ranges), start=1
)
for i, (field, field_range) in browse_iter:
if browse.mode == BROWSE_MODE_GRAYSCALE:
field = browse.field_list[0]
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:
layer_obj.setProcessingKey(
"SCALE_%d" % i,
"%s,%s" % tuple(range_)
_create_raster_style(
style or "blackwhite", layer_obj,
browse_range[0], browse_range[1],
browse.nodata_values
)

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 @@ -491,7 +493,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 @@ -621,7 +623,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 @@ -699,8 +702,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 @@ -820,6 +825,9 @@ def _create_raster_style(name, 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