phase 3 : segmentation basée sur la vraie longueur parcourue

This commit is contained in:
MaelREBOUX 2021-11-06 10:15:07 +01:00
parent 95b93bd070
commit fccc2b8c29
3 changed files with 118 additions and 45 deletions

View file

@ -120,13 +120,30 @@ FROM phase_3_troncons_pgr_vertices_pgr v WHERE id = """+ str(node_id) +""";"""
long = data[3] long = data[3]
lat = data[4] lat = data[4]
cursor.close() cursor.close()
return([the_geom,x,y,long,lat]) return([the_geom,x,y,long,lat])
#
# ==============================================================================
def getLongueurParcourue(node_start, node_end):
# cette fonction sert à retourner la longueur parcourue entre 2 nœuds
sql_get_longueur = "SELECT round(max(agg_cost))::integer "
sql_get_longueur += "FROM pgr_dijkstra('SELECT id, source, target, cost, reverse_cost FROM phase_3_troncons_pgr "
sql_get_longueur += " WHERE SOURCE IS NOT NULL', " + str(node_start) + ", " + str(node_end) + ")"
cursor = db_redadeg_pg_conn.cursor()
cursor.execute(sql_get_longueur)
data = cursor.fetchone()[0]
return (data)
# ==============================================================================
# ==============================================================================
# ==============================================================================
# Start processing # Start processing
# #
@ -172,7 +189,7 @@ except:
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
print("") print("")
print(" Calcul des PK et tronçons pour le secteur "+str(secteur)+" pour le millésime "+str(millesime)) print(" Calcul des PK pour le secteur "+str(secteur)+" pour le millésime "+str(millesime))
print("") print("")
print(" Lecture du fichier de configuration ") print(" Lecture du fichier de configuration ")
@ -209,26 +226,39 @@ try:
# PK de départ de la Redadeg (à cause de l'avant course) # PK de départ de la Redadeg (à cause de l'avant course)
pk_start_redadeg = config.get('redadeg', 'pk_start') pk_start_redadeg = config.get('redadeg', 'pk_start')
sql_get_infos_secteur = "SELECT node_start, node_stop, t.longueur_km_redadeg, nb_km_redadeg " sql_get_infos_secteur = "SELECT pk_start, node_start, node_stop, longueur, longueur_km_redadeg "
sql_get_infos_secteur += "FROM phase_3_secteurs s JOIN phase_2_tdb t ON s.secteur_id = t.secteur_id " sql_get_infos_secteur += "FROM secteur "
sql_get_infos_secteur += "WHERE s.secteur_id = "+secteur+" ;" sql_get_infos_secteur += "WHERE id = "+secteur+" ;"
db_redadeg_cursor.execute(sql_get_infos_secteur) db_redadeg_cursor.execute(sql_get_infos_secteur)
infos_secteur = db_redadeg_cursor.fetchone() infos_secteur = db_redadeg_cursor.fetchone()
secteur_node_start = infos_secteur[0] secteur_pk_start = infos_secteur[0]
secteur_node_stop = infos_secteur[1] secteur_node_start = infos_secteur[1]
secteur_longueur_km = infos_secteur[2] secteur_node_stop = infos_secteur[2]
secteur_nb_km = int(infos_secteur[3]) secteur_longueur = infos_secteur[3]
#secteur_nb_km = 10 secteur_longueur_km_redadeg = infos_secteur[4]
# pour test
#secteur_longueur = 10000
# longueur de découpage des tronçons de la phase 2
longueur_densification = config.get('redadeg', 'longueur_densification')
print(" fait") print(" fait")
print("") print("")
print(" "+str(secteur_nb_km)+" km / pk à créer") # on détermine le nb de PK pour ce secteur
secteur_nb_pk = int(secteur_longueur / secteur_longueur_km_redadeg)
# et la longueur réelle demandée au calculateur
longueur_decoupage = int(secteur_longueur_km_redadeg)
print(" " + str(secteur_nb_pk) + " KM redadeg de " + str(secteur_longueur_km_redadeg) + " m vont être créés")
print(" pour une longeur réelle de " + str(secteur_longueur) + " m")
print("") print("")
# cette variable pour stocker la requête SQL de création des PK # cette variable pour stocker la requête SQL de création des PK
# et la première requête sera de supprimer les données du secteur
sql_insert_pks = "DELETE FROM phase_3_pk WHERE secteur_id = "+secteur+" ;\n" sql_insert_pks = "DELETE FROM phase_3_pk WHERE secteur_id = "+secteur+" ;\n"
# ------------------------------------------------------ # ------------------------------------------------------
@ -239,7 +269,6 @@ try:
node_zero = secteur_node_start node_zero = secteur_node_start
node_zero_data = getPgrNodeInfos(node_zero) node_zero_data = getPgrNodeInfos(node_zero)
print(str(node_zero_data[0]))
sql_insert_pks += "INSERT INTO phase_3_pk (secteur_id, pk_id, the_geom, pk_x, pk_y, pk_long, pk_lat) VALUES (" sql_insert_pks += "INSERT INTO phase_3_pk (secteur_id, pk_id, the_geom, pk_x, pk_y, pk_long, pk_lat) VALUES ("
sql_insert_pks += secteur + ",1" sql_insert_pks += secteur + ",1"
@ -259,21 +288,36 @@ try:
# maintenant on peut itérer jusqu'à la fin du secteur # maintenant on peut itérer jusqu'à la fin du secteur
node_x = node_zero node_x = node_zero
for i in range(2, secteur_nb_km + 1): # en sa basant sur la longueur des PK posés et la longueur totale du secteur
longueur_parcourue = getLongueurParcourue(node_zero, node_x)
if longueur_parcourue is None: longueur_parcourue = 0
longueur_restante = secteur_longueur - longueur_parcourue
pk_data = getPKfromRouting(node_x,secteur_longueur_km) # le compteur
i = 1
#for i in range(2, secteur_nb_pk + 1):
# tant que la distance restante est supérieure à la distance de découpage
# on boucle
while longueur_restante >= longueur_decoupage:
# incrément du compteur
i += 1
# on va trouver le prochain PK
pk_data = getPKfromRouting(node_x , longueur_decoupage)
node_x = pk_data[0] node_x = pk_data[0]
previous_pk_edge = pk_data[1] previous_pk_edge = pk_data[1]
longueur_parcourue = getLongueurParcourue(node_zero,node_x)
# on met tt de suite en négatif l'info de routage du précédent tronçon afin de l'écarter du prochain calcul de routage longueur_restante = secteur_longueur - longueur_parcourue
sql_neutralisation = "UPDATE phase_3_troncons_pgr SET id = -ABS("+str(previous_pk_edge)+") WHERE id = "+str(previous_pk_edge)+" ;"
#print(sql_neutralisation)
db_redadeg_cursor.execute(sql_neutralisation)
#print(" nouveau nœud : " + str(node_x)) #print(" nouveau nœud : " + str(node_x))
#print(" previous_pk_edge : "+ str(previous_pk_edge)) #print(" previous_pk_edge : "+ str(previous_pk_edge))
# on sort une infos tous les 10 PK
#if i % 10 == 0:
print(" nœud du PK "+str(i)+" : " + str(node_x)) print(" nœud du PK "+str(i)+" : " + str(node_x))
print(" " + str(longueur_parcourue) + " m jusqu'à maintenant")
print(" " + str(longueur_restante) + " m restant jusqu'à la fin du secteur")
# ici on construit la requête avec les données du PK # ici on construit la requête avec les données du PK
node_x_data = getPgrNodeInfos(node_x) node_x_data = getPgrNodeInfos(node_x)
@ -286,11 +330,17 @@ try:
sql_insert_pks += "," + str(node_x_data[3]) + "," + str(node_x_data[4]) sql_insert_pks += "," + str(node_x_data[3]) + "," + str(node_x_data[4])
sql_insert_pks += ");\n" sql_insert_pks += ");\n"
# on met en négatif l'info de routage du précédent tronçon afin de l'écarter du prochain calcul de routage
sql_neutralisation = "UPDATE phase_3_troncons_pgr SET id = -ABS("+str(previous_pk_edge)+") WHERE id = "+str(previous_pk_edge)+" ;"
#print(sql_neutralisation)
db_redadeg_cursor.execute(sql_neutralisation)
print("") print("")
print(" Fin de la boucle") print(" Fin de la boucle")
print("") print("")
print(" RAZ de la neutralisation des infos de routage pour la boucle") print(" RAZ de la neutralisation des infos de routage pour la boucle")
sql_reset_neutralisation = "UPDATE phase_3_troncons_pgr SET id = -1*id WHERE id < 0 ;" sql_reset_neutralisation = "UPDATE phase_3_troncons_pgr SET id = -1*id WHERE id < 0 ;"
db_redadeg_cursor.execute(sql_reset_neutralisation) db_redadeg_cursor.execute(sql_reset_neutralisation)

View file

@ -187,12 +187,27 @@ WHERE n*"""+longueur_densification+"""/length < 1;"""
db_redadeg_cursor.execute(sql_insert) db_redadeg_cursor.execute(sql_insert)
print(" fait")
print("")
print(" Optimisations...")
# calcul des attributs de support du calcul pour PGR # calcul des attributs de support du calcul pour PGR
sql_update_costs = """ sql_update_costs = """
UPDATE phase_3_troncons_pgr UPDATE phase_3_troncons_pgr
SET cost = round(st_length(the_geom)::numeric), reverse_cost = round(st_length(the_geom)::numeric) SET
WHERE secteur_id = """+secteur +""" ;""" cost =
CASE
WHEN trunc(st_length(the_geom)::numeric,2) = """ + str( float(longueur_densification) - 0.01 ) + """ THEN """ + longueur_densification + """
ELSE trunc(st_length(the_geom)::numeric,2)
END,
reverse_cost =
CASE
WHEN trunc(st_length(the_geom)::numeric,2) = """ + str( float(longueur_densification) - 0.01 ) + """ THEN """ + longueur_densification + """
ELSE trunc(st_length(the_geom)::numeric,2)
END
WHERE secteur_id = """ + secteur + """ ;"""
db_redadeg_cursor.execute(sql_update_costs) db_redadeg_cursor.execute(sql_update_costs)
@ -214,19 +229,8 @@ WHERE secteur_id = """+secteur +""" ;"""
# ------------------------------------------------------ # ------------------------------------------------------
print(" Récupération id des nœuds de début et fin du secteur") print(" Récupération id des nœuds de début et fin du secteur, et la longueur")
# on commence par supprimer le secteur puis on y remet avec les infos de la table des secteurs
sql_init_secteurs = """
DELETE FROM phase_3_secteurs WHERE secteur_id = """+secteur+""" ;
INSERT INTO phase_3_secteurs (secteur_id, nom_br, nom_fr, longueur_km_redadeg)
SELECT id, nom_br, nom_fr, km_redadeg
FROM secteur
WHERE id = """+secteur+"""
ORDER BY id ;"""
db_redadeg_cursor.execute(sql_init_secteurs)
# récupération id node début et fin de secteur # récupération id node début et fin de secteur
secteurs_in_clause = secteur+","+str(int(secteur)+100) secteurs_in_clause = secteur+","+str(int(secteur)+100)
sql_get_nodes = """ sql_get_nodes = """
@ -247,9 +251,23 @@ INSERT INTO phase_3_secteurs (secteur_id, nom_br, nom_fr, longueur_km_redadeg)
node_end_id = node_end[0] node_end_id = node_end[0]
node_end_geom = node_end[1] node_end_geom = node_end[1]
# la longueur
sql_longueur_secteur = """
SELECT sum(COST) AS longueur
FROM phase_3_troncons_pgr
WHERE secteur_id = """ + secteur + """
GROUP BY secteur_id ;"""
# on maj les infos dans la table phase_3_secteurs db_redadeg_cursor.execute(sql_longueur_secteur)
sql_update_nodes_infos = "UPDATE phase_3_secteurs SET node_start = "+str(node_start_id)+", node_stop = "+str(node_end_id)+" WHERE secteur_id = "+secteur +" ;" longueur_secteur = db_redadeg_cursor.fetchone()[0]
longueur_km_secteur = longueur_secteur / 1000
# on maj les infos dans la table secteurs
sql_update_nodes_infos = "UPDATE secteur SET "
sql_update_nodes_infos += "node_start = " + str(node_start_id) + ", node_stop = " + str(node_end_id) + ", "
sql_update_nodes_infos += "longueur = " + str(longueur_secteur) + ", longueur_km = " + str(longueur_km_secteur) + " "
sql_update_nodes_infos += "WHERE id = " + secteur + " ;"
db_redadeg_cursor.execute(sql_update_nodes_infos) db_redadeg_cursor.execute(sql_update_nodes_infos)
print(" fait : "+str(node_start_id)+" -> "+str(node_end_id)) print(" fait : "+str(node_start_id)+" -> "+str(node_end_id))

View file

@ -21,13 +21,18 @@
DROP TABLE IF EXISTS secteur CASCADE ; DROP TABLE IF EXISTS secteur CASCADE ;
CREATE TABLE secteur CREATE TABLE secteur
( (
id integer, id integer,
nom_br text, nom_br text,
nom_fr text, nom_fr text,
objectif_km integer, longueur_km integer,
km_redadeg integer longueur integer,
longueur_km_redadeg integer,
node_start integer,
node_stop integer,
pk_start integer,
pk_stop integer,
CONSTRAINT secteur_pkey PRIMARY KEY (id)
); );
ALTER TABLE secteur OWNER to redadeg; ALTER TABLE secteur OWNER to redadeg;