def aspectRatio(grid_input, grid_output, roads_input, built_input, seg_dist, seg_length, buffer_size, epsg, project_encoding, server_postgis, port_number, user_postgis, password_postgis, database_postgis, schema_postgis, path_time_log, format_vector='ESRI Shapefile', extension_vector=".shp", save_results_intermediate=False, overwrite=True): print(bold + yellow + "Début du calcul de l'indicateur Aspect Ratio." + endC + "\n") timeLine(path_time_log, "Début du calcul de l'indicateur Aspect Ratio : ") if debug >= 3: print(bold + green + "aspectRatio() : Variables dans la fonction" + endC) print(cyan + "aspectRatio() : " + endC + "grid_input : " + str(grid_input) + endC) print(cyan + "aspectRatio() : " + endC + "grid_output : " + str(grid_output) + endC) print(cyan + "aspectRatio() : " + endC + "roads_input : " + str(roads_input) + endC) print(cyan + "aspectRatio() : " + endC + "built_input : " + str(built_input) + endC) print(cyan + "aspectRatio() : " + endC + "seg_dist : " + str(seg_dist) + endC) print(cyan + "aspectRatio() : " + endC + "seg_length : " + str(seg_length) + endC) print(cyan + "aspectRatio() : " + endC + "buffer_size : " + str(buffer_size) + endC) print(cyan + "aspectRatio() : " + endC + "epsg : " + str(epsg) + endC) print(cyan + "aspectRatio() : " + endC + "project_encoding : " + str(project_encoding) + endC) print(cyan + "aspectRatio() : " + endC + "server_postgis : " + str(server_postgis) + endC) print(cyan + "aspectRatio() : " + endC + "port_number : " + str(port_number) + endC) print(cyan + "aspectRatio() : " + endC + "user_postgis : " + str(user_postgis) + endC) print(cyan + "aspectRatio() : " + endC + "password_postgis : " + str(password_postgis) + endC) print(cyan + "aspectRatio() : " + endC + "database_postgis : " + str(database_postgis) + endC) print(cyan + "aspectRatio() : " + endC + "schema_postgis : " + str(schema_postgis) + endC) print(cyan + "aspectRatio() : " + endC + "format_vector : " + str(format_vector) + endC) print(cyan + "aspectRatio() : " + endC + "extension_vector : " + str(extension_vector) + endC) print(cyan + "aspectRatio() : " + endC + "path_time_log : " + str(path_time_log) + endC) print(cyan + "aspectRatio() : " + endC + "save_results_intermediate : " + str(save_results_intermediate) + endC) print(cyan + "aspectRatio() : " + endC + "overwrite : " + str(overwrite) + endC) # Constantes liées aux données PostGIS et GRASS LOCATION = "LOCATION" MAPSET = "MAPSET" SUFFIX_SEGMENTED = "_segmented" if not os.path.exists(grid_output) or overwrite: ############################################ ### Préparation générale des traitements ### ############################################ if os.path.exists(grid_output): removeVectorFile(grid_output) temp_path = os.path.dirname(grid_output) + os.sep + "AspectRatio" file_name = os.path.splitext(os.path.basename(roads_input))[0] roads_segmented = temp_path + os.sep + file_name + SUFFIX_SEGMENTED + extension_vector if os.path.exists(temp_path): shutil.rmtree(temp_path) # Variables d'environnement spécifiques à GRASS gisbase = os.environ['GISBASE'] gisdb = "GRASS_database" # Variables liées à GRASS permettant la construction de 'LOCATION' et 'MAPSET' xmin, xmax, ymin, ymax = getEmpriseFile(roads_input, format_vector) pixel_size_x, pixel_size_y = 1, 1 ##################################### ### Préparation géodatabase GRASS ### ##################################### print(bold + cyan + "Préparation de la géodatabase GRASS :" + endC) timeLine(path_time_log, " Préparation de la géodatabase GRASS : ") # Initialisation de la connexion à la géodatabase GRASS gisbase, gisdb, location, mapset = initializeGrass( temp_path, xmin, xmax, ymin, ymax, pixel_size_x, pixel_size_y, epsg, gisbase, gisdb, LOCATION, MAPSET, True, overwrite) ################################################### ### Division des routes en segments de x mètres ### ################################################### print(bold + cyan + "Segmentation des routes avec GRASS :" + endC) timeLine(path_time_log, " Segmentation des routes avec GRASS : ") # Segmentation du jeu de données route en segments de x mètres splitGrass(roads_input, roads_segmented, seg_dist, format_vector, overwrite) cleanGrass(temp_path, gisdb, save_results_intermediate) ########################################### ### Préparation base de données PostGIS ### ########################################### print(bold + cyan + "Préparation de la base de données PostGIS :" + endC) timeLine(path_time_log, " Préparation de la base de données PostGIS : ") # Création de la base de données PostGIS # Conflits avec autres indicateurs (Height of Roughness Elements / Terrain Roughness Class) createDatabase(database_postgis) # Import des fichiers shapes maille, bati et routes segmentées dans la base de données PostGIS table_name_maille = importVectorByOgr2ogr(database_postgis, grid_input, 'ara_maille', user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=str(port_number), schema_name=schema_postgis, epsg=str(epsg), codage=project_encoding) table_name_bati = importVectorByOgr2ogr(database_postgis, built_input, 'ara_bati', user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=str(port_number), schema_name=schema_postgis, epsg=str(epsg), codage=project_encoding) table_name_routes_seg = importVectorByOgr2ogr( database_postgis, roads_segmented, 'ara_routes_seg', user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=str(port_number), schema_name=schema_postgis, epsg=str(epsg), codage=project_encoding) # Connection à la base de données PostGIS et initialisation de 'cursor' (permet de récupérer des résultats de requêtes SQL pour les traiter en Python) connection = openConnection(database_postgis, user_postgis, password_postgis, server_postgis, str(port_number), schema_name=schema_postgis) cursor = connection.cursor() # Requête d'ajout de champ ID segment route dans la table routes_seg et création des index pour les shapes importés query_preparation = """ ALTER TABLE %s ADD COLUMN id_seg serial; --CREATE INDEX IF NOT EXISTS routes_seg_geom_gist ON %s USING GIST (geom); --CREATE INDEX IF NOT EXISTS bati_geom_gist ON %s USING GIST (geom); --CREATE INDEX IF NOT EXISTS maille_geom_gist ON %s USING GIST (geom); """ % (table_name_routes_seg, table_name_routes_seg, table_name_bati, table_name_maille) if debug >= 2: print(query_preparation) executeQuery(connection, query_preparation) ############################################################################## ### Création des segments de y mètres perpendiculaires aux segments routes ### ############################################################################## print(bold + cyan + "Création des segments perpendiculaires aux routes :" + endC) timeLine(path_time_log, " Création des segments perpendiculaires aux routes : ") # Début de la construction de la requête de création des segments perpendiculaires query_seg_perp = "DROP TABLE IF EXISTS ara_seg_perp;\n" query_seg_perp += "CREATE TABLE ara_seg_perp (id_seg text, id_perp text, xR float, yR float, xP float, yP float, geom geometry);\n" query_seg_perp += "INSERT INTO ara_seg_perp VALUES\n" # Récupération de la liste des identifiants segments routes cursor.execute( "SELECT id_seg FROM %s GROUP BY id_seg ORDER BY id_seg;" % table_name_routes_seg) id_seg_list = cursor.fetchall() # Boucle sur les segments routes nb_seg = len(id_seg_list) treat_seg = 1 for id_seg in id_seg_list: if debug >= 4: print(bold + " Traitement du segment route : " + endC + str(treat_seg) + "/" + str(nb_seg)) id_seg = id_seg[0] # Table temporaire ne contenant qu'un segment route donné : ST_LineMerge(geom) permet de passer la géométrie de MultiLineString à LineString, pour éviter des problèmes de requêtes spatiales query_temp1_seg = "DROP TABLE IF EXISTS ara_temp1_seg;\n" query_temp1_seg += "CREATE TABLE ara_temp1_seg AS SELECT id_seg as id_seg, ST_LineMerge(geom) as geom FROM %s WHERE id_seg = %s;\n" % ( table_name_routes_seg, id_seg) if debug >= 4: print(query_temp1_seg) executeQuery(connection, query_temp1_seg) # Récupération du nombre de sommets du segment route (utile pour les segments routes en courbe, permet de récupérer le dernier point du segment) cursor.execute("SELECT ST_NPoints(geom) FROM ara_temp1_seg;") nb_points = cursor.fetchone() # Récupération des coordonnées X et Y des points extrémités du segment route query_xR1 = "SELECT ST_X(geom) as X FROM (SELECT ST_AsText(ST_PointN(geom,1)) as geom FROM ara_temp1_seg) as toto;" cursor.execute(query_xR1) xR1 = cursor.fetchone() query_yR1 = "SELECT ST_Y(geom) as Y FROM (SELECT ST_AsText(ST_PointN(geom,1)) as geom FROM ara_temp1_seg) as toto;" cursor.execute(query_yR1) yR1 = cursor.fetchone() query_xR2 = "SELECT ST_X(geom) as X FROM (SELECT ST_AsText(ST_PointN(geom,%s)) as geom FROM ara_temp1_seg) as toto;" % ( nb_points) cursor.execute(query_xR2) xR2 = cursor.fetchone() query_yR2 = "SELECT ST_Y(geom) as Y FROM (SELECT ST_AsText(ST_PointN(geom,%s)) as geom FROM ara_temp1_seg) as toto;" % ( nb_points) cursor.execute(query_yR2) yR2 = cursor.fetchone() # Transformation des coordonnées X et Y des points extrémités du segment route en valeurs numériques xR1 = float(str(xR1)[1:-2]) yR1 = float(str(yR1)[1:-2]) xR2 = float(str(xR2)[1:-2]) yR2 = float(str(yR2)[1:-2]) if debug >= 4: print(" xR1 = " + str(xR1)) print(" yR1 = " + str(yR1)) print(" xR2 = " + str(xR2)) print(" yR2 = " + str(yR2)) # Calcul des delta X et Y entre les points extrémités du segment route dxR = xR1 - xR2 dyR = yR1 - yR2 if debug >= 4: print(" dxR = " + str(dxR)) print(" dyR = " + str(dyR)) print("\n") # Suppression des cas où le script créé des perpendiculaires tous les cm ! Bug lié à la segmentation des routes dist_R1_R2 = math.sqrt((abs(dxR)**2) + (abs(dyR)**2)) if dist_R1_R2 >= (seg_dist / 2): # Calcul de l'angle (= gisement) entre le Nord et le segment route if dxR == 0 or dyR == 0: if dxR == 0 and dyR > 0: aR = 0 elif dxR > 0 and dyR == 0: aR = 90 elif dxR == 0 and dyR < 0: aR = 180 elif dxR < 0 and dyR == 0: aR = 270 else: aR = math.degrees(math.atan(dxR / dyR)) if aR < 0: aR = aR + 360 if debug >= 4: print(" aR = " + str(aR)) # Calcul des angles (= gisements) entre le Nord et les 2 segments perpendiculaires au segment route aP1 = aR + 90 if aP1 < 0: aP1 = aP1 + 360 if aP1 >= 360: aP1 = aP1 - 360 aP2 = aR - 90 if aP2 < 0: aP2 = aP2 + 360 if aP2 >= 360: aP2 = aP2 - 360 if debug >= 4: print(" aP1 = " + str(aP1)) print(" aP2 = " + str(aP2)) # Calculs des coordonnées des nouveaux points à l'extrémité de chaque segment perpendiculaire pour le segment route sélectionné xP1 = xR1 + (seg_length * math.sin(math.radians(aP1))) yP1 = yR1 + (seg_length * math.cos(math.radians(aP1))) xP2 = xR1 + (seg_length * math.sin(math.radians(aP2))) yP2 = yR1 + (seg_length * math.cos(math.radians(aP2))) if debug >= 4: print(" xP1 = " + str(xP1)) print(" yP1 = " + str(yP1)) print(" xP2 = " + str(xP2)) print(" yP2 = " + str(yP2)) print("\n") # Construction de la requête de création des 2 segments perpendiculaires pour le segment route sélectionné query_seg_perp += " ('%s', '%s_perp1', %s, %s, %s, %s, 'LINESTRING(%s %s, %s %s)'),\n" % ( str(id_seg), str(id_seg), xR1, yR1, xP1, yP1, xR1, yR1, xP1, yP1) query_seg_perp += " ('%s', '%s_perp2', %s, %s, %s, %s, 'LINESTRING(%s %s, %s %s)'),\n" % ( str(id_seg), str(id_seg), xR1, yR1, xP2, yP2, xR1, yR1, xP2, yP2) treat_seg += 1 # Fin de la construction de la requête de création des segments perpendiculaires et exécution de cette requête query_seg_perp = query_seg_perp[:-2] + ";\n" # Transformer la virgule de la dernière ligne SQL en point-virgule (pour terminer la requête) query_seg_perp += "ALTER TABLE ara_seg_perp ALTER COLUMN geom TYPE geometry(LINESTRING,%s) USING ST_SetSRID(geom,%s);\n" % ( epsg, epsg) # Mise à jour du système de coordonnées query_seg_perp += "CREATE INDEX IF NOT EXISTS seg_perp_geom_gist ON ara_seg_perp USING GIST (geom);\n" if debug >= 2: print(query_seg_perp) executeQuery(connection, query_seg_perp) ################################################### ### Intersect segments perpendiculaires et bâti ### ################################################### print( bold + cyan + "Intersect entre les segments perpendiculaires et les bâtiments :" + endC) timeLine( path_time_log, " Intersect entre les segments perpendiculaires et les bâtiments : " ) # Requête d'intersect entre les segments perpendiculaires et les bâtiments query_intersect = """ DROP TABLE IF EXISTS ara_intersect_bati; CREATE TABLE ara_intersect_bati AS SELECT r.id_seg as id_seg, r.id_perp as id_perp, r.xR as xR, r.yR as yR, b.HAUTEUR as haut_bati, ST_Intersection(r.geom, b.geom) as geom FROM ara_seg_perp as r, %s as b WHERE ST_Intersects(r.geom, b.geom); ALTER TABLE ara_intersect_bati ADD COLUMN id_intersect serial; CREATE INDEX IF NOT EXISTS intersect_bati_geom_gist ON ara_intersect_bati USING GIST (geom); """ % table_name_bati if debug >= 2: print(query_intersect) executeQuery(connection, query_intersect) ################################################################################################################## ### Récupération des demi-largeurs de rue et de la hauteur du 1er bâtiment pour chaque segment perpendiculaire ### ################################################################################################################## print( bold + cyan + "Récupération des informations nécessaires au calcul du rapport d'aspect :" + endC) timeLine( path_time_log, " Récupération des informations nécessaires au calcul du rapport d'aspect : " ) # Début de la construction de la requête de création des points route, avec infos de demi-largeurs de rue et hauteurs des bâtiments query_pt_route = "DROP TABLE IF EXISTS ara_asp_ratio_by_seg;\n" query_pt_route += "CREATE TABLE ara_asp_ratio_by_seg (id_seg text, xR float, yR float, width1 float, height1 float, width2 float, height2 float, geom geometry);\n" query_pt_route += "INSERT INTO ara_asp_ratio_by_seg VALUES\n" # Récupération de la liste des identifiants segments routes (uniquement ceux qui intersectent du bâti) cursor.execute( "SELECT id_seg FROM ara_intersect_bati GROUP BY id_seg ORDER BY id_seg;" ) id_seg_list = cursor.fetchall() # Boucle sur les segments routes nb_seg = len(id_seg_list) treat_seg = 1 for id_seg in id_seg_list: if debug >= 4: print(bold + " Traitement du segment route : " + endC + str(treat_seg) + "/" + str(nb_seg)) id_seg = id_seg[0] # Table temporaire ne contenant que les intersects d'un segment route donné query_temp2_seg = "DROP TABLE IF EXISTS ara_temp2_seg;\n" query_temp2_seg += "CREATE TABLE ara_temp2_seg AS SELECT id_seg, id_perp, xR, yR, haut_bati, id_intersect, geom FROM ara_intersect_bati WHERE id_seg = '%s';\n" % ( id_seg) if debug >= 4: print(query_temp2_seg) executeQuery(connection, query_temp2_seg) # Récupération des coordonnées X et Y du point route du segment route associé cursor.execute("SELECT xR FROM ara_temp2_seg;") xR = cursor.fetchone() cursor.execute("SELECT yR FROM ara_temp2_seg;") yR = cursor.fetchone() # Transformation des coordonnées X et Y du point route du segment route associé en valeurs numériques xR = float(str(xR)[1:-2]) yR = float(str(yR)[1:-2]) if debug >= 4: print(" xR = " + str(xR)) print(" yR = " + str(yR)) print("\n") # Initialisation des variables demi-largeurs de rue et hauteur du 1er bâtiment intersecté w1 = 0 h1 = 0 w2 = 0 h2 = 0 # Récupération de la liste des identifiants segments perpendiculaires de la table temp2_seg cursor.execute( "SELECT id_perp FROM ara_temp2_seg GROUP BY id_perp ORDER BY id_perp;" ) id_perp_list = cursor.fetchall() # Boucle sur les perpendiculaires (max 2) d'un segment route donné for id_perp in id_perp_list: # Récupération du numéro de perpendiculaire (1 ou 2 ~ droite ou gauche) num_seg = float(str(id_perp)[-4:-3]) # Initialisation de listes contenant les demi-largeurs de rue et les hauteurs des bâtiments intersectés length_list = [] haut_bati_list = [] # Table temporaire ne contenant que les intersects d'un segment perpendiculaire donné query_temp2_perp = "DROP TABLE IF EXISTS ara_temp2_perp;\n" query_temp2_perp += "CREATE TABLE ara_temp2_perp AS SELECT id_seg, id_perp, xR, yR, haut_bati, id_intersect, geom FROM ara_temp2_seg WHERE id_perp = '%s';\n" % ( id_perp) if debug >= 4: print(query_temp2_perp) executeQuery(connection, query_temp2_perp) # Récupération de la liste des identifiants segments intersects de la table temp2_perp cursor.execute( "SELECT id_intersect FROM ara_temp2_perp GROUP BY id_intersect ORDER BY id_intersect;" ) id_intersect_list = cursor.fetchall() # Boucle sur les intersects d'un segment perpendiculaire donné, d'un segment route donné for id_intersect in id_intersect_list: # Récupération des coordonnées X et Y des points extrémités de chaque segment intersect query_xI1 = "SELECT ST_X(geom) as X FROM (SELECT ST_AsText(ST_PointN(geom,1)) as geom FROM ara_temp2_perp WHERE id_intersect = '%s') as toto;" % ( id_intersect) cursor.execute(query_xI1) xI1 = cursor.fetchone() query_yI1 = "SELECT ST_Y(geom) as Y FROM (SELECT ST_AsText(ST_PointN(geom,1)) as geom FROM ara_temp2_perp WHERE id_intersect = '%s') as toto;" % ( id_intersect) cursor.execute(query_yI1) yI1 = cursor.fetchone() query_xI2 = "SELECT ST_X(geom) as X FROM (SELECT ST_AsText(ST_PointN(geom,2)) as geom FROM ara_temp2_perp WHERE id_intersect = '%s') as toto;" % ( id_intersect) cursor.execute(query_xI2) xI2 = cursor.fetchone() query_yI2 = "SELECT ST_Y(geom) as Y FROM (SELECT ST_AsText(ST_PointN(geom,2)) as geom FROM ara_temp2_perp WHERE id_intersect = '%s') as toto;" % ( id_intersect) cursor.execute(query_yI2) yI2 = cursor.fetchone() # Transformation des coordonnées X et Y des points extrémités de chaque segment intersect en valeurs numériques try: xI1 = float(str(xI1)[1:-2]) yI1 = float(str(yI1)[1:-2]) xI2 = float(str(xI2)[1:-2]) yI2 = float(str(yI2)[1:-2]) except ValueError: # Python renvoie une valeur Null pour les bâtiments en U (= intersectés à plus de 2 points) xI1 = yI1 = xI2 = yI2 = 0 if debug >= 4: print(" xI1 = " + str(xI1)) print(" yI1 = " + str(yI1)) print(" xI2 = " + str(xI2)) print(" yI2 = " + str(yI2)) # Calcul des distances entre la route et chaque point du segment intersect length_intersect1 = math.sqrt((abs(xR - xI1)**2) + (abs(yR - yI1)**2)) length_intersect2 = math.sqrt((abs(xR - xI2)**2) + (abs(yR - yI2)**2)) if debug >= 4: print(" length_intersect1 = " + str(length_intersect1)) print(" length_intersect2 = " + str(length_intersect2)) # Récupération de la valeur de distance entre la route et le point d'intersect le plus proche (+ ajout dans la liste length_list) length = min(length_intersect1, length_intersect2) length_list.append(length) if debug >= 4: print(" length = " + str(length)) # Récupération de la hauteur du bâtiment correspondant à l'intersect (+ ajout dans la liste haut_bati_list) query_haut_bati = "SELECT haut_bati FROM ara_temp2_perp WHERE id_intersect = '%s';" % ( id_intersect) cursor.execute(query_haut_bati) haut_bati = cursor.fetchone() haut_bati = float(str(haut_bati)[10:-4]) haut_bati_list.append(haut_bati) if debug >= 4: print(" haut_bati = " + str(haut_bati)) print("\n") # Pour un segment perpendiculaire donné, récupération de la distance minimale entre la route et les intersect avec le bâti width = min(length_list) if debug >= 4: print(" width = " + str(width)) # Pour un segment perpendiculaire donné, récupération de la hauteur du bâtiment correspondant au segment intersect le plus proche de la route height_position = length_list.index(width) height = haut_bati_list[height_position] if debug >= 4: print(" height = " + str(height)) print("\n") # MAJ des variables demi-largeurs de rue et hauteur du 1er bâtiment intersecté suivant le côté de la perpendiculaire par rapport à la route if num_seg == 1: w1 = width h1 = height elif num_seg == 2: w2 = width h2 = height # Construction de la requête de création du point route pour le segment route donné query_pt_route += " ('%s', %s, %s, %s, %s, %s, %s, 'POINT(%s %s)'),\n" % ( str(id_seg), xR, yR, w1, h1, w2, h2, xR, yR) treat_seg += 1 # Fin de la construction de la requête de création des points route, avec infos de demi-largeurs de rue et hauteurs des bâtiments query_pt_route = query_pt_route[:-2] + ";\n" # Transformer la virgule de la dernière ligne SQL en point-virgule (pour terminer la requête) query_pt_route += "ALTER TABLE ara_asp_ratio_by_seg ALTER COLUMN geom TYPE geometry(POINT,%s) USING ST_SetSRID(geom,%s);\n" % ( epsg, epsg) # Mise à jour du système de coordonnées query_pt_route += "CREATE INDEX IF NOT EXISTS asp_ratio_by_seg_geom_gist ON ara_asp_ratio_by_seg USING GIST (geom);\n" if debug >= 2: print(query_pt_route) executeQuery(connection, query_pt_route) ########################################################### ### Calcul de l'indicateur et export de la table finale ### ########################################################### print(bold + cyan + "Calculs finaux de l'indicateur de rapport d'aspect :" + endC) timeLine(path_time_log, " Calculs finaux de l'indicateur de rapport d'aspect : ") # Requête de calcul d'un rapport d'aspect par segment route query_asp_ratio_by_seg = """ ALTER TABLE ara_asp_ratio_by_seg ADD COLUMN asp_ratio float; UPDATE ara_asp_ratio_by_seg SET asp_ratio = 0; UPDATE ara_asp_ratio_by_seg SET asp_ratio = ((height1 + height2) / 2) / (width1 + width2) WHERE height1 <> 0 AND height2 <> 0 AND width1 <> 0 AND width2 <> 0; """ if debug >= 2: print(query_asp_ratio_by_seg) executeQuery(connection, query_asp_ratio_by_seg) # Requête de bufferisation du fichier maillage query_buffer = """ DROP TABLE IF EXISTS ara_buffer; CREATE TABLE ara_buffer AS SELECT ID as ID, ST_Buffer(geom, %s) as geom FROM %s; CREATE INDEX IF NOT EXISTS buffer_geom_gist ON ara_buffer USING GIST (geom); """ % (buffer_size, table_name_maille) if debug >= 2: print(query_buffer) executeQuery(connection, query_buffer) # Requête de calcul d'un rapport d'aspect par maille (via un intersect sur le maillage bufferisé) query_asp_ratio_temp1 = """ DROP TABLE IF EXISTS ara_asp_ratio_temp1; CREATE TABLE ara_asp_ratio_temp1 AS SELECT m.ID as ID, avg(r.asp_ratio) as asp_ratio, m.geom as geom FROM %s as m, ara_buffer as b, ara_asp_ratio_by_seg as r WHERE ST_Intersects(b.geom, r.geom) AND m.ID = b.ID AND r.asp_ratio > 0 GROUP BY m.ID, m.geom; CREATE INDEX IF NOT EXISTS asp_ratio_temp1_geom_gist ON ara_asp_ratio_temp1 USING GIST (geom); """ % (table_name_maille) if debug >= 2: print(query_asp_ratio_temp1) executeQuery(connection, query_asp_ratio_temp1) # Rapport d'aspect pour les mailles n'intersectant pas de points-route avec un rapport d'aspect query_asp_ratio_temp2 = """ DROP TABLE IF EXISTS ara_asp_ratio_temp2; CREATE TABLE ara_asp_ratio_temp2 AS SELECT DISTINCT ID as ID, geom as geom FROM %s WHERE ID NOT IN (SELECT DISTINCT ID FROM ara_asp_ratio_temp1); ALTER TABLE ara_asp_ratio_temp2 ADD COLUMN asp_ratio float; UPDATE ara_asp_ratio_temp2 SET asp_ratio = 0; CREATE INDEX IF NOT EXISTS asp_ratio_temp2_geom_gist ON ara_asp_ratio_temp2 USING GIST (geom); """ % table_name_maille if debug >= 1: print(query_asp_ratio_temp2) executeQuery(connection, query_asp_ratio_temp2) # Fusion des 2 tables précédentes pour retrouver l'ensemble des mailles de départ query_asp_ratio = """ DROP TABLE IF EXISTS ara_asp_ratio; CREATE TABLE ara_asp_ratio AS SELECT ID, asp_ratio, geom FROM ara_asp_ratio_temp1 UNION SELECT ID, asp_ratio, geom FROM ara_asp_ratio_temp2; ALTER TABLE ara_asp_ratio ALTER COLUMN ID TYPE INTEGER; """ if debug >= 2: print(query_asp_ratio) executeQuery(connection, query_asp_ratio) closeConnection(connection) exportVectorByOgr2ogr(database_postgis, grid_output, 'ara_asp_ratio', user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=str(port_number), schema_name=schema_postgis, format_type=format_vector) ########################################## ### Nettoyage des fichiers temporaires ### ########################################## if not save_results_intermediate: if os.path.exists(temp_path): shutil.rmtree(temp_path) # ~ dropDatabase(database_postgis) # Conflits avec autres indicateurs (Height of Roughness Elements / Terrain Roughness Class) else: print(bold + magenta + "Le calcul de Aspect Ratio a déjà eu lieu." + endC) print(bold + yellow + "Fin du calcul de l'indicateur Aspect Ratio." + endC + "\n") timeLine(path_time_log, "Fin du calcul de l'indicateur Aspect Ratio : ") return
def statisticsVectorRaster(image_input, vector_input, vector_output, band_number, enable_stats_all_count, enable_stats_columns_str, enable_stats_columns_real, col_to_delete_list, col_to_add_list, class_label_dico, path_time_log, clean_small_polygons=False, format_vector='ESRI Shapefile', save_results_intermediate=False, overwrite=True): # INITIALISATION if debug >= 3: print(cyan + "statisticsVectorRaster() : " + endC + "image_input : " + str(image_input) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "vector_input : " + str(vector_input) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "vector_output : " + str(vector_output) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "band_number : " + str(band_number) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "enable_stats_all_count : " + str(enable_stats_all_count) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "enable_stats_columns_str : " + str(enable_stats_columns_str) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "enable_stats_columns_real : " + str(enable_stats_columns_real) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "col_to_delete_list : " + str(col_to_delete_list) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "col_to_add_list : " + str(col_to_add_list) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "class_label_dico : " + str(class_label_dico) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "clean_small_polygons : " + str(clean_small_polygons) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "path_time_log : " + str(path_time_log) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "format_vector : " + str(format_vector) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "save_results_intermediate : " + str(save_results_intermediate) + endC) print(cyan + "statisticsVectorRaster() : " + endC + "overwrite : " + str(overwrite) + endC) # Constantes PREFIX_AREA_COLUMN = "S_" # Mise à jour du Log starting_event = "statisticsVectorRaster() : Compute statistic crossing starting : " timeLine(path_time_log, starting_event) # creation du fichier vecteur de sortie if vector_output == "": vector_output = vector_input # Précisé uniquement pour l'affichage else: # Copy vector_output copyVectorFile(vector_input, vector_output, format_vector) # Vérifications image_xmin, image_xmax, image_ymin, image_ymax = getEmpriseImage( image_input) vector_xmin, vector_xmax, vector_ymin, vector_ymax = getEmpriseFile( vector_output, format_vector) extension_vector = os.path.splitext(vector_output)[1] if round(vector_xmin, 4) < round(image_xmin, 4) or round( vector_xmax, 4) > round(image_xmax, 4) or round( vector_ymin, 4) < round(image_ymin, 4) or round( vector_ymax, 4) > round(image_ymax, 4): print(cyan + "statisticsVectorRaster() : " + bold + red + "image_xmin, image_xmax, image_ymin, image_ymax" + endC, image_xmin, image_xmax, image_ymin, image_ymax, file=sys.stderr) print(cyan + "statisticsVectorRaster() : " + bold + red + "vector_xmin, vector_xmax, vector_ymin, vector_ymax" + endC, vector_xmin, vector_xmax, vector_ymin, vector_ymax, file=sys.stderr) raise NameError( cyan + "statisticsVectorRaster() : " + bold + red + "The extend of the vector file (%s) is greater than the image file (%s)" % (vector_output, image_input) + endC) pixel_size = getPixelSizeImage(image_input) # Suppression des très petits polygones qui introduisent des valeurs NaN if clean_small_polygons: min_size_area = pixel_size * 2 vector_temp = os.path.splitext( vector_output)[0] + "_temp" + extension_vector cleanMiniAreaPolygons(vector_output, vector_temp, min_size_area, '', format_vector) removeVectorFile(vector_output, format_vector) renameVectorFile(vector_temp, vector_output) # Récuperation du driver pour le format shape driver = ogr.GetDriverByName(format_vector) # Ouverture du fichier shape en lecture-écriture data_source = driver.Open(vector_output, 1) # 0 means read-only - 1 means writeable. if data_source is None: print(cyan + "statisticsVectorRaster() : " + bold + red + "Impossible d'ouvrir le fichier shape : " + vector_output + endC, file=sys.stderr) sys.exit(1) # exit with an error code # Récupération du vecteur layer = data_source.GetLayer( 0) # Recuperation de la couche (une couche contient les polygones) layer_definition = layer.GetLayerDefn( ) # GetLayerDefn => returns the field names of the user defined (created) fields # ETAPE 1/4 : CREATION AUTOMATIQUE DU DICO DE VALEUR SI IL N'EXISTE PAS if enable_stats_all_count and class_label_dico == {}: image_values_list = identifyPixelValues(image_input) # Pour toutes les valeurs for id_value in image_values_list: class_label_dico[id_value] = str(id_value) # Suppression de la valeur no date à 0 if 0 in class_label_dico: del class_label_dico[0] if debug >= 2: print(class_label_dico) # ETAPE 2/4 : CREATION DES COLONNES DANS LE FICHIER SHAPE if debug >= 2: print( cyan + "statisticsVectorRaster() : " + bold + green + "ETAPE 1/3 : DEBUT DE LA CREATION DES COLONNES DANS LE FICHIER VECTEUR %s" % (vector_output) + endC) # En entrée : # col_to_add_list = [UniqueID, majority/DateMaj/SrcMaj, minority, min, max, mean, median, sum, std, unique, range, all, count, all_S, count_S] - all traduisant le class_label_dico en autant de colonnes # Sous_listes de col_to_add_list à identifier pour des facilités de manipulations ultérieures: # col_to_add_inter01_list = [majority/DateMaj/SrcMaj, minority, min, max, mean, median, sum, std, unique, range] # col_to_add_inter02_list = [majority, minority, min, max, mean, median, sum, std, unique, range, all, count, all_S, count_S] # Construction des listes intermédiaires col_to_add_inter01_list = [] # Valeurs à injecter dans des colonnes - Format String if enable_stats_columns_str: stats_columns_str_list = ['majority', 'minority'] for e in stats_columns_str_list: col_to_add_list.append(e) # Valeurs à injecter dans des colonnes - Format Nbr if enable_stats_columns_real: stats_columns_real_list = [ 'min', 'max', 'mean', 'median', 'sum', 'std', 'unique', 'range' ] for e in stats_columns_real_list: col_to_add_list.append(e) # Valeurs à injecter dans des colonnes - Format Nbr if enable_stats_all_count: stats_all_count_list = ['all', 'count'] for e in stats_all_count_list: col_to_add_list.append(e) # Valeurs à injecter dans des colonnes - si class_label_dico est non vide if class_label_dico != {}: stats_all_count_list = ['all', 'count'] for e in stats_all_count_list: if not e in col_to_add_list: col_to_add_list.append(e) # Ajout colonne par colonne if "majority" in col_to_add_list: col_to_add_inter01_list.append("majority") if "DateMaj" in col_to_add_list: col_to_add_inter01_list.append("DateMaj") if "SrcMaj" in col_to_add_list: col_to_add_inter01_list.append("SrcMaj") if "minority" in col_to_add_list: col_to_add_inter01_list.append("minority") if "min" in col_to_add_list: col_to_add_inter01_list.append("min") if "max" in col_to_add_list: col_to_add_inter01_list.append("max") if "mean" in col_to_add_list: col_to_add_inter01_list.append("mean") if "median" in col_to_add_list: col_to_add_inter01_list.append("median") if "sum" in col_to_add_list: col_to_add_inter01_list.append("sum") if "std" in col_to_add_list: col_to_add_inter01_list.append("std") if "unique" in col_to_add_list: col_to_add_inter01_list.append("unique") if "range" in col_to_add_list: col_to_add_inter01_list.append("range") # Copy de col_to_add_inter01_list dans col_to_add_inter02_list col_to_add_inter02_list = list(col_to_add_inter01_list) if "all" in col_to_add_list: col_to_add_inter02_list.append("all") if "count" in col_to_add_list: col_to_add_inter02_list.append("count") if "all_S" in col_to_add_list: col_to_add_inter02_list.append("all_S") if "count_S" in col_to_add_list: col_to_add_inter02_list.append("count_S") if "DateMaj" in col_to_add_inter02_list: col_to_add_inter02_list.remove("DateMaj") col_to_add_inter02_list.insert(0, "majority") if "SrcMaj" in col_to_add_inter02_list: col_to_add_inter02_list.remove("SrcMaj") col_to_add_inter02_list.insert(0, "majority") # Valeurs à injecter dans des colonnes - Format Nbr if enable_stats_all_count: stats_all_count_list = ['all_S', 'count_S'] for e in stats_all_count_list: col_to_add_list.append(e) # Creation de la colonne de l'identifiant unique if ("UniqueID" in col_to_add_list) or ("uniqueID" in col_to_add_list) or ( "ID" in col_to_add_list): field_defn = ogr.FieldDefn( "ID", ogr.OFTInteger ) # Création du nom du champ dans l'objet stat_classif_field_defn layer.CreateField(field_defn) if debug >= 3: print(cyan + "statisticsVectorRaster() : " + endC + "Creation de la colonne : ID") # Creation des colonnes de col_to_add_inter01_list ([majority/DateMaj/SrcMaj, minority, min, max, mean, median, sum, std, unique, range]) for col in col_to_add_list: if layer_definition.GetFieldIndex( col ) == -1: # Vérification de l'existence de la colonne col (retour = -1 : elle n'existe pas) if col == 'majority' or col == 'DateMaj' or col == 'SrcMaj' or col == 'minority': # Identification de toutes les colonnes remplies en string stat_classif_field_defn = ogr.FieldDefn( col, ogr.OFTString ) # Création du champ (string) dans l'objet stat_classif_field_defn layer.CreateField(stat_classif_field_defn) elif col == 'mean' or col == 'median' or col == 'sum' or col == 'std' or col == 'unique' or col == 'range' or col == 'max' or col == 'min': stat_classif_field_defn = ogr.FieldDefn( col, ogr.OFTReal ) # Création du champ (real) dans l'objet stat_classif_field_defn # Définition de la largeur du champ stat_classif_field_defn.SetWidth(20) # Définition de la précision du champ valeur flottante stat_classif_field_defn.SetPrecision(2) layer.CreateField(stat_classif_field_defn) if debug >= 3: print(cyan + "statisticsVectorRaster() : " + endC + "Creation de la colonne : " + str(col)) # Creation des colonnes reliées au dictionnaire if ('all' in col_to_add_list) or ('count' in col_to_add_list) or ( 'all_S' in col_to_add_list) or ('count_S' in col_to_add_list): for col in class_label_dico: # Gestion du nom de la colonne correspondant à la classe name_col = class_label_dico[col] if len(name_col) > 10: name_col = name_col[:10] print( cyan + "statisticsVectorRaster() : " + bold + yellow + "Nom de la colonne trop long. Il sera tronque a 10 caracteres en cas d'utilisation: " + endC + name_col) # Gestion du nom de la colonne correspondant à la surface de la classe name_col_area = PREFIX_AREA_COLUMN + name_col if len(name_col_area) > 10: name_col_area = name_col_area[:10] if debug >= 3: print( cyan + "statisticsVectorRaster() : " + bold + yellow + "Nom de la colonne trop long. Il sera tronque a 10 caracteres en cas d'utilisation: " + endC + name_col_area) # Ajout des colonnes de % de répartition des éléments du raster if ('all' in col_to_add_list) or ('count' in col_to_add_list): if layer_definition.GetFieldIndex( name_col ) == -1: # Vérification de l'existence de la colonne name_col (retour = -1 : elle n'existe pas) stat_classif_field_defn = ogr.FieldDefn( name_col, ogr.OFTReal ) # Création du champ (real) dans l'objet stat_classif_field_defn # Définition de la largeur du champ stat_classif_field_defn.SetWidth(20) # Définition de la précision du champ valeur flottante stat_classif_field_defn.SetPrecision(2) if debug >= 3: print(cyan + "statisticsVectorRaster() : " + endC + "Creation de la colonne : " + str(name_col)) layer.CreateField( stat_classif_field_defn) # Ajout du champ # Ajout des colonnes de surface des éléments du raster if ('all_S' in col_to_add_list) or ('count_S' in col_to_add_list): if layer_definition.GetFieldIndex( name_col_area ) == -1: # Vérification de l'existence de la colonne name_col_area (retour = -1 : elle n'existe pas) stat_classif_field_defn = ogr.FieldDefn( name_col_area, ogr.OFTReal ) # Création du nom du champ dans l'objet stat_classif_field_defn # Définition de la largeur du champ stat_classif_field_defn.SetWidth(20) # Définition de la précision du champ valeur flottante stat_classif_field_defn.SetPrecision(2) if debug >= 3: print(cyan + "statisticsVectorRaster() : " + endC + "Creation de la colonne : " + str(name_col_area)) layer.CreateField( stat_classif_field_defn) # Ajout du champ if debug >= 2: print( cyan + "statisticsVectorRaster() : " + bold + green + "ETAPE 1/3 : FIN DE LA CREATION DES COLONNES DANS LE FICHIER VECTEUR %s" % (vector_output) + endC) # ETAPE 3/4 : REMPLISSAGE DES COLONNES DU VECTEUR if debug >= 2: print(cyan + "statisticsVectorRaster() : " + bold + green + "ETAPE 2/3 : DEBUT DU REMPLISSAGE DES COLONNES DU VECTEUR " + endC) # Calcul des statistiques col_to_add_inter02_list = [majority, minority, min, max, mean, median, sum, std, unique, range, all, count, all_S, count_S] de croisement images_raster / vecteur # Utilisation de la librairie rasterstat if debug >= 3: print(cyan + "statisticsVectorRaster() : " + bold + green + "Calcul des statistiques " + endC + "Stats : %s - Vecteur : %s - Raster : %s" % (col_to_add_inter02_list, vector_output, image_input) + endC) stats_info_list = raster_stats(vector_output, image_input, band_num=band_number, stats=col_to_add_inter02_list) # Decompte du nombre de polygones num_features = layer.GetFeatureCount() if debug >= 3: print(cyan + "statisticsVectorRaster() : " + bold + green + "Remplissage des colonnes polygone par polygone " + endC) if debug >= 3: print(cyan + "statisticsVectorRaster() : " + endC + "Nombre total de polygones : " + str(num_features)) polygone_count = 0 for polygone_stats in stats_info_list: # Pour chaque polygone représenté dans stats_info_list - et il y a autant de polygone que dans le fichier vecteur # Extraction de feature feature = layer.GetFeature(polygone_stats['__fid__']) polygone_count = polygone_count + 1 if debug >= 3 and polygone_count % 10000 == 0: print(cyan + "statisticsVectorRaster() : " + endC + "Avancement : %s polygones traites sur %s" % (polygone_count, num_features)) if debug >= 5: print( cyan + "statisticsVectorRaster() : " + endC + "Traitement du polygone : ", stats_info_list.index(polygone_stats) + 1) # Remplissage de l'identifiant unique if ("UniqueID" in col_to_add_list) or ( "uniqueID" in col_to_add_list) or ("ID" in col_to_add_list): feature.SetField('ID', int(stats_info_list.index(polygone_stats))) # Initialisation à 0 des colonnes contenant le % de répartition de la classe - Verifier ce qu'il se passe si le nom dépasse 10 caracteres if ('all' in col_to_add_list) or ('count' in col_to_add_list): for element in class_label_dico: name_col = class_label_dico[element] if len(name_col) > 10: name_col = name_col[:10] feature.SetField(name_col, 0) # Initialisation à 0 des colonnes contenant la surface correspondant à la classe - Verifier ce qu'il se passe si le nom dépasse 10 caracteres if ('all_S' in col_to_add_list) or ('count_S' in col_to_add_list): for element in class_label_dico: name_col = class_label_dico[element] name_col_area = PREFIX_AREA_COLUMN + name_col if len(name_col_area) > 10: name_col_area = name_col_area[:10] feature.SetField(name_col_area, 0) # Remplissage des colonnes contenant le % de répartition et la surface des classes if ('all' in col_to_add_list) or ('count' in col_to_add_list) or ( 'all_S' in col_to_add_list) or ('count_S' in col_to_add_list): # 'all' est une liste des couples : (Valeur_du_pixel_sur_le_raster, Nbr_pixel_ayant_cette_valeur) pour le polygone observe. # Ex : [(0,183),(803,45),(801,4)] : dans le polygone, il y a 183 pixels de valeur 0, 45 pixels de valeur 803 et 4 pixels de valeur 801 majority_all = polygone_stats['all'] # Deux valeurs de pixel peuvent faire référence à une même colonne. Par exemple : les pixels à 201, 202, 203 peuvent correspondre à la BD Topo # Regroupement des éléments de majority_all allant dans la même colonne au regard de class_label_dico count_for_idx_couple = 0 # Comptage du nombre de modifications (suppression de couple) de majority_all pour adapter la valeur de l'index lors de son parcours for idx_couple in range( 1, len(majority_all) ): # Inutile d'appliquer le traitement au premier élément (idx_couple == 0) idx_couple = idx_couple - count_for_idx_couple # Prise en compte dans le parcours de majority_all des couples supprimés couple = majority_all[idx_couple] # Ex : couple = (803,45) if (couple is None) or ( couple == "" ): # en cas de bug de rasterstats (erreur geometrique du polygone par exemple) if debug >= 3: print( cyan + "statisticsVectorRaster() : " + bold + red + "Probleme detecte dans la gestion du polygone %s" % (polygone_count) + endC, file=sys.stderr) pass else: for idx_verif in range(idx_couple): # Vérification au regard des éléments présents en amont dans majority_all # Cas où le nom correspondant au label a déjà été rencontré dans majority_all # Vérification que les pixels de l'image sont réferncés dans le dico if couple[0] in class_label_dico: if class_label_dico[couple[0]] == class_label_dico[ majority_all[idx_verif][0]]: majority_all[idx_verif] = ( majority_all[idx_verif][0], majority_all[idx_verif][1] + couple[1] ) # Ajout du nombre de pixels correspondant dans le couple précédent majority_all.remove( couple ) # Supression du couple présentant le "doublon" count_for_idx_couple = count_for_idx_couple + 1 # Mise à jour du décompte de modifications break else: raise NameError( cyan + "statisticsVectorRaster() : " + bold + red + "The image file (%s) contain pixel value '%d' not identified into class_label_dico" % (image_input, couple[0]) + endC) # Intégration des valeurs de majority all dans les colonnes for couple_value_count in majority_all: # Parcours de majority_all. Ex : couple_value_count = (803,45) if (couple_value_count is None) or ( couple_value_count == "" ): # en cas de bug de rasterstats (erreur geometrique du polygone par exemple) if debug >= 3: print( cyan + "statisticsVectorRaster() : " + bold + red + "Probleme detecte dans la gestion du polygone %s" % (polygone_count) + endC, file=sys.stderr) pass else: nb_pixel_total = polygone_stats[ 'count'] # Nbr de pixels du polygone pixel_value = couple_value_count[0] # Valeur du pixel value_count = couple_value_count[ 1] # Nbr de pixels ayant cette valeur name_col = class_label_dico[ pixel_value] # Transformation de la valeur du pixel en "signification" au regard du dictionnaire. Ex : BD Topo ou 2011 name_col_area = PREFIX_AREA_COLUMN + name_col # Identification du nom de la colonne en surfaces if len(name_col) > 10: name_col = name_col[:10] if len(name_col_area) > 10: name_col_area = name_col_area[:10] value_area = pixel_size * value_count # Calcul de la surface du polygone correspondant à la valeur du pixel if nb_pixel_total != None and nb_pixel_total != 0: percentage = ( float(value_count) / float(nb_pixel_total) ) * 100 # Conversion de la surface en pourcentages, arondi au pourcent else: if debug >= 3: print( cyan + "statisticsVectorRaster() : " + bold + red + "Probleme dans l'identification du nombre de pixels du polygone %s : le pourcentage de %s est mis à 0" % (polygone_count, name_col) + endC, file=sys.stderr) percentage = 0.0 if ('all' in col_to_add_list) or ('count' in col_to_add_list): feature.SetField( name_col, percentage ) # Injection du pourcentage dans la colonne correpondante if ('all_S' in col_to_add_list) or ('count_S' in col_to_add_list): feature.SetField( name_col_area, value_area ) # Injection de la surface dans la colonne correpondante else: pass # Remplissage des colonnes statistiques demandées ( col_to_add_inter01_list = [majority/DateMaj/SrcMaj, minority, min, max, mean, median, sum, std, unique, range] ) for stats in col_to_add_inter01_list: if stats == 'DateMaj' or stats == 'SrcMaj': # Cas particulier de 'DateMaj' et 'SrcMaj' : le nom de la colonne est DateMaj ou SrcMaj, mais la statistique utilisée est identifiée par majority name_col = stats # Nom de la colonne. Ex : 'DateMaj' value_statis = polygone_stats[ 'majority'] # Valeur majoritaire. Ex : '203' if value_statis == None: value_statis_class = 'nan' else: value_statis_class = class_label_dico[ value_statis] # Transformation de la valeur au regard du dictionnaire. Ex : '2011' feature.SetField(name_col, value_statis_class) # Ajout dans la colonne elif (stats is None) or (stats == "") or ( polygone_stats[stats] is None) or (polygone_stats[stats]) == "" or ( polygone_stats[stats]) == 'nan': # En cas de bug de rasterstats (erreur geometrique du polygone par exemple) pass else: name_col = stats # Nom de la colonne. Ex : 'majority', 'max' value_statis = polygone_stats[ stats] # Valeur à associer à la colonne, par exemple '2011' if ( name_col == 'majority' or name_col == 'minority' ) and class_label_dico != []: # Cas où la colonne fait référence à une valeur du dictionnaire value_statis_class = class_label_dico[value_statis] else: value_statis_class = value_statis feature.SetField(name_col, value_statis_class) layer.SetFeature(feature) feature.Destroy() if debug >= 2: print(cyan + "statisticsVectorRaster() : " + bold + green + "ETAPE 2/3 : FIN DU REMPLISSAGE DES COLONNES DU VECTEUR %s" % (vector_output) + endC) # ETAPE 4/4 : SUPRESSION DES COLONNES NON SOUHAITEES if col_to_delete_list != []: if debug >= 2: print(cyan + "statisticsVectorRaster() : " + bold + green + "ETAPE 3/3 : DEBUT DES SUPPRESSIONS DES COLONNES %s" % (col_to_delete_list) + endC) for col_to_delete in col_to_delete_list: if layer_definition.GetFieldIndex( col_to_delete ) != -1: # Vérification de l'existence de la colonne col (retour = -1 : elle n'existe pas) layer.DeleteField(layer_definition.GetFieldIndex( col_to_delete)) # Suppression de la colonne if debug >= 3: print(cyan + "statisticsVectorRaster() : " + endC + "Suppression de %s" % (col_to_delete) + endC) if debug >= 2: print(cyan + "statisticsVectorRaster() : " + bold + green + "ETAPE 3/3 : FIN DE LA SUPPRESSION DES COLONNES" + endC) else: print(cyan + "statisticsVectorRaster() : " + bold + yellow + "ETAPE 3/3 : AUCUNE SUPPRESSION DE COLONNE DEMANDEE" + endC) # Fermeture du fichier shape layer.SyncToDisk() layer = None data_source.Destroy() # Mise à jour du Log ending_event = "statisticsVectorRaster() : Compute statistic crossing ending : " timeLine(path_time_log, ending_event) return
def vectorsListToOcs(input_text, output_raster, footprint_vector, reference_raster, codage_raster='uint8', epsg=2154, no_data_value=0, format_raster='GTiff', format_vector='ESRI Shapefile', extension_raster='.tif', extension_vector='.shp', path_time_log='', save_results_intermediate=False, overwrite=True): if debug >= 3: print( '\n' + bold + green + "OCS raster à partir d'une liste de vecteurs - Variables dans la fonction :" + endC) print(cyan + " vectorsListToOcs() : " + endC + "input_text : " + str(input_text) + endC) print(cyan + " vectorsListToOcs() : " + endC + "output_raster : " + str(output_raster) + endC) print(cyan + " vectorsListToOcs() : " + endC + "footprint_vector : " + str(footprint_vector) + endC) print(cyan + " vectorsListToOcs() : " + endC + "reference_raster : " + str(reference_raster) + endC) print(cyan + " vectorsListToOcs() : " + endC + "codage_raster : " + str(codage_raster) + endC) print(cyan + " vectorsListToOcs() : " + endC + "epsg : " + str(epsg) + endC) print(cyan + " vectorsListToOcs() : " + endC + "no_data_value : " + str(no_data_value) + endC) print(cyan + " vectorsListToOcs() : " + endC + "format_raster : " + str(format_raster) + endC) print(cyan + " vectorsListToOcs() : " + endC + "format_vector : " + str(format_vector) + endC) print(cyan + " vectorsListToOcs() : " + endC + "extension_raster : " + str(extension_raster) + endC) print(cyan + " vectorsListToOcs() : " + endC + "extension_vector : " + str(extension_vector) + endC) print(cyan + " vectorsListToOcs() : " + endC + "path_time_log : " + str(path_time_log) + endC) print(cyan + " vectorsListToOcs() : " + endC + "save_results_intermediate : " + str(save_results_intermediate) + endC) print(cyan + " vectorsListToOcs() : " + endC + "overwrite : " + str(overwrite) + endC + '\n') # Définition des constantes SUFFIX_TEMP = '_temp' SUFFIX_CUT = '_cut' SUFFIX_FILTER = '_filter' SUFFIX_BUFFER = '_buffer' TEXT_SEPARATOR = ':' # Mise à jour du log starting_event = "vectorsListToOcs() : Début du traitement : " timeLine(path_time_log, starting_event) print(cyan + "vectorsListToOcs() : " + bold + green + "DEBUT DES TRAITEMENTS" + endC + '\n') # Définition des variables 'basename' output_raster_basename = os.path.basename( os.path.splitext(output_raster)[0]) output_raster_dirname = os.path.dirname(output_raster) # Définition des variables temp temp_directory = output_raster_dirname + os.sep + output_raster_basename + SUFFIX_TEMP temp_raster = temp_directory + os.sep + output_raster_basename + SUFFIX_TEMP + extension_raster # Nettoyage des traitements précédents if overwrite: if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + "Nettoyage des traitements précédents." + '\n') removeFile(output_raster) cleanTempData(temp_directory) else: if os.path.exists(output_raster): print(cyan + "vectorsListToOcs() : " + bold + yellow + "Le fichier de sortie existe déjà et ne sera pas regénéré." + endC) raise if not os.path.exixts(temp_directory): os.makedirs(temp_directory) pass # Test de l'emprise des fichiers vecteur d'emprise et raster de référence (le raster doit être de même taille ou plus grand que le vecteur) xmin_fpt, xmax_fpt, ymin_fpt, ymax_fpt = getEmpriseFile( footprint_vector, format_vector=format_vector) xmin_ref, xmax_ref, ymin_ref, ymax_ref = getEmpriseImage(reference_raster) if round(xmin_fpt, 4) < round(xmin_ref, 4) or round(xmax_fpt, 4) > round( xmax_ref, 4) or round(ymin_fpt, 4) < round(ymin_ref, 4) or round( ymax_fpt, 4) > round(ymax_ref, 4): print(cyan + "vectorsListToOcs() : " + bold + red + "xmin_fpt, xmax_fpt, ymin_fpt, ymax_fpt" + endC, xmin_fpt, xmax_fpt, ymin_fpt, ymax_fpt, file=sys.stderr) print(cyan + "vectorsListToOcs() : " + bold + red + "xmin_ref, xmax_ref, ymin_ref, ymax_ref" + endC, xmin_ref, xmax_ref, ymin_ref, ymax_ref, file=sys.stderr) raise NameError( cyan + "vectorsListToOcs() : " + bold + red + "The extend of the footprint vector (%s) is greater than the reference raster (%s)." % (footprint_vector, reference_raster) + endC) # Récupération des traitements à faire dans le fichier texte d'entrée text_list = readTextFileBySeparator(input_text, TEXT_SEPARATOR) #################################################################### print(cyan + "vectorsListToOcs() : " + bold + green + "Début de la génération de l'OCS raster à partir de vecteurs." + endC + '\n') # Boucle sur les traitements à réaliser for text in text_list: idx = text_list.index(text) + 1 class_label = int(text[0]) vector_file = text[1] if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + bold + "Génération %s/%s : " % (idx, len(text_list)) + endC + "traitement du fichier %s (label %s)." % (vector_file, str(class_label)) + '\n') # Gestion des noms des fichiers temporaires vector_file_basename = os.path.basename( os.path.splitext(vector_file)[0]) vector_file_cut = temp_directory + os.sep + vector_file_basename + SUFFIX_CUT + extension_vector vector_file_filter = temp_directory + os.sep + vector_file_basename + SUFFIX_FILTER + extension_vector vector_file_buffer = temp_directory + os.sep + vector_file_basename + SUFFIX_BUFFER + extension_vector vector_file_raster = temp_directory + os.sep + vector_file_basename + extension_raster # Gestion des variables de traitement (tampon et filtrage SQL) try: buffer_len = float(text[2]) except ValueError: buffer_len = text[2] except Exception: buffer_len = '' try: sql_filter = text[3] except Exception: sql_filter = '' # Découpage à l'emprise de la zone d'étude if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + "Découpage à l'emprise de la zone d'étude." + '\n') cutVectorAll(footprint_vector, vector_file, vector_file_cut, overwrite=overwrite, format_vector=format_vector) # Filtrage SQL (facultatif) if sql_filter != '': if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + "Application du filtrage SQL : %s." % sql_filter + '\n') attr_names_list = getAttributeNameList(vector_file_cut, format_vector=format_vector) column = "'" for attr_name in attr_names_list: column += attr_name + ", " column = column[:-2] column += "'" filterSelectDataVector(vector_file_cut, vector_file_filter, column, sql_filter, overwrite=overwrite, format_vector=format_vector) else: vector_file_filter = vector_file_cut # Application d'un tampon (facultatif) if buffer_len != '' and buffer_len != 0: if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + "Application d'un buffer : %s." % buffer_len + '\n') if type(buffer_len) is float: bufferVector(vector_file_filter, vector_file_buffer, buffer_len, col_name_buf='', fact_buf=1.0, quadsecs=10, format_vector=format_vector) else: bufferVector(vector_file_filter, vector_file_buffer, 0, col_name_buf=buffer_len, fact_buf=1.0, quadsecs=10, format_vector=format_vector) else: vector_file_buffer = vector_file_filter # Rastérisation du vecteur préparé if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + "Rastérisation du vecteur préparé." + '\n') rasterizeBinaryVector(vector_file_buffer, reference_raster, vector_file_raster, label=class_label, codage=codage_raster) # Ajout de l'information dans le raster de sortie if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + "Ajout de l'information dans le raster de sortie." + '\n') if idx == 1: shutil.copy(vector_file_raster, output_raster) else: removeFile(temp_raster) shutil.copy(output_raster, temp_raster) removeFile(output_raster) expression = "im1b1!=%s ? im1b1 : im2b1" % no_data_value rasterCalculator([temp_raster, vector_file_raster], output_raster, expression, codage=codage_raster) print(cyan + "vectorsListToOcs() : " + bold + green + "Fin de la génération de l'OCS raster à partir de vecteurs." + endC + '\n') #################################################################### # Suppression des fichiers temporaires if not save_results_intermediate: if debug >= 3: print(cyan + "vectorsListToOcs() : " + endC + "Suppression des fichiers temporaires." + '\n') deleteDir(temp_directory) print(cyan + "vectorsListToOcs() : " + bold + green + "FIN DES TRAITEMENTS" + endC + '\n') # Mise à jour du log ending_event = "vectorsListToOcs() : Fin du traitement : " timeLine(path_time_log, ending_event) return 0
def processTDCfilesSmoothAndFusion(coastline_vectors_input_list, vector_rocky_input, vector_all_output, vector_withrocky_output, generalize_param_method, generalize_param_threshold, name_column_fusion, path_time_log, epsg=2154, format_vector='ESRI Shapefile', extension_vector='.shp', save_results_intermediate=False, overwrite=True): # Mise à jour du Log starting_event = "processTDCfilesSmoothAndFusion() : Create final coastline starting : " timeLine(path_time_log,starting_event) print(endC) print(bold + green + "## START : POST TRAITEMENT TDC" + endC) print(endC) if debug >= 2: print(bold + green + "processTDCfilesSmoothAndFusion() : Variables dans la fonction" + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "coastline_vectors_input_list : " + str(coastline_vectors_input_list) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "vector_rocky_input : " + str(vector_rocky_input) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "vector_all_output : " + str(vector_all_output) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "vector_withrocky_output : " + str(vector_withrocky_output) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "generalize_param_method : " + str(generalize_param_method) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "generalize_param_threshold : " + str(generalize_param_threshold) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "name_column_fusion : " + str(name_column_fusion) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "epsg : " + str(epsg) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "format_vector : " + str(format_vector) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "extension_vector : " + str(extension_vector) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "path_time_log : " + str(path_time_log) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "save_results_intermediate : " + str(save_results_intermediate) + endC) print(cyan + "processTDCfilesSmoothAndFusion() : " + endC + "overwrite : " + str(overwrite) + endC) SUFFIX_SMOOTH = "_smooth" SUFFIX_TMP = "_tmp" SUFFIX_SMOOTH = "_smooth" SUFFIX_FUSION = "_fusion" repertory_output = os.path.dirname(vector_all_output) file_name = os.path.splitext(os.path.basename(vector_all_output))[0] vector_fusion = repertory_output + os.sep + file_name + SUFFIX_FUSION + extension_vector repertory_temp = repertory_output + os.sep + file_name + SUFFIX_TMP if not os.path.exists(repertory_temp): os.makedirs(repertory_temp) # Vérification de l'existence du vecteur de sortie check = os.path.isfile(vector_all_output) # Si oui et si la vérification est activée, passage à l'étape suivante if check and not overwrite : print(cyan + "processTDCfilesSmoothAndFusion() : " + bold + green + "Vector general coastline already existe : " + str(vector_all_output) + "." + endC) # Si non ou si la vérification est désactivée, application des traitements de lissage et de la fusion else: # Tentative de suppresion des fichiers try: removeVectorFile(vector_all_output) removeVectorFile(vector_withrocky_output) except Exception: # Ignore l'exception levée si le fichier n'existe pas (et ne peut donc pas être supprimé) pass # Pour tous les fichiers vecteurs d'entrée appliquer le traitement de lissage par GRASS param_generalize_dico = {"method":generalize_param_method, "threshold":generalize_param_threshold} vectors_temp_output_list = [] for input_vector in coastline_vectors_input_list : vector_name = os.path.splitext(os.path.basename(input_vector))[0] output_temp_vector = repertory_temp + os.sep + vector_name + SUFFIX_TMP + extension_vector output_smooth_vector = repertory_temp + os.sep + vector_name + SUFFIX_SMOOTH + extension_vector vectors_temp_output_list.append(output_temp_vector) xmin, xmax, ymin, ymax = getEmpriseFile(input_vector, format_vector) projection = getProjection(input_vector, format_vector) if projection is None: projection = epsg # Init GRASS if debug >= 3: print(cyan + "processTDCfilesSmoothAndFusion() : " + bold + green + "Initialisation de GRASS " + endC) initializeGrass(repertory_temp, xmin, xmax, ymin, ymax, 1, 1, projection) # Generalize GRASS if debug >= 3: print(cyan + "processTDCfilesSmoothAndFusion() : " + bold + green + "Applying smooth GRASS for vector : " + str(input_vector) + endC) smoothGeomGrass(input_vector, output_smooth_vector, param_generalize_dico, format_vector, overwrite) geometries2multigeometries(output_smooth_vector, output_temp_vector, name_column_fusion, format_vector) # Init GRASS if debug >= 3: print(cyan + "processTDCfilesSmoothAndFusion() : " + bold + green + "Cloture de GRASS " + endC) cleanGrass(repertory_temp) if debug >= 3: print(cyan + "processTDCfilesSmoothAndFusion() : " + bold + green + "Fusion de tous les vecteurs lissés : " + str(vectors_temp_output_list) + endC) # Fusion de tous les fichiers vecteurs temp fusionVectors(vectors_temp_output_list, vector_fusion, format_vector) # Suppression du champ "cat" introduit par l'application GRASS deleteFieldsVector(vector_fusion, vector_all_output, ["cat"], format_vector) # Re-met à jour le champ id avec un increment updateIndexVector(vector_all_output, "id", format_vector) # Nettoyage des zones rocheuses sur la ligne de trait de côte if vector_rocky_input != "" and vector_withrocky_output != "": if debug >= 3: print("\n" + cyan + "processTDCfilesSmoothAndFusion() : " + bold + green + "Creation d'un trait de côte generale sans les zones rocheuses : " + str(vector_withrocky_output) + endC) differenceVector(vector_rocky_input, vector_all_output, vector_withrocky_output, overwrite, format_vector) # Suppression des fichiers intermédiaires if not save_results_intermediate : if debug >= 3: print(cyan + "processTDCfilesSmoothAndFusion() : " + bold + green + "Suppression des fichiers temporaires " + endC) if os.path.exists(repertory_temp): shutil.rmtree(repertory_temp) removeVectorFile(vector_fusion) print(endC) print(bold + green + "## END : POST TRAITEMENT TDC" + endC) print(endC) # Mise à jour du Log ending_event = "processTDCfilesSmoothAndFusion() : Create final coastline ending : " timeLine(path_time_log,ending_event) return
def cutRasterImages(images_input_list, vector_cut, images_output_list, buffer_size, round_pixel_size, epsg, no_data_value, resampling_methode, z_compress, path_time_log, format_raster='GTiff', format_vector='ESRI Shapefile', extension_raster=".tif", extension_vector=".shp", save_results_intermediate=False, overwrite=True): # Mise à jour du Log starting_event = "cutRasterImages() : Cutting rasters and vector starting : " timeLine(path_time_log, starting_event) print(endC) print(bold + green + "## START : CUTTING IMAGES" + endC) print(endC) if debug >= 2: print(bold + green + "cutRasterImages() : Variables dans la fonction" + endC) print(cyan + "cutRasterImages() : " + endC + "images_input_list : " + str(images_input_list) + endC) print(cyan + "cutRasterImages() : " + endC + "vector_cut : " + str(vector_cut) + endC) print(cyan + "cutRasterImages() : " + endC + "images_output_list : " + str(images_output_list) + endC) print(cyan + "cutRasterImages() : " + endC + "buffer_size : " + str(buffer_size) + endC) print(cyan + "cutRasterImages() : " + endC + "round_pixel_size : " + str(round_pixel_size) + endC) print(cyan + "cutRasterImages() : " + endC + "epsg : " + str(epsg) + endC) print(cyan + "cutRasterImages() : " + endC + "no_data_value : " + str(no_data_value) + endC) print(cyan + "cutRasterImages() : " + endC + "resampling_methode : " + str(resampling_methode)) print(cyan + "cutRasterImages() : " + endC + "z_compress : " + str(z_compress)) print(cyan + "cutRasterImages() : " + endC + "path_time_log : " + str(path_time_log) + endC) print(cyan + "cutRasterImages() : " + endC + "format_raster : " + str(format_raster) + endC) print(cyan + "cutRasterImages() : " + endC + "format_vector : " + str(format_vector) + endC) print(cyan + "cutRasterImages() : " + endC + "extension_raster : " + str(extension_raster) + endC) print(cyan + "cutRasterImages() : " + endC + "extension_vector : " + str(extension_vector) + endC) print(cyan + "cutRasterImages() : " + endC + "save_results_intermediate : " + str(save_results_intermediate) + endC) print(cyan + "cutRasterImages() : " + endC + "overwrite : " + str(overwrite) + endC) # PREPARATION DES FICHIERS INTERMEDIAIRES BUFF_SUFFIX = "_buf" CUT_SUFFIX = "_cut" COMPRESS_SUFFIX = "_compress" EPSG_DEFAULT = 2154 if buffer_size > 0 and len( images_input_list ) > 0: # Cas le vecteur de découpe des rasteurs est bufferisé vector_buf_for_raster_cut = os.path.splitext( vector_cut)[0] + BUFF_SUFFIX + str(int(round( buffer_size, 0))) + 'm' + extension_vector if debug >= 3: print("vector_buf_for_raster_cut : " + str(vector_buf_for_raster_cut) + endC) # Test si le vecteur decoupe existe déjà et si il doit être écrasés check = os.path.isfile(vector_buf_for_raster_cut) if check and not overwrite: # Si le fichier existe deja et que overwrite n'est pas activé print(bold + yellow + "File vector cutting : " + vector_buf_for_raster_cut + " already exists and will not be created again." + endC) else: if check: try: removeVectorFile(vector_buf_for_raster_cut) except Exception: pass # si le fichier n'existe pas, il ne peut pas être supprimé : cette étape est ignorée # Création du vecteur de découpe bufferisé bufferVector(vector_cut, vector_buf_for_raster_cut, buffer_size, "", 1.0, 10, format_vector) else: # Cas le vecteur de découpe des rasteurs n'est pas bufferisé idem vecteur de découpe que les vecteurs vector_buf_for_raster_cut = vector_cut # DECOUPAGE DES RASTEURS PAR LE VECTEUR DE DECOUPE # Pour tous les fichiers raster à découpper for index_raster in range(len(images_input_list)): # Préparation des rasters de travail d'entrée et de sortie raster_input = images_input_list[index_raster] raster_output = images_output_list[index_raster] raster_output_compress = os.path.splitext( raster_output)[0] + COMPRESS_SUFFIX + extension_raster vector_cut_temp = os.path.splitext( raster_output)[0] + CUT_SUFFIX + extension_vector if debug >= 1: print("\n") print(cyan + "cutRasterImages() : " + endC + bold + green + "Découpe fichier raster : " + endC + str(raster_input) + endC) # Récuperation de l'emprise de l'image ima_xmin, ima_xmax, ima_ymin, ima_ymax = getEmpriseImage(raster_input) # Recuperation de la valeur de l'arrondi de la taille des pixels en X et Y si non définie if round_pixel_size == 0.0 and os.path.isfile(raster_input): # Identification de la tailles de pixels en x et en y pixel_size_x, pixel_size_y = getPixelWidthXYImage(raster_input) round_pixel_size = abs(pixel_size_x) else: pixel_size_x = round_pixel_size pixel_size_y = round_pixel_size # Préparation du vecteur de découpe temporaire createEmpriseShapeReduced(vector_buf_for_raster_cut, ima_xmin, ima_ymin, ima_xmax, ima_ymax, vector_cut_temp, format_vector) # Identification de l'emprise de vecteur de découpe empr_xmin, empr_xmax, empr_ymin, empr_ymax = getEmpriseFile( vector_cut_temp, format_vector) # Calculer l'emprise arrondi xmin, xmax, ymin, ymax = roundPixelEmpriseSize(pixel_size_x, pixel_size_y, empr_xmin, empr_xmax, empr_ymin, empr_ymax) # Trouver l'emprise optimale opt_xmin = xmin opt_xmax = xmax opt_ymin = ymin opt_ymax = ymax if ima_xmin > xmin: opt_xmin = ima_xmin if ima_xmax < xmax: opt_xmax = ima_xmax if ima_ymin > ymin: opt_ymin = ima_ymin if ima_ymax < ymax: opt_ymax = ima_ymax # Récuperation de la projection de l'image if epsg == 0: epsg_proj = getProjectionImage(raster_input) else: epsg_proj = epsg if epsg_proj == 0: epsg_proj = EPSG_DEFAULT if debug >= 3: print("epsg : " + str(epsg_proj) + endC) print("\n") # Test si le rasteur de sortie existe déjà et si il doit être écrasés check = os.path.isfile(raster_output) if check and not overwrite: # Si le fichier existe deja et que overwrite n'est pas activé print(bold + yellow + "File raster output : " + raster_output + " already exists and will not be created again." + endC) else: if check: try: removeFile(raster_output) except Exception: pass # si le fichier n'existe pas, il ne peut pas être supprimé : cette étape est ignorée # Commande de découpe raster command = 'gdalwarp -t_srs EPSG:' + str(epsg_proj) + ' -te ' + str( opt_xmin ) + ' ' + str(opt_ymin) + ' ' + str(opt_xmax) + ' ' + str( opt_ymax ) + ' -tap -multi -co "NUM_THREADS=ALL_CPUS" -dstnodata ' + str( no_data_value ) + ' -tr ' + str(abs(pixel_size_x)) + ' ' + str( abs(pixel_size_y) ) + ' -cutline ' + vector_cut_temp + ' -of ' + format_raster + ' ' + raster_input + ' ' + raster_output if resampling_methode != "": command += " -r " + resampling_methode if overwrite: command += ' -overwrite' if debug >= 2: print(bold + green + "Command : " + command + endC) exit_code = os.system(command) if exit_code != 0: print( cyan + "cutRasterImages() : " + bold + red + "!!! Une erreur c'est produite au cours du decoupage de l'image : " + raster_input + ". Voir message d'erreur." + endC, file=sys.stderr) raise if debug >= 2: print(cyan + "cutRasterImages() : " + bold + green + "DECOUPAGE DU RASTER %s AVEC LE VECTEUR %s" % (raster_input, vector_buf_for_raster_cut) + endC) print(command) if z_compress: # Commande de découpe raster et compression command = 'gdalwarp -t_srs EPSG:' + str( epsg_proj ) + ' -te ' + str(opt_xmin) + ' ' + str(opt_ymin) + ' ' + str( opt_xmax ) + ' ' + str( opt_ymax ) + ' -tap -multi -co "NUM_THREADS=ALL_CPUS" -dstnodata ' + str( no_data_value ) + ' -tr ' + str(abs(pixel_size_x)) + ' ' + str( abs(pixel_size_y) ) + ' -co "COMPRESS=DEFLATE" -co "PREDICTOR=2" -co "ZLEVEL=9" -cutline ' + vector_cut_temp + ' -of ' + format_raster + ' ' + raster_input + ' ' + raster_output_compress if resampling_methode != "": command += ' -r ' + resampling_methode if overwrite: command += ' -overwrite' if debug >= 2: print(bold + green + "Command : " + command + endC) exit_code = os.system(command) if exit_code != 0: print( cyan + "cutRasterImages() : " + bold + red + "!!! Une erreur c'est produite au cours du decoupage de l'image : " + raster_input + ". Voir message d'erreur." + endC, file=sys.stderr) raise if debug >= 2: print( cyan + "cutRasterImages() : " + bold + green + "DECOUPAGE ET COMPRESSION DU RASTER %s AVEC LE VECTEUR %s" % (raster_input, vector_buf_for_raster_cut) + endC) print(command) # Suppression des fichiers intermédiaires removeVectorFile(vector_cut_temp) # SUPPRESIONS FICHIERS INTERMEDIAIRES INUTILES # Suppression des fichiers intermédiaires if not save_results_intermediate and os.path.isfile( vector_buf_for_raster_cut ) and vector_buf_for_raster_cut != vector_cut: removeVectorFile(vector_buf_for_raster_cut) print(endC) print(bold + green + "## END : CUTTING IMAGES" + endC) print(endC) # Mise à jour du Log ending_event = "cutRasterImages() : Cutting rasters and vector ending : " timeLine(path_time_log, ending_event) return
def terrainRoughnessClass(grid_input, grid_output, built_input, distance_lines, epsg, project_encoding, server_postgis, port_number, user_postgis, password_postgis, database_postgis, schema_postgis, path_time_log, format_vector='ESRI Shapefile', save_results_intermediate=False, overwrite=True): print(bold + yellow + "Début du calcul de l'indicateur Terrain Roughness Class." + endC + "\n") timeLine(path_time_log, "Début du calcul de l'indicateur Terrain Roughness Class : ") if debug >= 3: print(bold + green + "terrainRoughnessClass() : Variables dans la fonction" + endC) print(cyan + "terrainRoughnessClass() : " + endC + "grid_input : " + str(grid_input) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "grid_output : " + str(grid_output) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "built_input : " + str(built_input) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "distance_lines : " + str(distance_lines) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "epsg : " + str(epsg) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "project_encoding : " + str(project_encoding) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "server_postgis : " + str(server_postgis) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "port_number : " + str(port_number) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "user_postgis : " + str(user_postgis) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "password_postgis : " + str(password_postgis) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "database_postgis : " + str(database_postgis) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "schema_postgis : " + str(schema_postgis) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "path_time_log : " + str(path_time_log) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "format_vector : " + str(format_vector) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "save_results_intermediate : " + str(save_results_intermediate) + endC) print(cyan + "terrainRoughnessClass() : " + endC + "overwrite : " + str(overwrite) + endC) print("\n") if not os.path.exists(grid_output) or overwrite: ############################################ ### Préparation générale des traitements ### ############################################ print(bold + cyan + "Préparation au calcul de Terrain Roughness Class :" + endC) timeLine(path_time_log, " Préparation au calcul de Terrain Roughness Class : ") if os.path.exists(grid_output): removeVectorFile(grid_output) # Création de la base de données PostGIS # ~ dropDatabase(database_postgis, user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=port_number, schema_name=schema_postgis) # Conflits avec autres indicateurs (Aspect Ratio / Height of Roughness Elements) createDatabase(database_postgis, user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=port_number, schema_name=schema_postgis) # Import des fichiers shapes maille et bati dans la base de données PostGIS table_name_maille = importVectorByOgr2ogr(database_postgis, grid_input, 'trc_maille', user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=str(port_number), schema_name=schema_postgis, epsg=str(epsg), codage=project_encoding) table_name_bati = importVectorByOgr2ogr(database_postgis, built_input, 'trc_bati', user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=str(port_number), schema_name=schema_postgis, epsg=str(epsg), codage=project_encoding) # Récupération de l'emprise de la zone d'étude, définie par le fichier maillage d'entrée xmin,xmax,ymin,ymax = getEmpriseFile(grid_input, format_vector) if debug >= 1: print(bold + "Emprise du fichier '%s' :" % (grid_input) + endC) print(" xmin = " + str(xmin)) print(" xmax = " + str(xmax)) print(" ymin = " + str(ymin)) print(" ymax = " + str(ymax)) # Création de la liste des valeurs de x à entrer dans la requêtes SQL de création de lignes x_list = [xmin] # Initialisation de la liste x = xmin # Définition de la valeur du 1er x à entrer dans la boucle while x < (xmax - distance_lines): # On boucle tant que la valeur de x ne dépasse pas le xmax du fichier maillage en entrée x = x + distance_lines x_list.append(x) # Ajout de la nouvelle valeur de x dans la liste if debug >= 2: print(bold + "x_list : " + endC + str(x_list) + "\n") # Création de la liste des valeurs de y à entrer dans la requêtes SQL de création de lignes y_list = [ymax] # Initialisation de la liste y = ymax # Définition de la valeur du 1er y à entrer dans la boucle while y > (ymin + distance_lines): # On boucle tant que la valeur de y ne descend pas en-dessous du ymin du fichier maillage en entrée y = y - distance_lines y_list.append(y) # Ajout de la nouvelle valeur de y dans la liste if debug >= 2: print(bold + "y_list : " + endC + str(y_list) + "\n") ################################################# ### Création des lignes parallèles N-S et W-E ### ################################################# print(bold + cyan + "Création des lignes parallèles N-S et W-E :" + endC) timeLine(path_time_log, " Création des lignes parallèles N-S et W-E : ") connection = openConnection(database_postgis, user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=port_number, schema_name=schema_postgis) # Construction de la requête de création des lignes parallèles N-S query_lines_NS = "DROP TABLE IF EXISTS trc_lines_NS;\n" query_lines_NS += "CREATE TABLE trc_lines_NS (line text, geom geometry);\n" query_lines_NS += "INSERT INTO trc_lines_NS VALUES\n" # Boucle sur les valeurs de x dans la liste associée, pour construire la requête de création des lignes parallèles N-S count_NS = 0 for x in x_list: count_NS += 1 query_lines_NS += " ('line_NS_%s', 'LINESTRING(%s %s, %s %s)'),\n" % (count_NS, x, ymax, x, ymin) # Fin de la requête de création des lignes parallèles N-S et exécution de cette requête query_lines_NS = query_lines_NS[:-2] + ";\n" # Transformer la virgule de la dernière ligne SQL en point-virgule (pour terminer la requête) query_lines_NS += "ALTER TABLE trc_lines_NS ALTER COLUMN geom TYPE geometry(LINESTRING,%s) USING ST_SetSRID(geom,%s);\n" % (epsg,epsg) # Mise à jour du système de coordonnées if debug >= 1: print(query_lines_NS) executeQuery(connection, query_lines_NS) # Construction de la requête de création des lignes parallèles W-E query_lines_WE = "DROP TABLE IF EXISTS trc_lines_WE;\n" query_lines_WE += "CREATE TABLE trc_lines_WE (line text, geom geometry);\n" query_lines_WE += "INSERT INTO trc_lines_WE VALUES\n" # Boucle sur les valeurs de y dans la liste associée, pour construire la requête de création des lignes parallèles W-E count_WE = 0 for y in y_list: count_WE += 1 query_lines_WE += " ('line_WE_%s', 'LINESTRING(%s %s, %s %s)'),\n" % (count_WE, xmin, y, xmax, y) # Fin de la requête de création des lignes parallèles W-E et exécution de cette requête query_lines_WE = query_lines_WE[:-2] + ";\n" # Transformer la virgule de la dernière ligne SQL en point-virgule (pour terminer la requête) query_lines_WE += "ALTER TABLE trc_lines_WE ALTER COLUMN geom TYPE geometry(LINESTRING,%s) USING ST_SetSRID(geom,%s);\n" % (epsg,epsg) # Mise à jour du système de coordonnées if debug >= 1: print(query_lines_WE) executeQuery(connection, query_lines_WE) ##################################################################################################### ### Découpage des bâtiments, et des lignes N-S et W-E à cheval sur plusieurs mailles (intersects) ### ##################################################################################################### print(bold + cyan + "Lancement des requêtes d'intersect :" + endC) timeLine(path_time_log, " Lancement des requêtes d'intersect : ") query_intersect = """ --CREATE INDEX IF NOT EXISTS maille_geom_gist ON %s USING GIST (geom); --CREATE INDEX IF NOT EXISTS bati_geom_gist ON %s USING GIST (geom); CREATE INDEX IF NOT EXISTS lines_NS_geom_gist ON trc_lines_NS USING GIST (geom); CREATE INDEX IF NOT EXISTS lines_WE_geom_gist ON trc_lines_WE USING GIST (geom); DROP TABLE IF EXISTS trc_decoup; CREATE TABLE trc_decoup AS SELECT b.ID as ID, b.HAUTEUR as hauteur, ST_Intersection(b.geom, m.geom) as geom FROM %s as b, %s as m WHERE ST_Intersects(b.geom, m.geom); CREATE INDEX IF NOT EXISTS decoup_geom_gist ON trc_decoup USING GIST (geom); DROP TABLE IF EXISTS trc_decoupNS; CREATE TABLE trc_decoupNS AS SELECT m.ID as ID, l.line as line, ST_Intersection(l.geom, m.geom) as geom FROM trc_lines_NS as l, %s as m WHERE ST_Intersects(l.geom, m.geom); CREATE INDEX IF NOT EXISTS decoupNS_geom_gist ON trc_decoupNS USING GIST (geom); DROP TABLE IF EXISTS trc_decoupWE; CREATE TABLE trc_decoupWE AS SELECT m.ID as ID, l.line as line, ST_Intersection(l.geom, m.geom) as geom FROM trc_lines_WE as l, %s as m WHERE ST_Intersects(l.geom, m.geom); CREATE INDEX IF NOT EXISTS decoupWE_geom_gist ON trc_decoupWE USING GIST (geom); """ % (table_name_maille, table_name_bati, table_name_bati, table_name_maille, table_name_maille, table_name_maille) if debug >= 1: print(query_intersect) executeQuery(connection, query_intersect) ####################################################################################################################################################### ### Calculs pour l'obtention des sous-indicateurs liés à l'intersect des bâtiments dans chaque maille : h, plan area ratio, hauteur de déplacement ### ####################################################################################################################################################### print(bold + cyan + "Calcul des indicateurs secondaires liés aux bâtiments intersectant chaque maille :" + endC) timeLine(path_time_log, " Calcul des indicateurs secondaires liés aux bâtiments intersectant chaque maille : ") query_bati = """ DROP TABLE IF EXISTS trc_temp_a; CREATE TABLE trc_temp_a AS SELECT ID, hauteur, st_area(geom) as surface, geom FROM trc_decoup; ALTER TABLE trc_temp_a ADD volume DOUBLE PRECISION; UPDATE trc_temp_a SET volume = (surface * hauteur); ALTER TABLE trc_temp_a ADD VxH DOUBLE PRECISION; UPDATE trc_temp_a SET VxH = (volume * hauteur); CREATE INDEX IF NOT EXISTS temp_a_geom_gist ON trc_temp_a USING GIST (geom); DROP TABLE IF EXISTS trc_temp_b; CREATE TABLE trc_temp_b AS SELECT m.ID as ID, (sum(a.VxH) / sum(a.volume)) as h, (sum(a.surface) / st_area(m.geom)) as PAR, m.geom as geom FROM %s as m, trc_temp_a as a WHERE ST_Intersects(m.geom, a.geom) GROUP BY m.ID, m.geom; ALTER TABLE trc_temp_b ADD zd DOUBLE PRECISION; UPDATE trc_temp_b SET zd = (h * (PAR ^ 0.6)); CREATE INDEX IF NOT EXISTS temp_b_geom_gist ON trc_temp_b USING GIST (geom); DROP TABLE IF EXISTS trc_temp_c; CREATE TABLE trc_temp_c AS SELECT DISTINCT ID, geom FROM %s WHERE ID NOT IN (SELECT DISTINCT ID FROM trc_temp_b); ALTER TABLE trc_temp_c ADD h DOUBLE PRECISION; UPDATE trc_temp_c SET h = 0; ALTER TABLE trc_temp_c ADD PAR DOUBLE PRECISION; UPDATE trc_temp_c SET PAR = 0; ALTER TABLE trc_temp_c ADD zd DOUBLE PRECISION; UPDATE trc_temp_c SET zd = 0; CREATE INDEX IF NOT EXISTS temp_c_geom_gist ON trc_temp_c USING GIST (geom); DROP TABLE IF EXISTS trc_temp; CREATE TABLE trc_temp AS SELECT ID, h, PAR, zd, geom FROM trc_temp_b UNION SELECT ID, h, PAR, zd, geom FROM trc_temp_c; ALTER TABLE trc_temp ALTER COLUMN ID TYPE INTEGER; CREATE INDEX IF NOT EXISTS temp_geom_gist ON trc_temp USING GIST (geom); """ % (table_name_maille, table_name_maille) if debug >= 1: print(query_bati) executeQuery(connection, query_bati) ##################################################################################################################################################### ### Calculs pour l'obtention des sous-indicateurs liés à l'intersect des bâtiments avec chaque ligne N-S, dans chaque maille : frontal area ratio ### ##################################################################################################################################################### print(bold + cyan + "Calcul des indicateurs secondaires liés aux bâtiments intersectant chaque ligne N-S, intersectant chaque maille :" + endC) timeLine(path_time_log, " Calcul des indicateurs secondaires liés aux bâtiments intersectant chaque ligne N-S, intersectant chaque maille : ") query_NS = """ DROP TABLE IF EXISTS trc_tempNS_a; CREATE TABLE trc_tempNS_a AS SELECT ns.ID as ID, ns.line as line, max(d.hauteur) as max_haut, (%s * max(d.hauteur)) as FA, ns.geom as geom FROM trc_decoup as d, trc_decoupNS as ns WHERE ST_Intersects(d.geom, ns.geom) GROUP BY ns.ID, ns.line, ns.geom; CREATE INDEX IF NOT EXISTS tempNS_a_geom_gist ON trc_tempNS_a USING GIST (geom); DROP TABLE IF EXISTS trc_tempNS_b; CREATE TABLE trc_tempNS_b AS SELECT m.ID as ID, (sum(a.FA) / st_area(m.geom)) as FAR, m.geom as geom FROM trc_tempNS_a as a, %s as m WHERE ST_Intersects(a.geom, m.geom) GROUP BY m.ID, m.geom; CREATE INDEX IF NOT EXISTS tempNS_b_geom_gist ON trc_tempNS_b USING GIST (geom); DROP TABLE IF EXISTS trc_tempNS_c; CREATE TABLE trc_tempNS_c AS SELECT DISTINCT ID, geom FROM %s WHERE ID NOT IN (SELECT DISTINCT ID FROM trc_tempNS_b); ALTER TABLE trc_tempNS_c ADD FAR DOUBLE PRECISION; UPDATE trc_tempNS_c SET FAR = 0; CREATE INDEX IF NOT EXISTS tempNS_c_geom_gist ON trc_tempNS_c USING GIST (geom); DROP TABLE IF EXISTS trc_tempNS; CREATE TABLE trc_tempNS AS SELECT ID, FAR, geom FROM trc_tempNS_b UNION SELECT ID, FAR, geom FROM trc_tempNS_c; ALTER TABLE trc_tempNS ALTER COLUMN ID TYPE INTEGER; CREATE INDEX IF NOT EXISTS tempNS_geom_gist ON trc_tempNS USING GIST (geom); """ % (distance_lines, table_name_maille, table_name_maille) if debug >= 1: print(query_NS) executeQuery(connection, query_NS) ##################################################################################################################################################### ### Calculs pour l'obtention des sous-indicateurs liés à l'intersect des bâtiments avec chaque ligne W-E, dans chaque maille : frontal area ratio ### ##################################################################################################################################################### print(bold + cyan + "Calcul des indicateurs secondaires liés aux bâtiments intersectant chaque ligne W-E, intersectant chaque maille :" + endC) timeLine(path_time_log, " Calcul des indicateurs secondaires liés aux bâtiments intersectant chaque ligne W-E, intersectant chaque maille : ") query_WE = """ DROP TABLE IF EXISTS trc_tempWE_a; CREATE TABLE trc_tempWE_a AS SELECT we.ID as ID, we.line as line, max(d.hauteur) as max_haut, (%s * max(d.hauteur)) as FA, we.geom as geom FROM trc_decoup as d, trc_decoupWE as we WHERE ST_Intersects(d.geom, we.geom) GROUP BY we.ID, we.line, we.geom; CREATE INDEX IF NOT EXISTS tempWE_a_geom_gist ON trc_tempWE_a USING GIST (geom); DROP TABLE IF EXISTS trc_tempWE_b; CREATE TABLE trc_tempWE_b AS SELECT m.ID as ID, (sum(a.FA) / st_area(m.geom)) as FAR, m.geom as geom FROM trc_tempWE_a as a, %s as m WHERE ST_Intersects(a.geom, m.geom) GROUP BY m.ID, m.geom; CREATE INDEX IF NOT EXISTS tempWE_b_geom_gist ON trc_tempWE_b USING GIST (geom); DROP TABLE IF EXISTS trc_tempWE_c; CREATE TABLE trc_tempWE_c AS SELECT DISTINCT ID, geom FROM %s WHERE ID NOT IN (SELECT DISTINCT ID FROM trc_tempWE_b); ALTER TABLE trc_tempWE_c ADD FAR DOUBLE PRECISION; UPDATE trc_tempWE_c SET FAR = 0; CREATE INDEX IF NOT EXISTS tempWE_c_geom_gist ON trc_tempWE_c USING GIST (geom); DROP TABLE IF EXISTS trc_tempWE; CREATE TABLE trc_tempWE AS SELECT ID, FAR, geom FROM trc_tempWE_b UNION SELECT ID, FAR, geom FROM trc_tempWE_c; ALTER TABLE trc_tempWE ALTER COLUMN ID TYPE INTEGER; CREATE INDEX IF NOT EXISTS tempWE_geom_gist ON trc_tempWE USING GIST (geom); """ % (distance_lines, table_name_maille, table_name_maille) if debug >= 1: print(query_WE) executeQuery(connection, query_WE) ######################################################################################################################## ### Calculs finaux pour l'obtention de l'indicateur de classe de rugosité : longueur de rugosité, classe de rugosité ### ######################################################################################################################## print(bold + cyan + "Calculs finaux de l'indicateur de classe de rugosité :" + endC) timeLine(path_time_log, " Calculs finaux de l'indicateur de classe de rugosité : ") query_rugo = """ DROP TABLE IF EXISTS trc_rugo; CREATE TABLE trc_rugo AS SELECT t.ID as ID, t.h as h, t.PAR as PAR, t.zd as zd, ns.FAR as FAR_NS, we.FAR as FAR_WE, t.geom as geom FROM trc_temp as t, trc_tempNS as ns, trc_tempWE as we WHERE t.ID = ns.ID and ns.ID = WE.ID; ALTER TABLE trc_rugo ALTER COLUMN ID TYPE INTEGER; ALTER TABLE trc_rugo ADD COLUMN z0_NS DOUBLE PRECISION; UPDATE trc_rugo SET z0_NS = ((h - zd) * exp(-sqrt(0.4 / FAR_NS))) WHERE FAR_NS > 0; UPDATE trc_rugo SET z0_NS = 0 WHERE FAR_NS = 0; ALTER TABLE trc_rugo ADD COLUMN z0_WE DOUBLE PRECISION; UPDATE trc_rugo SET z0_WE = ((h - zd) * exp(-sqrt(0.4 / FAR_WE))) WHERE FAR_WE > 0; UPDATE trc_rugo SET z0_WE = 0 WHERE FAR_WE = 0; ALTER TABLE trc_rugo ADD COLUMN mean_z0 DOUBLE PRECISION; UPDATE trc_rugo SET mean_z0 = (z0_NS + z0_WE) / 2; ALTER TABLE trc_rugo ADD COLUMN cl_rugo integer; UPDATE trc_rugo SET cl_rugo = 1 WHERE mean_z0 < 0.0025; UPDATE trc_rugo SET cl_rugo = 2 WHERE mean_z0 >= 0.0025 and mean_z0 < 0.0175; UPDATE trc_rugo SET cl_rugo = 3 WHERE mean_z0 >= 0.0175 and mean_z0 < 0.065; UPDATE trc_rugo SET cl_rugo = 4 WHERE mean_z0 >= 0.065 and mean_z0 < 0.175; UPDATE trc_rugo SET cl_rugo = 5 WHERE mean_z0 >= 0.175 and mean_z0 < 0.375; UPDATE trc_rugo SET cl_rugo = 6 WHERE mean_z0 >= 0.375 and mean_z0 < 0.75; UPDATE trc_rugo SET cl_rugo = 7 WHERE mean_z0 >= 0.75 and mean_z0 < 1.5; UPDATE trc_rugo SET cl_rugo = 8 WHERE mean_z0 >= 1.5; """ if debug >= 1: print(query_rugo) executeQuery(connection, query_rugo) closeConnection(connection) exportVectorByOgr2ogr(database_postgis, grid_output, 'trc_rugo', user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=str(port_number), schema_name=schema_postgis, format_type=format_vector) ########################################## ### Nettoyage des fichiers temporaires ### ########################################## if not save_results_intermediate: # ~ dropDatabase(database_postgis, user_name=user_postgis, password=password_postgis, ip_host=server_postgis, num_port=port_number, schema_name=schema_postgis) # Conflits avec autres indicateurs (Aspect Ratio / Height of Roughness Elements) pass else: print(bold + magenta + "Le calcul de Terrain Roughness Class a déjà eu lieu." + endC) print(bold + yellow + "Fin du calcul de l'indicateur Terrain Roughness Class." + endC + "\n") timeLine(path_time_log, "Fin du calcul de l'indicateur Terrain Roughness Class : ") return