From 77c2c69c449c8a1bc31666a56fa2cd09ff8307a4 Mon Sep 17 00:00:00 2001
From: Edward Betts <edward@4angle.com>
Date: Wed, 12 May 2021 09:27:34 +0200
Subject: [PATCH] Show OSM search tags/keys

---
 static/js/map.js | 22 ++++++++++++++++++----
 web_view.py      | 29 +++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/static/js/map.js b/static/js/map.js
index b4c02a3..0da2585 100644
--- a/static/js/map.js
+++ b/static/js/map.js
@@ -259,7 +259,7 @@ function set_isa_list(isa_count_list) {
   });
 }
 
-function build_item_detail(item) {
+function build_item_detail(item, tag_or_key_list) {
   var wd_url = "https://www.wikidata.org/wiki/" + item.qid;
 
   var popup = "<p><strong>Wikidata item</strong><br>";
@@ -275,12 +275,22 @@ function build_item_detail(item) {
       popup += `<br><a href="${isa_url}" target="_blank">${isa_label}</a> (${isa_qid})`;
     }
   }
+
+  if (tag_or_key_list && tag_or_key_list.length) {
+    popup += "<br><strong>OSM tags/keys to search for</strong>"
+    for (const v of tag_or_key_list) {
+      popup += `<br>${v}`;
+    }
+  }
+
   if (item.image_list && item.image_list.length) {
     popup += `<br><img class="w-100" src="/commons/${item.image_list[0]}">`;
   }
   if (item.street_address && item.street_address.length) {
-    popup += `<br><strong>street address</strong><br>${item.street_address[0]["text"]}`;
+    popup += "<br><strong>street address</strong>"
+    popup += `<br>${item.street_address[0]["text"]}`;
   }
+
   popup += "</p>";
 
   return popup;
@@ -326,8 +336,12 @@ function mouse_events(marker, qid) {
       detail_card.classList.remove("bg-highlight");
     }, 500);
 
-    var item_detail = build_item_detail(items[qid].wikidata);
-    detail.innerHTML = item_detail;
+    var item_tags_url = `/api/1/item/${qid}/tags`;
+    axios.get(item_tags_url).then((response) => {
+      var tag_or_key_list = response.data.tag_or_key_list;
+      var item_detail = build_item_detail(items[qid].wikidata, tag_or_key_list);
+      detail.innerHTML = item_detail;
+    });
   });
 
   item.markers ||= [];
diff --git a/web_view.py b/web_view.py
index 9913bff..efb8d92 100755
--- a/web_view.py
+++ b/web_view.py
@@ -374,6 +374,35 @@ def api_osm_objects():
     return jsonify(success=True, objects=objects, duration=t1)
 
 
+skip_isa = {13226383, 16686448, 2221906}
+skip_tags = {"Key:addr:street"}
+
+def get_item_tags(item):
+    isa_list = [v["numeric-id"] for v in item.get_claim("P31")]
+    isa_items = model.Item.query.filter(model.Item.item_id.in_(isa_list)).all()
+    osm_list = set()
+    seen = set(isa_list) | skip_isa
+    while isa_items:
+        isa = isa_items.pop()
+        osm = [v for v in isa.get_claim("P1282") if v not in skip_tags]
+        osm_list.update(osm)
+
+        subclass_of = [v["numeric-id"] for v in isa.get_claim("P279")]
+        isa_list = [isa_id for isa_id in subclass_of if isa_id not in seen]
+        seen.update(isa_list)
+        isa_items += model.Item.query.filter(model.Item.item_id.in_(isa_list)).all()
+    return sorted(osm_list)
+
+
+@app.route("/api/1/item/Q<int:item_id>/tags")
+def api_get_item_tags(item_id):
+    t0 = time()
+    item = model.Item.query.get(item_id)
+    osm_list = get_item_tags(item)
+    t1 = time() - t0
+    return jsonify(success=True, qid=item.qid, tag_or_key_list=osm_list, duration=t1)
+
+
 @app.route("/api/1/missing")
 def api_missing_wikidata_items():
     qids_arg = request.args.get("qids")