def handle(self, request): decoder = WMS13GetMapDecoder(request.GET) bbox = decoder.bbox time = decoder.time crs = decoder.crs layers = decoder.layers if not layers: raise InvalidParameterException("No layers specified", "layers") srid = crss.parseEPSGCode( crs, (crss.fromShortCode, crss.fromURN, crss.fromURL)) if srid is None: raise InvalidCRS(crs, "crs") if crss.hasSwappedAxes(srid): miny, minx, maxy, maxx = bbox else: minx, miny, maxx, maxy = bbox subsets = Subsets(( Trim("x", minx, maxx), Trim("y", miny, maxy), ), crs=crs) if time: subsets.append(time) # TODO: adjust way to get to renderer styles = decoder.styles if styles: styles = styles.split(',') from eoxserver.services.ows.wms.layerquery import LayerQuery render_map = LayerQuery().create_map( layers=layers, styles=styles, bbox=bbox, crs=crs, width=decoder.width, height=decoder.height, format=decoder.format, transparent=decoder.transparent, bgcolor=decoder.bgcolor, time=time, range=decoder.dim_range, bands=None, wavelengths=None, elevation=None, cql=decoder.cql, ) from eoxserver.render.mapserver.map_renderer import MapserverMapRenderer return MapserverMapRenderer().render_map(render_map)
def bbox(self): bbox = self._bbox crs = self.crs srid = crss.parseEPSGCode( self.crs, (crss.fromShortCode, crss.fromURN, crss.fromURL)) if srid is None: raise InvalidCRS(crs, "crs") if crss.hasSwappedAxes(srid): miny, minx, maxy, maxx = bbox else: minx, miny, maxx, maxy = bbox return (minx, miny, maxx, maxy)
def handle(self, request): decoder = WMS13GetMapDecoder(request.GET) bbox = decoder.bbox time = decoder.time crs = decoder.crs layers = decoder.layers if not layers: raise InvalidParameterException("No layers specified", "layers") srid = crss.parseEPSGCode( crs, (crss.fromShortCode, crss.fromURN, crss.fromURL) ) if srid is None: raise InvalidCRS(crs, "crs") if crss.hasSwappedAxes(srid): miny, minx, maxy, maxx = bbox else: minx, miny, maxx, maxy = bbox subsets = Subsets(( Trim("x", minx, maxx), Trim("y", miny, maxy), ), crs=crs) if time: subsets.append(time) renderer = self.renderer root_group = lookup_layers(layers, subsets, renderer.suffixes) result, _ = renderer.render( root_group, request.GET.items(), width=int(decoder.width), height=int(decoder.height), time=decoder.time, bands=decoder.dim_bands, subsets=subsets, elevation=decoder.elevation, dimensions=dict( (key[4:], values) for key, values in decoder.dimensions ) ) return to_http_response(result)
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 parse_mask(mask_elem): nsmap = {k: v for k, v in iteritems(mask_elem.nsmap) if k} # name = mask_elem.xpath('gml:name/text()', namespaces=nsmap)[0] try: crs = mask_elem.xpath('gml:boundedBy/gml:Envelope/@srsName', namespaces=nsmap)[0] except IndexError: # just return an empty polygon when no mask available return MultiPolygon() srid = crss.parseEPSGCode(crs, [crss.fromURN]) swap = crss.hasSwappedAxes(srid) mask_features = [ parse_polygon(polygon_elem, nsmap, swap) for polygon_elem in mask_elem.xpath( 'eop:maskMembers/eop:MaskFeature/eop:extentOf/gml:Polygon', namespaces=nsmap) ] return MultiPolygon(mask_features, srid=srid)
def handle(self, request): decoder = WMS13GetFeatureInfoDecoder(request.GET) bbox = decoder.bbox time = decoder.time crs = decoder.crs layers = decoder.layers if not layers: raise InvalidParameterException("No layers specified", "layers") srid = crss.parseEPSGCode( crs, (crss.fromShortCode, crss.fromURN, crss.fromURL)) if srid is None: raise InvalidParameterException("Invalid CRS specifier.", "crs") if crss.hasSwappedAxes(srid): miny, minx, maxy, maxx = bbox else: minx, miny, maxx, maxy = bbox subsets = Subsets(( Trim("x", minx, maxx), Trim("y", miny, maxy), ), crs=crs) if time: subsets.append(time) renderer = self.renderer root_group = lookup_layers(layers, subsets, renderer.suffixes) result, _ = renderer.render(root_group, request.GET.items(), request, time=decoder.time, bands=decoder.dim_bands) return to_http_response(result)
def handle(self, request): decoder = WMS13GetMapDecoder(request.GET) bbox = decoder.bbox time = decoder.time crs = decoder.crs layers = decoder.layers elevation = decoder.elevation if not layers: raise InvalidParameterException("No layers specified", "layers") srid = crss.parseEPSGCode( crs, (crss.fromShortCode, crss.fromURN, crss.fromURL) ) if srid is None: raise InvalidCRS(crs, "crs") if crss.hasSwappedAxes(srid): miny, minx, maxy, maxx = bbox else: minx, miny, maxx, maxy = bbox subsets = Subsets(( Trim("x", minx, maxx, crs), Trim("y", miny, maxy, crs), )) if time: subsets.append(time) renderer = self.renderer result, _ = renderer.render( layers, (minx, miny, maxx, maxy), crs, (decoder.width, decoder.height), decoder.format, time, elevation, decoder.styles ) return to_http_response(result)
def handle(self, request): decoder = WMS13GetFeatureInfoDecoder(request.GET) bbox = decoder.bbox time = decoder.time crs = decoder.crs layers = decoder.layers if not layers: raise InvalidParameterException("No layers specified", "layers") srid = crss.parseEPSGCode( crs, (crss.fromShortCode, crss.fromURN, crss.fromURL) ) if srid is None: raise InvalidParameterException("Invalid CRS specifier.", "crs") if crss.hasSwappedAxes(srid): miny, minx, maxy, maxx = bbox else: minx, miny, maxx, maxy = bbox subsets = Subsets(( Trim("x", minx, maxx), Trim("y", miny, maxy), ), crs=crs) if time: subsets.append(time) renderer = self.renderer root_group = lookup_layers(layers, subsets, renderer.suffixes) result, _ = renderer.render( root_group, request.GET.items(), time=decoder.time, bands=decoder.dim_bands ) return to_http_response(result)
def handle(self, request): decoder = WMS13GetMapDecoder(request.GET) bbox = decoder.bbox time = decoder.time crs = decoder.crs layers = decoder.layers elevation = decoder.elevation if not layers: raise InvalidParameterException("No layers specified", "layers") srid = crss.parseEPSGCode( crs, (crss.fromShortCode, crss.fromURN, crss.fromURL)) if srid is None: raise InvalidCRS(crs, "crs") if crss.hasSwappedAxes(srid): miny, minx, maxy, maxx = bbox else: minx, miny, maxx, maxy = bbox subsets = Subsets(( Trim("x", minx, maxx, crs), Trim("y", miny, maxy, crs), )) if time: subsets.append(time) renderer = self.renderer result, _ = renderer.render(layers, (minx, miny, maxx, maxy), crs, (decoder.width, decoder.height), decoder.format, time, elevation, decoder.styles) return to_http_response(result)
def _georef_from_parsed(parsed_browse, clipping=None): srid = fromShortCode(parsed_browse.reference_system_identifier) if parsed_browse.reference_system_identifier == "RAW" and parsed_browse.geo_type != "modelInGeotiffBrowse": raise IngestionException( "Given referenceSystemIdentifier '%s' not " "valid for a '%s'." % (parsed_browse.reference_system_identifier, parsed_browse.geo_type) ) if srid is None and parsed_browse.reference_system_identifier != "RAW": raise IngestionException( "Given referenceSystemIdentifier '%s' not valid." % parsed_browse.reference_system_identifier ) swap_axes = hasSwappedAxes(srid) if parsed_browse.geo_type == "rectifiedBrowse": coords = decode_coord_list(parsed_browse.coord_list, swap_axes) # values are for bottom/left and top/right pixel coords = [coord for pair in coords for coord in pair] assert len(coords) == 4 return Extent(*coords, srid=srid) elif parsed_browse.geo_type == "footprintBrowse": # Generate GCPs from footprint coordinates pixels = decode_coord_list(parsed_browse.col_row_list) coord_list = decode_coord_list(parsed_browse.coord_list, swap_axes) if _coord_list_crosses_dateline(coord_list, CRS_BOUNDS[srid]): logger.info("Footprint crosses the dateline. Normalizing it.") coord_list = _unwrap_coord_list(coord_list, CRS_BOUNDS[srid]) assert len(pixels) == len(coord_list) gcps = [(x, y, pixel, line) for (x, y), (pixel, line) in zip(coord_list, pixels)] # check that the last point of the footprint is the first if not gcps[0] == gcps[-1]: raise IngestionException("The last value of the footprint is not " "equal to the first.") gcps.pop() return GCPList(gcps, srid) elif parsed_browse.geo_type == "regularGridBrowse": # calculate a list of pixel coordinates according to the values of the # parsed browse report (col_node_number * row_node_number) range_x = arange(0.0, parsed_browse.row_node_number * parsed_browse.row_step, parsed_browse.row_step) range_y = arange(0.0, parsed_browse.col_node_number * parsed_browse.col_step, parsed_browse.col_step) pixels = [(x, y) for x in range_x for y in range_y] # apply clipping if clipping: clip_x, clip_y = clipping pixels[:] = [(min(clip_x, x), min(clip_y, y)) for x, y in pixels] # decode coordinate lists and check if any crosses the dateline coord_lists = [] crosses_dateline = False for coord_list in parsed_browse.coord_lists: coord_list = decode_coord_list(coord_list, swap_axes) crosses_dateline = crosses_dateline or _coord_list_crosses_dateline(coord_list, CRS_BOUNDS[srid]) coord_lists.append(coord_list) # if any coordinate list was crossing the dateline, unwrap all # coordinate lists if crosses_dateline: logger.info("Regular grid crosses the dateline. Normalizing it.") coord_lists = [_unwrap_coord_list(coord_list, CRS_BOUNDS[srid]) for coord_list in coord_lists] coords = [] for coord_list in coord_lists: coords.extend(coord_list) # check validity of regularGrid if len(parsed_browse.coord_lists) != parsed_browse.row_node_number: raise IngestionException( "Invalid regularGrid: number of coordinate " "lists is not equal to the given row node " "number." ) elif len(coords) / len(parsed_browse.coord_lists) != parsed_browse.col_node_number: raise IngestionException("Invalid regularGrid: number of coordinates " "does not fit given columns number.") gcps = [(x, y, pixel, line) for (x, y), (pixel, line) in zip(coords, pixels)] return GCPList(gcps, srid) elif parsed_browse.geo_type == "modelInGeotiffBrowse": return None else: raise NotImplementedError("Invalid geo-reference type '%s'." % parsed_browse.geo_type)
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 _georef_from_parsed(parsed_browse, clipping=None): srid = fromShortCode(parsed_browse.reference_system_identifier) if (parsed_browse.reference_system_identifier == "RAW" and parsed_browse.geo_type != "modelInGeotiffBrowse"): raise IngestionException("Given referenceSystemIdentifier '%s' not " "valid for a '%s'." % (parsed_browse.reference_system_identifier, parsed_browse.geo_type)) if srid is None and parsed_browse.reference_system_identifier != "RAW": raise IngestionException("Given referenceSystemIdentifier '%s' not valid." % parsed_browse.reference_system_identifier) swap_axes = hasSwappedAxes(srid) if parsed_browse.geo_type == "rectifiedBrowse": coords = decode_coord_list(parsed_browse.coord_list, swap_axes) # values are for bottom/left and top/right pixel coords = [coord for pair in coords for coord in pair] assert(len(coords) == 4) return Extent(*coords, srid=srid) elif parsed_browse.geo_type == "footprintBrowse": # Generate GCPs from footprint coordinates pixels = decode_coord_list(parsed_browse.col_row_list) # substitute ncol and nrow with image size if clipping: clip_x, clip_y = clipping pixels[:] = [(clip_x if x == "ncol" else x, clip_y if y == "nrow" else y) for x, y in pixels] coord_list = decode_coord_list(parsed_browse.coord_list, swap_axes) if _coord_list_crosses_dateline(coord_list, CRS_BOUNDS[srid]): logger.info("Footprint crosses the dateline. Normalizing it.") coord_list = _unwrap_coord_list(coord_list, CRS_BOUNDS[srid]) assert(len(pixels) == len(coord_list)) gcps = [(x, y, pixel, line) for (x, y), (pixel, line) in zip(coord_list, pixels)] # check that the last point of the footprint is the first if not gcps[0] == gcps[-1]: raise IngestionException("The last value of the footprint is not " "equal to the first.") gcps.pop() return GCPList(gcps, srid) elif parsed_browse.geo_type == "regularGridBrowse": # calculate a list of pixel coordinates according to the values of the # parsed browse report (col_node_number * row_node_number) range_x = arange( 0.0, parsed_browse.row_node_number * parsed_browse.row_step, parsed_browse.row_step ) range_y = arange( 0.0, parsed_browse.col_node_number * parsed_browse.col_step, parsed_browse.col_step ) pixels = [(x, y) for x in range_x for y in range_y] # apply clipping if clipping: clip_x, clip_y = clipping pixels[:] = [ (min(clip_x, x), min(clip_y, y)) for x, y in pixels ] # decode coordinate lists and check if any crosses the dateline coord_lists = [] crosses_dateline = False for coord_list in parsed_browse.coord_lists: coord_list = decode_coord_list(coord_list, swap_axes) crosses_dateline = crosses_dateline or \ _coord_list_crosses_dateline(coord_list, CRS_BOUNDS[srid]) coord_lists.append(coord_list) # if any coordinate list was crossing the dateline, unwrap all # coordinate lists if crosses_dateline: logger.info("Regular grid crosses the dateline. Normalizing it.") coord_lists = [ _unwrap_coord_list(coord_list, CRS_BOUNDS[srid]) for coord_list in coord_lists ] coords = [] for coord_list in coord_lists: coords.extend(coord_list) # check validity of regularGrid if len(parsed_browse.coord_lists) != parsed_browse.row_node_number: raise IngestionException("Invalid regularGrid: number of coordinate " "lists is not equal to the given row node " "number.") elif len(coords) / len(parsed_browse.coord_lists) != parsed_browse.col_node_number: raise IngestionException("Invalid regularGrid: number of coordinates " "does not fit given columns number.") gcps = [(x, y, pixel, line) for (x, y), (pixel, line) in zip(coords, pixels)] return GCPList(gcps, srid) elif parsed_browse.geo_type == "modelInGeotiffBrowse": return None else: raise NotImplementedError("Invalid geo-reference type '%s'." % parsed_browse.geo_type)
def _georef_from_parsed(parsed_browse): srid = fromShortCode(parsed_browse.reference_system_identifier) if (parsed_browse.reference_system_identifier == "RAW" and parsed_browse.geo_type != "modelInGeotiffBrowse"): raise IngestionException("Given referenceSystemIdentifier '%s' not " "valid for a '%s'." % (parsed_browse.reference_system_identifier, parsed_browse.geo_type)) if srid is None and parsed_browse.reference_system_identifier != "RAW": raise IngestionException("Given referenceSystemIdentifier '%s' not valid." % parsed_browse.reference_system_identifier) swap_axes = hasSwappedAxes(srid) if parsed_browse.geo_type == "rectifiedBrowse": coords = decode_coord_list(parsed_browse.coord_list, swap_axes) # values are for bottom/left and top/right pixel coords = [coord for pair in coords for coord in pair] assert(len(coords) == 4) return Extent(*coords, srid=srid) elif parsed_browse.geo_type == "footprintBrowse": # Generate GCPs from footprint coordinates pixels = decode_coord_list(parsed_browse.col_row_list) coord_list = decode_coord_list(parsed_browse.coord_list, swap_axes) if _coord_list_crosses_dateline(coord_list, CRS_BOUNDS[srid]): logger.info("Footprint crosses the dateline. Normalizing it.") coord_list = _unwrap_coord_list(coord_list, CRS_BOUNDS[srid]) assert(len(pixels) == len(coord_list)) gcps = [(x, y, pixel, line) for (x, y), (pixel, line) in zip(coord_list, pixels)] # check that the last point of the footprint is the first if not gcps[0] == gcps[-1]: raise IngestionException("The last value of the footprint is not " "equal to the first.") gcps.pop() return GCPList(gcps, srid) elif parsed_browse.geo_type == "regularGridBrowse": # calculate a list of pixel coordinates according to the values of the # parsed browse report (col_node_number * row_node_number) range_x = arange( 0.0, parsed_browse.row_node_number * parsed_browse.row_step, parsed_browse.row_step ) range_y = arange( 0.0, parsed_browse.col_node_number * parsed_browse.col_step, parsed_browse.col_step ) pixels = [(x, y) for x in range_x for y in range_y] # get the lat-lon coordinates as tuple-lists # TODO: normalize if dateline is crossed coord_lists = [] for coord_list in parsed_browse.coord_lists: coord_list = decode_coord_list(coord_list, swap_axes) # TODO: iterate over every coord pair. if a dateline cross occurred # move all the negative values to the positive space if _coord_list_crosses_dateline(coord_list, CRS_BOUNDS[srid]): logger.info("Regular grid crosses the dateline. Normalizing it.") coord_list = _unwrap_coord_list(coord_list, CRS_BOUNDS[srid]) coord_lists.append(coord_list) coords = [] for coord_list in coord_lists: coords.extend(coord_list) # check validity of regularGrid if len(parsed_browse.coord_lists) != parsed_browse.row_node_number: raise IngestionException("Invalid regularGrid: number of coordinate " "lists is not equal to the given row node " "number.") elif len(coords) / len(parsed_browse.coord_lists) != parsed_browse.col_node_number: raise IngestionException("Invalid regularGrid: number of coordinates " "does not fit given columns number.") gcps = [(x, y, pixel, line) for (x, y), (pixel, line) in zip(coords, pixels)] return GCPList(gcps, srid) elif parsed_browse.geo_type == "modelInGeotiffBrowse": return None elif parsed_browse.geo_type == "verticalCurtainBrowse": pixels = decode_coord_list(parsed_browse.col_row_list) coord_list = decode_coord_list(parsed_browse.coord_list, swap_axes) if _coord_list_crosses_dateline(coord_list, CRS_BOUNDS[srid]): logger.info("Vertical curtain footprint crosses the dateline. Normalizing it.") coord_list = _unwrap_coord_list(coord_list, CRS_BOUNDS[srid]) gcps = [(x, y, pixel, line) for (x, y), (pixel, line) in zip(coord_list, pixels)] return VerticalCurtainGeoReference(gcps, srid) else: raise NotImplementedError("Invalid geo-reference type '%s'." % parsed_browse.geo_type)