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_eo_metadata(self, coverage, request=None, subset_polygon=None): metadata_items = [ metadata_location for metadata_location in getattr( coverage, 'metadata_locations', []) if metadata_location.format == "eogml" ] if len(metadata_items) >= 1: with vsi.open(metadata_items[0].path) as f: earth_observation = etree.parse(f).getroot() if subset_polygon: try: feature = earth_observation.xpath("om:featureOfInterest", namespaces=nsmap)[0] feature[0] = self.encode_footprint( coverage.footprint.intersection(subset_polygon), coverage.identifier) except IndexError: pass # no featureOfInterest else: earth_observation = self.encode_earth_observation( coverage.identifier, coverage.begin_time, coverage.end_time, coverage.footprint, subset_polygon=subset_polygon) if not request: lineage = None elif request.method == "GET": lineage = EOWCS( "lineage", EOWCS( "referenceGetCoverage", self.encode_reference( "Reference", request.build_absolute_uri().replace("&", "&"), False)), GML("timePosition", isoformat(now()))) elif request.method == "POST": # TODO: better way to do this href = request.build_absolute_uri().replace("&", "&") lineage = EOWCS( "lineage", EOWCS( "referenceGetCoverage", OWS("ServiceReference", OWS("RequestMessage", etree.parse(request).getroot()), **{ns_xlink("href"): href})), GML("timePosition", isoformat(now()))) return GMLCOV( "metadata", GMLCOV( "Extension", EOWCS("EOMetadata", earth_observation, *[lineage] if lineage is not None else [])))
def encode_dataset_series_description(self, dataset_series): return EOWCS( "DatasetSeriesDescription", self.encode_bounded_by(dataset_series.extent_wgs84), EOWCS("DatasetSeriesId", dataset_series.identifier), self.encode_time_period( dataset_series.begin_time, dataset_series.end_time, "%s_timeperiod" % dataset_series.identifier), **{ns_gml("id"): self.get_gml_id(dataset_series.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_eo_coverage_set_description( self, dataset_series_set, coverages, number_matched=None, number_returned=None ): if number_matched is None: number_matched = len(coverages) + len(dataset_series_set) if number_returned is None: number_returned = len(coverages) + len(dataset_series_set) root = EOWCS("EOCoverageSetDescription", numberMatched=str(number_matched), numberReturned=str(number_returned)) if coverages: root.append(self.encode_coverage_descriptions(coverages)) if dataset_series_set: root.append(self.encode_dataset_series_descriptions(dataset_series_set)) return root
def encode_dataset_series_description(self, dataset_series): elements = [] if dataset_series.footprint: elements.append(self.encode_bounded_by(dataset_series, None)) elements.append(EOWCS("DatasetSeriesId", dataset_series.identifier)) if dataset_series.begin_time and dataset_series.end_time: elements.append( self.encode_time_period( dataset_series.begin_time, dataset_series.end_time, "%s_timeperiod" % dataset_series.identifier)) return EOWCS( "DatasetSeriesDescription", *elements, **{ns_gml("id"): self.get_gml_id(dataset_series.identifier)})
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, 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 alter_rectified_dataset(self, coverage, request, tree, subset_polygon=None): return EOWCS( "RectifiedDataset", *(tree.getchildren() + [self.encode_eo_metadata(coverage, request, subset_polygon)]), **tree.attrib)
def alter_rectified_stitched_mosaic(self, coverage, request, tree, subset_polygon=None): return EOWCS( "RectifiedStitchedMosaic", *(tree.getchildren() + [ self.encode_eo_metadata(coverage, request, subset_polygon), self.encode_contributing_datasets(coverage, subset_polygon) ]), **tree.attrib)
def encode_rectified_dataset(self, coverage, request, reference, mime_type, subset_polygon=None): return EOWCS( "RectifiedDataset", self.encode_bounded_by(coverage, coverage.grid), self.encode_domain_set(coverage, rectified=True), self.encode_range_set(reference, mime_type), self.encode_range_type(coverage.range_type), self.encode_eo_metadata(coverage, request, subset_polygon), **{ns_gml("id"): self.get_gml_id(coverage.identifier)})
def encode_referenceable_dataset(self, coverage, range_type, reference, mime_type, subset=None): # handle subset dst_srid = SpatialReference( coverage.grid.coordinate_reference_system).srid if not subset: # whole area - no subset domain_set = self.encode_domain_set(coverage, rectified=False) eo_metadata = self.encode_eo_metadata(coverage) extent = coverage.footprint.extent sr = SpatialReference(dst_srid) else: # subset is given srid, size, extent, footprint = subset srid = srid if srid is not None else 4326 domain_set = self.encode_domain_set(coverage, srid, size, extent, False) eo_metadata = self.encode_eo_metadata(coverage, subset_polygon=footprint) # get the WGS84 extent poly = Polygon.from_bbox(extent) poly.srid = srid if srid != dst_srid: poly.transform(dst_srid) extent = poly.extent sr = SpatialReference(srid) return EOWCS("ReferenceableDataset", self.encode_bounded_by(coverage, coverage.grid, extent), domain_set, self.encode_range_set(reference, mime_type), self.encode_range_type(range_type), eo_metadata, **{ns_gml("id"): self.get_gml_id(coverage.identifier)})
def encode_eo_coverage_set_description(self, dataset_series_set, coverages, number_matched=None, number_returned=None): if number_matched is None: number_matched = len(coverages) + len(dataset_series_set) if number_returned is None: number_returned = len(coverages) + len(dataset_series_set) root = EOWCS("EOCoverageSetDescription", numberMatched=str(number_matched), numberReturned=str(number_returned)) if coverages: root.append(self.encode_coverage_descriptions(coverages)) if dataset_series_set: root.append( self.encode_dataset_series_descriptions(dataset_series_set)) return root
def encode_dataset_series_descriptions(self, dataset_series_set): return EOWCS( "DatasetSeriesDescriptions", *[ self.encode_dataset_series_description(dataset_series) for dataset_series in dataset_series_set ])