1d70512abSGreg Roach<?php 2d70512abSGreg Roach 394e35917SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\MapDataList; 490949315SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\MapDataSave; 5d70512abSGreg Roachuse Fisharebest\Webtrees\I18N; 69a9dfcf7SGreg Roachuse Fisharebest\Webtrees\PlaceLocation; 7d70512abSGreg Roachuse Fisharebest\Webtrees\View; 8d70512abSGreg Roach 99a9dfcf7SGreg Roach/** 109a9dfcf7SGreg Roach * @var array<string,string> $breadcrumbs 119a9dfcf7SGreg Roach * @var string $latitude 12c9c6f2ecSGreg Roach * @var object $leaflet_config 139a9dfcf7SGreg Roach * @var string $longitude 149a9dfcf7SGreg Roach * @var PlaceLocation $location 159a9dfcf7SGreg Roach * @var array<array<float>> $map_bounds 1690949315SGreg Roach * @var array<float> $marker_position 179a9dfcf7SGreg Roach * @var PlaceLocation $parent 189a9dfcf7SGreg Roach * @var string $title 199a9dfcf7SGreg Roach */ 209a9dfcf7SGreg Roach 21d70512abSGreg Roach?> 22dd6b2bfcSGreg Roach 23dd6b2bfcSGreg Roach<?= view('components/breadcrumbs', ['links' => $breadcrumbs]) ?> 24dd6b2bfcSGreg Roach 25dd6b2bfcSGreg Roach<h1><?= $title ?></h1> 26dd6b2bfcSGreg Roach 27*84df6051SGreg Roach<div id="wt-map" class="wt-ajax-load mb-3 border wt-location-edit-map" dir="ltr"></div> 28dd6b2bfcSGreg Roach 292a93faa6SGreg Roach<form method="post" action="<?= e(route(MapDataSave::class)) ?>"> 30dd6b2bfcSGreg Roach <?= csrf_field() ?> 312a93faa6SGreg Roach <input type="hidden" name="parent_id" value="<?= e($parent->id()) ?>"> 322a93faa6SGreg Roach <input type="hidden" name="place_id" value="<?= e($location->id()) ?>"> 33dd6b2bfcSGreg Roach 34afc2d190SGreg Roach <div class="row form-group mb-3"> 35dd6b2bfcSGreg Roach <label class="col-form-label col-sm-1" for="new_place_name"> 36dd6b2bfcSGreg Roach <?= I18N::translate('Place') ?> 37dd6b2bfcSGreg Roach </label> 38e340fe65SGreg Roach <div class="col-sm-3"> 397dca5265SGreg Roach <input type="text" id="new_place_name" name="new_place_name" value="<?= e($location->locationName()) ?>" class="form-control" required="required" maxlength="120" pattern="[^,]+" dir="auto"> 40dd6b2bfcSGreg Roach </div> 41dd6b2bfcSGreg Roach </div> 42dd6b2bfcSGreg Roach 43afc2d190SGreg Roach <div class="row form-group mb-3"> 4456a34df1SGreg Roach <label class="col-form-label col-sm-1" for="new_place_lati"> 45dd6b2bfcSGreg Roach <?= I18N::translate('Latitude') ?> 46dd6b2bfcSGreg Roach </label> 47dd6b2bfcSGreg Roach <div class="col-sm-3"> 48dd6b2bfcSGreg Roach <div class="input-group"> 4990949315SGreg Roach <input type="text" dir="ltr" id="new_place_lati" class="editable form-control" name="new_place_lati" placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($latitude) ?>"> 50dd6b2bfcSGreg Roach </div> 51dd6b2bfcSGreg Roach </div> 52e340fe65SGreg Roach </div> 53dd6b2bfcSGreg Roach 54afc2d190SGreg Roach <div class="row form-group mb-3"> 5556a34df1SGreg Roach <label class="col-form-label col-sm-1" for="new_place_long"> 56dd6b2bfcSGreg Roach <?= I18N::translate('Longitude') ?> 57dd6b2bfcSGreg Roach </label> 58dd6b2bfcSGreg Roach <div class="col-sm-3"> 59dd6b2bfcSGreg Roach <div class="input-group"> 6090949315SGreg Roach <input type="text" dir="ltr" id="new_place_long" class="editable form-control" name="new_place_long" placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($longitude) ?>"> 61dd6b2bfcSGreg Roach </div> 62dd6b2bfcSGreg Roach </div> 63dd6b2bfcSGreg Roach </div> 64dd6b2bfcSGreg Roach 65afc2d190SGreg Roach <div class="row form-group mb-3"> 66dd6b2bfcSGreg Roach <div class="col-sm-10 offset-sm-1"> 67dd6b2bfcSGreg Roach <button class="btn btn-primary" type="submit"> 68dd6b2bfcSGreg Roach <?= /* I18N: A button label. */ 69dd6b2bfcSGreg Roach I18N::translate('save') 70dd6b2bfcSGreg Roach ?> 71dd6b2bfcSGreg Roach </button> 7294e35917SGreg Roach <a class="btn btn-secondary" href="<?= e(route(MapDataList::class, ['parent_id' => $parent->id()])) ?>"> 73dd6b2bfcSGreg Roach <?= I18N::translate('cancel') ?> 74dd6b2bfcSGreg Roach </a> 75dd6b2bfcSGreg Roach </div> 76dd6b2bfcSGreg Roach </div> 77dd6b2bfcSGreg Roach</form> 78dd6b2bfcSGreg Roach 79dd6b2bfcSGreg Roach<?php View::push('javascript') ?> 8074b9ba3fSGreg Roach<script> 81caa53803SDavid Drury 'use strict'; 82dd6b2bfcSGreg Roach 8304a72e8fSDavid Drury (function () { 84728c8c27SGreg Roach const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>; 85728c8c27SGreg Roach const add_place = <?= json_encode($location->id() === null, JSON_THROW_ON_ERROR) ?>; 862cbb0620SDavid Drury 8704a72e8fSDavid Drury let new_place_lati = document.getElementById('new_place_lati'); 8804a72e8fSDavid Drury let new_place_long = document.getElementById('new_place_long'); 8904a72e8fSDavid Drury 9075e7614aSGreg Roach // postcss_image_inliner breaks the autodetection of image paths. 91728c8c27SGreg Roach L.Icon.Default.imagePath = <?= json_encode(asset('css/images/'), JSON_THROW_ON_ERROR) ?>; 9275e7614aSGreg Roach 93caa53803SDavid Drury // draggable marker 94728c8c27SGreg Roach let marker = L.marker(<?= json_encode($marker_position, JSON_THROW_ON_ERROR) ?>, { 95caa53803SDavid Drury draggable: true, 96caa53803SDavid Drury }) 979a9dfcf7SGreg Roach .on('dragend', function () { 98dd6b2bfcSGreg Roach let coords = marker.getLatLng(); 99dd6b2bfcSGreg Roach map.panTo(coords); 10004a72e8fSDavid Drury new_place_lati.value = Number(coords.lat).toFixed(5); 10104a72e8fSDavid Drury new_place_long.value = Number(coords.lng).toFixed(5); 102dd6b2bfcSGreg Roach }); 103dd6b2bfcSGreg Roach 104caa53803SDavid Drury //reset map to initial state 105caa53803SDavid Drury let resetControl = L.Control.extend({ 106caa53803SDavid Drury options: { 107caa53803SDavid Drury position: 'topleft' 108caa53803SDavid Drury }, 109caa53803SDavid Drury onAdd: function (map) { 110caa53803SDavid Drury let container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom'); 111caa53803SDavid Drury container.onclick = function () { 112728c8c27SGreg Roach map.fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]}); 113728c8c27SGreg Roach marker.setLatLng(<?= json_encode([$location->latitude(), $location->longitude()], JSON_THROW_ON_ERROR) ?>); 11404a72e8fSDavid Drury document.querySelector('form').reset(); 11504a72e8fSDavid Drury 116caa53803SDavid Drury return false; 117caa53803SDavid Drury }; 118c9c6f2ecSGreg Roach let reset = config.i18n.reset; 119caa53803SDavid Drury let anchor = L.DomUtil.create('a', 'leaflet-control-reset', container); 120caa53803SDavid Drury anchor.setAttribute('aria-label', reset); 121caa53803SDavid Drury anchor.href = '#'; 122caa53803SDavid Drury anchor.title = reset; 123caa53803SDavid Drury anchor.role = 'button'; 124caa53803SDavid Drury let image = L.DomUtil.create('i', 'fas fa-redo', anchor); 125caa53803SDavid Drury image.alt = reset; 126dd6b2bfcSGreg Roach 127caa53803SDavid Drury return container; 128caa53803SDavid Drury } 129caa53803SDavid Drury }); 130dd6b2bfcSGreg Roach 131caa53803SDavid Drury // Geocoder (place lookup) 132caa53803SDavid Drury let geocoder = new L.Control.geocoder({ 133c9c6f2ecSGreg Roach position: 'bottomleft', 134caa53803SDavid Drury defaultMarkGeocode: false, 13522b076ddSGreg Roach expand: 'click', 136caa53803SDavid Drury showResultIcons: true, 137728c8c27SGreg Roach query: <?= json_encode($location->locationName(), JSON_THROW_ON_ERROR) ?>, 138728c8c27SGreg Roach placeholder: <?= json_encode(I18N::translate('Place'), JSON_THROW_ON_ERROR) ?>, 139728c8c27SGreg Roach errorMessage: <?= json_encode(I18N::translate('Nothing found.'), JSON_THROW_ON_ERROR) ?>, 140728c8c27SGreg Roach iconLabel: <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?> 141caa53803SDavid Drury }) 142caa53803SDavid Drury .on('markgeocode', function (result) { 143caa53803SDavid Drury let coords = result.geocode.center; 144164ab4fbSDavid Drury let place = result.geocode.name.split(',', 1).toString(); 145caa53803SDavid Drury marker.setLatLng(coords); 146caa53803SDavid Drury map.panTo(coords); 14762be603fSGreg Roach if (add_place) { 14804a72e8fSDavid Drury document.getElementById('new_place_name').value = place 149caa53803SDavid Drury } 15004a72e8fSDavid Drury new_place_lati.value = Number(coords.lat).toFixed(5); 15104a72e8fSDavid Drury new_place_long.value = Number(coords.lng).toFixed(5); 15262be603fSGreg Roach }); 153caa53803SDavid Drury 15404a72e8fSDavid Drury const map = webtrees.buildLeafletJsMap('wt-map', config) 155caa53803SDavid Drury .addControl(new resetControl()) 156caa53803SDavid Drury .addControl(geocoder) 157caa53803SDavid Drury .addLayer(marker) 158728c8c27SGreg Roach .fitBounds(<?= json_encode($map_bounds, JSON_THROW_ON_ERROR) ?>, {padding: [50, 30]}) 1599a9dfcf7SGreg Roach .on('zoomend', function () { 160d3a6a36aSGreg Roach if (!map.getBounds().contains(marker.getLatLng())) { 161d3a6a36aSGreg Roach map.panTo(marker.getLatLng()); 162d3a6a36aSGreg Roach } 163caa53803SDavid Drury }); 164dd6b2bfcSGreg Roach 16504a72e8fSDavid Drury document.querySelectorAll('.editable').forEach((element) => { 16604a72e8fSDavid Drury element.addEventListener('change', () => { 16704a72e8fSDavid Drury let lat = new_place_lati.value; 16804a72e8fSDavid Drury let lng = new_place_long.value; 16904a72e8fSDavid Drury marker.setLatLng([lat, lng]); 17004a72e8fSDavid Drury map.panTo([lat, lng]); 17104a72e8fSDavid Drury }); 17204a72e8fSDavid Drury }); 17304a72e8fSDavid Drury 17404a72e8fSDavid Drury window.onload = function() { 17504a72e8fSDavid Drury let icon = document.querySelector('.leaflet-control-geocoder-icon'); 17604a72e8fSDavid Drury icon.setAttribute('title', <?= json_encode(I18N::translate('Search'), JSON_THROW_ON_ERROR) ?>); 17704a72e8fSDavid Drury } 178dd6b2bfcSGreg Roach })(); 179dd6b2bfcSGreg Roach</script> 180dd6b2bfcSGreg Roach<?php View::endpush() ?> 181