o
    g                     @   s&  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	m
Z
mZmZmZmZmZmZmZ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 G dd dZG d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!d"Z)dS )$    Nslugify)CityCountryDemographicDistrictIso31662Location
LondonAreaLondonZipState
LondonZonePostCodePriceGrowthPropertyDataRawRegionsettings)GEOSGeometryPolygonMultiPolygonc                   @   s2   e Zd ZddddZdd Zdd Zdd
dZdS )
StreetViewNreturnc                 C   s
   || _ d S N)api_key)selfr    r   3/var/www/Entralon-Web-Backend/geo_location/utils.py__init__      
zStreetView.__init__c                 C   s   t j||d}|S )N)latlon)
streetviewsearch_panoramas)r   r   r    psr   r   r   get_panoramas   s   zStreetView.get_panoramasc                    s,   t j|dI d H }|d| dd |S )N)pano_id
downloads/.jpgjpeg)r!   get_panorama_asyncsave)r   idimager   r   r   r)      s   zStreetView.get_panorama_async   c                 C   s&   t j||d}|d| dd d S )N)r%   zoomr&   r'   r(   )r!   get_panoramar*   )r   r+   r.   r,   r   r   r   r/      s   zStreetView.get_panoramar   r   N)r-   )__name__
__module____qualname__r   r$   r)   r/   r   r   r   r   r      s
    r   c                   @   sP   e Zd ZddlmZ edej d dZddd	Z	dddZ
dd ZdS )GeoLocationr   )	Nominatimz	Entralon/z%Y%m%d%H)
user_agentr   Nc                 C   s
   i | _ d S r   )location)r   r   r   r   r   %   r   zGeoLocation.__init__enc                 C   s"   | j j|dd|d|d}|S )Nz.6fz, )language)geo_locatorreverse)r   r   r    r9   r7   r   r   r   get_address(   s   zGeoLocation.get_addressc                 C   s   | j |}|S r   )r:   geocode)r   addressr7   r   r   r   get_location,   s   zGeoLocation.get_locationr0   )r8   )r1   r2   r3   geopy.geocodersr5   datetimenowstrftimer:   r   r<   r?   r   r   r   r   r4       s    

r4   c                  C   s   t jjdd} td|    t }| D ])}td|j  ||jj	|jj
}|d ur:|j|_|j|_|  qt| qd S )NT)address__isnullzlocation num: zlocation id: )r	   objectsfilterprintcountr4   r+   r<   coordinatesyxr>   rawr*   )	locationsgeo_locationr7   glr   r   r   check_location_address1   s   

rP   c            <      C   s  t j d} tjjdd}tdD ]}t|  d| dddd	}t|}W d    n1 s1w   Y  |d
 D ][}|d}|dd}|dkrN|nd }|dd}|dkr\|nd }|dd}	|	dkrj|	nd }	|dd}
|
dkrx|
nd }
|dd}|dkr|nd }|dd}|dkrt	
dd|nd }|dd}|dkrt	
dd|nd }|dd}|dkrt	
dd|nd }|dd}|dkrt	
dd|nd }|dd}|dkrt	
dd|nd }|dd}|dkrt	
dd|nd }|dd}|dkr|nd }|dd}|dkr|nd }|dd}|dkr%|nd }|dd}|dkr4|nd }|dd}|dkrC|nd }|dd}|dkrR|nd }|d d}|dkra|nd }|d!d}|dkrp|nd }|d"d}|dkr|nd }|d#d}|dkr|nd }|d$d}|dkr|nd }|d%d}|dkr|nd }|d&d}|dkr|nd }|d'd}|dkr|nd }|d(d} | dkr| nd } |d)d}!|!dkrt	
dd|!nd }!|d*d}"|"dkrt	
dd|"nd }"|d+d}#|#dkrt	
dd|#nd }#|d,d}$|$dkr)t	
dd|$nd }$|d-d}%|%dkr=t	
dd|%nd }%|d.d}&|&dkrL|&nd }&|d/d}'|'dkr[|'nd }'|d0d}(|(dkrj|(nd }(|d1d})|)dkry|)nd })|d2d}*|*dkr|*nd }*|d3d}+|+dkr|+nd }+|d4d},|,dkr|,nd },|d5d}-|-dkr|-nd }-|d6d}.|.dkr|.nd }.|d7d}/|/dkr|/nd }/|d8d}0|0dkr|0nd }0d }1d }2d }3d }4d }5d }6|dkr|}3|}5z	tjj|
d9}4W nt   Y no|dkr(|$pd:}2|
}3|p|
}5z	tjj|	d9}4W nT   Y nO|d;krH|#p1d<}2|	}3|p8|	}5z	tjj|d9}4W n4   Y n/|d=krj|"pQd>}2|0}1|}3|pZ|}5z	tjj|d9}4W n   Y n|d?krwd@}2|}1|}3|}5|5d u rtdA| dB| dC| dC|	 dC|
 dC|  q:t|5dDdE}6|dF}7t|7}8t|8}9z	tjj|3d9}:W n   tjj|6|3|5|dG}:Y ||:_|1|:_|5|:_|9|:_|2|:_|3|:_|4|:_||:_||:_|	|:_|
|:_||:_||:_||:_||:_||:_ ||:_!||:_"||:_#||:_$||:_%||:_&||:_'||:_(||:_)||:_*||:_+||:_,||:_-||:_.||:_/| |:_0|!|:_1|"|:_2|#|:_3|$|:_4|%|:_5|&|:_6|'|:_7|(|:_8|)|:_9|*|:_:|+|:_;|,|:_<|-|:_=|.|:_>|/|:_?|0|:_@|:A  tBjjC|:jdH};|d?krg|;jD|:dI q:|d=krs|;jD|:dJ q:|d;kr|;jD|:dK q:|dkr|;jD|:dL q:|dkr|;jD|:dM q:qtjjd;d}tdND ]}t|  dO| dddd	}t|}W d    n	1 sw   Y  |d
 D ]q}|d}|dd}|dkr|nd }|dd}|dkr|nd }|dd}	|	dkr |	nd }	|dd}
|
dkr|
nd }
|dd}|dkr|nd }|dd}|dkr2t	
dd|nd }|dd}|dkrFt	
dd|nd }|dd}|dkrZt	
dd|nd }|dd}|dkrnt	
dd|nd }|dd}|dkrt	
dd|nd }|dd}|dkrt	
dd|nd }|dd}|dkr|nd }|dd}|dkr|nd }|dd}|dkr|nd }|dd}|dkr|nd }|dd}|dkr|nd }|dd}|dkr|nd }|d d}|dkr|nd }|d!d}|dkr|nd }|d"d}|dkr|nd }|d#d}|dkr,|nd }|d$d}|dkr;|nd }|d%d}|dkrJ|nd }|d&d}|dkrY|nd }|d'd}|dkrh|nd }|d(d} | dkrw| nd } |d)d}!|!dkrt	
dd|!nd }!|d*d}"|"dkrt	
dd|"nd }"|d+d}#|#dkrt	
dd|#nd }#|d,d}$|$dkrt	
dd|$nd }$|d-d}%|%dkrt	
dd|%nd }%|d.d}&|&dkr|&nd }&|d/d}'|'dkr|'nd }'|d0d}(|(dkr|(nd }(|d1d})|)dkr|)nd })|d2d}*|*dkr&|*nd }*|d3d}+|+dkr5|+nd }+|d4d},|,dkrD|,nd },|d5d}-|-dkrS|-nd }-|d6d}.|.dkrb|.nd }.|d7d}/|/dkrq|/nd }/|d8d}0|0dkr|0nd }0d }1d }2d }3d }4d }5d }6|dkr|}3|}5|%pdP}2z	tjj|
d9}4W nt   Y no|dkr|$pdQ}2|
}3|p|
}5z	tjj|	d9}4W nT   Y nO|d;kr|#pdR}2|	}3|p|	}5z	tjj|d9}4W n4   Y n/|d=kr|"pdS}2|0}1|}3|p|}5z	tjj|d9}4W n   Y n|d?krd@}2|}1|}3|}5|5d u r7tdT| dB| dC| dC|	 dC|
 dC|  qt|5dDdE}6|dF}7t|7}8t|8}9z	tjj|3d9}:W n   tjj|6|3|5|dG}:Y ||:_|1|:_|5|:_|9|:_|2|:_|3|:_|4|:_||:_||:_|	|:_|
|:_||:_||:_||:_||:_||:_ ||:_!||:_"||:_#||:_$||:_%||:_&||:_'||:_(||:_)||:_*||:_+||:_,||:_-||:_.||:_/| |:_0|!|:_1|"|:_2|#|:_3|$|:_4|%|:_5|&|:_6|'|:_7|(|:_8|)|:_9|*|:_:|+|:_;|,|:_<|-|:_=|.|:_>|/|:_?|0|:_@|:A  tBjjC|:jdH};|d?k	r|;jD|:dI q|d=k	r|;jD|:dJ q|d;k	r&|;jD|:dK q|dk	r3|;jD|:dL q|dk	r>|;jD|:dM q͐qd S )UN/geo_location/files   r+      z/gadm41_ARE_z.jsonrutf8encodingfeatures
propertiesGID_0NAGID_1GID_2GID_3GID_4NAME_0z(\w)([A-Z])z\1 \2NAME_1NAME_2NAME_3NAME_4COUNTRY	NL_NAME_0	NL_NAME_1	NL_NAME_2	NL_NAME_3	NL_NAME_4	VARNAME_0	VARNAME_1	VARNAME_2	VARNAME_3	VARNAME_4TYPE_0TYPE_1TYPE_2TYPE_3TYPE_4	ENGTYPE_0	ENGTYPE_1	ENGTYPE_2	ENGTYPE_3	ENGTYPE_4CC_0CC_1CC_2CC_3CC_4HASC_0HASC_1HASC_2HASC_3HASC_4ISO_1)gidMunicipality   zMunicipal Regionr-   Emirater   r   ARE_z name error:  Tallow_unicodegeometry)slugr   namecountrycoordinates__intersects)iso_3166_2_lvl_0)iso_3166_2_lvl_1)iso_3166_2_lvl_2)iso_3166_2_lvl_3)iso_3166_2_lvl_4   z/gadm41_GBR_zMetropolitan District WardzUnitary AuthorityzMetropolitan Borough (City)zConstituent CountryGBR_)Er   BASE_DIRr   rE   getrangeopenjsonloadresubr   rG   r   dumpsr   createlevelcoder   rI   typer   parentgid_0gid_1gid_2gid_3gid_4name_0name_1name_2name_3name_4	nl_name_0	nl_name_1	nl_name_2	nl_name_3	nl_name_4
var_name_0
var_name_1
var_name_2
var_name_3
var_name_4type_0type_1type_2type_3type_4
eng_type_0
eng_type_1
eng_type_2
eng_type_3
eng_type_4cc_0cc_1cc_2cc_3cc_4hasc_0hasc_1hasc_2hasc_3hasc_4iso_1r*   r	   rF   update)<dirr   ifiledatadl_propertiesr   r   r   r   r   r   r   r   r   r   country_namer   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   geo_typer   r   r   r   
l_geometrygeom_strgeomisorM   r   r   r   set_iso_3166A   s   
















,






  O

















,






 r   c                  C   s  t j d} t|  dddd}t|}W d    n1 s w   Y  |D ]?}|d d}|d d}|d urKtjjd	d
}tjjd	d
}ntjjdd
}tjjdd
}t	|dd}|d}	|d}
zt
|
}t|}t|tryn
t|trt|g}|	dkrz	tjj|d}W n   tjj||d}Y ||_||_||_|  n|	dkrz	tjj|d}W n   tjj||d}Y ||_||_||_|  ns|	dkrz	tjj|d}W n   tjj||d}Y ||_||_||_|  nK|	dkr$z	tjj|d}W n   tjj||d}Y ||_||_||_|  n"|	dkrFz	tjj|d}W n   tjj||d}Y ||_|  W q' tyg } ztd| d|	 d|  W Y d }~q'd }~ww d S )NrQ   z
/area.jsonrU   rV   rW   rZ   Name	LocalNamerR   rS   r   r-   Tr   Categoryr   zipstate)r   )r   r   zonearea	districtscityzfor z type z error: )r   r   r   r   r   r   r   rE   r   r   r   r   
isinstancer   r   r   r   r   r   rI   r*   r   r
   r   	ExceptionrG   )r   r   r   r   r   
local_namer   r   r   categoryr   r   r   	zip_stater   r   districter   r   r   set_area  sv   









&r   c                  C   sb  t j D ]} | jd urtjj| jdj| d qtj D ]} | jd ur1tjj| jdj| d qtj D ]} | jd urJtjj| jdj| d q7t	j D ]} | jd urctjj| jdj| d qPt
j D ]} | jd ur|tjj| jdj| d qitj D ]} | jd urtjj| jdj| d qt	j D ]} | jd urtjj| jdj| d qd S )Nr   )r   )r   )r   )london_zip_state)london_area)london_zone)r   rE   allrI   r	   rF   r   r   r   r   r
   r   )objr   r   r   get_are_locations&  s,   """""""r   c                  C   s  ddl m}  ddlm} | j d}tjjdd}t| ddd	d
}t	
|}W d    n1 s3w   Y  ddddddddddddd}|d}|D ]~}|d}|d}	|d}
d }d }|
D ]f}t|d dd  }zt||d d d }W n   d}Y t|d }|r|| nd }|}|d rt|d d d  nd }t||d}ztjj|||d! W qe   tjj||||	|||d" Y qeqNd S )#Nr   r   r   rQ   r   rS   z/propdata-uk-growth.jsonrU   rV   rW   123456789101112JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDECgrowthpostcodepostcode_typer   rR      r-   r   r  date)r   r  r  r  priceprice_changechange_percent)django.confr   django.utils.textr   r   r   rE   r   r   r   r   intfloatrA   r  r   r   )r   r   r   r   r   r   MONTHg_dr  r  g_data
last_priser  gyearmonthr  r  r  r   r   r   set_price_growth7  s<   



  $r%  c                  C   s  ddl m}  ddlm} | j d}tjjdd}t| ddd	d
}t	
|}W d    n1 s3w   Y  |d}|D ]}|d}z	tjj|d}W n   d }Y |d}	|d}
|
d}|dkrkd }|
d}|dkrvd }|
d}|dkrd }|
d}|dkrd }|
d}|dkrd }|
d}|dkrd }|
d}|dkrd }|
d}|dkrd }z
tjj||d}W n   tjj||d}Y ||_|	|_||_||_||_||_||_||_||_||_|  q?d S )Nr   r   r   rQ   r   rS   z/propdata-uk-demographics.jsonrU   rV   rW   demogr  )out_coder  r   deprivationInsufficient datahealthsocial_gradeagepoliticsproportion_with_degreevehicles_per_householdcommute_methodr   r  )r  r   r  r   r   r   rE   r   r   r   r   r   r   r   	post_coder  r(  r*  r+  r,  r-  r.  r/  r0  r*   )r   r   r   r   r   r   r  r  r2  r  r   r(  r*  r+  r,  r-  r.  r/  r0  demographicr   r   r   set_demographicsS  sX   












r4  c                  C   s  g d} t jjdd}| D ]b}d| }|dd }t|dd}tjj|||d	\}}tjj|dd
\}}i }|j	rA|j	}n!t
j|dd}	|	jdkr\|	 }||_	d|_|  nt|	j q|ddkrd|dD ]}
|
d}|
d}|
d}|
d}z|rt|d d }W n   td| d| d d }Y |
d}z|rt|d d }W n   td| d| d d }Y |
d}z|rt|d d }W n   td| d| d d }Y |
d}z|rt|d d }W n   td| d| d d }Y |
d }|
d!}z|r"t|d d }W n   td| d"| d d }Y tjj||d#\}}||_||_||_||_||_||_||_||_|  d|_|  qont|d$ td% qd S )&N)
north_east
north_westeast_midlandswest_midlandseast_of_englandgreater_london
south_east
south_westwalesscotlandnorthern_irelandr   rS   zHhttps://api.propertydata.co.uk/postcode-key-stats?key=YYRZRTTGG5&region=_r   Tr   )r   r   r   )regionr      timeout   Fstatussuccessr   outcode	avg_priceavg_rent	avg_yieldr  z	postcode z avg_yield z error	growth_1yz growth_1y 	growth_3yz growth_3y 	growth_5yz growth_5y sales_per_monthturnoverz
 turnover )r'  rA  messagerR   )r   rE   r   replacetitler   r   get_or_creater   r   requestsstatus_coder   checkedr*   rG   r  r   rI  rJ  rK  rL  rM  rN  rO  rP  timesleep)regionsr   rA  urlregion_nameregion_slugr@  pdrr   reqr   r'  rI  rJ  rK  rL  rM  rN  rO  rP  r2  r   r   r   get_uk_postcodes  s   














0r`  c                  C   s  t jjdd} tj }ddddddd	d
ddddd}|D ]}d|j }tjj|dd\}}i }|jr:|j}d}n%t	j|dd}	d}|	j
dkrW|	 }||_d|_|  nt|j|	j
 q|ddkr|d}
|d}|d}d }d }|D ]u}t|d dd  }zt||d d d }W n   d}Y t|d  }|r|| nd }|}|d rt|d d d! nd }t||d }ztjj| |
|d"}W n   tjj| |
|d"}Y ||_||_||_||_||_|  q{t|j d# |rtd qd S )$Nr   rS   r   r   r   r   r   r   r   r   r   r   r   r  r  z>https://api.propertydata.co.uk/growth?key=RORUV4AKHU&postcode=r   r  r   FrB  rC  TrE  rF  rG  r  r  r   r  rR   r  r-   r  r   check data)r   rE   r   r   r   r'  r   rT  r   rU  rV  r   rW  r*   rG   r  r  rA   r  r   r   r2  r  r  r  r  rX  rY  )r   
post_codesr  r2  r[  r^  r@  r   send_rr_  r  r  r   r!  r  r"  r#  r$  r  r  r  pgr   r   r   get_price_growth  s`   





  
rf  c                  C   s4  t jjdd} tj }ddddddd	d
ddddd}|D ]}d|j }tjj|dd\}}i }|jr:|j}d}n%t	j|dd}	d}|	j
dkrW|	 }||_d|_|  nt|j|	j
 q|ddkr|d}
|d}|d}|d}|dkrd }|d}|dkrd }|d }|dkrd }|d!}|dkrd }|d"}|dkrd }|d#}|dkrd }|d$}|dkrd }|d%}|dkrd }z
tjj| |
d&}W n   tjj| |
d&}Y ||_||_||_||_||_||_||_||_||_||_|  t|j d' |rtd qd S )(Nr   rS   r   r   r   r   r   r   r   r   r   r   r   r  r  zDhttps://api.propertydata.co.uk/demographics?key=RORUV4AKHU&postcode=rR   ra  FrB  rC  TrE  rF  rG  r  r  r   r(  r)  r*  r+  r,  r-  r.  r/  r0  r1  rb  )r   rE   r   r   r   r'  r   rT  r   rU  rV  r   rW  r*   rG   r   r   r2  r  r(  r*  r+  r,  r-  r.  r/  r0  rX  rY  )r   rc  r  r2  r[  r^  r@  r   rd  r_  r  r  r   r(  r*  r+  r,  r-  r.  r/  r0  r3  r   r   r   get_demographics  st   













rg  c                 C   s   d}d|  d| d| d| d|  d| d| d| d}t j||dd}| }g }|d D ]6}	d	|	v re|	d
 |	d |	d	 d|	d	 d|	d	 d|	d	 d|	dd|	ddd}
||
 q/|S )zv
    Get schools within a bounding box using Overpass API
    Parameters are coordinates defining the area bounds
    'https://overpass-api.de/api/interpreterzC
    [out:json][timeout:25];
    (
        way["amenity"="school"](,z$);
        node["amenity"="school"](4);
    );
    out body;
    >;
    out skel qt;
    rB  r   rD  elementstagsr+   r   name:enzisced:leveloperatorz	addr:fullr   r   r    )r+   r   r   isced_levelro  r>   r   r    rU  postr   r   append)southwestnortheastoverpass_urlqueryresponser   schoolselementschoolr   r   r   get_schools_in_areaI  sF   



r~  c                 C   s   d}d|  d| d| d| d|  d| d| d| d|  d| d| d| d}t j||dd}| }g }|d	 D ]1}	d
|	v rl|	d |	d
 d|	d
 d|	d
 d|	d
 d|	d|	dd}
||
 q;|S )z
    Get subway/metro stations within a bounding box using Overpass API
    Parameters are coordinates defining the area bounds
    rh  zD
    [out:json][timeout:25];
    (
        node["station"="subway"](ri  z5);
        node["railway"="station"]["subway"="yes"](z#);
        node["station"="metro"](rj  rB  rk  rl  rm  r+   rn  networkro  liner   r    )r+   r   r  ro  linesr   r    rq  )rt  ru  rv  rw  rx  ry  rz  r   stationsr|  stationr   r   r   get_subway_stationsp  sT   
	r  foot-walkingc              
   C   s   t j}d|dd}|| g||ggdd}d| }zAtj|||dd}	|	 }
d	|
v rX|
d	 d
 }|d d }|d d }t|t|t|d d dt|d  ddW S W dS  tyt } ztd|  W Y d}~dS d}~ww )z
    Calculate distance and duration between two points using OpenRouteService API
    mode options: foot-walking, driving-car, cycling-regular
    zSapplication/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8zapplication/json; charset=utf-8)AcceptAuthorizationzContent-Typefalse)rI   instructionsz/https://api.openrouteservice.org/v2/directions/rB  )r   headersrD  routesr   summarydistancedurationi  r   z km<   z mins)r  r  distance_textduration_textz%Error calculating distance/duration: N)r   OPENROUTE_API_KEYrU  rr  r   roundr   rG   )
origin_lat
origin_lngdest_latdest_lngmoder   r  bodyr[  rz  r   router  r  r   r   r   r   calculate_distance_duration  s6   
r  )r  )*rA   r   r   rX  rU  r!   r  r   geo_location.modelsr   r   r   r   r   r	   r
   r   r   r   r   r   r   r  r   django.contrib.gis.geosr   r   r   r   r4   rP   r   r   r   r%  r4  r`  rf  rg  r~  r  r  r   r   r   r   <module>   s8    <   *>.Y2=''