Exemplo n.º 1
0
    def __init__(self,
                 client,
                 image_opts=None,
                 coverage=None,
                 res_range=None,
                 transparent_color=None,
                 transparent_color_tolerance=None,
                 supported_srs=None,
                 supported_formats=None,
                 fwd_req_params=None):
        MapLayer.__init__(self, image_opts=image_opts)
        self.client = client
        self.supported_srs = supported_srs or []
        self.supported_formats = supported_formats or []
        self.fwd_req_params = fwd_req_params or set()

        self.transparent_color = transparent_color
        self.transparent_color_tolerance = transparent_color_tolerance
        if self.transparent_color:
            self.image_opts.transparent = True
        self.coverage = coverage
        self.res_range = res_range
        if self.coverage:
            self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
        else:
            self.extent = DefaultMapExtent()
Exemplo n.º 2
0
 def test_unsupported(self):
     assert (
         limit_srs_extents(
             {"EPSG:9999": DefaultMapExtent()}, ["EPSG:4326", "EPSG:3857"]
         )
         == {}
     )
Exemplo n.º 3
0
 def test_limited_unsupported(self):
     assert limit_srs_extents(
         {
             "EPSG:9999": DefaultMapExtent(),
             "EPSG:4326": MapExtent([0, 0, 10, 10], SRS(4326)),
         },
         ["EPSG:4326", "EPSG:3857"],
     ) == {"EPSG:4326": MapExtent([0, 0, 10, 10], SRS(4326))}
Exemplo n.º 4
0
 def test_limited_unsupported(self):
     eq_(
         limit_srs_extents(
             {
                 'EPSG:9999': DefaultMapExtent(),
                 'EPSG:4326': MapExtent([0, 0, 10, 10], SRS(4326))
             }, ['EPSG:4326', 'EPSG:3857']), {
                 'EPSG:4326': MapExtent([0, 0, 10, 10], SRS(4326)),
             })
Exemplo n.º 5
0
    def __init__(self, client, image_opts=None, coverage=None, res_range=None,
                 transparent_color=None, transparent_color_tolerance=None,
                 supported_srs=None, supported_formats=None, fwd_req_params=None):
        MapLayer.__init__(self, image_opts=image_opts)
        self.client = client
        self.supported_srs = supported_srs or []
        self.supported_formats = supported_formats or []
        self.fwd_req_params = fwd_req_params or set()

        self.transparent_color = transparent_color
        self.transparent_color_tolerance = transparent_color_tolerance
        if self.transparent_color:
            self.image_opts.transparent = True
        self.coverage = coverage
        self.res_range = res_range
        if self.coverage:
            self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
        else:
            self.extent = DefaultMapExtent()
Exemplo n.º 6
0
    def test_intersection(self):
        assert (DefaultMapExtent().intersection(MapExtent((0, 0, 10, 10), SRS(4326)))
            == MapExtent((0, 0, 10, 10), SRS(4326)))

        assert (MapExtent((0, 0, 10, 10), SRS(4326)).intersection(MapExtent((20, 20, 30, 30), SRS(4326)))
            == None)

        sub = MapExtent((0, 0, 10, 10), SRS(4326)).intersection(MapExtent((-1000, -1000, 100000, 100000), SRS(3857)))
        bbox = SRS(3857).transform_bbox_to(SRS(4326), (0, 0, 100000, 100000), 0)
        assert bbox_equals(bbox, sub.bbox)
Exemplo n.º 7
0
 def __init__(self, mapfile, layers=None, image_opts=None, coverage=None, res_range=None, lock=None):
     Source.__init__(self, image_opts=image_opts)
     self.mapfile = mapfile
     self.coverage = coverage
     self.res_range = res_range
     self.layers = set(layers) if layers else None
     self.lock = lock
     if self.coverage:
         self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
     else:
         self.extent = DefaultMapExtent()
Exemplo n.º 8
0
 def __init__(self, mapfile, layers=None, image_opts=None, coverage=None,
     res_range=None, lock=None, reuse_map_objects=False):
     MapLayer.__init__(self, image_opts=image_opts)
     self.mapfile = mapfile
     self.coverage = coverage
     self.res_range = res_range
     self.layers = set(layers) if layers else None
     self.lock = lock
     self._map_objs = {}
     self._map_objs_lock = threading.Lock()
     self._cache_map_obj = reuse_map_objects
     if self.coverage:
         self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
     else:
         self.extent = DefaultMapExtent()
Exemplo n.º 9
0
class DummyLayer(MapLayer):
    transparent = True
    extent = DefaultMapExtent()
    has_legend = False
    queryable = False
    def __init__(self, name):
        MapLayer.__init__(self)
        self.name = name
        self.requested = False
        self.queried = False
    def get_map(self, query):
        self.requested = True
    def get_info(self, query):
        self.queried = True
    def map_layers_for_query(self, query):
        return [(self.name, self)]
    def info_layers_for_query(self, query):
        return [(self.name, self)]
Exemplo n.º 10
0
 def __init__(self,
              mapfile,
              layers=None,
              image_opts=None,
              coverage=None,
              res_range=None,
              lock=None,
              reuse_map_objects=None,
              scale_factor=None):
     MapLayer.__init__(self, image_opts=image_opts)
     self.mapfile = mapfile
     self.coverage = coverage
     self.res_range = res_range
     self.layers = set(layers) if layers else None
     self.scale_factor = scale_factor
     self.lock = lock
     self._map_holder = threading.local()
     self._map_holder.__dict__.setdefault('map', None)
     if self.coverage:
         self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
     else:
         self.extent = DefaultMapExtent()
     # initialize map object
     self.map_obj()
Exemplo n.º 11
0
 def __init__(self):
     MapLayer.__init__(self)
     self.extent = DefaultMapExtent()
     self.res_range = None
Exemplo n.º 12
0
 def test_unsupported(self):
     eq_(
         limit_srs_extents({'EPSG:9999': DefaultMapExtent()},
                           ['EPSG:4326', 'EPSG:3857']), {})
Exemplo n.º 13
0
 def test_defaults(self):
     eq_(limit_srs_extents({}, ['EPSG:4326', 'EPSG:3857']), {
         'EPSG:4326': DefaultMapExtent(),
         'EPSG:3857': DefaultMapExtent(),
     })
Exemplo n.º 14
0
 def test_defaults(self):
     assert limit_srs_extents({}, ["EPSG:4326", "EPSG:3857"]) == {
         "EPSG:4326": DefaultMapExtent(),
         "EPSG:3857": DefaultMapExtent(),
     }
Exemplo n.º 15
0
 def __init__(self):
     Source.__init__(self)
     self.extent = DefaultMapExtent()
     self.transparent = True
     self.res_range = None
Exemplo n.º 16
0
 def __init__(self, coverage=None):
     MapLayer.__init__(self)
     self.extent = MapExtent((-180, -90, 180, 90), SRS(4326))
     self.extent = MapExtent(coverage.bbox, coverage.srs) if coverage else DefaultMapExtent()
Exemplo n.º 17
0
class WMSSource(MapLayer):
    supports_meta_tiles = True

    def __init__(self,
                 client,
                 image_opts=None,
                 coverage=None,
                 res_range=None,
                 transparent_color=None,
                 transparent_color_tolerance=None,
                 supported_srs=None,
                 supported_formats=None,
                 fwd_req_params=None):
        MapLayer.__init__(self, image_opts=image_opts)
        self.client = client
        self.supported_srs = supported_srs or []
        self.supported_formats = supported_formats or []
        self.fwd_req_params = fwd_req_params or set()

        self.transparent_color = transparent_color
        self.transparent_color_tolerance = transparent_color_tolerance
        if self.transparent_color:
            self.image_opts.transparent = True
        self.coverage = coverage
        self.res_range = res_range
        if self.coverage:
            self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
        else:
            self.extent = DefaultMapExtent()

    def is_opaque(self, query):
        """
        Returns true if we are sure that the image is not transparent.
        """
        if self.res_range and not self.res_range.contains(
                query.bbox, query.size, query.srs):
            return False

        if self.image_opts.transparent:
            return False

        if self.opacity is not None and (0.0 < self.opacity < 0.99):
            return False

        if not self.coverage:
            # not transparent and no coverage
            return True

        if self.coverage.contains(query.bbox, query.srs):
            # not transparent and completely inside coverage
            return True

        return False

    def get_map(self, query):
        if self.res_range and not self.res_range.contains(
                query.bbox, query.size, query.srs):
            raise BlankImage()
        if self.coverage and not self.coverage.intersects(
                query.bbox, query.srs):
            raise BlankImage()
        try:
            resp = self._get_map(query)
            if self.transparent_color:
                resp = make_transparent(resp, self.transparent_color,
                                        self.transparent_color_tolerance)
            resp.opacity = self.opacity
            return resp

        except HTTPClientError as e:
            log.warn('could not retrieve WMS map: %s', e)
            reraise_exception(SourceError(e.args[0]), sys.exc_info())

    def _get_map(self, query):
        format = self.image_opts.format
        if not format:
            format = query.format
        if self.supported_formats and format not in self.supported_formats:
            format = self.supported_formats[0]
        if self.supported_srs:
            if query.srs not in self.supported_srs:
                return self._get_transformed(query, format)
            # some srs are equal but not the same (e.g. 900913/3857)
            # use only supported srs so we use the right srs code.
            idx = self.supported_srs.index(query.srs)
            if self.supported_srs[idx] is not query.srs:
                query.srs = self.supported_srs[idx]
        if self.extent and not self.extent.contains(
                MapExtent(query.bbox, query.srs)):
            return self._get_sub_query(query, format)
        resp = self.client.retrieve(query, format)
        return ImageSource(resp, size=query.size, image_opts=self.image_opts)

    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,
                             dimensions=query.dimensions)
        resp = self.client.retrieve(src_query, format)
        return SubImageSource(resp,
                              size=query.size,
                              offset=offset,
                              image_opts=self.image_opts)

    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 _best_supported_srs(self, srs):
        latlong = srs.is_latlong

        for srs in self.supported_srs:
            if srs.is_latlong == latlong:
                return srs

        # else
        return self.supported_srs[0]

    def _is_compatible(self, other, query):
        if not isinstance(other, WMSSource):
            return False

        if self.opacity is not None or other.opacity is not None:
            return False

        if self.supported_srs != other.supported_srs:
            return False

        if self.supported_formats != other.supported_formats:
            return False

        if self.transparent_color != other.transparent_color:
            return False

        if self.transparent_color_tolerance != other.transparent_color_tolerance:
            return False

        if self.coverage != other.coverage:
            return False

        if (query.dimensions_for_params(self.fwd_req_params) !=
                query.dimensions_for_params(other.fwd_req_params)):
            return False

        return True

    def combined_layer(self, other, query):
        if not self._is_compatible(other, query):
            return None

        client = self.client.combined_client(other.client, query)
        if not client:
            return None

        return WMSSource(
            client,
            image_opts=self.image_opts,
            transparent_color=self.transparent_color,
            transparent_color_tolerance=self.transparent_color_tolerance,
            supported_srs=self.supported_srs,
            supported_formats=self.supported_formats,
            res_range=
            None,  # layer outside res_range should already be filtered out
            coverage=self.coverage,
            fwd_req_params=self.fwd_req_params,
        )
Exemplo n.º 18
0
 def __init__(self, coverage=None):
     Source.__init__(self)
     self.extent = MapExtent((-180, -90, 180, 90), SRS(4326))
     self.transparent = True
     self.extent = MapExtent(
         coverage.bbox, coverage.srs) if coverage else DefaultMapExtent()
Exemplo n.º 19
0
    @cached_property
    def layers(self):
        layers = []
        for layer in self.root_layer.layers:
            if not layer.name or self.layer_permitted(layer):
                filtered_layer = FilteredRootLayer(layer, self.permissions,
                                                   self.coverage)
                if filtered_layer.is_active or filtered_layer.layers:
                    # add filtered_layer only if it is active (no grouping layer)
                    # or if it contains other active layers
                    layers.append(filtered_layer)
        return layers


DEFAULT_EXTENTS = {
    'EPSG:3857': DefaultMapExtent(),
    'EPSG:4326': DefaultMapExtent(),
    'EPSG:900913': DefaultMapExtent(),
}


def limit_srs_extents(srs_extents, supported_srs):
    """
    Limit srs_extents to supported_srs.
    """
    if srs_extents:
        srs_extents = srs_extents.copy()
    else:
        srs_extents = DEFAULT_EXTENTS.copy()

    for srs in list(srs_extents.keys()):
Exemplo n.º 20
0
class WMSSource(MapLayer):
    supports_meta_tiles = True
    def __init__(self, client, image_opts=None, coverage=None, res_range=None,
                 transparent_color=None, transparent_color_tolerance=None,
                 supported_srs=None, supported_formats=None, fwd_req_params=None):
        MapLayer.__init__(self, image_opts=image_opts)
        self.client = client
        self.supported_srs = supported_srs or []
        self.supported_formats = supported_formats or []
        self.fwd_req_params = fwd_req_params or set()

        self.transparent_color = transparent_color
        self.transparent_color_tolerance = transparent_color_tolerance
        if self.transparent_color:
            self.image_opts.transparent = True
        self.coverage = coverage
        self.res_range = res_range
        if self.coverage:
            self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
        else:
            self.extent = DefaultMapExtent()

    def is_opaque(self, query):
        """
        Returns true if we are sure that the image is not transparent.
        """
        if self.res_range and not self.res_range.contains(query.bbox, query.size,
                                                          query.srs):
            return False

        if self.image_opts.transparent:
            return False

        if self.opacity is not None and (0.0 < self.opacity < 0.99):
            return False

        if not self.coverage:
            # not transparent and no coverage
            return True

        if self.coverage.contains(query.bbox, query.srs):
            # not transparent and completely inside coverage
            return True

        return False

    def get_map(self, query):
        if self.res_range and not self.res_range.contains(query.bbox, query.size,
                                                          query.srs):
            raise BlankImage()
        if self.coverage and not self.coverage.intersects(query.bbox, query.srs):
            raise BlankImage()
        try:
            resp = self._get_map(query)
            if self.transparent_color:
                resp = make_transparent(resp, self.transparent_color,
                                        self.transparent_color_tolerance)
            resp.opacity = self.opacity
            return resp

        except HTTPClientError as e:
            log.warn('could not retrieve WMS map: %s', e)
            reraise_exception(SourceError(e.args[0]), sys.exc_info())

    def _get_map(self, query):
        format = self.image_opts.format
        if not format:
            format = query.format
        if self.supported_formats and format not in self.supported_formats:
            format = self.supported_formats[0]
        if self.supported_srs:
            if query.srs not in self.supported_srs:
                return self._get_transformed(query, format)
            # some srs are equal but not the same (e.g. 900913/3857)
            # use only supported srs so we use the right srs code.
            idx = self.supported_srs.index(query.srs)
            if self.supported_srs[idx] is not query.srs:
                query.srs = self.supported_srs[idx]
        if self.extent and not self.extent.contains(MapExtent(query.bbox, query.srs)):
            return self._get_sub_query(query, format)
        resp = self.client.retrieve(query, format)
        return ImageSource(resp, size=query.size, image_opts=self.image_opts)

    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, dimensions=query.dimensions)
        resp = self.client.retrieve(src_query, format)
        return SubImageSource(resp, size=query.size, offset=offset, image_opts=self.image_opts)

    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 _best_supported_srs(self, srs):
        latlong = srs.is_latlong

        for srs in self.supported_srs:
            if srs.is_latlong == latlong:
                return srs

        # else
        return self.supported_srs[0]

    def _is_compatible(self, other, query):
        if not isinstance(other, WMSSource):
            return False

        if self.opacity is not None or other.opacity is not None:
            return False

        if self.supported_srs != other.supported_srs:
            return False

        if self.supported_formats != other.supported_formats:
            return False

        if self.transparent_color != other.transparent_color:
            return False

        if self.transparent_color_tolerance != other.transparent_color_tolerance:
            return False

        if self.coverage != other.coverage:
            return False


        if (query.dimensions_for_params(self.fwd_req_params) !=
            query.dimensions_for_params(other.fwd_req_params)):
            return False

        return True

    def combined_layer(self, other, query):
        if not self._is_compatible(other, query):
            return None

        client = self.client.combined_client(other.client, query)
        if not client:
            return None

        return WMSSource(client, image_opts=self.image_opts,
            transparent_color=self.transparent_color,
            transparent_color_tolerance=self.transparent_color_tolerance,
            supported_srs=self.supported_srs,
            supported_formats=self.supported_formats,
            res_range=None, # layer outside res_range should already be filtered out
            coverage=self.coverage,
            fwd_req_params=self.fwd_req_params,
        )