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
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))
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)
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
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
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
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
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")
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)
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))
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")
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
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)