Skip to content

Commit

Permalink
Merge branch '0.4' of git+ssh://github.com/EOxServer/eoxserver into 0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
constantinius committed Dec 3, 2014
2 parents 72ad446 + 855f86e commit 9e37c26
Show file tree
Hide file tree
Showing 17 changed files with 303 additions and 184 deletions.
5 changes: 2 additions & 3 deletions eoxserver/core/decoders/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def __get__(self, decoder, decoder_class=None):
"""

results = self.select(decoder, decoder_class)
count = len(results)
count = len(results)

locator = self.locator
multiple = self.num not in SINGLE_VALUES

Expand All @@ -79,7 +79,6 @@ def __get__(self, decoder, decoder_class=None):

# parse the value/values, or return the defaults
if multiple:

if count == 0 and self.num == ANY and self.default is not None:
return self.default

Expand Down
25 changes: 22 additions & 3 deletions eoxserver/core/decoders/kvp.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,25 @@ def locator(self):
return self._locator or self.key


class MultiParameter(Parameter):
""" Class for selecting different KVP parameters at once.
"""

def __init__(self, selector, num=1, default=None, locator=None):
super(MultiParameter, self).__init__(
"", lambda s: s, num, default, locator
)
self.key = selector

def select(self, decoder, decoder_class=None):
result = []
for key, values in decoder._query_dict.items():
if self.key(key):
result.append((key, values))

return result


class DecoderMetaclass(type):
""" Metaclass for KVP Decoders to allow easy parameter declaration.
"""
Expand All @@ -70,13 +89,13 @@ class Decoder(object):
""" Base class for KVP decoders.
"""
__metaclass__ = DecoderMetaclass

def __init__(self, params):
query_dict = {}
if isinstance(params, QueryDict):
for key, values in params.lists():
query_dict[key.lower()] = values

elif isinstance(params, basestring):
tmp = parse_qs(params)
for key, values in tmp.items():
Expand All @@ -90,6 +109,6 @@ def __init__(self, params):
raise ValueError(
"Decoder input '%s' not supported." % type(params).__name__
)

self.kvp = params
self._query_dict = query_dict
68 changes: 68 additions & 0 deletions eoxserver/core/util/perftools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#-------------------------------------------------------------------------------
# $Id$
#
# Project: EOxServer <http://eoxserver.org>
# Authors: Fabian Schindler <[email protected]>
#
#-------------------------------------------------------------------------------
# Copyright (C) 2014 EOX IT Services GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies of this Software or works derived from this Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#-------------------------------------------------------------------------------

import time
import logging


_logger = logging.getLogger(__name__)


class DurationMeasurement(object):
def __init__(self, name, logger, level):
self.name = name
self.logger = logger
self.level = level
self.start = None
self.end = None

def __enter__(self):
self.start = time.time()
return self

def __exit__(self, *args, **kwargs):
self.end = time.time()
msg = "'%s' took %f seconds." % (self.name, self.duration)
self.logger.log(self.level, msg)

@property
def duration(self):
if self.start is not None and self.end is not None:
return self.end - self.start
return None


def log_duration(name, logger=None, level=logging.DEBUG):
""" Convenience function to log the duration of a specific event.
:param name: The name of the event.
:param logger: The logger to use.
:param level: The log level to log the final message to.
"""

logger = logger or _logger
return DurationMeasurement(name, logger, level)
2 changes: 1 addition & 1 deletion eoxserver/resources/coverages/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class NilValueInline(AbstractInline):
class BandInline(AbstractInline):
form = BandInlineForm # TODO: not working as expected...
model = models.Band
extra = 1
extra = 0

def get_queryset(self):
queryset = super(BandInline, self).get_queryset()
Expand Down
68 changes: 21 additions & 47 deletions eoxserver/resources/coverages/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
from eoxserver.contrib import gdal, osr
from eoxserver.backends import models as backends
from eoxserver.resources.coverages.util import (
detect_circular_reference, collect_eo_metadata, is_same_grid
detect_circular_reference, collect_eo_metadata, is_same_grid,
parse_raw_value
)


Expand Down Expand Up @@ -334,50 +335,7 @@ def __unicode__(self):
def value(self):
""" Get the parsed python value from the saved value string.
"""
dt = self.nil_value_set.data_type
is_float = False
is_complex = False

if dt in gdal.GDT_INTEGRAL_TYPES :
value = int(self.raw_value)

elif dt in gdal.GDT_FLOAT_TYPES :
value = float(self.raw_value)
is_float = True

elif dt in gdal.GDT_INTEGRAL_COMPLEX_TYPES :
value = complex(self.raw_value)
is_complex = True

elif dt in gdal.GDT_FLOAT_COMPLEX_TYPES :
value = complex(self.raw_value)
is_complex = True
is_float = True

else:
value = None

# range check makes sense for integral values only
if not is_float :

limits = gdal.GDT_NUMERIC_LIMITS.get(dt)

if limits and value is not None:
def within(v, low, high):
return (v >= low and v <= high)

error = ValueError(
"Stored value is out of the limits for the data type"
)
if not is_complex and not within(value, *limits) :
raise error
elif is_complex:
if (not within(value.real, limits[0].real, limits[1].real)
or not within(value.real, limits[0].real, limits[1].real)):
raise error

return value

return parse_raw_value(self.raw_value, self.nil_value_set.data_type)

def clean(self):
""" Check that the value can be parsed.
Expand Down Expand Up @@ -439,9 +397,11 @@ class Band(models.Model):
data_type = models.PositiveIntegerField()
color_interpretation = models.PositiveIntegerField(null=True, blank=True)

raw_value_min = models.CharField(max_length=512, null=True, blank=True, help_text="The string representation of the minimum value.")
raw_value_max = models.CharField(max_length=512, null=True, blank=True, help_text="The string representation of the maximum value.")

range_type = models.ForeignKey(RangeType, related_name="bands", null=False, blank=False)
nil_value_set = models.ForeignKey(NilValueSet, null=True, blank=True)


def clean(self):
nil_value_set = self.nil_value_set
Expand All @@ -451,6 +411,12 @@ def clean(self):
"its nil value set."
)

min_ = parse_raw_value(self.raw_value_min, self.data_type)
max_ = parse_raw_value(self.raw_value_min, self.data_type)

if min_ is not None and max_ is not None and min_ > max_:
raise ValidationError("Minimum value larger than maximum value")

class Meta:
ordering = ('index',)
unique_together = (('index', 'range_type'), ('identifier', 'range_type'))
Expand All @@ -461,7 +427,15 @@ def __unicode__(self):

@property
def allowed_values(self):
return gdal.GDT_NUMERIC_LIMITS[self.data_type]
dt = self.data_type
min_ = parse_raw_value(self.raw_value_min, dt)
max_ = parse_raw_value(self.raw_value_max, dt)
limits = gdal.GDT_NUMERIC_LIMITS[dt]

return (
min_ if min_ is not None else limits[0],
max_ if max_ is not None else limits[1],
)

@property
def significant_figures(self):
Expand Down
68 changes: 39 additions & 29 deletions eoxserver/resources/coverages/rangetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def getRangeType( name ) :
# get range-type record
rt = RangeType.objects.get(name=name)

band = []
bands = []

# loop over band records (ordering set in model)
for b in rt.bands.all() :
Expand All @@ -326,23 +326,29 @@ def getRangeType( name ) :
# append created nil-value dictionary
nil_values.append( { 'reason': n.reason, 'value': n.raw_value } )


band = {
'name' : b.name,
'data_type' : gdal.GDT_TO_NAME.get(b.data_type,'Invalid'),
'identifier' : b.identifier,
'description' : b.description,
'definition' : b.definition,
'uom' : b.uom,
'nil_values' : nil_values,
'color_interpretation' :
gdal.GCI_TO_NAME.get(b.color_interpretation,'Invalid'),
}

if b.raw_value_min is not None:
band["value_min"] = b.raw_value_min
if b.raw_value_max is not None:
band["value_max"] = b.raw_value_max

# append created band dictionary
band.append(
{
'name' : b.name,
'data_type' : gdal.GDT_TO_NAME.get(b.data_type,'Invalid'),
'identifier' : b.identifier,
'description' : b.description,
'definition' : b.definition,
'uom' : b.uom,
'nil_values' : nil_values,
'color_interpretation' :
gdal.GCI_TO_NAME.get(b.color_interpretation,'Invalid'),
}
)
bands.append(band)

# return JSON serializable dictionary
return { 'name': rt.name, 'bands': band }
return { 'name': rt.name, 'bands': bands }

except RangeType.DoesNotExist :

Expand Down Expand Up @@ -382,20 +388,22 @@ def setRangeType( rtype ) :
cint = gdal.NAME_TO_GCI[cint.lower()]

# prepare nil-value set

nvset = NilValueSet.objects.create(
name = "__%s_%2.2d__"%(rtype['name'],idx),
data_type = dtype )

for nval in band['nil_values'] :

nv = NilValue.objects.create(
reason = nval['reason'],
raw_value = str(nval['value']),
nil_value_set = nvset )
if band['nil_values']:
nvset = NilValueSet.objects.create(
name = "__%s_%2.2d__"%(rtype['name'],idx),
data_type = dtype )
for nval in band['nil_values'] :

nv = NilValue.objects.create(
reason = nval['reason'],
raw_value = str(nval['value']),
nil_value_set = nvset )

# cheking value
tmp = nv.value
# cheking value
tmp = nv.value
else:
nvset = None

bn = Band.objects.create(
index = idx,
Expand All @@ -407,5 +415,7 @@ def setRangeType( rtype ) :
uom = band['uom'],
color_interpretation = cint,
range_type = rt,
nil_value_set = nvset
nil_value_set = nvset,
raw_value_min = band.get("value_min"),
raw_value_max = band.get("value_max")
)
Loading

0 comments on commit 9e37c26

Please sign in to comment.