Bonjour
Pour mon premier message à cette liste de distribution je vais me
présenter rapidement. Je vis à Toulouse et je participe à OpenstreetMap
depuis un peu plus d'un an (je sais plus trop). Bref. Au début c'était
juste pour corriger une évolution et je trouve que c'est de plus en plus
prenant et je me trouve maintenant à faire des modifs beaucoup plus
lourdes. :-)
J'ai toujours trouvé que la mise à jour des bâtiments était pénible à
faire. Parce qu'il faut comparer ce qui existe avec ce qui est fourni
par le cadastre. On peut superposer les deux avec josm. C'est très
facile quand il y a 100 pâtés de maison mais c'est un cauchemard quand
il y en a plus de 1000.
Du coup j'ai fait un petit script python (joint à ce message) qui fait
la comparaison entre ce qui existe et ce qui fourni par le cadastre. Il
détermine quels sont les bâtiments supprimés, les bâtiments nouveaux, et
les bâtiments modifiés. Il y a toujours un travail à faire à partir des
résultats obtenus parce que ce n'est pas possible d'éviter des faux
positifs mais ça évite de faire une comparaison maison par maison. Bien
sûr, il vaut mieux que la commune sur laquelle il est appliqué soit déjà
issue des données du cadastre. Une commune ou le bâti est tracé à partir
de Bing donnera des résultats plus mitigés.
Je ne vais pas détailler ici le fonctionnement de mon script. C'est déjà
fait dans cette fil que j'ai ouvert sur le forum osm-fr :
http://forum.openstreetmap.fr/viewtopic.php?f=5&t=1762
Je peux vous fournir un fichier exemple d'utilisation. Il s'agit du bâti
de la commune de Seilh (https://www.openstreetmap.org/relation/158877)
au nord de Toulouse :
http://sendbox.fr/pro/5r3o7uspdsb0/Seilh.zip.html
Ce zip contient 2 fichiers :
Seilh_as_is.osm : les batiments tels qu'ils sont dans OSM actuellement
Seilh_to_be.osm : les bâtiments tels que le cadastre le donne actuellement.
Pour l'utilisation la commande est simple :
python BatiOSm.py Seilh_as_is.osm Seilh_to_be.osm prefixe
préfixe sera utilisé pour nommer les fichiers résultats.
Merci pour votre aide et pour votre retour si vous avez des suggestions
d'améliorations ou si vous avez des comportements bizarres !
Sébastien
# -*- coding:Utf-8 -*-
#!/usr/bin/env python
import sys
import os
from math import sqrt
import time
from operator import attrgetter
BORNE_INF_MODIF = 1.e-5
BORNE_SUP_MODIF = 1.e-4
class Point:
"""Définition d'un point.
Attributs :
- identifiant (chaine de caractère)
- latitude et longitude (flottant)
"""
def __init__(self, node_id, node_lat, node_lon):
self.node_id = node_id
self.node_lat = float(node_lat)
self.node_lon = float(node_lon)
def affiche(self):
print self.node_id, self.node_lat, self.node_lon
def distance(self, other):
"""Calcul de la distance entre deux points"""
d_lat = self.node_lat - other.node_lat
d_lon = self.node_lon - other.node_lon
return sqrt(d_lat**2 + d_lon**2)
def export_node(self):
"""Création du code xml équivalent au point"""
self.print_node = " <node id='" + self.node_id + \
"' action='modify' visible='true' lat='" + \
str(self.node_lat) + "' lon='" + str(self.node_lon) + "' />"
class Batiment:
"""L'entité Batiment rassemble plusieurs données :
- bat_id : un identifiant (chaine de caractère)
- nbre_node : le nombre de points du batiment (nombre entier)
- node_id : le tableau des Points du batiments
- pt_moy : le point de référence du batiments (centre de gravité)
- dist_mini : une valeurs de distance pour détecter la modification du batiment
- largeur : la largeur du batiment
- status : le status du batiment (nouveau, identique, modifié, supprimé)
- nombre_tag : le nombre de tag défini dans le fichier
- tableau_tag_key : le tableau d'identifiants des tags
- tableau_tag_value : le tableau des valeurs des tags
- pbAire : l'information si le batiment a une aire nulle
- multipolygone : yes si le batiment en est un, no sinon
- role : le role si le batiment appartient à une relation
- ind_relation : l'indice de la relation auquel il appartient
"""
def __init__(self, bat_id, nbre_node, node_id,
numTag, tableauTagKey, tableauTagValue,
distance=1000, largeur = 0., status = "UNKNOWN", pbAire = "NO",
multipolygone = "no", role = "outer", ind_relation = 0):
self.bat_id = bat_id
self.nbre_node = nbre_node
self.node_id = node_id
self.dist_mini = float(distance)
self.largeur = largeur
self.status = status
self.nombre_tag = numTag
self.tableau_tag_key = tableauTagKey
self.tableau_tag_value = tableauTagValue
self.pbAire = "NO"
self.multipolygone = "no"
self.role = "outer"
self.ind_relation = 0
def BatimentToPoint(self):
"""Calcul du centre de gravité du batiment.
les coordonnées sont d'abord exprimés en "pseudo-mètres" en
prenant comme origine le premier point du batiment parce qu'il
n'y a pas suffisamment de différence entre chaque point pour
faire les calcul (il faudrait augmenter la précision).
Ensuite le calcul se fait d'après
https://fr.wikipedia.org/wiki/Aire_et_centre_de_masse_d%27un_polygone
Le calcul nécessite de diviser par la surface du batiment. Cela
pose problème si le batiment a une surface nulle. Les exceptions
sont traités avec pbAire. Dans ce cas le point de référence de
ces batiments est la moyenne des coordonnées de chaque point.
"""
i_node = 0
calculLatitude = 0
calculLongitude = 0
latMoyenne = 0
lonMoyenne = 0
aire = 0
latLocale = []
lonLocale = []
while i_node < self.nbre_node:
latLocale.append((self.node_id[i_node].node_lat - \
self.node_id[0].node_lat) * 6500000.)
lonLocale.append((self.node_id[i_node].node_lon - \
self.node_id[0].node_lon) * 6500000.)
i_node = i_node + 1
i_node = 0
while i_node < self.nbre_node - 1:
latMoyenne = latMoyenne + self.node_id[i_node].node_lat
lonMoyenne = lonMoyenne + self.node_id[i_node].node_lon
produitEnCroix = (latLocale[i_node] * lonLocale[i_node + 1] - \
latLocale[i_node + 1] * lonLocale[i_node])
aire = aire + 0.5 * produitEnCroix
calculLatitude = calculLatitude + (latLocale[i_node] + \
latLocale[i_node + 1]) * produitEnCroix
calculLongitude = calculLongitude + (lonLocale[i_node] + \
lonLocale[i_node + 1]) * produitEnCroix
i_node = i_node + 1
if aire == 0.:
self.pbAire = "YES"
latitude = latMoyenne / self.nbre_node
longitude = lonMoyenne / self.nbre_node
else:
latitude = self.node_id[0].node_lat + \
calculLatitude / (6 * aire * 6500000.)
longitude = self.node_id[0].node_lon + \
calculLongitude / (6 * aire * 6500000.)
self.pt_moy = Point(self.bat_id, latitude, longitude)
def calculLargeur(self):
"""Calcul de la largeur approximative du batiment.
Cette distance intervient ensuite dans la détermination
du status du batiment. Si la distance mini est supérieure à cette
largeur alors cela veut dire que le batiment est nouveau ou
supprimé."""
tableauLatitude = []
tableauLongitude = []
for node in range(self.nbre_node):
tableauLatitude.append(self.node_id[node].node_lat)
tableauLongitude.append(self.node_id[node].node_lon)
minLat = min(tableauLatitude)
maxLat = max(tableauLatitude)
minLon = min(tableauLongitude)
maxLon = max(tableauLongitude)
self.largeur = sqrt((maxLat - minLat)**2 + (maxLon - minLon)**2)
def setDistMini(self, distance):
"""Cette méthode permet de définir la distance mini comme étant celle
passé en paramètre"""
self.dist_mini = float(distance)
def setBatProche(self, nomBatProche, indBatProche):
"""Cette méthode permet de définir que le batiment auquel elle est
appliquée correspond au batiment passé en paramètre"""
self.id_bat_proche = nomBatProche
self.ind_bat_proche = indBatProche
def setStatus(self, status):
"""Cette méthode défini le status du batiment."""
self.status = status
def setRole(self, role):
"""
Cette méthode défini le role du batiment lorsqu'il appartient Ã
une relation. Le role est soit "inner" soit "outer".
"""
self.role = role
def export_bat(self):
"""Cette méthode défini une version xml du batiment, de ses noeuds
et de ses éventuels tag dans le but d'être transcrit dans un fichier."""
export = []
res_export = ""
export.append(" <way id='" + self.bat_id + "' visible='true'>")
i_node = 0
while i_node < self.nbre_node:
export.append(" <nd ref='" + self.node_id[i_node].node_id + \
"' />")
i_node = i_node + 1
for i_tag in range(self.nombre_tag):
export.append(" <tag k='" + self.tableau_tag_key[i_tag] + \
"' v='" + self.tableau_tag_value[i_tag] + "' />")
export.append(" </way>")
i_node = 0
while i_node < self.nbre_node:
self.node_id[i_node].export_node()
export.append(self.node_id[i_node].print_node)
i_node = i_node + 1
nb_ligne = len(export)
i_ligne = 0
while i_ligne < nb_ligne:
if i_ligne == nb_ligne - 1:
res_export = res_export + export[i_ligne]
else:
res_export = res_export + export[i_ligne] + "\n"
i_ligne = i_ligne + 1
self.print_bat = res_export
def copy_tag(self, other, status):
"""Cette méthode permet de copier les tag d'un batiment passé en
paramètre au batiment auquelle elle est appliquée.
Lorsque le batiment 'self' est détecté comme identique, la source est
hérité du batiment 'other'. Par contre lorsque le batiment 'self' est
détecté comme modifié, la source est mis à jour pour prendre la valeur
du batiment 'other'.
"""
if status == "IDENTIQUE":
self.nombre_tag = other.nombre_tag
self.tableau_tag_key = other.tableau_tag_key
self.tableau_tag_value = other.tableau_tag_value
elif status == "MODIFIE":
rang_tag_source = self.tableau_tag_key.index("source")
tag_source_save = self.tableau_tag_value[rang_tag_source]
self.nombre_tag = other.nombre_tag
self.tableau_tag_key = other.tableau_tag_key
self.tableau_tag_value = other.tableau_tag_value
try:
rang_tag_source = self.tableau_tag_key.index("source")
self.tableau_tag_value[rang_tag_source] = tag_source_save
except:
pass
class Relation:
"""
Classe qui regroupe les relations pour le traitement des multipolygones.
"""
def __init__(self, id_relation, nb_ways, tab_id_ways, tab_ind_ways, tab_role):
self.id = id_relation
self.nb_ways = nb_ways
self.id_ways = tab_id_ways
self.ind_ways = tab_ind_ways
self.role = tab_role
def export_relation(self):
export = []
res_export = ""
export.append(" <relation id='" + self.id + "'>")
export.append(" <tag k='value' v='multipolygon'/>")
for ways in range(self.nb_ways):
export.append(" <member type='way' ref='" + \
self.id_ways[ways] + "' role='" + \
self.role[ways] + "'/>")
export.append(" </relation>")
nb_ligne = len(export)
i_ligne = 0
while i_ligne < nb_ligne:
if i_ligne == nb_ligne - 1:
res_export = res_export + export[i_ligne]
else:
res_export = res_export + export[i_ligne] + "\n"
i_ligne = i_ligne + 1
self.print_relation = res_export
def formatLog(donnees):
"""Cette fonction permet de générer une chaine de caractère formaté et
de longueur constante à partir du tableau passé en paramètre"""
result = ""
nbData = len(donnees)
for i_data in range(nbData):
if i_data < nbData - 1:
nbCarLimite = 18
else:
nbCarLimite = 50
donnees[i_data] = " " + donnees[i_data]
nbCar = len(donnees[i_data])
while nbCar < nbCarLimite:
donnees[i_data] = donnees[i_data] + " "
nbCar = len(donnees[i_data])
result = result + "|" + donnees[i_data]
result = result + "|"
return result
#------------------------------------------------------------------------------
# D E B U T D U P R O G R A M M E
#------------------------------------------------------------------------------
adresse = sys.path[0]
fichier_osm_old = sys.argv[1]
fichier_osm_new = sys.argv[2]
prefixe = sys.argv[3]
separation = "--------------------------------------------------------------------------------------------------------------------------------"
tps1 = time.clock()
print "------------------------------------------------------------------"
print "- Lecture des données -"
print "------------------------------------------------------------------"
#------------------------------------------------------------------------
#lecture des vieux batiments :
#------------------------------------------------------------------------
file_old = open(fichier_osm_old, "r")
print "lecture du fichier " + fichier_osm_old + "..."
#détermination du séparateur du fichier : " ou '
ligne = file_old.readline().rstrip('\n\r')
tabLigne1 = ligne.split("'")
tabLigne2 = ligne.split("\"")
if len(tabLigne1) > len(tabLigne2):
delim = "'"
else:
delim = "\""
old_nodes = []
old_id_nodes = []
old_bati = []
old_bati_sorted = []
old_relation = []
old_nbre_nodes = 0
old_nbre_ways = 0
old_nbre_relation = 0
i_way = 0
i_nd_ref = 0
col_id = 0
col_lat = 0
col_lon = 0
for ligne in file_old:
champsLigne = ligne.rstrip('\n\r').split(delim)
if champsLigne[0].find("node id") != -1:
col_id = 1
col_lat = champsLigne.index(" lat=") + 1
col_lon = champsLigne.index(" lon=") + 1
old_nodes.append(Point(champsLigne[col_id], champsLigne[col_lat], \
champsLigne[col_lon]))
old_id_nodes.append(champsLigne[col_id])
old_nbre_nodes = old_nbre_nodes + 1
elif champsLigne[0].find("way id") != -1: # nouveau batiment : on initialise les données
way_id = champsLigne[1]
i_nd_ref = 0
nodes = []
tagKey = []
tagValue = []
numTag = 0
elif champsLigne[0].find("nd ref") != -1:
id_nd_ref = champsLigne[1]
i_nd_ref = i_nd_ref + 1
nodes.append(old_nodes[old_id_nodes.index(id_nd_ref)])
elif champsLigne[0].find("tag") != -1:
if i_nd_ref != 0:
tagKey.append(champsLigne[1])
tagValue.append(champsLigne[3])
numTag = numTag + 1
elif champsLigne[0].find("/way") != -1:
old_bati.append(Batiment(way_id, i_nd_ref, nodes, \
numTag, tagKey, tagValue, 1000, 0., "UNKNOWN"))
old_bati[old_nbre_ways].BatimentToPoint()
if old_bati[old_nbre_ways].pbAire == "YES":
print " Warning, surface nulle obtenue pour le batiment :", \
old_bati[old_nbre_ways].bat_id
old_bati[old_nbre_ways].calculLargeur()
old_nbre_ways = old_nbre_ways + 1
elif champsLigne[0].find("relation id") !=-1:
relation_id = champsLigne[1]
nb_member = 0
tab_id_member = []
tab_ind_member = []
tab_role = []
elif champsLigne[0].find("member type") != -1:
col_ref = champsLigne.index(" ref=") + 1
col_role = champsLigne.index(" role=") + 1
tab_id_member.append(champsLigne[col_ref])
tab_role.append(champsLigne[col_role])
nb_member = nb_member + 1
elif champsLigne[0].find("/relation") != -1:
for i_member in range(nb_member):
for i_bat in range(old_nbre_ways):
if old_bati[i_bat].bat_id == tab_id_member[i_member]:
old_bati[i_bat].multipolygone = "yes"
old_bat[i_bat].ind_relation = old_nbre_relation
tab_ind_member.append(i_bat)
if tab_role[i_member] == "inner":
old_bati[i_bat].setRole("inner")
old_relation.append(Relation(relation_id, nb_member, tab_id_member, \
tab_ind_member, tab_role))
old_nbre_relation = old_nbre_relation + 1
file_old.close()
print " " + str(old_nbre_nodes) + " noeuds répertoriés dans le fichier " + \
fichier_osm_old
print " " + str(old_nbre_ways) + " batiments répertoriés dans le fichier " + \
fichier_osm_old
#------------------------------------------------------------------------
#lecture des nouveaux batiments :
#------------------------------------------------------------------------
file_new = open(fichier_osm_new, "r")
print "lecture du fichier " + fichier_osm_new + "..."
ligne = file_new.readline().rstrip('\n\r')
tabLigne1 = ligne.split("'")
tabLigne2 = ligne.split("\"")
if len(tabLigne1) > len(tabLigne2):
delim = "'"
else:
delim = "\""
new_nodes = []
new_id_nodes = []
new_bati = []
new_bati_sorted = []
new_relation = []
new_nbre_nodes = 0
new_nbre_ways = 0
new_nbre_relation = 0
i_way = 0
i_nd_ref = 0
col_id = 0
col_lat = 0
col_lon = 0
for ligne in file_new:
champsLigne = ligne.rstrip('\n\r').split(delim)
if champsLigne[0].find("node id") != -1:
col_id = 1
col_lat = champsLigne.index(" lat=") + 1
col_lon = champsLigne.index(" lon=") + 1
new_nodes.append(Point(champsLigne[col_id], champsLigne[col_lat], \
champsLigne[col_lon]))
new_id_nodes.append(champsLigne[col_id])
new_nbre_nodes = new_nbre_nodes + 1
elif champsLigne[0].find("way id") != -1:
way_id = champsLigne[1]
i_nd_ref = 0
nodes = []
tagKey = []
tagValue = []
numTag = 0
elif champsLigne[0].find("nd ref") != -1:
id_nd_ref = champsLigne[1]
i_nd_ref = i_nd_ref + 1
nodes.append(new_nodes[new_id_nodes.index(id_nd_ref)])
elif champsLigne[0].find("tag") != -1:
if i_nd_ref != 0:
tagKey.append(champsLigne[1])
tagValue.append(champsLigne[3])
numTag = numTag + 1
elif champsLigne[0].find("/way") != -1:
new_bati.append(Batiment(way_id, i_nd_ref, nodes, \
numTag, tagKey, tagValue, 1000, 0., "UNKNOWN"))
new_bati[new_nbre_ways].BatimentToPoint()
if new_bati[new_nbre_ways].pbAire == "YES":
print " Attention, surface nulle obtenue pour le batiment :", \
new_bati[new_nbre_ways].bat_id
new_bati[new_nbre_ways].calculLargeur()
new_nbre_ways = new_nbre_ways + 1
elif champsLigne[0].find("relation id") !=-1:
relation_id = champsLigne[1]
nb_member = 0
tab_id_member = []
tab_ind_member = []
tab_role = []
elif champsLigne[0].find("member type") != -1:
col_ref = champsLigne.index(" ref=") + 1
col_role = champsLigne.index(" role=") + 1
tab_id_member.append(champsLigne[col_ref])
tab_role.append(champsLigne[col_role])
nb_member = nb_member + 1
elif champsLigne[0].find("/relation") != -1:
for i_member in range(nb_member):
for i_bat in range(new_nbre_ways):
if new_bati[i_bat].bat_id == tab_id_member[i_member]:
new_bati[i_bat].multipolygone = "yes"
new_bati[i_bat].ind_relation = new_nbre_relation
tab_ind_member.append(i_bat)
if tab_role[i_member] == "inner":
new_bati[i_bat].setRole("inner")
new_relation.append(Relation(relation_id, nb_member, tab_id_member, \
tab_ind_member, tab_role))
new_nbre_relation = new_nbre_relation + 1
file_new.close()
print " " + str(new_nbre_nodes) + " noeuds répertoriés dans le fichier " + \
fichier_osm_new
print " " + str(new_nbre_ways) + " batiments répertoriés dans le fichier " + \
fichier_osm_new
print "------------------------------------------------------------------"
print "- Recherche des similitudes et des différences entre batiments -"
print "------------------------------------------------------------------"
#------------------------------------------------------------------------------
#calcul des distances mini entre chaque anciens batiments
# pour chaque batiment anciens (resp. nouveau) on détermine la distance
# la plus petite avec tous les nouveaux batiments (resp. anciens)
#------------------------------------------------------------------------------
nbre_comparaison = 2 * old_nbre_ways * new_nbre_ways
avancement = 0
i_old = 0
while i_old < old_nbre_ways:
i_new = 0
if old_bati[i_old].role == "outer":
while i_new < new_nbre_ways:
if new_bati[i_new].role == "outer":
distance = old_bati[i_old].pt_moy.distance(new_bati[i_new].pt_moy)
if old_bati[i_old].dist_mini > distance:
old_bati[i_old].setDistMini(distance)
old_bati[i_old].setBatProche(new_bati[i_new].bat_id, i_new)
i_new = i_new + 1
else:
old_bati[i_old].setDistMini(9999.)
old_bati[i_old].setBatProche("-9999", 9999)
avancement = int(float(i_old) / (old_nbre_ways + new_nbre_ways) * 100.)
sys.stdout.write("Calcul en cours : " + str(avancement) + " %" + chr(13))
i_old = i_old + 1
i_new = 0
while i_new < new_nbre_ways:
i_old = 0
if new_bati[i_new].role == "outer":
while i_old < old_nbre_ways:
if old_bati[i_old].role == "outer":
distance = new_bati[i_new].pt_moy.distance(old_bati[i_old].pt_moy)
if new_bati[i_new].dist_mini > distance:
new_bati[i_new].setDistMini(distance)
new_bati[i_new].setBatProche(old_bati[i_old].bat_id, i_old)
i_old = i_old + 1
else:
new_bati[i_new].setDistMini(9999.)
new_bati[i_new].setBatProche("-9999", 9999)
avancement = int(float(old_nbre_ways + i_new) / \
(old_nbre_ways + new_nbre_ways) * 100.)
sys.stdout.write("Calcul en cours : " + str(avancement) + " %" + chr(13))
i_new = i_new + 1
#------------------------------------------------------------------------
#Classement des batiments :
# - dist_mini < BORNE_INF_MODIF : identique
# - BORNE_INF_MODIF < dist_mini < BORNE_SUP_MODIF : modifié
# - dist_mini > BORNE_SUP_MODIF : nouveau ou supprimé
# - dist_mini > largeur : nouveau ou supprimé
#------------------------------------------------------------------------
nb_bat_new = 0
nb_bat_mod = 0
nb_bat_del = 0
nb_bat_noMod = 0
nb_bat_inner_new = 0
nb_bat_inner_old = 0
for batiments in range(new_nbre_ways):
if new_bati[batiments].role == "outer":
if new_bati[batiments].dist_mini < BORNE_INF_MODIF:
new_bati[batiments].setStatus("IDENTIQUE")
new_bati[batiments].copy_tag(old_bati[new_bati[batiments].ind_bat_proche], \
"IDENTIQUE")
elif new_bati[batiments].dist_mini > BORNE_INF_MODIF and \
new_bati[batiments].dist_mini < BORNE_SUP_MODIF:
new_bati[batiments].setStatus("MODIFIE")
new_bati[batiments].copy_tag(old_bati[new_bati[batiments].ind_bat_proche], \
"MODIFIE")
elif new_bati[batiments].dist_mini > BORNE_SUP_MODIF:
new_bati[batiments].setStatus("NOUVEAU")
if new_bati[batiments].dist_mini > new_bati[batiments].largeur:
new_bati[batiments].setStatus("NOUVEAU")
else:
new_bati[batiments].setStatus("INNER")
for batiments in range(old_nbre_ways):
if old_bati[batiments].role == "outer":
if old_bati[batiments].dist_mini > BORNE_SUP_MODIF:
old_bati[batiments].setStatus("SUPPRIME")
if old_bati[batiments].dist_mini > old_bati[batiments].largeur:
old_bati[batiments].setStatus("SUPPRIME")
else:
old_bati[batiments].setStatus("INNER")
# Classement des batiments en fonction du status et de la distance mini.
new_bati_sorted = sorted(new_bati, key = attrgetter("status", \
"dist_mini"))
old_bati_sorted = sorted(old_bati, key = attrgetter("status", \
"dist_mini"))
dernier_id_inner_new = 0
i_new = 0
while i_new < new_nbre_ways:
if new_bati_sorted[i_new].status == "IDENTIQUE":
nb_bat_noMod = nb_bat_noMod + 1
dernier_id_identique = i_new
elif new_bati_sorted[i_new].status == "INNER":
nb_bat_inner_new = nb_bat_inner_new + 1
dernier_id_inner_new = i_new
elif new_bati_sorted[i_new].status == "MODIFIE":
nb_bat_mod = nb_bat_mod + 1
dernier_id_modifie = i_new
elif new_bati_sorted[i_new].status == "NOUVEAU":
nb_bat_new = nb_bat_new + 1
i_new = i_new + 1
dernier_id_inner_old = 0
i_old = 0
while i_old < old_nbre_ways:
if old_bati_sorted[i_old].status == "INNER":
nb_bat_inner_old = nb_bat_inner_old + 1
dernier_id_inner_old = i_old
elif old_bati_sorted[i_old].status == "SUPPRIME":
nb_bat_del = nb_bat_del + 1
i_old = i_old + 1
print "------------------------------------------------------------------"
print "- Création des fichiers -"
print "------------------------------------------------------------------"
print nb_bat_noMod, " batiments identiques"
print nb_bat_mod, " batiments modifiés"
print nb_bat_new, " batiments nouveaux"
print nb_bat_del, " batiments supprimés"
tps2 = time.clock()
file_log = open(adresse + "/" + prefixe + "_log.txt", "w")
file_log.write("Rappel des input : \n")
file_log.write(" BORNE_INF_MODIF : " + str(BORNE_INF_MODIF) + "\n")
file_log.write(" BORNE_SUP_MODIF : " + str(BORNE_SUP_MODIF) + "\n")
file_log.write("Le fichier " + fichier_osm_old + " contient :" + "\n")
file_log.write(" - " + str(old_nbre_nodes) + " noeuds" + "\n")
file_log.write(" - " + str(old_nbre_ways) + " batiments" + "\n")
file_log.write("Le fichier " + fichier_osm_new + " contient :" + "\n")
file_log.write(" - " + str(new_nbre_nodes) + " noeuds" + "\n")
file_log.write(" - " + str(new_nbre_ways) + " batiments" + "\n")
file_log.write("Résultat de la comparaison :" + "\n")
file_log.write(" Nombre de batiments identiques trouvés : " + \
str(nb_bat_noMod) + "\n")
file_log.write(" Nombre de batiments modifiés trouvés : " + \
str(nb_bat_mod) + "\n")
file_log.write(" Nombre de batiments nouveaux trouvés : " + \
str(nb_bat_new) + "\n")
file_log.write(" Nombre de batiments supprimés trouvés : " + \
str(nb_bat_del) + "\n")
file_log.write("Temps de calcul : " + str(tps2 - tps1) + " secondes." + "\n")
file_log.write(separation + "\n")
file_log.write("Récapitulatif des nouveaux batiments" + "\n")
file_log.write(separation + "\n")
i_new = 0
while i_new < new_nbre_ways:
Resultat = [new_bati_sorted[i_new].bat_id, new_bati_sorted[i_new].status, \
str(round(new_bati_sorted[i_new].dist_mini, 9)), \
str(new_bati_sorted[i_new].pt_moy.node_lat), \
str(new_bati_sorted[i_new].pt_moy.node_lon)]
file_log.write(formatLog(Resultat) + "\n")
i_new = i_new + 1
file_log.write(separation + "\n")
file_log.write("Récapitulatif des Anciens batiments" + "\n")
file_log.write(separation + "\n")
i_old = 0
while i_old < old_nbre_ways:
Resultat = [old_bati_sorted[i_old].bat_id, old_bati_sorted[i_old].status, \
str(round(old_bati_sorted[i_old].dist_mini, 9)), \
str(old_bati_sorted[i_old].pt_moy.node_lat), \
str(old_bati_sorted[i_old].pt_moy.node_lon)]
file_log.write(formatLog(Resultat) + "\n")
i_old = i_old + 1
file_log.write(separation + "\n")
file_log.write(str(nb_bat_noMod) + " batiments classés comme identiques" + "\n")
file_log.write(separation + "\n")
enTete = ["STATUS", "ANCIEN BATIMENT", "TOLERANCE", "NOUVEAU BATIMENT", "fichier"]
file_log.write(formatLog(enTete) +"\n")
# écriture des batiments identiques dans un même fichier
noMod_building = prefixe + "_unModified.osm"
file_noMod_building = open(adresse + "/" + noMod_building, "w")
file_noMod_building.write("<?xml version='1.0' encoding='UTF-8'?>" + "\n")
file_noMod_building.write("<osm version='0.6' upload='true' generator='JOSM'>" + "\n")
for i_bat in range(dernier_id_identique):
new_bati_sorted[i_bat].export_bat()
file_noMod_building.write(new_bati_sorted[i_bat].print_bat + "\n")
if new_bati_sorted[i_bat].multipolygone == "yes":
relation = new_bati_sorted[i_bat].ind_relation
for members in range(new_relation[relation].nb_ways):
if new_relation[relation].role[members] == "inner":
indic_bati_membre = new_relation[relation].ind_ways[members]
new_bati[indic_bati_membre].export_bat()
file_noMod_building.write(new_bati[indic_bati_membre].print_bat + "\n")
new_relation[relation].export_relation()
file_noMod_building.write(new_relation[relation].print_relation + "\n")
Ligne = ["IDENTIQUE", new_bati_sorted[i_bat].id_bat_proche , \
str(round(new_bati_sorted[i_bat].dist_mini, 9)), \
new_bati_sorted[i_bat].bat_id , noMod_building ]
file_log.write(formatLog(Ligne) + "\n")
file_noMod_building.write("</osm>")
file_noMod_building.close()
enTete = ["STATUS", "ANCIEN BATIMENT", "TOLERANCE", "NOUVEAU BATIMENT", "fichier"]
# écriture des batiments modifiés dans plusieurs fichier
file_log.write(separation + "\n")
file_log.write(str(nb_bat_mod) + " batiments classés comme modifiés" + "\n")
file_log.write(separation + "\n")
file_log.write(formatLog(enTete) +"\n")
nom_file = prefixe + "_mod_1_a_" + str(nb_bat_mod) + ".osm"
file_mod_building = open(adresse + "/" + nom_file, "w")
file_mod_building.write("<?xml version='1.0' encoding='UTF-8'?>" + "\n")
file_mod_building.write("<osm version='0.6' upload='true' generator='JOSM'>" + "\n")
for i_bat in range(nb_bat_mod):
indice = dernier_id_inner_new + i_bat + 1
new_bati_sorted[indice].export_bat()
file_mod_building.write(new_bati_sorted[indice].print_bat + "\n")
if new_bati_sorted[indice].multipolygone == "yes":
relation = new_bati_sorted[indice].ind_relation
for members in range(new_relation[relation].nb_ways):
if new_relation[relation].role[members] == "inner":
indic_bati_membre = new_relation[relation].ind_ways[members]
new_bati[indic_bati_membre].export_bat()
file_mod_building.write(new_bati[indic_bati_membre].print_bat + "\n")
new_relation[relation].export_relation()
file_mod_building.write(new_relation[relation].print_relation + "\n")
Ligne = ["MODIFIE", new_bati_sorted[indice].id_bat_proche, \
str(round(new_bati_sorted[indice].dist_mini, 9)), \
new_bati_sorted[indice].bat_id, nom_file]
file_log.write(formatLog(Ligne) + "\n")
file_mod_building.write("</osm>")
file_mod_building.close()
enTete = ["STATUS", "ANCIEN BATIMENT", "TOLERANCE", "NOUVEAU BATIMENT", "fichier"]
# écriture des batiments nouveaux dans plusieurs fichier
file_log.write(separation + "\n")
file_log.write(str(nb_bat_new) + " batiments classés comme nouveaux" + "\n")
file_log.write(separation + "\n")
file_log.write(formatLog(enTete) +"\n")
nom_file = prefixe + "_new_1_a_" + str(nb_bat_new) + ".osm"
file_new_building = open(adresse + "/" + nom_file , "w")
file_new_building.write("<?xml version='1.0' encoding='UTF-8'?>" + "\n")
file_new_building.write("<osm version='0.6' upload='true' generator='JOSM'>" + "\n")
for i_bat in range(nb_bat_new):
indice = dernier_id_modifie + i_bat + 1
new_bati_sorted[indice].export_bat()
file_new_building.write(new_bati_sorted[indice].print_bat + "\n")
if new_bati_sorted[indice].multipolygone == "yes":
relation = new_bati_sorted[indice].ind_relation
for members in range(new_relation[relation].nb_ways):
if new_relation[relation].role[members] == "inner":
indic_bati_membre = new_relation[relation].ind_ways[members]
new_bati[indic_bati_membre].export_bat()
file_new_building.write(new_bati[indic_bati_membre].print_bat + "\n")
new_relation[relation].export_relation()
file_new_building.write(new_relation[relation].print_relation + "\n")
Ligne = ["NOUVEAU", new_bati_sorted[indice].id_bat_proche, \
str(round(new_bati_sorted[indice].dist_mini, 9)), \
new_bati_sorted[indice].bat_id, nom_file]
file_log.write(formatLog(Ligne) + "\n")
file_new_building.write("</osm>")
file_new_building.close()
enTete = ["STATUS", "ANCIEN BATIMENT", "TOLERANCE", "fichier"]
# écriture des batiments supprimés dans plusieurs fichier
file_log.write(separation + "\n")
file_log.write(str(nb_bat_del) + " batiments classés comme supprimés" + "\n")
file_log.write(separation + "\n")
file_log.write(formatLog(enTete) +"\n")
nom_file = prefixe + "_sup_1_a_" + str(nb_bat_del) + ".osm"
file_del_building = open(adresse + "/" + nom_file , "w")
file_del_building.write("<?xml version='1.0' encoding='UTF-8'?>" + "\n")
file_del_building.write("<osm version='0.6' upload='true' generator='JOSM'>" + "\n")
for i_bat in range(nb_bat_del):
indice = dernier_id_inner_old + i_bat
old_bati_sorted[indice].export_bat()
file_del_building.write(old_bati_sorted[indice].print_bat + "\n")
if old_bati_sorted[indice].multipolygone == "yes":
relation = old_bati_sorted[indice].ind_relation
for members in range(old_relation[relation].nb_ways):
if old_relation[relation].role[members] == "inner":
indic_bati_membre = old_relation[relation].ind_ways[members]
old_bati[indic_bati_membre].export_bat()
file_del_building.write(old_bati[indic_bati_membre].print_bat + "\n")
old_relation[relation].export_relation()
file_del_building.write(old_relation[relation].print_relation + "\n")
Ligne = ["SUPPRIME", old_bati_sorted[indice].bat_id, \
str(round(old_bati_sorted[indice].dist_mini, 9)), nom_file]
file_log.write(formatLog(Ligne) + "\n")
file_del_building.write("</osm>")
file_del_building.close()
file_log.close()
print "Durée du calcul : ", tps2 - tps1
print "------------------------------------------------------------------"
print "- FIN DU PROCESS -"
print "------------------------------------------------------------------"
_______________________________________________
Talk-fr mailing list
Talk-fr@openstreetmap.org
https://lists.openstreetmap.org/listinfo/talk-fr