Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,255 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import streamlit as st
|
3 |
+
import requests
|
4 |
+
import pydeck as pdk
|
5 |
+
import pandas as pd
|
6 |
+
import geopandas as gpd
|
7 |
+
import plotly.express as px
|
8 |
+
import folium
|
9 |
+
import webbrowser
|
10 |
+
from shapely.geometry import Point
|
11 |
+
from folium import plugins
|
12 |
+
from streamlit_folium import st_folium
|
13 |
+
|
14 |
+
def load_polygon(filepath):
|
15 |
+
return gpd.read_file(filepath)
|
16 |
+
path='Z:/Shared/Axeria Shared/Pricing/Immopolis Pricing Review/DATA/'
|
17 |
+
# Polygon1 = load_polygon(path + 'risk_zones.shp')
|
18 |
+
# Polygon2 = load_polygon(path + 'Flooding/n_inondable_01_01for_s.shp')
|
19 |
+
# Polygon3 = load_polygon(path + 'ZUS/ZUS_FRM_BDA09_L93.shp')
|
20 |
+
#
|
21 |
+
|
22 |
+
# Initialize polygons if not already in session state
|
23 |
+
if 'polygons' not in st.session_state:
|
24 |
+
st.session_state.polygons = {
|
25 |
+
"Polygon1": load_polygon(path+'risk_zones.shp'),
|
26 |
+
"Polygon2": load_polygon(path+'Flooding/n_inondable_01_01for_s.shp'),
|
27 |
+
"Polygon3": load_polygon(path+'ZUS/ZUS_FRM_BDA09_L93.shp')
|
28 |
+
}
|
29 |
+
|
30 |
+
if 'polygons' in st.session_state:
|
31 |
+
st.session_state.polygons["Polygon1"]['geometry'] = st.session_state.polygons["Polygon1"]['geometry'].to_crs(epsg=4326)
|
32 |
+
st.session_state.polygons["Polygon2"]['geometry'] = st.session_state.polygons["Polygon2"]['geometry'].to_crs(epsg=4326)
|
33 |
+
st.session_state.polygons["Polygon3"]['geometry'] = st.session_state.polygons["Polygon3"]['geometry'].to_crs(epsg=4326)
|
34 |
+
|
35 |
+
#Polygon1['geometry'] = Polygon1['geometry'].to_crs(epsg=4326)
|
36 |
+
#Polygon2=load_polygon(path+'Flooding/n_inondable_01_01for_s.shp')
|
37 |
+
# Polygon1=load_polygon(path+'risk_zones.shp')
|
38 |
+
# Polygon1['geometry'] = Polygon1['geometry'].to_crs(epsg=4326)
|
39 |
+
# Polygon2=load_polygon(path+'Flooding/n_inondable_01_01for_s.shp')
|
40 |
+
# Polygon3=load_polygon(path+'ZUS/ZUS_FRM_BDA09_L93.shp')
|
41 |
+
|
42 |
+
# # Function to plot an interactive histogram
|
43 |
+
# # fig = px.histogram(polygon_gdf['poverty'], nbins=20)
|
44 |
+
# # st.plotly_chart(fig)
|
45 |
+
# fig = px.ecdf(polygon_gdf['poverty'])
|
46 |
+
# fig.show()
|
47 |
+
# # # #28% --> 5% of squares
|
48 |
+
# # #
|
49 |
+
# # #
|
50 |
+
# fig = px.ecdf(polygon_gdf['densite'])
|
51 |
+
# # #9000 --> 5% of squares
|
52 |
+
# fig.show()
|
53 |
+
# #
|
54 |
+
# #
|
55 |
+
# #
|
56 |
+
# # #Load geographical layers
|
57 |
+
#
|
58 |
+
|
59 |
+
# zus=gpd.read_file(path+'ZUS/ZUS_FRM_BDA09_L93.shp')
|
60 |
+
# polygon_gdf = gpd.read_file(path+'Geo_metropole/Filosofi2017_carreaux_nivNaturel_met.shp')
|
61 |
+
# polygon_gdf2 = gpd.read_file(path+'Filosofi2017_carreaux_1km_shp/Filosofi2017_carreaux_1km_met.shp')
|
62 |
+
# polygon_gdf2['densite']=polygon_gdf2['Ind']
|
63 |
+
# polygon_gdf2['poverty']=polygon_gdf2['Men_pauv']/polygon_gdf2['Men']
|
64 |
+
# polygon_gdf['tmaille']=pd.to_numeric(polygon_gdf['tmaille'])
|
65 |
+
# polygon_gdf['tmaillem2']=polygon_gdf['tmaille']**2
|
66 |
+
# polygon_gdf['densite']=1000000*polygon_gdf['Ind']/polygon_gdf['tmaillem2']
|
67 |
+
# polygon_gdf['poverty']=polygon_gdf['Men_pauv']/polygon_gdf['Men']
|
68 |
+
|
69 |
+
|
70 |
+
# risk_zones2=polygon_gdf2[polygon_gdf2.poverty>=0.30]
|
71 |
+
# risk_zones2=risk_zones2[risk_zones2.densite>=7000]
|
72 |
+
#risk_zones2.to_file(filename=path+'risk_zones2.shp', driver='ESRI Shapefile')
|
73 |
+
|
74 |
+
# risk_zones=gpd.read_file(filename=path+'risk_zones.shp')
|
75 |
+
# flooding = gpd.read_file(path+'Flooding/n_inondable_01_01for_s.shp')
|
76 |
+
#
|
77 |
+
# #
|
78 |
+
# #
|
79 |
+
# # #FLooding zones
|
80 |
+
#risk_zones=polygon_gdf[polygon_gdf.poverty>=0.28]
|
81 |
+
# risk_zones=risk_zones[risk_zones.densite>=7000]
|
82 |
+
#
|
83 |
+
# risk_zones.to_file(filename=path+'risk_zones.shp', driver='ESRI Shapefile')
|
84 |
+
#
|
85 |
+
# # #
|
86 |
+
# m =folium.Map(location = [48.885805,2.366191], zoom_start = 6)
|
87 |
+
# folium.GeoJson(Polygon2[Polygon2.index<1000],color='blue').add_to(m)
|
88 |
+
#folium.CircleMarker([48.885805, 2.366191],radius=1,color='red').add_to(m)
|
89 |
+
# folium.GeoJson(flooding[flo,color='yellow').add_to(m)
|
90 |
+
# #folium.GeoJson(risk_zones2,color='orange').add_to(m)
|
91 |
+
# folium.GeoJson(zus).add_to(m)
|
92 |
+
# #
|
93 |
+
# #
|
94 |
+
# # # m.save(path+"map2.html")
|
95 |
+
# # # webbrowser.open_new_tab(path+"map2.html")
|
96 |
+
# # #
|
97 |
+
# # #
|
98 |
+
# policies = pd.read_pickle(path+"DB_immoplus.pkl")
|
99 |
+
# geometry = [Point(xy) for xy in zip(policies['longitude'], policies['latitude'])]
|
100 |
+
# policies_geo = gpd.GeoDataFrame(policies, geometry=geometry,crs="EPSG:4326")
|
101 |
+
# #
|
102 |
+
# large_claims=policies_geo[policies_geo.Charge>20000]
|
103 |
+
# large_claims=large_claims.dropna(subset=['latitude'])
|
104 |
+
# # #
|
105 |
+
# for arr in large_claims["geometry"]:
|
106 |
+
# lat=arr.y
|
107 |
+
# lon=arr.x
|
108 |
+
# folium.CircleMarker([lat, lon],radius=1,color='red').add_to(m)
|
109 |
+
# m.save(path+"map2.html")
|
110 |
+
# webbrowser.open_new_tab(path+"map2.html")
|
111 |
+
#
|
112 |
+
#
|
113 |
+
# sum(risk_zones['tmaille'])/sum(polygon_gdf['tmaille'])*100
|
114 |
+
# sum(risk_zones['Ind'])/sum(polygon_gdf['Ind'])*100
|
115 |
+
|
116 |
+
# #
|
117 |
+
# #
|
118 |
+
# #
|
119 |
+
# # flooding["zone_inond_freq"]=1
|
120 |
+
# # zus['flag_ZUS']=1
|
121 |
+
# # Function to get address suggestions from the Autocomplete API
|
122 |
+
def create_geodataframe(longitude, latitude):
|
123 |
+
geometry = [Point(longitude, latitude)]
|
124 |
+
gdf = gpd.GeoDataFrame(geometry=geometry, crs="EPSG:4326")
|
125 |
+
return gdf
|
126 |
+
|
127 |
+
def get_address_suggestions(query):
|
128 |
+
if not query:
|
129 |
+
return []
|
130 |
+
|
131 |
+
url = "https://api-adresse.data.gouv.fr/search/"
|
132 |
+
params = {'q': query, 'autocomplete': 1, 'limit': 5}
|
133 |
+
response = requests.get(url, params=params)
|
134 |
+
|
135 |
+
if response.status_code == 200:
|
136 |
+
data = response.json()
|
137 |
+
suggestions = [{'label': feature['properties']['label'], 'coordinates': feature['geometry']['coordinates']}
|
138 |
+
for feature in data['features']]
|
139 |
+
return suggestions
|
140 |
+
else:
|
141 |
+
return []
|
142 |
+
|
143 |
+
|
144 |
+
# Function to create a map
|
145 |
+
def create_map(latitude, longitude):
|
146 |
+
map_data = pd.DataFrame({
|
147 |
+
'lat': [latitude],
|
148 |
+
'lon': [longitude]
|
149 |
+
})
|
150 |
+
|
151 |
+
st.pydeck_chart(pdk.Deck(
|
152 |
+
map_style='mapbox://styles/mapbox/light-v9',
|
153 |
+
initial_view_state=pdk.ViewState(
|
154 |
+
latitude=latitude,
|
155 |
+
longitude=longitude,
|
156 |
+
zoom=11,
|
157 |
+
pitch=50,
|
158 |
+
),
|
159 |
+
layers=[
|
160 |
+
pdk.Layer(
|
161 |
+
'ScatterplotLayer',
|
162 |
+
data=map_data,
|
163 |
+
get_position='[lon, lat]',
|
164 |
+
get_color='[200, 30, 0, 160]',
|
165 |
+
get_radius=200,
|
166 |
+
),
|
167 |
+
],
|
168 |
+
))
|
169 |
+
|
170 |
+
|
171 |
+
# Streamlit app layout
|
172 |
+
def main():
|
173 |
+
st.title("Immopolis Adress validation APP")
|
174 |
+
|
175 |
+
# Session state to store the current suggestions
|
176 |
+
if 'suggestions' not in st.session_state:
|
177 |
+
st.session_state.suggestions = []
|
178 |
+
|
179 |
+
# Text input for address with on_change callback
|
180 |
+
query = st.text_input("Enter your address", "", key="query")
|
181 |
+
|
182 |
+
# Update suggestions when query changes
|
183 |
+
st.session_state.suggestions = get_address_suggestions(query)
|
184 |
+
|
185 |
+
# Display autocomplete suggestions
|
186 |
+
if query:
|
187 |
+
selected_suggestion = st.selectbox("Did you mean:", [s['label'] for s in st.session_state.suggestions], index=0,
|
188 |
+
key="selected_suggestion")
|
189 |
+
else:
|
190 |
+
selected_suggestion = ""
|
191 |
+
|
192 |
+
|
193 |
+
if selected_suggestion:
|
194 |
+
selected_data = next((item for item in st.session_state.suggestions if item['label'] == selected_suggestion),
|
195 |
+
None)
|
196 |
+
if selected_data and 'coordinates' in selected_data:
|
197 |
+
longitude, latitude = selected_data['coordinates']
|
198 |
+
st.write(f"Latitude: {latitude}, Longitude: {longitude}")
|
199 |
+
#m = folium.Map(location=[longitude, latitude], zoom_start=6)
|
200 |
+
gdf = create_geodataframe(longitude, latitude)
|
201 |
+
gdf['geometry'] = gdf['geometry'].to_crs(epsg=4326)
|
202 |
+
st.write(gdf)
|
203 |
+
#polygon_name1 = gdf.within(st.session_state.polygons["Polygon1"])
|
204 |
+
#st.write(polygon_name1[polygon_name1.isna()])
|
205 |
+
#polygon_name2 = gdf.within(st.session_state.polygons["Polygon2"])
|
206 |
+
polygon_name1=gpd.sjoin(gdf, st.session_state.polygons["Polygon1"], how="left", predicate="within")['index_right']
|
207 |
+
st.write(polygon_name1)
|
208 |
+
polygon_name2=gpd.sjoin(gdf, st.session_state.polygons["Polygon2"], how="left", predicate="within")['index_right']
|
209 |
+
st.write(polygon_name2)
|
210 |
+
|
211 |
+
polygon_name3=gpd.sjoin(gdf, st.session_state.polygons["Polygon3"], how="left", predicate="within")['index_right']
|
212 |
+
st.write(polygon_name3)
|
213 |
+
|
214 |
+
#st.write(polygon_name2)
|
215 |
+
#st.write(np.isnan(polygon_name2[0]))
|
216 |
+
|
217 |
+
#st.write(polygon_name2)
|
218 |
+
#latitude=48.885805
|
219 |
+
# longitude=2.366191
|
220 |
+
#polygon_name3 = gdf.within(st.session_state.polygons["Polygon3"])
|
221 |
+
# folium.GeoJson(risk_zones).add_to(m)
|
222 |
+
#gdf=policies_geo[1:1]
|
223 |
+
#m =folium.Map(location = [longitude, latitude], zoom_start = 10)
|
224 |
+
m=folium.Map([gdf['geometry'].y, gdf['geometry'].x],zoom_start = 15)
|
225 |
+
folium.CircleMarker([gdf['geometry'].y, gdf['geometry'].x], radius=1, color='red').add_to(m)
|
226 |
+
#folium.GeoJson(st.session_state.polygons["Polygon2"], color='blue').add_to(m)
|
227 |
+
folium.GeoJson(st.session_state.polygons["Polygon3"], color='orange').add_to(m)
|
228 |
+
|
229 |
+
if not np.isnan(polygon_name1[0]):
|
230 |
+
folium.GeoJson(st.session_state.polygons["Polygon1"][st.session_state.polygons["Polygon1"].index==polygon_name1[0]],color='yellow').add_to(m)
|
231 |
+
if not np.isnan(polygon_name2[0]):
|
232 |
+
folium.GeoJson(st.session_state.polygons["Polygon2"][st.session_state.polygons["Polygon2"].index==polygon_name2[0]],color='blue').add_to(m)
|
233 |
+
if not np.isnan(polygon_name3[0]):
|
234 |
+
folium.GeoJson(st.session_state.polygons["Polygon3"][st.session_state.polygons["Polygon3"].index==polygon_name3[0]],color='orange').add_to(m)
|
235 |
+
|
236 |
+
point = Point(longitude, latitude)
|
237 |
+
st_folium(m, width=700, height=500)
|
238 |
+
|
239 |
+
|
240 |
+
if not np.isnan(polygon_name1[0]):
|
241 |
+
st.markdown(f"Address is High risk zone", unsafe_allow_html=True)
|
242 |
+
|
243 |
+
if not np.isnan(polygon_name2[0]):
|
244 |
+
st.markdown(f"Address is in flooding area", unsafe_allow_html=True)
|
245 |
+
|
246 |
+
if not np.isnan(polygon_name3[0]):
|
247 |
+
st.markdown(f"Address is in sensitive area", unsafe_allow_html=True)
|
248 |
+
|
249 |
+
if np.isnan(polygon_name1[0]) and np.isnan(polygon_name2[0]) and np.isnan(polygon_name3[0]):
|
250 |
+
st.markdown(f"Risk check OK", unsafe_allow_html=True)
|
251 |
+
|
252 |
+
|
253 |
+
# Run the app
|
254 |
+
if __name__ == "__main__":
|
255 |
+
main()
|