o
    Ò­Ò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 )"zëConverts 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   ú[/Users/abhinavbhinder/Documents/map/venv/lib/python3.10/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   st   t | tƒr%d| v rd| v r| d | d fS d| v r%d| v r%| d | d fS t| ƒr1| d | d fS tdt| ƒj ƒ‚)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 %s)Ú
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 )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>)r   Útupler   ÚjoinÚas_listr   r   r   r   Úlocation_listo   s   
r   c                 C   s   |   t|ƒ¡S )zÕIf 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 )z“Coerces 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ƒst| 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   s0   zt  W n ty   t| tƒ Y S w 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 )zÕConverts 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 )z²Returns 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   s6   dd„ }t | tƒrd t|| ƒƒ¡S tdt| ƒj ƒ‚)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   s4   � |   ¡ 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 %s)r   r   r   Úsortedr   r   r   )r   r5   r   r   r   Ú
componentsÐ   s   
ÿÿr7   c                 C   sp   t | ƒr|  d¡dkr|  d¡dkr| S t| tƒr/d| v r/d| v r/dt| d ƒt| d ƒf S tdt| ƒj ƒ‚)	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 %s)r   Úcountr   r   r   r   r   r   r   r   r   r   Úboundsï   s   $

ÿÿÿr;   c                 C   sD   t | tƒrd| | f S t| ƒrd| d | d f S tdt| ƒj ƒ‚)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 r0nq||d@ dkr=| d? n|d? 7 }d}d}	 t| | ƒd d }|d7 }|||> 7 }|d7 }|dk rdnqG||d@ dkrq|d?  n|d? 7 }| |d |d dœ¡ |t | ƒk s|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   Té?   é   é   gñhãˆµøä>)r   r   )ÚlenÚordÚappend)ZpolylineÚpointsÚindexr   r   ÚresultÚshiftÚbr   r   r   Údecode_polyline"  s8   ú"ú"érH   c                 C   sÊ   d }}d}| D ]Z}t |ƒ}tt|d d ƒƒ}tt|d d ƒƒ}|| }|| }	||	fD ]/}
|
dk r9|
d>  n|
d> }
|
dkrU|td|
d@ B d ƒ7 }|
dL }
|
dksA|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 r|S |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:%s)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"   		(*"