Exemple #1
0
    def test_append_highway(self):
        def query(el):
            return "highway" in el.tags or el.tags.get("place") == "square"

        with open("test/fixtures/current.osm", "rb") as fo:
            d1 = osmxml.deserialize(fo)
        d2 = osm.Osm()
        d2.append(d1, query)
        self.assertEqual(len(d2.nodes), 15)
        self.assertEqual(len(d2.ways), 3)
        for el in d2.ways:
            tag = el.tags.get("highway", el.tags.get("place", ""))
            self.assertNotEqual(tag, "")
Exemple #2
0
    def test_append_addr(self):
        def query(el):
            return "addr:street" in el.tags or "addr:place" in el.tags

        with open("test/fixtures/current.osm", "rb") as fo:
            d1 = osmxml.deserialize(fo)
        d2 = osm.Osm()
        d2.append(d1, query)
        self.assertEqual(len(d2.nodes), 6)
        self.assertEqual(len(d2.ways), 1)
        for el in d2.elements:
            if el not in list(d2.parents.keys()):
                tag = el.tags.get("addr:street", el.tags.get("addr:place", ""))
                self.assertNotEqual(tag, "")
Exemple #3
0
    def test_append_building(self):
        def query(el):
            return "building" in el.tags or el.tags.get(
                "leisure") == "swimming_pool"

        with open("test/fixtures/current.osm", "rb") as fo:
            d1 = osmxml.deserialize(fo)
        d2 = osm.Osm()
        d2.append(d1, query)
        self.assertEqual(len(d2.nodes), 27)
        self.assertEqual(len(d2.ways), 5)
        for el in d2.elements:
            if el not in list(d2.parents.keys()):
                tag = el.tags.get("building", el.tags.get("leisure", ""))
                self.assertNotEqual(tag, "")
Exemple #4
0
    def read_osm(self, *paths, **kwargs):
        """
        Read an OSM data set from an OSM XML file.

        If the file not exists, downloads data from overpass using ql query.

        Args:
            paths (str): input filename components relative to self.path
            ql (str): Query to put in the url for overpass

        Returns
            Osm: OSM data set
        """
        ql = kwargs.get("ql", False)
        osm_path = self.cat.get_path(*paths)
        filename = os.path.basename(osm_path)
        if not os.path.exists(osm_path):
            if not ql:
                return None
            log.info(_("Downloading '%s'") % filename)
            query = overpass.Query(self.boundary_search_area)
            if hasattr(self, "boundary_bbox") and self.boundary_bbox:
                query.set_search_area(self.boundary_bbox)
            query.add(ql)
            if log.app_level == logging.DEBUG:
                query.download(osm_path, log)
            else:
                query.download(osm_path)
        if osm_path.endswith(".gz"):
            fo = gzip.open(osm_path, "rb")
        else:
            fo = open(osm_path, "rb")
        data = osmxml.deserialize(fo)
        fo.close()
        if len(data.elements) == 0:
            msg = _("No OSM data were obtained from '%s'") % filename
            log.warning(msg)
            report.warnings.append(msg)
        else:
            log.info(
                _("Read '%s': %d nodes, %d ways, %d relations"),
                filename,
                len(data.nodes),
                len(data.ways),
                len(data.relations),
            )
        return data
Exemple #5
0
def get_districts(code):
    id, name = get_municipality(code)
    query = overpass.Query(id)
    query.add('wr["boundary"="administrative"]["admin_level"="9"]')
    query.add('wr["boundary"="administrative"]["admin_level"="10"]')
    result = query.read()
    with io.BytesIO(result) as fo:
        data = osmxml.deserialize(fo)
    district = {}
    subarea = []
    ward = []
    for e in data.elements:
        if e.tags.get("boundary", "") == "administrative":
            if e.type == "relation":
                if e.tags.get("admin_level", "") == "9":
                    id = e.id
                    district[id] = {"boundary": e, "subarea": []}
                    for m in e.members:
                        if m.role == "subarea":
                            district[id]["subarea"].append(m.element)
                            subarea.append(m.element.id)
                            if m.element in ward:
                                ward.remove(m.element)
                elif e.tags.get("admin_level",
                                "") == "10" and e.id not in subarea:
                    ward.append(e)
            elif e.type == "way" and e.is_closed():
                if e.tags.get("admin_level", "") == "9":
                    district[e.id] = {"boundary": e}
                elif e.tags.get("admin_level", "") == "10":
                    ward.append(e)
    by_name_dist = lambda d: d["boundary"].tags.get("name", "")
    by_name_ward = lambda w: w.tags.get("name", "")
    districts = []
    for d in sorted(district.values(), key=by_name_dist):
        e = d["boundary"]
        districts.append(
            (False, str(e.id), _("District"), e.tags.get("name", "")))
        for m in sorted(d["subarea"], key=by_name_ward):
            districts.append(
                (True, str(m.id), _("Ward"), m.tags.get("name", "")))
    for w in sorted(ward, key=by_name_ward):
        districts.append((False, str(w.id), _("Ward"), w.tags.get("name", "")))
    return districts
Exemple #6
0
def get_boundary(cat_path, boundary_search_area, id_or_name):
    query = overpass.Query(boundary_search_area)
    if re.search(r"^[0-9]+$", id_or_name):
        query.add(f"wr({id_or_name})")
    else:
        query.add(f'wr["boundary"="administrative"]["name"="{id_or_name}"]')
    result = query.read()
    with io.BytesIO(result) as fo:
        data = osmxml.deserialize(fo)
    fn = id_or_name
    for e in data.elements:
        if e.type == "relation" or (e.type == "way" and e.is_closed()):
            if e.tags.get("boundary", "") == "administrative":
                fn = e.tags.get("name", fn)
                break
    fn = os.path.join(cat_path, fn.replace(" ", "_") + ".osm")
    with open(fn, "wb") as fo:
        fo.write(result)
    fn += "|layername=multipolygons"
    return fn
Exemple #7
0
 def test_deserialize(self):
     attrs = dict(upload="1", version="2", generator="3")
     root = etree.Element("osm", attrs)
     nodexml = etree.Element("node", dict(id="-1", lon="4", lat="0"))
     nodexml.append(etree.Element("tag", dict(k="entrance", v="yes")))
     nodexml.append(
         etree.Element("tag", dict(k="addr:street", v="Calle la Ñ")))
     nodexml.append(etree.Element("tag", dict(k="addr:housenumber", v="7")))
     root.append(nodexml)
     wayxml = etree.Element("way", dict(id="-100"))
     for (i, node) in enumerate([(12, 0), (14, 0), (14, 2), (12, 2),
                                 (12, 0)]):
         nodexml = etree.Element(
             "node",
             dict(id=str(-i - 10), lon=str(node[0]), lat=str(node[1])))
         root.append(nodexml)
         wayxml.append(etree.Element("nd",
                                     dict(ref=str(nodexml.get("id")))))
     wayxml.append(etree.Element("tag", dict(k="leisure",
                                             v="swiming_pool")))
     root.append(wayxml)
     wayxml = etree.Element("way", dict(id="-101"))
     for (i, node) in enumerate([(0, 0), (10, 0), (10, 6), (0, 6), (0, 0)]):
         nodexml = etree.Element(
             "node",
             dict(id=str(-i - 20), lon=str(node[0]), lat=str(node[1])))
         root.append(nodexml)
         wayxml.append(etree.Element("nd",
                                     dict(ref=str(nodexml.get("id")))))
     root.append(wayxml)
     wayxml = etree.Element("way", dict(id="-102"))
     for (i, node) in enumerate([(8, 1), (9, 1), (9, 2), (8, 2), (8, 1)]):
         nodexml = etree.Element(
             "node",
             dict(id=str(-i - 30), lon=str(node[0]), lat=str(node[1])))
         root.append(nodexml)
         wayxml.append(etree.Element("nd",
                                     dict(ref=str(nodexml.get("id")))))
     root.append(wayxml)
     relxml = etree.Element("relation", dict(id="-200"))
     relxml.append(
         etree.Element("member", dict(type="way", ref="-101",
                                      role="outter")))
     relxml.append(
         etree.Element("member", dict(type="way", ref="-102",
                                      role="inner")))
     relxml.append(
         etree.Element("member", dict(type="relation", ref="-201")))
     relxml.append(etree.Element("tag", dict(k="building",
                                             v="residential")))
     root.append(relxml)
     relxml = etree.Element("relation", dict(id="-201"))
     relxml.append(etree.Element("tag", dict(k="test",
                                             v="nested relation")))
     relxml.append(
         etree.Element("member", dict(type="way", ref="-101",
                                      role="dummy")))
     root.append(relxml)
     root.append(etree.Element("dummy"))
     fo = BytesIO(etree.tostring(root))
     result = osmxml.deserialize(fo)
     self.assertEqual(result.upload, "1")
     self.assertEqual(result.version, "2")
     self.assertEqual(result.generator, "3")
     self.assertEqual(len(result.nodes), 16)
     for osmnode in result.nodes:
         xmlnode = root.find("node[@id='%d']" % osmnode.id)
         self.assertEqual(float(xmlnode.get("lon")), osmnode.x)
         self.assertEqual(float(xmlnode.get("lat")), osmnode.y)
     n = result.get("-1")
     self.assertEqual(n.tags["entrance"], "yes")
     self.assertEqual(n.tags["addr:street"], "Calle la Ñ")
     self.assertEqual(n.tags["addr:housenumber"], "7")
     self.assertEqual(len(result.ways), 3)
     for osmway in result.ways:
         xmlway = root.find("way[@id='%d']" % osmway.id)
         for nd in xmlway.findall("nd"):
             self.assertIn(nd.get("ref"), [str(w.id) for w in osmway.nodes])
     w = result.get("-100", "w")
     self.assertEqual(w.tags["leisure"], "swiming_pool")
     self.assertEqual(len(result.relations), 2)
     osmrel = result.get(-200, "r")
     xmlrel = root.find("relation[@id='%d']" % osmrel.id)
     roles = []
     for m in xmlrel.findall("member"):
         self.assertIn(m.get("ref"), [str(x.ref) for x in osmrel.members])
         roles.append(m.get("role"))
     self.assertEqual(roles, ["outter", "inner", None])
     r = result.get(-200, "r")
     self.assertEqual(r.tags["building"], "residential")
     nxml = etree.Element("note")
     nxml.text = "foobar"
     root.append(nxml)
     mxml = etree.Element("meta")
     mxml.set("foo", "bar")
     root.append(mxml)
     csxml = etree.Element("changeset")
     csxml.append(etree.Element("tag", dict(k="type", v="import")))
     root.append(csxml)
     fo = BytesIO(etree.tostring(root))
     result = osmxml.deserialize(fo)
     self.assertEqual(result.tags, dict(type="import"))
     self.assertEqual(result.note, "foobar")
     self.assertEqual(result.meta, dict(foo="bar"))
     root = etree.Element("osm")
     nodexml = etree.Element("node", dict(id="-50", lon="0", lat="4"))
     root.append(nodexml)
     fo = BytesIO(etree.tostring(root))
     result = osmxml.deserialize(fo, result)
     self.assertEqual(len(result.nodes), 17)
     root = etree.Element("osm")
     wayxml = etree.Element("way", dict(id="-103", version="1"))
     wayxml.append(etree.Element("nd", dict(ref="-99")))
     root.append(wayxml)
     relxml = etree.Element("relation", dict(id="-202"))
     relxml.append(
         etree.Element("member", dict(type="way", ref="-199",
                                      role="dummy")))
     root.append(relxml)
     fo = BytesIO(etree.tostring(root))
     result = osmxml.deserialize(fo, result)
     self.assertEqual(len(result.nodes), 17)
     self.assertEqual(len(result.ways), 4)
     self.assertEqual(len(result.relations), 3)
     self.assertEqual(result.get(-103, "w").version, "2")
     self.assertEqual(result.get(-202, "r").version, None)