def humanise_nom_fantoir(name, dict_premier_mot, dict_tout_les_mots): original_name = name name = name.title() mots = name.split() premier_mot_norm = to_ascii(mots[0]).upper() if premier_mot_norm in dict_premier_mot: if len(mots) > 1 and mots[1] == dict_premier_mot[premier_mot_norm]: # Le type de voie est répété dans le nom de la voie, ça arrive parfois, on le supprime: mots = mots[1:] else: # On remplace étend le préfixe: mots = dict_premier_mot[premier_mot_norm].split() + mots[1:] for i, mot in enumerate(mots): mot_norm = to_ascii(mot).upper() if mot_norm in dict_tout_les_mots: mots[i] = dict_tout_les_mots[mot_norm] name = " ".join(mots) name = name.replace(" Du ", " du ") name = name.replace(" De La ", " de la ") name = name.replace(" De ", " de ") name = name.replace(" Des ", " des ") name = name.replace(" Et ", " et ") name = name.replace(" L ", " l'") name = name.replace(" L'", " l'") name = name.replace(" D ", " d'") name = name.replace(" D'", " d'") name = name.replace(" Saint ", " Saint-") name = name.replace(" Sainte ", " Sainte-") name = name.replace("Grande Rue Grande Rue", "Grande Rue") name = name.replace("Grande Rue Grand Rue", "Grand'Rue") # if name != original_name: # print " - ", original_name, "=>", name return name
def get_dict_accents_mots(osm_noms): """Retourne un dictionnaire qui transforme un mot (ascii majuscule) en sa version avec accents. Pour cela on utilise en entrée le fichier osm CODE_COMUNE-noms.osm, qui contient les mots extraits des export PDF du cadastre. """ dict_accents_mots = {} if osm_noms: sys.stdout.write((u"Recherche l'orthographe accentuée depuis les exports PDF du cadastre.\n").encode("utf-8")) liste_mots_a_effacer_du_dict = ["DE", "LA", "ET"] # On essaye de parser l'ensemble des noms extraits du cadastre pour # en faire un dictionaire de remplacement a appliquer for node in osm_noms.nodes.itervalues(): #if not 'place' in node.tags: # on évite les nœuds place=neighbourhood qui sont écrit en majuscule sans accents if 'name' in node.tags and not 'place' in node.tags: # on évite les nœuds place=neighbourhood qui sont écrit en majuscule sans accents, et les noeuds sans tag name (sans aucun tag) for mot in node.tags['name'].replace("_"," ").replace("-"," ").replace("'"," ").split(): if len(mot) > 1: mot_norm = to_ascii(mot).upper() if mot_norm != mot.upper(): # il contient des accents mot = mot.capitalize() if mot_norm not in dict_accents_mots: dict_accents_mots[mot_norm] = mot elif dict_accents_mots[mot_norm] != mot: alternative = dict_accents_mots[mot_norm] # On a deux orthographes pour le même mot, on garde celle avec des caracères # bizares, genre accents ou cédille mot_est_complexe = to_ascii(mot) != mot alternative_est_complexe = to_ascii(alternative) != alternative if mot_est_complexe and not alternative_est_complexe: dict_accents_mots[mot_norm] = mot elif alternative_est_complexe and not mot_est_complexe: # on garde l'arternative qui est actuellement dans le dictionnaire pass elif alternative_est_complexe and mot_est_complexe: # je ne sais pas quoi faire, trop de risque pour cette orthographe # on supprime le mot liste_mots_a_effacer_du_dict.append(mot_norm) sys.stdout.write(("ATTENTION: ne peut pas choisir entre l'orthographe " + mot + " ou " + alternative + "\n").encode("utf-8")) else: # c'est juste un problème de capitale, on ignore pass for mot in liste_mots_a_effacer_du_dict: if mot in dict_accents_mots: del(dict_accents_mots[mot]) dict_accents_mots.update({ "EGLISE": u"Église", "ECOLE": u"École", "ECOLES": u"Écoles", "ALLEE": u"Allée", "ALLEES": u"Allées", "GENERAL" : u"Général", # Abréviations typiques du Fantoir: "PDT": u"Président", "CDT": "Commandant", "REGT" : u"Régiment", "DOC" : "Docteur", "ST" : "Saint", "STE" : "Sainte", }) return dict_accents_mots
def humanise_nom_fantoir(name, dict_premier_mot, dict_tout_les_mots): original_name = name name = name.title() mots = name.split() premier_mot_norm = to_ascii(mots[0]).upper() if premier_mot_norm in dict_premier_mot: if len(mots) > 1 and mots[1] == dict_premier_mot[premier_mot_norm]: # Le type de voie est répété dans le nom de la voie, ça arrive parfois, on le supprime: mots = mots[1:] else: # On remplace étend le préfixe: mots = dict_premier_mot[premier_mot_norm].split() + mots[1:] for i,mot in enumerate(mots): mot_norm = to_ascii(mot).upper() if mot_norm in dict_tout_les_mots: mots[i] = dict_tout_les_mots[mot_norm] name = ' '.join(mots) name = name.replace(" Du "," du ") name = name.replace(" De La "," de la ") name = name.replace(" De "," de ") name = name.replace(" Des "," des ") name = name.replace(" Et "," et ") name = name.replace(" L "," l'") name = name.replace(" L'"," l'") name = name.replace(" D "," d'") name = name.replace(" D'"," d'") name = name.replace(" Saint "," Saint-") name = name.replace(" Sainte "," Sainte-") name = name.replace("Grande Rue Grande Rue", "Grande Rue") name = name.replace("Grande Rue Grand Rue", "Grand'Rue") #if name != original_name: # print " - ", original_name, "=>", name return name
def get_dict_abrev_type_voie(): """ Retourne un dictionnaire qui transforme une abréviation de type de voie utilisée par le Fantoir en sa version non abrégée. """ dict_abrev_type_voie = {} for nom, abrev in addr_fantoir_building.dicts.abrev_type_voie.iteritems(): nom = nom.title() abrev = to_ascii(abrev).upper() if not abrev in dict_abrev_type_voie: dict_abrev_type_voie[abrev] = nom else: # Choisi le nom le plus petit: if len(nom) < len(dict_abrev_type_voie[abrev]): dict_abrev_type_voie[abrev] = nom dict_abrev_type_voie["CHEM"] = "Chemin" # à la place de CHEMINEMENT dict_abrev_type_voie["CHE"] = "Chemin" # à la place de CHEM dict_abrev_type_voie["ILE"] = u"Île" # pb d'encodage dans le projet associatedStreet dict_abrev_type_voie["ECA"] = u"Écart" # pb d'encodage dans le projet associatedStreet return dict_abrev_type_voie
def partitionnement_osm_associatedStreet_zip(osm, zip_filename, subdir=""): """ partitionnement du fichier osm: - par rue pour les numéros associés à une seule rue - par k-moyenne pour les numéros orphelins, ambigus ou les quartiers. """ filename_osm_map = {} if subdir: subdir += "/" # FIXME: le découpage fait ici ne marche qu'avec les restriction suposée # sur le fichier d'entrée, cad avec que: # - des nouveau node addr:housenumber ou place # - des nouvelle relations type=associatedStreet # - des ways extraits d'osm potentiellement modifiés # - des node extraits d'osm non modifiés # Cherche la relation associatedStreet de chaque nouveau node # addr:housenumber: associatedStreet_of_housenumber_node = {} for n in osm.nodes.itervalues(): if n.id() < 0 : if "addr:housenumber" in n.tags: associatedStreet_of_housenumber_node[n.id()] = [] else: assert(("place" in n.tags) or ("highway" in n.tags)) else: # le code actuel ne sait partitionner que des neuds addr:housenumber que l'on a # créé nous même (id<0) # les autres on vas les zapper donc on vérifie qu'il # s'agit bien d'un noeuds déjà existant dans OSM (id >=0) et # non modifié (pas d'attribut action) assert(n.id() >= 0 and "action" not in n.attrs) for r in osm.relations.itervalues(): if r.id() < 0 and r.tags.get("type") == "associatedStreet": for mtype,mref,mrole in r.itermembers(): if mtype == 'node': associatedStreet_of_housenumber_node[mref].append(r) else: # le code actuel ne sait partitionner que les relation # associatedStreet que l'on a créé nous même (id<0) # les autres on vas les zapper donc on vérifie qu'il # s'agit bien de relation déjà existantt dans OSM (id >=0) et # non modifié (pas d'attribut action) assert(r.id() >= 0 and "action" not in r.attrs) # Cree un fichier par relation associatedStreet: for r in osm.relations.itervalues(): if r.id() < 0 and r.tags.get('type') == "associatedStreet": street_osm = Osm({}) street_relation = Relation(r.attrs.copy(), r.tags.copy()) street_osm.add_relation(street_relation) for mtype,mref,mrole in r.itermembers(): if mrole == 'house': assert(mtype == 'node') if len(associatedStreet_of_housenumber_node[mref]) == 1: node = osm.nodes[mref] street_osm.add_node(node) street_relation.add_member(node, mrole) else: street_relation.add_member_type_ref_role(mtype, mref, mrole) filename = subdir + to_ascii(r.tags['name']) + ".osm" filename_osm_map[filename] = street_osm # Partitionne les noeuds ambigus noeuds_ambigus = [osm.nodes[i] for i in associatedStreet_of_housenumber_node.iterkeys() if len(associatedStreet_of_housenumber_node[i]) > 1] filename_osm_map.update(partitionnement_osm_nodes_filename_map(noeuds_ambigus, subdir + "_AMBIGUS_")) # Partitionne les noeuds orphelins noeuds_orphelins = [osm.nodes[i] for i in associatedStreet_of_housenumber_node.iterkeys() if len(associatedStreet_of_housenumber_node[i]) == 0] filename_osm_map.update(partitionnement_osm_nodes_filename_map(noeuds_orphelins, subdir + "_ORPHELINS_")) # Partitionne les noeuds de quartiers (place=neighbourhood): noeuds_quartiers = [n for n in osm.nodes.itervalues() if (n.id()<0) and ("place" in n.tags)] osms_quartiers = partitionnement_osm_nodes_filename_map(noeuds_quartiers, subdir + "_QUARTIERS_") filename_osm_map.update(osms_quartiers) # Partitionne les noeuds de rue (highway=): noeuds_rues = [n for n in osm.nodes.itervalues() if (n.id()<0) and ("highway" in n.tags)] osms_rues = partitionnement_osm_nodes_filename_map(noeuds_rues, subdir + "_ADRESSES_RESSEMBLANTS_NOM_DE_RUE_") for filename, new_osm in osms_rues.iteritems(): new_osm.attrs["upload"] = "false" filename_osm_map.update(osms_rues) # Avec l'intégration des addr:housenumber au buildings, le fichier d'entrée # contiens peut-être aussi des way issue d'OSM qui ont été modifiés. # On vas donc essayer de répartir ces ways dans le partitionnement, mais # cela est possible que si le way est utilisé dans une seule partition (un # seul fichier). filenames_of_new_nodes = {} for filename, new_osm in filename_osm_map.iteritems(): for n in new_osm.nodes.itervalues(): if n.id() < 0: if not n.id() in filenames_of_new_nodes: filenames_of_new_nodes[n.id()] = set() filenames_of_new_nodes[n.id()].add(filename) for way in osm.ways.itervalues(): assert(way.id() >= 0) if "action" in way.attrs: filenames_of_way = set() for nid in way.nodes: if nid < 0: filenames_of_way.update(filenames_of_new_nodes[nid]) if len(filenames_of_way) == 1: # Ajoute le way dans le seul fichier: way_new_osm = filename_osm_map[filenames_of_way.pop()] for nid in way.nodes: if not nid in way_new_osm.nodes: node = osm.nodes[nid] way_new_osm.add_node(node) way_new_osm.add_way(way) elif len(filenames_of_way) > 1: # On ne duplique pas la version modifié du way # On rajoute donc un fixme vers ses neuds pour indiquer # qu'il faudrait les intégrer au way manuellement: for nid in way.nodes: if nid<0: node = osm.nodes[nid] if "fixme" in node.tags: node.tags["fixme"] += " et " + FIXME_JOINDRE_NOEUD_AU_WAY else: node.tags["fixme"] = FIXME_JOINDRE_NOEUD_AU_WAY zip_output = zipfile.ZipFile(zip_filename,"w", zipfile.ZIP_DEFLATED) for filename, osm in filename_osm_map.iteritems(): s = StringIO() OsmWriter(osm).write_to_stream(s) zip_output.writestr(filename, s.getvalue()) zip_output.close()
def partitionnement_osm_associatedStreet_zip(osm, zip_filename, subdir=""): """ partitionnement du fichier osm: - par rue pour les numéros associés à une seule rue - par k-moyenne pour les numéros orphelins, ambigus ou les quartiers. """ filename_osm_map = {} if subdir: subdir += "/" # FIXME: le découpage fait ici ne marche qu'avec les restriction suposée # sur le fichier d'entrée, cad avec que: # - des nouveau node addr:housenumber ou place # - des nouvelle relations type=associatedStreet # - des ways extraits d'osm potentiellement modifiés # - des node extraits d'osm non modifiés # Cherche la relation associatedStreet de chaque nouveau node # addr:housenumber: associatedStreet_of_housenumber_node = {} for n in osm.nodes.itervalues(): if n.id() < 0: if "addr:housenumber" in n.tags: associatedStreet_of_housenumber_node[n.id()] = [] else: assert (("place" in n.tags) or ("highway" in n.tags)) else: # le code actuel ne sait partitionner que des neuds addr:housenumber que l'on a # créé nous même (id<0) # les autres on vas les zapper donc on vérifie qu'il # s'agit bien d'un noeuds déjà existant dans OSM (id >=0) et # non modifié (pas d'attribut action) assert (n.id() >= 0 and "action" not in n.attrs) for r in osm.relations.itervalues(): if r.id() < 0 and r.tags.get("type") == "associatedStreet": for mtype, mref, mrole in r.itermembers(): if mtype == 'node': associatedStreet_of_housenumber_node[mref].append(r) else: # le code actuel ne sait partitionner que les relation # associatedStreet que l'on a créé nous même (id<0) # les autres on vas les zapper donc on vérifie qu'il # s'agit bien de relation déjà existantt dans OSM (id >=0) et # non modifié (pas d'attribut action) assert (r.id() >= 0 and "action" not in r.attrs) # Cree un fichier par relation associatedStreet: for r in osm.relations.itervalues(): if r.id() < 0 and r.tags.get('type') == "associatedStreet": street_osm = Osm({}) street_relation = Relation(r.attrs.copy(), r.tags.copy()) street_osm.add_relation(street_relation) for mtype, mref, mrole in r.itermembers(): if mrole == 'house': assert (mtype == 'node') if len(associatedStreet_of_housenumber_node[mref]) == 1: node = osm.nodes[mref] street_osm.add_node(node) street_relation.add_member(node, mrole) else: street_relation.add_member_type_ref_role( mtype, mref, mrole) filename = subdir + to_ascii(r.tags['name']) + ".osm" filename_osm_map[filename] = street_osm # Partitionne les noeuds ambigus noeuds_ambigus = [ osm.nodes[i] for i in associatedStreet_of_housenumber_node.iterkeys() if len(associatedStreet_of_housenumber_node[i]) > 1 ] filename_osm_map.update( partitionnement_osm_nodes_filename_map(noeuds_ambigus, subdir + "_AMBIGUS_")) # Partitionne les noeuds orphelins noeuds_orphelins = [ osm.nodes[i] for i in associatedStreet_of_housenumber_node.iterkeys() if len(associatedStreet_of_housenumber_node[i]) == 0 ] filename_osm_map.update( partitionnement_osm_nodes_filename_map(noeuds_orphelins, subdir + "_ORPHELINS_")) # Partitionne les noeuds de quartiers (place=neighbourhood): noeuds_quartiers = [ n for n in osm.nodes.itervalues() if (n.id() < 0) and ("place" in n.tags) ] osms_quartiers = partitionnement_osm_nodes_filename_map( noeuds_quartiers, subdir + "_QUARTIERS_") filename_osm_map.update(osms_quartiers) # Partitionne les noeuds de rue (highway=): noeuds_rues = [ n for n in osm.nodes.itervalues() if (n.id() < 0) and ("highway" in n.tags) ] osms_rues = partitionnement_osm_nodes_filename_map( noeuds_rues, subdir + "_ADRESSES_RESSEMBLANTS_NOM_DE_RUE_") for filename, new_osm in osms_rues.iteritems(): new_osm.attrs["upload"] = "false" filename_osm_map.update(osms_rues) # Avec l'intégration des addr:housenumber au buildings, le fichier d'entrée # contiens peut-être aussi des way issue d'OSM qui ont été modifiés. # On vas donc essayer de répartir ces ways dans le partitionnement, mais # cela est possible que si le way est utilisé dans une seule partition (un # seul fichier). filenames_of_new_nodes = {} for filename, new_osm in filename_osm_map.iteritems(): for n in new_osm.nodes.itervalues(): if n.id() < 0: if not n.id() in filenames_of_new_nodes: filenames_of_new_nodes[n.id()] = set() filenames_of_new_nodes[n.id()].add(filename) for way in osm.ways.itervalues(): assert (way.id() >= 0) if "action" in way.attrs: filenames_of_way = set() for nid in way.nodes: if nid < 0: filenames_of_way.update(filenames_of_new_nodes[nid]) if len(filenames_of_way) == 1: # Ajoute le way dans le seul fichier: way_new_osm = filename_osm_map[filenames_of_way.pop()] for nid in way.nodes: if not nid in way_new_osm.nodes: node = osm.nodes[nid] way_new_osm.add_node(node) way_new_osm.add_way(way) elif len(filenames_of_way) > 1: # On ne duplique pas la version modifié du way # On rajoute donc un fixme vers ses neuds pour indiquer # qu'il faudrait les intégrer au way manuellement: for nid in way.nodes: if nid < 0: node = osm.nodes[nid] if "fixme" in node.tags: node.tags[ "fixme"] += " et " + FIXME_JOINDRE_NOEUD_AU_WAY else: node.tags["fixme"] = FIXME_JOINDRE_NOEUD_AU_WAY zip_output = zipfile.ZipFile(zip_filename, "w", zipfile.ZIP_DEFLATED) for filename, osm in filename_osm_map.iteritems(): s = StringIO() OsmWriter(osm).write_to_stream(s) zip_output.writestr(filename, s.getvalue()) zip_output.close()
def normalize(nom): result = addr_fantoir_building.normalize(to_ascii(nom)) if result.startswith("GR GRANDE RUE") or result.startswith("GR GRAND RUE"): result = result[3:] return result