Browse Source

Merge branch 'tags-display'

master
parent
commit
0e9879a022
  1. 4
      bin/download_dependencies
  2. 52
      bin/tag2link-converter
  3. 7
      lib/tag2link-sophox.qry
  4. 15
      lib/tag2link-wikidata.qry
  5. 23
      src/category.css
  6. 15
      src/index.js
  7. 63
      src/tagsDisplay-tag2link.js
  8. 96
      src/tagsDisplay.js
  9. 8
      src/wikipedia.js

4
bin/download_dependencies

@ -1,3 +1,7 @@
#!/bin/sh
curl -H "Accept: application/json" -H "Content-Type: application/sparql-query" -H "User-Agent: OpenStreetBrowser" -XPOST -d @'lib/tag2link-wikidata.qry' https://query.wikidata.org/sparql > data/tag2link-wikidata.json
curl -H "Accept: application/json" -H "Content-Type: application/sparql-query" -H "User-Agent: OpenStreetBrowser" -XPOST -d @'lib/tag2link-sophox.qry' https://sophox.org/sparql > data/tag2link-sophox.json
bin/tag2link-converter
bin/download_geoip2

52
bin/tag2link-converter

@ -0,0 +1,52 @@
#!/usr/bin/php
<?php
$tag2link = array();
$files = array('data/tag2link-wikidata.json', 'data/tag2link-sophox.json');
foreach ($files as $file) {
$data = json_decode(file_get_contents($file), true);
foreach ($data['results']['bindings'] as $entry) {
$key = substr($entry['OSM_key']['value'], 4);
$link = $entry['formatter_URL']['value'];
if (array_key_exists($key, $tag2link)) {
// avoid duplicates
$duplicates = array_filter($tag2link[$key]['formatter'], function ($e) use ($link) {
return $e['link'] === $link;
});
if (sizeof($duplicates)) {
if (array_key_exists('operatorLabel', $entry)) {
foreach ($duplicates as $i => $d) {
$tag2link[$key]['formatter'][$i]['operator'] = $entry['operatorLabel']['value'];
}
}
continue;
}
}
else {
$tag2link[$key] = array(
'label' => $entry['itemLabel']['value'],
'formatter' => array(),
);
}
$formatter = array(
'link' => $link,
);
if (array_key_exists('operatorLabel', $entry)) {
$formatter['operator'] = $entry['operatorLabel']['value'];
print "{$formatter['operator']}\n";
}
else if (preg_match("/^https?:\/\/([^\/]*)(\/.*|)$/", $link, $m)) {
$formatter['operator'] = $m[1];
}
$tag2link[$key]['formatter'][] = $formatter;
}
}
file_put_contents('dist/tag2link.json', json_encode($tag2link, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));

7
lib/tag2link-sophox.qry

@ -0,0 +1,7 @@
SELECT ?item ?itemLabel (CONCAT("Key:", ?permanent_key_ID) as ?OSM_key) ?formatter_URL WHERE {
FILTER(?permanent_key_ID NOT IN ('image', 'url', 'website', 'wikidata', 'wikimedia_commons')).
?item osmdt:P2 osmd:Q7.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
?item osmdt:P16 ?permanent_key_ID.
?item osmdt:P8 ?formatter_URL.
}

15
lib/tag2link-wikidata.qry

@ -0,0 +1,15 @@
SELECT ?itemLabel ?OSM_key ?formatter_URL ?operatorLabel WHERE {
?item wdt:P1282 ?OSM_key .
FILTER(?OSM_key NOT IN("Key:image", "Key:url", "Key:website", "Key:wikidata", "Key:wikimedia_commons"))
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
{
?item p:P1630 ?statement.
?statement ps:P1630 ?formatter_URL.
}
UNION
{
?item p:P3303 ?statement.
?statement ps:P3303 ?formatter_URL.
}
OPTIONAL { ?statement pq:P137 ?operator. }
}

23
src/category.css

@ -161,3 +161,26 @@
.info .infoShowDetails .summary {
display: none;
}
dl > dd {
position: relative;
}
.tag2link {
position: absolute;
top: 1em;
left: 0;
border: 1px solid black;
padding: 0.25em;
background: white;
z-index: 1;
}
.tag2link > .closeButton {
float: right;
}
.tag2link > ul {
padding-left: 0;
margin: 0;
}
.tag2link > ul > li {
list-style: none;
}

15
src/index.js

@ -42,6 +42,8 @@ require('./GeoInfo')
require('./PluginMeasure')
require('./PluginGeoLocate')
let exportAll = require('./exportAll')
const tagsDisplay = require('./tagsDisplay').display
require('./tagsDisplay-tag2link')
window.onload = function () {
var initState = config.defaultView
@ -309,18 +311,7 @@ window.showDetails = function (data, category) {
h.innerHTML = lang('header:attributes')
dom.appendChild(h)
div = document.createElement('dl')
div.className = 'tags'
for (k in data.object.tags) {
dt = document.createElement('dt')
dt.appendChild(document.createTextNode(k))
div.appendChild(dt)
dd = document.createElement('dd')
dd.appendChild(document.createTextNode(data.object.tags[k]))
div.appendChild(dd)
}
dom.appendChild(div)
dom.appendChild(tagsDisplay(data.object.tags))
h = document.createElement('h3')
h.innerHTML = lang('header:osm_meta')

63
src/tagsDisplay-tag2link.js

@ -0,0 +1,63 @@
const httpGet = require('./httpGet')
const formatter = require('./tagsDisplay').formatter
let tag2link
register_hook('init_callback', (initState, callback) => {
httpGet('dist/tag2link.json', {}, (err, result) => {
if (err) {
console.error('Can\'t read dist/tag2link.json - execute bin/download_dependencies')
return callback()
}
tag2link = JSON.parse(result.body)
Object.keys(tag2link).forEach(key => {
let tag = tag2link[key]
let link = tag.formatter[0].link.replace('$1', '{{ value }}')
if (tag.formatter.length > 1) {
link = "#\" onclick=\"return tag2link(this, " + JSON.stringify(key).replace(/"/g, '&quot;') + ", {{ value|json_encode }})"
}
formatter.push({
regexp: new RegExp("^" + key + "$"),
link
})
})
callback()
})
})
global.tag2link = function (dom, key, value) {
let div = document.createElement('div')
div.className = 'tag2link'
dom.parentNode.appendChild(div)
let closeButton = document.createElement('div')
closeButton.className = 'closeButton'
closeButton.innerHTML = '❌'
closeButton.onclick = () => {
dom.parentNode.removeChild(div)
}
div.appendChild(closeButton)
let selector = document.createElement('ul')
div.appendChild(selector)
let tag = tag2link[key]
tag.formatter.forEach(formatter => {
let li = document.createElement('li')
let a = document.createElement('a')
a.target = '_blank'
a.href = formatter.link.replace('$1', value)
a.appendChild(document.createTextNode(formatter.operator))
li.appendChild(a)
selector.appendChild(li)
})
return false
}

96
src/tagsDisplay.js

@ -0,0 +1,96 @@
const OverpassLayer = require('overpass-layer')
const formatter = [
{
regexp: /^(.*:)?wikidata$/,
link: 'https://wikidata.org/wiki/{{ value }}'
},
{
regexp: /^(.*:)?wikipedia$/,
link: '{% set v = value|split(":") %}https://{{ v[0] }}.wikipedia.org/wiki/{{ v[1]|replace({" ": "_"}) }}'
},
{
regexp: /^(.*:)?wikipedia:([a-zA-Z]+)$/,
link: '{% set v = key|matches(":([a-zA-Z]+)") %}https://{{ v[1] }}.wikipedia.org/wiki/{{ value|replace({" ": "_"}) }}'
},
{
regexp: /^((.*:)?website(:.*)?|(.*:)?url(:.*)?|contact:website)$/,
link: '{{ value|websiteUrl }}'
},
{
regexp: /^(image|wikimedia_commons)$/,
link: '{% if value matches "/^(File|Category):/" %}' +
'https://commons.wikimedia.org/wiki/{{ value|replace({" ": "_"}) }}' +
'{% else %}' +
'{{ value|websiteUrl }}' +
'{% endif %}'
},
{
regexp: /^(species)$/,
link: 'https://species.wikimedia.org/wiki/{{ value|replace({" ": "_"}) }}'
},
{
regexp: /^(phone|contact:phone|fax|contact:fax)(:.*|)$/,
link: 'tel:{{ value }}'
},
{
regexp: /^(email|contact:email)(:.*|)$/,
link: 'mailto:{{ value }}'
}
]
let compiled = false
let defaultTemplate
function tagsDisplay (tags) {
if (!compiled) {
defaultTemplate = OverpassLayer.twig.twig({ data: '{{ value }}', autoescape: true })
for (let i in formatter) {
if (formatter[i].format) {
formatter[i].template = OverpassLayer.twig.twig({ data: formatter[i].format, autoescape: true })
} else {
formatter[i].template = OverpassLayer.twig.twig({ data: '<a target="_blank" href="' + formatter[i].link + '">{{ value }}</a>', autoescape: true })
}
}
compiled = true
}
const div = document.createElement('dl')
div.className = 'tags'
for (let k in tags) {
const dt = document.createElement('dt')
dt.appendChild(document.createTextNode(k))
div.appendChild(dt)
let template = defaultTemplate
const dd = document.createElement('dd')
for (let i = 0; i < formatter.length; i++) {
if (k.match(formatter[i].regexp)) {
template = formatter[i].template
break
}
}
let value = tags[k].split(/;/g)
value = value.map(v => {
// trim whitespace (but add it around the formatted value later)
let m = v.match(/^( *)([^ ].*[^ ]|[^ ])( *)$/)
if (m) {
return m[1] + template.render({ key: k, value: m[2] }) + m[3]
}
return v
}).join(';')
dd.innerHTML = value
div.appendChild(dd)
}
return div
}
module.exports = {
display: tagsDisplay,
formatter
}

8
src/wikipedia.js

@ -128,6 +128,8 @@ register_hook('show-details', function (data, category, dom, callback) {
foundPrefixes.push('')
ob.tags.wikipedia.split(/;/g).forEach(value => {
value = value.trim()
found++
showWikipedia(value, div, done)
})
@ -145,6 +147,8 @@ register_hook('show-details', function (data, category, dom, callback) {
foundPrefixes.push(prefix)
ob.tags[k].split(/;/g).forEach(value => {
value = value.trim()
found++
showWikipedia(value, div, done)
})
@ -180,6 +184,8 @@ register_hook('show-details', function (data, category, dom, callback) {
foundPrefixes.push('')
ob.tags.wikidata.split(/;/g).forEach(value => {
value = value.trim()
found++
wikidata.load(value, function (err, result) {
@ -228,6 +234,8 @@ register_hook('show-details', function (data, category, dom, callback) {
div.appendChild(h)
ob.tags[k].split(/;/g).forEach(value => {
value = value.trim()
wikidata.load(value, (err, result) => {
var x

Loading…
Cancel
Save