Update pages/12_🌲_VertXtractor.py
Browse files- pages/12_🌲_VertXtractor.py +27 -73
pages/12_🌲_VertXtractor.py
CHANGED
@@ -7,12 +7,10 @@ import requests
|
|
7 |
from shapely.geometry import box
|
8 |
import json
|
9 |
|
10 |
-
# Configuration de la page Streamlit
|
11 |
st.set_page_config(layout="wide", page_title="Extracteur de données géospatiales")
|
12 |
|
13 |
-
# DĂ©finition des couches disponibles
|
14 |
LAYERS = {
|
15 |
-
#
|
16 |
"SWISSIMAGE 10 cm": {"id": "ch.swisstopo.swissimage-dop10", "source": "swisstopo", "type": "image"},
|
17 |
"Carte nationale 1:25'000": {"id": "ch.swisstopo.pixelkarte-farbe-pk25.noscale", "source": "swisstopo", "type": "image"},
|
18 |
"MNT": {"id": "ch.swisstopo.swissalti3d", "source": "swisstopo", "type": "raster"},
|
@@ -20,7 +18,7 @@ LAYERS = {
|
|
20 |
"Limites administratives": {"id": "ch.swisstopo.swissboundaries3d-gemeinde-flaeche.fill", "source": "swisstopo", "type": "vector"},
|
21 |
"RĂ©seau hydrographique": {"id": "ch.bafu.vec25-gewaessernetz", "source": "swisstopo", "type": "vector"},
|
22 |
"swissBUILDINGS3D 3.0 Beta": {"id": "ch.swisstopo.swissbuildings3d_3_0", "source": "swisstopo", "type": "3d"},
|
23 |
-
#
|
24 |
"World Imagery": {"id": "World_Imagery", "source": "esri", "type": "image"},
|
25 |
"World Elevation": {"id": "Elevation/World_Elevation", "source": "esri", "type": "raster"},
|
26 |
"World Topographic": {"id": "World_Topo_Map", "source": "esri", "type": "image"},
|
@@ -29,85 +27,46 @@ LAYERS = {
|
|
29 |
}
|
30 |
|
31 |
def draw_box_on_map():
|
32 |
-
"""Crée une carte Folium avec un outil de dessin pour sélectionner une zone."""
|
33 |
m = folium.Map(location=[46.8, 8.2], zoom_start=8)
|
34 |
Draw(draw_options={'polyline': False, 'polygon': False, 'circle': False, 'marker': False, 'circlemarker': False},
|
35 |
edit_options={'edit': False}).add_to(m)
|
36 |
return st_folium(m, width=700, height=500)
|
37 |
|
38 |
def create_geojson_from_box(bbox):
|
39 |
-
"""Crée des objets GeoJSON à partir d'une boîte englobante."""
|
40 |
gdf = gpd.GeoDataFrame({'geometry': [bbox]}, crs="EPSG:4326")
|
41 |
return json.loads(gdf.to_json()), json.loads(gdf.to_crs("EPSG:2056").to_json())
|
42 |
|
43 |
@st.cache_data
|
44 |
def get_download_url(bbox, layer_info):
|
45 |
-
"""Génère l'URL de téléchargement pour une couche spécifique."""
|
46 |
if layer_info["source"] == "swisstopo":
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
data = response.json()
|
57 |
-
if data['features']:
|
58 |
-
feature = data['features'][0]
|
59 |
-
asset_keys = feature['assets'].keys()
|
60 |
-
# Choisit le format de données approprié
|
61 |
-
data_key = 'gltf' if 'gltf' in asset_keys else next(iter(asset_keys))
|
62 |
-
return feature['assets'][data_key]['href']
|
63 |
-
else:
|
64 |
-
# Gestion standard pour les autres données Swisstopo
|
65 |
-
api_url = f"https://data.geo.admin.ch/api/stac/v0.9/collections/{layer_info['id']}/items"
|
66 |
-
params = {"bbox": ",".join(map(str, bbox)), "limit": 1}
|
67 |
-
response = requests.get(api_url, params=params)
|
68 |
-
data = response.json()
|
69 |
-
if data['features']:
|
70 |
-
feature = data['features'][0]
|
71 |
-
asset_keys = feature['assets'].keys()
|
72 |
-
# Choisit le format de données approprié
|
73 |
-
data_key = 'rgb' if 'rgb' in asset_keys else 'data' if 'data' in asset_keys else next(iter(asset_keys))
|
74 |
-
return feature['assets'][data_key]['href']
|
75 |
else: # ESRI
|
76 |
-
|
77 |
-
service_url = f"https://services.arcgisonline.com/arcgis/rest/services/{layer_info['id']}/MapServer/export"
|
78 |
params = {
|
79 |
-
"bbox": f"{bbox[0]},{bbox[1]},{bbox[2]},{bbox[3]}",
|
80 |
-
"bboxSR": 4326,
|
81 |
-
"size": "1000,1000",
|
82 |
-
"format": "
|
83 |
-
"f": "
|
84 |
-
"imageSR": 4326,
|
85 |
-
"
|
|
|
|
|
86 |
}
|
87 |
-
|
88 |
-
|
89 |
-
response.raise_for_status()
|
90 |
-
json_response = response.json()
|
91 |
-
if 'error' in json_response:
|
92 |
-
st.error(f"Erreur ESRI: {json_response['error']['message']}")
|
93 |
-
return None
|
94 |
-
elif 'href' in json_response:
|
95 |
-
image_url = json_response['href']
|
96 |
-
world_file_url = json_response.get('worldFileURL')
|
97 |
-
return {
|
98 |
-
"image": image_url,
|
99 |
-
"world_file": world_file_url
|
100 |
-
}
|
101 |
-
else:
|
102 |
-
st.error(f"Erreur ESRI: RĂ©ponse inattendue - {json_response}")
|
103 |
-
return None
|
104 |
-
except requests.RequestException as e:
|
105 |
-
st.error(f"Erreur ESRI: {str(e)}")
|
106 |
-
return None
|
107 |
return None
|
108 |
|
109 |
def main():
|
110 |
-
st.title("Extracteur de
|
111 |
|
112 |
col1, col2 = st.columns([1, 2])
|
113 |
|
@@ -126,7 +85,7 @@ def main():
|
|
126 |
st.session_state['geojson_swiss'] = json.loads(gdf.to_crs(2056).to_json())
|
127 |
st.success("GeoJSON chargé!")
|
128 |
|
129 |
-
st.subheader("3. Télécharger les
|
130 |
if st.button("Obtenir les liens de téléchargement"):
|
131 |
if 'geojson_wgs84' not in st.session_state or 'geojson_swiss' not in st.session_state:
|
132 |
st.error("Définissez d'abord une zone d'intérêt.")
|
@@ -140,12 +99,7 @@ def main():
|
|
140 |
st.write(f"Bbox : {bbox}")
|
141 |
download_url = get_download_url(bbox, layer_info)
|
142 |
if download_url:
|
143 |
-
|
144 |
-
st.markdown(f"[Télécharger {layer_name} (Image)]({download_url['image']})")
|
145 |
-
if download_url['world_file']:
|
146 |
-
st.markdown(f"[Télécharger {layer_name} (Fichier World)]({download_url['world_file']})")
|
147 |
-
else: # Pour Swisstopo
|
148 |
-
st.markdown(f"[Télécharger {layer_name}]({download_url})")
|
149 |
else:
|
150 |
st.error(f"Impossible d'obtenir le lien pour {layer_name}")
|
151 |
|
@@ -159,7 +113,7 @@ def main():
|
|
159 |
st.session_state['geojson_wgs84'], st.session_state['geojson_swiss'] = create_geojson_from_box(bbox)
|
160 |
st.success("Zone sélectionnée!")
|
161 |
|
162 |
-
st.sidebar.markdown("## À propos\nExtracteur de
|
163 |
|
164 |
if __name__ == "__main__":
|
165 |
main()
|
|
|
7 |
from shapely.geometry import box
|
8 |
import json
|
9 |
|
|
|
10 |
st.set_page_config(layout="wide", page_title="Extracteur de données géospatiales")
|
11 |
|
|
|
12 |
LAYERS = {
|
13 |
+
# Swisstopo
|
14 |
"SWISSIMAGE 10 cm": {"id": "ch.swisstopo.swissimage-dop10", "source": "swisstopo", "type": "image"},
|
15 |
"Carte nationale 1:25'000": {"id": "ch.swisstopo.pixelkarte-farbe-pk25.noscale", "source": "swisstopo", "type": "image"},
|
16 |
"MNT": {"id": "ch.swisstopo.swissalti3d", "source": "swisstopo", "type": "raster"},
|
|
|
18 |
"Limites administratives": {"id": "ch.swisstopo.swissboundaries3d-gemeinde-flaeche.fill", "source": "swisstopo", "type": "vector"},
|
19 |
"RĂ©seau hydrographique": {"id": "ch.bafu.vec25-gewaessernetz", "source": "swisstopo", "type": "vector"},
|
20 |
"swissBUILDINGS3D 3.0 Beta": {"id": "ch.swisstopo.swissbuildings3d_3_0", "source": "swisstopo", "type": "3d"},
|
21 |
+
# ESRI
|
22 |
"World Imagery": {"id": "World_Imagery", "source": "esri", "type": "image"},
|
23 |
"World Elevation": {"id": "Elevation/World_Elevation", "source": "esri", "type": "raster"},
|
24 |
"World Topographic": {"id": "World_Topo_Map", "source": "esri", "type": "image"},
|
|
|
27 |
}
|
28 |
|
29 |
def draw_box_on_map():
|
|
|
30 |
m = folium.Map(location=[46.8, 8.2], zoom_start=8)
|
31 |
Draw(draw_options={'polyline': False, 'polygon': False, 'circle': False, 'marker': False, 'circlemarker': False},
|
32 |
edit_options={'edit': False}).add_to(m)
|
33 |
return st_folium(m, width=700, height=500)
|
34 |
|
35 |
def create_geojson_from_box(bbox):
|
|
|
36 |
gdf = gpd.GeoDataFrame({'geometry': [bbox]}, crs="EPSG:4326")
|
37 |
return json.loads(gdf.to_json()), json.loads(gdf.to_crs("EPSG:2056").to_json())
|
38 |
|
39 |
@st.cache_data
|
40 |
def get_download_url(bbox, layer_info):
|
|
|
41 |
if layer_info["source"] == "swisstopo":
|
42 |
+
api_url = f"https://data.geo.admin.ch/api/stac/v0.9/collections/{layer_info['id']}/items"
|
43 |
+
params = {"bbox": ",".join(map(str, bbox)), "limit": 1}
|
44 |
+
response = requests.get(api_url, params=params)
|
45 |
+
data = response.json()
|
46 |
+
if data['features']:
|
47 |
+
feature = data['features'][0]
|
48 |
+
asset_keys = feature['assets'].keys()
|
49 |
+
data_key = 'geotiff' if 'geotiff' in asset_keys else 'rgb' if 'rgb' in asset_keys else 'data' if 'data' in asset_keys else next(iter(asset_keys))
|
50 |
+
return feature['assets'][data_key]['href']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
else: # ESRI
|
52 |
+
service_url = f"https://server.arcgisonline.com/arcgis/rest/services/{layer_info['id']}/ImageServer/exportImage"
|
|
|
53 |
params = {
|
54 |
+
"bbox": f"{bbox[0]},{bbox[1]},{bbox[2]},{bbox[3]}",
|
55 |
+
"bboxSR": 4326,
|
56 |
+
"size": "1000,1000",
|
57 |
+
"format": "tiff",
|
58 |
+
"f": "image",
|
59 |
+
"imageSR": 4326,
|
60 |
+
"pixelType": "U8",
|
61 |
+
"noDataInterpretation": "esriNoDataMatchAny",
|
62 |
+
"interpolation": "+RSP_BilinearInterpolation"
|
63 |
}
|
64 |
+
url = f"{service_url}?{'&'.join([f'{k}={v}' for k, v in params.items()])}"
|
65 |
+
return url
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
return None
|
67 |
|
68 |
def main():
|
69 |
+
st.title("Extracteur de rasters géoréférencés")
|
70 |
|
71 |
col1, col2 = st.columns([1, 2])
|
72 |
|
|
|
85 |
st.session_state['geojson_swiss'] = json.loads(gdf.to_crs(2056).to_json())
|
86 |
st.success("GeoJSON chargé!")
|
87 |
|
88 |
+
st.subheader("3. Télécharger les rasters")
|
89 |
if st.button("Obtenir les liens de téléchargement"):
|
90 |
if 'geojson_wgs84' not in st.session_state or 'geojson_swiss' not in st.session_state:
|
91 |
st.error("Définissez d'abord une zone d'intérêt.")
|
|
|
99 |
st.write(f"Bbox : {bbox}")
|
100 |
download_url = get_download_url(bbox, layer_info)
|
101 |
if download_url:
|
102 |
+
st.markdown(f"[Télécharger {layer_name} (Raster géoréférencé)]({download_url})")
|
|
|
|
|
|
|
|
|
|
|
103 |
else:
|
104 |
st.error(f"Impossible d'obtenir le lien pour {layer_name}")
|
105 |
|
|
|
113 |
st.session_state['geojson_wgs84'], st.session_state['geojson_swiss'] = create_geojson_from_box(bbox)
|
114 |
st.success("Zone sélectionnée!")
|
115 |
|
116 |
+
st.sidebar.markdown("## À propos\nExtracteur de rasters géoréférencés Swisstopo et ESRI.\nDéveloppé par Vertdure")
|
117 |
|
118 |
if __name__ == "__main__":
|
119 |
main()
|