From 140a9ed598b2e1eaa521135ed8612a4e0a98fea4 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Fri, 14 May 2021 17:09:56 +0200 Subject: [PATCH] Show address nodes for buildings --- static/js/map.js | 9 +++++- web_view.py | 77 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/static/js/map.js b/static/js/map.js index b118cea..e9b5b1e 100644 --- a/static/js/map.js +++ b/static/js/map.js @@ -453,7 +453,14 @@ function mouse_events(marker, qid) { osm_html += osm.name; } if (!osm.presets.length && !osm.name) { - osm_html += "no name"; + osm_html += " no name"; + } + if (osm.address_list && osm.address_list.length) { + if (osm.address_list.length == 1) { + osm_html += " address node: " + osm.address_list[0]; + } else { + osm_html += " address nodes: " + osm.address_list.join("; ") + } } osm_html += ` ` osm_html += '
'; diff --git a/web_view.py b/web_view.py index 481cdcc..9e4a61f 100755 --- a/web_view.py +++ b/web_view.py @@ -812,34 +812,63 @@ def get_nearby(bbox, item, max_distance=200): return nearby[:10] -def get_presets_from_tags(tags): +def find_preset_file(k, v, ending): preset_dir = app.config["ID_PRESET_DIR"] + + filename = os.path.join(preset_dir, k, v + ".json") + if os.path.exists(filename): + return {"tag_or_key": f"Tag:{k}={v}", "filename": filename} + + filename = os.path.join(preset_dir, k, f"{v}_{ending}.json") + if os.path.exists(filename): + return {"tag_or_key": f"Tag:{k}={v}", "filename": filename} + + filename = os.path.join(preset_dir, k, "_" + v + ".json") + if os.path.exists(filename): + return {"tag_or_key": f"Tag:{k}={v}", "filename": filename} + + filename = os.path.join(preset_dir, k + ".json") + if os.path.exists(filename): + return {"tag_or_key": f"Key:{k}", "filename": filename} + + +def get_presets_from_tags(osm): found = [] - for k, v in tags.items(): - if k == 'amenity' and v == 'clock' and tags.get('display') == 'sundial': + ending = { + model.Point: "point", + model.Line: "line", + model.Polygon: "area" + }[type(osm)] + for k, v in osm.tags.items(): + if k == 'amenity' and v == 'clock' and osm.tags.get('display') == 'sundial': tag_or_key = f"Tag:{k}={v}" found.append({"tag_or_key": tag_or_key, "name": "Sundial"}) continue - filename = os.path.join(preset_dir, k, v + ".json") - if os.path.exists(filename): - tag_or_key = f"Tag:{k}={v}" - else: - filename = os.path.join(preset_dir, k, "_" + v + ".json") - if os.path.exists(filename): - tag_or_key = f"Tag:{k}={v}" - else: - filename = os.path.join(preset_dir, k + ".json") - if os.path.exists(filename): - tag_or_key = f"Key:{k}" - else: - continue - data = json.load(open(filename)) - name = data["name"] - found.append({"tag_or_key": tag_or_key, "name": name}) + match = find_preset_file(k, v, ending) + if not match: + continue + + match["name"] = json.load(open(match.pop("filename")))["name"] + found.append(match) return found +def get_address_nodes_within_building(building, bbox): + db_bbox = make_envelope(bbox) + ewkt = building.as_EWKT + q = model.Point.query.filter( + func.ST_Intersects(db_bbox, model.Point.way), + func.ST_Covers(func.ST_GeomFromEWKT(ewkt), model.Point.way), + model.Point.tags.has_key("addr:street"), + model.Point.tags.has_key("addr:housenumber"), + ) + + return [node.tags for node in q] + +def address_from_tags(tags): + return " ".join(tags["addr:" + k] for k in ("street", "housenumber")) + @app.route("/api/1/item/Q/candidates") def api_find_osm_candidates(item_id): @@ -852,15 +881,21 @@ def api_find_osm_candidates(item_id): tags = osm.tags name = osm.name or tags.get("addr:housename") if not name and "addr:housenumber" in tags and "addr:street" in tags: - name = tags["addr:housenumber"] + " " + tags["addr:street"] + name = address_from_tags(tags) + if isinstance(osm, model.Polygon) and "building" in osm.tags: + address_nodes = get_address_nodes_within_building(osm, bounds) + address_list = [address_from_tags(addr) for addr in address_nodes] + else: + address_list = [] cur = { "identifier": osm.identifier, "distance": dist, "name": name, "tags": tags, "geojson": osm.geojson(), - "presets": get_presets_from_tags(tags), + "presets": get_presets_from_tags(osm), + "address_list": address_list, } if hasattr(osm, 'area'): cur["area"] = osm.area