treeadvisor/server/static/app.js

152 lines
4.6 KiB
JavaScript

const TREES_MIN_ZOOM = 17;
var map = L.map('map').setView([51.05, 13.75], TREES_MIN_ZOOM, {
maxZoom: 20,
});
var tiles = L.tileLayer('https://stamen-tiles.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg', {
attribution: '&copy; <a href="https://osm.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 17,
}).addTo(map);
var HeatmapLayer = L.TileLayer.extend({
getTileUrl: function (coords) {
var cs = this._tileCoordsToNwSe(coords);
var x1 = Math.min(cs[0].lng, cs[1].lng);
var y1 = Math.min(cs[0].lat, cs[1].lat);
var x2 = Math.max(cs[0].lng, cs[1].lng);
var y2 = Math.max(cs[0].lat, cs[1].lat);
return ["", "heatmap", x1, y1, x2, y2].join("/");
},
});
L.tileLayer('/heatmap/{z}/{x}/{y}/tile.png', {
maxZoom: TREES_MIN_ZOOM - 1,
opacity: 0.8,
}).addTo(map);
var treeIcon = L.icon({
iconUrl: "tree.png",
iconSize: [12, 12],
iconAnchor: [6, 6],
popupAnchor: [0, -6],
});
function treePopup(coords, entry) {
var popup = L.popup()
.setLatLng(coords);
popup.on('add', function() {
var info = {};
function update(newInfo) {
Object.keys(newInfo).forEach(function(k) {
info[k] = newInfo[k];
});
popup.setContent(function() {
var div = document.createElement("div");
var h2 = document.createElement("h2");
h2.textContent = entry.german;
if (entry.age)
h2.textContent += " (" + entry.age + ")";
div.appendChild(h2);
var p = document.createElement("p");
p.textContent = entry.botanic;
div.appendChild(p);
if (info.area) {
p = document.createElement("p");
p.textContent = JSON.stringify(info.area);
div.appendChild(p);
}
if (info.tree) {
p = document.createElement("p");
p.style.maxHeight = "10em";
p.style.overflow = "scroll";
p.textContent = JSON.stringify(info.tree);
div.appendChild(p);
}
return div;
});
}
update({});
fetch(["", "area", coords[1], coords[0]].join("/"))
.then(res => res.json())
.then(data => {
update({ area: data });
});
fetch(["", "tree", entry.id].join("/"))
.then(res => res.json())
.then(data => {
console.log("tree data", data);
update({ tree: data });
});
});
return popup;
}
var trees;
var trees_pending = false;
var visible_trees;
function updateTrees() {
if (map.getZoom() < TREES_MIN_ZOOM) {
if (trees) {
trees.remove();
trees = null;
}
return;
}
var bounds = map.getBounds();
if (!trees) {
trees = L.layerGroup().addTo(map);
visible_trees = {};
} else {
trees.eachLayer(function(marker) {
var ll = marker.getLatLng();
if (ll.lng < bounds.getWest() || ll.lng > bounds.getEast() ||
ll.lat < bounds.getSouth() || ll.lat > bounds.getNorth()) {
delete visible_trees[marker.options.id];
trees.removeLayer(marker);
}
});
}
if (trees_pending) return;
trees_pending = true;
fetch(["", "trees", bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()].join("/"))
.then(res => res.json())
.then(data => {
if (map.getZoom() < TREES_MIN_ZOOM) {
return;
}
data.forEach(function(entry) {
var coords = [entry.coords[1], entry.coords[0]];
if (entry.planted) {
entry.age = Math.round((Date.now() - Date.parse(entry.planted)) / (365.25 * 24 * 60 * 60 * 1000));
}
if (!visible_trees[entry.id]) {
visible_trees[entry.id] = true;
var marker = L.marker(coords, {
id: entry.id,
title: entry.german,
icon: treeIcon,
}).bindPopup(treePopup(coords, entry));
trees.addLayer(marker);
}
});
trees_pending = false;
})
.catch (error => {
console.error('Error:' + error)
trees_pending = false;
});
}
map.on('moveend', updateTrees);
map.on('zoomend', updateTrees);
updateTrees();