U
    ҭc'                     @   s   d Z dd Zdd Zdd Zdd Zd	d
 Zdd Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd  Zd!S )"zConverts Python types to string representations suitable for Maps API server.

    For example:

    sydney = {
        "lat" : -33.8674869,
        "lng" : 151.2069902
    }

    convert.latlng(sydney)
    # '-33.8674869,151.2069902'
c                 C   s   dt |  ddS )a[  Formats a float value to be as short as possible.

    Truncates float to 8 decimal places and trims extraneous
    trailing zeros and period to give API args the best
    possible chance of fitting within 2000 char URL length
    restrictions.

    For example:

    format_float(40) -> "40"
    format_float(40.0) -> "40"
    format_float(40.1) -> "40.1"
    format_float(40.001) -> "40.001"
    format_float(40.0010) -> "40.001"
    format_float(40.000000001) -> "40"
    format_float(40.000000009) -> "40.00000001"

    :param arg: The lat or lng float.
    :type arg: float

    :rtype: string
    z%.8f0.)floatrstriparg r   O/home/ubuntu/graampay/app_env/lib/python3.8/site-packages/googlemaps/convert.pyformat_float    s    r	   c                 C   s0   t | r| S t| }dt|d t|d f S )a  Converts a lat/lon pair to a comma-separated string.

    For example:

    sydney = {
        "lat" : -33.8674869,
        "lng" : 151.2069902
    }

    convert.latlng(sydney)
    # '-33.8674869,151.2069902'

    For convenience, also accepts lat/lon pair as a string, in
    which case it's returned unchanged.

    :param arg: The lat/lon pair.
    :type arg: string or dict or list or tuple
    z%s,%s       )	is_stringnormalize_lat_lngr	   )r   
normalizedr   r   r   latlng:   s    r   c                 C   sx   t | trJd| kr*d| kr*| d | d fS d| krJd| krJ| d | d fS t| rb| d | d fS tdt| j dS )	a1  Take the various lat/lng representations and return a tuple.

    Accepts various representations:
    1) dict with two entries - "lat" and "lng"
    2) list or tuple - e.g. (-33, 151) or [-33, 151]

    :param arg: The lat/lng pair.
    :type arg: dict or list or tuple

    :rtype: tuple (lat, lng)
    latlngZlatitudeZ	longituder
   r   z,Expected a lat/lng dict or tuple, but got %sN)
isinstancedict_is_list	TypeErrortype__name__r   r   r   r   r   T   s    
r   c                 C   s.   t | trt| S ddd t| D S dS )aR  Joins a list of locations into a pipe separated string, handling
    the various formats supported for lat/lng values.

    For example:
    p = [{"lat" : -33.867486, "lng" : 151.206990}, "Sydney"]
    convert.waypoint(p)
    # '-33.867486,151.206990|Sydney'

    :param arg: The lat/lng list.
    :type arg: list

    :rtype: string
    |c                 S   s   g | ]}t |qS r   )r   ).0locationr   r   r   
<listcomp>   s     z!location_list.<locals>.<listcomp>N)r   tupler   joinas_listr   r   r   r   location_listo   s    
r   c                 C   s   |  t|S )zIf arg is list-like, then joins it with sep.

    :param sep: Separator string.
    :type sep: string

    :param arg: Value to coerce into a list.
    :type arg: string or list of strings

    :rtype: string
    )r   r   )sepr   r   r   r   	join_list   s    r!   c                 C   s   t | r| S | gS )zCoerces arg into a list. If arg is already list-like, returns arg.
    Otherwise, returns a one-element list containing arg.

    :rtype: list
    )r   r   r   r   r   r      s    r   c                 C   s:   t | trdS t | trdS t| ds0t| dS t| dS )z<Checks if arg is list-like. This excludes strings and dicts.Fstrip__getitem____iter__)r   r   str_has_methodr   r   r   r   r      s
    

r   c                 C   s2   zt  W n tk
r&   t| t Y S X t| t S )z>Determines whether the passed value is a string, safe for 2/3.)
basestring	NameErrorr   r%   )valr   r   r   r      s
    r   c                 C   s,   t | dr|  } t| tr$t| } t| S )zConverts the value into a unix time (seconds since unix epoch).

    For example:
        convert.time(datetime.now())
        # '1409810596'

    :param arg: The time.
    :type arg: datetime.datetime or int
    	timestamp)r&   r*   r   r   intr%   r   r   r   r   time   s
    

r,   c                 C   s   t | |ott| |S )zReturns true if the given object has a method with the given name.

    :param arg: the object

    :param method: the method name
    :type method: string

    :rtype: bool
    )hasattrcallablegetattr)r   methodr   r   r   r&      s    
r&   c                 C   s:   dd }t | tr$dt|| S tdt| j dS )a.  Converts a dict of components to the format expected by the Google Maps
    server.

    For example:
    c = {"country": "US", "postal_code": "94043"}
    convert.components(c)
    # 'country:US|postal_code:94043'

    :param arg: The component filter.
    :type arg: dict

    :rtype: basestring
    c                 s   s2   |   D ]$\}}t|D ]}d||f V  qqd S )Nz%s:%s)itemsr   )r   kvitemr   r   r   expand   s    zcomponents.<locals>.expandr   z*Expected a dict for components, but got %sN)r   r   r   sortedr   r   r   )r   r5   r   r   r   
components   s    
r7   c                 C   st   t | r(| ddkr(| ddkr(| S t| tr^d| kr^d| kr^dt| d t| d f S tdt| j d	S )
a  Converts a lat/lon bounds to a comma- and pipe-separated string.

    Accepts two representations:
    1) string: pipe-separated pair of comma-separated lat/lon pairs.
    2) dict with two entries - "southwest" and "northeast". See convert.latlng
    for information on how these can be represented.

    For example:

    sydney_bounds = {
        "northeast" : {
            "lat" : -33.4245981,
            "lng" : 151.3426361
        },
        "southwest" : {
            "lat" : -34.1692489,
            "lng" : 150.502229
        }
    }

    convert.bounds(sydney_bounds)
    # '-34.169249,150.502229|-33.424598,151.342636'

    :param arg: The bounds.
    :type arg: dict
    r   r   ,   Z	southwestZ	northeastz%s|%sz8Expected a bounds (southwest/northeast) dict, but got %sN)r   countr   r   r   r   r   r   r   r   r   r   bounds   s    $

r;   c                 C   sH   t | trd| | f S t| r2d| d | d f S tdt| j d S )Nz%sx%sr
   r   z'Expected a size int or list, but got %s)r   r+   r   r   r   r   r   r   r   r   size  s    
r<   c                 C   s  g }d } }}|t | k rd}d}t| | d d }|d7 }|||> 7 }|d7 }|dk r&qbq&||d@ dkrz| d? n|d? 7 }d}d}t| | d d }|d7 }|||> 7 }|d7 }|dk rqq||d@ dkr|d?  n|d? 7 }||d |d d q|S )aH  Decodes a Polyline string into a list of lat/lng dicts.

    See the developer docs for a detailed description of this encoding:
    https://developers.google.com/maps/documentation/utilities/polylinealgorithm

    :param polyline: An encoded polyline
    :type polyline: string

    :rtype: list of dicts with lat/lng keys
    r
   r   ?         gh㈵>)r   r   )lenordappend)Zpolylinepointsindexr   r   resultshiftbr   r   r   decode_polyline"  s.    ""rH   c                 C   s   d }}d}| D ]}t |}tt|d d }tt|d d }|| }|| }	||	fD ]X}
|
dk rr|
d>  n|
d> }
|
dkr|td|
d@ B d 7 }|
dL }
qz|t|
d 7 }q\|}|}q|S )	a9  Encodes a list of points into a polyline string.

    See the developer docs for a detailed description of this encoding:
    https://developers.google.com/maps/documentation/utilities/polylinealgorithm

    :param points: a list of lat/lng pairs
    :type points: list of dicts or tuples

    :rtype: string
    r
    g     j@r       r?   r=   r>   )r   r+   roundchr)rC   Zlast_latZlast_lngrE   ZpointZllr   r   Zd_latZd_lngr3   r   r   r   encode_polylineL  s"    
rM   c                 C   s@   t | tr| g} dt|  }t| }t|t|k r8|S |S dS )ai  Returns the shortest representation of the given locations.

    The Elevations API limits requests to 2000 characters, and accepts
    multiple locations either as pipe-delimited lat/lng values, or
    an encoded polyline, so we determine which is shortest and use it.

    :param locations: The lat/lng list.
    :type locations: list

    :rtype: string
    zenc:%sN)r   r   rM   r   r@   )Z	locationsencoded	unencodedr   r   r   shortest_pathn  s    
rP   N)__doc__r	   r   r   r   r!   r   r   r   r,   r&   r7   r;   r<   rH   rM   rP   r   r   r   r   <module>   s    		(*"