class WMS10GetFeatureInfoHandler(Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) renderer = UniqueExtensionPoint(WMSFeatureInfoRendererInterface) service = ("WMS", None) versions = ("1.0", "1.0.0") request = "GetFeatureInfo" def handle(self, request): decoder = WMS10GetFeatureInfoDecoder(request.GET) bbox = decoder.bbox srs = decoder.srs layers = decoder.layers if not layers: raise InvalidParameterException("No layers specified", "layers") minx, miny, maxx, maxy = bbox subsets = Subsets(( Trim("x", minx, maxx), Trim("y", miny, maxy), ), crs=srs) root_group = lookup_layers(layers, subsets) result, _ = self.renderer.render(root_group, request.GET.items(), request) return to_http_response(result)
class NativeFormat(Component): implements(MetadataReaderInterface) implements(MetadataWriterInterface) formats = ("native", ) def test(self, obj): xml = parse(obj) return xml is not None and xml.getroot().tag == "Metadata" def get_format_name(self, obj): return "native" def read(self, obj): tree = parse(obj) if tree is not None: decoder = NativeFormatDecoder(tree) return { "identifier": decoder.identifier, "begin_time": decoder.begin_time, "end_time": decoder.end_time, "footprint": MultiPolygon(*decoder.polygons), "format": "native" } raise Exception("Could not parse from obj '%s'." % repr(obj)) def write(self, values, file_obj, format=None, encoding=None, pretty=False): def flip(point): return point[1], point[0] # ignore format tree = E.Metadata( E.EOID(values["identifier"]), E.BeginTime(isoformat(values["begin_time"])), E.EndTime(isoformat(values["end_time"])), E.Footprint(*map( lambda polygon: E.Polygon( E.Exterior(" ".join([ "%f %f" % flip(point) for point in polygon.exterior_ring ])), *[ E.Interior(" ".join( ["%f %f" % flip(point) for point in interior])) for interior in polygon[1:] ]), values["footprint"]))) file_obj.write( etree.tostring(tree, pretty_print=pretty, encoding=encoding))
class WMS13GetMapHandler(Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) renderer = UniqueExtensionPoint(WMSMapRendererInterface) service = ("WMS", None) versions = ("1.3.0", "1.3") request = "GetMap" 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)
class WCS20GetCapabilitiesHandler(WCSGetCapabilitiesHandlerBase, Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) implements(PostServiceHandlerInterface) implements(VersionNegotiationInterface) versions = ("2.0.0", "2.0.1") def get_decoder(self, request): if request.method == "GET": return WCS20GetCapabilitiesKVPDecoder(request.GET) elif request.method == "POST": return WCS20GetCapabilitiesXMLDecoder(request.body) def lookup_coverages(self, decoder): sections = decoder.sections inc_coverages = ( "all" in sections or "contents" in sections or "coveragesummary" in sections ) inc_dataset_series = ( "all" in sections or "contents" in sections or "datasetseriessummary" in sections ) if inc_coverages: coverages = models.Coverage.objects \ .order_by("identifier") \ .filter(visible=True) else: coverages = () if inc_dataset_series: dataset_series = models.DatasetSeries.objects \ .order_by("identifier") \ .exclude( footprint__isnull=True, begin_time__isnull=True, end_time__isnull=True ) else: dataset_series = () return coverages, dataset_series def get_params(self, models, decoder): coverages, dataset_series = models return WCS20CapabilitiesRenderParams( coverages, dataset_series, decoder.sections, decoder.acceptlanguages, decoder.acceptformats, decoder.updatesequence )
class WCS20GetCoverageHandler(WCSGetCoverageHandlerBase, Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) implements(PostServiceHandlerInterface) encoding_extensions = ExtensionPoint(EncodingExtensionInterface) versions = ("2.0.0", "2.0.1") def get_decoder(self, request): if request.method == "GET": return WCS20GetCoverageKVPDecoder(request.GET) elif request.method == "POST": return WCS20GetCoverageXMLDecoder(request.body) def get_params(self, coverage, decoder, request): subsets = Subsets(decoder.subsets, crs=decoder.subsettingcrs) encoding_params = None for encoding_extension in self.encoding_extensions: if encoding_extension.supports(decoder.format, {}): encoding_params = encoding_extension.get_encoding_params( request ) scalefactor = decoder.scalefactor scales = list( chain(decoder.scaleaxes, decoder.scalesize, decoder.scaleextent) ) # check scales validity: ScaleFactor and any other scale if scalefactor and scales: raise InvalidRequestException( "ScaleFactor and any other scale operation are mutually " "exclusive.", locator="scalefactor" ) # check scales validity: Axis uniqueness axes = set() for scale in scales: if scale.axis in axes: raise InvalidRequestException( "Axis '%s' is scaled multiple times." % scale.axis, locator=scale.axis ) axes.add(scale.axis) return WCS20CoverageRenderParams( coverage, subsets, decoder.rangesubset, decoder.format, decoder.outputcrs, decoder.mediatype, decoder.interpolation, scalefactor, scales, encoding_params or {}, request )
class WMS13GetCapabilitiesHandler(Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) service = "WMS" request = "GetCapabilities" versions = ("1.3.0", "1.3") renderer = UniqueExtensionPoint(WMSCapabilitiesRendererInterface) def handle(self, request): result, _ = self.renderer.render() return to_http_response(result)
class WMS13GetFeatureInfoHandler(Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) renderer = UniqueExtensionPoint(WMSFeatureInfoRendererInterface) service = "WMS" versions = ("1.3.0", "1.3") request = "GetFeatureInfo" 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)
class TestProcess01(Component): """ Test identity process (the output is a copy of the input) demonstrating various features of the bounding box data inputs and outputs. """ implements(ProcessInterface) identifier = "TC01:identity:bbox" title = "Test Case 01: Bounding box data identity." metadata = {"test-metadata": "http://www.metadata.com/test-metadata"} profiles = ["test_profile"] inputs = [ ("input00", BoundingBoxData( "TC01:input00", crss=CRSS, default=BoundingBox([[-90, -180], [+90, +180]]), )), ] outputs = [ ("output00", BoundingBoxData("TC01:output00", crss=(4326, 0))), ] @staticmethod def execute(input00, **kwargs): """ WPS Process execute handler. """ return input00
class MapServerCapabilitiesRenderer(Component): """ Base class for various WMS render components using MapServer. """ implements(WMSCapabilitiesRendererInterface) def render(self): mapfile_path = get_eoxserver_config().get("wmm", "mapfile") map_ = ms.mapObj(mapfile_path) #TODO: path to map map_.setMetaData("ows_enable_request", "*") map_.setProjection("EPSG:4326") map_.imagecolor.setRGB(0, 0, 0) # set supported CRSs decoder = CRSsConfigReader(get_eoxserver_config()) crss_string = " ".join( map(lambda crs: "EPSG:%d" % crs, decoder.supported_crss_wms)) map_.setMetaData("ows_srs", crss_string) map_.setMetaData("wms_srs", crss_string) ms_request = ms.create_request(( ("service", "WMS"), ("version", "1.3.0"), ("request", "GetCapabilities"), )) raw_result = map_.dispatch(ms_request) result = result_set_from_raw_data(raw_result) return result, get_content_type(result)
class BaseResultFormat(Component): """ Base class for result formats """ implements(ResultFormatInterface) abstract = True
class NativeConfigFormatReader(Component): implements(MetadataReaderInterface) def open_reader(self, obj): if isinstance(obj, basestring): try: parser = RawConfigParser() if os.path.exists(obj): parser.read((obj, )) else: parser.readfp(StringIO(obj)) return NativeConfigReader(parser) except: pass return None def test(self, obj): try: reader = self.open_reader(obj) reader.range_type_name return True except: return False def get_format_name(self, obj): return "native_config" def read(self, obj): reader = self.open_reader(obj) if reader: return {"range_type_name": reader.range_type_name}
class GDALDatasetEnvisatMetadataFormatReader(Component): """ Metadata format reader for specific ENVISAT products. """ implements(GDALDatasetMetadataReaderInterface) def test_ds(self, ds): """ Check whether or not the dataset seems to be an ENVISAT image and has the correct metadata tags. """ md_dict = ds.GetMetadata_Dict() for key in ("MPH_PRODUCT", "MPH_SENSING_START", "MPH_SENSING_STOP"): if key not in md_dict: return False if ds.GetGCPCount() == 0: return False return True def read_ds(self, ds): """ Return the ENVISAT specific metadata items. """ return { "identifier": splitext(ds.GetMetadataItem("MPH_PRODUCT"))[0], "begin_time": parse_datetime(ds.GetMetadataItem("MPH_SENSING_START")), "end_time": parse_datetime(ds.GetMetadataItem("MPH_SENSING_STOP")) }
class TestProcess04(Component): """ Test processes testing time-zone aware date-time input data-type with automatic time-zone conversion. """ implements(ProcessInterface) identifier = "TC04:identity:literal:datetime" title = "Test Case 04: Literal input date-time time-zone test." profiles = ["test_profile"] TZ_DEFAULT = DateTime.TZOffset(+90) TZ_TARGET = DateTime.TZOffset(-120) #TIME_ZONE_UTC = DateTime.UTC inputs = [ ('datetime', LiteralData( "TC04:datetime", DateTimeTZAware(TZ_DEFAULT, TZ_TARGET), title="Date-time input.", )), ] outputs = [ ('datetime', LiteralData( "TC04:datetime", DateTime, title="Date-time output.", )), ] def execute(self, **inputs): return inputs['datetime']
class WCS11ExceptionHandler(Component): implements(ExceptionHandlerInterface) service = "WCS" versions = ("1.1.0", "1.1.1", "1.1.2") request = None def handle_exception(self, request, exception): message = str(exception) code = getattr(exception, "code", None) locator = getattr(exception, "locator", None) status = 400 if code is None: if isinstance(exception, MissingParameterException): code = "MissingParameterValue" elif isinstance(exception, DecodingException): code = "InvalidParameterValue" else: code = "InvalidRequest" encoder = OWS11ExceptionXMLEncoder() xml = encoder.serialize( encoder.encode_exception(message, "1.1.2", code, locator)) return (xml, encoder.content_type, status)
class WCS20ExceptionHandler(Component): implements(ExceptionHandlerInterface) service = "WCS" versions = ("2.0.0", "2.0.1") request = None def handle_exception(self, request, exception): message = str(exception) code = getattr(exception, "code", None) locator = getattr(exception, "locator", None) status = 400 if code is None: if isinstance(exception, MissingParameterException): code = "MissingParameterValue" elif isinstance(exception, DecodingException): code = "InvalidParameterValue" else: code = "InvalidRequest" if code in CODES_404: status = 404 elif code in ("OperationNotSupported", "OptionNotSupported"): status = 501 encoder = OWS20ExceptionXMLEncoder() xml = encoder.serialize( encoder.encode_exception(message, "2.0.1", code, locator)) return (xml, encoder.content_type, status)
class execute_pep_process(Component): """ API for pep processing """ implements(ProcessInterface) identifier = "execute_pep_interpolation" title = "Execute interpolation process of the PEP Library" metadata = {"test-metadata": "http://www.metadata.com/test-metadata"} profiles = ["test_profile"] inputs = [ ("collection", LiteralData( 'collection', str, optional=False, abstract="CoverageID to search in wcs server", )), ] outputs = [ ("output", LiteralData('output', str, abstract="pep Processing result")), ] def execute(self, collection, **kwarg): outputs = {} cmd_args = ['python', pep_path, '-c', collection] Popen(cmd_args) outputs['output'] = "Interpolation process started" return outputs
class WCS10ExceptionHandler(Component): implements(ExceptionHandlerInterface) service = "WCS" versions = ("1.0.0", ) request = None def handle_exception(self, request, exception): message = str(exception) code = getattr(exception, "code", None) locator = getattr(exception, "locator", None) status = 400 # TODO if code is None: if isinstance(exception, MissingParameterException): code = "MissingParameterValue" elif isinstance(exception, DecodingException): code = "InvalidParameterValue" else: code = "InvalidRequest" if code in ("NoSuchCoverage", "InvalidAxisLabel", "InvalidSubsetting"): status = 404 elif code in ("OperationNotSupported", "OptionNotSupported"): status = 501 return message, 400 #content, content_type, status
class Test07RequestParameterTest(Component): """ RequestParameters WPS test. """ implements(ProcessInterface) identifier = "TC07:request-parameter" title = "Test Case 07: Request parameter." description = ( "This test process demonstrates use of the RequestParameters " "input. The request parameter is a special input which passes " "meta-data extracted from the Django HTTPRequest object to the " "executed process.") inputs = [ ("test_header", RequestParameter(get_header('X-Test-Header'))), ("input", LiteralData( 'TC07:input01', str, optional=True, abstract="Optional simple string input.", )), ] outputs = [ ("output", LiteralData( 'TC07:output01', str, abstract="Simple string input.", )), ] @staticmethod def execute(test_header, **kwarg): return test_header or ""
class WPS10ExceptionHandler(Component): """ WPS 1.0 exception handler. """ implements(ExceptionHandlerInterface) service = "WPS" versions = ("1.0.0", "1.0") request = None def handle_exception(self, request, exception): """ Handle exception. """ # pylint: disable=unused-argument, no-self-use code = getattr(exception, "code", None) locator = getattr(exception, "locator", None) http_status_code = getattr(exception, "http_status_code", 400) if not code: code = "NoApplicableCode" locator = type(exception).__name__ encoder = OWS11ExceptionXMLEncoder() return (encoder.serialize( encoder.encode_exception(str(exception), "1.1.0", code, locator)), encoder.content_type, http_status_code)
class WMS13ExceptionHandler(Component): implements(ExceptionHandlerInterface) service = "WMS" versions = ("1.3.0", "1.3") request = None def get_encoder(self, request): decoder = WMS13Decoder(request.GET) exceptions = decoder.exceptions if exceptions in ("xml", "application/vnd.ogc.se_xml") or not HAS_PIL: return WMS13ExceptionXMLEncoder() elif exceptions in ("inimage", "blank"): return WMS13ExceptionImageEncoder( decoder.width, decoder.height, decoder.format, decoder.bgcolor, exceptions=="blank" ) print decoder.exceptions def handle_exception(self, request, exception): encoder = self.get_encoder(request) locator = getattr(exception, "locator", None) code = getattr(exception, "code", None) or type(exception).__name__ return ( encoder.serialize( encoder.encode_exception( str(exception), code, locator ), ), encoder.content_type, 400 )
class NativeWCS20CapabilitiesRenderer(Component): implements(WCSCapabilitiesRendererInterface) versions = (Version(2, 0), ) def supports(self, params): if params.version not in self.versions: return False if params.accept_formats and "text/xml" not in params.accept_formats: return False # TODO: accept_languages? return True def render(self, params): encoder = WCS20CapabilitiesXMLEncoder() return [ ResultBuffer( encoder.serialize(encoder.encode_capabilities( params.sections or ("all"), None, params.coverages, params.dataset_series, params.http_request), pretty_print=settings.DEBUG), encoder.content_type) ]
class SiteFormatReader(Component): implements(MetadataReaderInterface) def test(self, obj): tree = parse(obj) return (tree is not None and tree.find("siteName") is not None and tree.find("siteLongitude") is not None and tree.find("siteLatitude") is not None and tree.find("siteElevation") is not None) def read(self, obj): tree = parse(obj) if self.test(tree): decoder = SiteFormatDecoder(tree) location = Point(decoder.longitude, decoder.latitude) return { "identifier": decoder.identifier, "location": location, "footprint": MultiPolygon(location.buffer(0.01)), "elevation": decoder.elevation, "coverage_type": "", "size": (decoder.size, 1), "projection": 4326, "begin_time": min(decoder.start_times), "end_time": max(decoder.end_times), "extent": (0, 0, 1, 1), "coverage_type": "dav_prc.models.SiteDataset" } raise Exception("Could not parse from obj '%r'." % obj)
class WMS13GetMapHandler(Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) renderer = UniqueExtensionPoint(WMSMapRendererInterface) service = ("WMS", None) versions = ("1.3.0", "1.3") request = "GetMap" 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)
class WPS10GetCapabilitiesHandler(Component): """ WPS 1.0 GetCapabilities service handler. """ implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) implements(PostServiceHandlerInterface) implements(VersionNegotiationInterface) service = "WPS" versions = ("1.0.0", ) request = "GetCapabilities" processes = ExtensionPoint(ProcessInterface) def handle(self, request): """ Handle HTTP request. """ encoder = WPS10CapabilitiesXMLEncoder() return encoder.serialize(encoder.encode_capabilities(self.processes))
class WCS20DescribeCoverageHandler(WCSDescribeCoverageHandlerBase, Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) implements(PostServiceHandlerInterface) versions = ("2.0.0", "2.0.1") index = 5 def get_decoder(self, request): if request.method == "GET": return WCS20DescribeCoverageKVPDecoder(request.GET) elif request.method == "POST": return WCS20DescribeCoverageXMLDecoder(request.body) def get_params(self, coverages, decoder): return WCS20CoverageDescriptionRenderParams(coverages)
class LocalStorage(Component): implements(FileStorageInterface) name = "local" def retrieve(self, url, location, path): return location
class WCS10DescribeCoverageHandler(WCSDescribeCoverageHandlerBase, Component): implements(ServiceHandlerInterface) implements(GetServiceHandlerInterface) #implements(PostServiceHandlerInterface) versions = ("1.0.0", ) def get_decoder(self, request): if request.method == "GET": return WCS10DescribeCoverageKVPDecoder(request.GET) # TODO: implement POST elif request.method == "POST": #return WCS10GetCoverageXMLDecoder(request.body) pass def get_params(self, coverages, decoder): return WCS10CoverageDescriptionRenderParams(coverages)
class TimeExtension(Component): """ Implementation of the OpenSearch `'Time' extension <http://www.opensearch.org/Specifications/OpenSearch/Extensions/Time/1.0/Draft_1>`_. """ implements(SearchExtensionInterface) namespace = NameSpace("http://a9.com/-/opensearch/extensions/time/1.0/", "time") def filter(self, qs, parameters): decoder = TimeExtensionDecoder(parameters) start = decoder.start end = decoder.end relation = decoder.relation if start and end: if relation == "intersects": qs = qs.filter(Q(begin_time__lte=end) & Q(end_time__gte=start)) elif relation == "contains": qs = qs.filter(Q(begin_time__lte=start) & Q(end_time__gte=end)) elif relation == "during": qs = qs.filter(Q(begin_time__gte=start) & Q(end_time__lte=end)) elif relation == "disjoint": qs = qs.filter(Q(begin_time__gt=end) | Q(end_time__lt=start)) elif relation == "equals": qs = qs.filter(Q(begin_time=start) & Q(end_time=end)) elif start: if relation == "intersects": qs = qs.filter(end_time__gte=start) elif relation == "contains": # not possible for a coverage to contain an open interval pass elif relation == "during": qs = qs.filter(begin_time__gte=start) elif relation == "disjoint": qs = qs.filter(end_time__lt=start) elif relation == "equals": qs = qs.filter(begin_time=start) elif end: if relation == "intersects": qs = qs.filter(begin_time__lte=end) elif relation == "contains": # see above pass elif relation == "during": qs = qs.filter(end_time__lte=end) elif relation == "disjoint": qs = qs.filter(begin_time__gt=end) elif relation == "equals": qs = qs.filter(end_time=end) return qs def get_schema(self): return (dict(name="start", type="start"), dict(name="end", type="end"), dict(name="timerel", type="relation", options=["intersects", "contains", "disjoint", "equals"]))
class DimapGeneralFormatReader(Component): implements(MetadataReaderInterface) def test(self, obj): tree = parse(obj) return tree is not None and tree.getroot().tag == "Dimap_Document" def get_format_name(self, obj): return "dimap" def read(self, obj): tree = parse(obj) if self.test(tree): version = tree.xpath( "Metadadata_Id/METADATA_FORMAT/" "|Metadata_Identification/METADATA_FORMAT")[0].get( "version", "1.1") if version.startswith("1.1"): decoder = DimapGeneralFormat11Decoder(tree) elif version.startswith("2.0"): decoder = DimapGeneralFormat20Decoder(tree) else: raise Exception("DIMAP version '%s' is not supported." % version) values = {"identifier": decoder.identifier, "format": "dimap"} # in Dimap, pretty much everything is optional def cond_set(dct, key, value): if value is not None: dct[key] = value # decode begin_time = decoder.begin_time end_time = decoder.end_time footprint = decoder.footprint projection = decoder.projection size = decoder.size gt = decoder.geotransform # calculate extent extent = None if size and gt: extent = (gt[0], gt[3], gt[0] + gt[1] * size[0], gt[3] + gt[5] * size[1]) # set values cond_set(values, "begin_time", begin_time) cond_set(values, "end_time", begin_time) cond_set(values, "footprint", begin_time) cond_set(values, "size", begin_time) cond_set(values, "extent", begin_time) cond_set(values, "projection", begin_time) return values raise Exception("Could not parse from obj '%s'." % repr(obj))
class HTTPStorage(Component): implements(FileStorageInterface) name = "HTTP" def validate(self, url): pass def retrieve(self, url, location, path): urlretrieve(urljoin(url, location), path)