From 98fce653620953b398d97e8ef239d379f65fe3a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Tue, 21 Jun 2022 20:56:23 +0200
Subject: [PATCH 01/10] New "OSM QA" categories

---
 culture-media.yaml | 64 ++++++++++++++++++++++++++++++++++++++++++++++
 fixme.yaml         | 24 +++++++++++++++++
 index.json         | 12 +++++++++
 3 files changed, 100 insertions(+)
 create mode 100644 culture-media.yaml
 create mode 100644 fixme.yaml

diff --git a/culture-media.yaml b/culture-media.yaml
new file mode 100644
index 0000000..f5eebfe
--- /dev/null
+++ b/culture-media.yaml
@@ -0,0 +1,64 @@
+type: "overpass"
+query: 
+  15: |
+    (nwr[historic];nwr[tourism~'^(attraction|artwork)$'];nwr[heritage];)
+feature: 
+  pre: |
+    {% set color = 'red' %}
+    {% if tags.wikidata %}
+    {% set color = 'blue' %}
+    {% elseif tags.wikimedia_commons or tags.image %}
+    {% set color = 'cyan' %}
+    {% endif %}
+  description: |
+    {% if tags.historic and tags.historic != 'yes' %}
+      {{ tagTransList('historic', tags.historic) }}
+      {% if tags.historic == 'memorial' and tags.memorial %}
+        ({{ tagTransList('memorial', tags.memorial) }})
+      {% endif %}
+    {% elseif tags.tourism %}
+      {{ tagTransList('tourism', tags.tourism) }}
+    {% elseif tags.heritage %}
+      {{ keyTrans('heritage') }}
+    {% endif %}
+  markerSymbol: "{{ markerPointer({ fillColor: color })|raw }}"
+  listMarkerSymbol: "{{ markerCircle({ fillColor: color })|raw }}"
+filter: 
+  type: 
+    name: "{{ trans('filter:type') }}"
+    show_default: "true"
+    query: "nwr[{{ value }}]"
+    type: "select"
+    key: "tourism"
+    values: |
+      <option value='tourism-artwork' query='nwr[tourism=artwork]'>{{ tagTrans('tourism', 'artwork') }}</option>
+      <option value='tourism-attraction' query='nwr[tourism=attraction]'>{{ tagTrans('tourism', 'attraction') }}</option>
+      <option value='historic-memorial' query='nwr[historic=memorial]'>{{ tagTrans('historic', 'memorial') }}</option>
+      <option value='historic-monument' query='nwr[historic=monument]'>{{ tagTrans('historic', 'monument') }}</option>
+      <option value='historic-wayside_cross' query='nwr[historic=wayside_cross]'>{{ tagTrans('historic', 'wayside_cross') }}</option>
+      <option value='historic-wayside_shrine' query='nwr[historic=wayside_shrine]'>{{ tagTrans('historic', 'wayside_shrine') }}</option>
+      <option value='historic-building' query='nwr[historic=building]'>{{ tagTrans('historic', 'building') }}</option>
+      <option value='historic-other' query='nwr[historic][historic!~"^(memorial|monument|wayside_cross|wayside_shrine|building)$"]'>{{ keyTrans('historic') }} {{ trans('other') }}</option>
+      <option value='heritage' query='nwr[heritage]'>{{ keyTrans('heritage') }}</option>
+    op: "has"
+info: |
+  <table>
+      <tr>
+        <td>
+          {{ markerCircle({ fillColor: 'red' })|raw }}
+        </td>
+        <td>No image, wikimedia_commons or wikidata</td>
+      </tr>
+      <tr>
+        <td>
+          {{ markerCircle({ fillColor: 'cyan' })|raw }}
+        </td>
+        <td>image or wikimedia_commons but no wikidata</td>
+      </tr>
+      <tr>
+        <td>
+          {{ markerCircle({ fillColor: 'blue' })|raw }}
+        </td>
+        <td>has wikidata link</td>
+      </tr>
+  </table>
diff --git a/fixme.yaml b/fixme.yaml
new file mode 100644
index 0000000..787234e
--- /dev/null
+++ b/fixme.yaml
@@ -0,0 +1,24 @@
+type: overpass
+query:
+  15: "nwr[fixme]"
+feature:
+  description: |
+    {% set found = false %}
+    {% for k in ['amenity', 'shop', 'telecom', 'waterway', 'craft', 'highway', 'railway', 'aerialway', 'emergency', 'geological', 'man_made', 'natural', 'office', 'power', 'aeroway', 'tourism', 'leisure', 'military', 'landuse', 'barrier', 'route'] if not found %}
+      {% if attribute(tags, k) and attribute(tags, k) != 'yes' %}
+        {{ tagTransList(k, attribute(tags, k)) }}
+        {% set found = true %}
+      {% endif %}
+    {% endfor %}
+    {% if found %}{# nothing #}
+    {% elseif tags.building and tags.building != 'yes' %}
+    {{ tagTransList('building', tags.building) }}
+    {% elseif tags.historic and tags.historic not in ['heritage', 'yes', 'building'] %}
+    {{ tagTransList('historic', tags.historic) }}
+    {% elseif tags.building == 'yes' or tags.historic == 'building' %}
+    {{ keyTrans('building') }}
+    {% elseif tags.boundary %}
+    {{ tagTrans('boundary', tags.boundary) }}
+    {% endif %}
+  body: |
+    {{ tags.fixme == 'yes' ? keyTrans('fixme') : tags.fixme }}
diff --git a/index.json b/index.json
index e2c2824..52cf771 100644
--- a/index.json
+++ b/index.json
@@ -391,6 +391,18 @@
                     "id": "xmas"
                 }
             ]
+        },
+        {
+            "id": "osm-qa",
+            "type": "index",
+            "subCategories": [
+                {
+                    "id": "fixme"
+                },
+                {
+                    "id": "culture-media"
+                }
+            ]
         }
     ]
 }

From 5ada01027a52ebb1849d0cca5db813dde65205bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Tue, 21 Jun 2022 20:57:47 +0200
Subject: [PATCH 02/10] culture-media: check wikidata entity if it is a human

---
 culture-media.yaml | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/culture-media.yaml b/culture-media.yaml
index f5eebfe..a4bb882 100644
--- a/culture-media.yaml
+++ b/culture-media.yaml
@@ -10,6 +10,11 @@ feature:
     {% elseif tags.wikimedia_commons or tags.image %}
     {% set color = 'cyan' %}
     {% endif %}
+
+    {% if tags.wikidata %}
+    {% set wikidata = tags.wikidata|wikidataEntity %}
+    {% if wikidata.claims.P31[0].mainsnak.datavalue.value.id in ['Q5'] %}{% set color = 'magenta' %}{% endif %}
+    {% endif %}
   description: |
     {% if tags.historic and tags.historic != 'yes' %}
       {{ tagTransList('historic', tags.historic) }}
@@ -61,4 +66,10 @@ info: |
         </td>
         <td>has wikidata link</td>
       </tr>
+      <tr>
+        <td>
+          {{ markerCircle({ fillColor: 'magenta' })|raw }}
+        </td>
+        <td>wikidata points to a human, should most likely be 'subject:wikidata'</td>
+      </tr>
   </table>

From 22a6c363b506c96eb9a8ba6ea47591c752d34bb0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Tue, 21 Jun 2022 22:03:15 +0200
Subject: [PATCH 03/10] fix

---
 lang/en.json | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lang/en.json b/lang/en.json
index 1c34a2f..3a5fba8 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -22,6 +22,7 @@
     "category:craft": "Craft",
     "category:culture": "Culture",
     "category:culture_religion": "Culture and Religion",
+    "category:culture-media": "Culture Media/Wikidata",
     "category:cycle_amenities": "Amenities",
     "category:cycle_routes": "Cycle Routes",
     "category:developable_areas": "Developable Areas",
@@ -31,6 +32,7 @@
     "category:emergency": "Emergency Services",
     "category:energy": "Energy",
     "category:financial": "Financial",
+    "category:fixme": "Fix Me",
     "category:gastro": "Gastronomy",
     "category:gastro-smoking": "Smokefree Gastronomy",
     "category:health": "Health",
@@ -50,6 +52,7 @@
     "category:office": "Offices",
     "category:oil_gas": "Petroleum and natural gas",
     "category:organisations": "Organisations",
+    "category:osm-qa": "OpenStreetMap Quality Control",
     "category:other": "Other",
     "category:outdoor": "Outdoor activities",
     "category:phone": "Phone",

From ac7dd6ec1a9a2bce83ee7654d2437b1c2da1f181 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Fri, 26 Aug 2022 22:01:06 +0100
Subject: [PATCH 04/10] fixme: query case-insenstive; also 'fixme:...'; also
 >=z14

---
 fixme.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fixme.yaml b/fixme.yaml
index 787234e..17b9f45 100644
--- a/fixme.yaml
+++ b/fixme.yaml
@@ -1,6 +1,6 @@
 type: overpass
 query:
-  15: "nwr[fixme]"
+  14: nwr[~"^fixme(:.*|)$"~".",i]
 feature:
   description: |
     {% set found = false %}

From 4260c2ad492d8510dd7fa161232b5621d8ea6607 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Sat, 27 Aug 2022 11:36:57 +0200
Subject: [PATCH 05/10] fixme: display value of fixme or other tags as details

---
 fixme.yaml | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/fixme.yaml b/fixme.yaml
index 17b9f45..dffa1e8 100644
--- a/fixme.yaml
+++ b/fixme.yaml
@@ -2,6 +2,20 @@ type: overpass
 query:
   14: nwr[~"^fixme(:.*|)$"~".",i]
 feature:
+  pre: |
+    {% set fixme = tags.fixme %}
+    {% set category = null %}
+
+    {% if not fixme %}
+      {% for k, v in tags %}
+        {% set m = k|matches('^fixme(:(.*))?$', 'i') %}
+        {% if m %}
+          {% set fixme = v %}
+        {% endif %}
+      {% endfor %}
+    {% endif %}
+  details: |
+    {{ fixme }}
   description: |
     {% set found = false %}
     {% for k in ['amenity', 'shop', 'telecom', 'waterway', 'craft', 'highway', 'railway', 'aerialway', 'emergency', 'geological', 'man_made', 'natural', 'office', 'power', 'aeroway', 'tourism', 'leisure', 'military', 'landuse', 'barrier', 'route'] if not found %}
@@ -21,4 +35,4 @@ feature:
     {{ tagTrans('boundary', tags.boundary) }}
     {% endif %}
   body: |
-    {{ tags.fixme == 'yes' ? keyTrans('fixme') : tags.fixme }}
+    {{ fixme == 'yes' ? keyTrans('fixme') : fixme }}

From e8259aa3ffa69b660a7e3ff361e85728ebc1ac07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Wed, 22 Jun 2022 18:50:00 +0200
Subject: [PATCH 06/10] culture-media: improvements

---
 culture-media.yaml | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/culture-media.yaml b/culture-media.yaml
index a4bb882..b5c81fd 100644
--- a/culture-media.yaml
+++ b/culture-media.yaml
@@ -5,16 +5,27 @@ query:
 feature: 
   pre: |
     {% set color = 'red' %}
+    {% set str = 'No image, wikimedia_commons or wikidata' %}
+
     {% if tags.wikidata %}
-    {% set color = 'blue' %}
+      {% set color = 'blue' %}
+      {% set str = 'has wikidata tag' %}
+      {% set wikidata = tags.wikidata|wikidataEntity %}
+
+      {% if wikidata.claims.P31[0].mainsnak.datavalue.value.id in ['Q5'] %}
+        {% set color = 'magenta' %}
+        {% set str = "wikidata points to a human, should most likely be 'subject:wikidata'" %}
+      {% endif %}
+
     {% elseif tags.wikimedia_commons or tags.image %}
-    {% set color = 'cyan' %}
-    {% endif %}
+      {% set color = 'cyan' %}
+      {% set str = tags.wikimedia_commons ? 'has wikimedia_commons tag' : 'has image tag' %}
 
-    {% if tags.wikidata %}
-    {% set wikidata = tags.wikidata|wikidataEntity %}
-    {% if wikidata.claims.P31[0].mainsnak.datavalue.value.id in ['Q5'] %}{% set color = 'magenta' %}{% endif %}
     {% endif %}
+
+  body: |
+    {{ str }}
+
   description: |
     {% if tags.historic and tags.historic != 'yes' %}
       {{ tagTransList('historic', tags.historic) }}
@@ -56,20 +67,23 @@ info: |
       </tr>
       <tr>
         <td>
-          {{ markerCircle({ fillColor: 'cyan' })|raw }}
+          {{ markerCircle({ fillColor: 'magenta' })|raw }}
         </td>
-        <td>image or wikimedia_commons but no wikidata</td>
+        <td>wikidata tag points to a human, should most likely be 'subject:wikidata'</td>
       </tr>
       <tr>
         <td>
-          {{ markerCircle({ fillColor: 'blue' })|raw }}
+          {{ markerCircle({ fillColor: 'cyan' })|raw }}
         </td>
-        <td>has wikidata link</td>
+        <td>image or wikimedia_commons tag but no wikidata</td>
       </tr>
       <tr>
         <td>
-          {{ markerCircle({ fillColor: 'magenta' })|raw }}
+          {{ markerCircle({ fillColor: 'blue' })|raw }}
         </td>
-        <td>wikidata points to a human, should most likely be 'subject:wikidata'</td>
+        <td>has wikidata tag</td>
       </tr>
   </table>
+
+  This category lists artwork, memorials, historic and heritage protected objects. These should have an <a target="_blank" href="https://wiki.openstreetmap.org/wiki/Key:image">image</a> or <a target="_blank" href="https://wiki.openstreetmap.org/wiki/Key:wikimedia_commons">wikimedia_commons</a> tag, or (even better) a <a target="_blank" href="https://wiki.openstreetmap.org/wiki/Key:wikidata">wikidata</a> tag pointing to the object's entry.<br>
+  Memorials erroneously often have a wikidata (and wikipedia) tag of the person/event, which should be changed to <a target="_blank" href="https://wiki.openstreetmap.org/wiki/Key:wikidata#Secondary_Wikidata_links">subject:wikidata</a> resp. <a target="_blank" href="https://wiki.openstreetmap.org/wiki/Key:wikipedia#Secondary_Wikipedia_links">subject:wikipedia</a>".

From 6d49dba5bddca041c7c3adfb3b53f73476f78c28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Sat, 27 Aug 2022 12:23:29 +0200
Subject: [PATCH 07/10] fixme: defines categories of fixme's, set color per
 category

---
 fixme.yaml | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/fixme.yaml b/fixme.yaml
index dffa1e8..4ecdee5 100644
--- a/fixme.yaml
+++ b/fixme.yaml
@@ -11,6 +11,15 @@ feature:
         {% set m = k|matches('^fixme(:(.*))?$', 'i') %}
         {% if m %}
           {% set fixme = v %}
+          {% set category = m[2] %}
+        {% endif %}
+      {% endfor %}
+    {% endif %}
+
+    {% if not category %}
+      {% for k, d in const if d.match %}
+        {% if fixme|matches(d.match, 'i') %}
+          {% set category = k %}
         {% endif %}
       {% endfor %}
     {% endif %}
@@ -36,3 +45,48 @@ feature:
     {% endif %}
   body: |
     {{ fixme == 'yes' ? keyTrans('fixme') : fixme }}
+  markerSymbol: |
+    {{ markerPointer({ fillColor: const[category].color|default('#f2756a') }) }}
+  listMarkerSymbol: |
+    {{ markerCircle({ fillColor: const[category].color|default('#f2756a') }) }}
+filter:
+  category:
+    name: Category
+    show_default: true
+    type: select
+    values: |
+      <option value='name' query='(nwr[~"fixme:name"~".",i];nwr[~"fixme(:.*|)"~"name",i];)'>{{ keyTrans('name') }}</option>
+      <option value='position' query='nwr[fixme~"(position|location)",i]'>{{ tagTrans('fixme', 'position') }}</option>
+      <option value='addr' query='(nwr["fixme:addr"];nwr[fixme~"addr",i];)'>{{ tagTrans('fixme', 'addr') }}</option>
+      <option value='maxspeed' query='(nwr["fixme:maxspeed"];nwr[fixme~"maxspeed",i];)'>{{ tagTrans('fixme', 'maxspeed') }}</option>
+      <option value='imcomplete' query='nwr[fixme~"(continue|incomplete|unfinished)",i]'>{{ tagTrans('fixme', 'continue') }}</option>
+      <option value='resurvey' query='nwr[fixme~"resurvey",i]'>{{ tagTrans('fixme', 'resurvey') }}</option>
+      <option value='verify' query='nwr[fixme~"(verify|recheck)",i]'>{{ tagTrans('fixme', 'verify') }}</option>
+      <option value='import' query='nwr[fixme~"import",i]'>{{ tagTrans('fixme', 'import') }}</option>
+const:
+  default:
+    color: '#f2756a'
+  name:
+    match: 'name'
+    color: '#00b6a9'
+  incomplete:
+    match: '(continue|incomplete|unfinished)'
+    color: '#bb972f'
+  position:
+    match: '(position|location)'
+    color: '#71ab43'
+  addr:
+    match: 'addr'
+    color: '#0070b6'
+  maxspeed:
+    match: 'maxspeed'
+    color: '#a36af2'
+  resurvey:
+    match: 're-?survey'
+    color: '#00b647'
+  verify:
+    match: '(verify|recheck)'
+    color: '#eeb600'
+  import:
+    match: 'import'
+    color: '#a6b600'

From 6c5fded3234897a5597fe8e73554f15ebfb82dd9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Sat, 27 Aug 2022 18:48:28 +0200
Subject: [PATCH 08/10] fixme: filter queries from const

---
 fixme.yaml | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/fixme.yaml b/fixme.yaml
index 4ecdee5..aeb8a27 100644
--- a/fixme.yaml
+++ b/fixme.yaml
@@ -55,19 +55,13 @@ filter:
     show_default: true
     type: select
     values: |
-      <option value='name' query='(nwr[~"fixme:name"~".",i];nwr[~"fixme(:.*|)"~"name",i];)'>{{ keyTrans('name') }}</option>
-      <option value='position' query='nwr[fixme~"(position|location)",i]'>{{ tagTrans('fixme', 'position') }}</option>
-      <option value='addr' query='(nwr["fixme:addr"];nwr[fixme~"addr",i];)'>{{ tagTrans('fixme', 'addr') }}</option>
-      <option value='maxspeed' query='(nwr["fixme:maxspeed"];nwr[fixme~"maxspeed",i];)'>{{ tagTrans('fixme', 'maxspeed') }}</option>
-      <option value='imcomplete' query='nwr[fixme~"(continue|incomplete|unfinished)",i]'>{{ tagTrans('fixme', 'continue') }}</option>
-      <option value='resurvey' query='nwr[fixme~"resurvey",i]'>{{ tagTrans('fixme', 'resurvey') }}</option>
-      <option value='verify' query='nwr[fixme~"(verify|recheck)",i]'>{{ tagTrans('fixme', 'verify') }}</option>
-      <option value='import' query='nwr[fixme~"import",i]'>{{ tagTrans('fixme', 'import') }}</option>
+      {% for k, d in const %}
+      <option value='{{ k }}' query='{{ d.query|default('nwr[~"fixme(:.*|)"~"' ~ d.match ~ '"') }},i]'>{{ tagTrans('fixme', k) }}</option>
+      {% endfor %}
 const:
-  default:
-    color: '#f2756a'
   name:
     match: 'name'
+    query: '(nwr[~"fixme:name"~".",i];nwr[~"fixme(:.*|)"~"name",i];)'
     color: '#00b6a9'
   incomplete:
     match: '(continue|incomplete|unfinished)'
@@ -77,9 +71,11 @@ const:
     color: '#71ab43'
   addr:
     match: 'addr'
+    query: '(nwr["fixme:addr"];nwr[fixme~"addr",i];)'
     color: '#0070b6'
   maxspeed:
     match: 'maxspeed'
+    query: '(nwr["fixme:maxspeed"];nwr[fixme~"maxspeed",i];)'
     color: '#a36af2'
   resurvey:
     match: 're-?survey'

From b434fae7be702e79a0c308ead523a87f234d7b9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Sat, 27 Aug 2022 18:52:47 +0200
Subject: [PATCH 09/10] fixme: map key

---
 fixme.yaml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/fixme.yaml b/fixme.yaml
index aeb8a27..6b1baba 100644
--- a/fixme.yaml
+++ b/fixme.yaml
@@ -58,6 +58,19 @@ filter:
       {% for k, d in const %}
       <option value='{{ k }}' query='{{ d.query|default('nwr[~"fixme(:.*|)"~"' ~ d.match ~ '"') }},i]'>{{ tagTrans('fixme', k) }}</option>
       {% endfor %}
+info: |
+  <table>
+    <tr>
+      <td>{{ markerCircle({ fillColor: '#f2756a' }) }}</td>
+      <td>{{ trans('other') }}</td>
+    </tr>
+    {% for k, d in const %}
+    <tr>
+      <td>{{ markerCircle({ fillColor: d.color }) }}</td>
+      <td>{{ tagTrans('fixme', k) }}</td>
+    </tr>
+    {% endfor %}
+  </table>
 const:
   name:
     match: 'name'

From cbdbd663f5dfcda7d35acb5c1af2afb906bd7e0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= <skunk@xover.mud.at>
Date: Sat, 27 Aug 2022 19:58:19 +0200
Subject: [PATCH 10/10] fixme: add a 'type' filter

---
 fixme.yaml | 176 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 144 insertions(+), 32 deletions(-)

diff --git a/fixme.yaml b/fixme.yaml
index 6b1baba..55d9e4b 100644
--- a/fixme.yaml
+++ b/fixme.yaml
@@ -17,7 +17,7 @@ feature:
     {% endif %}
 
     {% if not category %}
-      {% for k, d in const if d.match %}
+      {% for k, d in const.fixme if d.match %}
         {% if fixme|matches(d.match, 'i') %}
           {% set category = k %}
         {% endif %}
@@ -46,25 +46,33 @@ feature:
   body: |
     {{ fixme == 'yes' ? keyTrans('fixme') : fixme }}
   markerSymbol: |
-    {{ markerPointer({ fillColor: const[category].color|default('#f2756a') }) }}
+    {{ markerPointer({ fillColor: const.fixme[category].color|default('#f2756a') }) }}
   listMarkerSymbol: |
-    {{ markerCircle({ fillColor: const[category].color|default('#f2756a') }) }}
+    {{ markerCircle({ fillColor: const.fixme[category].color|default('#f2756a') }) }}
 filter:
   category:
     name: Category
     show_default: true
     type: select
     values: |
-      {% for k, d in const %}
+      {% for k, d in const.fixme %}
       <option value='{{ k }}' query='{{ d.query|default('nwr[~"fixme(:.*|)"~"' ~ d.match ~ '"') }},i]'>{{ tagTrans('fixme', k) }}</option>
       {% endfor %}
+  type:
+    name: Type
+    show_default: true
+    type: select
+    values: |
+      {% for k, d in const.types %}
+      <option value='{{ k }}' query='{{ d.query }}'>{{ d.title|matches('^repo/') ? repoTrans(d.title|slice(5)) : trans(d.title) }}</option>
+      {% endfor %}
 info: |
   <table>
     <tr>
       <td>{{ markerCircle({ fillColor: '#f2756a' }) }}</td>
       <td>{{ trans('other') }}</td>
     </tr>
-    {% for k, d in const %}
+    {% for k, d in const.fixme %}
     <tr>
       <td>{{ markerCircle({ fillColor: d.color }) }}</td>
       <td>{{ tagTrans('fixme', k) }}</td>
@@ -72,30 +80,134 @@ info: |
     {% endfor %}
   </table>
 const:
-  name:
-    match: 'name'
-    query: '(nwr[~"fixme:name"~".",i];nwr[~"fixme(:.*|)"~"name",i];)'
-    color: '#00b6a9'
-  incomplete:
-    match: '(continue|incomplete|unfinished)'
-    color: '#bb972f'
-  position:
-    match: '(position|location)'
-    color: '#71ab43'
-  addr:
-    match: 'addr'
-    query: '(nwr["fixme:addr"];nwr[fixme~"addr",i];)'
-    color: '#0070b6'
-  maxspeed:
-    match: 'maxspeed'
-    query: '(nwr["fixme:maxspeed"];nwr[fixme~"maxspeed",i];)'
-    color: '#a36af2'
-  resurvey:
-    match: 're-?survey'
-    color: '#00b647'
-  verify:
-    match: '(verify|recheck)'
-    color: '#eeb600'
-  import:
-    match: 'import'
-    color: '#a6b600'
+  fixme:
+    name:
+      match: 'name'
+      query: '(nwr[~"fixme:name"~".",i];nwr[~"fixme(:.*|)"~"name",i];)'
+      color: '#00b6a9'
+    incomplete:
+      match: '(continue|incomplete|unfinished)'
+      color: '#bb972f'
+    position:
+      match: '(position|location)'
+      color: '#71ab43'
+    addr:
+      match: 'addr'
+      query: '(nwr["fixme:addr"];nwr[fixme~"addr",i];)'
+      color: '#0070b6'
+    maxspeed:
+      match: 'maxspeed'
+      query: '(nwr["fixme:maxspeed"];nwr[fixme~"maxspeed",i];)'
+      color: '#a36af2'
+    resurvey:
+      match: 're-?survey'
+      color: '#00b647'
+    verify:
+      match: '(verify|recheck)'
+      color: '#eeb600'
+    import:
+      match: 'import'
+      color: '#a6b600'
+  types:
+    shops:
+      title: 'tag:shop'
+      query: 'nwr[shop]'
+    craft:
+      title: 'tag:craft'
+      query: 'nwr[craft]'
+    tourism:
+      title: 'tag:tourism'
+      query: 'nwr[tourism]'
+    roads:
+      title: 'tag:highway'
+      query: 'nwr[highway]'
+    gastro:
+      title: 'repo/category:gastro'
+      query: 'nwr[amenity~"^(bar|biergarten|cafe|fast_food|food_court|ice_cream|pub|restaurant)$"]'
+    agriculture:
+      title: 'repo/category:agriculture'
+      query: 'nwr[landuse~"^(allotments|farm|farmland|farmyard|greenhouse_horticulture|orchard|vineyard)$"]'
+    buildings:
+      title: 'repo/category:buildings'
+      query: '(nwr[building];nwr[entrance];)'
+    transport_car:
+      title: 'repo/category:transport_car'
+      query: 'nwr[amenity~"^(car_rental|car_sharing|car_wash|fuel|motorcycle_parking|parking)$"];'
+    children:
+      title: 'repo/category:children'
+      query: '(nwr[leisure~"^(playground|summer_camp|indoor_play)$"];nwr[shop~"^(baby_goods|toys)$"];nwr[changing_table];nwr[diaper];nwr[kids_area];nwr[playground];)'
+    sport:
+      title: 'tag:sport'
+      query: '(nwr[sport];nwr[climbing];nwr[highway~"^(via_ferrata)$"];nwr[leisure~"^(sports_.*)$"];)'
+    industrial:
+      title: 'tag:landuse=industrial'
+      query: '(nwr[landuse~"^(quarry|industrial)$"];nwr[man_made~"^(mineshaft|pipeline|goods_conveyor)$"];)'
+    power:
+      title: 'repo/category:electric_power'
+      query: '(nwr[power];relation[type=route][route=power];)'
+    communication:
+      title: 'repo/category:communication'
+      query: '(nwr[amenity~"^(post_office|internet_cafe|post_box|parcel_locker|telephone)$"];nwr[office~"^(telecommunication|it|newspaper|publisher|advertising_agency)$"];nwr[vending~"parcel"];)'
+    construction:
+      title: 'repo/category:construction'
+      query: '(nwr[~"."~"^(construction)$"];nwr[~"^construction:"~"."];)'
+    culture:
+      title: 'repo/category:culture'
+      query: '(nwr[amenity~"^(arts_centre|cinema|community_centre|fountain|studio|theatre)$"];nwr[tourism~"^(artwork|gallery|museum|theme_park)$"];nwr[amenity~"^(clock)$"];nwr[shop~"^(art)$"];)'
+    bicycle:
+      title: 'repo/category:transport_cycle'
+      query: '(nwr[amenity~"^(bicycle_.*|compressed_air|charging_station)$"];nwr[shop~"^(bicycle)$"];nwr["monitoring:bicycle"];nwr[vending~"^bicycle_"];relation[type=route][route~"^(|.*;)bicycle(|;.*)$"];)'
+    education:
+      title: 'repo/category:education'
+      query: '(nwr[amenity~"^(college|university|library|school|kindergarten|language_school|childcare|public_bookcase)$"];nwr[office~"^(educational_institution|research)$"];)'
+    emergency:
+      title: 'repo/category:emergency'
+      query: '(nwr[amenity~"^(fire_station|hospital|police)$"];nwr[emergency];nwr[highway~"^(emergency_access_point)$"];)'
+    financial:
+      title: 'repo/category:financial'
+      query: '(nwr[amenity~"^(bank|bureau_de_change|atm)$"];nwr[office~"^(financial|accountant|insurance|tax|tax_advisor)$"];)'
+    health:
+      title: 'repo/category:health'
+      query: '(nwr[amenity~"^(baby_hatch|clinic|dentist|doctors|hospital|nursing_home|pharmacy|social_facility|veterinary)$"];nwr[healthcare];)'
+    heritage:
+      title: 'repo/category:heritage'
+      query: 'nwr[heritage]'
+    walking:
+      title: 'repo/category:transport_walk'
+      query: '(nwr[amenity~"^(bench|shelter)$"];relation[type=route][route~"^(|.*;)hiking(|;.*)$"];nwr[highway~"^(footway|path|pedestrian|elevator|steps|crossing)$"];)'
+    historic:
+      title: 'tag:historic'
+      query: 'nwr[historic]'
+    law:
+      title: 'repo/category:law'
+      query: 'nwr[amenity~"^(courthouse)$"];nwr[office~"^(lawyer|notary)$"];)'
+    leisure:
+      title: 'tag:leisure'
+      query: 'nwr[leisure]'
+    memorial:
+      title: 'repo/category:memorial'
+      query: 'nwr[historic~"^(memorial|monument|wayside_(cross|shrine|chapel))$"]'
+    military:
+      title: 'repo/category:military'
+      query: '(nwr[military];nwr[landuse=military];)'
+    natural:
+      title: 'repo/category:natural'
+      query: '(nwr[natural];nwr[place~"^(island|islet)$"];)'
+    office:
+      title: 'repo/category:office'
+      query: 'nwr[office]'
+    places:
+      title: 'tag:place'
+      query: 'node[place]'
+    public:
+      title: 'repo/category:public'
+      query: '(nwr[amenity~"^(embassy|public_building|townhall|clock|drinking_water|recycling|toilets)$"];node[drinking_water];nwr[office~"^(government|administration)$"];)'
+    railway:
+      title: 'tag:railway'
+      query: '(nwr[railway];relation[type=route][route=railway];)'
+    religion:
+      title: 'tag:religion'
+      query: '(nwr[amenity~"^(place_of_worship|grave_yard|crematorium)$"];nwr[landuse~"^(cemetery)$"];nwr[historic~"wayside_(cross|shrine|chapel)$"];nwr[office~\"^(parish|religion)$\"];)'
+    landuse:
+      title: 'tag:landuse'
+      query: 'nwr[landuse]'