Commit b25d759b authored by Justin Bronn's avatar Justin Bronn
Browse files

Fixed #8113. Made `get_width_height` a `GoogleZoom` method that takes the...

Fixed #8113.  Made `get_width_height` a `GoogleZoom` method that takes the extent instead of an envelope so it may handle Point geometries.  Thanks to Santiago Aguiar for the bug report.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8428 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent e3ea9dde
Loading
Loading
Loading
Loading
+34 −37
Original line number Diff line number Diff line
@@ -6,17 +6,6 @@ from math import pi, sin, cos, log, exp, atan
DTOR = pi / 180.
RTOD = 180. / pi

def get_width_height(envelope):
    # Getting the lower-left, upper-left, and upper-right
    #  coordinates of the envelope.
    ll = Point(envelope[0][0])
    ul = Point(envelope[0][1])
    ur = Point(envelope[0][2])
    
    height = ll.distance(ul)
    width  = ul.distance(ur)
    return width, height

class GoogleZoom(object):
    """
    GoogleZoom is a utility for performing operations related to the zoom
@@ -34,21 +23,19 @@ class GoogleZoom(object):
    
    def __init__(self, num_zoom=19, tilesize=256):
        "Initializes the Google Zoom object."

        # Google's tilesize is 256x256, square tiles are assumed.
        self._tilesize = tilesize
        
        # The number of zoom levels
        self._nzoom = num_zoom

        # Initializing arrays to hold the parameters for each
        #  one of the zoom levels.
        # Initializing arrays to hold the parameters for each one of the 
        # zoom levels.
        self._degpp = [] # Degrees per pixel
        self._radpp = [] # Radians per pixel
        self._npix  = [] # 1/2 the number of pixels for a tile at the given zoom level
        
        # Incrementing through the zoom levels and populating the
        #  parameter arrays.
        # Incrementing through the zoom levels and populating the parameter arrays.
        z = tilesize # The number of pixels per zoom level.
        for i in xrange(num_zoom):
            # Getting the degrees and radians per pixel, and the 1/2 the number of
@@ -79,9 +66,8 @@ class GoogleZoom(object):
        lon, lat = self.get_lon_lat(lonlat)
        npix = self._npix[zoom]

        # Calculating the pixel x coordinate by multiplying the longitude
        #  value with with the number of degrees/pixel at the given
        #  zoom level.
        # Calculating the pixel x coordinate by multiplying the longitude value
        # with with the number of degrees/pixel at the given zoom level.
        px_x = round(npix + (lon * self._degpp[zoom]))

        # Creating the factor, and ensuring that 1 or -1 is not passed in as the 
@@ -136,7 +122,6 @@ class GoogleZoom(object):
        
    def get_zoom(self, geom):
        "Returns the optimal Zoom level for the given geometry."

        # Checking the input type.
        if not isinstance(geom, GEOSGeometry) or geom.srid != 4326:
            raise TypeError('get_zoom() expects a GEOS Geometry with an SRID of 4326.')
@@ -144,13 +129,12 @@ class GoogleZoom(object):
        # Getting the envelope for the geometry, and its associated width, height
        # and centroid.
        env = geom.envelope
        env_w, env_h = get_width_height(env)
        env_w, env_h = self.get_width_height(env.extent)
        center = env.centroid

        for z in xrange(self._nzoom):
            # Getting the tile at the zoom level.
            tile = self.tile(center, z)
            tile_w, tile_h = get_width_height(tile)
            tile_w, tile_h = self.get_width_height(self.tile(center, z).extent)

            # When we span more than one tile, this is an approximately good
            # zoom level.
@@ -162,3 +146,16 @@ class GoogleZoom(object):
        # Otherwise, we've zoomed in to the max.
        return self._nzoom-1

    def get_width_height(self, extent):
        """
        Returns the width and height for the given extent.
        """
        # Getting the lower-left, upper-left, and upper-right
        # coordinates from the extent.
        ll = Point(extent[:2])
        ul = Point(extent[0], extent[3])
        ur = Point(extent[2:])
        # Calculating the width and height.
        height = ll.distance(ul)
        width  = ul.distance(ur)
        return width, height