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
Exemple #2
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 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 #4
0
def generate_osm_housenumbers(numeros, transform):
    osm = Osm({'upload': 'false'})
    for numero, position, angle in numeros:
        node = osm_add_point(osm, position, transform)
        node.tags['fixme'] = u"à vérifier et associer à la bonne rue"
        node.tags['addr:housenumber'] = numero
        node.tags['source'] = SOURCE_TAG
        node.tags['angle'] = str(int(round(angle * 180 / math.pi))) + u"°"
    return osm
Exemple #5
0
def generate_osm_noms(quartiers, rues, transform):
    osm = Osm({'upload': 'false'})
    for nom, position, angle in quartiers:
        node = osm_add_point(osm, position, transform)
        node.tags['name'] = nom
        if nom.lower().startswith("hameau "):
            node.tags['place'] = 'hamlet'
        else:
            node.tags['place'] = 'neighbourhood'
        node.tags['source'] = SOURCE_TAG
    for nom, position, angle in rues:
        node = osm_add_point(osm, position, transform)
        node.tags['name'] = nom
        node.tags['angle'] = str(int(round(angle * 180 / math.pi))) + u"°"
        node.tags['source'] = SOURCE_TAG
    return osm
Exemple #6
0
def pdf_vers_osm_noms(pdf_filename_list, osm_output):
    projection, quartiers, rues = pdf_vers_cadastre_noms(pdf_filename_list)
    cadastre_to_osm_transform = CadastreToOSMTransform(projection).transform_point
    osm = Osm({'upload':'false'})
    for nom, position, angle in quartiers:
        node = osm_add_node(osm, cadastre_to_osm_transform(position))
        node.tags['name'] = nom
        if nom.lower().split()[0]== "hameau":
            node.tags['place'] = 'hamlet'
        else:
            node.tags['place'] = 'neighbourhood'
    for nom, position, angle in rues:
        node = osm_add_node(osm, cadastre_to_osm_transform(position))
        node.tags['name'] = nom
        node.tags['angle'] = str(int(round(angle * 180 / math.pi))) + u"°"
    OsmWriter(osm).write_to_stream(osm_output)
Exemple #7
0
def osm(location, proxies='', timeout=5.0):
    """
    Retrieves geocoding data from OSM's data using Nominatim's geocoding API.

        >>> g = geocoder.osm('Tacloban City')
        >>> g.latlng
        (11.2430274, 125.0081402)
        >>> g.country
        'Philippines'
        ...

    Official Docs
    -------------
    http://wiki.openstreetmap.org/wiki/Nominatim
    """
    provider = Osm(location)
    return Geocoder(provider, proxies=proxies, timeout=timeout)
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)
Exemple #9
0
def generate_osm_parcelles(parcelles, transform):
    osm = Osm({'upload': 'false'})
    for parcelle in parcelles.itervalues():
        if hasattr(parcelle, "limite") and parcelle.limite != None:
            limite = parcelle.limite
        else:
            limite = parcelle.box
        way = osm_add_polygon(osm, limite, transform)
        if hasattr(parcelle, 'adresses'):
            for i, addr in enumerate(parcelle.adresses):
                numero_match = RE_NUMERO_CADASTRE.match(addr)
                if numero_match:
                    num = numero_match.group(0)
                    way.tags['addr%d:housenumber' % i] = num
                    rue = addr[len(num) + 1:].strip()
                else:
                    rue = addr
                way.tags['addr%d:street' % i] = rue
        way.tags['area'] = "yes"
        way.tags['ref:FR:CADASTRE:PARCELLE'] = parcelle.fid
        way.tags['source'] = SOURCE_TAG
    return osm
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 generate_osm_adresses(parcelles, numeros_restant, transform):
    osm = Osm({'upload':'false'})
    # Numéros dont on a pas trouvé la parcelle associée (et donc la rue)
    for n in numeros_restant:
        if n:
            num, position, angle = n
            node = osm_add_point(osm, position, transform)
            node.tags['fixme'] = u"à vérifier et associer à la bonne rue"
            node.tags['addr:housenumber'] = num
            node.tags['source'] = SOURCE_TAG
            node.angle = angle
            node.limite_parcelle = None
    associatedStreets = {}
    # Adresse des parcelles:
    for parcelle in parcelles.itervalues():
        for num in parcelle.positions_numeros.keys():
            for i in range(len(parcelle.addrs_numeros[num])):
                #nom_parcelle = parcelle.fid[5:10].lstrip('0') + " " + parcelle.fid[10:].lstrip('0')
                num_parcelle = parcelle.fid[10:].lstrip('0')
                fixme = []
                if len(parcelle.positions_numeros[num]) > i:
                    position, angle = parcelle.positions_numeros[num][i] 
                    # le numéro est souvent dessiné en dehors des limites
                    # de la parcelle, si c'est le cas et qu'il est proche des limites,
                    # on le déplace sur la limite:
                    if hasattr(parcelle,'limite') and \
                            (parcelle.limite != None) and \
                            (not position.within(parcelle.limite)) and \
                            (position.distance(parcelle.limite) < 2):
                        boundary = parcelle.limite.boundary
                        position = boundary.interpolate(boundary.project(position))
                else:
                    # on ne connait pas la position du numéro
                    # de cette adresse de la parcelle.
                    # on la fixe sur le label de la parcelle:
                    position = Point(parcelle.libellex, parcelle.libelley)
                    # Pour les petites parcelles, le label est parfois en dehors 
                    # de la parcelle, si c'est le cas on le déplace
                    # au centre de la parcelle:
                    if not position.within(parcelle.box):
                      position = parcelle.box.centroid
                    fixme.append(u"position à preciser, parcelle associée: n°" + num_parcelle)
                    angle = None
                node = osm_add_point(osm, position, transform)
                node.angle = angle
                if hasattr(parcelle,'limite'):
                    node.limite_parcelle = parcelle.limite
                else:
                    node.limite_parcelle = None
                node.tags['addr:housenumber'] = num
                node.tags['source'] = SOURCE_TAG
                rues = [addr[len(num)+1:].strip() for addr in parcelle.addrs_numeros[num]]
                for rue in rues:
                    if not associatedStreets.has_key(rue):
                        rel = Relation({})
                        rel.tags['type'] = 'associatedStreet'
                        rel.tags['name'] = rue
                        osm.add_relation(rel)
                        associatedStreets[rue] = rel
                    associatedStreets[rue].add_member(node, 'house')
                if len(rues) > 1:
                    fixme.append(u"choisir la bonne rue: " +
                        " ou ".join(rues))
                if hasattr(parcelle,'limite') and parcelle.limite != None:
                    limite = parcelle.limite
                else:
                    limite = parcelle.box
                distance = position.distance(limite)
                if distance > 10:
                    fixme.append(str(int(distance)) + u" m de la parcelle n°" + num_parcelle + u": vérifier la position et/ou la rue associée")
                    fixme.reverse()
                if fixme:
                    node.tags['fixme'] = " et ".join(fixme)
                  

    # Cherche les nom de lieus: toutes les adresse sans numéro qui ne sont pas des nom de rue:
    positions_des_lieus = {}
    for parcelle in parcelles.itervalues():
        for addr in parcelle.adresses:
            numero_match = RE_NUMERO_CADASTRE.match(addr)
            if addr and (not numero_match) and (not associatedStreets.has_key(addr)):
                if not positions_des_lieus.has_key(addr):
                    positions_des_lieus[addr] = []
                if hasattr(parcelle,'limite') and parcelle.limite != None:
                    centroid = parcelle.limite.centroid
                    if centroid.wkt == 'GEOMETRYCOLLECTION EMPTY':
                        # Pour la ville de Kingersheim (68), il existe une limite de parcelle
                        # aplatie (sur une ligne, donc d'area nulle) ce qui lui donne
                        # un centroid vide.
                        # On utilise alors le centre des points composant sa limite exteieur
                        centroid = parcelle.limite.exterior.centroid
                    positions_des_lieus[addr].append(centroid)
                else:
                    positions_des_lieus[addr].append(parcelle.box.centroid)
    for lieu, positions in positions_des_lieus.iteritems():
        centre = MultiPoint(positions).centroid
        node = osm_add_point(osm, centre, transform)
        node.tags['name'] = lieu
        node.tags['source'] = SOURCE_TAG
        if lieu.lower().startswith("hameau "):
            node.tags['place'] = 'hamlet'
        else:
            node.tags['place'] = 'neighbourhood'
        node.tags['fixme'] = u"à vérifier: lieu créé automatiquement à partir des adresses du coin"
    return osm
Exemple #13
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()
Exemple #14
0
def generate_osm_adresses(parcelles, numeros_restant, transform):
    osm = Osm({'upload': 'false'})
    # Numéros dont on a pas trouvé la parcelle associée (et donc la rue)
    for n in numeros_restant:
        if n:
            num, position, angle = n
            node = osm_add_point(osm, position, transform)
            node.tags['fixme'] = u"à vérifier et associer à la bonne rue"
            node.tags['addr:housenumber'] = num
            node.tags['source'] = SOURCE_TAG
            node.angle = angle
            node.limite_parcelle = None
    associatedStreets = {}
    # Adresse des parcelles:
    for parcelle in parcelles.itervalues():
        for num in parcelle.positions_numeros.keys():
            for i in range(len(parcelle.addrs_numeros[num])):
                #nom_parcelle = parcelle.fid[5:10].lstrip('0') + " " + parcelle.fid[10:].lstrip('0')
                num_parcelle = parcelle.fid[10:].lstrip('0')
                fixme = []
                if len(parcelle.positions_numeros[num]) > i:
                    position, angle = parcelle.positions_numeros[num][i]
                    # le numéro est souvent dessiné en dehors des limites
                    # de la parcelle, si c'est le cas et qu'il est proche des limites,
                    # on le déplace sur la limite:
                    if hasattr(parcelle,'limite') and \
                            (parcelle.limite != None) and \
                            (not position.within(parcelle.limite)) and \
                            (position.distance(parcelle.limite) < 2):
                        boundary = parcelle.limite.boundary
                        position = boundary.interpolate(
                            boundary.project(position))
                else:
                    # on ne connait pas la position du numéro
                    # de cette adresse de la parcelle.
                    # on la fixe sur le label de la parcelle:
                    position = Point(parcelle.libellex, parcelle.libelley)
                    # Pour les petites parcelles, le label est parfois en dehors
                    # de la parcelle, si c'est le cas on le déplace
                    # au centre de la parcelle:
                    if not position.within(parcelle.box):
                        position = parcelle.box.centroid
                    fixme.append(
                        u"position à preciser, parcelle associée: n°" +
                        num_parcelle)
                    angle = None
                node = osm_add_point(osm, position, transform)
                node.angle = angle
                if hasattr(parcelle, 'limite'):
                    node.limite_parcelle = parcelle.limite
                else:
                    node.limite_parcelle = None
                node.tags['addr:housenumber'] = num
                node.tags['source'] = SOURCE_TAG
                rues = [
                    addr[len(num) + 1:].strip()
                    for addr in parcelle.addrs_numeros[num]
                ]
                for rue in rues:
                    if not associatedStreets.has_key(rue):
                        rel = Relation({})
                        rel.tags['type'] = 'associatedStreet'
                        rel.tags['name'] = rue
                        osm.add_relation(rel)
                        associatedStreets[rue] = rel
                    associatedStreets[rue].add_member(node, 'house')
                if len(rues) > 1:
                    fixme.append(u"choisir la bonne rue: " + " ou ".join(rues))
                if hasattr(parcelle, 'limite') and parcelle.limite != None:
                    limite = parcelle.limite
                else:
                    limite = parcelle.box
                distance = position.distance(limite)
                if distance > 10:
                    fixme.append(
                        str(int(distance)) + u" m de la parcelle n°" +
                        num_parcelle +
                        u": vérifier la position et/ou la rue associée")
                    fixme.reverse()
                if fixme:
                    node.tags['fixme'] = " et ".join(fixme)

    # Cherche les nom de lieus: toutes les adresse sans numéro qui ne sont pas des nom de rue:
    positions_des_lieus = {}
    for parcelle in parcelles.itervalues():
        for addr in parcelle.adresses:
            numero_match = RE_NUMERO_CADASTRE.match(addr)
            if addr and (not numero_match) and (
                    not associatedStreets.has_key(addr)):
                if not positions_des_lieus.has_key(addr):
                    positions_des_lieus[addr] = []
                if hasattr(parcelle, 'limite') and parcelle.limite != None:
                    centroid = parcelle.limite.centroid
                    if centroid.wkt == 'GEOMETRYCOLLECTION EMPTY':
                        # Pour la ville de Kingersheim (68), il existe une limite de parcelle
                        # aplatie (sur une ligne, donc d'area nulle) ce qui lui donne
                        # un centroid vide.
                        # On utilise alors le centre des points composant sa limite exteieur
                        centroid = parcelle.limite.exterior.centroid
                    positions_des_lieus[addr].append(centroid)
                else:
                    positions_des_lieus[addr].append(parcelle.box.centroid)
    for lieu, positions in positions_des_lieus.iteritems():
        centre = MultiPoint(positions).centroid
        node = osm_add_point(osm, centre, transform)
        node.tags['name'] = lieu
        node.tags['source'] = SOURCE_TAG
        if lieu.lower().startswith("hameau "):
            node.tags['place'] = 'hamlet'
        else:
            node.tags['place'] = 'neighbourhood'
        node.tags[
            'fixme'] = u"à vérifier: lieu créé automatiquement à partir des adresses du coin"
    return osm