Vertdure commited on
Commit
c287c52
·
verified ·
1 Parent(s): 86c6ae5

Update pages/sol.py

Browse files
Files changed (1) hide show
  1. pages/sol.py +63 -19
pages/sol.py CHANGED
@@ -1,9 +1,11 @@
1
  import streamlit as st
2
  import rasterio
3
  import numpy as np
4
- import pyvista as pv
5
- from datetime import datetime
6
  from pysolar.solar import get_altitude, get_azimuth
 
 
 
7
 
8
  # Lieux prédéfinis en Suisse
9
  locations = {
@@ -20,7 +22,7 @@ locations = {
20
  "Montreux": (46.4312, 6.9107),
21
  }
22
 
23
- # Fonction pour charger le raster
24
  def load_raster(file_path):
25
  with rasterio.open(file_path) as src:
26
  raster = src.read(1)
@@ -31,42 +33,84 @@ def load_raster(file_path):
31
  def calculate_shadows(raster, altitude, azimuth):
32
  shadow = np.zeros_like(raster)
33
  if altitude > 0: # Si le soleil est au-dessus de l'horizon
34
- shadow[raster > altitude] = 1 # Simplifié
35
  return shadow
36
 
37
- # Interface Streamlit
38
  st.title("Simulation des Ombres en 3D - Suisse")
39
 
40
- uploaded_file = st.file_uploader("Téléchargez un fichier raster (MES ou MNT)", type=["tif"])
 
41
  if uploaded_file:
42
  raster, transform = load_raster(uploaded_file)
43
- st.write("Raster chargé avec succès !")
44
 
45
- location_choice = st.selectbox("Choisissez un lieu", list(locations.keys()))
 
 
46
  latitude, longitude = locations[location_choice]
47
 
48
- selected_date = st.date_input("Sélectionnez une date", value=datetime.now().date())
49
- selected_time = st.time_input("Sélectionnez une heure", value=datetime.now().time())
50
- specific_datetime = datetime.combine(selected_date, selected_time)
 
 
 
 
 
 
 
 
51
 
52
- altitude = get_altitude(latitude, longitude, specific_datetime)
53
- azimuth = get_azimuth(latitude, longitude, specific_datetime)
 
 
54
  shadows = calculate_shadows(raster, altitude, azimuth)
55
 
56
- # Rendu 3D avec PyVista
 
 
 
57
  st.subheader("Rendu 3D")
58
  grid = pv.UniformGrid()
59
- grid.dimensions = raster.shape + (1,) # Ajoute une 3ème dimension
60
- grid.spacing = (transform[0], transform[4], 1) # Espacement (pixels)
61
  grid.point_arrays["Topography"] = raster.flatten(order="F")
62
  grid.point_arrays["Shadows"] = shadows.flatten(order="F")
63
 
64
- # PyVista plot
65
- plotter = pv.Plotter(notebook=False)
66
  plotter.add_mesh(grid, scalars="Topography", cmap="terrain", show_edges=False)
67
  plotter.add_mesh(grid, scalars="Shadows", cmap="gray", opacity=0.5)
68
  plotter.view_isometric()
69
  plotter.add_scalar_bar("Élévation (m)")
70
  plotter.show(screenshot="render_3d.png")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
- st.image("render_3d.png", caption="Rendu 3D des ombres", use_column_width=True)
 
 
 
 
1
  import streamlit as st
2
  import rasterio
3
  import numpy as np
4
+ from datetime import datetime, timedelta
 
5
  from pysolar.solar import get_altitude, get_azimuth
6
+ from pytz import timezone
7
+ import pyvista as pv
8
+ import imageio
9
 
10
  # Lieux prédéfinis en Suisse
11
  locations = {
 
22
  "Montreux": (46.4312, 6.9107),
23
  }
24
 
25
+ # Fonction pour charger un raster
26
  def load_raster(file_path):
27
  with rasterio.open(file_path) as src:
28
  raster = src.read(1)
 
33
  def calculate_shadows(raster, altitude, azimuth):
34
  shadow = np.zeros_like(raster)
35
  if altitude > 0: # Si le soleil est au-dessus de l'horizon
36
+ shadow[raster > altitude] = 1 # Simplifié pour cet exemple
37
  return shadow
38
 
39
+ # Interface utilisateur Streamlit
40
  st.title("Simulation des Ombres en 3D - Suisse")
41
 
42
+ # Chargement du raster
43
+ uploaded_file = st.sidebar.file_uploader("Téléchargez un fichier raster (MES ou MNT)", type=["tif"])
44
  if uploaded_file:
45
  raster, transform = load_raster(uploaded_file)
46
+ st.sidebar.write("Raster chargé avec succès !")
47
 
48
+ # Menu des paramètres utilisateur
49
+ st.sidebar.header("Paramètres")
50
+ location_choice = st.sidebar.selectbox("Choisissez un lieu", list(locations.keys()))
51
  latitude, longitude = locations[location_choice]
52
 
53
+ # Récupération des dates et heures
54
+ selected_start_date = st.sidebar.date_input("Date de début", value=datetime.now().date())
55
+ selected_end_date = st.sidebar.date_input("Date de fin", value=datetime.now().date() + timedelta(days=1))
56
+ selected_time = st.sidebar.time_input("Heure", value=datetime.now().time())
57
+ timezone_swiss = timezone("Europe/Zurich")
58
+
59
+ # Combinaison avec fuseau horaire
60
+ naive_start_datetime = datetime.combine(selected_start_date, selected_time)
61
+ naive_end_datetime = datetime.combine(selected_end_date, selected_time)
62
+ start_datetime = timezone_swiss.localize(naive_start_datetime)
63
+ end_datetime = timezone_swiss.localize(naive_end_datetime)
64
 
65
+ # Section de visualisation statique
66
+ st.subheader("Visualisation statique")
67
+ altitude = get_altitude(latitude, longitude, start_datetime)
68
+ azimuth = get_azimuth(latitude, longitude, start_datetime)
69
  shadows = calculate_shadows(raster, altitude, azimuth)
70
 
71
+ # Affichage 2D des ombres
72
+ st.image(shadows, caption=f"Ombres pour {start_datetime}", use_column_width=True)
73
+
74
+ # Rendu 3D
75
  st.subheader("Rendu 3D")
76
  grid = pv.UniformGrid()
77
+ grid.dimensions = raster.shape + (1,)
78
+ grid.spacing = (transform[0], transform[4], 1)
79
  grid.point_arrays["Topography"] = raster.flatten(order="F")
80
  grid.point_arrays["Shadows"] = shadows.flatten(order="F")
81
 
82
+ # PyVista rendu 3D
83
+ plotter = pv.Plotter(off_screen=True)
84
  plotter.add_mesh(grid, scalars="Topography", cmap="terrain", show_edges=False)
85
  plotter.add_mesh(grid, scalars="Shadows", cmap="gray", opacity=0.5)
86
  plotter.view_isometric()
87
  plotter.add_scalar_bar("Élévation (m)")
88
  plotter.show(screenshot="render_3d.png")
89
+ st.image("render_3d.png", caption="Rendu 3D des ombres", use_column_width=True)
90
+
91
+ # Timelapse
92
+ st.subheader("Génération d'un Timelapse")
93
+ if st.button("Générer un timelapse"):
94
+ current_time = start_datetime
95
+ frames = []
96
+ while current_time <= end_datetime:
97
+ altitude = get_altitude(latitude, longitude, current_time)
98
+ azimuth = get_azimuth(latitude, longitude, current_time)
99
+ shadows = calculate_shadows(raster, altitude, azimuth)
100
+
101
+ # Ajout des ombres comme une frame
102
+ grid.point_arrays["Shadows"] = shadows.flatten(order="F")
103
+ plotter = pv.Plotter(off_screen=True)
104
+ plotter.add_mesh(grid, scalars="Topography", cmap="terrain", show_edges=False)
105
+ plotter.add_mesh(grid, scalars="Shadows", cmap="gray", opacity=0.5)
106
+ plotter.view_isometric()
107
+ plotter.add_scalar_bar("Élévation (m)")
108
+ filename = f"frame_{current_time.strftime('%Y%m%d%H%M')}.png"
109
+ plotter.show(screenshot=filename)
110
+ frames.append(imageio.imread(filename))
111
+ current_time += timedelta(hours=1) # Intervalle d'une heure
112
 
113
+ # Création du GIF
114
+ gif_path = "timelapse.gif"
115
+ imageio.mimsave(gif_path, frames, duration=0.5) # 0.5s par frame
116
+ st.image(gif_path, caption="Timelapse des ombres", use_column_width=True)