Esempio n. 1
0
def test_encode_getmap():
    print(
        kvp_encode_get_map_request(
            GetMapRequest(Version(1, 3, 0),
                          layers=['a', 'b', 'c'],
                          styles=['s1', 's2', None],
                          bounding_box=BoundingBox('EPSG:4326',
                                                   [0, 0, 10, 10]),
                          width=256,
                          height=256,
                          format='image/jpeg',
                          dimensions={})))

    print(
        kvp_encode_get_map_request(
            GetMapRequest(Version(1, 3, 0),
                          layers=['a', 'b', 'c'],
                          styles=['s1', 's2', None],
                          bounding_box=BoundingBox('EPSG:4326',
                                                   [0, 0, 10, 10]),
                          width=256,
                          height=256,
                          format='image/jpeg',
                          time=Range(year(2012), year(2013)),
                          elevation=1000,
                          dimensions={
                              'wavelength': '2456.2',
                              'pressure': ['123', '234'],
                              'range': [Range('0', '1'),
                                        Range('2', '4')]
                          })))
Esempio n. 2
0
def test_kvp_decode_getmap():
    # simplest form
    request = "service=WMS&version=1.3.0&request=GetMap&layers=a,b,c&styles=s1,s2,&crs=EPSG:4326&bbox=0,0,10,10&width=256&height=256&format=image/jpeg"  # noqa
    assert kvp_decode_getmap(request) == GetMapRequest(
        Version(1, 3, 0),
        layers=['a', 'b', 'c'],
        styles=['s1', 's2', None],
        bounding_box=BoundingBox('EPSG:4326', [0, 0, 10, 10]),
        width=256,
        height=256,
        format='image/jpeg',
        dimensions={})

    # multi-dim
    request = "service=WMS&version=1.3.0&request=GetMap&layers=a,b,c&styles=s1,s2,&crs=EPSG:4326&bbox=0,0,10,10&width=256&height=256&format=image/jpeg&time=2012/2013&elevation=1000&dim_wavelength=2456.2&dim_pressure=123,234&dim_range=0/1,2/4"  # noqa
    assert kvp_decode_getmap(request) == GetMapRequest(
        Version(1, 3, 0),
        layers=['a', 'b', 'c'],
        styles=['s1', 's2', None],
        bounding_box=BoundingBox('EPSG:4326', [0, 0, 10, 10]),
        width=256,
        height=256,
        format='image/jpeg',
        time=Range(year(2012), year(2013)),
        elevation=1000,
        dimensions={
            'wavelength': '2456.2',
            'pressure': ['123', '234'],
            'range': [Range('0', '1'), Range('2', '4')]
        })

    # elevation-range
    request = "service=WMS&version=1.3.0&request=GetMap&layers=a,b,c&styles=s1,s2,&crs=EPSG:4326&bbox=0,0,10,10&width=256&height=256&format=image/jpeg&elevation=1000/2000/10"  # noqa
    assert kvp_decode_getmap(request) == GetMapRequest(
        Version(1, 3, 0),
        layers=['a', 'b', 'c'],
        styles=['s1', 's2', None],
        bounding_box=BoundingBox('EPSG:4326', [0, 0, 10, 10]),
        width=256,
        height=256,
        format='image/jpeg',
        elevation=Range(1000, 2000, 10),
        dimensions={})

    # month to date
    request = "service=WMS&version=1.3.0&request=GetMap&layers=a,b,c&styles=s1,s2,&crs=EPSG:4326&bbox=0,0,10,10&width=256&height=256&format=image/jpeg&time=2012-02/2012-03-15"  # noqa
    assert kvp_decode_getmap(request) == GetMapRequest(
        Version(1, 3, 0),
        layers=['a', 'b', 'c'],
        styles=['s1', 's2', None],
        bounding_box=BoundingBox('EPSG:4326', [0, 0, 10, 10]),
        width=256,
        height=256,
        format='image/jpeg',
        time=Range(month(2012, 2), date(2012, 3, 15)),
        dimensions={})
Esempio n. 3
0
class ExecuteRequest:
    process_id: str
    mode: ExecutionMode
    response: ResponseType
    inputs: List[Input] = field(default_factory=list)
    output_definitions: List[OutputDefinition] = field(default_factory=list)
    version: Version = Version(2, 0, 0)
Esempio n. 4
0
def test_kvp_decode_getfeatureinfo():
    # minimal form
    request = "service=WMS&version=1.3.0&request=GetFeatureInfo&layers=a,b,c&styles=s1,s2,&crs=EPSG:4326&bbox=0,0,10,10&width=256&height=256&format=image/jpeg&query_layers=a,b&info_format=text/xml&i=12&j=12"  # noqa
    assert kvp_decode_getfeatureinfo(request) == GetFeatureInfoRequest(
        Version(1, 3, 0),
        layers=['a', 'b', 'c'],
        styles=['s1', 's2', None],
        bounding_box=BoundingBox('EPSG:4326', [0, 0, 10, 10]),
        width=256,
        height=256,
        format='image/jpeg',
        dimensions={},
        query_layers=['a', 'b'],
        info_format='text/xml',
        i=12,
        j=12,
        # feature_count=15,
    )

    # full
    request = "service=WMS&version=1.3.0&request=GetFeatureInfo&layers=a,b,c&styles=s1,s2,&crs=EPSG:4326&bbox=0,0,10,10&width=256&height=256&format=image/jpeg&query_layers=a,b&info_format=text/xml&i=12&j=12&feature_count=15"  # noqa
    assert kvp_decode_getfeatureinfo(request) == GetFeatureInfoRequest(
        Version(1, 3, 0),
        layers=['a', 'b', 'c'],
        styles=['s1', 's2', None],
        bounding_box=BoundingBox('EPSG:4326', [0, 0, 10, 10]),
        width=256,
        height=256,
        format='image/jpeg',
        dimensions={},
        query_layers=['a', 'b'],
        info_format='text/xml',
        i=12,
        j=12,
        feature_count=15,
    )
Esempio n. 5
0
class GetCoverageRequest:
    coverage_id: str
    version: Version = Version(2, 0, 1)
    format: str = None
    mediatype: str = None
    subsetting_crs: str = None
    output_crs: str = None
    subsets: List[SubsetTypes] = field(default_factory=list)
    scalefactor: float = None
    scales: List[ScaleTypes] = field(default_factory=list)
    interpolation: str = None
    axis_interpolations: List[AxisInterpolation] = field(default_factory=list)
    range_subset: List[Union[str, RangeInterval]] = None
    geotiff_encoding_parameters: GeoTIFFEncodingParameters = field(
        default_factory=GeoTIFFEncodingParameters)  # noqa
Esempio n. 6
0
def test_encode_getfeatureinfo():
    GetFeatureInfoRequest(
        Version(1, 3, 0),
        layers=['a', 'b', 'c'],
        styles=['s1', 's2', None],
        bounding_box=BoundingBox('EPSG:4326', [0, 0, 10, 10]),
        width=256,
        height=256,
        format='image/jpeg',
        dimensions={},
        query_layers=['a', 'b'],
        info_format='text/xml',
        i=12,
        j=12,
        feature_count=15,
    )
Esempio n. 7
0
class DescribeProcessRequest:
    process_ids: List[str]
    version: Version = Version(2, 0, 0)
Esempio n. 8
0
class DismissRequest:
    job_id: str
    version: Version = Version(2, 0, 0)
Esempio n. 9
0
class GetResultRequest:
    job_id: str
    version: Version = Version(2, 0, 0)
Esempio n. 10
0
class GetStatusRequest:
    job_id: str
    version: Version = Version(2, 0, 0)
Esempio n. 11
0
class WCS1GetCoverageRequest():
    version = Version(1, 0, 0)

    #pylint: disable=too-many-instance-attributes, too-many-branches, too-many-statements, too-many-locals
    def __init__(self, args):
        self.args = args
        cfg = get_config()

        # Argument: Coverage (required)
        if "coverage" not in args:
            raise WCS1Exception("No coverage specified",
                                WCS1Exception.MISSING_PARAMETER_VALUE,
                                locator="COVERAGE parameter",
                                valid_keys=list(cfg.product_index))
        self.product_name = args["coverage"]
        self.product = cfg.product_index.get(self.product_name)
        if not self.product or not self.product.wcs:
            raise WCS1Exception("Invalid coverage: %s" % self.product_name,
                                WCS1Exception.COVERAGE_NOT_DEFINED,
                                locator="COVERAGE parameter",
                                valid_keys=list(cfg.product_index))

        # Argument: FORMAT (required)
        if "format" not in args:
            raise WCS1Exception("No FORMAT parameter supplied",
                                WCS1Exception.MISSING_PARAMETER_VALUE,
                                locator="FORMAT parameter",
                                valid_keys=cfg.wcs_formats_by_name)
        if args["format"] not in cfg.wcs_formats_by_name:
            raise WCS1Exception("Unsupported format: %s" % args["format"],
                                WCS1Exception.INVALID_PARAMETER_VALUE,
                                locator="FORMAT parameter",
                                valid_keys=cfg.wcs_formats_by_name)
        self.format = cfg.wcs_formats_by_name[args["format"]]

        # Argument: (request) CRS (required)
        if "crs" not in args:
            raise WCS1Exception("No request CRS specified",
                                WCS1Exception.MISSING_PARAMETER_VALUE,
                                locator="CRS parameter",
                                valid_keys=list(cfg.published_CRSs))
        self.request_crsid = args["crs"]
        if self.request_crsid not in cfg.published_CRSs:
            raise WCS1Exception("%s is not a supported CRS" %
                                self.request_crsid,
                                WCS1Exception.INVALID_PARAMETER_VALUE,
                                locator="CRS parameter",
                                valid_keys=list(cfg.published_CRSs))
        self.request_crs = cfg.crs(self.request_crsid)

        # Argument: response_crs (optional)
        if "response_crs" in args:
            self.response_crsid = args["response_crs"]
            if self.response_crsid not in cfg.published_CRSs:
                raise WCS1Exception("%s is not a supported CRS" %
                                    self.response_crsid,
                                    WCS1Exception.INVALID_PARAMETER_VALUE,
                                    locator="RESPONSE_CRS parameter",
                                    valid_keys=list(cfg.published_CRSs))
            self.response_crs = geometry.CRS(self.response_crsid)
            self.response_crs = cfg.crs(self.response_crsid)
        else:
            self.response_crsid = self.request_crsid
            self.response_crs = self.request_crs

        # Arguments: One of BBOX or TIME is required
        #if "bbox" not in args and "time" not in args:
        #    raise WCS1Exception("At least one of BBOX or TIME parameters must be supplied",
        #                        WCS1Exception.MISSING_PARAMETER_VALUE,
        #                        locator="BBOX or TIME parameter"
        #                        )

        # Argument: BBOX (technically not required if TIME supplied, but
        #       it's not clear to me what that would mean.)
        # For WCS 1.0.0 all bboxes will be specified as minx, miny, maxx, maxy
        if "bbox" not in args:
            raise WCS1Exception("No BBOX parameter supplied",
                                WCS1Exception.MISSING_PARAMETER_VALUE,
                                locator="BBOX or TIME parameter")
        try:
            self.minx, self.miny, self.maxx, self.maxy = map(
                float, args['bbox'].split(','))
        except:
            raise WCS1Exception("Invalid BBOX parameter",
                                WCS1Exception.INVALID_PARAMETER_VALUE,
                                locator="BBOX parameter")

        # Argument: TIME
        # if self.product.wcs_sole_time:
        #    self.times = [parse(self.product.wcs_sole_time).date()]
        if "time" not in args:
            #      CEOS treats no supplied time argument as all time.
            # I'm really not sure what the right thing to do is, but QGIS wants us to do SOMETHING - treat it as "now"
            self.times = [self.product.ranges["times"][-1]]
        else:
            # TODO: the min/max/res format option?
            # It's a bit underspeced. I'm not sure what the "res" would look like.
            times = args["time"].split(",")
            self.times = []
            for t in times:
                if t == "now":
                    continue
                try:
                    time = parse(t).date()
                    if time not in self.product.ranges["time_set"]:
                        raise WCS1Exception(
                            "Time value '%s' not a valid date for coverage %s"
                            % (t, self.product_name),
                            WCS1Exception.INVALID_PARAMETER_VALUE,
                            locator="TIME parameter",
                            valid_keys=[
                                d.strftime('%Y-%m-%d')
                                for d in self.product.ranges["time_set"]
                            ])
                    self.times.append(time)
                except ValueError:
                    raise WCS1Exception(
                        "Time value '%s' not a valid ISO-8601 date" % t,
                        WCS1Exception.INVALID_PARAMETER_VALUE,
                        locator="TIME parameter",
                        valid_keys=[
                            d.strftime('%Y-%m-%d')
                            for d in self.product.ranges["time_set"]
                        ])
            self.times.sort()

            if len(self.times) == 0:
                raise WCS1Exception(
                    "No valid ISO-8601 dates",
                    WCS1Exception.INVALID_PARAMETER_VALUE,
                    locator="TIME parameter",
                    valid_keys=[
                        d.strftime('%Y-%m-%d')
                        for d in self.product.ranges["time_set"]
                    ])
            elif len(self.times) > 1 and not self.format["multi-time"]:
                raise WCS1Exception(
                    "Cannot select more than one time slice with the %s format"
                    % self.format["name"],
                    WCS1Exception.INVALID_PARAMETER_VALUE,
                    locator="TIME and FORMAT parameters")

        # Range constraint parameter: MEASUREMENTS
        # No default is set in the DescribeCoverage, so it is required
        # But QGIS wants us to work without one, so take default from config
        if "measurements" in args:
            bands = args["measurements"]
            self.bands = []
            for b in bands.split(","):
                if not b:
                    continue
                try:
                    self.bands.append(self.product.band_idx.band(b))
                except ConfigException:
                    raise WCS1Exception(
                        f"Invalid measurement: {b}",
                        WCS1Exception.INVALID_PARAMETER_VALUE,
                        locator="MEASUREMENTS parameter",
                        valid_keys=self.product.band_idx.band_labels())
            if not bands:
                raise WCS1Exception(
                    "No measurements supplied",
                    WCS1Exception.INVALID_PARAMETER_VALUE,
                    locator="MEASUREMENTS parameter",
                    valid_keys=self.product.band_idx.band_labels())
        elif "styles" in args and args["styles"]:
            # Use style bands.
            # Non-standard protocol extension.
            #
            # As we have correlated WCS and WMS service implementations,
            # we can accept a style from WMS, and return the bands used for it.
            styles = args["styles"].split(",")
            if len(styles) != 1:
                raise WCS1Exception("Multiple style parameters not supported")
            style = self.product.style_index.get(styles[0])
            if style:
                self.bands = style.needed_bands
            else:
                self.bands = self.product.wcs_default_bands
        else:
            self.bands = self.product.wcs_default_bands

        # Argument: EXCEPTIONS (optional - defaults to XML)
        if "exceptions" in args and args[
                "exceptions"] != "application/vnd.ogc.se_xml":
            raise WCS1Exception(
                f"Unsupported exception format: {args['exceptions']}",
                WCS1Exception.INVALID_PARAMETER_VALUE,
                locator="EXCEPTIONS parameter")

        # Argument: INTERPOLATION (optional only nearest-neighbour currently supported.)
        #      If 'none' is supported in future, validation of width/height/res will need to change.
        if "interpolation" in args and args[
                "interpolation"] != "nearest neighbor":
            raise WCS1Exception(
                f'Unsupported interpolation method: {args["interpolation"]}',
                WCS1Exception.INVALID_PARAMETER_VALUE,
                locator="INTERPOLATION parameter")

        if "width" in args:
            if "resx" in args or "resy" in args:
                raise WCS1Exception(
                    "Specify WIDTH/HEIGHT parameters OR RESX/RESY parameters - not both",
                    WCS1Exception.MISSING_PARAMETER_VALUE,
                    locator="RESX/RESY/WIDTH/HEIGHT parameters")
            if "height" not in args:
                raise WCS1Exception(
                    "WIDTH parameter supplied without HEIGHT parameter",
                    WCS1Exception.MISSING_PARAMETER_VALUE,
                    locator="WIDTH/HEIGHT parameters")
            try:
                self.height = int(args["height"])
                if self.height < 1:
                    raise ValueError()
            except ValueError:
                raise WCS1Exception(
                    "HEIGHT parameter must be a positive integer",
                    WCS1Exception.INVALID_PARAMETER_VALUE,
                    locator="HEIGHT parameter")
            try:
                self.width = int(args["width"])
                if self.width < 1:
                    raise ValueError()
            except ValueError:
                raise WCS1Exception(
                    "WIDTH parameter must be a positive integer",
                    WCS1Exception.INVALID_PARAMETER_VALUE,
                    locator="WIDTH parameter")
            self.resx = (self.maxx - self.minx) / self.width
            self.resy = (self.maxy - self.miny) / self.height
        elif "resx" in args:
            if "height" in args:
                raise WCS1Exception(
                    "Specify WIDTH/HEIGHT parameters OR RESX/RESY parameters - not both",
                    WCS1Exception.MISSING_PARAMETER_VALUE,
                    locator="RESX/RESY/WIDTH/HEIGHT parameters")
            if "resy" not in args:
                raise WCS1Exception(
                    "RESX parameter supplied without RESY parameter",
                    WCS1Exception.MISSING_PARAMETER_VALUE,
                    locator="RESX/RESY parameters")
            try:
                self.resx = float(args["resx"])
                if self.resx <= 0.0:
                    raise ValueError(0)
            except ValueError:
                raise WCS1Exception("RESX parameter must be a positive number",
                                    WCS1Exception.INVALID_PARAMETER_VALUE,
                                    locator="RESX parameter")
            try:
                self.resy = float(args["resy"])
                if self.resy <= 0.0:
                    raise ValueError(0)
            except ValueError:
                raise WCS1Exception("RESY parameter must be a positive number",
                                    WCS1Exception.INVALID_PARAMETER_VALUE,
                                    locator="RESY parameter")
            self.width = (self.maxx - self.minx) / self.resx
            self.height = (self.maxy - self.miny) / self.resy
            self.width = int(self.width + 0.5)
            self.height = int(self.height + 0.5)
        elif "height" in args:
            raise WCS1Exception(
                "HEIGHT parameter supplied without WIDTH parameter",
                WCS1Exception.MISSING_PARAMETER_VALUE,
                locator="WIDTH/HEIGHT parameters")
        elif "resy" in args:
            raise WCS1Exception(
                "RESY parameter supplied without RESX parameter",
                WCS1Exception.MISSING_PARAMETER_VALUE,
                locator="RESX/RESY parameters")
        else:
            raise WCS1Exception(
                "You must specify either the WIDTH/HEIGHT parameters or RESX/RESY",
                WCS1Exception.MISSING_PARAMETER_VALUE,
                locator="RESX/RESY/WIDTH/HEIGHT parameters")

        self.extent = geometry.polygon([(self.minx, self.miny),
                                        (self.minx, self.maxy),
                                        (self.maxx, self.maxy),
                                        (self.maxx, self.miny),
                                        (self.minx, self.miny)],
                                       self.request_crs)

        xscale = (self.maxx - self.minx) / self.width
        yscale = (self.miny - self.maxy) / self.height
        trans_aff = Affine.translation(self.minx, self.maxy)
        scale_aff = Affine.scale(xscale, yscale)
        self.affine = trans_aff * scale_aff
        self.geobox = geometry.GeoBox(self.width, self.height, self.affine,
                                      self.request_crs)
Esempio n. 12
0
class DescribeCoverageRequest:
    coverage_ids: List[str]
    version: Version = Version(2, 0, 1)