def test_merge_address(self): address = osm.Osm() address.Node(0, 0, { "ref": "1", "addr:street": "address1", "image": "foo" }) address.Node( 2, 0, { "ref": "2", "addr:street": "address2", "entrance": "yes", "image": "bar" }, ) address.Node(4, 0, { "ref": "3", "addr:street": "address3", "entrance": "yes" }) address.Node(6, 0, { "ref": "4", "addr:place": "address5", "entrance": "yes" }) building = osm.Osm() w0 = building.Way([], {"ref": "0"}) # building with ref not in address # no entrance address, tags to way w1 = building.Way([(0, 0), (1, 0), (1, 1), (0, 0)], {"ref": "1"}) # entrance exists, tags to node n2 = building.Node(2, 0) building.Way([n2, (3, 0), (3, 1), (2, 0)], {"ref": "2"}) # entrance don't exists, tags to way w3 = building.Way([(4, 1), (5, 0), (5, 1), (4, 1)], {"ref": "3"}) # entrance exists, tags to node in relation n5 = building.Node(6, 0) w6 = building.Way([(6, 5), (9, 5), (9, 8), (6, 8), (6, 5)]) w7 = building.Way([n5, (9, 0), (9, 3), (6, 3), (6, 0)]) w8 = building.Way([(7, 1), (8, 1), (8, 2), (7, 2), (7, 1)]) r1 = building.Relation(tags={"ref": "4"}) r1.append(w6, "outer") r1.append(w7, "outer") r1.append(w8, "inner") self.m_app.merge_address = get_func(app.CatAtom2Osm.merge_address) self.m_app.merge_address(self.m_app, building, address) self.assertNotIn("addrtags", w0.tags) self.assertEqual(w1.tags["addr:street"], "address1") self.assertNotIn("image", w1.tags) self.assertEqual(n2.tags["addr:street"], "address2") self.assertNotIn("image", n2.tags) self.assertEqual(w3.tags["addr:street"], "address3") self.assertNotIn("addr:street", [k for n in w3.nodes for k in list(n.tags.keys())]) self.assertEqual(n5.tags["addr:place"], "address5") address.tags["source:date"] = "foobar" self.m_app.merge_address(self.m_app, building, address) self.assertEqual(building.tags["source:date:addr"], address.tags["source:date"])
def test_clone(self): w1 = self.d.Way([(0, 0), (1, 3), (1, 1), (0, 0)], tags={"name": "w1"}) w2 = self.d.Way([(0, 0), (3, 2), (1, 2), (0, 0)], tags={"name": "w2"}) r = self.d.Relation(members=[w1, w2]) d2 = osm.Osm() r.copyto(d2) self.assertEqual(d2.get(r.fid), r) self.assertEqual(len(self.d.elements), len(d2.elements))
def test_serialize(self): data = osm.Osm() n = data.Node(4, 0) n.tags["entrance"] = "yes" n.tags["addr:street"] = "Calle la Ñ" n.tags["addr:housenumber"] = "7" w = data.Way([(12, 0), (14, 0), (14, 2), (12, 2), (12, 0)]) w.tags["leisure"] = "swiming_pool" mp1 = [(0, 0), (10, 0), (10, 6), (0, 6), (0, 0)] mp2 = [(8, 1), (9, 1), (9, 2), (8, 2), (8, 1)] r = data.MultiPolygon([[mp1, mp2]]) r.tags["building"] = "residential" fo = StringIO() osmxml.serialize(fo, data) result = bytes(fo.getvalue().encode("utf-8")) root = etree.fromstring(result) for (xmlnode, osmnode) in zip(root.findall("node"), data.nodes): self.assertEqual(float(xmlnode.get("lon")), osmnode.x) self.assertEqual(float(xmlnode.get("lat")), osmnode.y) for (xmltag, osmtag) in zip(root.findall("node/tag"), n.tags.items()): self.assertEqual(xmltag.get("k"), osmtag[0]) self.assertEqual(xmltag.get("v"), osmtag[1]) nw = 0 for (xmlway, osmway) in zip(root.findall("way"), data.ways): nw += 1 for (xmlnd, osmnd) in zip(xmlway.findall("nd"), osmway.nodes): self.assertEqual(int(xmlnd.get("ref")), osmnd.id) self.assertEqual(nw, 3) for (xmltag, osmtag) in zip(root.findall("way/tag"), w.tags.items()): self.assertEqual(xmltag.get("k"), osmtag[0]) self.assertEqual(xmltag.get("v"), osmtag[1]) for (i, (xmlm, osmm)) in enumerate( zip(root.findall("relation/member"), r.members)): self.assertEqual(int(xmlm.get("ref")), osmm.ref) self.assertEqual(xmlm.get("role"), "outer" if i == 0 else "inner") for (xmltag, osmtag) in zip(root.findall("relation/tag"), r.tags.items()): self.assertEqual(xmltag.get("k"), osmtag[0]) self.assertEqual(xmltag.get("v"), osmtag[1]) self.assertEqual(sum([1 for r in root.findall("relation")]), 1) self.assertEqual(root.find("note"), None) self.assertEqual(root.find("meta"), None) data.note = "foobar" data.meta = {"foo": "bar"} data.tags["type"] = "import" fo = StringIO() osmxml.serialize(fo, data) result = bytes(fo.getvalue().encode("utf-8")) root = etree.fromstring(result) self.assertEqual(root.find("note").text, "foobar") self.assertEqual(root.find("meta").get("foo"), "bar") for (xmltag, osmtag) in zip(root.findall("changeset/tag"), data.tags.items()): self.assertEqual(xmltag.get("k"), osmtag[0]) self.assertEqual(xmltag.get("v"), osmtag[1])
def test_replace(self): n1 = self.d.Node(1, 1) d2 = osm.Osm() n2 = d2.Node(2, 2) p = self.d.parents[n1] self.d.replace(n1, n2) self.assertNotIn(n1, self.d.elements) self.assertIn(n2, self.d.elements) self.assertEqual(n2.container, self.d) self.assertEqual(self.d.get(n2.id), n2) self.assertEqual(self.d.parents[n2], p)
def test_address_stats(self): ad = osm.Osm() ad.Node(0, 0, {"addr:street": "s1"}) ad.Node(2, 0, {"addr:street": "s2", "entrance": "yes"}) ad.Node(4, 0, {"addr:place": "p1", "entrance": "yes"}) ad.Way([], {"addr:street": "s3"}) r = report.Report() r.address_stats(ad) self.assertEqual(r.out_addr_str, 3) self.assertEqual(r.out_addr_plc, 1) self.assertEqual(r.out_address_entrance, 2) self.assertEqual(r.out_address_parcel, 2)
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_clone(self): # * (1,3) * n2 (2,3) # w1 w2 * (3,2) # * (1,1) * n1 (2,1) n1 = self.d.Node(2, 1, tags={"name": "n1"}) n2 = self.d.Node(2, 3, tags={"name": "n2"}) w1 = self.d.Way([n1, n2, (1, 3), (1, 1), n1], tags={"name": "w1"}) w2 = self.d.Way([n1, (3, 2), n2, n1], tags={"name": "w2"}) d2 = osm.Osm() w1.copyto(d2) w2.copyto(d2) self.assertEqual(len(d2.elements), len(self.d.elements)) self.assertEqual(d2.get(w1.fid), w1) self.assertEqual(d2.get(w2.fid), w2)
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 test_get_current_ad_osm(self, m_report, m_log): d = osm.Osm() d.Node(0, 0, {"addr:housenumber": "12", "addr:street": "foobar"}) d.Node(1, 1, {"addr:housenumber": "14", "addr:street": "foobar"}) d.Node(2, 2, {"addr:housenumber": "10", "addr:place": "bartaz"}) self.m_app.get_current_ad_osm = get_func( app.CatAtom2Osm.get_current_ad_osm) self.m_app.read_osm.return_value = d address = self.m_app.get_current_ad_osm(self.m_app) self.assertEqual(address, set(["foobar14", "foobar12", "bartaz10"])) self.assertNotIn("osm_addresses_whithout_number", m_report) d.Node(3, 3, {"addr:street": "x"}) d.Node(4, 4, {"addr:place": "y"}) self.m_app.read_osm.return_value = d address = self.m_app.get_current_ad_osm(self.m_app) self.assertEqual(m_report.osm_addresses_without_number, 2)
def test_append_node(self): def query(el): return "building" in el.tags n1 = self.d.Node(2, 2, tags=dict(highway="residential")) n2 = self.d.Node(1, 1, tags=dict(building="yes"), attrs=dict(user="******")) d2 = osm.Osm() d2.append(n1, query) self.assertEqual(len(d2.elements), 0) # n1 is ignored due to query d2.append(n2, query) self.assertEqual(len(d2.elements), 1) # n2.id is copied self.assertEqual(d2.get(n2.id), n2) # with all tags and attrs d2.append(n2) self.assertEqual(len(d2.elements), 1) # don't insert repeated
def test_cons_stats(self): r = report.Report() r.building_counter = Counter() data = osm.Osm() data.Node(0, 0, {"leisure": "swimming_pool"}) data.Node(0, 0, {"building": "a", "fixme": "f1"}) data.Node(0, 0, {"building": "b", "fixme": "f2"}) data.Node(0, 0, {"building:part": "yes", "fixme": "f2"}) data.Node(0, 0) r.cons_stats(data) self.assertEqual(r.out_pools, 1) self.assertEqual(r.out_buildings, 2) self.assertEqual(r.out_parts, 1) self.assertEqual(r.building_counter["a"], 1) self.assertEqual(r.building_counter["b"], 1) self.assertEqual(r.fixme_counter["f1"], 1) self.assertEqual(r.fixme_counter["f2"], 2)
def test_write_osm(self, m_gz, m_io, m_codecs, m_xml): m_xml.serialize.return_value = "taz" data = osm.Osm() data.Node(0, 0, {"ref": "1"}) data.Node(1, 1, {"ref": "2"}) data.Node(2, 2) self.m_app.write_osm = get_func(app.CatAtom2Osm.write_osm) self.m_app.write_osm(self.m_app, data, "bar") self.assertNotIn( "ref", [k for el in data.elements for k in list(el.tags.keys())]) m_io.open.assert_called_once_with("33333/bar", "w", encoding="utf-8") file_obj = m_io.open.return_value m_xml.serialize.assert_called_once_with(file_obj, data) m_xml.reset_mock() self.m_app.write_osm(self.m_app, data, "bar.gz") m_gz.open.assert_called_once_with("33333/bar.gz", "w") f_gz = m_gz.open.return_value m_codecs.getwriter.return_value.assert_called_once_with(f_gz)
def test_to_osm(self): self.layer.append(self.address_gml) self.layer.join_field(self.tn_gml, "TN_id", "gml_id", ["text"], "TN_") self.layer.join_field(self.au_gml, "AU_id", "gml_id", ["text"], "AU_") self.layer.join_field(self.pd_gml, "PD_id", "gml_id", ["postCode"]) self.layer.source_date = "foobar" data = osm.Osm(upload="ifyoudare") data.Node(0, 0) data = self.layer.to_osm(data=data) self.assertEqual(data.upload, "ifyoudare") self.assertEqual(data.tags["source:date"], "foobar") self.assertEqual(len(data.elements), self.layer.featureCount() + 1) address = { n.tags["ref"]: n.tags["addr:street"] + n.tags["addr:housenumber"] for n in data.nodes if "ref" in n.tags } for feat in self.layer.getFeatures(): t = address[feat["localId"].split(".")[-1]] self.assertEqual(feat["TN_text"] + feat["designator"], t)
def test_read_from_osm(self): layer = HighwayLayer() data = osm.Osm() data.Way(((10, 10), (15, 15)), {"name": "FooBar"}) w2 = data.Way(((20, 20), (30, 30))) data.Relation([w2], {"name": "BarTaz"}) layer.read_from_osm(data) self.assertEqual(layer.featureCount(), 2) names = [feat["name"] for feat in layer.getFeatures()] self.assertIn("BarTaz", names) self.assertIn("FooBar", names) for f in layer.getFeatures(): if f["name"] == "FooBar": self.assertEqual( f.geometry().asPolyline(), [Point(10, 10), Point(15, 15)] ) if f["name"] == "BarTaz": self.assertEqual( f.geometry().asPolyline(), [Point(20, 20), Point(30, 30)] )
def setUp(self): self.d = osm.Osm()
def to_osm( self, tags_translation=translate.all_tags, data=None, tags={}, upload="never", ): """ Export this layer to an Osm data set. Args: tags_translation (function): Function to translate fields to tags. By defaults convert all fields. data (Osm): OSM data set to append. By default creates a new one. upload (str): upload attribute of the osm dataset, default 'never' tags (dict): tags to update config.changeset_tags Returns: Osm: OSM data set """ if data is None: generator = config.app_name + " " + config.app_version data = osm.Osm(upload, generator=generator) nodes = ways = relations = 0 else: nodes = len(data.nodes) ways = len(data.ways) relations = len(data.relations) for feature in self.getFeatures(): geom = feature.geometry() e = None if geom.wkbType() == WKBPoint: e = data.Node(geom.asPoint()) elif geom.wkbType() in [WKBPolygon, WKBMultiPolygon]: mp = Geometry.get_multipolygon(geom) if len(mp) == 1: if len(mp[0]) == 1: e = data.Way(mp[0][0]) else: e = data.Polygon(mp[0]) else: e = data.MultiPolygon(mp) else: msg = _("Detected a %s geometry in the '%s' layer") % ( QgsWkbTypes.displayString(geom.wkbType()), self.name(), ) log.warning(msg) report.warnings.append(msg) if e: e.tags.update(tags_translation(feature)) changeset_tags = dict(config.changeset_tags, **tags) for (key, value) in changeset_tags.items(): data.tags[key] = value if getattr(self, "source_date", False): data.tags["source:date"] = self.source_date log.debug( _("Loaded %d nodes, %d ways, %d relations from '%s' layer"), len(data.nodes) - nodes, len(data.ways) - ways, len(data.relations) - relations, self.name(), ) return data
def test_clone(self): n = self.d.Node(1, 1, tags=dict(foo="bar"), attrs=dict(user="******")) d2 = osm.Osm() n.copyto(d2) self.assertEqual(d2.get(n.id), n) self.assertEqual(len(self.d.elements), len(d2.elements))
def test_conflate(self): self.layer.reproject() d = osm.Osm() d.Way( ( (-16.44211325828, 28.23715394977), (-16.44208978895, 28.23714124855), (-16.44209884141, 28.23712884271), (-16.44212197546, 28.23714361157), (-16.44211325828, 28.23715394977), ), dict(building="yes", ref="1"), ) d.Way( ( (-16.44016295806, 28.23657619128), (-16.43985450402, 28.23641077902), (-16.43991753593, 28.23632689127), (-16.44020855561, 28.23648403305), (-16.44016295806, 28.23657619128), ), dict(building="yes", ref="2"), ) d.Way( ( (-16.44051231511, 28.23655551417), (-16.44042112, 28.23650529975), (-16.4405699826, 28.23631153095), (-16.44065782495, 28.23635288407), (-16.44051231511, 28.23655551417), ), dict(building="yes", ref="3"), ) self.assertEqual(len(d.ways), 3) self.layer.conflate(d, delete=False) self.assertEqual(len(d.ways), 3) for el in d.ways: self.assertEqual("conflict" in el.tags, el.tags["ref"] == "3") d.Way( ( (-16.44038491018, 28.23645095), (-16.44029706784, 28.23640132629), (-16.44042514332, 28.23624713819), (-16.44049689241, 28.23629558045), (-16.44038491018, 28.23645095), ), dict(building="yes", ref="4"), ) d.Way( ( (-16.44019514591, 28.23634461522), (-16.44002616674, 28.23625009376), (-16.44011199743, 28.23611540052), (-16.44027829438, 28.23619810692), ), dict(building="yes", ref="5"), ) d.Way( ( (-16.43993497163, 28.23591926797), (-16.43972575933, 28.23580584175), (-16.4398062256, 28.23610122228), (-16.43959701329, 28.23598543321), (-16.43993497163, 28.23591926797), ), dict(building="yes", ref="6"), ) d.Way( ( (-16.4386775, 28.2360472), (-16.4386158, 28.2363235), (-16.4384536, 28.2362954), (-16.4385153, 28.2360191), (-16.4386775, 28.2360472), ), dict(building="yes", ref="7"), ) d.Way( ( (-16.4386049, 28.2357006), (-16.4385316, 28.2356401), (-16.4385093, 28.2356419), (-16.4384993, 28.2357054), (-16.4386049, 28.2357006), ), dict(building="yes", ref="8"), ) w0 = d.Way(( (-16.4409784, 28.2365733), (-16.4409231, 28.236542), (-16.4409179, 28.2365154), (-16.4409268, 28.236504), (-16.4408588, 28.236465), )) w1 = d.Way(((-16.4406755, 28.236688), (-16.4408332, 28.2367735))) w2 = d.Way(( (-16.4408332, 28.2367735), (-16.4408943, 28.2366893), (-16.4409395, 28.2367147), (-16.4409818, 28.2366563), (-16.4409366, 28.2366308), (-16.4409784, 28.2365733), )) w3 = d.Way(( (-16.4408588, 28.236465), (-16.4408086, 28.2365319), (-16.4407037, 28.2364709), (-16.4406669, 28.2365102), (-16.4406513, 28.2365338), (-16.440639, 28.2365663), (-16.4407394, 28.2366223), (-16.4407188, 28.2366474), (-16.440707, 28.2366405), (-16.4406755, 28.236688), )) w4 = d.Way(( (-16.440072, 28.236560), (-16.439966, 28.236505), (-16.439888, 28.236605), (-16.4399860, 28.236666), (-16.440072, 28.236560), )) w5 = d.Way(( (-16.439965, 28.236703), (-16.439861, 28.236642), (-16.439805, 28.236733), (-16.439903, 28.236790), (-16.439965, 28.236703), )) r1 = d.Relation(tags=dict(building="yes", ref="9")) r1.append(w0, "outer") r1.append(w1, "outer") r1.append(w2, "outer") r1.append(w3, "outer") r2 = d.Relation(tags=dict(building="yes", ref="10")) r2.append(w4, "outer") r2.append(w5, "outer") self.assertEqual(len(d.ways), 14) self.assertEqual(len(d.relations), 2) self.layer.conflate(d) self.assertEqual(len(d.ways), 12) self.assertEqual(len(d.relations), 2) self.assertEqual( {e.tags["ref"] for e in d.ways if "ref" in e.tags}, {"3", "4", "5", "6", "7", "8"}, )