summaryrefslogtreecommitdiffci
path: root/views/partials/global-map-widget.html
blob: f50020f96a5fa7f8e2074277bdf0531fda9f2e54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<div
    id="map-container"
    class="bg-paper bg-background-dark flex z-10 w-full h-full"
></div>

<script>
(function() {
    var map;
    var markers = L.markerClusterGroup();
    const THUMB_BASE = "{{ .PhotoStorage.Thumbnail320p.BaseUrl }}";

    function createCustomIcon(color, borderColor = "var(--color-main-soft)") {
        const svgIcon = `
            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 1C7.5 1 4 4.5 4 9c0 6.5 8 14 8 14s8-7.5 8-14c0-4.5-3.5-8-8-8zm0 11c-1.5 0-3-1.5-3-3s1.5-3 3-3 3 1.5 3 3-1.5 3-3 3z"
                        fill="${color}"
                        stroke="${borderColor}"
                        stroke-width="1"
                        stroke-linejoin="round"/>
            </svg>
        `;

        return L.divIcon({
            html: svgIcon,
            className: 'custom-svg-marker',
            iconSize: [32, 32],
            iconAnchor: [16, 32],
            popupAnchor: [0, -32]
        });
    }

    function initLocationMap() {
        map = L.map('map-container').setView([{{ .MapLocationLat }}, {{ .MapLocationLong }}], {{ .MapLocationZoom }});

        protomapsL.leafletLayer({
            url: '{{ .StaticStorage.Map.BaseUrl }}/{{ .StaticStorage.Map.PMTiles }}',
            maxZoom: 15,
            flavor: window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light',
            lang: '{{ .Lang }}'
        }).addTo(map);

        {{- with .ZoomPosition }}
        L.control.zoom({
            position: '{{ . }}'
        }).addTo(map);
        {{- end }}

        map.addLayer(markers);
    }

    function markerToHsl(str, newCoef) {
        let hash = 0;
        for (let i = 0; i < str.length / 2; i++) {
            hash = str.charCodeAt(i) + ((hash << 5) - hash);
            hash = str.charCodeAt(str.length - i - 1) + ((hash << 5) - hash);
            hash %= 360;
        }

        return [hash, (20 + newCoef * 80).toFixed(0), (20 + newCoef * 75).toFixed(0)];
    }

    function mapAddMarker(x, y, relativeErrorMeters = 0, title = "", link = "", thumbnail = "", newCoef = 1, toHighlight = false) {
        const [h, s, l] = markerToHsl(title, newCoef);
        const color = `hsl(${h} ${s}% ${l}%)`;

        if (relativeErrorMeters != 0) {
            var circle = L.circle([x, y], {
                color: color,
                fillColor: color,
                fillOpacity: 0.15,
                radius: relativeErrorMeters
            }).addTo(map);
        }

        var marker = L.marker([x, y], {
            icon: createCustomIcon(color),
            title: title,
        }).bindPopup(`
                <div class="flex flex-row justify-center justify-items-center">
                    <img onclick="location.href='${link}';" class="cursor-pointer object-cover rounded-[10%] select-none w-12 h-12 mr-1" src="${THUMB_BASE.replace('%s', thumbnail)}">
                    <span><b><a href="${link}">${title}</a></b><br><a href="https://www.openstreetmap.org/#map=13/${x}/${y}">${x}, ${y}</a></span>
                </div>`);

        markers.addLayer(marker);

        if (toHighlight) {
            markers.zoomToShowLayer(marker, () => marker.openPopup());
        }
    }

    initLocationMap();
    {{- range .MapMarkers }}
    mapAddMarker({{ .Lat }}, {{ .Long }}, {{ .AccuracyMeters }}, {{ .Title }}, {{ .PageLink }}, {{ .Thumbnail }}, {{ fdiv .Index (len $.MapMarkers) }}, {{ .ToHighlight }});
    {{- end }}

    function onResize() {
        setTimeout(() => {
            if (map) map.invalidateSize();
        }, 300);
    }
    window.addEventListener('resize', onResize);
    new MutationObserver((muts, obs) => {
        if (!document.getElementById('map-container')) {
            window.removeEventListener('resize', onResize);
            obs.disconnect();
        }
    }).observe(document.body, { childList: true, subtree: true });
})();
</script>