
    C.i5(                        d Z ddlmZ dZddlZddlZddlZej        dk    r ej        d           n ej        ej	                   ddl
Z
ddlmZ ddlmZ ddlZd	Zd
ZdZdZi ddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0Zddddd1Zg d2Zd3Zd4Zd5Zd6 Ze G d7 d8e                      Zd9 Z d: Z!dEd<Z"dEd=Z#e$d>k    rl e%d?           d@Z& e%dA            e"e&          Z' e%e'            e%dB           g dCZ( e%dD e)e(          z              e#e(          Z* e%e*           dS dS )Fz A Fast, Offline Reverse Geocoder in Python

A Python library for offline reverse geocoding. It improves on an existing library
called reverse_geocode developed by Richard Penman.
    )print_functionzAjay ThampiNwin32i)cKDTree)
cKDTree_MPz)http://download.geonames.org/export/dump/
cities1000zadmin1CodesASCII.txtzadmin2Codes.txt	geoNameIdname   	asciiName   alternateNames   latitude   	longitude   featureClass   featureCode   countryCode   cc2	   
admin1Code
   
admin2Code   
admin3Code   
admin4Code   
population   	elevation   dem         )timezonemodificationDate)concatCodesr	   r   r   latlonr	   admin1admin2cczrg_cities1000.csvgn#@gk{?c                      i  fd}|S )z@
    Function to get single instance of the RGeocoder class
    c                  2    vr di | <            S )zI
        Creates a new RGeocoder instance if not created already
         r6   )kwargscls	instancess    a/home/louicyp/clawd-clean/.venv-aircash/lib/python3.11/site-packages/reverse_geocoder/__init__.pygetinstancezsingleton.<locals>.getinstanceS   s/     i S]]6]]IcN~    r6   )r8   r;   r9   s   ` @r:   	singletonr=   N   s1     I      r<   c                   ,    e Zd ZdZd	dZd Zd Zd ZdS )
	RGeocoderz)
    The main reverse geocoder class
    r   TNc                 *   || _         || _        |r|                     |          \  }| _        n/|                     t          t                              \  }| _        |dk    rt          |          | _        dS t          j
        |          | _        dS )aZ   Class Instantiation
        Args:
        mode (int): Library supports the following two modes:
                    - 1 = Single-threaded K-D Tree
                    - 2 = Multi-threaded K-D Tree (Default)
        verbose (bool): For verbose output, set to True
        stream (io.StringIO): An in-memory stream of a custom data source
        r
   N)modeverboseload	locationsextractrel_pathRG_FILEKDTreetree	KDTree_MPr   )selfrA   rB   streamcoordinatess        r:   __init__zRGeocoder.__init__a   s     	 	J*.))F*;*;'K*.,,x7H7H*I*I'K199{++DIII!,[99DIIIr<   c                       j         dk    r  j                            |d          \  }}n j                            |d          \  }} fd|D             S )z
        Function to query the K-D tree to find the nearest city
        Args:
        coordinates (list): List of tuple coordinates, i.e. [(latitude, longitude)]
        r
   )kc                 *    g | ]}j         |         S r6   )rD   ).0indexrK   s     r:   
<listcomp>z#RGeocoder.query.<locals>.<listcomp>   s     ;;;%u%;;;r<   )rA   rI   querypquery)rK   rM   _indicess   `   r:   rU   zRGeocoder.queryv   se     9>>::JAww))+);;JAw;;;;7;;;;r<   c                 F   t          j        |d          }|j        }|t          k    r5t          j        ddd                    t                    z  z   dz             g g }}|D ]:}|                    |d         |d         f           |                    |           ;||fS )aA  
        Function that loads a custom data source
        Args:
        stream (io.StringIO): An in-memory stream of a custom data source.
                              The format of the stream must be a comma-separated file
                              with header containing the columns defined in RG_COLUMNS.
        ,	delimiterz<Input must be a comma-separated file with header containing z2the following columns - %s. For more help, visit: z-https://github.com/thampiman/reverse-geocoderr/   r0   )csv
DictReader
fieldnames
RG_COLUMNSErrorjoinappend)rK   rL   stream_readerheader
geo_coordsrD   rows          r:   rC   zRGeocoder.load   s     v===)Z)ZDQ[H\H\]^?@ A A A
 !#BI
  	" 	"Cs5z3u:6777S!!!!9$$r<   c                 N	   t           j                            |          r:| j        rt	          d           t          j        t          |d                    }nt          t          z   dz   }t          t          z   }t          t          z   }t          dz   }t          dz   }t           j                            |          s| j        rt	          d           	 ddl}|j                            ||           |j                            |t                     |j                            |t                     n`# t          $ rS ddl}|                    ||           |                    |t                     |                    |t                     Y nw xY w| j        rt	          d           t#          j        t          |d	                    }	t          |d
                              |	                    |                     | j        rt	          d           i }
t          j        t          t          d          d          }|D ])}|t,          d                  |
|t,          d                  <   *| j        rt	          d           i }t          j        t          t          d          d          D ])}|t,          d                  ||t,          d                  <   *| j        rt	          d           t          j        t          |d          t0                    }g }t          j        t          |d          dt
          j                  D ]}|t4          d                  }|t4          d                  }|t4          d                  }|t4          d                  }|t4          d                  }|t4          d                  }|dz   |z   }|dz   |z   dz   |z   }d}d}||
v r|
|         }||v r||         }||||||d}|                    |           |                                 |                    |           | j        rt	          d           t          j        |           g g }}|D ]:}|                    |d         |d         f           |                    |           ;||fS ) z
        Function loads the already extracted GeoNames cities file or downloads and extracts it if
        it doesn't exist locally
        Args:
        local_filename (str): Path to local RG_FILE
        z"Loading formatted geocoded file...rtz.zipz.txtz!Downloading files from Geoname...r   NzExtracting cities1000...rbwbzLoading admin1 codes...	r[   r   r-   zLoading admin2 codes...z#Creating formatted geocoded file...wt)r_   )r\   quotingr   r   r   r   r   . r.   z.Removing extracted cities1000 to save space...r/   r0   )ospathexistsrB   printr]   r^   openGN_URLGN_CITIES1000	GN_ADMIN1	GN_ADMIN2urllib.requestrequesturlretrieveImportErrorurllibzipfileZipFilewritereadreaderADMIN_COLUMNS
DictWriterr`   
QUOTE_NONE
GN_COLUMNSrc   writeheader	writerowsremove)rK   local_filenamerowsgn_cities1000_urlgn_admin1_urlgn_admin2_urlcities1000_zipfilenamecities1000_filenamer~   _z
admin1_mapt_rowsrg   
admin2_mapwriterr/   r0   r	   r3   admin1_cadmin2_c	cc_admin1	cc_admin2r1   r2   	write_rowrf   rD   s                               r:   rE   zRGeocoder.extract   s    7>>.)) R	+| <:;;;>$~t"<"<==DD & 6 ?"Y.M"Y.M%2V%;""/&"87>>"899 A< ?=>>>	A))))N../@BXYYYN..}iHHHN..}iHHHH" A A A!MMM&&'8:PQQQ&&}i@@@&&}i@@@@@	A | 20111&<d!C!CDDB$d++11"'':M2N2NOOO| 1/000JZY 5 5FFFF ` `@CMR]D^@_
3}];<==| 1/000Jz$y$"7"74HHH ` `@CMR]D^@_
3}];<==| =;<<<^D$>$>:VVVFDz$':D"A"A"CN< < < ' '*Z01*[12:k23M23z,78z,78sF8O	sF8OC/8	
**'	2F
**'	2F#&#&$(&,&,"$& &	 I&&&&   T"""| HFGGGI)*** !#BI
 	" 	"Cs5z3u:6777S!!!!9$$s   AD4 4AFF)r   TN)__name__
__module____qualname____doc__rN   rU   rC   rE   r6   r<   r:   r?   r?   \   sd         : : : :*
< 
< 
<% % %0`% `% `% `% `%r<   r?   c                 ~   t          j        |                               t           j                  } | d d df         }| d d df         }t          j        |          }t          j        |          }t
          t          j        dt          t          j        |          dz  z  z
            z  }|t          j	        |          z  t          j	        |          z  }|t          j	        |          z  t          j        |          z  }|dt          z
  z  t          j        |          z  }t          j
        |||g          S )Nr   r
   r   )npasarrayastypefloatradiansAsqrtE2sincoscolumn_stack)	rf   r/   r0   lat_rlon_rnormalxyzs	            r:   geodetic_in_ecefr      s    J''..rx88J
QQQT
C
QQQT
CJsOOEJsOOE"'!bBF5MMQ$677889F.A.A!b&BF3KK'A?Aq!9%%%r<   c                     t           j                            t          j                    t           j                            t
                    |           S )z:
    Function that gets relative path to the filename
    )rq   rr   rb   getcwddirname__file__)filenames    r:   rF   rF     s0     7<<	RW__X%>%>IIIr<   Tc                     t          | t                    rt          | d         t                    st          d          t	          ||          }|                    | g          d         S )z3
    Function to query for a single coordinate
    r   zExpecting a tuplerA   rB   )
isinstancetupler   	TypeErrorr?   rU   )	geo_coordrA   rB   _rgs       r:   getr     se     i'' -z)A,/N/N -+,,,
w
/
/
/C99i[!!!$$r<   c                     t          | t                    s$t          | t                    st          d          t          | d         t                    s| g} t	          ||          }|                    |           S )z5
    Function to query for a list of coordinates
    z+Expecting a tuple or a tuple/list of tuplesr   r   )r   r   listr   r?   rU   )rf   rA   rB   r   s       r:   searchr     sw     j%(( "J1M1M "EFFF
1u-- " \

w
/
/
/C99Z   r<   __main__z(Testing single coordinate through get...)g?:uB@g5!^zReverse geocoding 1 city...zTesting coordinates...))gv)I@g֫#ƿ)g?#@g衶S@)gvOjB@gAc]^zReverse geocoding %d cities...)r   T)+r   
__future__r   
__author__rq   sysr]   platformfield_size_limitmaxsizer   scipy.spatialr   rH   reverse_geocoderr   rJ   numpyr   rv   rw   rx   ry   r   r   r`   rG   r   r   r=   objectr?   r   rF   r   r   r   rt   cityresultcitieslenresultsr6   r<   r:   <module>r      s5   
 & % % % % %
 				 



 



<7 C!!!!C%%%  + + + + + + 4 4 4 4 4 4    	4"		
A  a	
   A 1 1 
1 " " " " "  !" 
2#$ '  
0 	   
      ]% ]% ]% ]% ]% ]% ]% ]%~& & &J J J% % % %
! 
! 
! 
! z	E
4555!D	E
'(((SYYF	E&MMM	E
"###VVVF	E
*SS[[
8999fVnnG	E'NNNNN r<   