Esempio n. 1
0
    def method_specific_init(self, args):
        # Validate Format parameter
        self.format = get_arg(args,
                              "format",
                              "image format",
                              errcode=WMSException.INVALID_FORMAT,
                              lower=True,
                              permitted_values=["image/png"])
        # Styles
        self.styles = args.get("styles", "").split(",")
        if len(self.styles) != 1:
            raise WMSException("Multi-layer GetMap requests not supported")
        style_r = self.styles[0]
        if not style_r:
            style_r = self.product.default_style
        self.style = self.product.style_index.get(style_r)
        if not self.style:
            raise WMSException("Style %s is not defined" % style_r,
                               WMSException.STYLE_NOT_DEFINED,
                               locator="Style parameter")
        # Zoom factor
        self.zf = zoom_factor(args, self.crs)

        # Read Resampling method from config
        self.resampling = Resampling.nearest
        layer_name = unquote(self.get_raw_product(args))
        for layer in layer_cfg:
            if layer["name"] == layer_name:
                if "resampling" in layer:
                    self.resampling = RESAMPLING_METHODS[
                        layer["resampling"].lower()]
                break
Esempio n. 2
0
def ogc_impl():
    #pylint: disable=too-many-branches
    nocase_args = lower_get_args()
    nocase_args = capture_headers(request, nocase_args)
    service = nocase_args.get("service", "").upper()
    if service:
        return ogc_svc_impl(service.lower())

    # create dummy env if not exists
    try:
        with rio_env():
            # service argument is only required (in fact only defined) by OGC for
            # GetCapabilities requests.  As long as we are persisting with a single
            # routing end point for all services, we must derive the service from the request
            # parameter.
            # This is a quick hack to fix #64.  Service and operation routing could be
            # handled more elegantly.
            op = nocase_args.get("request", "").upper()
            if op in WMS_REQUESTS:
                return ogc_svc_impl("wms")
            elif op in WCS_REQUESTS:
                return ogc_svc_impl("wcs")
            else:
                # Should we return a WMS or WCS exception if there is no service specified?
                # Defaulting to WMS because that's what we already have.
                raise WMSException("Invalid service and/or request",
                                   locator="Service and request parameters")
    except OGCException as e:
        return e.exception_response()
    except Exception as e:
        tb = sys.exc_info()[2]
        ogc_e = WMSException("Unexpected server error: %s" % str(e),
                             http_response=500)
        return ogc_e.exception_response(traceback=traceback.extract_tb(tb))
Esempio n. 3
0
 def method_specific_init(self, args):
     # Validate Formata parameter
     self.format = get_arg(args,
                           "info_format",
                           "info format",
                           lower=True,
                           errcode=WMSException.INVALID_FORMAT,
                           permitted_values=["application/json"])
     # Point coords
     if self.version == "1.1.1":
         coords = ["x", "y"]
     else:
         coords = ["i", "j"]
     i = args.get(coords[0])
     j = args.get(coords[1])
     if i is None:
         raise WMSException("HorizontalCoordinate not supplied",
                            WMSException.INVALID_POINT,
                            "%s parameter" % coords[0])
     if j is None:
         raise WMSException("Vertical coordinate not supplied",
                            WMSException.INVALID_POINT,
                            "%s parameter" % coords[0])
     self.i = int(i)
     self.j = int(j)
Esempio n. 4
0
def get_time(args, product, raw_product):
    # Time parameter
    times = args.get('time', '').split('/')
    # If all times are equal we can proceed
    if len(set(times)) > 1:
        raise WMSException(
            "Selecting multiple time dimension values not supported",
            WMSException.INVALID_DIMENSION_VALUE,
            locator="Time parameter")
    elif not times[0]:
        # default to last available time if not supplied.
        chunks = raw_product.split("__")
        if len(chunks) == 1:
            path = None
            ranges = product.ranges
        else:
            path = int(chunks[1])
            ranges = product.sub_ranges[path]

        return ranges["times"][-1]
    try:
        time = parse(times[0]).date()
    except ValueError:
        raise WMSException(
            "Time dimension value '%s' not valid for this layer" % times[0],
            WMSException.INVALID_DIMENSION_VALUE,
            locator="Time parameter")

    # Validate time paramter for requested layer.
    if time not in product.ranges["time_set"]:
        raise WMSException(
            "Time dimension value '%s' not valid for this layer" % times[0],
            WMSException.INVALID_DIMENSION_VALUE,
            locator="Time parameter")
    return time
Esempio n. 5
0
def get_product_from_arg(args, argname="layers"):
    layers = args.get(argname, "").split(",")
    if len(layers) != 1:
        raise WMSException("Multi-layer requests not supported")
    layer = layers[0]
    layer_chunks = layer.split("__")
    layer = layer_chunks[0]
    platforms = get_layers()
    product = platforms.product_index.get(layer)
    if not product:
        raise WMSException("Layer %s is not defined" % layer,
                           WMSException.LAYER_NOT_DEFINED,
                           locator="Layer parameter")
    return product
Esempio n. 6
0
def get_arg(args, argname, verbose_name, lower=False,
            errcode=None, permitted_values=[]):
    fmt = args.get(argname, "")
    if lower: fmt = fmt.lower()
    if not fmt:
        raise WMSException("No %s specified" % verbose_name,
                           errcode,
                           locator="%s parameter" % argname)

    if permitted_values:
        if fmt not in permitted_values:
            raise WMSException("%s %s is not supported" % (verbose_name, fmt),
                               errcode,
                               locator="%s parameter" % argname)
    return fmt
Esempio n. 7
0
def get_time(args, product, raw_product):
    # Time parameter
    times = args.get('time', '')
    if times.find(',') != -1:
        raise WMSException(
            "Selecting a list of time dimension values not supported",
            WMSException.INVALID_DIMENSION_VALUE,
            locator="Time parameter")

    times = times.split('/')
    # Time range handling follows the implementation described by GeoServer
    # https://docs.geoserver.org/stable/en/user/services/wms/time.html

    # If all times are equal we can proceed
    if len(times) > 1:
        start, end = parse_wms_time_strings(times)
        start, end = start.date(), end.date()
        matching_times = [
            t for t in product.ranges['times'] if start <= t <= end
        ]
        if matching_times:
            # default to the first matching time
            return matching_times[0]
        else:
            raise WMSException(
                "Time dimension range '%s'-'%s' not valid for this layer" %
                (start, end),
                WMSException.INVALID_DIMENSION_VALUE,
                locator="Time parameter")
    elif not times[0]:
        # default to last available time if not supplied.
        product_times = get_times_for_product(product, raw_product)
        return product_times[-1]
    try:
        time = parse(times[0]).date()
    except ValueError:
        raise WMSException(
            "Time dimension value '%s' not valid for this layer" % times[0],
            WMSException.INVALID_DIMENSION_VALUE,
            locator="Time parameter")

    # Validate time parameter for requested layer.
    if time not in product.ranges["time_set"]:
        raise WMSException(
            "Time dimension value '%s' not valid for this layer" % times[0],
            WMSException.INVALID_DIMENSION_VALUE,
            locator="Time parameter")
    return time
Esempio n. 8
0
def handle_wms(nocase_args):
    operation = nocase_args.get("request", "").upper()
    # WMS operation Map
    if not operation:
        raise WMSException("No operation specified",
                           locator="Request parameter")
    elif operation == "GETCAPABILITIES":
        return get_capabilities(nocase_args)
    elif operation == "GETMAP":
        return get_map(nocase_args)
    elif operation == "GETFEATUREINFO":
        return feature_info(nocase_args)
    else:
        raise WMSException("Unrecognised operation: %s" % operation,
                           WMSException.OPERATION_NOT_SUPPORTED,
                           "Request parameter")
Esempio n. 9
0
 def method_specific_init(self, args):
     # Validate Format parameter
     self.format = get_arg(args, "format", "image format",
               errcode=WMSException.INVALID_FORMAT,
               lower=True,
               permitted_values=["image/png"])
     # Styles
     self.styles = args.get("styles", "").split(",")
     if len(self.styles) != 1:
         raise WMSException("Multi-layer GetMap requests not supported")
     style_r = self.styles[0]
     if not style_r:
         style_r = self.product.default_style
     self.style = self.product.style_index.get(style_r)
     if not self.style:
         raise WMSException("Style %s is not defined" % style_r,
                            WMSException.STYLE_NOT_DEFINED,
                            locator="Style parameter")
     # Zoom factor
     self.zf = zoom_factor(args, self.crs)
Esempio n. 10
0
def ogc_impl():
    nocase_args = lower_get_args()
    nocase_args['referer'] = request.headers.get('Referer', None)
    nocase_args['origin'] = request.headers.get('Origin', None)
    nocase_args['requestid'] = request.environ.get("FLASK_REQUEST_ID")
    service = nocase_args.get("service", "").upper()
    svc_cfg = get_service_cfg()
    try:
        if service == "WMS":
            # WMS operation Map
            if svc_cfg.wms:
                return handle_wms(nocase_args)
            else:
                raise WMSException("Invalid service",
                                   locator="Service parameter")
        elif service == "WCS":
            # WCS operation Map
            if svc_cfg.wcs:
                return handle_wcs(nocase_args)
            else:
                raise WCS1Exception("Invalid service",
                                    locator="Service parameter")
        else:
            # Should we return a WMS or WCS exception if there is no service specified?
            # Defaulting to WMS because that's what we already have.
            raise WMSException("Invalid service", locator="Service parameter")
    except OGCException as e:
        return e.exception_response()
    except Exception as e:
        tb = sys.exc_info()[2]
        if service == "WCS":
            eclass = WCS1Exception
        else:
            eclass = WMSException
        ogc_e = eclass("Unexpected server error: %s" % str(e),
                       http_response=500)
        return ogc_e.exception_response(traceback=traceback.extract_tb(tb))
Esempio n. 11
0
def handle_wms(nocase_args):
    operation = nocase_args.get("request", "").upper()
    # WMS operation Map
    if not operation:
        raise WMSException("No operation specified",
                           locator="Request parameter")
    elif operation == "GETCAPABILITIES":
        return get_capabilities(nocase_args)
    elif operation == "GETMAP":
        return get_map(nocase_args)
    elif operation == "GETFEATUREINFO":
        return feature_info(nocase_args)
    elif operation == "GETLEGENDGRAPHIC":
        response = legend_graphic(nocase_args)
        if response is None:
            raise WMSException(
                "Operation GetLegendGraphic not supported for this product and style",
                WMSException.OPERATION_NOT_SUPPORTED, "Request parameter")
        else:
            return response
    else:
        raise WMSException("Unrecognised operation: %s" % operation,
                           WMSException.OPERATION_NOT_SUPPORTED,
                           "Request parameter")
Esempio n. 12
0
def parse_wms_time_strings(parts):
    start = parse_wms_time_string(parts[0])
    end = parse_wms_time_string(parts[-1], start=False)

    a_tiny_bit = relativedelta(microseconds=1)
    # Follows GeoServer https://docs.geoserver.org/stable/en/user/services/wms/time.html#reduced-accuracy-times

    if isinstance(start, relativedelta):
        if isinstance(end, relativedelta):
            raise WMSException("Could not understand time value '%s'" % parts,
                               WMSException.INVALID_DIMENSION_VALUE,
                               locator="Time parameter")
        fuzzy_end = parse_wms_time_string(parts[-1], start=True)
        return fuzzy_end - start + a_tiny_bit, end
    if isinstance(end, relativedelta):
        return start, start + end - a_tiny_bit
    return start, end
Esempio n. 13
0
    def __init__(self, args):
        self.product = get_product_from_arg(args, 'layer')

        # Validate Format parameter
        self.format = get_arg(args,
                              "format",
                              "image format",
                              errcode=WMSException.INVALID_FORMAT,
                              lower=True,
                              permitted_values=["image/png"])
        # Styles
        self.styles = args.get("styles", "").split(",")
        if len(self.styles) != 1:
            raise WMSException("Multi-layer GetMap requests not supported")
        self.style_name = style_r = self.styles[0]
        if not style_r:
            style_r = self.product.default_style
        self.style = self.product.style_index.get(style_r)