Exemple #1
0
    def encode_coverage_description(self,
                                    coverage,
                                    srid=None,
                                    size=None,
                                    extent=None,
                                    footprint=None):
        source_mime = None
        for arraydata_location in getattr(coverage, 'arraydata_locations', []):
            if arraydata_location.format:
                source_mime = arraydata_location.format
                break

        native_format = None
        if source_mime:
            source_format = getFormatRegistry().getFormatByMIME(source_mime)
            # map the source format to the native one
            native_format = getFormatRegistry().mapSourceToNativeWCS20(
                source_format)
        # elif issubclass(coverage.real_type, RectifiedStitchedMosaic):
        #     # use the default format for RectifiedStitchedMosaics
        #     native_format = getFormatRegistry().getDefaultNativeFormat()
        # else:
        #     # TODO: improve if no native format availabe
        #     native_format = None
        sr = SpatialReference(4326)
        if extent:
            poly = Polygon.from_bbox(extent)
            poly.srid = srid
            extent = poly.transform(4326).extent

        else:
            # extent = coverage.extent
            extent = (0, 0, 1, 1)
            # sr = coverage.spatial_reference

        # if issubclass(coverage.real_type, ReferenceableDataset):
        #     rectified = False
        # else:
        #     rectified = True

        rectified = (coverage.grid is not None)

        return WCS(
            "CoverageDescription",
            self.encode_bounded_by(coverage, coverage.grid),
            WCS("CoverageId", coverage.identifier),
            self.encode_eo_metadata(coverage),
            self.encode_domain_set(coverage, srid, size, extent, rectified),
            self.encode_range_type(coverage.range_type),
            WCS(
                "ServiceParameters",
                WCS("CoverageSubtype", self.get_coverage_subtype(coverage)),
                WCS("nativeFormat",
                    native_format.mimeType if native_format else "")),
            **{ns_gml("id"): self.get_gml_id(coverage.identifier)})
Exemple #2
0
    def encode_coverage_description(self,
                                    coverage,
                                    srid=None,
                                    size=None,
                                    extent=None,
                                    footprint=None):
        source_mime = None
        band_items = coverage.data_items.filter(semantic__startswith="bands")
        for data_item in band_items:
            if data_item.format:
                source_mime = data_item.format
                break

        if source_mime:
            source_format = getFormatRegistry().getFormatByMIME(source_mime)
            # map the source format to the native one
            native_format = getFormatRegistry().mapSourceToNativeWCS20(
                source_format)
        elif issubclass(coverage.real_type, RectifiedStitchedMosaic):
            # use the default format for RectifiedStitchedMosaics
            native_format = getFormatRegistry().getDefaultNativeFormat()
        else:
            # TODO: improve if no native format availabe
            native_format = None

        if extent:
            poly = Polygon.from_bbox(extent)
            poly.srid = srid
            extent = poly.transform(4326).extent
            sr = SpatialReference(4326)
        else:
            extent = coverage.extent
            sr = coverage.spatial_reference

        if issubclass(coverage.real_type, ReferenceableDataset):
            rectified = False
        else:
            rectified = True

        return WCS(
            "CoverageDescription", self.encode_bounded_by(extent, sr),
            WCS("CoverageId", coverage.identifier),
            self.encode_eo_metadata(coverage),
            self.encode_domain_set(coverage, srid, size, extent, rectified),
            self.encode_range_type(self.get_range_type(
                coverage.range_type_id)),
            WCS(
                "ServiceParameters",
                WCS("CoverageSubtype", coverage.real_type.__name__),
                WCS("nativeFormat",
                    native_format.mimeType if native_format else "")),
            **{ns_gml("id"): self.get_gml_id(coverage.identifier)})
Exemple #3
0
    def encode_coverage_description(self, coverage, srid=None, size=None,
                                    extent=None, footprint=None):
        source_mime = None
        band_items = coverage.data_items.filter(semantic__startswith="bands")
        for data_item in band_items:
            if data_item.format:
                source_mime = data_item.format
                break

        if source_mime:
            source_format = getFormatRegistry().getFormatByMIME(source_mime)
            # map the source format to the native one
            native_format = getFormatRegistry().mapSourceToNativeWCS20(
                source_format
            )
        elif issubclass(coverage.real_type, RectifiedStitchedMosaic):
            # use the default format for RectifiedStitchedMosaics
            native_format = getFormatRegistry().getDefaultNativeFormat()
        else:
            # TODO: improve if no native format availabe
            native_format = None

        if extent:
            poly = Polygon.from_bbox(extent)
            poly.srid = srid
            extent = poly.transform(4326).extent
            sr = SpatialReference(4326)
        else:
            extent = coverage.extent
            sr = coverage.spatial_reference

        if issubclass(coverage.real_type, ReferenceableDataset):
            rectified = False
        else:
            rectified = True

        return WCS("CoverageDescription",
            self.encode_bounded_by(extent, sr),
            WCS("CoverageId", coverage.identifier),
            self.encode_eo_metadata(coverage),
            self.encode_domain_set(coverage, srid, size, extent, rectified),
            self.encode_range_type(self.get_range_type(coverage.range_type_id)),
            WCS("ServiceParameters",
                WCS("CoverageSubtype", coverage.real_type.__name__),
                WCS(
                    "nativeFormat",
                    native_format.mimeType if native_format else ""
                )
            ),
            **{ns_gml("id"): self.get_gml_id(coverage.identifier)}
        )
Exemple #4
0
    def encode_service_metadata(self):
        service_metadata = WCS("ServiceMetadata")

        # get the list of enabled formats from the format registry
        formats = filter(lambda f: f,
                         getFormatRegistry().getSupportedFormatsWCS())
        service_metadata.extend(
            map(lambda f: WCS("formatSupported", f.mimeType), formats))

        # get a list of supported CRSs from the CRS registry
        supported_crss = crss.getSupportedCRS_WCS(format_function=crss.asURL)
        extension = WCS("Extension")
        service_metadata.append(extension)
        crs_metadata = CRS("CrsMetadata")
        extension.append(crs_metadata)
        crs_metadata.extend(
            map(lambda c: CRS("crsSupported", c), supported_crss))

        base_url = "http://www.opengis.net/def/interpolation/OGC/1/"

        extension.append(
            INT(
                "InterpolationMetadata", *[
                    INT("InterpolationSupported",
                        base_url + supported_interpolation)
                    for supported_interpolation in SUPPORTED_INTERPOLATIONS
                ]))
        return service_metadata
Exemple #5
0
    def encode_service_metadata(self):
        service_metadata = WCS("ServiceMetadata")

        # get the list of enabled formats from the format registry
        formats = filter(
            lambda f: f, getFormatRegistry().getSupportedFormatsWCS()
        )
        service_metadata.extend(
            map(lambda f: WCS("formatSupported", f.mimeType), formats)
        )

        # get a list of supported CRSs from the CRS registry
        supported_crss = crss.getSupportedCRS_WCS(
            format_function=crss.asURL
        )
        extension = WCS("Extension")
        service_metadata.append(extension)
        crs_metadata = CRS("CrsMetadata")
        extension.append(crs_metadata)
        crs_metadata.extend(
            map(lambda c: CRS("crsSupported", c), supported_crss)
        )

        base_url = "http://www.opengis.net/def/interpolation/OGC/1/"

        extension.append(
            INT("InterpolationMetadata", *[
                INT("InterpolationSupported",
                    base_url + supported_interpolation
                ) for supported_interpolation in SUPPORTED_INTERPOLATIONS
            ])
        )
        return service_metadata
Exemple #6
0
    def get_native_format(self, coverage, data_items):
        if issubclass(coverage.real_type, RectifiedStitchedMosaic):
            # use the default format for RectifiedStitchedMosaics
            return getFormatRegistry().getDefaultNativeFormat().wcs10name

        if len(data_items) == 1:
            return data_items[0].format

        return None
    def get_native_format(self, coverage, data_items):
        if issubclass(coverage.real_type, RectifiedStitchedMosaic):
            # use the default format for RectifiedStitchedMosaics
            return getFormatRegistry().getDefaultNativeFormat().wcs10name

        if len(data_items) == 1:
            return data_items[0].format

        return None
 def _src2nat(src_format):
     if src_format is None:
         return None
     frmreg = getFormatRegistry()
     f_src = frmreg.getFormatByMIME(src_format)
     f_dst = frmreg.mapSourceToNativeWCS20(f_src)
     f_nat = frmreg._mapSourceToNativeWCS20(f_src)
     if src_format == 'application/x-esa-envisat' and f_src == f_nat:
         return src_format
     elif f_dst is not None:
         return f_dst.mimeType
def get_format_by_mime(mime_type):
    """ Convenience function to return an enabled format descriptior for the 
        given mime type or WCS 1.0 format name. Returns ``None``, if none 
        applies.
    """

    registry = getFormatRegistry()
    reg_format = registry.getFormatByMIME(mime_type)

    if not reg_format:
        wcs10_frmts = registry.getFormatsByWCS10Name(mime_type)
        if wcs10_frmts:
            reg_format = wcs10_frmts[0]

    return reg_format
        def _get_driver(mime_src, mime_out):
            """Select backend for the given source and output formats."""
            # TODO: make this configurable
            if mime_src == 'application/x-esa-envisat' and \
               mime_out == 'application/x-netcdf':
                return "BEAM", "NetCDF4-BEAM"
            elif mime_src == 'application/x-esa-envisat' and \
               mime_out == 'application/x-esa-envisat':
                return "EOXS", "envisat"

            frmreg = getFormatRegistry()
            fobj = frmreg.getFormatByMIME(mime_out)
            if fobj is None:
                raise RenderException("Invallid output format '%s'!"%mime_out, "format")
            backend, _, driver = fobj.driver.partition("/")
            return backend, driver
Exemple #11
0
def get_format_by_mime(mime_type):
    """ Convenience function to return an enabled format descriptior for the
        given mime type or WCS 1.0 format name. Returns ``None``, if none
        applies.
    """

    registry = getFormatRegistry()
    reg_format = registry.getFormatByMIME(mime_type)

    if not reg_format:
        wcs10_frmts = registry.getFormatsByWCS10Name(mime_type)
        if wcs10_frmts:
            reg_format = wcs10_frmts[0]

    if reg_format and not is_format_supported(reg_format.mimeType):
        return None

    return reg_format
 def get_wms_formats(self):
     return getFormatRegistry().getSupportedFormatsWMS()
Exemple #13
0
 def get_wcs_formats(self):
     return getFormatRegistry().getSupportedFormatsWCS()
Exemple #14
0
    def encode_capabilities(self, sections, coverages_qs=None, dataset_series_qs=None):
        conf = CapabilitiesConfigReader(get_eoxserver_config())

        all_sections = "all" in sections
        caps = []
        if all_sections or "serviceidentification" in sections:
            caps.append(
                OWS("ServiceIdentification",
                    OWS("Title", conf.title),
                    OWS("Abstract", conf.abstract),
                    OWS("Keywords", *[
                        OWS("Keyword", keyword) for keyword in conf.keywords
                    ]),
                    OWS("ServiceType", "OGC WCS", codeSpace="OGC"),
                    OWS("ServiceTypeVersion", "2.0.1"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_application-profile_earth-observation/1.0/conf/eowcs"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_application-profile_earth-observation/1.0/conf/eowcs_get-kvp"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_service-extension_crs/1.0/conf/crs"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS/2.0/conf/core"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_protocol-binding_get-kvp/1.0/conf/get-kvp"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_protocol-binding_post-xml/1.0/conf/post-xml"),
                    OWS("Profile", "http://www.opengis.net/spec/GMLCOV/1.0/conf/gml-coverage"),
                    OWS("Profile", "http://www.opengis.net/spec/GMLCOV/1.0/conf/multipart"),
                    OWS("Profile", "http://www.opengis.net/spec/GMLCOV/1.0/conf/special-format"),
                    OWS("Profile", "http://www.opengis.net/spec/GMLCOV_geotiff-coverages/1.0/conf/geotiff-coverage"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_geotiff-coverages/1.0/conf/geotiff-coverage"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_service-model_crs-predefined/1.0/conf/crs-predefined"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_service-model_scaling+interpolation/1.0/conf/scaling+interpolation"),
                    OWS("Profile", "http://www.opengis.net/spec/WCS_service-model_band-subsetting/1.0/conf/band-subsetting"),
                    OWS("Fees", conf.fees),
                    OWS("AccessConstraints", conf.access_constraints)
                )
            )

        if all_sections or "serviceprovider" in sections:
            caps.append(
                OWS("ServiceProvider",
                    OWS("ProviderName", conf.provider_name),
                    self.encode_reference("ProviderSite", conf.provider_site),
                    OWS("ServiceContact",
                        OWS("IndividualName", conf.individual_name),
                        OWS("PositionName", conf.position_name),
                        OWS("ContactInfo",
                            OWS("Phone",
                                OWS("Voice", conf.phone_voice),
                                OWS("Facsimile", conf.phone_facsimile)
                            ),
                            OWS("Address",
                                OWS("DeliveryPoint", conf.delivery_point),
                                OWS("City", conf.city),
                                OWS("AdministrativeArea", conf.administrative_area),
                                OWS("PostalCode", conf.postal_code),
                                OWS("Country", conf.country),
                                OWS("ElectronicMailAddress", conf.electronic_mail_address)
                            ),
                            self.encode_reference(
                                "OnlineResource", conf.onlineresource
                            ),
                            OWS("HoursOfService", conf.hours_of_service),
                            OWS("ContactInstructions", conf.contact_instructions)
                        ),
                        OWS("Role", conf.role)
                    )
                )
            )


        if all_sections or "operationsmetadata" in sections:
            component = ServiceComponent(env)
            versions = ("2.0.0", "2.0.1")
            get_handlers = component.query_service_handlers(
                service="WCS", versions=versions, method="GET"
            )
            post_handlers = component.query_service_handlers(
                service="WCS", versions=versions, method="POST"
            )
            all_handlers = sorted(
                set(get_handlers + post_handlers), key=lambda h: h.request
            )

            operations = []
            for handler in all_handlers:
                methods = []
                if handler in get_handlers:
                    methods.append(
                        self.encode_reference("Get", conf.http_service_url)
                    )
                if handler in post_handlers:
                    post = self.encode_reference("Post", conf.http_service_url)
                    post.append(
                        OWS("Constraint", 
                            OWS("AllowedValues", 
                                OWS("Value", "XML")
                            ), name="PostEncoding"
                        )
                    )
                    methods.append(post)

                operations.append(
                    OWS("Operation",
                        OWS("DCP",
                            OWS("HTTP", *methods)
                        ), 
                        # apply default values as constraints
                        *[
                            OWS("Constraint",
                                OWS("NoValues"),
                                OWS("DefaultValue", str(default)),
                                name=name
                            ) for name, default 
                            in getattr(handler, "constraints", {}).items()
                        ],
                        name=handler.request
                    )
                )
            caps.append(OWS("OperationsMetadata", *operations))


        if all_sections or "servicemetadata" in sections:
            service_metadata = WCS("ServiceMetadata")

            # get the list of enabled formats from the format registry
            formats = filter(
                lambda f: f, getFormatRegistry().getSupportedFormatsWCS()
            )
            service_metadata.extend(
                map(lambda f: WCS("formatSupported", f.mimeType), formats)
            )

            # get a list of supported CRSs from the CRS registry
            supported_crss = crss.getSupportedCRS_WCS(format_function=crss.asURL)
            extension = WCS("Extension")
            service_metadata.append(extension)
            extension.extend(
                map(lambda c: CRS("crsSupported", c), supported_crss)
            )

            caps.append(service_metadata)

        inc_contents = all_sections or "contents" in sections
        inc_coverage_summary = inc_contents or "coveragesummary" in sections
        inc_dataset_series_summary = inc_contents or "datasetseriessummary" in sections
        inc_contents = inc_contents or inc_coverage_summary or inc_dataset_series_summary

        if inc_contents:
            contents = []

            if inc_coverage_summary:
                coverages = []

                # reduce data transfer by only selecting required elements
                # TODO: currently runs into a bug
                #coverages_qs = coverages_qs.only(
                #    "identifier", "real_content_type"
                #)

                for coverage in coverages_qs:
                    coverages.append(
                        WCS("CoverageSummary",
                            WCS("CoverageId", coverage.identifier),
                            WCS("CoverageSubtype", coverage.real_type.__name__)
                        )
                    )
                contents.extend(coverages)

            if inc_dataset_series_summary:
                dataset_series_set = []
                
                # reduce data transfer by only selecting required elements
                # TODO: currently runs into a bug
                #dataset_series_qs = dataset_series_qs.only(
                #    "identifier", "begin_time", "end_time", "footprint"
                #)
                
                for dataset_series in dataset_series_qs:
                    minx, miny, maxx, maxy = dataset_series.extent_wgs84

                    dataset_series_set.append(
                        EOWCS("DatasetSeriesSummary",
                            OWS("WGS84BoundingBox",
                                OWS("LowerCorner", "%f %f" % (miny, minx)),
                                OWS("UpperCorner", "%f %f" % (maxy, maxx)),
                            ),
                            EOWCS("DatasetSeriesId", dataset_series.identifier),
                            GML("TimePeriod",
                                GML("beginPosition", isoformat(dataset_series.begin_time)),
                                GML("endPosition", isoformat(dataset_series.end_time)),
                                **{ns_gml("id"): dataset_series.identifier + "_timeperiod"}
                            )
                        )
                    )

                contents.append(WCS("Extension", *dataset_series_set))

            caps.append(WCS("Contents", *contents))

        root = WCS("Capabilities", *caps, version="2.0.1", updateSequence=conf.update_sequence)
        return root
    def read(self, obj):
        ds = open_gdal(obj)
        if ds is None:
            raise Exception("Could not parse from obj '%s'." % repr(obj))

        driver = ds.GetDriver()
        size = (ds.RasterXSize, ds.RasterYSize)
        values = {"size": size}

        # --= rectified datasets =--
        # NOTE: If the projection is a non-zero string then
        #       the geocoding is given by the Geo-Trasnformation
        #       matrix - not matter what are the values.
        if ds.GetProjection():
            values["coverage_type"] = "RectifiedDataset"
            values["projection"] = (ds.GetProjection(), "WKT")

            # get coordinates of all four image corners
            gt = ds.GetGeoTransform()
            def gtrans(x, y):
                return gt[0] + x*gt[1] + y*gt[2], gt[3] + x*gt[4] + y*gt[5]
            vpix = [(0, 0), (0, size[1]), (size[0], 0), (size[0], size[1])]
            vx, vy = zip(*(gtrans(x, y) for x, y in vpix))

            # find the extent
            values["extent"] = (min(vx), min(vy), max(vx), max(vy))

        # --= tie-point encoded referenceable datasets =--
        # NOTE: If the GCP projection is a non-zero string and
        #       there are GCPs we are dealing with a tie-point geocoded
        #       referenceable dataset. The extent is given by the image
        #       footprint. The fooprint must not be wrapped arround
        #       the date-line!
        elif ds.GetGCPProjection() and ds.GetGCPCount() > 0:
            values["coverage_type"] = "ReferenceableDataset"
            projection = ds.GetGCPProjection()
            values["projection"] = (projection, "WKT")

            # parse the spatial reference to get the EPSG code
            sr = osr.SpatialReference(projection, "WKT")

            # NOTE: GeosGeometry can't handle non-EPSG geometry projections.
            if sr.GetAuthorityName(None) == "EPSG":
                srid = int(sr.GetAuthorityCode(None))

                # get the footprint
                rt_prm = rt.suggest_transformer(ds)
                fp_wkt = rt.get_footprint_wkt(ds, **rt_prm)
                footprint = GEOSGeometry(fp_wkt, srid)

                if isinstance(footprint, Polygon):
                    footprint = MultiPolygon(footprint)
                elif not isinstance(footprint, MultiPolygon):
                    raise TypeError(
                        "Got invalid geometry %s" % type(footprint).__name__
                    )

                values["footprint"] = footprint
                values["extent"] = footprint.extent

        # --= dataset with no geocoding =--
        # TODO: Handling of other types of GDAL geocoding (e.g, RPC).
        else:
            pass

        reader = self._find_additional_reader(ds)
        if reader:
            additional_values = reader.read_ds(ds)
            for key, value in additional_values.items():
                values.setdefault(key, value)

        driver_metadata = driver.GetMetadata()
        frmt = driver_metadata.get("DMD_MIMETYPE")
        if frmt is None:
            _driver_name = "GDAL/" + driver.ShortName
            _frmt = getFormatRegistry().getFormatsByDriver(_driver_name)
            if _frmt:
                frmt = _frmt[0].mimeType
        if frmt:
            values["format"] = frmt

        return values
Exemple #16
0
 def get_supported_formats(self):
     return getFormatRegistry().getSupportedFormatsWMS()
Exemple #17
0
    def render_map(self, render_map):
        # TODO: get layer creators for each layer type in the map
        map_obj = ms.mapObj()

        if render_map.bgcolor:
            map_obj.imagecolor.setHex("#" + render_map.bgcolor.lower())
        else:
            map_obj.imagecolor.setRGB(0, 0, 0)

        frmt = getFormatRegistry().getFormatByMIME(render_map.format)

        if not frmt:
            raise MapRenderError('No such format %r' % render_map.format,
                                 code='InvalidFormat',
                                 locator='format')

        outputformat_obj = ms.outputFormatObj(frmt.driver)

        outputformat_obj.transparent = (ms.MS_ON if render_map.transparent else
                                        ms.MS_OFF)
        outputformat_obj.mimetype = frmt.mimeType

        if frmt.defaultExt:
            if frmt.defaultExt.startswith('.'):
                extension = frmt.defaultExt[1:]
            else:
                extension = frmt.defaultExt

            outputformat_obj.extension = extension

        map_obj.setOutputFormat(outputformat_obj)

        #
        map_obj.setExtent(*render_map.bbox)
        map_obj.setSize(render_map.width, render_map.height)
        map_obj.setProjection(render_map.crs)
        map_obj.setConfigOption('MS_NONSQUARE', 'yes')

        layers_plus_factories = self._get_layers_plus_factories(render_map)
        layers_plus_factories_plus_data = [
            (layer, factory, factory.create(map_obj, layer))
            for layer, factory in layers_plus_factories
        ]

        # log the resulting map
        if logger.isEnabledFor(logging.DEBUG):
            with tempfile.NamedTemporaryFile() as f:
                map_obj.save(f.name)
                f.seek(0)
                logger.debug(f.read().decode('ascii'))

        try:
            # actually render the map
            image_obj = map_obj.draw()

            try:
                image_bytes = image_obj.getBytes()
            except Exception:
                tmp_name = '/vsimem/%s' % uuid4().hex
                image_obj.save(tmp_name, map_obj)
                with vsi.open(tmp_name) as f:
                    image_bytes = f.read()
                vsi.unlink(tmp_name)

            extension = outputformat_obj.extension
            if extension:
                if len(render_map.layers) == 1:
                    filename = '%s.%s' % (render_map.layers[0].name, extension)
                else:
                    filename = 'map.%s' % extension
            else:
                filename = None

            return image_bytes, outputformat_obj.mimetype, filename

        finally:
            # disconnect
            for layer, factory, data in layers_plus_factories_plus_data:
                factory.destroy(map_obj, layer, data)