photolib/templates/map.html

126 lines
4.7 KiB
HTML

{% set title = "Map" %}
{% extends "page.html" %}
{% block title %}Photo map{% endblock %}
{% block subtitle %}GPS data{% endblock %}
{% block buttons %}{% endblock %}
{% block head %}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
{% endblock %}
{% block body %}
<div class="photo-map">
<div id="map" style="height:800px"></div>
<script type="text/javascript">
var points = [
{%- for item in images -%}
{coord: [{{item.lat}}, {{item.lon}}, ],uuid: "{{ item.uuid }}",date: "{{ item.date.strftime('%b %-d %Y') }}"},
{%- endfor -%}
];
// Determine initial position by parsing url fragment (or fall back to a random point)
if (window.location.hash) {
var hash = window.location.hash.substr(1).split(",");
var initial_pos = [parseFloat(hash[0]), parseFloat(hash[1])];
var initial_zoom = parseInt(hash[2]);
} else {
var initial_pos = points.length == 0 ? [0, 0] : points[0].coord;
var initial_zoom = 5;
}
var map = L.map('map', {
preferCanvas: true,
crs: L.CRS.EPSG3857, // default
attributionControl: false
}).setView(initial_pos, initial_zoom);
for(var i=0;i<points.length;i++) {
L.circleMarker(points[i].coord, {
color: '#3388ff'
}).addTo(map).bindPopup(
'<a href="/photo/' + points[i].uuid + '">' +
'<img src="/thumb/set/feed/' + points[i].uuid + '.jpg"/>' +
'</a>' +
'<span>' + points[i].date + '</span>');
}
var baseMaps = {
"Google Earth": L.tileLayer('http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
}),
"Google Hybrid": L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
}),
"Google Streets": L.tileLayer('http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
}),
"Google Terrain": L.tileLayer('http://{s}.google.com/vt/lyrs=p&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
}),
"OSM Streets": L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {}).addTo(map),
};
var layerControl = L.control.layers(baseMaps).addTo(map);
// when resolving_hash is > 0 we ignore the map's moveend events as to avoid pushing state during a pop
var resolving_hash = 0;
// last_hash is used to avoid pushing duplicate states (e.g. zoom/panning an amount that is rounded out)
var last_hash = window.location.hash;
// we set a dynamic title by prepending the coordinates onto the original html title
var base_title = document.getElementsByTagName("title")[0].text
var updateTitle = function() {
var center = map.getCenter();
document.title = center.lat.toFixed(5) + ", " + center.lng.toFixed(5) + " - " + base_title;
}
var updateState = function() {
if(resolving_hash) {
return;
}
var center = map.getCenter();
var zoom = map.getZoom();
var hash = "#" + center.lat.toFixed(5) + "," + center.lng.toFixed(5) + "," + zoom
if(hash == last_hash) {
return;
}
var state = {
pos: [
center.lat,
center.lng,
],
zoom: zoom,
};
history.pushState(state, null, hash);
last_hash = hash;
updateTitle();
}
addEventListener('popstate', function(state) {
var state = state.state;
if (!state) {
return;
}
resolving_hash += 1;
map.setView(state.pos, state.zoom);
setTimeout(
function() {
resolving_hash -= 1;
},
500
)
});
map.on('moveend', updateState);
updateState();
updateTitle();
</script>
</div>
{% endblock %}