ó
Š*Pc           @   s˜   d  d l  m Z m Z m Z m Z d  d l m Z d  d l m Z d  d l	 m
 Z
 m Z m Z m Z m Z e
 d Z d e
 Z d e f d „  ƒ  YZ d S(	   iÿÿÿÿ(   t   GEOSGeometryt
   LinearRingt   Polygont   Point(   t   GoogleMapException(   t   xrange(   t   pit   sint   logt   expt   atang     €f@t
   GoogleZoomc           B   s\   e  Z d  Z d d d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z d	 „  Z	 d
 „  Z
 RS(   s  
    GoogleZoom is a utility for performing operations related to the zoom
    levels on Google Maps.

    This class is inspired by the OpenStreetMap Mapnik tile generation routine
    `generate_tiles.py`, and the article "How Big Is the World" (Hack #16) in
    "Google Maps Hacks" by Rich Gibson and Schuyler Erle.

    `generate_tiles.py` may be found at:
      http://trac.openstreetmap.org/browser/applications/rendering/mapnik/generate_tiles.py

    "Google Maps Hacks" may be found at http://safari.oreilly.com/0596101619
    i   i   c         C   s˜   | |  _  | |  _ g  |  _ g  |  _ g  |  _ | } x^ t | ƒ D]P } |  j j | d ƒ |  j j | d t ƒ |  j j | d ƒ | d 9} q@ Wd S(   s#   Initializes the Google Zoom object.g     €v@i   N(   t	   _tilesizet   _nzoomt   _degppt   _radppt   _npixR   t   appendR   (   t   selft   num_zoomt   tilesizet   zt   i(    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   __init__   s    					c         C   s   |  j  S(   s"   Returns the number of zoom levels.(   R   (   R   (    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   __len__3   s    c         C   s7   t  | t ƒ r! | j \ } } n | \ } } | | f S(   s:   Unpacks longitude, latitude from GEOS Points and 2-tuples.(   t
   isinstanceR   t   coords(   R   t   lonlatt   lont   lat(    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   get_lon_lat7   s    c   	      C   sž   |  j  | ƒ \ } } |  j | } t | | |  j | ƒ } t t t t | ƒ d ƒ d ƒ } t | d t d | d | ƒ d |  j	 | ƒ } | | f S(   sH   Converts a longitude, latitude coordinate pair for the given zoom level.g§èH.ÿï¿g§èH.ÿï?g      à?i   g      ð¿(
   R   R   t   roundR   t   mint   maxR   t   DTORR   R   (	   R   R   t   zoomR   R   t   npixt   px_xt   fact   px_y(    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   lonlat_to_pixel?   s    "5c         C   sŠ   t  | ƒ d k r! t d ƒ ‚ n  |  j | } | d | |  j | } t d t t | d | d |  j | ƒ ƒ d t } | | f S(   sG   Converts a pixel to a longitude, latitude pair at the given zoom level.i   s+   Pixel should be a sequence of two elements.i    i   g      ð¿g      à?(	   t   lent	   TypeErrorR   R   t   RTODR
   R	   R   R   (   R   t   pxR#   R$   R   R   (    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   pixel_to_lonlatV   s    9c         C   s­   |  j  d } |  j | | ƒ } |  j | d | | d | f | ƒ } |  j | d | | d | f | ƒ } t t | | d | d f | | d | d f | ƒ d d ƒS(   só   
        Returns a Polygon  corresponding to the region represented by a fictional
        Google Tile for the given longitude/latitude pair and zoom level. This
        tile is used to determine the size of a tile at the given point.
        i   i    i   t   sridiæ  (   R   R(   R-   R   R   (   R   R   R#   t   deltaR,   t   llt   ur(    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   tileg   s
    ((c   	      C   sÜ   t  | t ƒ s | j d k r. t d ƒ ‚ n  | j } |  j | j ƒ \ } } | j } xv t |  j	 ƒ D]e } |  j |  j
 | | ƒ j ƒ \ } } | | k sª | | k rh | d k rÅ t d ƒ ‚ n  | d Sqh W|  j	 d S(   s6   Returns the optimal Zoom level for the given geometry.iæ  s8   get_zoom() expects a GEOS Geometry with an SRID of 4326.i    s>   Geometry width and height should not exceed that of the Earth.i   (   R   R    R.   R*   t   envelopet   get_width_heightt   extentt   centroidR   R   R2   R   (	   R   t   geomt   envt   env_wt   env_ht   centerR   t   tile_wt   tile_h(    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   get_zoom|   s    		$c         C   s_   t  | d  ƒ } t  | d | d ƒ } t  | d ƒ } | j | ƒ } | j | ƒ } | | f S(   sD   
        Returns the width and height for the given extent.
        i   i    i   (   R   t   distance(   R   R5   R0   t   ulR1   t   heightt   width(    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyR4   –   s    (   t   __name__t
   __module__t   __doc__R   R   R   R(   R-   R2   R>   R4   (    (    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyR   
   s   						N(   t   django.contrib.gis.geosR    R   R   R   t#   django.contrib.gis.maps.google.gmapR   t   django.utils.six.movesR   t   mathR   R   R   R	   R
   R"   R+   t   objectR   (    (    (    s<   ../Django//lib/python/django/contrib/gis/maps/google/zoom.pyt   <module>   s   "(

