def handle(self, req): if req.path.startswith('/demo/static/'): filename = req.path.lstrip('/') filename = static_filename(filename) if not os.path.isfile(filename): return Response('file not found', content_type='text/plain', status=404) type, encoding = mimetypes.guess_type(filename) return Response(open(filename, 'rb'), content_type=type) # we don't authorize the static files (css, js) # since they are not confidential try: authorized = self.authorized_demo(req.environ) except RequestError as ex: return ex.render() if not authorized: return Response('forbidden', content_type='text/plain', status=403) if 'wms_layer' in req.args: demo = self._render_wms_template('demo/wms_demo.html', req) elif 'tms_layer' in req.args: demo = self._render_tms_template('demo/tms_demo.html', req) elif 'wmts_layer' in req.args: demo = self._render_wmts_template('demo/wmts_demo.html', req) elif 'wms_capabilities' in req.args: internal_url = '%s/service?REQUEST=GetCapabilities'%(req.server_script_url) url = internal_url.replace(req.server_script_url, req.script_url)
def kml(self, map_request): """ :return: the rendered KML response """ layer = self.layer(map_request) self.authorize_tile_layer(layer, map_request) tile_coord = map_request.tile initial_level = False if tile_coord[2] == 0: initial_level = True bbox = self._tile_wgs_bbox(tile_coord, layer.grid, limit=True) if bbox is None: raise RequestError('The requested tile is outside the bounding box ' 'of the tile map.', request=map_request) tile = SubTile(tile_coord, bbox) subtiles = self._get_subtiles(tile_coord, layer) tile_size = layer.grid.tile_size[0] url = map_request.http.script_url.rstrip('/') result = KMLRenderer().render(tile=tile, subtiles=subtiles, layer=layer, url=url, name=map_request.layer, format=layer.format, name_path=layer.md['name_path'], initial_level=initial_level, tile_size=tile_size) resp = Response(result, content_type='application/vnd.google-earth.kml+xml') resp.cache_headers(etag_data=(result,), max_age=self.max_tile_age) resp.make_conditional(map_request.http) return resp
def __call__(self, environ, start_response): resp = None req = Request(environ) if self.cors_origin: orig_start_response = start_response def start_response(status, headers, exc_info=None): headers.append(('Access-control-allow-origin', self.cors_origin)) return orig_start_response(status, headers, exc_info) with local_base_config(self.base_config): match = self.handler_path_re.match(req.path) if match: handler_name = match.group(1) if handler_name in self.handlers: try: resp = self.handlers[handler_name].handle(req) except Exception: if self.base_config.debug_mode: raise else: log_wsgiapp.fatal('fatal error in %s for %s?%s', handler_name, environ.get('PATH_INFO'), environ.get('QUERY_STRING'), exc_info=True) import traceback traceback.print_exc(file=environ['wsgi.errors']) resp = Response('internal error', status=500) if resp is None: if req.path in ('', '/'): resp = self.welcome_response(req.script_url) else: resp = Response('not found', mimetype='text/plain', status=404) return resp(environ, start_response)
def __call__(self, environ, start_response): req = Request(environ) try: if req.path == '/': resp = self.do_request(req) elif req.path == '/_status': resp = self.do_status(req) else: resp = Response(json.dumps({ 'status': 'error', 'error_message': 'endpoint not found' }), content_type='application/json', status=404) except LockTimeout, ex: resp = Response(json.dumps({ 'status': 'lock', 'error_message': 'lock timeout error: %s' % ex.args[0] }), content_type='application/json', status=503)
def handle(self, req): if req.path.startswith('/demo/static/'): filename = req.path.lstrip('/') filename = static_filename(filename) if not os.path.isfile(filename): return Response('file not found', content_type='text/plain', status=404) type, encoding = mimetypes.guess_type(filename) return Response(open(filename, 'rb'), content_type=type) # we don't authorize the static files (css, js) # since they are not confidential try: authorized = self.authorized_demo(req.environ) except RequestError as ex: return ex.render() if not authorized: return Response('forbidden', content_type='text/plain', status=403) if 'wms_layer' in req.args: demo = self._render_wms_template('demo/wms_demo.html', req) elif 'tms_layer' in req.args: demo = self._render_tms_template('demo/tms_demo.html', req) elif 'wmts_layer' in req.args: demo = self._render_wmts_template('demo/wmts_demo.html', req) elif 'wms_capabilities' in req.args: url = '%s/service?REQUEST=GetCapabilities'%(req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template('demo/capabilities_demo.html', capabilities, 'WMS', url) elif 'wmsc_capabilities' in req.args: url = '%s/service?REQUEST=GetCapabilities&tiled=true'%(req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template('demo/capabilities_demo.html', capabilities, 'WMS-C', url) elif 'wmts_capabilities_kvp' in req.args: url = '%s/service?REQUEST=GetCapabilities&SERVICE=WMTS' % (req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template('demo/capabilities_demo.html', capabilities, 'WMTS', url) elif 'wmts_capabilities' in req.args: url = '%s/wmts/1.0.0/WMTSCapabilities.xml' % (req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template('demo/capabilities_demo.html', capabilities, 'WMTS', url) elif 'tms_capabilities' in req.args: if 'layer' in req.args and 'srs' in req.args: # prevent dir traversal (seems it's not possible with urllib2, but better safe then sorry) layer = req.args['layer'].replace('..', '') srs = req.args['srs'].replace('..', '') url = '%s/tms/1.0.0/%s/%s'%(req.script_url, layer, srs) else: url = '%s/tms/1.0.0/'%(req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template('demo/capabilities_demo.html', capabilities, 'TMS', url) elif req.path == '/demo/': demo = self._render_template('demo/demo.html') else: resp = Response('', status=301) resp.headers['Location'] = req.script_url.rstrip('/') + '/demo/' return resp return Response(demo, content_type='text/html')
def tile(self, request): self.check_request(request) tile_layer = self.layers[request.layer][request.tilematrixset] if not request.format: request.format = tile_layer.format tile = tile_layer.render(request) resp = Response(tile.as_buffer(), content_type='image/' + request.format) resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) resp.make_conditional(request.http) return resp
def create_app(self, user, uuid): try: mapproxy_conf = self.config_cache.config(user, uuid, self.max_uuids_per_user) except RequestError: log.exception('unable to query config') return Response('service unavailable', status=503) if not mapproxy_conf: return Response('not found', status=404) log.debug('initializing project %s', mapproxy_conf) return make_mapproxy_wsgi_app(mapproxy_conf)
def tile(self, request): self.check_request(request) tile_layer = self.layers[request.layer][request.tilematrixset] if not request.format: request.format = tile_layer.format limited_to = self.authorize_tile_layer(tile_layer, request) tile = tile_layer.render(request, coverage=limited_to) # set the content_type to tile.format and not to request.format ( to support mixed_mode) resp = Response(tile.as_buffer(), content_type="image/" + tile.format) resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) resp.make_conditional(request.http) return resp
def map(self, tile_request): """ :return: the requested tile :rtype: Response """ if self.origin and not tile_request.origin: tile_request.origin = self.origin layer, limit_to = self.layer(tile_request) def decorate_img(image): query_extent = (layer.grid.srs.srs_code, layer.tile_bbox( tile_request, use_profiles=tile_request.use_profiles)) return self.decorate_img(image, 'tms', [layer.name], tile_request.http.environ, query_extent) tile = layer.render(tile_request, use_profiles=tile_request.use_profiles, coverage=limit_to, decorate_img=decorate_img) tile_format = getattr(tile, 'format', tile_request.format) resp = Response(tile.as_buffer(), content_type='image/' + tile_format) if tile.cacheable: resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) else: resp.cache_headers(no_cache=True) resp.make_conditional(tile_request.http) return resp
def handle(self, req): if req.path.startswith('/demo/static/'): filename = req.path.lstrip('/') if not pkg_resources.resource_exists(__name__, 'templates/' + filename): return Response('file not found', content_type='text/plain', status=404) type, encoding = mimetypes.guess_type(filename) return Response(pkg_resources.resource_string(__name__, 'templates/' + filename), content_type=type) # we don't authorize the static files (css, js) # since they are not confidential try: authorized = self.authorized_demo(req.environ) except RequestError, ex: return ex.render()
def map(self, map_request): """ :return: the requested tile """ # force 'sw' origin for kml map_request.origin = 'sw' layer = self.layer(map_request) self.authorize_tile_layer(layer.name, map_request.http.environ) tile = layer.render(map_request) resp = Response(tile.as_buffer(), content_type='image/' + map_request.format) resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) resp.make_conditional(map_request.http) return resp
def render(self): """ Return a response with the rendered exception. The rendering is delegated to the ``exception_handler`` that issued the ``RequestError``. :rtype: `Response` """ if self.request is not None: handler = self.request.exception_handler return handler.render(self) elif self.status is not None: return Response(self.msg, status=self.status) else: return Response('internal error: %s' % self.msg, status=500)
def welcome_response(self, script_url): import mapproxy.version html = "<html><body><h1>Welcome to MapProxy %s</h1>" % mapproxy.version.version if 'demo' in self.handlers: html += '<p>See all configured layers and services at: <a href="%s/demo/">demo</a>' % ( script_url, ) return Response(html, mimetype='text/html')
def handle(self, req): log.info('%s', req.path) year = req.pop_path() month = req.pop_path() day = req.pop_path() hour = req.pop_path() app_part = req.pop_path() #log.info('year: %s month: %s day: %s hour: %s app_part: %s', year, month, day, hour, app_part) app_name = os.path.join(year, month, day, hour, app_part) #log.info('req: %s appname: %s', req.path, app_name) if not app_name: return self.index_list(req) if not app_name or (app_name not in self.apps and not self.loader.app_available(app_name)): return Response('not found', status=404) # safe instance/app name for authorization req.environ['mapproxy.instance_name'] = app_name return self.proj_app(app_name)
def capabilities(self, request): service = self._service_md(request) layers = self.authorized_tile_layers(request.http.environ) result = self.capabilities_class(service, layers, self.matrix_sets, info_formats=self.info_formats).render(request) return Response(result, mimetype='application/xml')
def capabilities(self, map_request): # TODO: debug layer # if '__debug__' in map_request.params: # layers = self.layers.values() # else: # layers = [layer for name, layer in self.layers.iteritems() # if name != '__debug__'] if map_request.params.get('tiled', 'false').lower() == 'true': tile_layers = self.tile_layers.values() else: tile_layers = [] service = self._service_md(map_request) root_layer = self.authorized_capability_layers( map_request.http.environ) info_types = ['text', 'html', 'xml'] # defaults if self.info_types: info_types = self.info_types elif self.fi_transformers: info_types = self.fi_transformers.keys() info_formats = [ mimetype_from_infotype(map_request.version, info_type) for info_type in info_types ] result = Capabilities(service, root_layer, tile_layers, self.image_formats, info_formats, srs=self.srs, bbox_srs=self.bbox_srs).render(map_request) return Response(result, mimetype=map_request.mime_type)
def test_str_response(self): resp = Response('string content') assert isinstance(resp.response, basestring) start_response = self.mock() self.expect(start_response('200 OK', ANY)) self.replay() result = resp({'REQUEST_METHOD': 'GET'}, start_response) assert result.next() == 'string content'
def test_str_response(self): resp = Response("string content") assert isinstance(resp.response, string_type) start_response = self.mock() self.expect(start_response("200 OK", ANY)) self.replay() result = resp({"REQUEST_METHOD": "GET"}, start_response) assert next(result) == b"string content"
def handle(self, req): if req.path.startswith('/demo/static/'): filename = req.path.lstrip('/') filename = static_filename(filename) if not os.path.isfile(filename): return Response('file not found', content_type='text/plain', status=404) type, encoding = mimetypes.guess_type(filename) return Response(open(filename, 'rb'), content_type=type) # we don't authorize the static files (css, js) # since they are not confidential try: authorized = self.authorized_demo(req.environ) except RequestError, ex: return ex.render()
def tms_root_resource(self, tms_request): """ :return: root resource with all available versions of the service :rtype: Response """ service = self._service_md(tms_request) result = self._render_root_resource_template(service) return Response(result, mimetype='text/xml')
def featureinfo(self, request): infos = [] self.check_request(request, self.info_formats) tile_layer = self.layers[request.layer][request.tilematrixset] if not request.format: request.format = tile_layer.format bbox = tile_layer.grid.tile_bbox(request.tile) query = InfoQuery( bbox, tile_layer.grid.tile_size, tile_layer.grid.srs, request.pos, request.infoformat, ) self.check_request_dimensions(tile_layer, request) coverage = self.authorize_tile_layer(tile_layer, request, featureinfo=True) if not tile_layer.info_sources: raise RequestError('layer %s not queryable' % str(request.layer), code='OperationNotSupported', request=request) if coverage and not coverage.contains(query.coord, query.srs): infos = [] else: for source in tile_layer.info_sources: info = source.get_info(query) if info is None: continue infos.append(info) mimetype = request.infoformat if not infos: return Response('', mimetype=mimetype) resp, _ = combine_docs(infos) return Response(resp, mimetype=mimetype)
def map(self, tile_request): """ :return: the requested tile :rtype: Response """ if self.origin and not tile_request.origin: tile_request.origin = self.origin layer, limit_to = self.layer(tile_request) def decorate_img(image): query_extent = (layer.grid.srs.srs_code, layer.tile_bbox(tile_request, use_profiles=tile_request.use_profiles)) return self.decorate_img(image, 'tms', [layer.name], tile_request.http.environ, query_extent) tile = layer.render(tile_request, use_profiles=tile_request.use_profiles, coverage=limit_to, decorate_img=decorate_img) tile_format = getattr(tile, 'format', tile_request.format) resp = Response(tile.as_buffer(), content_type='image/' + tile_format) if tile.cacheable: resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) else: resp.cache_headers(no_cache=True) resp.make_conditional(tile_request.http) return resp
def test_file_response(self): data = StringIO('foobar') resp = Response(data) assert resp.response == data start_response = self.mock() self.expect(start_response('200 OK', ANY)) self.replay() result = resp({'REQUEST_METHOD': 'GET'}, start_response) assert result.next() == 'foobar'
def test_itr_response(self): resp = Response(iter(['string content', 'as iterable'])) assert hasattr(resp.response, 'next') start_response = self.mock() self.expect(start_response('200 OK', ANY)) self.replay() result = resp({'REQUEST_METHOD': 'GET'}, start_response) assert result.next() == 'string content' assert result.next() == 'as iterable'
def test_file_response_content_length(self): data = BytesIO(b"*" * 342) resp = Response(data) assert resp.response == data start_response = self.mock() self.expect(start_response("200 OK", ANY)) self.replay() resp({"REQUEST_METHOD": "GET"}, start_response) assert resp.content_length == 342
def test_file_response(self): data = BytesIO(b"foobar") resp = Response(data) assert resp.response == data start_response = self.mock() self.expect(start_response("200 OK", ANY)) self.replay() result = resp({"REQUEST_METHOD": "GET"}, start_response) assert next(result) == b"foobar"
def test_file_response_content_length(self): data = StringIO('*' * 342) resp = Response(data) assert resp.response == data start_response = self.mock() self.expect(start_response('200 OK', ANY)) self.replay() resp({'REQUEST_METHOD': 'GET'}, start_response) assert resp.content_length == 342
def test_itr_response(self): resp = Response(iter(["string content", "as iterable"])) assert hasattr(resp.response, "next") or hasattr(resp.response, "__next__") start_response = self.mock() self.expect(start_response("200 OK", ANY)) self.replay() result = resp({"REQUEST_METHOD": "GET"}, start_response) assert next(result) == "string content" assert next(result) == "as iterable"
def handle(self, req): if req.path.startswith('/demo/static/'): filename = req.path.lstrip('/') filename = static_filename(filename) if not os.path.isfile(filename): return Response('file not found', content_type='text/plain', status=404) type, encoding = mimetypes.guess_type(filename) return Response(open(filename, 'rb'), content_type=type) # we don't authorize the static files (css, js) # since they are not confidential try: authorized = self.authorized_demo(req.environ) except RequestError as ex: return ex.render() if not authorized: return Response('forbidden', content_type='text/plain', status=403) if 'wms_layer' in req.args: demo = self._render_wms_template('demo/wms_demo.html', req) elif 'tms_layer' in req.args: demo = self._render_tms_template('demo/tms_demo.html', req) elif 'wmts_layer' in req.args: demo = self._render_wmts_template('demo/wmts_demo.html', req) elif 'wms_capabilities' in req.args: url = '%s/service?REQUEST=GetCapabilities' % (req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template( 'demo/capabilities_demo.html', capabilities, 'WMS', url) elif 'wmsc_capabilities' in req.args: url = '%s/service?REQUEST=GetCapabilities&tiled=true' % ( req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template( 'demo/capabilities_demo.html', capabilities, 'WMS-C', url) elif 'wmts_capabilities' in req.args: url = '%s/wmts/1.0.0/WMTSCapabilities.xml' % (req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template( 'demo/capabilities_demo.html', capabilities, 'WMTS', url) elif 'tms_capabilities' in req.args: if 'layer' in req.args and 'srs' in req.args: url = '%s/tms/1.0.0/%s/%s' % ( req.script_url, req.args['layer'], req.args['srs']) else: url = '%s/tms/1.0.0/' % (req.script_url) capabilities = urllib2.urlopen(url) demo = self._render_capabilities_template( 'demo/capabilities_demo.html', capabilities, 'TMS', url) elif req.path == '/demo/': demo = self._render_template('demo/demo.html') else: resp = Response('', status=301) resp.headers['Location'] = req.script_url.rstrip('/') + '/demo/' return resp return Response(demo, content_type='text/html')
def do_request(self, req): req = json.loads(req.body()) log.info('got request: %s', req) req_id = req.get('id') if not req_id: req_id = uuid.uuid4().hex resp = self.broker.dispatch( Task(req_id, req, priority=req.get('priority', 10))) log.info('got resp: %s', resp) return Response(json.dumps(resp.doc), content_type='application/json')
def handle(self, req): app_name = req.pop_path() # if not app_name: # return self.index_list(req) if not app_name or (app_name not in self.apps and not self.loader.app_available(app_name)): return Response('not found', status=404) # safe instance/app name for authorization req.environ['mapproxy.instance_name'] = app_name return self.proj_app(app_name)
def tile(self, request): self.check_request(request) tile_layer = self.layers[request.layer][request.tilematrixset] if not request.format: request.format = tile_layer.format self.check_request_dimensions(tile_layer, request) limited_to = self.authorize_tile_layer(tile_layer, request) def decorate_img(image): query_extent = tile_layer.grid.srs.srs_code, tile_layer.tile_bbox( request) return self.decorate_img(image, 'wmts', [tile_layer.name], request.http.environ, query_extent) tile = tile_layer.render(request, coverage=limited_to, decorate_img=decorate_img) # set the content_type to tile.format and not to request.format ( to support mixed_mode) resp = Response(tile.as_buffer(), content_type='image/' + tile.format) resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) resp.make_conditional(request.http) return resp
def kml(self, map_request): """ :return: the rendered KML response """ layer = self.layer(map_request) self.authorize_tile_layer(layer.name, map_request.http.environ) tile_coord = map_request.tile initial_level = False if tile_coord[2] == 0: initial_level = True bbox = self._tile_wgs_bbox(tile_coord, layer.grid, limit=True) if bbox is None: raise RequestError('The requested tile is outside the bounding box ' 'of the tile map.', request=map_request) tile = SubTile(tile_coord, bbox) subtiles = self._get_subtiles(tile_coord, layer) tile_size = layer.grid.tile_size[0] url = map_request.http.script_url.rstrip('/') result = KMLRenderer().render(tile=tile, subtiles=subtiles, layer=layer, url=url, name=map_request.layer, format=layer.format, name_path=layer.md['name_path'], initial_level=initial_level, tile_size=tile_size) resp = Response(result, content_type='application/vnd.google-earth.kml+xml') resp.cache_headers(etag_data=(result,), max_age=self.max_tile_age) resp.make_conditional(map_request.http) return resp
def do_status(self, req): body = """\ running: %d waiting: %d worker: %d """ % ( self.broker.render_queue.running, self.broker.render_queue.waiting, self.broker.worker.pool_size, ) body = textwrap.dedent(body) return Response(body, content_type='text/plain')
def render(self, request_error): """ Render the template of this exception handler. Passes the ``request_error.msg`` and ``request_error.code`` to the template. :type request_error: `RequestError` """ status_code = self.status_codes.get(request_error.code, self.status_code) # escape &<> in error message (e.g. URL params) msg = cgi.escape(request_error.msg) result = self.template.substitute(exception=msg, code=request_error.code) return Response(result, mimetype=self.mimetype, content_type=self.content_type, status=status_code)
def tile(self, request): self.check_request(request) tile_layer = self.layers[request.layer][request.tilematrixset] if not request.format: request.format = tile_layer.format self.check_request_dimensions(tile_layer, request) limited_to = self.authorize_tile_layer(tile_layer, request) def decorate_img(image): query_extent = tile_layer.grid.srs.srs_code, tile_layer.tile_bbox(request) return self.decorate_img(image, 'wmts', [tile_layer.name], request.http.environ, query_extent) tile = tile_layer.render(request, coverage=limited_to, decorate_img=decorate_img) # set the content_type to tile.format and not to request.format ( to support mixed_mode) resp = Response(tile.as_buffer(), content_type='image/' + tile.format) resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) resp.make_conditional(request.http) return resp
def tms_capabilities(self, tms_request): """ :return: the rendered tms capabilities :rtype: Response """ service = self._service_md(tms_request) if hasattr(tms_request, 'layer'): layer, limit_to = self.layer(tms_request) result = self._render_layer_template(layer, service) else: layers = self.authorized_tile_layers(tms_request.http.environ) result = self._render_template(layers, service) return Response(result, mimetype='text/xml')
def map(self, tile_request): """ :return: the requested tile :rtype: Response """ if self.origin and not tile_request.origin: tile_request.origin = self.origin layer = self.layer(tile_request) tile = layer.render(tile_request, use_profiles=tile_request.use_profiles) resp = Response(tile.as_buffer(), content_type='image/' + tile_request.format) if tile.cacheable: resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size), max_age=self.max_tile_age) else: resp.cache_headers(no_cache=True) resp.make_conditional(tile_request.http) return resp
def map(self, map_request): self.check_map_request(map_request) params = map_request.params query = MapQuery(params.bbox, params.size, SRS(params.srs), params.format) if map_request.params.get("tiled", "false").lower() == "true": query.tiled_only = True actual_layers = odict() for layer_name in map_request.params.layers: layer = self.layers[layer_name] # only add if layer renders the query if layer.renders_query(query): # if layer is not transparent and will be rendered, # remove already added (then hidden) layers if not layer.transparent: actual_layers = odict() for layer_name, map_layers in layer.map_layers_for_query(query): actual_layers[layer_name] = map_layers authorized_layers, coverage = self.authorized_layers( "map", actual_layers.keys(), map_request.http.environ, query_extent=(query.srs.srs_code, query.bbox) ) self.filter_actual_layers(actual_layers, map_request.params.layers, authorized_layers) render_layers = [] for layers in actual_layers.values(): render_layers.extend(layers) self.update_query_with_fwd_params(query, params=params, layers=render_layers) raise_source_errors = True if self.on_error == "raise" else False renderer = LayerRenderer( render_layers, query, map_request, raise_source_errors=raise_source_errors, concurrent_rendering=self.concurrent_layer_renderer, ) merger = LayerMerger() renderer.render(merger) if self.attribution and not query.tiled_only: merger.add(attribution_image(self.attribution["text"], params.size)) img_opts = self.image_formats[params.format_mime_type].copy() img_opts.bgcolor = params.bgcolor img_opts.transparent = params.transparent result = merger.merge( size=params.size, image_opts=img_opts, bbox=params.bbox, bbox_srs=params.srs, coverage=coverage ) resp = Response(result.as_buffer(img_opts), content_type=img_opts.format.mime_type) if query.tiled_only and isinstance(result.cacheable, CacheInfo): cache_info = result.cacheable resp.cache_headers( cache_info.timestamp, etag_data=(cache_info.timestamp, cache_info.size), max_age=self.max_tile_age ) resp.make_conditional(map_request.http) if not result.cacheable: resp.cache_headers(no_cache=True) return resp
def map(self, map_request): self.check_map_request(map_request) params = map_request.params query = MapQuery(params.bbox, params.size, SRS(params.srs), params.format) if map_request.params.get('tiled', 'false').lower() == 'true': query.tiled_only = True orig_query = query if self.srs_extents and params.srs in self.srs_extents: # limit query to srs_extent if query is larger query_extent = MapExtent(params.bbox, SRS(params.srs)) if not self.srs_extents[params.srs].contains(query_extent): limited_extent = self.srs_extents[params.srs].intersection(query_extent) if not limited_extent: img_opts = self.image_formats[params.format_mime_type].copy() img_opts.bgcolor = params.bgcolor img_opts.transparent = params.transparent img = BlankImageSource(size=params.size, image_opts=img_opts, cacheable=True) return Response(img.as_buffer(), content_type=img_opts.format.mime_type) sub_size, offset, sub_bbox = bbox_position_in_image(params.bbox, params.size, limited_extent.bbox) query = MapQuery(sub_bbox, sub_size, SRS(params.srs), params.format) actual_layers = odict() for layer_name in map_request.params.layers: layer = self.layers[layer_name] # only add if layer renders the query if layer.renders_query(query): # if layer is not transparent and will be rendered, # remove already added (then hidden) layers if not layer.transparent: actual_layers = odict() for layer_name, map_layers in layer.map_layers_for_query(query): actual_layers[layer_name] = map_layers authorized_layers, coverage = self.authorized_layers('map', actual_layers.keys(), map_request.http.environ, query_extent=(query.srs.srs_code, query.bbox)) self.filter_actual_layers(actual_layers, map_request.params.layers, authorized_layers) render_layers = [] for layers in actual_layers.values(): render_layers.extend(layers) self.update_query_with_fwd_params(query, params=params, layers=render_layers) raise_source_errors = True if self.on_error == 'raise' else False renderer = LayerRenderer(render_layers, query, map_request, raise_source_errors=raise_source_errors, concurrent_rendering=self.concurrent_layer_renderer) merger = LayerMerger() renderer.render(merger) if self.attribution and self.attribution.get('text') and not query.tiled_only: merger.add(attribution_image(self.attribution['text'], query.size)) img_opts = self.image_formats[params.format_mime_type].copy() img_opts.bgcolor = params.bgcolor img_opts.transparent = params.transparent result = merger.merge(size=query.size, image_opts=img_opts, bbox=query.bbox, bbox_srs=params.srs, coverage=coverage) if query != orig_query: result = SubImageSource(result, size=orig_query.size, offset=offset, image_opts=img_opts) # Provide the wrapping WSGI app or filter the opportunity to process the # image before it's wrapped up in a response result = self.decorate_img(result, 'wms.map', actual_layers.keys(), map_request.http.environ, (query.srs.srs_code, query.bbox)) try: result_buf = result.as_buffer(img_opts) except IOError as ex: raise RequestError('error while processing image file: %s' % ex, request=map_request) resp = Response(result_buf, content_type=img_opts.format.mime_type) if query.tiled_only and isinstance(result.cacheable, CacheInfo): cache_info = result.cacheable resp.cache_headers(cache_info.timestamp, etag_data=(cache_info.timestamp, cache_info.size), max_age=self.max_tile_age) resp.make_conditional(map_request.http) if not result.cacheable: resp.cache_headers(no_cache=True) return resp