Update pages/12_🌲_VertXtractor.py
Browse files- pages/12_🌲_VertXtractor.py +101 -40
pages/12_🌲_VertXtractor.py
CHANGED
@@ -3,56 +3,117 @@ import geopandas as gpd
|
|
3 |
import folium
|
4 |
from streamlit_folium import folium_static, st_folium
|
5 |
from folium.plugins import Draw
|
6 |
-
from shapely.geometry import box, shape
|
7 |
import requests
|
8 |
from io import BytesIO
|
9 |
from PIL import Image
|
10 |
-
import
|
11 |
|
12 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
def main():
|
15 |
-
|
16 |
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
# Calcul du centre de la carte en utilisant total_bounds
|
30 |
-
bounds = gdf_wgs84.total_bounds
|
31 |
-
center_lat = (bounds[1] + bounds[3]) / 2
|
32 |
-
center_lon = (bounds[0] + bounds[2]) / 2
|
33 |
-
|
34 |
-
m = folium.Map(location=[center_lat, center_lon], zoom_start=12)
|
35 |
-
folium.GeoJson(gdf_wgs84).add_to(m)
|
36 |
-
folium_static(m)
|
37 |
-
|
38 |
-
# Téléchargement des données
|
39 |
-
if "swissimage" in collection:
|
40 |
-
if 'assets' in gdf.iloc[0] and 'rgb' in gdf.iloc[0]['assets']:
|
41 |
-
image_url = gdf.iloc[0]['assets']['rgb']['href']
|
42 |
-
st.markdown(f"[Télécharger l'image]({image_url})")
|
43 |
-
else:
|
44 |
-
st.download_button(
|
45 |
-
label="Télécharger les données (GeoJSON)",
|
46 |
-
data=gdf.to_json(),
|
47 |
-
file_name=f"{selected_collection.lower().replace(' ', '_')}.geojson",
|
48 |
-
mime="application/json"
|
49 |
-
)
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
-
|
|
|
|
|
56 |
|
57 |
if __name__ == "__main__":
|
58 |
main()
|
|
|
3 |
import folium
|
4 |
from streamlit_folium import folium_static, st_folium
|
5 |
from folium.plugins import Draw
|
|
|
6 |
import requests
|
7 |
from io import BytesIO
|
8 |
from PIL import Image
|
9 |
+
from shapely.geometry import box
|
10 |
|
11 |
+
# Liste des couches disponibles
|
12 |
+
LAYERS = {
|
13 |
+
"Swisstopo - SWISSIMAGE 10 cm": {"id": "ch.swisstopo.swissimage-dop10", "source": "swisstopo"},
|
14 |
+
"Swisstopo - Carte nationale 1:25'000": {"id": "ch.swisstopo.pixelkarte-farbe-pk25.noscale", "source": "swisstopo"},
|
15 |
+
"Swisstopo - Modèle numérique de terrain": {"id": "ch.swisstopo.swissalti3d", "source": "swisstopo"},
|
16 |
+
"ESRI - World Imagery": {"id": "esri_world_imagery", "source": "esri"},
|
17 |
+
"ESRI - World Elevation": {"id": "esri_world_elevation", "source": "esri"}
|
18 |
+
}
|
19 |
+
|
20 |
+
def draw_box_on_map():
|
21 |
+
m = folium.Map(location=[46.8, 8.2], zoom_start=8)
|
22 |
+
draw = Draw(
|
23 |
+
draw_options={
|
24 |
+
'polyline': False,
|
25 |
+
'polygon': False,
|
26 |
+
'circle': False,
|
27 |
+
'marker': False,
|
28 |
+
'circlemarker': False,
|
29 |
+
},
|
30 |
+
edit_options={'edit': False}
|
31 |
+
)
|
32 |
+
draw.add_to(m)
|
33 |
+
|
34 |
+
output = st_folium(m, width=700, height=500)
|
35 |
+
|
36 |
+
if output['last_active_drawing']:
|
37 |
+
coords = output['last_active_drawing']['geometry']['coordinates'][0]
|
38 |
+
return box(min(c[0] for c in coords), min(c[1] for c in coords),
|
39 |
+
max(c[0] for c in coords), max(c[1] for c in coords))
|
40 |
+
return None
|
41 |
+
|
42 |
+
def create_geojson_from_box(bbox):
|
43 |
+
gdf = gpd.GeoDataFrame({'geometry': [bbox]}, crs="EPSG:4326")
|
44 |
+
gdf_swiss = gdf.to_crs("EPSG:2056")
|
45 |
+
gdf['geometry_swiss'] = gdf_swiss['geometry']
|
46 |
+
return gdf
|
47 |
+
|
48 |
+
def extract_swisstopo_data(bbox, layer_id):
|
49 |
+
api_url = f"https://data.geo.admin.ch/api/stac/v0.9/collections/{layer_id}/items"
|
50 |
+
params = {"bbox": ",".join(map(str, bbox)), "limit": 100}
|
51 |
+
|
52 |
+
response = requests.get(api_url, params=params)
|
53 |
+
response.raise_for_status()
|
54 |
+
|
55 |
+
data = response.json()
|
56 |
+
if data['features']:
|
57 |
+
return gpd.GeoDataFrame.from_features(data['features'])
|
58 |
+
return None
|
59 |
+
|
60 |
+
def extract_esri_data(bbox, layer_id):
|
61 |
+
# Placeholder pour l'extraction des données ESRI
|
62 |
+
st.warning("L'extraction des données ESRI n'est pas implémentée dans cet exemple")
|
63 |
+
return None
|
64 |
|
65 |
def main():
|
66 |
+
st.title("Extracteur de données Swisstopo et ESRI")
|
67 |
|
68 |
+
# Étape 1: Dessiner la boîte de sélection
|
69 |
+
st.subheader("Étape 1: Dessiner la zone d'intérêt")
|
70 |
+
bbox = draw_box_on_map()
|
71 |
+
|
72 |
+
if bbox:
|
73 |
+
st.success("Zone sélectionnée avec succès!")
|
74 |
+
gdf = create_geojson_from_box(bbox)
|
75 |
+
|
76 |
+
# Affichage de la carte avec la boîte dessinée
|
77 |
+
m = folium.Map()
|
78 |
+
folium.GeoJson(gdf).add_to(m)
|
79 |
+
m.fit_bounds(m.get_bounds())
|
80 |
+
folium_static(m)
|
81 |
+
|
82 |
+
# Étape 2: Sélection des couches
|
83 |
+
st.subheader("Étape 2: Sélection des couches")
|
84 |
+
selected_layers = st.multiselect("SĂ©lectionnez les couches Ă extraire", list(LAYERS.keys()))
|
85 |
+
|
86 |
+
if st.button("Extraire les données"):
|
87 |
+
for layer_name in selected_layers:
|
88 |
+
layer_info = LAYERS[layer_name]
|
89 |
|
90 |
+
# Choix des coordonnées en fonction de la source
|
91 |
+
if layer_info["source"] == "swisstopo":
|
92 |
+
bbox = gdf['geometry_swiss'].total_bounds
|
93 |
+
else: # ESRI
|
94 |
+
bbox = gdf['geometry'].total_bounds
|
95 |
+
|
96 |
+
st.write(f"Extraction de {layer_name}...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
|
98 |
+
if layer_info["source"] == "swisstopo":
|
99 |
+
data = extract_swisstopo_data(bbox, layer_info["id"])
|
100 |
+
else:
|
101 |
+
data = extract_esri_data(bbox, layer_info["id"])
|
102 |
+
|
103 |
+
if data is not None:
|
104 |
+
st.write(data.head())
|
105 |
+
st.download_button(
|
106 |
+
label=f"Télécharger {layer_name} (GeoJSON)",
|
107 |
+
data=data.to_json(),
|
108 |
+
file_name=f"{layer_name.lower().replace(' ', '_')}.geojson",
|
109 |
+
mime="application/json"
|
110 |
+
)
|
111 |
+
else:
|
112 |
+
st.warning(f"Aucune donnée trouvée pour {layer_name}")
|
113 |
|
114 |
+
st.sidebar.markdown("## À propos")
|
115 |
+
st.sidebar.markdown("Cet outil permet d'extraire des données géospatiales de Swisstopo et ESRI.")
|
116 |
+
st.sidebar.markdown("Développé par Vertdure")
|
117 |
|
118 |
if __name__ == "__main__":
|
119 |
main()
|