Exemple #1
0
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
Exemple #3
0
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()
Exemple #7
0
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()