def encode_bounded_by(self, extent, sr=None): minx, miny, maxx, maxy = extent sr = sr or SpatialReference(4326) swap = crss.getAxesSwapper(sr.srid) labels = ("x", "y") if sr.IsProjected() else ("long", "lat") axis_labels = " ".join(swap(*labels)) axis_units = "m m" if sr.IsProjected() else "deg deg" frmt = "%.3f %.3f" if sr.IsProjected() else "%.8f %.8f" # Make sure values are outside of actual extent if sr.IsProjected(): minx -= 0.0005 miny -= 0.0005 maxx += 0.0005 maxy += 0.0005 else: minx -= 0.000000005 miny -= 0.000000005 maxx += 0.000000005 maxy += 0.000000005 return GML( "boundedBy", GML("Envelope", GML("lowerCorner", frmt % swap(minx, miny)), GML("upperCorner", frmt % swap(maxx, maxy)), srsName=sr.url, axisLabels=axis_labels, uomLabels=axis_units, srsDimension="2"))
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_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_referenceable_grid(self, size, sr, grid_name): size_x, size_y = size swap = crss.getAxesSwapper(sr.srid) labels = ("x", "y") if sr.IsProjected() else ("long", "lat") axis_labels = " ".join(swap(*labels)) return GML( "ReferenceableGrid", GML("limits", self.encode_grid_envelope([size_x - 1, size_y - 1])), GML("axisLabels", axis_labels), **{ ns_gml("id"): self.get_gml_id(grid_name), "dimension": "2" })
def encode_rectified_grid(self, size, extent, sr, grid_name): size_x, size_y = size minx, miny, maxx, maxy = extent srs_name = sr.url swap = crss.getAxesSwapper(sr.srid) frmt = "%.3f %.3f" if sr.IsProjected() else "%.8f %.8f" labels = ("x", "y") if sr.IsProjected() else ("long", "lat") axis_labels = " ".join(swap(*labels)) origin = frmt % swap(minx, maxy) x_offsets = frmt % swap((maxx - minx) / float(size_x), 0) y_offsets = frmt % swap(0, (miny - maxy) / float(size_y)) return GML( "RectifiedGrid", GML("limits", self.encode_grid_envelope(0, 0, size_x - 1, size_y - 1)), GML("axisLabels", axis_labels), GML( "origin", GML( "Point", GML("pos", origin), **{ ns_gml("id"): self.get_gml_id("%s_origin" % grid_name), "srsName": srs_name })), GML("offsetVector", x_offsets, srsName=srs_name), GML("offsetVector", y_offsets, srsName=srs_name), **{ ns_gml("id"): self.get_gml_id(grid_name), "dimension": "2" })
def encode_domain_set(self, coverage, srid=None, size=None, extent=None, rectified=True): grid_name = "%s_grid" % coverage.identifier grid = coverage.grid sr = SpatialReference(grid.coordinate_reference_system) if grid and not grid.is_referenceable: return GML("domainSet", self.encode_rectified_grid(grid, coverage, grid_name)) else: return GML( "domainSet", self.encode_referenceable_grid(size or coverage.size, sr, grid_name))
def encode_domain_set(self, coverage, srid=None, size=None, extent=None, rectified=True): grid_name = "%s_grid" % coverage.identifier srs = SpatialReference(srid) if srid is not None else None if rectified: return GML( "domainSet", self.encode_rectified_grid(size or coverage.size, extent or coverage.extent, srs or coverage.spatial_reference, grid_name)) else: return GML( "domainSet", self.encode_referenceable_grid( size or coverage.size, srs or coverage.spatial_reference, grid_name))
def encode_range_set(self, reference, mime_type): return GML( "rangeSet", GML( "File", GML( "rangeParameters", **{ ns_xlink("arcrole"): "fileReference", ns_xlink("href"): reference, ns_xlink("role"): mime_type }), GML("fileReference", reference), GML("fileStructure"), GML("mimeType", mime_type)))
def encode_range_set(self, reference, mime_type): return GML( "rangeSet", GML( "File", GML( "rangeParameters", **{ ns_xlink("arcrole"): "fileReference", ns_xlink("href"): reference, ns_xlink("role"): "http://www.opengis.net/spec/GMLCOV_geotiff-coverages/1.0/conf/geotiff-coverage" }), GML("fileReference", reference), GML("fileStructure"), GML("mimeType", mime_type)))
def encode_rectified_grid(self, grid, coverage, name): axis_names = [axis.name for axis in grid] offsets = [axis.offset for axis in grid] origin = coverage.origin sr = SpatialReference(grid.coordinate_reference_system) url = sr.url frmt = "%.3f" if sr.IsProjected() else "%.8f" offset_vectors = [ GML("offsetVector", " ".join([frmt % 0.0] * i + [frmt % offset] + [frmt % 0.0] * (len(offsets) - i - 1)), srsName=url) for i, offset in enumerate(offsets) ] if crss.hasSwappedAxes(sr.srid): axis_names[0:2] = [axis_names[1], axis_names[0]] # offset_vectors[0:2] = [offset_vectors[1], offset_vectors[0]] for offset_vector in offset_vectors[0:2]: parts = offset_vector.text.split(" ") parts[0:2] = reversed(parts[0:2]) offset_vector.text = " ".join(parts) origin[0:2] = [origin[1], origin[0]] origin_str = " ".join(["%.3f" if sr.IsProjected() else "%.8f"] * len(origin)) % tuple(origin) return GML( "RectifiedGrid", GML("limits", self.encode_grid_envelope(coverage.size)), GML("axisLabels", " ".join(axis_names)), GML( "origin", GML( "Point", GML("pos", origin_str), **{ ns_gml("id"): self.get_gml_id("%s_origin" % name), "srsName": url })), *offset_vectors, **{ ns_gml("id"): self.get_gml_id(name), "dimension": "2" })
def encode_grid_envelope(self, low_x, low_y, high_x, high_y): return GML("GridEnvelope", GML("low", "%d %d" % (low_x, low_y)), GML("high", "%d %d" % (high_x, high_y)))
def encode_bounded_by(self, coverage, grid=None, subset_extent=None): # if grid is None: footprint = coverage.footprint if grid and not grid.is_referenceable: sr = SpatialReference(grid.coordinate_reference_system) labels = grid.names axis_units = " ".join(["m" if sr.IsProjected() else "deg"] * len(labels)) extent = list(subset_extent) if subset_extent else list( coverage.extent) lc = extent[:len(extent) // 2] uc = extent[len(extent) // 2:] if crss.hasSwappedAxes(sr.srid): labels[0:2] = labels[1], labels[0] lc[0:2] = lc[1], lc[0] uc[0:2] = uc[1], uc[0] frmt = " ".join(["%.3f" if sr.IsProjected() else "%.8f"] * len(labels)) lower_corner = frmt % tuple(lc) upper_corner = frmt % tuple(uc) axis_labels = " ".join(labels) srs_name = sr.url elif footprint: minx, miny, maxx, maxy = subset_extent or footprint.extent sr = SpatialReference(4326) swap = crss.getAxesSwapper(sr.srid) labels = ("x", "y") if sr.IsProjected() else ("long", "lat") axis_labels = " ".join(swap(*labels)) axis_units = "m m" if sr.IsProjected() else "deg deg" frmt = "%.3f %.3f" if sr.IsProjected() else "%.8f %.8f" # Make sure values are outside of actual extent if sr.IsProjected(): minx -= 0.0005 miny -= 0.0005 maxx += 0.0005 maxy += 0.0005 else: minx -= 0.000000005 miny -= 0.000000005 maxx += 0.000000005 maxy += 0.000000005 lower_corner = frmt % swap(minx, miny) upper_corner = frmt % swap(maxx, maxy) srs_name = sr.url else: lower_corner = "" upper_corner = "" srs_name = "" axis_labels = "" axis_units = "" return GML( "boundedBy", GML("Envelope", GML("lowerCorner", lower_corner), GML("upperCorner", upper_corner), srsName=srs_name, axisLabels=axis_labels, uomLabels=axis_units, srsDimension="2"))
def encode_grid_envelope(self, sizes): return GML( "GridEnvelope", GML("low", " ".join("0" for size in sizes)), GML("high", " ".join(("%d" % (size - 1) for size in sizes))))