Ejemplo n.º 1
0
    def set_zoom_at(self, zoom, x, y, scale=None):
        """Sets the zoom level, leaving the (x, y) at the exact same point
        in the view.
        """
        zoom = clamp(zoom,
                     self.map_source.get_min_zoom(),
                     self.map_source.get_max_zoom())
        if int(zoom) == int(self._zoom):
            return
        scale = scale or 1.

        # first, rescale the scatter
        scatter = self._scatter
        scale = clamp(scale, scatter.scale_min, scatter.scale_max)
        rescale = scale * 1.0 / scatter.scale
        scatter.apply_transform(Matrix().scale(rescale, rescale, rescale),
                             post_multiply=True,
                             anchor=scatter.to_local(x, y))

        # adjust position if the zoom changed
        c1 = self.map_source.get_col_count(self._zoom)
        c2 = self.map_source.get_col_count(zoom)
        if c1 != c2:
            f = float(c2) / float(c1)
            self.delta_x = scatter.x + self.delta_x * f
            self.delta_y = scatter.y + self.delta_y * f
            # back to 0 every time
            scatter.apply_transform(Matrix().translate(
                -scatter.x, -scatter.y, 0
            ), post_multiply=True)

        # avoid triggering zoom changes.
        self._zoom = zoom
        self.zoom = self._zoom
Ejemplo n.º 2
0
    def center_on(self, *args):
        """Center the map on the coordinate :class:`Coordinate`, or a (lat, lon)
        """
        map_source = self.map_source
        zoom = self._zoom

        if len(args) == 1 and isinstance(args[0], Coordinate):
            coord = args[0]
            lat = coord.lat
            lon = coord.lon
        elif len(args) == 2:
            lat, lon = args
        else:
            raise Exception("Invalid argument for center_on")
        lon = clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE)
        lat = clamp(lat, MIN_LATITUDE, MAX_LATITUDE)
        scale = self._scatter.scale
        x = map_source.get_x(zoom, lon) - self.center_x / scale
        y = map_source.get_y(zoom, lat) - self.center_y / scale
        self.delta_x = -x
        self.delta_y = -y
        self.lon = lon
        self.lat = lat
        self._scatter.pos = 0, 0
        self.trigger_update(True)
Ejemplo n.º 3
0
    def set_zoom_at(self, zoom, x, y, scale=None):
        """Sets the zoom level, leaving the (x, y) at the exact same point
        in the view.
        """
        zoom = clamp(zoom, self.map_source.get_min_zoom(),
                     self.map_source.get_max_zoom())
        if int(zoom) == int(self._zoom):
            return
        scale = scale or 1.

        # first, rescale the scatter
        scatter = self._scatter
        scale = clamp(scale, scatter.scale_min, scatter.scale_max)
        rescale = scale * 1.0 / scatter.scale
        scatter.apply_transform(Matrix().scale(rescale, rescale, rescale),
                                post_multiply=True,
                                anchor=scatter.to_local(x, y))

        # adjust position if the zoom changed
        c1 = self.map_source.get_col_count(self._zoom)
        c2 = self.map_source.get_col_count(zoom)
        if c1 != c2:
            f = float(c2) / float(c1)
            self.delta_x = scatter.x + self.delta_x * f
            self.delta_y = scatter.y + self.delta_y * f
            # back to 0 every time
            scatter.apply_transform(Matrix().translate(-scatter.x, -scatter.y,
                                                       0),
                                    post_multiply=True)

        # avoid triggering zoom changes.
        self._zoom = zoom
        self.zoom = self._zoom
Ejemplo n.º 4
0
    def center_on(self, *args):
        """Center the map on the coordinate :class:`Coordinate`, or a (lat, lon)
        """
        map_source = self.map_source
        zoom = self._zoom

        if len(args) == 1 and isinstance(args[0], Coordinate):
            coord = args[0]
            lat = coord.lat
            lon = coord.lon
        elif len(args) == 2:
            lat, lon = args
        else:
            raise Exception("Invalid argument for center_on")
        lon = clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE)
        lat = clamp(lat, MIN_LATITUDE, MAX_LATITUDE)
        scale = self._scatter.scale
        x = map_source.get_x(zoom, lon) - self.center_x / scale
        y = map_source.get_y(zoom, lat) - self.center_y / scale
        self.delta_x = -x
        self.delta_y = -y
        self.lon = lon
        self.lat = lat
        self._scatter.pos = 0, 0
        self.trigger_update(True)
Ejemplo n.º 5
0
 def scale_at(self, scale, x, y):
     scatter = self._scatter
     scale = clamp(scale, scatter.scale_min, scatter.scale_max)
     rescale = scale * 1.0 / scatter.scale
     scatter.apply_transform(Matrix().scale(rescale, rescale, rescale),
                             post_multiply=True,
                             anchor=scatter.to_local(x, y))
Ejemplo n.º 6
0
 def get_lat(self, zoom, y):
     """Get the latitude to the y position in the map source's projection
     """
     dy = y / float(self.dp_tile_size)
     n = pi - 2 * pi * dy / pow(2., zoom)
     lat = -180. / pi * atan(.5 * (exp(n) - exp(-n)))
     return clamp(lat, MIN_LATITUDE, MAX_LATITUDE)
Ejemplo n.º 7
0
 def scale_at(self, scale, x, y):
     scatter = self._scatter
     scale = clamp(scale, scatter.scale_min, scatter.scale_max)
     rescale = scale * 1.0 / scatter.scale
     scatter.apply_transform(Matrix().scale(rescale, rescale, rescale),
                          post_multiply=True,
                          anchor=scatter.to_local(x, y))
Ejemplo n.º 8
0
    def on_transform(self, *args):
        self._invalid_scale = True
        if self._transform_lock:
            return
        self._transform_lock = True
        # recalculate viewport
        map_source = self.map_source
        zoom = self._zoom
        scatter = self._scatter
        scale = scatter.scale
        if scale >= 2.:
            zoom += 1
            scale /= 2.
        elif scale < 1:
            zoom -= 1
            scale *= 2.
        zoom = clamp(zoom, map_source.min_zoom, map_source.max_zoom)
        if zoom != self._zoom:
            self.set_zoom_at(zoom, scatter.x, scatter.y, scale=scale)
            self.trigger_update(True)
        else:
            if zoom == map_source.min_zoom and scatter.scale < 1.:
                scatter.scale = 1.
                self.trigger_update(True)
            else:
                self.trigger_update(False)

        if map_source.bounds:
            self._apply_bounds()
        self._transform_lock = False
        self._scale = self._scatter.scale
Ejemplo n.º 9
0
 def get_lat(self, zoom, y):
     """Get the latitude to the y position in the map source's projection
     """
     dy = y / float(self.dp_tile_size)
     n = pi - 2 * pi * dy / pow(2., zoom)
     lat = -180. / pi * atan(.5 * (exp(n) - exp(-n)))
     return clamp(lat, MIN_LATITUDE, MAX_LATITUDE)
Ejemplo n.º 10
0
    def on_transform(self, *args):
        self._invalid_scale = True
        if self._transform_lock:
            return
        self._transform_lock = True
        # recalculate viewport
        map_source = self.map_source
        zoom = self._zoom
        scatter = self._scatter
        scale = scatter.scale
        if scale >= 2.01:
            zoom += 1
            scale /= 2.
        elif scale < 0.99:
            zoom -= 1
            scale *= 2.
        zoom = clamp(zoom, map_source.min_zoom, map_source.max_zoom)
        if zoom != self._zoom:
            self.set_zoom_at(zoom, scatter.x, scatter.y, scale=scale)
            self.trigger_update(True)
        else:
            if zoom == map_source.min_zoom and scatter.scale < 1.:
                scatter.scale = 1.
                self.trigger_update(True)
            else:
                self.trigger_update(False)

        if map_source.bounds:
            self._apply_bounds()
        self._transform_lock = False
        self._scale = self._scatter.scale
Ejemplo n.º 11
0
 def get_y(self, zoom, lat):
     """Get the y position on the map using this map source's projection
     (0, 0) is located at the top left.
     """
     lat = clamp(-lat, MIN_LATITUDE, MAX_LATITUDE)
     lat = lat * pi / 180.
     return ((1.0 - log(tan(lat) + 1.0 / cos(lat)) / pi) / \
         2. * pow(2., zoom)) * self.dp_tile_size
Ejemplo n.º 12
0
 def get_y(self, zoom, lat):
     """Get the y position on the map using this map source's projection
     (0, 0) is located at the top left.
     """
     lat = clamp(-lat, MIN_LATITUDE, MAX_LATITUDE)
     lat = lat * pi / 180.
     return ((1.0 - log(tan(lat) + 1.0 / cos(lat)) / pi) / \
         2. * pow(2., zoom)) * self.dp_tile_size
Ejemplo n.º 13
0
    def bbox_for_zoom(self, vx, vy, w, h, zoom):
        # return a tile-bbox for the zoom
        map_source = self.map_source
        size = map_source.dp_tile_size
        scale = self._scale

        max_x_end = map_source.get_col_count(zoom)
        max_y_end = map_source.get_row_count(zoom)

        x_count = int(ceil(w / scale / float(size))) + 1
        y_count = int(ceil(h / scale / float(size))) + 1

        tile_x_first = int(clamp(vx / float(size), 0, max_x_end))
        tile_y_first = int(clamp(vy / float(size), 0, max_y_end))
        tile_x_last = tile_x_first + x_count
        tile_y_last = tile_y_first + y_count
        tile_x_last = int(clamp(tile_x_last, tile_x_first, max_x_end))
        tile_y_last = int(clamp(tile_y_last, tile_y_first, max_y_end))

        x_count = tile_x_last - tile_x_first
        y_count = tile_y_last - tile_y_first
        return (tile_x_first, tile_y_first, tile_x_last, tile_y_last, x_count,
                y_count)
Ejemplo n.º 14
0
    def bbox_for_zoom(self, vx, vy, w, h, zoom):
        # return a tile-bbox for the zoom
        map_source = self.map_source
        size = map_source.dp_tile_size
        scale = self._scale

        max_x_end = map_source.get_col_count(zoom)
        max_y_end = map_source.get_row_count(zoom)

        x_count = int(ceil(w / scale / float(size))) + 1
        y_count = int(ceil(h / scale / float(size))) + 1

        tile_x_first = int(clamp(vx / float(size), 0, max_x_end))
        tile_y_first = int(clamp(vy / float(size), 0, max_y_end))
        tile_x_last = tile_x_first + x_count
        tile_y_last = tile_y_first + y_count
        tile_x_last = int(clamp(tile_x_last, tile_x_first, max_x_end))
        tile_y_last = int(clamp(tile_y_last, tile_y_first, max_y_end))

        x_count = tile_x_last - tile_x_first
        y_count = tile_y_last - tile_y_first
        return (tile_x_first, tile_y_first, tile_x_last, tile_y_last,
                x_count, y_count)
Ejemplo n.º 15
0
    def on_transform(self, *args):
        if self._transform_lock:
            return
        self._transform_lock = True
        # recalculate viewport
        map_source = self.map_source
        zoom = self._zoom
        scatter = self._scatter
        scale = scatter.scale
        if scale >= 2.:
            zoom += 1
            scale /= 2.
        elif scale < 1:
            zoom -= 1
            scale *= 2.
        zoom = clamp(zoom, self.map_source.min_zoom, self.map_source.max_zoom)
        if zoom != self._zoom:
            self.set_zoom_at(zoom, scatter.x, scatter.y, scale=scale)
            self.trigger_update(True)
        else:
            self.trigger_update(False)

        if map_source.bounds:
            # if the map_source have any constraints, apply them here.
            min_lon, min_lat, max_lon, max_lat = map_source.bounds
            xmin = map_source.get_x(zoom, min_lon)
            xmax = map_source.get_x(zoom, max_lon)
            ymin = map_source.get_y(zoom, min_lat)
            ymax = map_source.get_y(zoom, max_lat)

            mx, my = self._scatter.to_local(*self.center)
            mx -= self.delta_x
            my -= self.delta_y
            if mx < xmin:
                x_diff = xmin - mx
                self._scatter.x -= x_diff
            elif mx > xmax:
                x_diff = xmax - mx
                self._scatter.x -= x_diff
            if my < ymin:
                y_diff = ymin - my
                self._scatter.y -= y_diff
            elif my > ymax:
                y_diff = ymax - my
                self._scatter.y -= y_diff

        self._transform_lock = False
        self._scale = self._scatter.scale
Ejemplo n.º 16
0
 def on_map_source(self, instance, source):
     if isinstance(source, string_types):
         self.map_source = MapSource.from_provider(source)
     elif isinstance(source, (tuple, list)):
         cache_key, min_zoom, max_zoom, url, attribution, options = source
         self.map_source = MapSource(url=url, cache_key=cache_key,
                                     min_zoom=min_zoom, max_zoom=max_zoom,
                                     attribution=attribution, **options)
     elif isinstance(source, MapSource):
         self.map_source = source
     else:
         raise Exception("Invalid map source provider")
     self.zoom = clamp(self.zoom,
                       self.map_source.min_zoom, self.map_source.max_zoom)
     self.remove_all_tiles()
     self.trigger_update(True)
Ejemplo n.º 17
0
 def on_map_source(self, instance, source):
     if isinstance(source, string_types):
         self.map_source = MapSource.from_provider(source)
     elif isinstance(source, (tuple, list)):
         cache_key, min_zoom, max_zoom, url, attribution, options = source
         self.map_source = MapSource(url=url, cache_key=cache_key,
                                     min_zoom=min_zoom, max_zoom=max_zoom,
                                     attribution=attribution, **options)
     elif isinstance(source, MapSource):
         self.map_source = source
     else:
         raise Exception("Invalid map source provider")
     self.zoom = clamp(self.zoom,
                       self.map_source.min_zoom, self.map_source.max_zoom)
     self.remove_all_tiles()
     self.trigger_update(True)
Ejemplo n.º 18
0
 def on_transform(self, *args):
     if self._transform_lock:
         return
     self._transform_lock = True
     # recalculate viewport
     zoom = self._zoom
     scatter = self._scatter
     scale = scatter.scale
     if scale >= 2.:
         zoom += 1
         scale /= 2.
     elif scale < 1:
         zoom -= 1
         scale *= 2.
     zoom = clamp(zoom, self.map_source.min_zoom, self.map_source.max_zoom)
     if zoom != self._zoom:
         self.set_zoom_at(zoom, scatter.x, scatter.y, scale=scale)
         self.trigger_update(True)
     else:
         self.trigger_update(False)
     self._transform_lock = False
Ejemplo n.º 19
0
 def on_transform(self, *args):
     if self._transform_lock:
         return
     self._transform_lock = True
     # recalculate viewport
     zoom = self._zoom
     scatter = self._scatter
     scale = scatter.scale
     if scale >= 2.:
         zoom += 1
         scale /= 2.
     elif scale < 1:
         zoom -= 1
         scale *= 2.
     zoom = clamp(zoom, self.map_source.min_zoom, self.map_source.max_zoom)
     if zoom != self._zoom:
         self.set_zoom_at(zoom, scatter.x, scatter.y, scale=scale)
         self.trigger_update(True)
     else:
         self.trigger_update(False)
     self._transform_lock = False
Ejemplo n.º 20
0
 def get_lon(self, zoom, x):
     """Get the longitude to the x position in the map source's projection
     """
     dx = x / float(self.dp_tile_size)
     lon = dx / pow(2., zoom) * 360. - 180.
     return clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE)
Ejemplo n.º 21
0
 def get_x(self, zoom, lon):
     """Get the x position on the map using this map source's projection
     (0, 0) is located at the top left.
     """
     lon = clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE)
     return ((lon + 180.) / 360. * pow(2., zoom)) * self.dp_tile_size
Ejemplo n.º 22
0
 def get_lon(self, zoom, x):
     """Get the longitude to the x position in the map source's projection
     """
     dx = x / float(self.dp_tile_size)
     lon = dx / pow(2., zoom) * 360. - 180.
     return clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE)
Ejemplo n.º 23
0
 def get_x(self, lon):
     '''Get the x position on the map using this map source's projection
     (0, 0) is located at the top left.
     '''
     return clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE) * self.ms / 360.0
Ejemplo n.º 24
0
 def get_y(self, lat):
     '''Get the y position on the map using this map source's projection
     (0, 0) is located at the top left.
     '''
     lat = radians(clamp(-lat, MIN_LATITUDE, MAX_LATITUDE))
     return ((1.0 - log(tan(lat) + 1.0 / cos(lat)) / pi)) * self.ms / 2.0
Ejemplo n.º 25
0
 def get_x(self, zoom, lon):
     """Get the x position on the map using this map source's projection
     (0, 0) is located at the top left.
     """
     lon = clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE)
     return ((lon + 180.) / 360. * pow(2., zoom)) * self.dp_tile_size