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)})
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)})
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)} )
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
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
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
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()
def get_wcs_formats(self): return getFormatRegistry().getSupportedFormatsWCS()
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
def get_supported_formats(self): return getFormatRegistry().getSupportedFormatsWMS()
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)