def partitionnement_osm_nodes_filename_map(node_list, filenameprefix): """Partitionne les noeuds de la node list en plusieurs objet Osm() et retourne une map entre un nom de fichier et ces éléments Osm. """ filename_osm_map = {} if len(node_list) > TAILLE_PARTITIONEMENT_NOEUDS: partitions = partitionnement_osm_nodes(node_list, TAILLE_PARTITIONEMENT_NOEUDS) partitions = zip(*partitions)[0] else: partitions = [node_list] if len(partitions) > 1: taille_index = int(math.ceil(math.log10(len(partitions) + 1))) for i in xrange(len(partitions)): osm = Osm({}) for n in partitions[i]: osm.add_node(n) filename = filenameprefix + ("%%0%dd.osm" % taille_index) % (i + 1, ) filename_osm_map[filename] = osm elif len(partitions[0]) > 0: osm = Osm({}) for n in partitions[0]: osm.add_node(n) filename_osm_map[filenameprefix + ".osm"] = osm return filename_osm_map
def get_osm_buildings_and_barrier_ways(code_departement, code_commune): """ Retourne un objet Osm contenant tout les ways de la commune correspondant au buildings et au barrier.""" merge_osm = Osm({}) input_osms = [ open_osm_ways_commune(code_departement, code_commune, "building", nodes=True), open_osm_multipolygon_s_ways_commune(code_departement, code_commune, "building", nodes=True), open_osm_ways_commune(code_departement, code_commune, "barrier", nodes=True), ] for osm in input_osms: for id,node in osm.nodes.iteritems(): if not id in merge_osm.nodes: merge_osm.add_node(node) for id, way in osm.ways.iteritems(): if any([nid not in osm.nodes for nid in way.nodes]): # Il manque des nodes à ce way, ça arrive parfois # dans les résultats d'overpass, je ne sais pas pourquoi # mais cela ferait bugger l'utilisation de ce way # donc on le zap: continue if not id in merge_osm.ways: merge_osm.add_way(way) for id, rel in osm.ways.iteritems(): if not id in merge_osm.relations: merge_osm.add_relation(rel) return merge_osm
def get_osm_buildings_and_barrier_ways(code_departement, code_commune): """ Retourne un objet Osm contenant tout les ways de la commune correspondant au buildings et au barrier.""" merge_osm = Osm({}) input_osms = [ open_osm_ways_commune(code_departement, code_commune, "building", nodes=True), open_osm_multipolygon_s_ways_commune(code_departement, code_commune, "building", nodes=True), open_osm_ways_commune(code_departement, code_commune, "barrier", nodes=True), ] for osm in input_osms: for id, node in osm.nodes.iteritems(): if not id in merge_osm.nodes: merge_osm.add_node(node) for id, way in osm.ways.iteritems(): if any([nid not in osm.nodes for nid in way.nodes]): # Il manque des nodes à ce way, ça arrive parfois # dans les résultats d'overpass, je ne sais pas pourquoi # mais cela ferait bugger l'utilisation de ce way # donc on le zap: continue if not id in merge_osm.ways: merge_osm.add_way(way) for id, rel in osm.ways.iteritems(): if not id in merge_osm.relations: merge_osm.add_relation(rel) return merge_osm
def pdf_vers_osm_limites_parcelles(pdf_filename_list, osm_output): projection, parcelles = pdf_vers_limites_parcelles(pdf_filename_list) cadastre_to_osm_transform = CadastreToOSMTransform(projection) osm = Osm({'upload':'false'}) for parcelle in parcelles: #for linear_ring in list(polygon.interiors) + [polygon.exterior]: for linear_ring in parcelle: points = map(cadastre_to_osm_transform.transform_point, linear_ring) nodes = [Node({'lon':str(p.x), 'lat':str(p.y)}) for p in points] way = Way({}) for n in nodes: osm.add_node(n) way.add_node(n) osm.add_way(way) OsmWriter(osm).write_to_stream(osm_output)
def partitionnement_osm_nodes_filename_map(node_list, filenameprefix): """Partitionne les noeuds de la node list en plusieurs objet Osm() et retourne une map entre un nom de fichier et ces éléments Osm. """ filename_osm_map = {} if len(node_list) > TAILLE_PARTITIONEMENT_NOEUDS: partitions = partitionnement_osm_nodes(node_list , TAILLE_PARTITIONEMENT_NOEUDS) partitions = zip(*partitions)[0] else: partitions = [node_list] if len(partitions) > 1: taille_index = int(math.ceil(math.log10(len(partitions)+1))) for i in xrange(len(partitions)): osm = Osm({}) for n in partitions[i]: osm.add_node(n) filename = filenameprefix + ("%%0%dd.osm" % taille_index) % (i+1,) filename_osm_map[filename] = osm elif len(partitions[0]) > 0: osm = Osm({}) for n in partitions[0]: osm.add_node(n) filename_osm_map[filenameprefix + ".osm"] = osm return filename_osm_map
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()