Esempio n. 1
0
    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))
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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))]
Esempio n. 5
0
 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))
Esempio n. 6
0
 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))
Esempio n. 7
0
 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]
Esempio n. 8
0
    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
Esempio n. 9
0
    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)
Esempio n. 10
0
 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)
Esempio n. 11
0
 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'
Esempio n. 12
0
 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
Esempio n. 13
0
 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)
Esempio n. 14
0
 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"
     )
Esempio n. 15
0
 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))
Esempio n. 16
0
 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")
Esempio n. 17
0
 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)
Esempio n. 18
0
    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)
Esempio n. 19
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))
Esempio n. 20
0
 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))
Esempio n. 21
0
    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))])
Esempio n. 22
0
 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)
Esempio n. 23
0
 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))
Esempio n. 24
0
 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)
Esempio n. 25
0
 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=')
Esempio n. 26
0
 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)
Esempio n. 27
0
 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)
Esempio n. 28
0
 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))
Esempio n. 29
0
    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')
Esempio n. 30
0
    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
Esempio n. 31
0
 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)
Esempio n. 32
0
    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
Esempio n. 33
0
    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