summaryrefslogtreecommitdiff
path: root/ero1/src/generation
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
commit967be9e750221ab2ab783f95df79bb26d290a45e (patch)
tree6802900a5e975f9f68b169f0f503f040056d6952 /ero1/src/generation
add: added projectsHEADmain
Diffstat (limited to 'ero1/src/generation')
-rw-r--r--ero1/src/generation/graph_generation.py17
-rw-r--r--ero1/src/generation/habitation_generation.py24
-rw-r--r--ero1/src/generation/snow_generation.py85
-rw-r--r--ero1/src/generation/suburb_snowplow_generation.py88
4 files changed, 214 insertions, 0 deletions
diff --git a/ero1/src/generation/graph_generation.py b/ero1/src/generation/graph_generation.py
new file mode 100644
index 0000000..641e761
--- /dev/null
+++ b/ero1/src/generation/graph_generation.py
@@ -0,0 +1,17 @@
+import osmnx as ox
+from src.helper.duplicate_removal import remove_duplicates
+
+def generate_graph(city_name, debug_mode=False):
+ """
+ Génère un graphe à partir du nom d'une ville en utilisant OSMnx.
+
+ Parameters:
+ city_name : Le nom de la ville pour laquelle générer le graphe.
+
+ Returns:
+ MultiDiGraph : Le graphe généré.
+ """
+ # Generate the graph from the city name
+ GRAPH = ox.graph_from_place(city_name, network_type='drive')
+ GRAPH = remove_duplicates(GRAPH, debug_mode)
+ return GRAPH \ No newline at end of file
diff --git a/ero1/src/generation/habitation_generation.py b/ero1/src/generation/habitation_generation.py
new file mode 100644
index 0000000..35cddaa
--- /dev/null
+++ b/ero1/src/generation/habitation_generation.py
@@ -0,0 +1,24 @@
+# FICHIER DEPRECATED : Ce fichier n'est plus utilisé.
+
+import random
+import parameters as params
+
+def place_habitation(G):
+ """
+ Place des zones d'habitation sur les arêtes du graphe.
+ Parameters:
+ G (voir quel type on veut utiliser): le graphe des routes
+ Returns:
+ None: le graphe est modifié en place
+ """
+ edges = list(G.edges(keys=True, data=True))
+ n = len(edges)
+ amount_to_place = int(params.HABITATION_PERCENTAGE * n)
+
+ # Trie les arrêtes par leur longueur. (x[3] = data)
+ edges_sorted = sorted(edges, key=lambda x: x[3].get('length', 0), reverse=True)
+
+ # Place les habitations sur les plus longues arêtes ? (tentative - juste pour tester les drones)
+ # WARNING : peut être remplacer la fonction plus tard.
+ for (u, v, k, data) in edges_sorted[:amount_to_place]:
+ data['habitation'] = True
diff --git a/ero1/src/generation/snow_generation.py b/ero1/src/generation/snow_generation.py
new file mode 100644
index 0000000..449a4ec
--- /dev/null
+++ b/ero1/src/generation/snow_generation.py
@@ -0,0 +1,85 @@
+# FICHIER DEPRECATED : Ce fichier n'est plus utilisé.
+
+import random
+import parameters as params
+
+
+def place_snow(G):
+ """
+ Place de la neige sur les egdes du graphe
+ Parameters:
+ G (voir quel type on veut utiliser): le graphe des routes
+ Returns:
+ None: le graphe est modifié en place
+ """
+ # WARNING: je ne suis pas sûr de cette manière de faire qui me semble boffe, je pense qu'une manière plus random (mais plus sale/lente) serait de shuffle la liste d'edges. Le soucis avec la méthode actuelle c'est que si G.egdes(...) ordonne les arcs/arêtes d'une manière prédéfinie, alors le début/la fin de la liste sera composé de beacoup/peu de neige, ce qui n'est pas uniforme
+ edges = list(G.edges(keys=True, data=True))
+ n = len(edges)
+ random.shuffle(edges)
+ amount_to_cover = int(params.SNOW_PERCENTAGE * n)
+ quantity: float = 0
+
+ for u, v, k, data in edges:
+ if (amount_to_cover == 0): # we should place > 2.5cm snow
+ quantity = random.uniform(
+ params.SNOW_THRESHOLD + 0.01, params.SNOW_MAX)
+ else: # we do not care
+ quantity = random.uniform(params.SNOW_MIN, params.SNOW_MAX)
+
+ if (quantity >= params.SNOW_THRESHOLD):
+ amount_to_cover -= 1
+
+ data['snow'] = quantity
+
+
+def place_snow_v2(G):
+ """
+ Place de la neige sur les egdes du graphe, moins opti que la v1 mais gère les cas (u,v) et (v,u) (plus réaliste)
+ Parameters:
+ G (voir quel type on veut utiliser): le graphe des routes
+ Returns:
+ (int, int): (nb_edges_oriented, nb_edges_nonoriented), renvoie le nombre d'edges qui ont plus de 2.5 cm de neige (utile pour débug les drônes)
+ """
+ edges = list(G.edges(keys=True, data=True))
+ n = len(edges)
+ random.shuffle(edges)
+ amount_to_cover = int(params.SNOW_PERCENTAGE * n)
+ TO_DELETE = amount_to_cover # pls delete once testing is finished
+ quantity: float = 0
+
+ res_oriented = 0
+ res_unoriented = 0
+ visited = {} # (u,v) => quantity
+
+ for u, v, k, data in edges:
+ if (v, u) in visited:
+ data['snow'] = visited[(v, u)]
+ amount_to_cover -= 1
+
+ res_unoriented += 1
+ # we do not increment res_oriented since (u,v) and (v,u) are the same thing
+ # => check to_undirected but should be good
+ elif (u, v) in visited:
+ data['snow'] = visited[(u, v)]
+ # WARNING: this implementation might not be the most accurate/best
+
+ amount_to_cover -= 1
+ # TODO : wtf do I do with the counters ... technically nothing ?
+ else:
+ if (amount_to_cover <= 0): # we should place > 2.5cm snow
+ quantity = random.uniform(
+ params.SNOW_THRESHOLD + 0.01, params.SNOW_MAX)
+ else: # we do not care
+ quantity = random.uniform(params.SNOW_MIN, params.SNOW_MAX)
+
+ if (quantity >= params.SNOW_THRESHOLD):
+ amount_to_cover -= 1
+
+ data['snow'] = quantity
+ visited[(u, v)] = quantity
+
+ res_unoriented += 1
+ res_oriented += 1
+
+ # assert (TO_DELETE == res_unoriented) => need to check how to handle duplicate of the form (u,v)
+ return res_oriented, res_unoriented
diff --git a/ero1/src/generation/suburb_snowplow_generation.py b/ero1/src/generation/suburb_snowplow_generation.py
new file mode 100644
index 0000000..156bdda
--- /dev/null
+++ b/ero1/src/generation/suburb_snowplow_generation.py
@@ -0,0 +1,88 @@
+import networkx as nx
+from src.generation.graph_generation import generate_graph
+from src.helper.export_import_yaml import load_paths_from_yaml
+import osmnx as ox
+
+arrondissements = [
+ 'Anjou',
+ 'Le Plateau-Mont-Royal',
+ 'Outremont',
+ 'Rivière-des-Prairies–Pointe-aux-Trembles',
+ 'Verdun',
+]
+
+
+def logic_quartiers_(path_list, montreal_g, suburb_list, debug_mode=False):
+ """
+ the main logic behind the generate_quartiers functions
+ """
+
+ if debug_mode:
+ tot_edges = 0
+ tot_nodes = 0
+ for arr in suburb_list:
+ g_temp = ox.graph_from_place(
+ arr + ", Montréal, Québec, Canada", network_type='drive')
+ removed = [(u, v, k)
+ for u, v, k in g_temp.edges(keys=True) if k > 0]
+ g_temp.remove_edges_from(removed)
+ tot_edges += len(g_temp.edges)
+ tot_nodes += len(g_temp.nodes)
+
+ print("tot_edges = " + str(tot_edges))
+ print("tot_nodes = " + str(tot_nodes))
+
+ # graph_mont = generate_graph("Montréal, Québec, Canada")
+ graph_mont = montreal_g
+
+ res = nx.DiGraph()
+
+ i = 0
+
+ for arr in suburb_list:
+ for u, v in path_list[arr]:
+ # print("u : " + str(u))
+ # print("v : " + str(v))
+ # print("noeud u: "+str(graph_mont.nodes[u]))
+ # print("noeud v: "+str(graph_mont.nodes[v]))
+ # print("(u,v) in graph : " + str((u, v)
+ # in graph_mont.edges(keys=False)))
+ # print("edge u,v: "+str(graph_mont.edges[(u, v, 0)]))
+ try:
+ res.add_node(u, **graph_mont.nodes[u])
+ res.add_node(v, **graph_mont.nodes[v])
+ if graph_mont.has_edge(u, v):
+ res.add_edge(u, v, **graph_mont.edges[(u, v, 0)])
+ if graph_mont.has_edge(v, u):
+ res.add_edge(v, u, **graph_mont.edges[(v, u, 0)])
+ except:
+ i += 1
+ continue
+
+ return res
+
+
+def generate_quartiers_from_yaml(path_yaml_drone, montreal_g, suburb_list=arrondissements, debug_mode=False):
+ """
+ Génère un graphe qui est l'union des edges/nodes des graphes de chaque
+ quartiers où path_yaml_drone est le chemin du fichier yaml qui
+ contient le resultat du drone
+ Parameters:
+ debug_mode (bool: default = False): le debug mode duh
+ Return:
+ nx.MultiDiGraph/nx.DiGraph : la fusion des quartiers
+ """
+ path_res = load_paths_from_yaml(path_yaml_drone)
+ return logic_quartiers_(path_res, montreal_g, suburb_list, debug_mode)
+
+
+def generate_quartiers_from_path(path_list, montreal_g, suburb_list=arrondissements, debug_mode=False):
+ """
+ Génère un graphe qui est l'union des edges/nodes des graphes de chaque
+ quartiers où path_list est le resultat du drone
+ Parameters:
+ debug_mode (bool: default = False): le debug mode duh
+ Return:
+ nx.MultiDiGraph/nx.DiGraph : la fusion des quartiers
+ """
+ return logic_quartiers_(path_list, montreal_g, suburb_list, debug_mode)