174 lines
5.2 KiB
JavaScript
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.")
|
|
}
|
|
})
|
|
})
|