Vertdure commited on
Commit
d043ba9
1 Parent(s): b6b6ea7

Update pages/12_🌲_VertXtractor.py

Browse files
Files changed (1) hide show
  1. pages/12_🌲_VertXtractor.py +88 -30
pages/12_🌲_VertXtractor.py CHANGED
@@ -6,17 +6,23 @@ from folium.plugins import Draw
6
  import requests
7
  from shapely.geometry import box
8
  import json
 
 
 
 
 
9
 
10
  # Liste des couches disponibles
11
  LAYERS = {
12
- "Swisstopo - SWISSIMAGE 10 cm": {"id": "ch.swisstopo.swissimage-dop10", "source": "swisstopo"},
13
- "Swisstopo - Carte nationale 1:25'000": {"id": "ch.swisstopo.pixelkarte-farbe-pk25.noscale", "source": "swisstopo"},
14
- "Swisstopo - Modèle numérique de terrain": {"id": "ch.swisstopo.swissalti3d", "source": "swisstopo"},
15
- "ESRI - World Imagery": {"id": "esri_world_imagery", "source": "esri"},
16
- "ESRI - World Elevation": {"id": "esri_world_elevation", "source": "esri"}
17
  }
18
 
19
  def draw_box_on_map():
 
20
  m = folium.Map(location=[46.8, 8.2], zoom_start=8)
21
  draw = Draw(
22
  draw_options={
@@ -32,27 +38,89 @@ def draw_box_on_map():
32
  return st_folium(m, width=700, height=500)
33
 
34
  def create_geojson_from_box(bbox):
 
35
  gdf = gpd.GeoDataFrame({'geometry': [bbox]}, crs="EPSG:4326")
36
  gdf_swiss = gdf.to_crs("EPSG:2056")
37
  return json.loads(gdf.to_json()), json.loads(gdf_swiss.to_json())
38
 
39
- def extract_swisstopo_data(bbox, layer_id):
 
40
  api_url = f"https://data.geo.admin.ch/api/stac/v0.9/collections/{layer_id}/items"
41
- params = {"bbox": ",".join(map(str, bbox)), "limit": 100}
42
 
43
- response = requests.get(api_url, params=params)
44
- response.raise_for_status()
45
-
46
- data = response.json()
47
- if data['features']:
48
- return gpd.GeoDataFrame.from_features(data['features'])
 
 
 
 
 
 
 
 
 
 
49
  return None
50
 
51
- def extract_esri_data(bbox, layer_id):
52
- # Placeholder pour l'extraction des données ESRI
53
- st.warning("L'extraction des données ESRI n'est pas implémentée dans cet exemple")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  return None
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  def main():
57
  st.title("Extracteur de données Swisstopo et ESRI")
58
 
@@ -94,22 +162,12 @@ def main():
94
 
95
  if layer_info["source"] == "swisstopo":
96
  bbox = gpd.GeoDataFrame.from_features(st.session_state['geojson_swiss']).total_bounds
97
- data = extract_swisstopo_data(bbox, layer_info["id"])
98
  else: # ESRI
99
  bbox = gpd.GeoDataFrame.from_features(st.session_state['geojson_wgs84']).total_bounds
100
- data = extract_esri_data(bbox, layer_info["id"])
101
-
102
- if data is not None:
103
- st.write(f"Données extraites pour {layer_name}:")
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.")
 
6
  import requests
7
  from shapely.geometry import box
8
  import json
9
+ import io
10
+ import rasterio
11
+ from rasterio.io import MemoryFile
12
+ from PIL import Image
13
+ import numpy as np
14
 
15
  # Liste des couches disponibles
16
  LAYERS = {
17
+ "Swisstopo - SWISSIMAGE 10 cm": {"id": "ch.swisstopo.swissimage-dop10", "source": "swisstopo", "type": "image"},
18
+ "Swisstopo - Carte nationale 1:25'000": {"id": "ch.swisstopo.pixelkarte-farbe-pk25.noscale", "source": "swisstopo", "type": "image"},
19
+ "Swisstopo - Modèle numérique de terrain": {"id": "ch.swisstopo.swissalti3d", "source": "swisstopo", "type": "raster"},
20
+ "ESRI - World Imagery": {"id": "WorldImagery", "source": "esri", "type": "image"},
21
+ "ESRI - World Elevation": {"id": "WorldElevation", "source": "esri", "type": "raster"}
22
  }
23
 
24
  def draw_box_on_map():
25
+ """Permet à l'utilisateur de dessiner une boîte sur une carte Folium."""
26
  m = folium.Map(location=[46.8, 8.2], zoom_start=8)
27
  draw = Draw(
28
  draw_options={
 
38
  return st_folium(m, width=700, height=500)
39
 
40
  def create_geojson_from_box(bbox):
41
+ """Crée des GeoJSON en WGS84 et LV95 à partir d'une boîte englobante."""
42
  gdf = gpd.GeoDataFrame({'geometry': [bbox]}, crs="EPSG:4326")
43
  gdf_swiss = gdf.to_crs("EPSG:2056")
44
  return json.loads(gdf.to_json()), json.loads(gdf_swiss.to_json())
45
 
46
+ def extract_swisstopo_data(bbox, layer_id, layer_type):
47
+ """Extrait les données Swisstopo en utilisant l'API STAC."""
48
  api_url = f"https://data.geo.admin.ch/api/stac/v0.9/collections/{layer_id}/items"
49
+ params = {"bbox": ",".join(map(str, bbox)), "limit": 1}
50
 
51
+ try:
52
+ response = requests.get(api_url, params=params)
53
+ response.raise_for_status()
54
+
55
+ data = response.json()
56
+ if data['features']:
57
+ feature = data['features'][0]
58
+ if layer_type == "image":
59
+ return feature['assets']['rgb']['href']
60
+ elif layer_type == "raster":
61
+ raster_url = feature['assets']['data']['href']
62
+ raster_response = requests.get(raster_url)
63
+ raster_response.raise_for_status()
64
+ return raster_response.content
65
+ except requests.RequestException as e:
66
+ st.error(f"Erreur lors de l'extraction des données Swisstopo: {str(e)}")
67
  return None
68
 
69
+ def extract_esri_data(bbox, layer_id, layer_type):
70
+ """Extrait les données ESRI en utilisant les services ArcGIS REST."""
71
+ if layer_type == "image":
72
+ service_url = "https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/export"
73
+ elif layer_type == "raster":
74
+ service_url = "https://elevation.arcgis.com/arcgis/rest/services/WorldElevation/Terrain/ImageServer/exportImage"
75
+
76
+ params = {
77
+ "bbox": f"{bbox[0]},{bbox[1]},{bbox[2]},{bbox[3]}",
78
+ "bboxSR": 4326,
79
+ "size": "1000,1000",
80
+ "format": "tiff",
81
+ "f": "image"
82
+ }
83
+
84
+ try:
85
+ response = requests.get(service_url, params=params)
86
+ response.raise_for_status()
87
+ return response.content
88
+ except requests.RequestException as e:
89
+ st.error(f"Erreur lors de l'extraction des données ESRI: {str(e)}")
90
  return None
91
 
92
+ def process_and_display_data(data, layer_name, layer_type):
93
+ """Traite et affiche les données extraites."""
94
+ if data is None:
95
+ st.warning(f"Aucune donnée trouvée pour {layer_name}")
96
+ return
97
+
98
+ if layer_type == "image":
99
+ try:
100
+ with MemoryFile(data) as memfile:
101
+ with memfile.open() as dataset:
102
+ image_array = dataset.read()
103
+ image = Image.fromarray(np.transpose(image_array, (1, 2, 0)))
104
+ st.image(image, caption=layer_name, use_column_width=True)
105
+ except Exception as e:
106
+ st.error(f"Erreur lors du traitement de l'image pour {layer_name}: {str(e)}")
107
+ elif layer_type == "raster":
108
+ try:
109
+ with MemoryFile(data) as memfile:
110
+ with memfile.open() as dataset:
111
+ raster_array = dataset.read(1) # Lire le premier canal
112
+ st.image(raster_array, caption=f"{layer_name} (première bande)", use_column_width=True)
113
+ except Exception as e:
114
+ st.error(f"Erreur lors du traitement du raster pour {layer_name}: {str(e)}")
115
+
116
+ # Bouton de téléchargement
117
+ st.download_button(
118
+ label=f"Télécharger {layer_name}",
119
+ data=data,
120
+ file_name=f"{layer_name.lower().replace(' ', '_')}.tif",
121
+ mime="application/octet-stream"
122
+ )
123
+
124
  def main():
125
  st.title("Extracteur de données Swisstopo et ESRI")
126
 
 
162
 
163
  if layer_info["source"] == "swisstopo":
164
  bbox = gpd.GeoDataFrame.from_features(st.session_state['geojson_swiss']).total_bounds
165
+ data = extract_swisstopo_data(bbox, layer_info["id"], layer_info["type"])
166
  else: # ESRI
167
  bbox = gpd.GeoDataFrame.from_features(st.session_state['geojson_wgs84']).total_bounds
168
+ data = extract_esri_data(bbox, layer_info["id"], layer_info["type"])
169
+
170
+ process_and_display_data(data, layer_name, layer_info["type"])
 
 
 
 
 
 
 
 
 
 
171
 
172
  st.sidebar.markdown("## À propos")
173
  st.sidebar.markdown("Cet outil permet d'extraire des données géospatiales de Swisstopo et ESRI.")