This is more or less the same as the campsites, as public information goes, but for buildings and other amenities that the camping provides that are not campsites.
138 lines
4.5 KiB
JavaScript
138 lines
4.5 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
const container = document.getElementById('campground_map');
|
|
container.style.height = '80vh';
|
|
|
|
const svg = container.childNodes[0];
|
|
svg.remove();
|
|
|
|
const latLngBounds = L.latLngBounds([[0, 0], [1192, 1500]]);
|
|
const map = L.map(container, {
|
|
center: latLngBounds.getCenter(),
|
|
minZoom: -2,
|
|
maxZoom: 2,
|
|
zoom: -1,
|
|
scrollWheelZoom: false,
|
|
//maxBounds: latLngBounds,
|
|
//maxBoundsViscosity: 1.0,
|
|
zoomSnap: 0,
|
|
crs: L.CRS.Simple,
|
|
});
|
|
map.fitBounds(latLngBounds);
|
|
L.svgOverlay(svg, latLngBounds).addTo(map);
|
|
|
|
// from https://github.com/jkroso/parse-svg-path/
|
|
const parse = (function () {
|
|
'use strict';
|
|
|
|
const length = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0}
|
|
const segment = /([astvzqmhlc])([^astvzqmhlc]*)/ig;
|
|
const number = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/ig;
|
|
|
|
function parseValues(args) {
|
|
const numbers = args.match(number)
|
|
return numbers ? numbers.map(Number) : []
|
|
}
|
|
|
|
return function (path) {
|
|
const data = []
|
|
path.replace(segment, function (_, command, args) {
|
|
let type = command.toLowerCase()
|
|
args = parseValues(args)
|
|
|
|
// overloaded moveTo
|
|
if (type === 'm' && args.length > 2) {
|
|
data.push([command].concat(args.splice(0, 2)))
|
|
type = 'l'
|
|
command = command === 'm' ? 'l' : 'L'
|
|
}
|
|
|
|
while (true) {
|
|
if (args.length === length[type]) {
|
|
args.unshift(command)
|
|
return data.push(args)
|
|
}
|
|
if (args.length < length[type]) throw new Error('malformed path data')
|
|
data.push([command].concat(args.splice(0, length[type])))
|
|
}
|
|
})
|
|
return data
|
|
}
|
|
})();
|
|
|
|
function highlightAccommodation(e) {
|
|
const layer = e.target;
|
|
layer.setStyle({
|
|
color: '#ffe673',
|
|
});
|
|
layer.bringToFront();
|
|
}
|
|
|
|
function resetHighlight(e) {
|
|
const layer = e.target;
|
|
layer.setStyle({
|
|
color: 'transparent',
|
|
});
|
|
}
|
|
|
|
// XXX: this is from the “parceles” layer.
|
|
const ctm = [1, 0, 0, 1, 83.2784, 66.1766];
|
|
|
|
function transform(x, y) {
|
|
return [ctm[0] * x + ctm[2] * y + ctm[4], ctm[1] * x + ctm[3] * y + ctm[5]];
|
|
}
|
|
|
|
function setupFeatures(prefix, baseURI) {
|
|
for (const campsite of Array.from(container.querySelectorAll(`[id^="${prefix}"]`))) {
|
|
const label = campsite.id.substring(prefix.length);
|
|
if (!label) {
|
|
continue;
|
|
}
|
|
const path = campsite.firstElementChild;
|
|
const commands = parse(path.getAttribute('d'));
|
|
const points = [];
|
|
const p0 = [0, 0];
|
|
for (const cmd of commands) {
|
|
switch (cmd[0]) {
|
|
case 'M':
|
|
case 'L':
|
|
const cmdM = transform(cmd[1], cmd[2]);
|
|
p0[0] = cmdM[0];
|
|
p0[1] = latLngBounds.getNorth() - cmdM[1];
|
|
break;
|
|
case 'm':
|
|
case 'l':
|
|
p0[0] += cmd[1];
|
|
p0[1] -= cmd[2];
|
|
break;
|
|
case 'C':
|
|
const cmdC = transform(cmd[5], cmd[6]);
|
|
p0[0] = cmdC[0];
|
|
p0[1] = latLngBounds.getNorth() - cmdC[1];
|
|
break;
|
|
case 'Z':
|
|
case 'z':
|
|
continue;
|
|
default:
|
|
console.error(cmd);
|
|
}
|
|
points.push([p0[1], p0[0]]);
|
|
}
|
|
console.log(points);
|
|
const feature = L.polygon(points, {color: 'transparent'}).addTo(map);
|
|
feature.on({
|
|
mouseover: highlightAccommodation,
|
|
mouseout: resetHighlight,
|
|
click: function () {
|
|
window.location = `${baseURI}/${label}`;
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
const language = document.documentElement.getAttribute('lang');
|
|
setupFeatures('cp_', `/${language}/campsites`)
|
|
setupFeatures('cr_', `/${language}/amenities`)
|
|
})();
|