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, "")
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, "")
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, "")
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
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
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
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)