2021-08-26 01:13:49 +02:00
|
|
|
const TREES_MIN_ZOOM = 17;
|
|
|
|
|
|
|
|
var map = L.map('map').setView([51.05, 13.75], TREES_MIN_ZOOM, {
|
|
|
|
});
|
|
|
|
|
|
|
|
attribution: '© <a href="https://osm.org/copyright">OpenStreetMap</a> contributors',
|
2021-08-27 02:14:17 +02:00
|
|
|
maxZoom: 30,
|
2021-08-26 01:13:49 +02:00
|
|
|
}).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("/");
|
|
|
|
},
|
|
|
|
});
|
2021-08-26 17:35:55 +02:00
|
|
|
L.tileLayer('/heatmap/{z}/{x}/{y}/tile.png', {
|
2021-08-26 01:13:49 +02:00
|
|
|
maxZoom: TREES_MIN_ZOOM - 1,
|
2021-08-26 17:35:55 +02:00
|
|
|
opacity: 0.8,
|
|
|
|
}).addTo(map);
|
2021-08-26 01:13:49 +02:00
|
|
|
|
|
|
|
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();
|