lawrencedeerclub/map.html

154 lines
5.4 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lawrence Deer Club Maps</title>
<link rel="stylesheet" href="/leaflet/leaflet.css" />
<script src="/leaflet/leaflet.js"></script>
<style>
html, body {
margin: 0;
padding: 0;
}
#map {
height: 100vh;
width: 100vw;
}
div.popup dt {
font-weight: bold;
}
.label {
font-weight: bold;
text-align: center;
margin-top: -1em;
}
.label div {
position: relative;
left: -50%;
top: 10px;
text-shadow: 0 0 2px white;
}
.leaflet-popup-content-wrapper {
height: min(800px, 60vh);
overflow-y: auto;
}
#popupcontainer {
position: relative;
z-index: 1000;
}
#popupcontainer .leaflet-popup-content-wrapper {
height: unset;
}
#popupcontainer .leaflet-popup {
transform: none !important;
position: fixed;
width: 100vw;
height: 100vh;
right: 0;
left: 0 !important;
top: 1em;
bottom: 1em !important;
overflow: auto;
}
#popupcontainer .leaflet-popup-content {
width: initial;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="popupcontainer" class="leaflet-container"></div>
<script>
(async function() {
const map = L.map('map', {
minZoom: 12,
maxZoom: 21,
maxBounds: [
[47.517085, -93.427584],
[47.457925, -93.340026],
],
}).setView([94.505, -0.09], 13);
// L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
// maxZoom: 19,
// attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
// }).addTo(map);
L.tileLayer('./satellite/{z}/{x}/{y}.jpg', {
minNativeZoom: 12,
maxNativeZoom: 20,
bounds: [
[47.517085, -93.427584],
[47.457925, -93.340026],
],
}).addTo(map);
// Make these requests in parallel
const track_req_promise = fetch('data/track.geojson');
const plats_req_promise = fetch('data/plats.geojson');
const data_req_promise = fetch('data/data.json');
const track_req = await track_req_promise;
const plats_req = await plats_req_promise;
const data_req = await data_req_promise;
const track = await track_req.json();
const plats = await plats_req.json();
const data = await data_req.json();
L.geoJSON(track).addTo(map);
L.geoJSON(plats, {
filter: feature => !feature.properties.TAO_NAME.toLowerCase().includes("lawrence deer club"),
onEachFeature: function(feature, layer) {
const latLngs = layer.getLatLngs()[0];
const centerish = [ // TODO: actual centroid
latLngs.reduce((acc, i) => acc + i.lat, 0) / latLngs.length,
latLngs.reduce((acc, i) => acc + i.lng, 0) / latLngs.length,
];
const label = L.marker(centerish, {
icon: L.divIcon({
iconSize: null,
className: "label",
html: "<div>" + feature.properties.TAO_NAME + "</div>"
})
}).addTo(map);
},
}).addTo(map);
for (let stand of data.stands) {
if (stand.location) {
const marker = L.marker(stand.location).addTo(map);
const popupContentWrapper = document.createElement('div');
popupContentWrapper.classList.add('popup');
let attributesString = '<dl>';
for (let [attribute, value] of Object.entries(stand.attributes)) {
attributesString += `<dt>${attribute}</dt><dd>${value}</dd>`;
}
attributesString += '</dl>';
popupContentWrapper.innerHTML = `
<h2>${stand.name}</h2>
<img style="width: min(80vw, 300px);" src="images/${stand.image}">
${attributesString}
`;
let popupOptions = {};
// TODO: evaluate this when creating popup instead of at
// page instantiation time -- if the page is resized, this
// won't keep up with those changes.
if (window.visualViewport.width < 600) {
popupOptions.pane = document.getElementById('popupcontainer');
}
marker.bindPopup(popupContentWrapper, popupOptions);
}
}
map.fitBounds([
[47.4865,-93.4068],
[47.4992,-93.3746],
]);
})();
</script>
</body>
</html>