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)
def encode_capabilities(self, processes): config = get_eoxserver_config() # TODO conf = CapabilitiesConfigReader(get_eoxserver_config()) return WPS("Capabilities", OWS("ServiceIdentification", OWS("Title", conf.title), OWS("Abstract", conf.abstract), OWS("Keywords", *[ OWS("Keyword", keyword) for keyword in conf.keywords ]), OWS("ServiceType", "WPS"), OWS("ServiceTypeVersion", "1.0.0"), OWS("Fees", conf.fees), OWS("AccessConstraints", conf.access_constraints), ), OWS("ServiceProvider", OWS("ProviderName", conf.provider_name), OWS("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_operations_metadata(conf), self.encode_process_offerings(processes), WPS("Languages", WPS("Default", OWS("Language", "en-US") ), WPS("Supported", OWS("Language", "en-US") ) ), # TODO: WPS("WSDL") ? **{ "service": "WPS", ns_xml("lang"): "en-US", "updateSequence": conf.update_sequence } )
def create_map(self): """ Helper function to create a WCS enabled MapServer mapObj. """ map_ = ms.mapObj() map_.setMetaData("ows_enable_request", "*") maxsize = WCSConfigReader(get_eoxserver_config()).maxsize if maxsize is not None: map_.maxsize = maxsize map_.setMetaData("ows_updateSequence", WCSConfigReader(get_eoxserver_config()).update_sequence) return map_
def create_map(self): """ Helper function to create a WCS enabled MapServer mapObj. """ map_ = ms.mapObj() map_.setMetaData("ows_enable_request", "*") maxsize = WCSConfigReader(get_eoxserver_config()).maxsize if maxsize is not None: map_.maxsize = maxsize map_.setMetaData( "ows_updateSequence", WCSConfigReader(get_eoxserver_config()).update_sequence) return map_
def authorize(self, request): """ This method handles authorization requests according to the requirements given in the :class:`PolicyDecisionPointInterface` declaration. Internally, it invokes the :meth:`_decide` method that implements the actual authorization decision logic. """ reader = AuthConfigReader(get_eoxserver_config()) # This code segment allows local clients bypassing the # Authorisation process. if reader.allowLocal: remoteAddress = request.META['REMOTE_ADDR'] # Check all possibilities, also IPv6 if remoteAddress in ('127.0.0.1', 'localhost', '::1'): return True authorized, message = self._decide(request) if authorized: return True else: raise AuthorisationException(message)
def getPDP(): reader = AuthConfigReader(get_eoxserver_config()) if not reader.pdp_type or reader.pdp_type == "none": logger.debug("Authorization deactivated.") return None else: return PDPComponent(env).get_pdp(reader.pdp_type)
def encode_capabilities(processes): """ Encode Capabilities XML document. """ conf = CapabilitiesConfigReader(get_eoxserver_config()) # Avoid duplicate process offerings ... process_set = set() process_offerings = [] for process in processes: process_identifier = (getattr(process, 'identifier', None) or type(process).__name__) if process_identifier not in process_set: process_offerings.append(encode_process_brief(process)) process_set.add(process_identifier) return WPS( "Capabilities", OWS( "ServiceIdentification", OWS("Title", conf.title), OWS("Abstract", conf.abstract), OWS("Keywords", *(OWS("Keyword", kw) for kw in conf.keywords)), OWS("ServiceType", "WPS"), OWS("ServiceTypeVersion", "1.0.0"), OWS("Fees", conf.fees), OWS("AccessConstraints", conf.access_constraints), ), OWS( "ServiceProvider", OWS("ProviderName", conf.provider_name), OWS("ProviderSite", **{ns_xlink("href"): 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))))), _encode_operations_metadata(conf), WPS("ProcessOfferings", *process_offerings), WPS("Languages", WPS("Default", OWS("Language", "en-US")), WPS("Supported", OWS("Language", "en-US"))), # TODO: WPS("WSDL") **{ "service": "WPS", "version": "1.0.0", ns_xml("lang"): "en-US", "updateSequence": conf.update_sequence, })
def encode_url(self, request, collection, result_format, method): """ Encode a single opensearch URL, either for a specific collection, or the whole service. """ if collection is not None: search_url = reverse("opensearch:collection:search", kwargs={ "collection_id": collection.identifier, "format_name": result_format.name }) else: search_url = reverse("opensearch:search", kwargs={"format_name": result_format.name}) conf = OpenSearchConfigReader(get_eoxserver_config()) search_url = request.build_absolute_uri(search_url) default_parameters = ( dict(name="q", type="searchTerms", profiles=[]), dict(name="count", type="count", min=0, max=conf.max_count), dict(name="startIndex", type="startIndex", min=0), ) parameters = list( chain( default_parameters, *[[ dict(parameter, **{"namespace": search_extension.namespace}) for parameter in search_extension.get_schema( collection, models. Collection if collection is None else models.Product) ] for search_extension in self.search_extensions])) query_template = "&".join( "%s={%s%s%s%s}" % (parameter["name"], parameter["namespace"].prefix if "namespace" in parameter else "", ":" if "namespace" in parameter else "", parameter["type"], "?" if parameter.get("optional", True) else "") for parameter in parameters) url = self.OS( "Url", *[ self.encode_parameter(parameter, parameter.get("namespace")) for parameter in parameters ], type=result_format.mimetype, template="%s?%s" % (search_url, query_template) if method == "GET" else search_url, rel="results" if collection is not None else "collection", **{ self.ns_param("method"): method, self.ns_param("enctype"): "application/x-www-form-urlencoded", "indexOffset": "0" }) return url
def setup_cache_session(config=None): """ Initialize the cache context for this session. If a cache context was already present, an exception is raised. """ if not config: config = CacheConfigReader(get_eoxserver_config()) set_cache_context( CacheContext(config.retention_time, config.directory, True))
def render(self, layer_groups, request_values, request, **options): config = CapabilitiesConfigReader(get_eoxserver_config()) http_service_url = get_http_service_url(request) map_ = ms.Map() map_.setMetaData({ "enable_request": "*", "onlineresource": http_service_url, }, namespace="ows") map_.setMetaData("wms_getfeatureinfo_formatlist", "text/html") map_.setProjection("EPSG:4326") session = self.setup_map(layer_groups, map_, options) # check if the required format is EO O&M frmt = pop_param(request_values, "info_format") use_eoom = False if frmt in ("application/xml", "text/xml"): request_values.append(("info_format", "application/vnd.ogc.gml")) use_eoom = True else: request_values.append(("info_format", frmt)) with session: request = ms.create_request(request_values) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) if not use_eoom: # just return the response return result, get_content_type(result) else: # do a postprocessing step and get all identifiers in order # to encode them with EO O&M decoder = GMLFeatureDecoder(result[0].data_file.read()) identifiers = decoder.identifiers coverages = models.Coverage.objects.filter( identifier__in=identifiers ) # sort the result with the returned order of coverages lookup_table = dict((c.identifier, c) for c in coverages) coverages = [ lookup_table[identifier] for identifier in identifiers ] # encode the coverages with the EO O&M encoder = WCS20EOXMLEncoder() return [ ResultBuffer( encoder.serialize( encoder.encode_coverage_descriptions(coverages) ), encoder.content_type ) ], encoder.content_type
def render(self, layer_groups, request_values, **options): config = CapabilitiesConfigReader(get_eoxserver_config()) map_ = ms.Map() map_.setMetaData({ "enable_request": "*", "onlineresource": config.http_service_url, }, namespace="ows") map_.setMetaData("wms_getfeatureinfo_formatlist", "text/html") map_.setProjection("EPSG:4326") session = self.setup_map(layer_groups, map_, options) # check if the required format is EO O&M frmt = pop_param(request_values, "info_format") use_eoom = False if frmt in ("application/xml", "text/xml"): request_values.append(("info_format", "application/vnd.ogc.gml")) use_eoom = True else: request_values.append(("info_format", frmt)) with session: request = ms.create_request(request_values) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) if not use_eoom: # just return the response return result, get_content_type(result) else: # do a postprocessing step and get all identifiers in order # to encode them with EO O&M decoder = GMLFeatureDecoder(result[0].data_file.read()) identifiers = decoder.identifiers coverages = models.Coverage.objects.filter( identifier__in=identifiers ) # sort the result with the returned order of coverages lookup_table = dict((c.identifier, c) for c in coverages) coverages = [ lookup_table[identifier] for identifier in identifiers ] # encode the coverages with the EO O&M encoder = WCS20EOXMLEncoder() return [ ResultBuffer( encoder.serialize( encoder.encode_coverage_descriptions(coverages) ), encoder.content_type ) ], encoder.content_type
def check_disabled(self): config = get_eoxserver_config() try: disabled_tests = config.get("testing", "disabled_tests").split(",") except: disabled_tests = () name = type(self).__name__ if name in disabled_tests: raise SkipTest("Test '%s' is disabled by the configuration." % name)
def setup_cache_session(config=None): """ Initialize the cache context for this session. If a cache context was already present, an exception is raised. """ if not config: config = CacheConfigReader(get_eoxserver_config()) set_cache_context( CacheContext(config.retention_time, config.directory, True) )
def check_disabled(self): config = get_eoxserver_config() try: disabled_tests = config.get("testing", "disabled_tests").split(",") except: disabled_tests = () name = type(self).__name__ if name in disabled_tests: raise SkipTest( "Test '%s' is disabled by the configuration." % name )
def getSupportedCRS_WCS(format_function=asShortCode): """ Get list of CRSes supported by WCS. The ``format_function`` is used to format individual list items.""" global __SUPPORTED_CRS_WCS if __SUPPORTED_CRS_WCS is None: reader = CRSsConfigReader(get_eoxserver_config()) __SUPPORTED_CRS_WCS = reader.supported_crss_wcs # return formated list of EPSG codes return map(format_function, __SUPPORTED_CRS_WCS)
def getSupportedCRS_WCS(format_function=asShortCode): """ Get list of CRSes supported by WCS. The ``format_function`` is used to format individual list items.""" global __SUPPORTED_CRS_WCS if __SUPPORTED_CRS_WCS is None: reader = CRSsConfigReader(get_eoxserver_config()) __SUPPORTED_CRS_WCS = reader.supported_crss_wcs # return formated list of EPSG codes return list(map(format_function, __SUPPORTED_CRS_WCS))
def time_interval(time_or_period, containment='overlaps', begin_time_field='begin_time', end_time_field='end_time'): """ """ config = get_eoxserver_config() reader = SubsetConfigReader(config) if reader.time_interval_interpretation == "closed": gt_op = "__gte" lt_op = "__lte" else: gt_op = "__gt" lt_op = "__lt" is_slice = len(time_or_period) == 1 if len(time_or_period) == 1: is_slice = True value = time_or_period[0] else: is_slice = False low, high = time_or_period if is_slice or (high == low and containment == "overlaps"): return Q( **{ begin_time_field + "__lte": time_or_period[0], end_time_field + "__gte": time_or_period[0] }) elif high == low: return Q(**{ begin_time_field + "__gte": value, end_time_field + "__lte": value }) else: q = Q() # check if the temporal bounds must be strictly contained if containment == "contains": if high is not None: q &= Q(**{end_time_field + lt_op: high}) if low is not None: q &= Q(**{begin_time_field + gt_op: low}) # or just overlapping else: if high is not None: q &= Q(**{begin_time_field + lt_op: high}) if low is not None: q &= Q(**{end_time_field + gt_op: low}) return q
def handle(self, request): decoder = self.get_decoder(request) qs = models.EOObject.objects.all() cql_text = decoder.cql if cql_text: mapping, mapping_choices = filters.get_field_mapping_for_model( qs.model) ast = parse(cql_text) filter_expressions = to_filter(ast, mapping, mapping_choices) qs = qs.filter(filter_expressions) else: # lookup Collections, Products and Coverages qs = models.EOObject.objects.filter( Q( # include "WMS-visible" Products product__isnull=False, service_visibility__service='wms', service_visibility__visibility=True) | Q( # include "WMS-visible" Coverages coverage__isnull=False, service_visibility__service='wms', service_visibility__visibility=True) | Q( # include all Collections, exclude "WMS-invisible" later collection__isnull=False)).exclude( collection__isnull=False, service_visibility__service='wms', service_visibility__visibility=False) qs = qs.select_subclasses() # map_renderer = get_map_renderer() raster_styles = map_renderer.get_raster_styles() geometry_styles = map_renderer.get_geometry_styles() layer_mapper = LayerMapper(map_renderer.get_supported_layer_types(), "__") layer_descriptions = [ layer_mapper.get_layer_description(eo_object, raster_styles, geometry_styles) for eo_object in qs ] encoder = self.get_encoder() conf = CapabilitiesConfigReader(get_eoxserver_config()) return encoder.serialize( encoder.encode_capabilities( conf, request.build_absolute_uri(reverse(views.ows)), crss.getSupportedCRS_WMS(format_function=crss.asShortCode), map_renderer.get_supported_formats(), [], layer_descriptions), pretty_print=settings.DEBUG), encoder.content_type
def isRequestConfigEnabled(self, config_key, default=False): config = get_eoxserver_config() try: value = config.get("testing", config_key) except: value = None if value is None: return default elif value.lower() in ("yes", "y", "true", "on"): return True elif value.lower() in ("no", "n", "false", "off"): return False else: return default
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)
def _encode_common_response(process, status_elem, inputs, raw_inputs, resp_doc): """Encode common execute response part shared by all specific responses.""" inputs = inputs or {} conf = CapabilitiesConfigReader(get_eoxserver_config()) url = conf.http_service_url if url[-1] == "?": url = url[:-1] elem = WPS( "ExecuteResponse", encode_process_brief(process), WPS("Status", status_elem, creationTime=isoformat(now())), { "service": "WPS", "version": "1.0.0", ns_xml("lang"): "en-US", "serviceInstance": ("%s?service=WPS&version=1.0.0&request=GetCapabilities" % url) }, ) if resp_doc.lineage: inputs_data = [] for id_, prm in process.inputs: if isinstance(prm, RequestParameter): continue prm = fix_parameter(id_, prm) data = inputs.get(id_) rawinp = raw_inputs.get(prm.identifier) if rawinp is not None: inputs_data.append(_encode_input(data, prm, rawinp)) elem.append(WPS("DataInputs", *inputs_data)) outputs_def = [] for id_, prm in process.outputs: prm = fix_parameter(id_, prm) outdef = resp_doc.get(prm.identifier) if outdef is not None: outputs_def.append(encode_output_def(outdef)) elem.append(WPS("OutputDefinitions", *outputs_def)) return elem
def layers2json(selection, json_opts=None): """ convert EOxClient layers' selection to JSON """ json_opts = (json_opts or {}) # get the service URL url = get_eoxserver_config().get("services.owscommon", "http_service_url") if url and url[-1] == "?": url = url[:-1] # generate the layers' list layer_list = [] for item in selection: id_ = item.eoobj.identifier layer = { "name": (item.name or id_), "description": (item.description or ""), "timeSlider": item.has_time, "timeSliderProtocol": "WPS", "visible": item.visible, "view": { "id": id_, "protocol": "WMS", "urls": [url], "style": (item.wms_style or "default"), #"cloudMask": item.has_cloud_mask, #"snowMask": item.has_snow_mask, "extraLayers": {}, }, "download": { "id": id_, "protocol": "EOWCS", "url": url, "rectified": item.rectified, }, "info": { "id": id_, "protocol": "WPS", "url": url, }, } if item.color: layer['color'] = item.color layer_list.append(layer) return json.dumps({"products": layer_list}, **json_opts)
def render(self, layer_groups, request_values, **options): map_ = ms.Map() map_.setMetaData("ows_enable_request", "*") map_.setProjection("EPSG:4326") map_.imagecolor.setRGB(0, 0, 0) # set supported CRSs crss = CRSsConfigReader(get_eoxserver_config()) crss_string = " ".join("EPSG:%d"%v for v in crss.supported_crss_wms) map_.setMetaData("ows_srs", crss_string) map_.setMetaData("wms_srs", crss_string) self.check_parameters(map_, request_values) with self.setup_map(layer_groups, map_, options) as session: request = ms.create_request(self._alter_request(request_values)) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) return result, get_content_type(result)
def encode(driver, dataset, mime_type, encoding_params): """ Encode (i.e., create) the output image and return the opened GDAL dataset object. """ # temporary filename path_temp = SystemConfigReader(get_eoxserver_config()).path_temp while True: path = join(path_temp, "eoxs_tmp_%s" % uuid4().hex) if not exists(path): break # parse the encoding options options = () if mime_type == "image/tiff": options = _get_gtiff_options(**encoding_params) args = [("%s=%s" % key, value) for key, value in options] return driver.CreateCopy(path, dataset, True, args)
def encode_capabilities(self, request, sections): conf = CapabilitiesConfigReader(get_eoxserver_config()) all_sections = "all" in sections caps = [] if all_sections or "serviceidentification" in sections: caps.append(self.encode_service_identification("DSEO", 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, "DSEO", ["1.0.0"])) return DSEO("Capabilities", *caps, version="1.0.0", updateSequence=conf.update_sequence)
def webclient(request, identifier): """ View for webclient interface. Uses `webclient.preview_service`, `webclient.outline_service`, `webclient.preview_url` """ try: eo_object = models.Collection.objects.get(identifier=identifier) except models.Collection.DoesNotExist: raise Http404("No such collection.") begin = eo_object.begin_time end = eo_object.end_time extent = eo_object.extent_wgs84 # zoom to Europe if we don't have a proper extent if extent == (0,0,1,1): extent = (-10,30,34,72) reader = WebclientConfigReader(get_eoxserver_config()) return render_to_response( 'webclient/webclient.html', { "eoid": identifier, "ows_url": reverse("eoxserver.services.views.ows"), #reader.http_service_url, "preview_service": reader.preview_service, "outline_service": reader.outline_service, "preview_url": reader.preview_url or reader.http_service_url, "outline_url": reader.outline_url or reader.http_service_url, #"begin": {"date": begin.strftime("%Y-%m-%d"), # "time": begin.strftime("%H:%M")}, #"end": {"date": end.strftime("%Y-%m-%d"), # "time": end.strftime("%H:%M")}, "begin": isoformat(begin), "end": isoformat(end), "extent": "%f,%f,%f,%f" % extent, "debug": settings.DEBUG }, context_instance=RequestContext(request) )
def __init__(self, client=None): cfgReader = AuthConfigReader(get_eoxserver_config()) url = cfgReader.authorisationServiceURL # For tests self.client = client or AuthorisationClient(url) self.attribMapping = {} self.serviceID = cfgReader.serviceID or "default" dictLocation = cfgReader.getAttributeMappingDictionary() if not dictLocation or dictLocation == "default": basePath = os.path.split(eoxserver.__file__)[0] dictLocation = os.path.join(basePath, 'conf', 'defaultAttributeDictionary') CHAR_COMMENT = '#' CHAR_ASSIGN = '=' try: logger.debug( "Loading attribute dictionary from the file %s" % dictLocation ) with open(dictLocation) as f: for line in f: if CHAR_COMMENT in line: line, comment = line.split(CHAR_COMMENT, 1) if CHAR_ASSIGN in line: key, value = line.split(CHAR_ASSIGN, 1) key = key.strip() value = value.strip() self.attribMapping[key] = value logger.debug( "Adding SAML attribute to dictionary: %s = %s" % (key, value) ) except IOError : logger.warn( "Cannot read dictionary for attributes mapping from the path: " "%s" % dictLocation )
def _encode_common_response(process, status_elem, inputs, raw_inputs, resp_doc): """Encode common execute response part shared by all specific responses.""" inputs = inputs or {} conf = CapabilitiesConfigReader(get_eoxserver_config()) url = conf.http_service_url if url[-1] == "?": url = url[:-1] elem = WPS("ExecuteResponse", encode_process_brief(process), WPS("Status", status_elem, creationTime=isoformat(now())), { "service": "WPS", "version": "1.0.0", ns_xml("lang"): "en-US", "serviceInstance": ( "%s?service=WPS&version=1.0.0&request=GetCapabilities" % url ) }, ) if resp_doc.lineage: inputs_data = [] for id_, prm in process.inputs: if isinstance(prm, RequestParameter): continue prm = fix_parameter(id_, prm) data = inputs.get(id_) rawinp = raw_inputs.get(prm.identifier) if rawinp is not None: inputs_data.append(_encode_input(data, prm, rawinp)) elem.append(WPS("DataInputs", *inputs_data)) outputs_def = [] for id_, prm in process.outputs: prm = fix_parameter(id_, prm) outdef = resp_doc.get(prm.identifier) if outdef is not None: outputs_def.append(encode_output_def(outdef)) elem.append(WPS("OutputDefinitions", *outputs_def)) return elem
def getFormatRegistry() : """ Get initialised instance of the FormatRegistry class. This is the preferable way to get the Format Registry. """ global __FORMAT_REGISTRY if __FORMAT_REGISTRY is None : logger.debug(" --- getFormatRegistry() --- ") logger.debug( repr(__FORMAT_REGISTRY) ) logger.debug( repr(_gerexValMime) ) logger.debug( repr(_gerexValDriv) ) # load configuration if not already loaded __FORMAT_REGISTRY = FormatRegistry( get_eoxserver_config() ) logger.debug( repr(__FORMAT_REGISTRY) ) return __FORMAT_REGISTRY
def __init__(self, client=None): cfgReader = AuthConfigReader(get_eoxserver_config()) url = cfgReader.authorisationServiceURL # For tests self.client = client or AuthorisationClient(url) self.attribMapping = {} self.serviceID = cfgReader.serviceID or "default" dictLocation = cfgReader.getAttributeMappingDictionary() if not dictLocation or dictLocation == "default": basePath = os.path.split(eoxserver.__file__)[0] dictLocation = os.path.join(basePath, 'conf', 'defaultAttributeDictionary') CHAR_COMMENT = '#' CHAR_ASSIGN = '=' try: logger.debug("Loading attribute dictionary from the file %s" % dictLocation) with open(dictLocation) as f: for line in f: if CHAR_COMMENT in line: line, comment = line.split(CHAR_COMMENT, 1) if CHAR_ASSIGN in line: key, value = line.split(CHAR_ASSIGN, 1) key = key.strip() value = value.strip() self.attribMapping[key] = value logger.debug( "Adding SAML attribute to dictionary: %s = %s" % (key, value)) except IOError: logger.warn( "Cannot read dictionary for attributes mapping from the path: " "%s" % dictLocation)
def _add_metadata(product, zipfile, pattern, semantic, frmt=None): def _get_file_info(zipfile, pattern): for info in zipfile.infolist(): if re.match(pattern, info.filename): return info reader = RegistrationConfigReader(get_eoxserver_config()) metadata_filename_template = reader.metadata_filename_template info = _get_file_info(zipfile, pattern) if info and metadata_filename_template: frmt = frmt or mimetypes.guess_type(info.filename)[0] semantic_code = { name: code for code, name in models.MetaDataItem.SEMANTIC_CHOICES }[semantic] out_filename = metadata_filename_template.format( product_id=product.identifier, filename=info.filename ) out_dirname = os.path.dirname(out_filename) # make directories try: os.makedirs(out_dirname) except OSError as exc: if exc.errno != 17: raise with open(out_filename, "w") as out_file: shutil.copyfileobj(zipfile.open(info), out_file) models.MetaDataItem.objects.create( eo_object=product, format=frmt, location=out_filename, semantic=semantic_code )
def render(self, layer_groups, request_values, **options): map_ = ms.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) self.check_parameters(map_, request_values) session = self.setup_map(layer_groups, map_, options) with session: request = ms.create_request(request_values) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) return result, get_content_type(result)
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, 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 lookup_layer(self, layer_name, suffix, style, filters_expressions, sort_by, time, ranges, bands, wavelengths, elevation, zoom): """ Lookup the layer from the registered objects. """ reader = LayerMapperConfigReader(get_eoxserver_config()) limit_products = (reader.limit_products if reader.limit_mode == 'hide' else None) min_render_zoom = reader.min_render_zoom full_name = '%s%s%s' % (layer_name, self.suffix_separator, suffix) try: eo_object = models.EOObject.objects.select_subclasses( models.Collection, models.Product, models.Coverage, models.Mosaic).get(identifier=layer_name) except models.EOObject.DoesNotExist: raise NoSuchLayer('Layer %r does not exist' % layer_name) if isinstance(eo_object, models.Coverage): if suffix in ('', 'bands'): return CoverageLayer(full_name, style, RenderCoverage.from_model(eo_object), bands, wavelengths, time, elevation, ranges) elif suffix == 'outlines': return OutlinesLayer(name=full_name, style=style, fill=None, footprints=[eo_object.footprint]) # TODO: masked coverages, when using the coverages product else: raise NoSuchLayer('Invalid layer suffix %r' % suffix) # TODO: deprecated elif isinstance(eo_object, models.Mosaic): if suffix == 'outlines': return OutlinesLayer( name=full_name, style=style, fill=None, footprints=[ coverage.footprint for coverage in self.iter_coverages( eo_object, filters_expressions, sort_by) ]) else: return MosaicLayer( full_name, style, RenderMosaic.from_model(eo_object), [ RenderCoverage.from_model(coverage) for coverage in self.iter_coverages( eo_object, filters_expressions, sort_by) ], bands, wavelengths, time, elevation, ranges) elif isinstance(eo_object, (models.Collection, models.Product)): if suffix == '' or suffix == 'outlined' or suffix == 'bands': browses = [] product_browses = self.iter_products_browses( eo_object, filters_expressions, sort_by, None, style, limit=limit_products) has_products = False for product, browse, _ in product_browses: # When bands/wavelengths are specifically requested, make a # generated browse if bands or wavelengths: browse = _generate_browse_from_bands( product, bands, wavelengths, ranges) if browse: browses.append(browse) has_products = True # When available use the default browse elif browse: browses.append(Browse.from_model(product, browse)) has_products = True # As fallback use the default browse type (with empty name) # to generate a browse from the specified bands else: browse_type = product.product_type.browse_types.filter( name='').first() if browse_type: browse = _generate_browse_from_browse_type( product, browse_type) if browse: browses.append(browse) has_products = True if not has_products: coverages = self.iter_coverages(eo_object, filters_expressions, sort_by) if suffix == '': return CoveragesLayer(full_name, style, [ RenderCoverage.from_model(coverage) for coverage in coverages ], bands, wavelengths, time, elevation, ranges) else: return OutlinedCoveragesLayer(full_name, style, [ RenderCoverage.from_model(coverage) for coverage in coverages ], bands, wavelengths, time, elevation, ranges) # detect whether we are below the zoom limit if min_render_zoom is None or zoom >= min_render_zoom: # either return the simple browse layer or the outlined one if suffix == '': return BrowseLayer(name=full_name, style=style, browses=browses, ranges=ranges) else: return OutlinedBrowseLayer(name=full_name, style=style, browses=browses, ranges=ranges) # render outlines when we are below the zoom limit else: return OutlinesLayer(name=full_name, style=reader.color, fill=reader.fill_opacity, footprints=[ product.footprint for product in self.iter_products( eo_object, filters_expressions, sort_by, limit=limit_products) ]) elif suffix == 'outlines': return OutlinesLayer( name=full_name, style=style, fill=None, footprints=[ product.footprint for product in self.iter_products(eo_object, filters_expressions, sort_by, limit=limit_products) ]) elif suffix.startswith('outlines_masked_'): post_suffix = suffix[len('outlines_masked_'):] product_browses_mask = self.iter_products_browses_masks( eo_object, filters_expressions, sort_by, post_suffix, limit=limit_products) footprints = [] masks = [] for product, browse, mask, mask_type in product_browses_mask: footprints.append(product.footprint) masks.append(Mask.from_model(mask, mask_type)) return OutlinesLayer( name=full_name, style=style, fill=None, footprints=footprints, masks=masks, ) elif suffix.startswith('masked_'): post_suffix = suffix[len('masked_'):] mask_type = self.get_mask_type(eo_object, post_suffix) if not mask_type: raise NoSuchLayer('No such mask type %r' % post_suffix) masked_browses = [] product_browses_mask = self.iter_products_browses_masks( eo_object, filters_expressions, sort_by, post_suffix, limit=limit_products) for product, browse, mask, mask_type in product_browses_mask: # When bands/wavelengths are specifically requested, make a # generated browse if bands or wavelengths: masked_browses.append( MaskedBrowse(browse=_generate_browse_from_bands( product, bands, wavelengths, ranges), mask=Mask.from_model(mask, mask_type))) # When available use the default browse elif browse: masked_browses.append( MaskedBrowse.from_models(product, browse, mask, mask_type)) # As fallback use the default browse type (with empty name) # to generate a browse from the specified bands else: browse_type = product.product_type.browse_types.filter( name='').first() if browse_type: masked_browses.append( MaskedBrowse( browse=_generate_browse_from_browse_type( product, browse_type), mask=Mask.from_model(mask, mask_type))) return MaskedBrowseLayer(name=full_name, style=style, masked_browses=masked_browses) else: # either browse type or mask type browse_type = self.get_browse_type(eo_object, suffix) if browse_type: browses = [] product_browses = self.iter_products_browses( eo_object, filters_expressions, sort_by, suffix, style, limit=limit_products) for product, browse, browse_type in product_browses: # check if a browse is already available for that # browse type. if browse: browses.append(Browse.from_model(product, browse)) # if no browse is available for that browse type, # generate a new browse with the instructions of that # browse type else: browse = _generate_browse_from_browse_type( product, browse_type) if browse: browses.append(browse) return BrowseLayer(name=full_name, style=style, ranges=ranges, browses=browses) mask_type = self.get_mask_type(eo_object, suffix) if mask_type: return MaskLayer( name=full_name, style=style, masks=[ Mask.from_model(mask_model, mask_type) for _, mask_model in self.iter_products_masks( eo_object, filters_expressions, sort_by, suffix, limit=limit_products) ]) raise NoSuchLayer('Invalid layer suffix %r' % suffix)
def render(self, collections, coverages, request_values, request): conf = CapabilitiesConfigReader(get_eoxserver_config()) suffixes = self.suffixes http_service_url = get_http_service_url(request) map_ = Map() map_.setMetaData( { "enable_request": "*", "onlineresource": http_service_url, "service_onlineresource": conf.onlineresource, "updateSequence": conf.update_sequence, "name": conf.name, "title": conf.title, "abstract": conf.abstract, "accessconstraints": conf.access_constraints, "addresstype": "postal", "address": conf.delivery_point, "stateorprovince": conf.administrative_area, "city": conf.city, "postcode": conf.postal_code, "country": conf.country, "contactelectronicmailaddress": conf.electronic_mail_address, "contactfacsimiletelephone": conf.phone_facsimile, "contactvoicetelephone": conf.phone_voice, "contactperson": conf.individual_name, "contactorganization": conf.provider_name, "contactposition": conf.position_name, "fees": conf.fees, "keywordlist": ",".join(conf.keywords), "srs": " ".join( crss.getSupportedCRS_WCS( format_function=crss.asShortCode)), }, namespace="ows") map_.setProjection("EPSG:4326") map_.setMetaData( { "getmap_formatlist": ",".join([f.mimeType for f in self.get_wms_formats()]), "getfeatureinfo_formatlist": "text/html,application/vnd.ogc.gml,text/plain", }, namespace="wms") map_extent = None for collection in collections: group_name = None # calculate extent and timextent for every collection extent = collection.extent_wgs84 # save overall map extent map_extent = self.join_extents(map_extent, extent) eo_objects = collection.eo_objects.filter(begin_time__isnull=False, end_time__isnull=False) timeextent = ",".join( map( lambda o: ("/".join(map(isoformat, o.time_extent)) + "/PT1S"), eo_objects)) if len(suffixes) > 1: # create group layer, if there is more than one suffix for this # collection group_name = collection.identifier + "_group" group_layer = Layer(group_name) group_layer.setMetaData( { "title": group_name, "abstract": group_name, "extent": " ".join(map(str, extent)), }, namespace="wms") minx, miny, maxx, maxy = extent group_layer.setExtent(minx, miny, maxx, maxy) # add default style default_class = Class("default") default_style = Style("default") default_class.insertStyle(default_style) group_layer.insertClass(default_class) map_.insertLayer(group_layer) for suffix in suffixes: layer_name = collection.identifier + (suffix or "") layer = Layer(layer_name) if group_name: layer.setMetaData({"layer_group": "/" + group_name}, namespace="wms") layer.setMetaData( { "title": layer_name, "abstract": layer_name, "extent": " ".join(map(str, extent)), "timeextent": timeextent, }, namespace="wms") map_.insertLayer(layer) for coverage in coverages: extent = coverage.extent_wgs84 minx, miny, maxx, maxy = extent # save overall map extent map_extent = self.join_extents(map_extent, extent) layer_name = coverage.identifier layer = Layer(layer_name) layer.setMetaData( { "title": layer_name, "abstract": layer_name, "extent": " ".join(map(str, extent)), }, namespace="wms") minx, miny, maxx, maxy = extent layer.setExtent(minx, miny, maxx, maxy) map_.insertLayer(layer) # set the map_extent to a reasonable default value # in case there is no coverage or collection if map_extent is None: map_extent = (0.0, 0.0, 1.0, 1.0) map_minx, map_miny, map_maxx, map_maxy = map_extent map_.setExtent(map_minx, map_miny, map_maxx, map_maxy) request = create_request(request_values) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) return result, get_content_type(result)
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 constraints(self): reader = WCSEOConfigReader(get_eoxserver_config()) return { "CountDefault": reader.paging_count_default }
def enabled_masks(self): decoder = EnabledMasksConfigReader(get_eoxserver_config()) return decoder.mask_names
def is_format_supported(mime_type): reader = WCSConfigReader(get_eoxserver_config()) return mime_type in reader.supported_formats
def render(self, params): conf = CapabilitiesConfigReader(get_eoxserver_config()) http_service_url = get_http_service_url(params.http_request) map_ = Map() map_.setMetaData({ "enable_request": "*", "onlineresource": http_service_url, "service_onlineresource": conf.onlineresource, "updateSequence": conf.update_sequence, "name": conf.name, "title": conf.title, "label": conf.title, "abstract": conf.abstract, "accessconstraints": conf.access_constraints, "addresstype": "", "address": conf.delivery_point, "stateorprovince": conf.administrative_area, "city": conf.city, "postcode": conf.postal_code, "country": conf.country, "contactelectronicmailaddress": conf.electronic_mail_address, "contactfacsimiletelephone": conf.phone_facsimile, "contactvoicetelephone": conf.phone_voice, "contactperson": conf.individual_name, "contactorganization": conf.provider_name, "contactposition": conf.position_name, "role": conf.role, "hoursofservice": conf.hours_of_service, "contactinstructions": conf.contact_instructions, "fees": conf.fees, "keywordlist": ",".join(conf.keywords), "formats": " ".join([f.wcs10name for f in self.get_wcs_formats()]), "srs": " ".join(crss.getSupportedCRS_WCS(format_function=crss.asShortCode)), }, namespace="ows") map_.setProjection("EPSG:4326") for outputformat in self.get_all_outputformats(False): map_.appendOutputFormat(outputformat) for coverage in params.coverages: layer = Layer(coverage.identifier) layer.setProjection(coverage.spatial_reference.proj) extent = coverage.extent size = coverage.size resolution = ((extent[2] - extent[0]) / float(size[0]), (extent[1] - extent[3]) / float(size[1])) layer.setExtent(*extent) layer.setMetaData({ "title": coverage.identifier, "label": coverage.identifier, "extent": "%.10g %.10g %.10g %.10g" % extent, "resolution": "%.10g %.10g" % resolution, "size": "%d %d" % size, "formats": " ".join([f.wcs10name for f in self.get_wcs_formats()]), "srs": " ".join(crss.getSupportedCRS_WCS(format_function=crss.asShortCode)), }, namespace="wcs") map_.insertLayer(layer) request = create_request(params) request.setParameter("version", params.version) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) return result
def encode_capabilities(processes): conf = CapabilitiesConfigReader(get_eoxserver_config()) # Avoid duplicate process offerings ... process_set = set() process_offerings = [] for process in processes: if process.identifier not in process_set: process_offerings.append(encode_process_brief(process)) process_set.add(process.identifier) return WPS("Capabilities", OWS("ServiceIdentification", OWS("Title", conf.title), OWS("Abstract", conf.abstract), OWS("Keywords", *(OWS("Keyword", kw) for kw in conf.keywords)), OWS("ServiceType", "WPS"), OWS("ServiceTypeVersion", "1.0.0"), OWS("Fees", conf.fees), OWS("AccessConstraints", conf.access_constraints), ), OWS("ServiceProvider", OWS("ProviderName", conf.provider_name), OWS("ProviderSite", **{ns_xlink("href"): 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 ) ) ) ) ), _encode_operations_metadata(conf), WPS("ProcessOfferings", *process_offerings), WPS("Languages", WPS("Default", OWS("Language", "en-US") ), WPS("Supported", OWS("Language", "en-US") ) ), # TODO: WPS("WSDL") ? **{ "service": "WPS", "version": "1.0.0", ns_xml("lang"): "en-US", "updateSequence": conf.update_sequence, } )
def get_conf(self): from eoxserver.core.config import get_eoxserver_config return CapabilitiesConfigReader(get_eoxserver_config())
def render(self, params): conf = CapabilitiesConfigReader(get_eoxserver_config()) http_service_url = get_http_service_url(params.http_request) map_ = Map() map_.setMetaData( { "enable_request": "*", "onlineresource": http_service_url, "service_onlineresource": conf.onlineresource, "updateSequence": conf.update_sequence, "name": conf.name, "title": conf.title, "label": conf.title, "abstract": conf.abstract, "accessconstraints": conf.access_constraints, "addresstype": "", "address": conf.delivery_point, "stateorprovince": conf.administrative_area, "city": conf.city, "postcode": conf.postal_code, "country": conf.country, "contactelectronicmailaddress": conf.electronic_mail_address, "contactfacsimiletelephone": conf.phone_facsimile, "contactvoicetelephone": conf.phone_voice, "contactperson": conf.individual_name, "contactorganization": conf.provider_name, "contactposition": conf.position_name, "role": conf.role, "hoursofservice": conf.hours_of_service, "contactinstructions": conf.contact_instructions, "fees": conf.fees, "keywordlist": ",".join(conf.keywords), "formats": " ".join([f.wcs10name for f in self.get_wcs_formats()]), "srs": " ".join( crss.getSupportedCRS_WCS( format_function=crss.asShortCode)), }, namespace="ows") map_.setProjection("EPSG:4326") for outputformat in self.get_all_outputformats(False): map_.appendOutputFormat(outputformat) for coverage in params.coverages: layer = Layer(coverage.identifier) render_coverage = Coverage.from_model(coverage) layer.setProjection(render_coverage.grid.spatial_reference.proj) extent = render_coverage.extent size = render_coverage.size resolution = ((extent[2] - extent[0]) / float(size[0]), (extent[1] - extent[3]) / float(size[1])) layer.setExtent(*extent) layer.setMetaData( { "title": coverage.identifier, "label": coverage.identifier, "extent": "%.10g %.10g %.10g %.10g" % extent, "resolution": "%.10g %.10g" % resolution, "size": "%d %d" % size, "formats": " ".join([f.wcs10name for f in self.get_wcs_formats()]), "srs": " ".join( crss.getSupportedCRS_WCS( format_function=crss.asShortCode)), }, namespace="wcs") map_.insertLayer(layer) request = create_request(params) request.setParameter("version", params.version) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) xml_result = etree.fromstring(result[0].data) for elem in xml_result.xpath('//*[local-name() = "metadataLink"]'): elem.getparent().remove(elem) # Add CQL parameter to GetCapabilities operation for elem in xml_result.xpath( '//*[local-name() = "Operation"][@name = "GetCapabilities"]'): ows = elem.nsmap['ows'] param = etree.SubElement(elem, '{%s}Parameter' % ows) param.attrib['name'] = 'cql' etree.SubElement(param, '{%s}AnyValue' % ows) xml_result_data = etree.tostring(xml_result, pretty_print=True, encoding='UTF-8', xml_declaration=True) result[0] = ResultBuffer(xml_result_data, result[0].content_type) return result
def render(self, layers, bbox, crs, size, frmt, time, elevation, styles): if not time: raise RenderException("Missing mandatory 'time' parameter.") try: time = time.value except AttributeError: raise RenderException( "Parameter 'time' must be a slice and not a range." ) llbbox = self.get_llbbox(bbox, crs) 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 = crss.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) datasources = [] datasets = [] for layer_name in layers: layer = map_.getLayerByName(layer_name) if not layer: continue product = layer.metadata.get("wmm_product") filename = self.generate_filename("tif") ds = self.create_dataset( llbbox, time, elevation, size, product, filename ) datasets.append(ds) if layer.type == ms.MS_LAYER_LINE: flavor = layer.metadata.get("wmm_flavor") contour_steps = self.get_contour_intervals( flavor, llbbox, size ) filename = self.generate_filename("shp") self.generate_contours( ds, contour_steps, filename ) layer.connectiontype = ms.MS_OGR layer.connection = filename layer.data, _ = splitext(basename(filename)) datasources.append(filename) ms_request = ms.create_request(( ("service", "WMS"), ("version", "1.3.0"), ("request", "GetMap"), ("layers", ",".join(layers)), ("bbox", "%f,%f,%f,%f" % (bbox[1], bbox[0], bbox[3], bbox[2])), ("crs", crs), ("width", str(size[0])), ("height", str(size[1])), ("styles", ",".join(styles)), ("format", frmt) )) raw_result = ms.dispatch(map_, ms_request) result = result_set_from_raw_data(raw_result) shp_drv = ogr.GetDriverByName("ESRI Shapefile") # cleanup datasources and datasets for filename in datasources: shp_drv.DeleteDataSource(filename) for ds in datasets: driver = ds.GetDriver() for filename in ds.GetFileList(): os.remove(filename) return result, get_content_type(result)
def render(self, params): # get the requested coverage, data items and range type. coverage = params.coverage data_items = coverage.data_items.filter(semantic__startswith="bands") range_type = coverage.range_type subsets = params.subsets # GDAL source dataset. Either a single file dataset or a composed VRT # dataset. src_ds = self.get_source_dataset( coverage, data_items, range_type ) # retrieve area of interest of the source image according to given # subsets src_rect, dst_rect = self.get_source_and_dest_rect(src_ds, subsets) # deduct "native" format of the source image native_format = data_items[0].format if len(data_items) == 1 else None # get the requested image format, which defaults to the native format # if available frmt = params.format or native_format if not frmt: raise RenderException("No format specified.", "format") if params.scalefactor is not None or params.scales: raise RenderException( "ReferenceableDataset cannot be scaled.", "scalefactor" if params.scalefactor is not None else "scale" ) maxsize = WCSConfigReader(get_eoxserver_config()).maxsize if maxsize is not None: if maxsize < dst_rect.size_x or maxsize < dst_rect.size_y: raise RenderException( "Requested image size %dpx x %dpx exceeds the allowed " "limit maxsize=%dpx." % ( dst_rect.size_x, dst_rect.size_y, maxsize ), "size" ) # perform subsetting either with or without rangesubsetting subsetted_ds = self.perform_subset( src_ds, range_type, src_rect, dst_rect, params.rangesubset ) # encode the processed dataset and save it to the filesystem out_ds, out_driver = self.encode( subsetted_ds, frmt, getattr(params, "encoding_params", {}) ) driver_metadata = out_driver.GetMetadata_Dict() mime_type = driver_metadata.get("DMD_MIMETYPE") extension = driver_metadata.get("DMD_EXTENSION") time_stamp = datetime.now().strftime("%Y%m%d%H%M%S") filename_base = "%s_%s" % (coverage.identifier, time_stamp) result_set = [ ResultFile( path, mime_type, "%s.%s" % (filename_base, extension), ("cid:coverage/%s" % coverage.identifier) if i == 0 else None ) for i, path in enumerate(out_ds.GetFileList()) ] if params.mediatype and params.mediatype.startswith("multipart"): reference = "cid:coverage/%s" % result_set[0].filename if subsets.has_x and subsets.has_y: footprint = GEOSGeometry(reftools.get_footprint_wkt(out_ds)) if not subsets.srid: extent = footprint.extent else: extent = subsets.xy_bbox encoder_subset = ( subsets.srid, src_rect.size, extent, footprint ) else: encoder_subset = None encoder = WCS20EOXMLEncoder() content = encoder.serialize( encoder.encode_referenceable_dataset( coverage, range_type, reference, mime_type, encoder_subset ) ) result_set.insert(0, ResultBuffer(content, encoder.content_type)) return result_set
def handle(self, request, collection_id=None, format_name=None): if request.method == "GET": request_parameters = request.GET elif request.method == "POST": request_parameters = request.POST else: raise Exception("Invalid request method '%s'." % request.method) decoder = OpenSearch11BaseDecoder(request_parameters) if collection_id: # search for products in that collection and coverages not # associated with a product but contained in this collection ModelClass = get_opensearch_record_model() qs = ModelClass.objects.all() if ModelClass == models.EOObject: qs = qs.filter( Q(product__collections__identifier=collection_id) | Q(coverage__collections__identifier=collection_id, coverage__parent_product__isnull=True) ).select_subclasses() else: qs = qs.filter(collections__identifier=collection_id) else: qs = models.Collection.objects.all() if decoder.search_terms: # TODO: search descriptions, summary etc once available qs = qs.filter(identifier__icontains=decoder.search_terms) namespaces = NameSpaceMap() all_parameters = {} for search_extension_class in get_extensions(): # get all search extension related parameters and translate the name # to the actual parameter name search_extension = search_extension_class() params = dict( (parameter["type"], request_parameters[parameter["name"]]) for parameter in search_extension.get_schema( model_class=qs.model) if parameter["name"] in request_parameters) qs = search_extension.filter(qs, params) namespaces.add(search_extension.namespace) all_parameters[search_extension.namespace.prefix] = params if not qs.ordered: qs = qs.order_by('begin_time') # use [:] here, otherwise the queryset would be evaluated and return # lists upon slicing total_count = qs[:].count() # read the configuration and determine the count parameter conf = OpenSearchConfigReader(get_eoxserver_config()) requested_count = min( decoder.count if decoder.count is not None else conf.default_count, conf.max_count) start_index = decoder.start_index # if count is zero, then return an 'empty' queryset if requested_count == 0: qs = models.EOObject.objects.none() else: qs = qs[start_index:start_index + requested_count] result_count = qs[:].count() try: result_format = next(result_format() for result_format in get_formats() if result_format.name == format_name) except StopIteration: raise Http404("No such result format '%s'." % format_name) search_context = SearchContext(total_count, start_index, requested_count, result_count, all_parameters, namespaces) return (result_format.encode(request, collection_id, qs, search_context), result_format.mimetype)
def render(self, params): # get the requested coverage, data items and range type. coverage = params.coverage data_items = coverage.data_items.filter(semantic__startswith="bands") range_type = coverage.range_type subsets = params.subsets # GDAL source dataset. Either a single file dataset or a composed VRT # dataset. src_ds = self.get_source_dataset( coverage, data_items, range_type ) # retrieve area of interest of the source image according to given # subsets src_rect, dst_rect = self.get_src_and_dst_rect(src_ds, subsets) # deduct "native" format of the source image def _src2nat(src_format): if src_format is None: return None frmreg = getFormatRegistry() f_src = frmreg.getFormatByMIME(src_format) f_dst = frmreg.mapSourceToNativeWCS20(f_src) f_nat = frmreg._mapSourceToNativeWCS20(f_src) if src_format == 'application/x-esa-envisat' and f_src == f_nat: return src_format elif f_dst is not None: return f_dst.mimeType source_format = data_items[0].format if len(data_items) == 1 else None native_format = _src2nat(source_format) # get the requested image format, which defaults to the native format # if available output_format = params.format or native_format if not output_format: raise RenderException("Failed to deduce the native format of " "the coverage. Output format must be provided!", "format") if params.scalefactor is not None or params.scales: raise RenderException( "ReferenceableDataset cannot be scaled.", "scalefactor" if params.scalefactor is not None else "scale" ) # check it the requested image fits the max. allowed coverage size maxsize = WCSConfigReader(get_eoxserver_config()).maxsize if maxsize < dst_rect.size_x or maxsize < dst_rect.size_y: raise RenderException( "Requested image size %dpx x %dpx exceeds the allowed " "limit maxsize=%dpx!" % (dst_rect.size_x, dst_rect.size_y, maxsize), "size" ) # get the output backend and driver for the requested format def _get_driver(mime_src, mime_out): """Select backend for the given source and output formats.""" # TODO: make this configurable if mime_src == 'application/x-esa-envisat' and \ mime_out == 'application/x-netcdf': return "BEAM", "NetCDF4-BEAM" elif mime_src == 'application/x-esa-envisat' and \ mime_out == 'application/x-esa-envisat': return "EOXS", "envisat" frmreg = getFormatRegistry() fobj = frmreg.getFormatByMIME(mime_out) if fobj is None: raise RenderException("Invallid output format '%s'!"%mime_out, "format") backend, _, driver = fobj.driver.partition("/") return backend, driver driver_backend, driver_name = _get_driver(source_format, output_format) if driver_backend not in ("GDAL", "BEAM", "EOXS"): raise RenderException("Invallid output format backend name %s!" "" % driver_backend, "format") # prepare output # --------------------------------------------------------------------- if driver_backend == "BEAM": path_out, extension = self.encode_beam( driver_name, src_ds.GetFileList()[0], src_rect, getattr(params, "encoding_params", {}) ) mime_type = output_format path_list = [path_out] time_stamp = datetime.now().strftime("%Y%m%d%H%M%S") filename_base = "%s_%s" % (coverage.identifier, time_stamp) result_set = [ ResultFile( path_item, mime_type, "%s.%s" % (filename_base, extension), ("cid:coverage/%s" % coverage.identifier) if i == 0 else None ) for i, path_item in enumerate(path_list) ] # --------------------------------------------------------------------- elif driver_backend == "EOXS": #EOxServer native backend result_set = [ResultAlt( file(src_ds.GetFileList()[0]), content_type=output_format, filename=basename(src_ds.GetFileList()[0]), identifier="cid:coverage/%s" % coverage.identifier, close=True, )] mime_type = output_format subsets = Subsets(()) # reset all subsets # --------------------------------------------------------------------- elif driver_backend == "GDAL": # get the output driver driver = gdal.GetDriverByName(driver_name) if driver is None: raise RenderException("Unsupported GDAL driver %s!" % driver_name) # perform subsetting either with or without rangesubsetting subsetted_ds = self.get_subset( src_ds, range_type, src_rect, dst_rect, params.rangesubset ) # encode the processed dataset and save it to the filesystem out_ds = self.encode(driver, subsetted_ds, output_format, getattr(params, "encoding_params", {})) driver_metadata = driver.GetMetadata_Dict() mime_type = driver_metadata.get("DMD_MIMETYPE") extension = driver_metadata.get("DMD_EXTENSION") path_list = out_ds.GetFileList() time_stamp = datetime.now().strftime("%Y%m%d%H%M%S") filename_base = "%s_%s" % (coverage.identifier, time_stamp) result_set = [ ResultFile( path_item, mime_type, "%s.%s" % (filename_base, extension), ("cid:coverage/%s" % coverage.identifier) if i == 0 else None ) for i, path_item in enumerate(path_list) ] # --------------------------------------------------------------------- if params.mediatype and params.mediatype.startswith("multipart"): reference = "cid:coverage/%s" % result_set[0].filename if subsets.has_x and subsets.has_y: footprint = GEOSGeometry(reftools.get_footprint_wkt(out_ds)) if not subsets.srid: extent = footprint.extent else: extent = subsets.xy_bbox encoder_subset = ( subsets.srid, src_rect.size, extent, footprint ) else: encoder_subset = None encoder = WCS20EOXMLEncoder() content = encoder.serialize( encoder.encode_referenceable_dataset( coverage, range_type, reference, mime_type, encoder_subset ) ) result_set.insert(0, ResultBuffer(content, encoder.content_type)) return result_set
def render(self, params): conf = CapabilitiesConfigReader(get_eoxserver_config()) map_ = Map() map_.setMetaData({ "enable_request": "*", "onlineresource": conf.http_service_url, "service_onlineresource": conf.onlineresource, "updateSequence": conf.update_sequence, "name": conf.name, "title": conf.title, "label": conf.title, "abstract": conf.abstract, "accessconstraints": conf.access_constraints, "addresstype": "", "address": conf.delivery_point, "stateorprovince": conf.administrative_area, "city": conf.city, "postcode": conf.postal_code, "country": conf.country, "contactelectronicmailaddress": conf.electronic_mail_address, "contactfacsimiletelephone": conf.phone_facsimile, "contactvoicetelephone": conf.phone_voice, "contactperson": conf.individual_name, "contactorganization": conf.provider_name, "contactposition": conf.position_name, "role": conf.role, "hoursofservice": conf.hours_of_service, "contactinstructions": conf.contact_instructions, "fees": conf.fees, "keywordlist": ",".join(conf.keywords), "formats": " ".join([f.wcs10name for f in self.get_wcs_formats()]), "srs": " ".join(crss.getSupportedCRS_WCS(format_function=crss.asShortCode)), }, namespace="ows") map_.setProjection("EPSG:4326") for outputformat in self.get_all_outputformats(False): map_.appendOutputFormat(outputformat) for coverage in params.coverages: layer = Layer(coverage.identifier) layer.setProjection(coverage.spatial_reference.proj) extent = coverage.extent size = coverage.size resolution = ((extent[2] - extent[0]) / float(size[0]), (extent[1] - extent[3]) / float(size[1])) layer.setExtent(*extent) layer.setMetaData({ "title": coverage.identifier, "label": coverage.identifier, "extent": "%.10g %.10g %.10g %.10g" % extent, "resolution": "%.10g %.10g" % resolution, "size": "%d %d" % size, "formats": " ".join([f.wcs10name for f in self.get_wcs_formats()]), "srs": " ".join(crss.getSupportedCRS_WCS(format_function=crss.asShortCode)), }, namespace="wcs") map_.insertLayer(layer) request = create_request(params) request.setParameter("version", params.version) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) return result
def constraints(self): reader = WCSEOConfigReader(get_eoxserver_config()) return {"CountDefault": reader.paging_count_default}
def get_filters(self, containment="overlaps"): """ Filter a :class:`Django QuerySet <django.db.models.query.QuerySet>` of objects inheriting from :class:`EOObject <eoxserver.resources.coverages.models.EOObject>`. :param queryset: the ``QuerySet`` to filter :param containment: either "overlaps" or "contains" :returns: a ``dict`` with the filters """ filters = {} if not len(self): return filters bbox = [None, None, None, None] srid = self.srid if srid is None: srid = 4326 max_extent = crss.crs_bounds(srid) tolerance = crss.crs_tolerance(srid) # check if time intervals are configured as "open" or "closed" config = get_eoxserver_config() reader = SubsetConfigReader(config) if reader.time_interval_interpretation == "closed": gt_op = "__gte" lt_op = "__lte" else: gt_op = "__gt" lt_op = "__lt" for subset in self: if isinstance(subset, Slice): is_slice = True value = subset.value elif isinstance(subset, Trim): is_slice = False low = subset.low high = subset.high # we need the value in case low == high value = low if subset.is_temporal: if is_slice or (high == low and containment == "overlaps"): filters['begin_time__lte'] = value filters['end_time__gte'] = value elif high == low: filters['begin_time__gte'] = value filters['end_time__lte'] = value else: # check if the temporal bounds must be strictly contained if containment == "contains": if high is not None: filters['end_time' + lt_op] = high if low is not None: filters['begin_time' + gt_op] = low # or just overlapping else: if high is not None: filters['begin_time' + lt_op] = high if low is not None: filters['end_time' + gt_op] = low else: if is_slice: if subset.is_x: line = LineString( (value, max_extent[1]), (value, max_extent[3]) ) else: line = LineString( (max_extent[0], value), (max_extent[2], value) ) line.srid = srid if srid != 4326: line.transform(4326) filters['footprint__intersects'] = line else: if subset.is_x: bbox[0] = subset.low bbox[2] = subset.high else: bbox[1] = subset.low bbox[3] = subset.high if bbox != [None, None, None, None]: bbox = list(map( lambda v: v[0] if v[0] is not None else v[1], zip(bbox, max_extent) )) bbox[0] -= tolerance bbox[1] -= tolerance bbox[2] += tolerance bbox[3] += tolerance logger.debug( "Applying BBox %s with containment '%s'." % (bbox, containment) ) poly = Polygon.from_bbox(bbox) poly.srid = srid if srid != 4326: poly.transform(4326) if containment == "overlaps": filters['footprint__intersects'] = poly elif containment == "contains": filters['footprint__within'] = poly return filters
def render(self, collections, coverages, request_values): conf = CapabilitiesConfigReader(get_eoxserver_config()) suffixes = self.suffixes map_ = Map() map_.setMetaData({ "enable_request": "*", "onlineresource": conf.http_service_url, "service_onlineresource": conf.onlineresource, "updateSequence": conf.update_sequence, "name": conf.name, "title": conf.title, "abstract": conf.abstract, "accessconstraints": conf.access_constraints, "addresstype": "postal", "address": conf.delivery_point, "stateorprovince": conf.administrative_area, "city": conf.city, "postcode": conf.postal_code, "country": conf.country, "contactelectronicmailaddress": conf.electronic_mail_address, "contactfacsimiletelephone": conf.phone_facsimile, "contactvoicetelephone": conf.phone_voice, "contactperson": conf.individual_name, "contactorganization": conf.provider_name, "contactposition": conf.position_name, "fees": conf.fees, "keywordlist": ",".join(conf.keywords), "srs": " ".join(crss.getSupportedCRS_WCS(format_function=crss.asShortCode)), }, namespace="ows") map_.setProjection("EPSG:4326") map_.setMetaData({ "getmap_formatlist": ",".join([f.mimeType for f in self.get_wms_formats()]), "getfeatureinfo_formatlist": "text/html,application/vnd.ogc.gml,text/plain", }, namespace="wms") map_extent = None for collection in collections: group_name = None # calculate extent and timextent for every collection extent = collection.extent_wgs84 # save overall map extent map_extent = self.join_extents(map_extent, extent) eo_objects = collection.eo_objects.filter( begin_time__isnull=False, end_time__isnull=False ) timeextent = ",".join( map( lambda o: ( "/".join( map(isoformat, o.time_extent) ) + "/PT1S" ), eo_objects ) ) if len(suffixes) > 1: # create group layer, if there is more than one suffix for this # collection group_name = collection.identifier + "_group" group_layer = Layer(group_name) group_layer.setMetaData({ "title": group_name, "abstract": group_name, "extent": " ".join(map(str, extent)), }, namespace="wms") group_layer.setExtent(*extent) # add default style default_class = Class("default") default_style= Style("default") default_class.insertStyle(default_style) group_layer.insertClass(default_class) map_.insertLayer(group_layer) for suffix in suffixes: layer_name = collection.identifier + (suffix or "") layer = Layer(layer_name) if group_name: layer.setMetaData({ "layer_group": "/" + group_name }, namespace="wms") layer.setMetaData({ "title": layer_name, "abstract": layer_name, "extent": " ".join(map(str, extent)), "timeextent": timeextent, }, namespace="wms") map_.insertLayer(layer) for coverage in coverages: extent = coverage.extent_wgs84 # save overall map extent map_extent = self.join_extents(map_extent, extent) layer_name = coverage.identifier layer = Layer(layer_name) layer.setMetaData({ "title": layer_name, "abstract": layer_name, "extent": " ".join(map(str, extent)), }, namespace="wms") layer.setExtent(*extent) map_.insertLayer(layer) # set the map_extent to a reasonable default value # in case there is no coverage or collection if map_extent is None: map_extent = (0.0, 0.0, 1.0, 1.0) map_.setExtent(*map_extent) request = create_request(request_values) raw_result = map_.dispatch(request) result = result_set_from_raw_data(raw_result) return result, get_content_type(result)
#------------------------------------------------------------------------------- # Copyright (C) 2015 EOX IT Services GmbH # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies of this Software or works derived from this Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #------------------------------------------------------------------------------- from eoxserver.core.decoders import config from eoxserver.core.config import get_eoxserver_config class WebappConfigReader(config.Reader): section = "damats" default_user = config.Option(default="") WEBAPP_CONFIG = WebappConfigReader(get_eoxserver_config())
def encode_beam(driver_name, path_src, src_rect, encoding_params): # get and check the location of the BEAM toolbox sys_config = SystemConfigReader(get_eoxserver_config()) path_beam = sys_config.path_beam beam_options = [f for f in sys_config.beam_options.split()] if path_beam is None: raise RenderException("Path to BEAM toolbox is not defined!", "config") path_beam_gpt = join(path_beam, 'bin/gpt.sh') if not isfile(path_beam_gpt): raise RenderException("Invalid path to BEAM toolbox %s!" % repr(path_beam), "config") # mime-type and output extenstion if driver_name.startswith("NetCDF-"): extension = "nc" elif driver_name.startswith("NetCDF4-"): extension = "nc4" elif driver_name.startswith("GeoTIFF"): extension = "tif" else: extension = "" # temporary filename path_temp = SystemConfigReader(get_eoxserver_config()).path_temp while True: path_base = join(path_temp, "eoxs_tmp_%s" % uuid4().hex) path_gpt = "%s%s"%(path_base, ".gpt") path_data = "%s%s"%(path_base, "."+extension) if not exists(path_gpt) and not exists(path_data): break # BEAM graph generator def _graph(): yield '<graph id="data_subset">' yield ' <version>1.0</version> ' yield ' <node id="subsetter">' yield ' <operator>Subset</operator>' yield ' <sources>' yield ' <sourceProduct>${INPUT}</sourceProduct>' yield ' </sources>' yield ' <parameters>' yield ' <region>' yield ' <x>%d</x>' % src_rect.offset_x yield ' <y>%d</y>' % src_rect.offset_y yield ' <width>%d</width>' % src_rect.size_x yield ' <height>%d</height>' % src_rect.size_y yield ' </region>' yield ' <copyMetadata>true</copyMetadata>' yield ' </parameters>' yield ' </node>' yield ' <node id="writer">' yield ' <operator>Write</operator>' yield ' <sources>' yield ' <source>subsetter</source>' yield ' </sources>' yield ' <parameters>' yield ' <file>${OUTPUT}</file>' yield ' <formatName>%s</formatName>' % driver_name yield ' <deleteOutputOnFailure>true</deleteOutputOnFailure>' yield ' <writeEntireTileRows>false</writeEntireTileRows>' yield ' <clearCacheAfterRowWrite>true</clearCacheAfterRowWrite>' yield ' </parameters>' yield ' </node>' yield '</graph>' try: with file(path_gpt, "w") as fid: for item in _graph(): logger.debug(item) fid.write(item) beam_gpt_argv = [ path_beam_gpt, path_gpt, '-SINPUT=%s' % path_src, '-POUTPUT=%s' % path_data ] + beam_options logger.debug("%s", beam_gpt_argv) if call(beam_gpt_argv): raise RenderException("BEAM toolbox failed to generate the output!", "beam") except: if isfile(path_data): remove(path_data) raise finally: if isfile(path_gpt): remove(path_gpt) return path_data, extension
def matches(self, eo_object, containment="overlaps"): """ Check if the given :class:`EOObject <eoxserver.resources.coverages.models.EOObject>` matches the given subsets. :param eo_object: the ``EOObject`` to match :param containment: either "overlaps" or "contains" :returns: a boolean value indicating if the object is contained in the given subsets """ if not len(self): return True bbox = [None, None, None, None] srid = self.srid if srid is None: srid = 4326 max_extent = crss.crs_bounds(srid) tolerance = crss.crs_tolerance(srid) # check if time intervals are configured as "open" or "closed" config = get_eoxserver_config() reader = SubsetConfigReader(config) # note that the operator is inverted from filter() above as the # filters use an inclusive search whereas here it's exclusive if reader.time_interval_interpretation == "closed": gt_op = operator.gt lt_op = operator.lt else: gt_op = operator.ge lt_op = operator.le footprint = eo_object.footprint begin_time = eo_object.begin_time end_time = eo_object.end_time for subset in self: if isinstance(subset, Slice): is_slice = True value = subset.value elif isinstance(subset, Trim): is_slice = False low = subset.low high = subset.high # we need the value in case low == high value = low if subset.is_temporal: if is_slice or (low == high and containment == "overlaps"): if begin_time > value or end_time < value: return False elif low == high: if begin_time < value or end_time > value: return False else: # check if the temporal bounds must be strictly contained if containment == "contains": if high is not None: if gt_op(end_time, high): return False if low is not None: if lt_op(begin_time, low): return False # or just overlapping else: if high is not None: if gt_op(begin_time, high): return False if low is not None: if lt_op(end_time, low): return False else: if is_slice: if subset.is_x: line = LineString( (value, max_extent[1]), (value, max_extent[3]) ) else: line = LineString( (max_extent[0], value), (max_extent[2], value) ) line.srid = srid if srid != 4326: line.transform(4326) if not line.intersects(footprint): return False else: if subset.is_x: bbox[0] = subset.low bbox[2] = subset.high else: bbox[1] = subset.low bbox[3] = subset.high if bbox != [None, None, None, None]: bbox = map( lambda v: v[0] if v[0] is not None else v[1], zip(bbox, max_extent) ) bbox[0] -= tolerance bbox[1] -= tolerance bbox[2] += tolerance bbox[3] += tolerance logger.debug( "Applying BBox %s with containment '%s'." % (bbox, containment) ) poly = Polygon.from_bbox(bbox) poly.srid = srid if srid != 4326: poly.transform(4326) if containment == "overlaps": if not footprint.intersects(poly): return False elif containment == "contains": if not footprint.within(poly): return False return True