def test_get_map_with_res_range(self): res_range = resolution_range(1000, 10) self.source = WMSSource(self.client, res_range=res_range) self.locker = TileLocker(tmp_lock_dir, 10, "id") self.tile_mgr = TileManager(self.grid, self.file_cache, [self.source], 'png', meta_size=[2, 2], meta_buffer=0, image_opts=self.image_opts, locker=self.locker) self.layer = CacheMapLayer(self.tile_mgr, image_opts=default_image_opts) try: result = self.layer.get_map( MapQuery( (-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913), 'png')) except BlankImage: pass else: assert False, 'expected BlankImage exception' eq_(self.file_cache.stored_tiles, set()) result = self.layer.get_map( MapQuery((0, 0, 10000, 10000), (50, 50), SRS(900913), 'png')) eq_( self.file_cache.stored_tiles, set([(512, 257, 10), (513, 256, 10), (512, 256, 10), (513, 257, 10)])) eq_(result.size, (50, 50))
def test_get_map_with_res_range(self, mock_file_cache, mock_wms_client, tile_locker): grid = TileGrid(SRS(4326), bbox=[-180, -90, 180, 90]) res_range = resolution_range(1000, 10) source = WMSSource(mock_wms_client, res_range=res_range) image_opts = ImageOptions(resampling='nearest') tile_mgr = TileManager(grid, mock_file_cache, [source], 'png', meta_size=[2, 2], meta_buffer=0, image_opts=image_opts, locker=tile_locker) layer = CacheMapLayer(tile_mgr, image_opts=default_image_opts) with pytest.raises(BlankImage): result = layer.get_map( MapQuery( (-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913), 'png')) assert mock_file_cache.stored_tiles == set() result = layer.get_map( MapQuery((0, 0, 10000, 10000), (50, 50), SRS(900913), 'png')) assert mock_file_cache.stored_tiles == \ set([(512, 257, 10), (513, 256, 10), (512, 256, 10), (513, 257, 10)]) assert result.size == (50, 50)
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) # 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, ex: raise RequestError('error while processing image file: %s' % ex, request=map_request)
def test_multiple_image_responses(self): error_handler = HTTPSourceErrorHandler() error_handler.add_handler(500, (255, 0, 0), cacheable=False) error_handler.add_handler(204, (255, 0, 127, 200), cacheable=True) self.source = TiledSource(self.grid, self.client, error_handler=error_handler) with mock_httpd( TEST_SERVER_ADDRESS, [ ( { "path": "/1/0/0.png" }, { "body": b"error", "status": 500, "headers": { "content-type": "text/plain" }, }, ), ( { "path": "/1/0/0.png" }, { "body": b"error", "status": 204, "headers": { "content-type": "text/plain" }, }, ), ], ): resp = self.source.get_map( MapQuery([-180, -90, 0, 90], (256, 256), SRS(4326), format="png")) assert not resp.cacheable assert resp.as_image().getcolors() == [((256 * 256), (255, 0, 0))] resp = self.source.get_map( MapQuery([-180, -90, 0, 90], (256, 256), SRS(4326), format="png")) assert resp.cacheable assert resp.as_image().getcolors() == [((256 * 256), (255, 0, 127, 200))]
def test_get_map_small_with_source_extent(self): self.source.extent = BBOXCoverage([0, 0, 90, 45], SRS(4326)).extent result = self.layer.get_map(MapQuery((-180, -90, 180, 90), (300, 150), SRS(4326), 'png')) eq_(self.file_cache.stored_tiles, set([(1, 0, 1)])) # source requests one tile (no meta-tiling configured) limited to source.extent eq_(self.client.requested, [((0, 0, 90, 45), (128, 64), (SRS(4326)))]) eq_(result.size, (300, 150))
def test_get_map_large(self): # gets next resolution layer result = self.layer.get_map(MapQuery((-180, -90, 180, 90), (600, 300), SRS(4326), 'png')) eq_(self.file_cache.stored_tiles, set([(0, 0, 2), (1, 0, 2), (0, 1, 2), (1, 1, 2), (2, 0, 2), (3, 0, 2), (2, 1, 2), (3, 1, 2)])) eq_(result.size, (600, 300))
def _create_single_tile(self, tile): tile_bbox = self.grid.tile_bbox(tile.coord) query = MapQuery(tile_bbox, self.grid.tile_size, self.grid.srs, self.tile_mgr.request_format, dimensions=self.dimensions) with self.tile_mgr.lock(tile): if not self.is_cached(tile): try: source = self._query_sources(query) # if source is not available, try to serve tile in cache except SourceError as e: if self.is_stale(tile): self.cache.load_tile(tile) else: reraise_exception(e, sys.exc_info()) if not source: return [] if source.authorize_stale and self.is_stale(tile): # The configuration authorises blank tiles generated by the error_handler # to be replaced by stale tiles from cache. self.cache.load_tile(tile) return [tile] if self.tile_mgr.image_opts != source.image_opts: # call as_buffer to force conversion into cache format source.as_buffer(self.tile_mgr.image_opts) source.image_opts = self.tile_mgr.image_opts tile.source = source tile.cacheable = source.cacheable tile = self.tile_mgr.apply_tile_filter(tile) if source.cacheable: self.cache.store_tile(tile) else: self.cache.load_tile(tile) return [tile]
def _get_transformed(self, query, format): dst_srs = query.srs src_srs = self._best_supported_srs(dst_srs) dst_bbox = query.bbox src_bbox = dst_srs.transform_bbox_to(src_srs, dst_bbox) src_width, src_height = src_bbox[2] - src_bbox[0], src_bbox[ 3] - src_bbox[1] ratio = src_width / src_height dst_size = query.size xres, yres = src_width / dst_size[0], src_height / dst_size[1] if xres < yres: src_size = dst_size[0], int(dst_size[0] / ratio + 0.5) else: src_size = int(dst_size[1] * ratio + 0.5), dst_size[1] src_query = MapQuery(src_bbox, src_size, src_srs, format, dimensions=query.dimensions) if self.coverage and not self.coverage.contains(src_bbox, src_srs): img = self._get_sub_query(src_query, format) else: resp = self.client.retrieve(src_query, format) img = ImageSource(resp, size=src_size, image_opts=self.image_opts) img = ImageTransformer(src_srs, dst_srs).transform(img, src_bbox, query.size, dst_bbox, self.image_opts) img.format = format return img
def test_basic_auth(self): http_client = HTTPClient(self.req_template.url, username='******', password='******') self.client.http_client = http_client def assert_auth(req_handler): assert 'Authorization' in req_handler.headers auth_data = req_handler.headers['Authorization'].split()[1] auth_data = base64.b64decode( auth_data.encode('utf-8')).decode('utf-8') eq_(auth_data, 'foo:bar@') return True expected_req = ({ 'path': r'/service?LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng' '&REQUEST=GetMap&HEIGHT=512&SRS=EPSG%3A4326' '&VERSION=1.1.1&BBOX=0.0,10.0,10.0,20.0&WIDTH=512&STYLES=', 'require_basic_auth': True, 'req_assert_function': assert_auth }, { 'body': b'no image', 'headers': { 'content-type': 'image/png' } }) with mock_httpd(TEST_SERVER_ADDRESS, [expected_req]): q = MapQuery((0.0, 10.0, 10.0, 20.0), (512, 512), SRS(4326)) self.source.get_map(q)
def test_get_map_large(self, layer, mock_file_cache): # gets next resolution layer result = layer.get_map(MapQuery((-180, -90, 180, 90), (600, 300), SRS(4326), 'png')) assert mock_file_cache.stored_tiles == \ set([(0, 0, 2), (1, 0, 2), (0, 1, 2), (1, 1, 2), (2, 0, 2), (3, 0, 2), (2, 1, 2), (3, 1, 2)]) assert result.size == (600, 300)
def test_no_image(self, caplog): try: with mock_httpd(TESTSERVER_ADDRESS, [({ 'path': '/service?map=foo&layers=foo&transparent=true&bbox=-200000,-200000,200000,200000&width=512&height=512&srs=EPSG%3A900913&format=image%2Fpng&request=GetMap&version=1.1.1&service=WMS&styles=' }, { 'status': '200', 'body': b'x' * 1000, 'headers': { 'content-type': 'application/foo' }, })]): req = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo', param={ 'layers': 'foo', 'transparent': 'true' }) query = MapQuery((-200000, -200000, 200000, 200000), (512, 512), SRS(900913), 'png') wms = WMSClient(req).retrieve(query, 'png') except SourceError: assert len(caplog.record_tuples) == 1 assert ( "'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' [output truncated]" in caplog.record_tuples[0][2]) else: assert False, 'expected no image returned error'
def _create_meta_tile(self, meta_tile): """ _create_meta_tile queries a single meta tile and splits it into tiles. """ tile_size = self.grid.tile_size query = MapQuery(meta_tile.bbox, meta_tile.size, self.grid.srs, self.tile_mgr.request_format, dimensions=self.dimensions) main_tile = Tile(meta_tile.main_tile_coord) with self.tile_mgr.lock(main_tile): if not all( self.is_cached(t) for t in meta_tile.tiles if t is not None): meta_tile_image = self._query_sources(query) if not meta_tile_image: return [] splitted_tiles = split_meta_tiles(meta_tile_image, meta_tile.tile_patterns, tile_size, self.tile_mgr.image_opts) splitted_tiles = [ self.tile_mgr.apply_tile_filter(t) for t in splitted_tiles ] if meta_tile_image.cacheable: self.cache.store_tiles(splitted_tiles) return splitted_tiles # else tiles = [Tile(coord) for coord in meta_tile.tiles] self.cache.load_tiles(tiles) return tiles
def test_get_map_small_with_source_extent(self, source, layer, mock_file_cache, mock_wms_client): source.extent = BBOXCoverage([0, 0, 90, 45], SRS(4326)).extent result = layer.get_map(MapQuery((-180, -90, 180, 90), (300, 150), SRS(4326), 'png')) assert mock_file_cache.stored_tiles == set([(1, 0, 1)]) # source requests one tile (no meta-tiling configured) limited to source.extent assert mock_wms_client.requested == [((0, 0, 90, 45), (128, 64), (SRS(4326)))] assert result.size == (300, 150)
def test_get_map(self, source, mock_http_client): source.get_map(MapQuery((-180, -90, 180, 90), (300, 150), SRS(4326))) assert query_eq( mock_http_client.requested[0], "http://localhost/service?" "layers=foo&width=300&version=1.1.1&bbox=-180,-90,180,90&service=WMS" "&format=image%2Fpng&styles=&srs=EPSG%3A4326&request=GetMap&height=150" )
def test_single_tile_no_match(self, layer): with pytest.raises(MapBBOXError): layer.get_map( MapQuery((0.1, 0, 90, 90), (256, 256), SRS(4326), 'png', tiled_only=True))
def test_get_map_transformed(self, source, mock_http_client): source.get_map(MapQuery( (556597, 4865942, 1669792, 7361866), (300, 150), SRS(900913))) assert wms_query_eq(mock_http_client.requested[0], "http://localhost/service?" "layers=foo&width=300&version=1.1.1" "&bbox=4.99999592195,39.9999980766,14.999996749,54.9999994175&service=WMS" "&format=image%2Fpng&styles=&srs=EPSG%3A4326&request=GetMap&height=450")
def _get_sub_query(self, query, format): size, offset, bbox = bbox_position_in_image(query.bbox, query.size, self.extent.bbox_for(query.srs)) if size[0] == 0 or size[1] == 0: raise BlankImage() src_query = MapQuery(bbox, size, query.srs, format) resp = self.client.retrieve(src_query, format) return SubImageSource(resp, size=query.size, offset=offset, image_opts=self.image_opts)
def test_transformed_request_transparent(self): self.req = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo', param={ 'layers': 'foo', 'transparent': 'true' }) self.wms = WMSClient(self.req, http_client=self.http) self.source = WMSSource(self.wms, supported_srs=[SRS(4326)], image_opts=ImageOptions(resampling='bilinear')) req = MapQuery((-200000, -200000, 200000, 200000), (512, 512), SRS(900913), 'png') resp = self.source.get_map(req) eq_(len(self.http.requested), 1) assert wms_query_eq( self.http.requested[0], TESTSERVER_URL + '/service?map=foo&LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng' '&REQUEST=GetMap&HEIGHT=512&SRS=EPSG%3A4326' '&VERSION=1.1.1&WIDTH=512&STYLES=&transparent=true' '&BBOX=-1.79663056824,-1.7963362121,1.79663056824,1.7963362121') img = resp.as_image() assert img.mode in ('P', 'RGBA') img = img.convert('RGBA') eq_(img.getpixel((5, 5))[3], 0)
def test_get_map_small(self): result = self.layer.get_map( MapQuery((-180, -90, 180, 90), (300, 150), SRS(4326), 'png')) eq_(self.file_cache.stored_tiles, set([(1, 0, 1)])) # source requests one tile (no meta-tiling configured) eq_(self.client.requested, [((0.0, -90.0, 180.0, 90.0), (256, 256), SRS('EPSG:4326'))]) eq_(result.size, (300, 150))
def test_transformed(self): result = self.layer.get_map(MapQuery( (-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913), 'png')) eq_(self.file_cache.stored_tiles, set([(0, 0, 2), (1, 0, 2), (0, 1, 2), (1, 1, 2), (2, 0, 2), (3, 0, 2), (2, 1, 2), (3, 1, 2)])) eq_(result.size, (500, 500))
def test_multiple_image_responses(self): error_handler = HTTPSourceErrorHandler() error_handler.add_handler(500, (255, 0, 0), cacheable=False) error_handler.add_handler(204, (255, 0, 127, 200), cacheable=True) self.source = TiledSource(self.grid, self.client, error_handler=error_handler) with mock_httpd(TEST_SERVER_ADDRESS, [ ({'path': '/1/0/0.png'}, {'body': b'error', 'status': 500, 'headers':{'content-type': 'text/plain'}}), ({'path': '/1/0/0.png'}, {'body': b'error', 'status': 204, 'headers':{'content-type': 'text/plain'}})]): resp = self.source.get_map(MapQuery([-180, -90, 0, 90], (256, 256), SRS(4326), format='png')) assert not resp.cacheable eq_(resp.as_image().getcolors(), [((256*256), (255, 0, 0))]) resp = self.source.get_map(MapQuery([-180, -90, 0, 90], (256, 256), SRS(4326), format='png')) assert resp.cacheable eq_(resp.as_image().getcolors(), [((256*256), (255, 0, 127, 200))])
def test_get_map_small(self, layer, mock_file_cache, mock_wms_client): result = layer.get_map( MapQuery((-180, -90, 180, 90), (300, 150), SRS(4326), 'png')) assert mock_file_cache.stored_tiles == set([(1, 0, 1)]) # source requests one tile (no meta-tiling configured) assert mock_wms_client.requested == [((0.0, -90.0, 180.0, 90.0), (256, 256), SRS('EPSG:4326'))] assert result.size == (300, 150)
def test_get_map_mercator(self): result = self.layer.get_map( MapQuery((-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913), 'png')) eq_(self.client.requested, [((-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913))]) eq_(result.size, (500, 500))
def test_get_map_mercator(self, layer, mock_wms_client): result = layer.get_map(MapQuery( (-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913), 'png')) assert mock_wms_client.requested == \ [((-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913))] assert result.size == (500, 500)
def test_request(self, source, mock_http_client): req = MapQuery((-180.0, -90.0, 180.0, 90.0), (512, 256), SRS(4326), 'png') source.get_map(req) assert len(mock_http_client.requested) == 1 assert_query_eq(mock_http_client.requested[0], TESTSERVER_URL+'/service?map=foo&LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng' '&REQUEST=GetMap&HEIGHT=256&SRS=EPSG%3A4326' '&VERSION=1.1.1&BBOX=-180.0,-90.0,180.0,90.0&WIDTH=512&STYLES=')
def test_transformed(self, layer, mock_file_cache): result = layer.get_map(MapQuery( (-20037508.34, -20037508.34, 20037508.34, 20037508.34), (500, 500), SRS(900913), 'png')) assert mock_file_cache.stored_tiles == \ set([(0, 0, 2), (1, 0, 2), (0, 1, 2), (1, 1, 2), (2, 0, 2), (3, 0, 2), (2, 1, 2), (3, 1, 2)]) assert result.size == (500, 500)
def test_single_tile_match(self, layer, mock_file_cache): result = layer.get_map( MapQuery((0.001, 0, 90, 90), (256, 256), SRS(4326), 'png', tiled_only=True)) assert mock_file_cache.stored_tiles == \ set([(3, 0, 2), (2, 0, 2), (3, 1, 2), (2, 1, 2)]) assert result.size == (256, 256)
def test_single_tile_match(self): result = self.layer.get_map( MapQuery((0.001, 0, 90, 90), (256, 256), SRS(4326), 'png', tiled_only=True)) eq_(self.file_cache.stored_tiles, set([(3, 0, 2), (2, 0, 2), (3, 1, 2), (2, 1, 2)])) eq_(result.size, (256, 256))
def test_transformed_request(self, source, mock_http_client): req = MapQuery((-200000, -200000, 200000, 200000), (512, 512), SRS(900913), 'png') resp = source.get_map(req) assert len(mock_http_client.requested) == 1 assert wms_query_eq(mock_http_client.requested[0], TESTSERVER_URL+'/service?map=foo&LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng' '&REQUEST=GetMap&HEIGHT=512&SRS=EPSG%3A4326' '&VERSION=1.1.1&WIDTH=512&STYLES=' '&BBOX=-1.79663056824,-1.7963362121,1.79663056824,1.7963362121') img = resp.as_image() assert img.mode in ('P', 'RGB')
def test_combine_different_url(self): req1 = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=bar', param={'layers':'foo', 'transparent': 'true'}) wms1 = WMSClient(req1, http_client=self.http) req2 = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo', param={'layers':'bar', 'transparent': 'true'}) wms2 = WMSClient(req2, http_client=self.http) req = MapQuery((-200000, -200000, 200000, 200000), (512, 512), SRS(900913), 'png') combined = wms1.combined_client(wms2, req) assert combined is None
def test_get_map(self, source): with tmp_image((512, 512)) as img: expected_req = ({'path': r'/service?LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng' '&REQUEST=GetMap&HEIGHT=512&SRS=EPSG%3A4326&styles=' '&VERSION=1.1.1&BBOX=0.0,10.0,10.0,20.0&WIDTH=512'}, {'body': img.read(), 'headers': {'content-type': 'image/png'}}) with mock_httpd(TEST_SERVER_ADDRESS, [expected_req]): q = MapQuery((0.0, 10.0, 10.0, 20.0), (512, 512), SRS(4326)) result = source.get_map(q) assert isinstance(result, ImageSource) assert result.size == (512, 512) assert is_png(result.as_buffer(seekable=True)) assert result.as_image().size == (512, 512)
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
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