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_coverage_description(self, coverage): grid = coverage.grid return WCS( "CoverageDescription", self.encode_bounded_by(coverage, grid), WCS("CoverageId", coverage.identifier), self.encode_domain_set(coverage, rectified=(grid is not None)), self.encode_range_type(coverage.range_type), WCS("ServiceParameters", WCS("CoverageSubtype", self.get_coverage_subtype(coverage))), **{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 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_contents(self, coverages_qs, dataset_series_qs): contents = [] if coverages_qs: 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 dataset_series_qs: 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)) return WCS("Contents", *contents)
def encode_contents(self, coverages, dataset_series_set): contents = [] if coverages is not None: contents.extend([ WCS( "CoverageSummary", WCS("CoverageId", coverage.identifier), WCS("CoverageSubtype", self.get_coverage_subtype(coverage))) for coverage in coverages ]) if dataset_series_set is not None: dataset_series_elements = [] for dataset_series in dataset_series_set: footprint = dataset_series.footprint dataset_series_summary = EOWCS("DatasetSeriesSummary") # NOTE: non-standard, ows:WGS84BoundingBox is actually mandatory, # but not available for e.g: empty collections if footprint: minx, miny, maxx, maxy = footprint.extent dataset_series_summary.append( OWS( "WGS84BoundingBox", OWS("LowerCorner", "%f %f" % (miny, minx)), OWS("UpperCorner", "%f %f" % (maxy, maxx)), )) dataset_series_summary.append( EOWCS("DatasetSeriesId", dataset_series.identifier)) # NOTE: non-standard, gml:TimePosition is actually mandatory, # but not available for e.g: empty collections if dataset_series.begin_time and dataset_series.end_time: dataset_series_summary.append( GML( "TimePeriod", GML("beginPosition", isoformat(dataset_series.begin_time)), GML("endPosition", isoformat(dataset_series.end_time)), **{ ns_gml("id"): dataset_series.identifier + "_timeperiod" })) dataset_series_elements.append(dataset_series_summary) if dataset_series_elements: contents.append(WCS("Extension", *dataset_series_elements)) return WCS("Contents", *contents)
def encode_contributing_datasets(self, coverage, subset_polygon=None): eo_objects = coverage.eo_objects if subset_polygon: if subset_polygon.srid != 4326: subset_polygon = subset_polygon.transform(4326, True) eo_objects = eo_objects.filter( footprint__intersects=subset_polygon) # iterate over all subsets in reverse order to get the eo_objects = eo_objects.order_by("-begin_time") actual_contributions = [] all_contributions = [] for eo_object in eo_objects: contribution = self.calculate_contribution(eo_object.footprint, all_contributions, subset_polygon) if not contribution.empty and contribution.num_geom > 0: actual_contributions.append((eo_object, contribution)) return EOWCS( "datasets", *[ EOWCS( "dataset", WCS("CoverageId", eo_object.identifier), EOWCS("contributingFootprint", self.encode_footprint(contrib, eo_object.identifier))) for eo_object, contrib in reversed(actual_contributions) ])
def encode_coverage_description(self, coverage): if issubclass(coverage.real_type, ReferenceableDataset): rectified = False else: rectified = True return WCS( "CoverageDescription", self.encode_bounded_by(coverage.extent_wgs84), WCS("CoverageId", coverage.identifier), self.encode_domain_set(coverage, rectified=rectified), self.encode_range_type(self.get_range_type( coverage.range_type_id)), WCS("ServiceParameters", WCS("CoverageSubtype", coverage.real_type.__name__)), **{ns_gml("id"): self.get_gml_id(coverage.identifier)})
def encode_contributing_datasets(self, mosaic, subset_polygon=None): actual_contributions = [] all_contributions = [] for coverage in mosaic.coverages: contribution = self.calculate_contribution(coverage.footprint, all_contributions, subset_polygon) if not contribution.empty and contribution.num_geom > 0: actual_contributions.append((coverage, contribution)) return EOWCS( "datasets", *[ EOWCS( "dataset", WCS("CoverageId", coverage.identifier), EOWCS("contributingFootprint", self.encode_footprint(contrib, coverage.identifier))) for coverage, contrib in reversed(actual_contributions) ])
def encode_capabilities( self, sections, conf, coverages=None, dataset_series=None, request=None, ): conf = self.get_conf() all_sections = "all" in sections caps = [] if all_sections or "serviceidentification" in sections: caps.append( self.encode_service_identification("WCS", conf, PROFILES)) if all_sections or "serviceprovider" in sections: caps.append(self.encode_service_provider(conf)) if all_sections or "operationsmetadata" in sections: caps.append( self.encode_operations_metadata(request, "WCS", ("2.0.0", "2.0.1"))) if all_sections or "servicemetadata" in sections: caps.append(self.encode_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) if inc_contents or inc_coverage_summary or inc_dataset_series_summary: caps.append( self.encode_contents( coverages if inc_coverage_summary else None, dataset_series if inc_dataset_series_summary else None, )) return WCS("Capabilities", *caps, version="2.0.1", updateSequence=conf.update_sequence)
def encode_capabilities(self, sections, coverages_qs=None, dataset_series_qs=None, request=None): conf = CapabilitiesConfigReader(get_eoxserver_config()) all_sections = "all" in sections caps = [] if all_sections or "serviceidentification" in sections: caps.append(self.encode_service_identification(conf)) if all_sections or "serviceprovider" in sections: caps.append(self.encode_service_provider(conf)) if all_sections or "operationsmetadata" in sections: caps.append(self.encode_operations_metadata(request)) if all_sections or "servicemetadata" in sections: caps.append(self.encode_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) if inc_contents or inc_coverage_summary or inc_dataset_series_summary: caps.append( self.encode_contents( coverages_qs if inc_coverage_summary else None, dataset_series_qs if inc_dataset_series_summary else None)) return WCS("Capabilities", *caps, version="2.0.1", updateSequence=conf.update_sequence)
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 encode_coverage_descriptions(self, coverages): return WCS( "CoverageDescriptions", *[ self.encode_coverage_description(coverage) for coverage in coverages ])
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