c3d2-web/content/static/datenspuren/2016/script/pois.js

174 lines
5.2 KiB
JavaScript

var poisJson
var currentPosition = {
lat: 51.0420162,
lon: 13.7976983
}
var currentCenter
var geoListeners = []
function POI(info) {
this.info = info
this.lon = info.lon || info.center.lon
this.lat = info.lat || info.center.lat
}
POI.prototype.getDistance = function() {
return WGS84Util.distanceBetween({
coordinates: [this.lon, this.lat]
}, {
coordinates: [currentPosition.lon, currentPosition.lat]
})
}
POI.prototype.makeArrowEl = function() {
var el = $('<div class="geo-arrow"><p class="arrow"><span></span></p><p class="dist"></p></div>')
var update = function() {
var bearing = -180.0 * Math.atan2(
this.lat - currentPosition.lat,
this.lon - currentPosition.lon
) / Math.PI
el.find('.arrow span').css('transform', 'rotate(' + (bearing - (currentPosition.heading || 0)) + 'deg)')
el.find('.arrow span').text(typeof currentPosition.heading === 'number' ?
"➡" : "➢"
)
el.find('.dist').text(formatDistance(this.getDistance()))
}.bind(this)
// Initialize:
update()
// hook onGeo listener
geoListeners.push(update)
return el
}
function onGeo(geo) {
console.log("onGeo", geo)
currentPosition = {
lat: geo.coords.latitude,
lon: geo.coords.longitude,
heading: geo.heading
}
// if distance > 100m to old center (not currentPosition!), reset list
var dist = WGS84Util.distanceBetween({
coordinates: [currentCenter.lon, currentCenter.lat]
}, {
coordinates: [currentPosition.lon, currentPosition.lat]
})
if (dist >= 100) {
if (poisJson)
showPOIs(poisJson)
} else {
// call listeners
geoListeners.forEach(function(f) {
f(currentPosition)
})
}
}
function formatDistance(x) {
if (x >= 1000) {
return (Math.round(x / 100) / 10) + " km"
} else {
return Math.round(x) + " m"
}
}
function makeLink(link) {
var a = $('<a></a>')
a.attr('href', link.indexOf("://") < 0 ? "http://" + link : link)
a.text(link.replace(/^\w+?:\/\//, "").replace(/\/+$/, ""))
return a
}
function showPOIs(json) {
geoListeners = []
var dl = $('#food')
dl.empty()
currentCenter = currentPosition
var pois = json.elements.map(function(info) {
return new POI(info)
}).sort(function(a, b) {
return a.getDistance() - b.getDistance()
})
while(pois.length > 20 && pois[pois.length - 1].getDistance() > 1000) {
pois.pop()
}
pois.forEach(function(poi) {
if (!poi.info.tags.name) {
console.warn("No name:", poi.info)
return // Skip
}
var dt = $('<dt><a></a></dt>')
dt.find('a').
attr('href', "https://www.openstreetmap.org/" + poi.info.type + "/" + poi.info.id).
text(poi.info.tags.name)
if (poi.info.tags.wheelchair == 'yes')
dt.append("<span class='wheelchair'>♿</span>")
if (poi.info.tags['addr:street'] && poi.info.tags['addr:housenumber']) {
var addr = $('<span class="addr"></span>')
addr.text(poi.info.tags['addr:street'] + " " +
poi.info.tags['addr:housenumber'])
dt.append(addr)
}
if (poi.info.tags.website) {
var addr = $('<span class="website"></span>')
addr.append(makeLink(poi.info.tags.website))
dt.append(addr)
}
dt.prepend(poi.makeArrowEl())
dl.append(dt)
if (poi.info.tags.opening_hours) {
poi.info.tags.opening_hours.split(/\s*;\s*/g).forEach(function(range) {
var dd = $('<dd></dd>')
dd.text(range)
dl.append(dd)
})
}
})
}
var h3 = $('<h3 id="foodlocator">Imbißmöglichkeiten anzeigen</h3>')
$('article').append(h3)
$('article').append('<p id="geopos-privacy-hint">Sollte ich in meinem Browser Geopositionsabfragen erlauben? Sie werden lediglich von JavaScript im Browser ausgewertet. Diese Daten werden nicht ins Netz übermittelt. Bei Fehlen wird der Veranstaltungsort als aktueller Standort benutzt.</p>')
var ran = false
h3.click(function() {
if (ran) return
ran = true
navigator.geolocation.getCurrentPosition(function(geo) {
onGeo(geo)
navigator.geolocation.watchPosition(onGeo, null, {
enableHighAccuracy: true
})
})
h3.addClass('expanded')
h3.text("Lade Imbißmöglichkeiten...")
$('#geopos-privacy-hint').remove()
$.ajax({
url: "pois.json",
success: function(json) {
$('article').append('<dl id="food"></dl>')
showPOIs(json)
poisJson = json
h3.text("Imbißmöglichkeiten in der Umgebung")
$('article').append("<p style='margin-top: 1.5em'>Quelle: <a href='https://www.openstreetmap.org/'>OpenStreetMap</a>. Wir ermutigen zur Vervollständigung der Daten dort. Stündlich aktualisiert mithilfe Overpass Turbo.</p>")
},
error: function() {
h3.text("Fehler! Versuch z.B. osm24.eu stattdessen.")
}
})
})