xref: /webtrees/resources/views/modules/place-hierarchy/map.phtml (revision b7b71725c00e545f55686e19948ab12c8a573982)
1<?php
2
3use Fisharebest\Webtrees\View;
4
5/**
6 * @var array<mixed> $data
7 * @var object       $leaflet_config
8 */
9
10?>
11
12<div class="row gchart wt-place-hierarchy-wrapper">
13    <div id="wt-map" class="col-sm-9 wt-ajax-load wt-map wt-place-hierarchy-map" dir="ltr"></div>
14    <ul class="col-sm-3 wt-place-hierarchy-sidebar wt-page-options-value list-unstyled px-md-1"></ul>
15</div>
16
17<?php View::push('javascript') ?>
18<script>
19  'use strict';
20
21  (function () {
22    const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
23
24    let map = null;
25    const sidebar = document.querySelector('.wt-place-hierarchy-sidebar');
26
27    const scrollOptions = {
28      behavior: "smooth",
29      block: "start",
30      inline: "start"
31    };
32
33    // Map components
34    let markers = L.markerClusterGroup({
35      showCoverageOnHover: false,
36    });
37
38    /**
39     * Passed to resetControl to
40     * perform necessary reset actions on map
41     */
42     let resetCallback = function () {
43      map.flyToBounds(markers.getBounds(), {padding: [50, 30], maxZoom: 15 });
44      sidebar.firstElementChild.scrollIntoView(scrollOptions);
45    }
46
47    /**
48     * @private
49     */
50    let _drawMap = function () {
51      map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback);
52    };
53
54    /**
55     * @private
56     */
57    let _buildMapData = function () {
58      let data = <?= json_encode($data['markers'], JSON_THROW_ON_ERROR) ?>;
59
60      let geoJsonLayer = L.geoJson(data, {
61        pointToLayer: function (feature, latlng) {
62          return new L.Marker(latlng, {
63            icon: L.BeautifyIcon.icon({
64              icon: 'bullseye fas',
65              borderColor: 'transparent',
66              backgroundColor: '#1e90ff',
67              iconShape: 'marker',
68              textColor: 'white',
69            }),
70            title: feature.properties.tooltip,
71            alt: feature.properties.tooltip,
72            id: feature.id,
73          })
74            .on('popupopen', function (e) {
75              let item = document.querySelector('.mapped[data-wt-feature-id="' + e.target.feature.id + '"]');
76              item.classList.add('messagebox');
77              item.scrollIntoView(scrollOptions);
78            })
79            .on('popupclose', function () {
80              sidebar.querySelectorAll('.mapped').forEach(e => e.classList.remove('messagebox'));
81              sidebar.firstElementChild.scrollIntoView(scrollOptions);
82            });
83        },
84        onEachFeature: function (feature, layer) {
85          layer.bindPopup(feature.properties.popup);
86        },
87      });
88
89      if (data.features.length > 0) {
90        markers.addLayer(geoJsonLayer);
91        map.addLayer(markers);
92      }
93
94      map.fitBounds(<?= json_encode($data['bounds'], JSON_THROW_ON_ERROR) ?>, { padding: [50, 30] });
95      sidebar.innerHTML = <?= json_encode($data['sidebar'], JSON_THROW_ON_ERROR) ?>;
96   };
97
98    window.onload = function() {
99      // Activate marker popup when sidebar entry clicked
100      sidebar.querySelectorAll('.mapped').forEach((element) => {
101        var eventId = parseInt(element.dataset.wtFeatureId);
102
103        element.addEventListener('click', () => {
104          // first close any existing
105          map.closePopup();
106          //find the marker corresponding to the clicked event
107          let mkrLayer = markers.getLayers().filter(function (v) {
108            return v.feature !== undefined && v.feature.id === eventId;
109          });
110
111          let mkr = mkrLayer.pop();
112
113          markers.zoomToShowLayer(mkr, function (e) {
114            mkr.openPopup();
115          });
116
117          return false;
118        });
119
120        // stop clicking on a person also opening the popup
121        element.querySelectorAll('a').forEach((el) => {
122          el.addEventListener('click', (e) => {
123            e.stopPropagation();
124          });
125        });
126      });
127    }
128
129    _drawMap();
130    _buildMapData();
131  })();
132</script>
133<?php View::endpush() ?>
134