Update pages/5_đ_VertXtractor.py
Browse files- pages/5_đ_VertXtractor.py +83 -88
pages/5_đ_VertXtractor.py
CHANGED
@@ -8,58 +8,40 @@ import logging
|
|
8 |
from io import BytesIO
|
9 |
import folium
|
10 |
from streamlit_folium import folium_static
|
|
|
|
|
11 |
|
12 |
# Configuration du logging
|
13 |
logging.basicConfig(level=logging.INFO)
|
14 |
logger = logging.getLogger(__name__)
|
15 |
|
16 |
-
|
17 |
def load_swiss_dem():
|
18 |
"""
|
19 |
Charge le MNT de la Suisse. Cette fonction devrait ĂȘtre implĂ©mentĂ©e pour charger
|
20 |
le MNT complet de la Suisse à partir d'une source de données appropriée.
|
21 |
"""
|
22 |
# Placeholder - à remplacer par le chargement réel du MNT suisse
|
23 |
-
|
|
|
|
|
|
|
24 |
|
25 |
-
# Fonction pour extraire une partie du MNT
|
26 |
def extract_dem_region(dem, transform, bbox):
|
27 |
"""
|
28 |
Extrait une région spécifique du MNT basée sur une boßte englobante.
|
29 |
-
|
30 |
-
Args:
|
31 |
-
dem (numpy.array): Données du MNT complet
|
32 |
-
transform (affine.Affine): Transformation géospatiale
|
33 |
-
bbox (tuple): BoĂźte englobante (minx, miny, maxx, maxy)
|
34 |
-
|
35 |
-
Returns:
|
36 |
-
tuple: (données du MNT extraites, nouvelle transformation)
|
37 |
"""
|
38 |
-
# Conversion des coordonnées de la bbox en indices de pixels
|
39 |
minx, miny, maxx, maxy = bbox
|
40 |
rows, cols = rasterio.transform.rowcol(transform, [minx, maxx], [miny, maxy])
|
41 |
-
|
42 |
-
# Extraction de la région
|
43 |
-
window = ((rows[0], rows[1]), (cols[0], cols[1]))
|
44 |
dem_region = dem[window[0][0]:window[0][1], window[1][0]:window[1][1]]
|
45 |
-
|
46 |
-
# Calcul de la nouvelle transformation
|
47 |
new_transform = rasterio.transform.from_bounds(minx, miny, maxx, maxy,
|
48 |
dem_region.shape[1], dem_region.shape[0])
|
49 |
-
|
50 |
return dem_region, new_transform
|
51 |
|
52 |
def create_mesh(dem, transform, resolution):
|
53 |
"""
|
54 |
Crée un maillage 3D à partir des données du MNT.
|
55 |
-
|
56 |
-
Args:
|
57 |
-
dem (numpy.array): Données du MNT
|
58 |
-
transform (affine.Affine): Transformation géospatiale
|
59 |
-
resolution (int): RĂ©solution du maillage
|
60 |
-
|
61 |
-
Returns:
|
62 |
-
trimesh.Trimesh: Maillage 3D
|
63 |
"""
|
64 |
try:
|
65 |
height, width = dem.shape
|
@@ -88,12 +70,6 @@ def create_mesh(dem, transform, resolution):
|
|
88 |
def visualize_mesh(mesh):
|
89 |
"""
|
90 |
Crée une visualisation du maillage.
|
91 |
-
|
92 |
-
Args:
|
93 |
-
mesh (trimesh.Trimesh): Maillage 3D Ă visualiser
|
94 |
-
|
95 |
-
Returns:
|
96 |
-
matplotlib.figure.Figure: Figure contenant la visualisation du maillage
|
97 |
"""
|
98 |
import matplotlib.pyplot as plt
|
99 |
from mpl_toolkits.mplot3d import Axes3D
|
@@ -110,12 +86,6 @@ def visualize_mesh(mesh):
|
|
110 |
def export_for_blender(mesh):
|
111 |
"""
|
112 |
Exporte le maillage dans un format compatible avec Blender.
|
113 |
-
|
114 |
-
Args:
|
115 |
-
mesh (trimesh.Trimesh): Maillage 3D Ă exporter
|
116 |
-
|
117 |
-
Returns:
|
118 |
-
bytes: Contenu du fichier d'export
|
119 |
"""
|
120 |
try:
|
121 |
obj_file = BytesIO()
|
@@ -126,47 +96,68 @@ def export_for_blender(mesh):
|
|
126 |
st.error("Erreur lors de l'export pour Blender. Veuillez réessayer.")
|
127 |
return None
|
128 |
|
129 |
-
|
130 |
-
st.title("Mesh Tiler CH - Streamlit Edition")
|
131 |
-
st.write("Sélectionnez une zone en Suisse pour créer un maillage 3D.")
|
132 |
|
133 |
-
# Chargement du MNT complet de la Suisse
|
134 |
-
swiss_dem, swiss_transform = load_swiss_dem()
|
135 |
|
136 |
-
# Sélection de la méthode d'entrée
|
137 |
-
input_method = st.radio("Choisissez la méthode de sélection de la zone :",
|
138 |
-
|
139 |
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
draw = folium.plugins.Draw(export=True)
|
146 |
-
draw.add_to(m)
|
147 |
-
|
148 |
-
# Afficher la carte
|
149 |
-
folium_static(m)
|
150 |
-
|
151 |
-
# Récupérer les coordonnées du rectangle dessiné
|
152 |
-
if st.button("Créer le maillage à partir de la sélection"):
|
153 |
-
# Ici, vous devriez récupérer les coordonnées du rectangle dessiné
|
154 |
-
# Cette partie nécessite une implémentation plus avancée avec JavaScript
|
155 |
-
st.write("Fonctionnalité en cours de développement.")
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
|
171 |
resolution = st.slider("RĂ©solution du maillage", min_value=1, max_value=100, value=10)
|
172 |
mesh = create_mesh(dem_region, region_transform, resolution)
|
@@ -175,24 +166,28 @@ else:
|
|
175 |
fig = visualize_mesh(mesh)
|
176 |
st.pyplot(fig)
|
177 |
|
178 |
-
if st.button("Exporter pour Blender"):
|
179 |
blender_file = export_for_blender(mesh)
|
180 |
if blender_file is not None:
|
181 |
st.download_button("Télécharger le fichier Blender (.obj)",
|
182 |
blender_file,
|
183 |
file_name="mesh_export.obj",
|
184 |
-
mime="application/octet-stream"
|
|
|
|
|
|
|
|
|
|
|
185 |
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
|
|
|
|
189 |
|
190 |
-
|
191 |
-
|
192 |
-
3. Cliquez sur "Créer le maillage" pour générer le modÚle 3D.
|
193 |
-
4. Ajustez la résolution du maillage si nécessaire.
|
194 |
-
5. Visualisez le maillage 3D généré.
|
195 |
-
6. Exportez le maillage au format OBJ pour Blender si souhaité.
|
196 |
|
197 |
-
|
198 |
-
|
|
|
8 |
from io import BytesIO
|
9 |
import folium
|
10 |
from streamlit_folium import folium_static
|
11 |
+
from folium.plugins import Draw
|
12 |
+
import json
|
13 |
|
14 |
# Configuration du logging
|
15 |
logging.basicConfig(level=logging.INFO)
|
16 |
logger = logging.getLogger(__name__)
|
17 |
|
18 |
+
@st.cache_data
|
19 |
def load_swiss_dem():
|
20 |
"""
|
21 |
Charge le MNT de la Suisse. Cette fonction devrait ĂȘtre implĂ©mentĂ©e pour charger
|
22 |
le MNT complet de la Suisse à partir d'une source de données appropriée.
|
23 |
"""
|
24 |
# Placeholder - à remplacer par le chargement réel du MNT suisse
|
25 |
+
# Pour l'exemple, on crée un MNT fictif
|
26 |
+
dem = np.random.rand(1000, 1000) * 1000 # MNT fictif de 1000x1000 pixels
|
27 |
+
transform = rasterio.transform.from_bounds(5.9, 45.8, 10.5, 47.8, 1000, 1000)
|
28 |
+
return dem, transform
|
29 |
|
|
|
30 |
def extract_dem_region(dem, transform, bbox):
|
31 |
"""
|
32 |
Extrait une région spécifique du MNT basée sur une boßte englobante.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
"""
|
|
|
34 |
minx, miny, maxx, maxy = bbox
|
35 |
rows, cols = rasterio.transform.rowcol(transform, [minx, maxx], [miny, maxy])
|
36 |
+
window = ((min(rows), max(rows)), (min(cols), max(cols)))
|
|
|
|
|
37 |
dem_region = dem[window[0][0]:window[0][1], window[1][0]:window[1][1]]
|
|
|
|
|
38 |
new_transform = rasterio.transform.from_bounds(minx, miny, maxx, maxy,
|
39 |
dem_region.shape[1], dem_region.shape[0])
|
|
|
40 |
return dem_region, new_transform
|
41 |
|
42 |
def create_mesh(dem, transform, resolution):
|
43 |
"""
|
44 |
Crée un maillage 3D à partir des données du MNT.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
"""
|
46 |
try:
|
47 |
height, width = dem.shape
|
|
|
70 |
def visualize_mesh(mesh):
|
71 |
"""
|
72 |
Crée une visualisation du maillage.
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
"""
|
74 |
import matplotlib.pyplot as plt
|
75 |
from mpl_toolkits.mplot3d import Axes3D
|
|
|
86 |
def export_for_blender(mesh):
|
87 |
"""
|
88 |
Exporte le maillage dans un format compatible avec Blender.
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
"""
|
90 |
try:
|
91 |
obj_file = BytesIO()
|
|
|
96 |
st.error("Erreur lors de l'export pour Blender. Veuillez réessayer.")
|
97 |
return None
|
98 |
|
99 |
+
def main():
|
100 |
+
st.title("Mesh Tiler CH - Streamlit Edition")
|
101 |
+
st.write("Sélectionnez une zone en Suisse pour créer un maillage 3D.")
|
102 |
|
103 |
+
# Chargement du MNT complet de la Suisse
|
104 |
+
swiss_dem, swiss_transform = load_swiss_dem()
|
105 |
|
106 |
+
# Sélection de la méthode d'entrée
|
107 |
+
input_method = st.radio("Choisissez la méthode de sélection de la zone :",
|
108 |
+
("Dessiner sur la carte", "Entrer les coordonnées"))
|
109 |
|
110 |
+
bbox_coords = None
|
111 |
+
|
112 |
+
if input_method == "Dessiner sur la carte":
|
113 |
+
# Créer une carte centrée sur la Suisse
|
114 |
+
m = folium.Map(location=[46.8182, 8.2275], zoom_start=8)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
+
# Ajouter un outil de dessin de rectangle
|
117 |
+
draw = Draw(
|
118 |
+
draw_options={
|
119 |
+
'rectangle': True,
|
120 |
+
'polyline': False,
|
121 |
+
'polygon': False,
|
122 |
+
'circle': False,
|
123 |
+
'marker': False,
|
124 |
+
'circlemarker': False},
|
125 |
+
edit_options={'edit': False}
|
126 |
+
)
|
127 |
+
draw.add_to(m)
|
128 |
+
|
129 |
+
# Afficher la carte
|
130 |
+
map_data = folium_static(m, width=700, height=500)
|
131 |
+
|
132 |
+
# Récupérer les coordonnées du rectangle dessiné
|
133 |
+
if st.button("Créer le maillage à partir de la sélection", key="create_mesh_map"):
|
134 |
+
draw_data = st.session_state.get('last_active_drawing', None)
|
135 |
+
if draw_data:
|
136 |
+
bbox = draw_data['geometry']['coordinates'][0]
|
137 |
+
bbox_coords = (
|
138 |
+
min(coord[0] for coord in bbox),
|
139 |
+
min(coord[1] for coord in bbox),
|
140 |
+
max(coord[0] for coord in bbox),
|
141 |
+
max(coord[1] for coord in bbox)
|
142 |
+
)
|
143 |
+
else:
|
144 |
+
st.warning("Veuillez dessiner un rectangle sur la carte.")
|
145 |
+
|
146 |
+
else:
|
147 |
+
# Entrer les coordonnées manuellement
|
148 |
+
col1, col2 = st.columns(2)
|
149 |
+
with col1:
|
150 |
+
minx = st.number_input("Min X", value=7.0)
|
151 |
+
miny = st.number_input("Min Y", value=46.0)
|
152 |
+
with col2:
|
153 |
+
maxx = st.number_input("Max X", value=8.0)
|
154 |
+
maxy = st.number_input("Max Y", value=47.0)
|
155 |
+
|
156 |
+
if st.button("Créer le maillage", key="create_mesh_coords"):
|
157 |
+
bbox_coords = (minx, miny, maxx, maxy)
|
158 |
+
|
159 |
+
if bbox_coords:
|
160 |
+
dem_region, region_transform = extract_dem_region(swiss_dem, swiss_transform, bbox_coords)
|
161 |
|
162 |
resolution = st.slider("RĂ©solution du maillage", min_value=1, max_value=100, value=10)
|
163 |
mesh = create_mesh(dem_region, region_transform, resolution)
|
|
|
166 |
fig = visualize_mesh(mesh)
|
167 |
st.pyplot(fig)
|
168 |
|
169 |
+
if st.button("Exporter pour Blender", key="export_blender"):
|
170 |
blender_file = export_for_blender(mesh)
|
171 |
if blender_file is not None:
|
172 |
st.download_button("Télécharger le fichier Blender (.obj)",
|
173 |
blender_file,
|
174 |
file_name="mesh_export.obj",
|
175 |
+
mime="application/octet-stream",
|
176 |
+
key="download_blender")
|
177 |
+
|
178 |
+
# Guide d'utilisation simplifié
|
179 |
+
st.markdown("""
|
180 |
+
## Guide d'utilisation
|
181 |
|
182 |
+
1. Choisissez entre dessiner sur la carte ou entrer les coordonnées manuellement.
|
183 |
+
2. SĂ©lectionnez la zone d'intĂ©rĂȘt en Suisse.
|
184 |
+
3. Cliquez sur "Créer le maillage" pour générer le modÚle 3D.
|
185 |
+
4. Ajustez la résolution du maillage si nécessaire.
|
186 |
+
5. Visualisez le maillage 3D généré.
|
187 |
+
6. Exportez le maillage au format OBJ pour Blender si souhaité.
|
188 |
|
189 |
+
Pour toute question ou problÚme, n'hésitez pas à contacter le support technique.
|
190 |
+
""")
|
|
|
|
|
|
|
|
|
191 |
|
192 |
+
if __name__ == "__main__":
|
193 |
+
main()
|