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]
lat = data[4]
cursor.close()
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
#
@ -172,7 +189,7 @@ except:
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(" Lecture du fichier de configuration ")
@ -209,26 +226,39 @@ try:
# PK de départ de la Redadeg (à cause de l'avant course)
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 += "FROM phase_3_secteurs s JOIN phase_2_tdb t ON s.secteur_id = t.secteur_id "
sql_get_infos_secteur += "WHERE s.secteur_id = "+secteur+" ;"
sql_get_infos_secteur = "SELECT pk_start, node_start, node_stop, longueur, longueur_km_redadeg "
sql_get_infos_secteur += "FROM secteur "
sql_get_infos_secteur += "WHERE id = "+secteur+" ;"
db_redadeg_cursor.execute(sql_get_infos_secteur)
infos_secteur = db_redadeg_cursor.fetchone()
secteur_node_start = infos_secteur[0]
secteur_node_stop = infos_secteur[1]
secteur_longueur_km = infos_secteur[2]
secteur_nb_km = int(infos_secteur[3])
#secteur_nb_km = 10
secteur_pk_start = infos_secteur[0]
secteur_node_start = infos_secteur[1]
secteur_node_stop = infos_secteur[2]
secteur_longueur = infos_secteur[3]
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("")
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("")
# 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"
# ------------------------------------------------------
@ -239,7 +269,6 @@ try:
node_zero = secteur_node_start
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 += secteur + ",1"
@ -259,21 +288,36 @@ try:
# maintenant on peut itérer jusqu'à la fin du secteur
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]
previous_pk_edge = pk_data[1]
# 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
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)
longueur_parcourue = getLongueurParcourue(node_zero,node_x)
longueur_restante = secteur_longueur - longueur_parcourue
#print(" nouveau nœud : " + str(node_x))
#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(" " + 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
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 += ");\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(" Fin de la boucle")
print("")
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 ;"
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)
print(" fait")
print("")
print(" Optimisations...")
# calcul des attributs de support du calcul pour PGR
sql_update_costs = """
UPDATE phase_3_troncons_pgr
SET cost = round(st_length(the_geom)::numeric), reverse_cost = round(st_length(the_geom)::numeric)
WHERE secteur_id = """+secteur +""" ;"""
SET
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)
@ -214,18 +229,7 @@ WHERE secteur_id = """+secteur +""" ;"""
# ------------------------------------------------------
print(" Récupération id des nœuds de début et fin du secteur")
# 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)
print(" Récupération id des nœuds de début et fin du secteur, et la longueur")
# récupération id node début et fin de secteur
secteurs_in_clause = secteur+","+str(int(secteur)+100)
@ -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_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
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 +" ;"
db_redadeg_cursor.execute(sql_longueur_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)
print(" fait : "+str(node_start_id)+" -> "+str(node_end_id))

View file

@ -21,13 +21,18 @@
DROP TABLE IF EXISTS secteur CASCADE ;
CREATE TABLE secteur
(
id integer,
nom_br text,
nom_fr text,
objectif_km integer,
km_redadeg integer
id integer,
nom_br text,
nom_fr text,
longueur_km 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;