lighthousemap/index.html

135 wiersze
3.9 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Lights at sea</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
crossorigin=""/>
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#seamap {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="seamap"></div>
<script id="seamap-query" type="text/x-overpass">
[out:json][timeout:25];
// gather results
(
// query part for: “"seamark:light:sequence"=*”
node["seamark:light:sequence"]({{bbox}});
way["seamark:light:sequence"]({{bbox}});
relation["seamark:light:sequence"]({{bbox}});
);
// print results
out body;
>;
out skel qt;
</script>
<script id="seamap-wikidata-query" type="text/x-sparql">
SELECT ?item ?itemLabel ?location ?height ?focalHeight ?sequence
WHERE
{
?item wdt:P31 wd:Q39715.
?item wdt:P625 ?location.
OPTIONAL {
?item wdt:P2048 ?height.
?item wdt:P2923 ?focalHeight.
?item wdt:P1030 ?sequence.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
</script>
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet-src.js"></script>
<script src="https://unpkg.com/osmtogeojson@3.0.0-beta.2/osmtogeojson.js"
integrity="sha384-O1DMEF/gKYhLsICYtozkRWjEr9OfkZzVawUjyOPtevnKB2S1BegNJO0R251Pfuwz"
crossorigin=""></script>
<script src="https://unpkg.com/rbush@2.0.1/rbush.js"></script>
<script src="https://unpkg.com/@turf/turf@3.5.2/turf.min.js"></script>
<script src="leaflet.indexedfeaturelayer.js"></script>
<script src="leaflet.rangedmarker.js"></script>
<script src="leaflet.light.js"></script>
<script>
let map = L.map('seamap').setView([54.2, 2.6], 6);
L.tileLayer('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
detectRetina: true,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>'
}).addTo(map);
let bounds = map.getBounds();
function bbox(bounds) {
let ne = bounds.getNorthEast();
let sw = bounds.getSouthWest();
return [sw.lat, sw.lng, ne.lat, ne.lng]
}
let query = document.getElementById('seamap-query').textContent
.replace(/\{\{bbox\}\}/g, bbox(bounds).join(','));
let url = 'https://www.overpass-api.de/api/interpreter?data=' + encodeURIComponent(query);
url = 'data-full.json'; // For testing
let data = fetch(url)
.then(req => req.json())
.then(json => osmtogeojson(json))
.then(json => ({
type: json.type,
features: json.features.map(feature => {
return feature.geometry.type == 'Polygon'
? Object.assign({}, feature, {geometry: turf.centroid(feature).geometry})
: feature;
})
}));
let lights = data.then(geojson => {
return L.indexedGeoJSON(null, {
pointToLayer: function(feat, latlng) {
return new L.Light(latlng, {
interactive: false,
title: feat.properties.tags['name'],
radius: (parseFloat(feat.properties.tags['seamark:light:range'], 10) || 1) * 1000,
sequence: new L.Light.Sequence(feat.properties.tags['seamark:light:sequence']),
stroke: false,
fillOpacity: 0.9,
fillColor: '#FF0'
});
}
}).addTo(map).addData(geojson);
});
lights.then(layer => {
let draw = function(t) {
layer.eachLayer(marker => {
try {
marker.setState(marker.options.sequence.state(t));
} catch (e) {
console.error(e, marker);
}
});
};
let update = function(t) {
draw(t / 1000);
requestAnimationFrame(update);
};
update(0);
})
lights.catch(e => console.error(e));
</script>
</body>
</html>