phase 3 : le mix du chef
1. découpage des tronçons tous les x mètres 2. récup ligne pgr_drivingDistance 3. ST_LocateAlong tous les x mètres -> la distance est calculée par les infos dans la table secteurs
This commit is contained in:
parent
708afdab93
commit
110c8eb4f6
|
@ -14,5 +14,4 @@ user=redadeg
|
||||||
passwd=redadeg
|
passwd=redadeg
|
||||||
|
|
||||||
[redadeg]
|
[redadeg]
|
||||||
longueur_densification=5
|
longueur_densification=10
|
||||||
pk_start=11
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ import datetime
|
||||||
import time
|
import time
|
||||||
import configparser
|
import configparser
|
||||||
import psycopg2
|
import psycopg2
|
||||||
#from logguer import log_verif
|
|
||||||
|
# from logguer import log_verif
|
||||||
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
@ -24,123 +25,47 @@ date = datetime.datetime.now()
|
||||||
|
|
||||||
# lecture du fichier de configuration qui contient les infos de connection
|
# lecture du fichier de configuration qui contient les infos de connection
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read( script_dir + '/config.ini')
|
config.read(script_dir + '/config.ini')
|
||||||
|
|
||||||
|
# fichier_log = str(date.year)+str(date.month)+str(date.day)+"_"+str(date.hour)+str(date.minute)
|
||||||
|
fichier_log = str(date.year) + str(date.month) + str(date.day)
|
||||||
#fichier_log = str(date.year)+str(date.month)+str(date.day)+"_"+str(date.hour)+str(date.minute)
|
|
||||||
fichier_log = str(date.year)+str(date.month)+str(date.day)
|
|
||||||
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
def initConnRedadegDB():
|
def initConnRedadegDB():
|
||||||
|
# connexion à la base postgresql
|
||||||
# connexion à la base postgresql
|
|
||||||
try:
|
|
||||||
global db_redadeg_pg_conn
|
|
||||||
db_redadeg_pg_conn = psycopg2.connect(db_redadeg_conn_str)
|
|
||||||
db_redadeg_pg_conn.set_session(autocommit=True)
|
|
||||||
|
|
||||||
print(" Connexion à la base "+db_redadeg_db+" sur "+db_redadeg_host+" réussie ")
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as err:
|
|
||||||
print(" Connexion à la base "+db_redadeg_db+" sur "+db_redadeg_host+ " impossible ")
|
|
||||||
try:
|
try:
|
||||||
err.pgcode
|
global db_redadeg_pg_conn
|
||||||
print(" PostgreSQL error code : " + err.pgcode)
|
db_redadeg_pg_conn = psycopg2.connect(db_redadeg_conn_str)
|
||||||
sys.exit()
|
db_redadeg_pg_conn.set_session(autocommit=True)
|
||||||
except:
|
|
||||||
print(" " + str(err),0)
|
print(" Connexion à la base " + db_redadeg_db + " sur " + db_redadeg_host + " réussie ")
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
print(" Connexion à la base " + db_redadeg_db + " sur " + db_redadeg_host + " impossible ")
|
||||||
|
try:
|
||||||
|
err.pgcode
|
||||||
|
print(" PostgreSQL error code : " + err.pgcode)
|
||||||
|
sys.exit()
|
||||||
|
except:
|
||||||
|
print(" " + str(err), 0)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
def closeConnRedadegDB():
|
def closeConnRedadegDB():
|
||||||
|
try:
|
||||||
try:
|
db_redadeg_pg_conn.close()
|
||||||
db_redadeg_pg_conn.close()
|
print(" Fermeture de la connexion à la base " + db_redadeg_db + " sur " + db_redadeg_host)
|
||||||
print(" Fermeture de la connexion à la base "+db_redadeg_db+" sur "+db_redadeg_host)
|
except:
|
||||||
except:
|
pass
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
def getPKfromRouting(start, distance):
|
|
||||||
|
|
||||||
sql_routage = """
|
|
||||||
WITH t AS (
|
|
||||||
SELECT *
|
|
||||||
FROM pgr_drivingDistance('SELECT id, source, target, cost, reverse_cost FROM phase_3_troncons_pgr
|
|
||||||
WHERE SOURCE IS NOT NULL AND id > 0',
|
|
||||||
"""+str(start)+""", """+str(distance)+""")
|
|
||||||
)
|
|
||||||
SELECT node, edge, round(agg_cost) FROM t ORDER BY seq DESC LIMIT 1;"""
|
|
||||||
|
|
||||||
#print(sql_routage)
|
|
||||||
|
|
||||||
cursor = db_redadeg_pg_conn.cursor()
|
|
||||||
cursor.execute(sql_routage)
|
|
||||||
|
|
||||||
# on récupère l'id du nœud de fin
|
|
||||||
data = cursor.fetchone()
|
|
||||||
node_end = data[0]
|
|
||||||
edge = data[1]
|
|
||||||
distance = data[2]
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
return([node_end, edge, distance])
|
|
||||||
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
def getPgrNodeInfos(node_id):
|
|
||||||
|
|
||||||
# cette fonction va chercher les infos où il faut pour le PK
|
|
||||||
cursor = db_redadeg_pg_conn.cursor()
|
|
||||||
|
|
||||||
# géométrie…
|
|
||||||
sql_get_from_pgr_node = """
|
|
||||||
SELECT
|
|
||||||
the_geom,
|
|
||||||
TRUNC(ST_X(the_geom)::numeric,1) AS x,
|
|
||||||
TRUNC(ST_Y(the_geom)::numeric,1) AS y,
|
|
||||||
TRUNC(ST_X(ST_Transform(the_geom,4326)::geometry(Point, 4326))::numeric,8) AS long,
|
|
||||||
TRUNC(ST_Y(ST_Transform(the_geom,4326)::geometry(Point, 4326))::numeric,8) AS lat
|
|
||||||
FROM phase_3_troncons_pgr_vertices_pgr v WHERE id = """+ str(node_id) +""";"""
|
|
||||||
#print(sql_get_from_pgr_node)
|
|
||||||
|
|
||||||
cursor.execute(sql_get_from_pgr_node)
|
|
||||||
data = cursor.fetchone()
|
|
||||||
the_geom = data[0]
|
|
||||||
x = data[1]
|
|
||||||
y = data[2]
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
@ -153,44 +78,42 @@ startTime = time.perf_counter()
|
||||||
# on récupère les arguments passés
|
# on récupère les arguments passés
|
||||||
list_of_args = sys.argv
|
list_of_args = sys.argv
|
||||||
|
|
||||||
millesime=""
|
millesime = ""
|
||||||
secteur=""
|
secteur = ""
|
||||||
typemaj=""
|
typemaj = ""
|
||||||
|
|
||||||
# et on fait des tests
|
# et on fait des tests
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if len(list_of_args[1]) != 4:
|
if len(list_of_args[1]) != 4:
|
||||||
print("Pas de millésime en argument")
|
print("Pas de millésime en argument")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
else:
|
|
||||||
millesime = list_of_args[1]
|
|
||||||
|
|
||||||
# millesime ok : on passe au secteur
|
|
||||||
if len(list_of_args[2]) != 3:
|
|
||||||
print("Pas d'id secteur en argument")
|
|
||||||
sys.exit()
|
|
||||||
else:
|
else:
|
||||||
secteur = list_of_args[2]
|
millesime = list_of_args[1]
|
||||||
|
|
||||||
# ok : tout est bon on peut commencer
|
# millesime ok : on passe au secteur
|
||||||
# sortie des tests
|
if len(list_of_args[2]) != 3:
|
||||||
|
print("Pas d'id secteur en argument")
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
secteur = list_of_args[2]
|
||||||
|
|
||||||
|
# ok : tout est bon on peut commencer
|
||||||
|
# sortie des tests
|
||||||
|
|
||||||
|
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
print("Erreur dans les arguments --> stop")
|
print("Erreur dans les arguments --> stop")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
except:
|
except:
|
||||||
print("oups : vérifiez vos arguments passés au script !")
|
print("oups : vérifiez vos arguments passés au script !")
|
||||||
print("stop")
|
print("stop")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
|
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
|
||||||
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
|
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
|
||||||
print("")
|
print("")
|
||||||
print(" Calcul des PK 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 ")
|
||||||
|
@ -199,15 +122,14 @@ print("")
|
||||||
# BD Ar Redadeg
|
# BD Ar Redadeg
|
||||||
global db_redadeg_host
|
global db_redadeg_host
|
||||||
global db_redadeg_db
|
global db_redadeg_db
|
||||||
db_redadeg_host = config.get('redadeg_database', 'host')
|
db_redadeg_host = config.get('redadeg_database', 'host')
|
||||||
db_redadeg_port = config.get('redadeg_database', 'port')
|
db_redadeg_port = config.get('redadeg_database', 'port')
|
||||||
db_redadeg_db = config.get('redadeg_database', 'db')+"_"+str(millesime)
|
db_redadeg_db = config.get('redadeg_database', 'db') + "_" + str(millesime)
|
||||||
db_redadeg_user = config.get('redadeg_database', 'user')
|
db_redadeg_user = config.get('redadeg_database', 'user')
|
||||||
db_redadeg_passwd = config.get('redadeg_database', 'passwd')
|
db_redadeg_passwd = config.get('redadeg_database', 'passwd')
|
||||||
# chaîne de connection
|
# chaîne de connection
|
||||||
global db_redadeg_conn_str
|
global db_redadeg_conn_str
|
||||||
db_redadeg_conn_str = "host="+db_redadeg_host+" port="+db_redadeg_port+" dbname="+db_redadeg_db+" user="+db_redadeg_user+" password="+db_redadeg_passwd
|
db_redadeg_conn_str = "host=" + db_redadeg_host + " port=" + db_redadeg_port + " dbname=" + db_redadeg_db + " user=" + db_redadeg_user + " password=" + db_redadeg_passwd
|
||||||
|
|
||||||
|
|
||||||
initConnRedadegDB()
|
initConnRedadegDB()
|
||||||
|
|
||||||
|
@ -220,164 +142,91 @@ print("")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
print(" Récupération des infos du secteur")
|
||||||
|
|
||||||
# ------------------------------------------------------
|
sql_get_infos_secteur = "SELECT pk_start, pk_stop, node_start, node_stop, longueur "
|
||||||
print(" Récupération des infos du secteur")
|
sql_get_infos_secteur += "FROM secteur "
|
||||||
|
sql_get_infos_secteur += "WHERE id = " + secteur + " ;"
|
||||||
|
|
||||||
# PK de départ de la Redadeg (à cause de l'avant course)
|
db_redadeg_cursor.execute(sql_get_infos_secteur)
|
||||||
pk_start_redadeg = config.get('redadeg', 'pk_start')
|
infos_secteur = db_redadeg_cursor.fetchone()
|
||||||
|
|
||||||
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)
|
secteur_pk_start = infos_secteur[0]
|
||||||
infos_secteur = db_redadeg_cursor.fetchone()
|
secteur_pk_stop = infos_secteur[1]
|
||||||
|
secteur_node_start = infos_secteur[2]
|
||||||
|
secteur_node_stop = infos_secteur[3]
|
||||||
|
secteur_longueur = infos_secteur[4]
|
||||||
|
# pour test
|
||||||
|
# secteur_longueur = 10000
|
||||||
|
|
||||||
secteur_pk_start = infos_secteur[0]
|
print(" fait")
|
||||||
secteur_node_start = infos_secteur[1]
|
print("")
|
||||||
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
|
# on détermine le nb théorique de PK pour ce secteur
|
||||||
longueur_densification = config.get('redadeg', 'longueur_densification')
|
secteur_nb_pk = secteur_pk_stop - secteur_pk_start
|
||||||
|
# et ainsi la longueur réelle entre chaque PK
|
||||||
|
longueur_decoupage = int(secteur_longueur / secteur_nb_pk)
|
||||||
|
|
||||||
print(" fait")
|
print(" " + str(secteur_nb_pk + 1) + " KM redadeg de " + str(longueur_decoupage) + " m vont être créés")
|
||||||
print("")
|
print(" pour une longeur réelle de " + '{:,}'.format(secteur_longueur).replace(',', ' ') + " m")
|
||||||
|
print("")
|
||||||
|
|
||||||
# on détermine le nb théorique de PK pour ce secteur
|
# ------------------------------------------------------
|
||||||
secteur_nb_pk = int(secteur_longueur / secteur_longueur_km_redadeg)
|
print(" Suppression des PK du secteur")
|
||||||
# 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")
|
sql_delete_pks = f"DELETE FROM phase_3_pk WHERE secteur_id = {secteur} ;"
|
||||||
print(" pour une longeur réelle de " + str(secteur_longueur) + " m")
|
db_redadeg_cursor.execute(sql_delete_pks)
|
||||||
print("")
|
print(" fait")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
print(" Création des nouveaux PK du secteur tous les " + str(longueur_decoupage) + " m")
|
||||||
|
|
||||||
|
sql_generate_pks = f"""
|
||||||
|
WITH linemeasure AS (
|
||||||
|
WITH line AS (
|
||||||
|
-- on récupère un itinéraire calculée par pgRouting
|
||||||
|
SELECT ST_Union(the_geom) AS the_geom
|
||||||
|
FROM pgr_drivingDistance('SELECT id, source, target, cost, reverse_cost FROM phase_3_troncons_pgr
|
||||||
|
WHERE SOURCE IS NOT NULL AND secteur_id = {secteur}',
|
||||||
|
{secteur_node_start},{secteur_longueur}) a
|
||||||
|
JOIN phase_3_troncons_pgr b ON a.edge = b.id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
generate_series(0, (ST_Length(line.the_geom))::int, {longueur_decoupage}) AS i,
|
||||||
|
ST_AddMeasure(the_geom,0,ST_length(the_geom)) AS the_geom
|
||||||
|
FROM line
|
||||||
|
)
|
||||||
|
INSERT INTO phase_3_pk (pk_id,secteur_id,length_real,length_total,the_geom)
|
||||||
|
SELECT
|
||||||
|
ROW_NUMBER() OVER() + ({secteur_pk_start}-1)
|
||||||
|
,{secteur}
|
||||||
|
,{longueur_decoupage}
|
||||||
|
,i
|
||||||
|
,(ST_Dump(ST_GeometryN(ST_LocateAlong(the_geom, i), 1))).geom AS the_geom
|
||||||
|
FROM linemeasure ;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_redadeg_cursor.execute(sql_generate_pks)
|
||||||
|
print(" fait")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
print(" sauvegarde de la longueur de découpage pour ce secteur")
|
||||||
|
sql_update_secteur = "UPDATE secteur SET longueur_km_redadeg = " + str(longueur_decoupage)
|
||||||
|
sql_update_secteur += f"WHERE id = {secteur} ;"
|
||||||
|
db_redadeg_cursor.execute(sql_update_secteur)
|
||||||
|
print(" fait")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
# cette variable pour stocker la requête SQL de création des PK
|
db_redadeg_cursor.close()
|
||||||
# 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"
|
|
||||||
|
|
||||||
# ------------------------------------------------------
|
|
||||||
print(" Calcul du 1er PK du secteur")
|
|
||||||
|
|
||||||
# on a les infos -> on calcule la route qui va du 1er nœud de départ et qui fait la distance demandée
|
|
||||||
# pour récupérer l'id du noeud de fin qui va devenir notre PK
|
|
||||||
node_zero = secteur_node_start
|
|
||||||
node_zero_data = getPgrNodeInfos(node_zero)
|
|
||||||
|
|
||||||
sql_insert_pks += "INSERT INTO phase_3_pk (secteur_id, pk_id, the_geom, pk_x, pk_y, pk_long, pk_lat, length_theorical, length_real) VALUES ("
|
|
||||||
sql_insert_pks += secteur + ", " + str(secteur_pk_start)
|
|
||||||
sql_insert_pks += ",'" + node_zero_data[0] + "'"
|
|
||||||
sql_insert_pks += "," + str(node_zero_data[1]) + "," + str(node_zero_data[2])
|
|
||||||
sql_insert_pks += "," + str(node_zero_data[3]) + "," + str(node_zero_data[4])
|
|
||||||
sql_insert_pks += f",{longueur_decoupage},0"
|
|
||||||
sql_insert_pks += ");\n"
|
|
||||||
|
|
||||||
print(" nœud du PK " + str(secteur_pk_start) + " : " + str(node_zero))
|
|
||||||
print("")
|
|
||||||
|
|
||||||
# ------------------------------------------------------
|
|
||||||
print(" Calcul des autres PK")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
# maintenant on peut itérer jusqu'à la fin du secteur
|
|
||||||
node_x = node_zero
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# un compteur pour la boucle
|
|
||||||
i = 1
|
|
||||||
# début de l'id des PK qui commence avec le PK de début du secteur
|
|
||||||
pk_id = secteur_pk_start
|
|
||||||
|
|
||||||
# tant que la distance restante est supérieure à la distance de découpage
|
|
||||||
# on boucle
|
|
||||||
while longueur_restante >= longueur_decoupage:
|
|
||||||
|
|
||||||
# incrément du compteur de la boucle
|
|
||||||
i += 1
|
|
||||||
# incrément du compteur de PK
|
|
||||||
pk_id += 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]
|
|
||||||
longueur_km_redadeg = pk_data[2]
|
|
||||||
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 pour suivre si le traitement bosse
|
|
||||||
if (i <= 5) or (i % 10 == 0) or (i >= secteur_nb_pk - 5):
|
|
||||||
print(" PK " + str(pk_id))
|
|
||||||
print(" id du nœud : " + 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)
|
|
||||||
|
|
||||||
# on fait une requête SQL d'insert de ce PK
|
|
||||||
sql_insert_pks += "INSERT INTO phase_3_pk (secteur_id, pk_id, the_geom, pk_x, pk_y, pk_long, pk_lat, length_theorical, length_real) VALUES ("
|
|
||||||
sql_insert_pks += secteur + "," + str(pk_id)
|
|
||||||
sql_insert_pks += ",'" + node_x_data[0] + "'"
|
|
||||||
sql_insert_pks += "," + str(node_x_data[1]) + "," + str(node_x_data[2])
|
|
||||||
sql_insert_pks += "," + str(node_x_data[3]) + "," + str(node_x_data[4])
|
|
||||||
sql_insert_pks += f",{longueur_decoupage},{longueur_km_redadeg}"
|
|
||||||
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)
|
|
||||||
print(" fait")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
print(" Écriture des PK dans la couche phase_3_pk")
|
|
||||||
db_redadeg_cursor.execute(sql_insert_pks)
|
|
||||||
print(" fait")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
print(" sauvegarde du dernier PK calculé pour ce secteur")
|
|
||||||
# on est sorti de la boucle alors on va écrire en base l'id du dernier PK calculé
|
|
||||||
sql_update_pk_end = "UPDATE secteur SET pk_stop = " + str(pk_id)
|
|
||||||
sql_update_pk_end += "WHERE id = " + secteur + " ;"
|
|
||||||
db_redadeg_cursor.execute(sql_update_pk_end)
|
|
||||||
print(" fait")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
db_redadeg_cursor.close()
|
|
||||||
|
|
||||||
print("")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print(" ERREUR : " + str(err))
|
print(" ERREUR : " + str(err))
|
||||||
closeConnRedadegDB()
|
closeConnRedadegDB()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
@ -385,7 +234,6 @@ db_redadeg_cursor.close()
|
||||||
|
|
||||||
closeConnRedadegDB()
|
closeConnRedadegDB()
|
||||||
|
|
||||||
|
|
||||||
# pour connaître le temps d'exécution
|
# pour connaître le temps d'exécution
|
||||||
print("")
|
print("")
|
||||||
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
|
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
|
||||||
|
@ -395,11 +243,11 @@ print("")
|
||||||
stopTime = time.perf_counter()
|
stopTime = time.perf_counter()
|
||||||
|
|
||||||
# version simple en secondes
|
# version simple en secondes
|
||||||
#print(f"Exécuté en {stopTime - startTime:0.4f} secondes")
|
# print(f"Exécuté en {stopTime - startTime:0.4f} secondes")
|
||||||
|
|
||||||
# version en h min s
|
# version en h min s
|
||||||
hours, rem = divmod(stopTime - startTime, 3600)
|
hours, rem = divmod(stopTime - startTime, 3600)
|
||||||
minutes, seconds = divmod(rem, 60)
|
minutes, seconds = divmod(rem, 60)
|
||||||
print("Exécuté en {:0>2}:{:0>2}:{:05.2f}".format(int(hours),int(minutes),seconds))
|
print("Exécuté en {:0>2}:{:0>2}:{:05.2f}".format(int(hours), int(minutes), seconds))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -507,25 +507,8 @@ ALTER TABLE phase_2_tdb OWNER TO redadeg;
|
||||||
==========================================================================
|
==========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
-- cette table contient les infos de découpage des tronçons
|
|
||||||
DROP TABLE IF EXISTS phase_3_secteurs CASCADE ;
|
|
||||||
CREATE TABLE phase_3_secteurs
|
|
||||||
(
|
|
||||||
secteur_id integer,
|
|
||||||
nom_br text,
|
|
||||||
nom_fr text,
|
|
||||||
longueur_km_redadeg integer,
|
|
||||||
node_start integer,
|
|
||||||
node_stop integer,
|
|
||||||
pk_start integer,
|
|
||||||
pk_stop integer,
|
|
||||||
CONSTRAINT phase_3_secteurs_pkey PRIMARY KEY (secteur_id)
|
|
||||||
);
|
|
||||||
ALTER TABLE phase_3_secteurs OWNER TO redadeg;
|
|
||||||
|
|
||||||
|
|
||||||
-- la table qui va accueillir une couche support de calcul itinéraire phase 3
|
-- la table qui va accueillir une couche support de calcul itinéraire phase 3
|
||||||
-- à savoir les tronçons phase 2 découpés tous les x mètres
|
|
||||||
DROP TABLE IF EXISTS phase_3_troncons_pgr CASCADE ;
|
DROP TABLE IF EXISTS phase_3_troncons_pgr CASCADE ;
|
||||||
CREATE TABLE phase_3_troncons_pgr
|
CREATE TABLE phase_3_troncons_pgr
|
||||||
(
|
(
|
||||||
|
@ -552,6 +535,7 @@ CREATE INDEX phase_3_troncons_pgr_geom_idx ON phase_3_troncons_pgr USING gist(th
|
||||||
ALTER TABLE phase_3_troncons_pgr OWNER to redadeg;
|
ALTER TABLE phase_3_troncons_pgr OWNER to redadeg;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
DROP TABLE IF EXISTS phase_3_troncons CASCADE ;
|
DROP TABLE IF EXISTS phase_3_troncons CASCADE ;
|
||||||
CREATE TABLE phase_3_troncons
|
CREATE TABLE phase_3_troncons
|
||||||
(
|
(
|
||||||
|
@ -575,7 +559,7 @@ CREATE VIEW phase_3_troncons_4326 AS
|
||||||
ST_Transform(the_geom,4326) AS the_geom
|
ST_Transform(the_geom,4326) AS the_geom
|
||||||
FROM phase_3_troncons ;
|
FROM phase_3_troncons ;
|
||||||
ALTER TABLE phase_3_troncons_4326 OWNER TO redadeg;
|
ALTER TABLE phase_3_troncons_4326 OWNER TO redadeg;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS phase_3_trace_secteurs CASCADE ;
|
DROP TABLE IF EXISTS phase_3_trace_secteurs CASCADE ;
|
||||||
|
@ -617,6 +601,7 @@ CREATE TABLE phase_3_pk
|
||||||
pk_lat numeric(10,8),
|
pk_lat numeric(10,8),
|
||||||
length_real integer,
|
length_real integer,
|
||||||
length_theorical integer,
|
length_theorical integer,
|
||||||
|
length_total integer,
|
||||||
secteur_id integer,
|
secteur_id integer,
|
||||||
municipality_admincode text,
|
municipality_admincode text,
|
||||||
municipality_postcode text,
|
municipality_postcode text,
|
||||||
|
@ -631,7 +616,7 @@ CREATE TABLE phase_3_pk
|
||||||
way_name_br text,
|
way_name_br text,
|
||||||
the_geom geometry,
|
the_geom geometry,
|
||||||
CONSTRAINT phase_3_pk_pkey PRIMARY KEY (pk_id),
|
CONSTRAINT phase_3_pk_pkey PRIMARY KEY (pk_id),
|
||||||
CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype(the_geom) = 'POINT'::text),
|
--CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype(the_geom) = 'POINT'::text),
|
||||||
CONSTRAINT enforce_srid_the_geom CHECK (st_srid(the_geom) = 2154)
|
CONSTRAINT enforce_srid_the_geom CHECK (st_srid(the_geom) = 2154)
|
||||||
) ;
|
) ;
|
||||||
CREATE INDEX phase_3_pk_geom_idx ON phase_3_pk USING gist(the_geom);
|
CREATE INDEX phase_3_pk_geom_idx ON phase_3_pk USING gist(the_geom);
|
||||||
|
|
115
scripts_v2/sql/phase_3_linear_referencing.sql
Normal file
115
scripts_v2/sql/phase_3_linear_referencing.sql
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
https://postgis.net/docs/ST_AddMeasure.html
|
||||||
|
http://postgis.net/docs/ST_LocateAlong.html
|
||||||
|
https://qastack.fr/gis/115341/point-sampling-along-a-pole-wrapping-coastline-with-postgis
|
||||||
|
https://qastack.fr/gis/88196/how-can-i-transform-polylines-into-points-every-n-metres-in-postgis
|
||||||
|
https://www.ibm.com/docs/en/informix-servers/12.10?topic=functions-st-locatealong-function
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
-- RAZ de la topologie pgRouting
|
||||||
|
TRUNCATE TABLE phase_3_troncons_pgr;
|
||||||
|
ALTER SEQUENCE phase_3_troncons_pgr_id_seq RESTART WITH 1;
|
||||||
|
VACUUM phase_3_troncons_pgr;
|
||||||
|
|
||||||
|
TRUNCATE TABLE phase_3_troncons_pgr_vertices_pgr;
|
||||||
|
ALTER SEQUENCE phase_3_troncons_pgr_vertices_pgr_id_seq RESTART WITH 1;
|
||||||
|
VACUUM phase_3_troncons_pgr_vertices_pgr;
|
||||||
|
|
||||||
|
-- RAZ de la couche de PK
|
||||||
|
TRUNCATE TABLE phase_3_pk ;
|
||||||
|
VACUUM phase_3_pk;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- on supprime ce qui concerne le secteur
|
||||||
|
DELETE FROM phase_3_troncons_pgr WHERE secteur_id = 100 ;
|
||||||
|
INSERT INTO phase_3_troncons_pgr (secteur_id, path_seq, osm_id, highway, type, oneway, ref, name_fr, name_br, the_geom)
|
||||||
|
SELECT
|
||||||
|
secteur_id, path_seq, osm_id, highway, type, oneway, ref, name_fr, name_br, the_geom
|
||||||
|
FROM phase_2_trace_pgr
|
||||||
|
WHERE secteur_id = 100 ;
|
||||||
|
|
||||||
|
|
||||||
|
-- calcul des coûts (longueur)
|
||||||
|
UPDATE phase_3_troncons_pgr
|
||||||
|
SET
|
||||||
|
cost = trunc(st_length(the_geom)::numeric,2),
|
||||||
|
reverse_cost = trunc(st_length(the_geom)::numeric,2)
|
||||||
|
WHERE secteur_id = 100 ;
|
||||||
|
|
||||||
|
-- calcul de la topologie
|
||||||
|
SELECT pgr_createTopology('phase_3_troncons_pgr', 0.001, rows_where:='secteur_id=100', clean:=false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- calcul d'un point placé à 920 m sur une ligne de 1000 m
|
||||||
|
WITH linemeasure AS (
|
||||||
|
WITH line AS (
|
||||||
|
-- on récupère une ligne de 1000 m calculée par pgRouting
|
||||||
|
SELECT ST_Union(the_geom) AS the_geom
|
||||||
|
FROM pgr_drivingDistance('SELECT id, source, target, cost, reverse_cost FROM phase_3_troncons_pgr
|
||||||
|
WHERE SOURCE IS NOT NULL AND id > 0',
|
||||||
|
9,1000) a
|
||||||
|
JOIN phase_3_troncons_pgr b ON a.edge = b.id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
ST_AddMeasure(the_geom,0,ST_length(the_geom)) AS the_geom
|
||||||
|
FROM line
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
ST_LocateAlong(the_geom,920) AS the_geom
|
||||||
|
FROM linemeasure;
|
||||||
|
|
||||||
|
|
||||||
|
-- calcul de points tous les 200 m
|
||||||
|
-- depuis une ligne calculée par pgRouting
|
||||||
|
WITH linemeasure AS (
|
||||||
|
WITH line AS (
|
||||||
|
-- on récupère une ligne de 1000 m calculée par pgRouting
|
||||||
|
SELECT ST_Union(the_geom) AS the_geom
|
||||||
|
FROM pgr_drivingDistance('SELECT id, source, target, cost, reverse_cost FROM phase_3_troncons_pgr
|
||||||
|
WHERE SOURCE IS NOT NULL AND id > 0',
|
||||||
|
9,2000) a
|
||||||
|
JOIN phase_3_troncons_pgr b ON a.edge = b.id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
generate_series(0, (ST_Length(line.the_geom))::int, 200) AS i,
|
||||||
|
ST_AddMeasure(the_geom,0,ST_length(the_geom)) AS the_geom
|
||||||
|
FROM line
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
i
|
||||||
|
,(ST_Dump(ST_GeometryN(ST_LocateAlong(the_geom, i), 1))).geom AS geom
|
||||||
|
FROM linemeasure;
|
||||||
|
|
||||||
|
|
||||||
|
-- calcul de points tous les 920 m
|
||||||
|
-- depuis une ligne calculée par pgRouting
|
||||||
|
WITH linemeasure AS (
|
||||||
|
WITH line AS (
|
||||||
|
-- on récupère un itinéraire calculée par pgRouting
|
||||||
|
SELECT ST_Union(the_geom) AS the_geom
|
||||||
|
FROM pgr_dijkstra('SELECT id, source, target, cost, reverse_cost FROM phase_3_troncons_pgr',
|
||||||
|
9,1506) a
|
||||||
|
JOIN phase_3_troncons_pgr b ON a.edge = b.id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
generate_series(0, (ST_Length(line.the_geom))::int, 920) AS i,
|
||||||
|
ST_AddMeasure(the_geom,0,ST_length(the_geom)) AS the_geom
|
||||||
|
FROM line
|
||||||
|
)
|
||||||
|
INSERT INTO phase_3_pk (pk_id,length_real,length_total,the_geom)
|
||||||
|
SELECT
|
||||||
|
ROW_NUMBER() OVER() + 11 AS pk
|
||||||
|
,920
|
||||||
|
,i AS longueur_cumulee
|
||||||
|
,(ST_Dump(ST_GeometryN(ST_LocateAlong(the_geom, i), 1))).geom AS the_geom
|
||||||
|
FROM linemeasure ;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ FROM (
|
||||||
pk.pk_id,
|
pk.pk_id,
|
||||||
t.osm_id, t.highway, t."type", t.oneway, t."ref", t.name_fr, t.name_br
|
t.osm_id, t.highway, t."type", t.oneway, t."ref", t.name_fr, t.name_br
|
||||||
FROM phase_3_pk pk, phase_3_troncons_pgr t
|
FROM phase_3_pk pk, phase_3_troncons_pgr t
|
||||||
WHERE ST_INTERSECTS(pk.the_geom, t.the_geom)
|
WHERE ST_INTERSECTS(ST_BUFFER(pk.the_geom,1), t.the_geom)
|
||||||
ORDER BY pk_id
|
ORDER BY pk_id
|
||||||
) sub
|
) sub
|
||||||
WHERE phase_3_pk.pk_id = sub.pk_id;"""
|
WHERE phase_3_pk.pk_id = sub.pk_id;"""
|
||||||
|
@ -164,7 +164,7 @@ WHERE phase_3_pk.pk_id = sub.pk_id;"""
|
||||||
|
|
||||||
print(" Mise à jour des informations sur les communes")
|
print(" Mise à jour des informations sur les communes")
|
||||||
|
|
||||||
sql_update_infos_ways = """
|
sql_update_infos_communes = """
|
||||||
UPDATE phase_3_pk
|
UPDATE phase_3_pk
|
||||||
SET
|
SET
|
||||||
municipality_admincode = sub.insee ,
|
municipality_admincode = sub.insee ,
|
||||||
|
@ -182,7 +182,7 @@ FROM (
|
||||||
) sub
|
) sub
|
||||||
WHERE phase_3_pk.pk_id = sub.pk_id;"""
|
WHERE phase_3_pk.pk_id = sub.pk_id;"""
|
||||||
|
|
||||||
db_redadeg_cursor.execute(sql_update_infos_ways)
|
db_redadeg_cursor.execute(sql_update_infos_communes)
|
||||||
print(" fait")
|
print(" fait")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue