Exemplo n.º 1
0
def transform_bbox():
    source = SRS(request.json.get('source'))
    dest = SRS(request.json.get('dest'))
    bbox = source.align_bbox(request.json.get('bbox'))

    if grid.is_valid_transformation(bbox, source, dest):
        transformed_bbox = source.transform_bbox_to(dest, bbox)
        return {'bbox': transformed_bbox}
    else:
        response.status = 400
        return {'error': 'Could not transform bbox'}
Exemplo n.º 2
0
class TestTransform(object):
    def setup(self):
        self.src_img = ImageSource(create_debug_img((200, 200), transparent=False))
        self.src_srs = SRS(31467)
        self.dst_size = (100, 150)
        self.dst_srs = SRS(4326)
        self.dst_bbox = (0.2, 45.1, 8.3, 53.2)
        self.src_bbox = self.dst_srs.transform_bbox_to(self.src_srs, self.dst_bbox)
    def test_transform(self, mesh_div=4):
        transformer = ImageTransformer(self.src_srs, self.dst_srs, mesh_div=mesh_div)
        result = transformer.transform(self.src_img, self.src_bbox, self.dst_size, self.dst_bbox,
            image_opts=ImageOptions(resampling='nearest'))
        assert isinstance(result, ImageSource)
        assert result.as_image() != self.src_img
        assert result.size == (100, 150)
    
    def _test_compare_mesh_div(self):
        """
        Create transformations with different div values.
        """
        for div in [1, 2, 4, 6, 8, 12, 16]:
            transformer = ImageTransformer(self.src_srs, self.dst_srs, mesh_div=div)
            result = transformer.transform(self.src_img, self.src_bbox,
                                           self.dst_size, self.dst_bbox)
            result.as_image().save('/tmp/transform-%d.png' % (div,))
Exemplo n.º 3
0
 def setup(self):
     self.src_img = ImageSource(create_debug_img((200, 200), transparent=False))
     self.src_srs = SRS(31467)
     self.dst_size = (100, 150)
     self.dst_srs = SRS(4326)
     self.dst_bbox = (0.2, 45.1, 8.3, 53.2)
     self.src_bbox = self.dst_srs.transform_bbox_to(self.src_srs, self.dst_bbox)
Exemplo n.º 4
0
    def __init__(self, request_bbox=[], grid_bbox=[], level=None,
                 grid_srs=None, grid_bbox_srs=None, map_srs=None, res=[],
                 scales=[], origin='ll', units='m', dpi=None):

        self.grid_srs = SRS(grid_srs) if grid_srs else None
        self.grid_bbox_srs = SRS(grid_bbox_srs) if grid_bbox_srs else None
        self.map_srs = SRS(map_srs) if map_srs else None
        self.request_bbox = map(float, request_bbox) if request_bbox else None
        self.origin = origin
        self._res = list(map(float, res)) if res else None
        self._scales = list(map(float, scales)) if scales else None
        self._units = 1 if units == 'm' else constants.UNIT_FACTOR
        self._dpi = float(dpi) if dpi else constants.OGC_DPI

        _grid_bbox = list(map(float, grid_bbox)) if grid_bbox else None
        self.grid_bbox = self.transform_grid_bbox(_grid_bbox)

        if self._res:
            self._num_levels = len(self._res)
        elif self._scales:
            self._num_levels = len(self._scales)
        else:
            self._num_levels = None

        try:
            self.level = int(level)
        except TypeError:
            self.level = None
        if self.grid_srs:
            self.tilegrid = tile_grid(srs=self.grid_srs,
                                      bbox=_grid_bbox,
                                      bbox_srs=self.grid_bbox_srs,
                                      origin=self.origin,
                                      res=self.res,
                                      num_levels=self._num_levels)
            self.validate_tile_bbox_for_level_0()
        else:
            self.tilegrid = None
Exemplo n.º 5
0
    def test_geotiff_tags(
        self,
        tmpdir,
        srs,
        bbox,
        size,
        expected_pixel_res,
        expected_origin,
        projected,
        compression,
    ):
        img = ImageSource(create_debug_img(size),
                          georef=GeoReference(bbox=bbox, srs=SRS(srs)))
        fname = os.path.join(str(tmpdir), 'geo.tiff')

        img_opts = ImageOptions(
            format='tiff', encoding_options={'tiff_compression': compression})
        img2 = ImageSource(img.as_buffer(img_opts)).as_image()

        assert_geotiff_tags(img2, expected_origin, expected_pixel_res, srs,
                            projected)
Exemplo n.º 6
0
 def test_get_map_non_image_content_type(self):
     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': 'text/plain'
             }
         })
         with mock_httpd(TEST_SERVER_ADDRESS, [expected_req]):
             q = MapQuery((0.0, 10.0, 10.0, 20.0), (512, 512), SRS(4326))
             try:
                 self.source.get_map(q)
             except SourceError, e:
                 assert 'no image returned' in e.args[0]
             else:
                 assert False, 'no SourceError raised'
Exemplo n.º 7
0
 def test_meter(self):
     res_range = ResolutionRange(1000, 10)
     assert not res_range.contains([0, 0, 100000, 100000],
                                   (10, 10), SRS(900913))
     assert not res_range.contains([0, 0, 100000, 100000],
                                   (99, 99), SRS(900913))
     # min is exclusive but there is a delta
     assert res_range.contains([0, 0, 100000, 100000], (100, 100),
                               SRS(900913))
     assert res_range.contains([0, 0, 100000, 100000], (1000, 1000),
                               SRS(900913))
     # max is inclusive
     assert res_range.contains([0, 0, 100000, 100000], (10000, 10000),
                               SRS(900913))
     assert not res_range.contains([0, 0, 100000, 100000],
                                   (10001, 10001), SRS(900913))
Exemplo n.º 8
0
class TestTransform(object):
    def setup(self):
        self.src_img = ImageSource(
            create_debug_img((200, 200), transparent=False))
        self.src_srs = SRS(31467)
        self.dst_size = (100, 150)
        self.dst_srs = SRS(4326)
        self.dst_bbox = (0.2, 45.1, 8.3, 53.2)
        self.src_bbox = self.dst_srs.transform_bbox_to(self.src_srs,
                                                       self.dst_bbox)

    def test_transform(self):
        transformer = ImageTransformer(self.src_srs, self.dst_srs)
        result = transformer.transform(
            self.src_img,
            self.src_bbox,
            self.dst_size,
            self.dst_bbox,
            image_opts=ImageOptions(resampling="nearest"),
        )
        assert isinstance(result, ImageSource)
        assert result.as_image() != self.src_img.as_image()
        assert result.size == (100, 150)

    def _test_compare_max_px_err(self):
        """
        Create transformations with different div values.
        """
        for err in [0.2, 0.5, 1, 2, 4, 6, 8, 12, 16]:
            transformer = ImageTransformer(self.src_srs,
                                           self.dst_srs,
                                           max_px_err=err)
            result = transformer.transform(
                self.src_img,
                self.src_bbox,
                self.dst_size,
                self.dst_bbox,
                image_opts=ImageOptions(resampling="nearest"),
            )
            result.as_image().save("/tmp/transform-%03d.png" % (err * 10, ))
Exemplo n.º 9
0
    def test_http_error_handler(self, client):
        error_handler = HTTPSourceErrorHandler()
        error_handler.add_handler(500, (255, 0, 0), cacheable=True)
        error_handler.add_handler(400, (0, 0, 0), cacheable=False)
        source = WMSSource(client, error_handler=error_handler)
        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='
                },
                {
                    'body': b'error',
                    'status': 500,
                    'headers': {'content-type': 'text/plain'},
                },
            ),
            (
                {
                    '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='
                },
                {
                    'body': b'error',
                    'status': 400,
                    'headers': {'content-type': 'text/plain'},
                },
            ),
        ]
        with mock_httpd(TEST_SERVER_ADDRESS, expected_req):
            query = MapQuery((0.0, 10.0, 10.0, 20.0), (512, 512), SRS(4326))
            resp = source.get_map(query)
            assert resp.cacheable
            assert resp.as_image().getcolors() == [((512 * 512), (255, 0, 0))]

            resp = source.get_map(query)
            assert not resp.cacheable
            assert resp.as_image().getcolors() == [((512 * 512), (0, 0, 0))]
Exemplo n.º 10
0
    def test_image_response(self):
        error_handler = HTTPSourceErrorHandler()
        error_handler.add_handler(500, (255, 0, 0), cacheable=False)
        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'
                }
        })]):
            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))])
Exemplo n.º 11
0
class TestTransform(object):
    def setup(self):
        self.src_img = ImageSource(
            create_debug_img((200, 200), transparent=False))
        self.src_srs = SRS(31467)
        self.dst_size = (100, 150)
        self.dst_srs = SRS(4326)
        self.dst_bbox = (0.2, 45.1, 8.3, 53.2)
        self.src_bbox = self.dst_srs.transform_bbox_to(self.src_srs,
                                                       self.dst_bbox)

    def test_transform(self, mesh_div=4):
        transformer = ImageTransformer(self.src_srs,
                                       self.dst_srs,
                                       mesh_div=mesh_div)
        result = transformer.transform(
            self.src_img,
            self.src_bbox,
            self.dst_size,
            self.dst_bbox,
            image_opts=ImageOptions(resampling='nearest'))
        assert isinstance(result, ImageSource)
        assert result.as_image() != self.src_img.as_image()
        assert result.size == (100, 150)

    def _test_compare_mesh_div(self):
        """
        Create transformations with different div values.
        """
        for div in [1, 2, 4, 6, 8, 12, 16]:
            transformer = ImageTransformer(self.src_srs,
                                           self.dst_srs,
                                           mesh_div=div)
            result = transformer.transform(self.src_img, self.src_bbox,
                                           self.dst_size, self.dst_bbox)
            result.as_image().save('/tmp/transform-%d.png' % (div, ))
Exemplo n.º 12
0
    def doc(self, tile, grid):
        doc = {}
        x, y, z = tile.coord
        for key, value in iteritems(self.attributes):
            if not isinstance(value, string_type) or not value.startswith('{{'):
                doc[key] = value
                continue

            if value == '{{timestamp}}':
                doc[key] = time.time()
            elif value == '{{x}}':
                doc[key] = x
            elif value == '{{y}}':
                doc[key] = y
            elif value in ('{{z}}', '{{level}}'):
                doc[key] = z
            elif value == '{{utc_iso}}':
                doc[key] = utc_now_isoformat()
            elif value == '{{wgs_tile_centroid}}':
                tile_bbox = grid.tile_bbox(tile.coord)
                centroid = (
                    tile_bbox[0] + (tile_bbox[2]-tile_bbox[0])/2,
                    tile_bbox[1] + (tile_bbox[3]-tile_bbox[1])/2
                )
                centroid = grid.srs.transform_to(SRS(4326), centroid)
                doc[key] = centroid
            elif value == '{{tile_centroid}}':
                tile_bbox = grid.tile_bbox(tile.coord)
                centroid = (
                    tile_bbox[0] + (tile_bbox[2]-tile_bbox[0])/2,
                    tile_bbox[1] + (tile_bbox[3]-tile_bbox[1])/2
                )
                doc[key] = centroid
            else:
                raise ValueError('unknown CouchDB tile_metadata value: %r' % (value, ))
        return doc
Exemplo n.º 13
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")
Exemplo n.º 14
0
 def test_get_map(self, layer, mock_wms_client):
     result = layer.get_map(MapQuery((-180, -90, 180, 90), (300, 150), SRS(4326), 'png'))
     assert mock_wms_client.requested == [((-180, -90, 180, 90), (300, 150), SRS(4326))]
     assert result.size == (300, 150)
Exemplo n.º 15
0
class ConfigGeoJSONGrid(object):

    def __init__(self, request_bbox=[], grid_bbox=[], level=None,
                 grid_srs=None, grid_bbox_srs=None, map_srs=None, res=[],
                 scales=[], origin='ll', units='m', dpi=None):

        self.grid_srs = SRS(grid_srs) if grid_srs else None
        self.grid_bbox_srs = SRS(grid_bbox_srs) if grid_bbox_srs else None
        self.map_srs = SRS(map_srs) if map_srs else None
        self.request_bbox = map(float, request_bbox) if request_bbox else None
        self.origin = origin
        self._res = list(map(float, res)) if res else None
        self._scales = list(map(float, scales)) if scales else None
        self._units = 1 if units == 'm' else constants.UNIT_FACTOR
        self._dpi = float(dpi) if dpi else constants.OGC_DPI

        _grid_bbox = list(map(float, grid_bbox)) if grid_bbox else None
        self.grid_bbox = self.transform_grid_bbox(_grid_bbox)

        if self._res:
            self._num_levels = len(self._res)
        elif self._scales:
            self._num_levels = len(self._scales)
        else:
            self._num_levels = None

        try:
            self.level = int(level)
        except TypeError:
            self.level = None
        if self.grid_srs:
            self.tilegrid = tile_grid(srs=self.grid_srs,
                                      bbox=_grid_bbox,
                                      bbox_srs=self.grid_bbox_srs,
                                      origin=self.origin,
                                      res=self.res,
                                      num_levels=self._num_levels)
            self.validate_tile_bbox_for_level_0()
        else:
            self.tilegrid = None

    def transform_grid_bbox(self, _grid_bbox=None):
        if not _grid_bbox:
            return None
        if self.grid_bbox_srs:
            _grid_bbox = self.grid_bbox_srs.align_bbox(_grid_bbox)
            if self.grid_srs:
                if is_valid_transformation(_grid_bbox, self.grid_bbox_srs, self.grid_srs):
                    return self.grid_bbox_srs.transform_bbox_to(self.grid_srs, _grid_bbox)
                else:
                    raise InvalidGridBBoxTransformationException(
                        'Invalid transformation for grid_bbox')
        return _grid_bbox if _grid_bbox else self._grid_bbox

    def validate_tile_bbox_for_level_0(self):
        tile_bbox = self.tilegrid.tile_bbox((0, 0, 0))
        if not is_valid_transformation(tile_bbox, self.grid_srs, self.map_srs):
            raise InvalidTileBBoxTransformationException(
                'Invalid transformation for tile in level 0')

    @property
    def res(self):
        if not self._res:
            if not self._scales:
                return None
            return [scale_to_res(scale, self._dpi, self._units) for scale in self._scales]
        return self._res

    @property
    def map_bbox(self):
        if not self.map_srs or not self.grid_srs:
            return None

        if self.map_srs == 'EPSG:4326':
            self.request_bbox = self.map_srs.align_bbox(self.request_bbox)
        else:
            (minx, miny, maxx, maxy) = self.request_bbox
            self.request_bbox = minx, miny, maxx, maxy

        if not is_valid_transformation(self.request_bbox, self.map_srs, self.grid_srs):
            return None

        temp = self.map_srs.transform_bbox_to(self.grid_srs, self.request_bbox)
        return temp

    @property
    def view_bbox(self):
        gridbbox = self.grid_bbox if self.grid_bbox else self.tilegrid.bbox()
        mapbbox = self.map_bbox
        if not mapbbox:
            return gridbbox
        return [
            max(gridbbox[0], mapbbox[0]),
            max(gridbbox[1], mapbbox[1]),
            min(gridbbox[2], mapbbox[2]),
            min(gridbbox[3], mapbbox[3])
        ]

    @property
    def scales(self):
        return [res_to_scale(res, self._dpi, self._units) for res in self.tilegrid.resolutions]
Exemplo n.º 16
0
def test_srs_conditional_layers():
    l4326 = MockLayer()
    l3857 = MockLayer()
    l25832 = MockLayer()
    preferred = PreferredSrcSRS()
    preferred.add(SRS(31467), [SRS(25832), SRS(3857)])
    layer = SRSConditional([
        (l4326, SRS(4326)),
        (l3857, SRS(3857)),
        (l25832, SRS(25832)),
    ], GLOBAL_GEOGRAPHIC_EXTENT, preferred_srs=preferred,
    )

    # srs match
    assert layer._select_layer(SRS(4326)) == l4326
    assert layer._select_layer(SRS(3857)) == l3857
    assert layer._select_layer(SRS(25832)) == l25832
    # type match (projected)
    assert layer._select_layer(SRS(31466)) == l3857
    assert layer._select_layer(SRS(32633)) == l3857
    assert layer._select_layer(SRS(4258)) == l4326
    # preferred
    assert layer._select_layer(SRS(31467)) == l25832
Exemplo n.º 17
0
 def setup(self):
     self.grid = TileGrid(SRS(4326), bbox=[-180, -90, 180, 90])
     self.client = MockTileClient()
     self.source = TiledSource(self.grid, self.client)
Exemplo n.º 18
0
 def test_get_single(self, tile_mgr, file_cache, slow_source):
     tile_mgr.creator().create_tiles([Tile((0, 0, 1)), Tile((1, 0, 1))])
     assert file_cache.stored_tiles == set([(0, 0, 1), (1, 0, 1)])
     assert slow_source.requested == \
         [((-180.0, -90.0, 180.0, 90.0), (512, 256), SRS(4326))]
Exemplo n.º 19
0
 def test_create_tile_multiple_fragmented(self, tile_mgr, mock_file_cache, mock_wms_client):
     tile_mgr.creator().create_tiles([Tile((4, 0, 3)), Tile((5, 2, 3))])
     assert mock_file_cache.stored_tiles == \
         set([(4, 0, 3), (4, 1, 3), (4, 2, 3), (5, 0, 3), (5, 1, 3), (5, 2, 3)])
     assert sorted(mock_wms_client.requested) == \
         [((-1.7578125, -90, 91.7578125, 46.7578125), (532, 778), SRS(4326))]
Exemplo n.º 20
0
 def test_create_tile(self, tile_mgr, mock_file_cache, mock_wms_client):
     tile_mgr.creator().create_tiles([Tile((0, 0, 2))])
     assert mock_file_cache.stored_tiles == \
         set([(0, 0, 2), (1, 0, 2), (0, 1, 2), (1, 1, 2)])
     assert sorted(mock_wms_client.requested) == \
         [((-180.0, -90.0, 0.0, 90.0), (512, 512), SRS(4326))]
Exemplo n.º 21
0
 def test_create_tile_first_level(self, tile_mgr, mock_file_cache, mock_wms_client):
     tile_mgr.creator().create_tiles([Tile((0, 0, 1)), Tile((1, 0, 1))])
     assert mock_file_cache.stored_tiles == set([(0, 0, 1), (1, 0, 1)])
     assert mock_wms_client.requested == \
         [((-180.0, -90.0, 180.0, 90.0), (512, 256), SRS(4326))]
Exemplo n.º 22
0
 def test_create_tile(self, tile_mgr, mock_file_cache, mock_source):
     tile_mgr.creator().create_tiles([Tile((0, 0, 1)), Tile((1, 0, 1))])
     assert mock_file_cache.stored_tiles == set([(0, 0, 1), (1, 0, 1)])
     assert sorted(mock_source.requested) == \
         [((-180.0, -90.0, 0.0, 90.0), (256, 256), SRS(4326)),
          ((0.0, -90.0, 180.0, 90.0), (256, 256), SRS(4326))]
Exemplo n.º 23
0
 def tile_mgr(self, file_cache, tile_locker):
     grid = TileGrid(SRS(4326), bbox=[-180, -90, 180, 90])
     client = MockTileClient()
     source = TiledSource(grid, client)
     tile_mgr = TileManager(grid, file_cache, [source], 'png', locker=tile_locker)
     return tile_mgr
Exemplo n.º 24
0
 def source(self, mock_http_client):
     req = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo', param={'layers':'foo'})
     wms = WMSClient(req, http_client=mock_http_client)
     return WMSSource(wms, supported_srs=SupportedSRS([SRS(4326)]),
         image_opts=ImageOptions(resampling='bilinear'))
Exemplo n.º 25
0
 def test_get_map_small(self, layer, mock_file_cache):
     result = layer.get_map(MapQuery((-180, -90, 180, 90), (300, 150), SRS(4326), 'png'))
     assert mock_file_cache.stored_tiles == set([(0, 0, 1), (1, 0, 1)])
     assert result.size == (300, 150)
Exemplo n.º 26
0
 def test_match(self):
     self.source.get_map(MapQuery([-180, -90, 0, 90], (256, 256), SRS(4326)))
     self.source.get_map(MapQuery([0, -90, 180, 90], (256, 256), SRS(4326)))
     assert self.client.requested_tiles == [(0, 0, 1), (1, 0, 1)]
Exemplo n.º 27
0
    def __init__(self,
                 srs=900913,
                 bbox=None,
                 tile_size=(256, 256),
                 res=None,
                 threshold_res=None,
                 is_geodetic=False,
                 levels=None,
                 stretch_factor=1.15,
                 max_shrink_factor=4.0,
                 origin='ll',
                 name=None):
        """
        :param stretch_factor: allow images to be scaled up by this factor
            before the next level will be selected
        :param max_shrink_factor: allow images to be scaled down by this
            factor before NoTiles is raised

        >>> grid = TileGrid(srs=900913)
        >>> [round(x, 2) for x in grid.bbox]
        [-20037508.34, -20037508.34, 20037508.34, 20037508.34]
        """
        if isinstance(srs, (int, basestring)):
            srs = SRS(srs)
        self.srs = srs
        self.tile_size = tile_size
        self.origin = origin_from_string(origin)
        self.name = name

        if self.origin == 'ul':
            self.flipped_y_axis = True

        self.is_geodetic = is_geodetic

        self.stretch_factor = stretch_factor
        self.max_shrink_factor = max_shrink_factor

        if levels is None:
            self.levels = 20
        else:
            self.levels = levels

        if bbox is None:
            bbox = self._calc_bbox()
        self.bbox = bbox

        factor = None

        if res is None:
            factor = 2.0
            res = self._calc_res(factor=factor)
        elif res == 'sqrt2':
            if levels is None:
                self.levels = 40
            factor = math.sqrt(2)
            res = self._calc_res(factor=factor)
        elif is_float(res):
            factor = float(res)
            res = self._calc_res(factor=factor)

        self.levels = len(res)
        self.resolutions = NamedGridList(res)
        self.threshold_res = threshold_res

        self.grid_sizes = self._calc_grids()
Exemplo n.º 28
0
def grid_bbox(bbox, bbox_srs, srs):
    bbox = bbox_tuple(bbox)
    if bbox_srs:
        bbox = SRS(bbox_srs).transform_bbox_to(srs, bbox)
    return bbox
Exemplo n.º 29
0
    def featureinfo(self, request):
        infos = []
        self.check_featureinfo_request(request)

        p = request.params
        query = InfoQuery(p.bbox,
                          p.size,
                          SRS(p.srs),
                          p.pos,
                          p['info_format'],
                          format=request.params.format or None,
                          feature_count=p.get('feature_count'))

        actual_layers = odict()

        for layer_name in request.params.query_layers:
            layer = self.layers[layer_name]
            if not layer.queryable:
                raise RequestError('layer %s is not queryable' % layer_name,
                                   request=request)
            for layer_name, info_layers in layer.info_layers_for_query(query):
                actual_layers[layer_name] = info_layers

        authorized_layers, coverage = self.authorized_layers(
            'featureinfo',
            actual_layers.keys(),
            request.http.environ,
            query_extent=(query.srs.srs_code, query.bbox))
        self.filter_actual_layers(actual_layers, request.params.layers,
                                  authorized_layers)

        # outside of auth-coverage
        if coverage and not coverage.contains(query.coord, query.srs):
            infos = []
        else:
            info_layers = []
            for layers in actual_layers.values():
                info_layers.extend(layers)

            for layer in info_layers:
                info = layer.get_info(query)
                if info is None:
                    continue
                infos.append(info)

        mimetype = None
        if 'info_format' in request.params:
            mimetype = request.params.info_format

        if not infos:
            return Response('', mimetype=mimetype)

        if self.fi_transformers:
            doc = infos[0].combine(infos)
            if doc.info_type == 'text':
                resp = doc.as_string()
                mimetype = 'text/plain'
            else:
                if not mimetype:
                    if 'xml' in self.fi_transformers:
                        info_type = 'xml'
                    elif 'html' in self.fi_transformers:
                        info_type = 'html'
                    else:
                        info_type = 'text'
                    mimetype = mimetype_from_infotype(request.version,
                                                      info_type)
                else:
                    info_type = infotype_from_mimetype(request.version,
                                                       mimetype)
                resp = self.fi_transformers[info_type](doc).as_string()
        else:
            mimetype = mimetype_from_infotype(request.version,
                                              infos[0].info_type)
            if len(infos) > 1:
                resp = infos[0].combine(infos).as_string()
            else:
                resp = infos[0].as_string()

        return Response(resp, mimetype=mimetype)
Exemplo n.º 30
0
def mask_image(img, bbox, bbox_srs, coverage):
    geom = mask_polygons(bbox, SRS(bbox_srs), coverage)
    mask = image_mask_from_geom(img, bbox, geom)
    img = img.convert('RGBA')
    img.paste((255, 255, 255, 0), (0, 0), mask)
    return img
Exemplo n.º 31
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)
         )
Exemplo 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
Exemplo n.º 33
0
 def test_get_outside_extent(self, layer):
     with pytest.raises(BlankImage):
         layer.get_map(MapQuery((-180, -90, 0, 0), (300, 150), SRS(4326), 'png'))
Exemplo n.º 34
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)
Exemplo n.º 35
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)