1d70512abSGreg Roach<?php 2d70512abSGreg Roach 3d70512abSGreg Roachuse Fisharebest\Webtrees\I18N; 49a9dfcf7SGreg Roachuse Fisharebest\Webtrees\PlaceLocation; 5d70512abSGreg Roachuse Fisharebest\Webtrees\View; 6d70512abSGreg Roach 79a9dfcf7SGreg Roach/** 89a9dfcf7SGreg Roach * @var array<string,string> $breadcrumbs 99a9dfcf7SGreg Roach * @var string $latitude 109a9dfcf7SGreg Roach * @var string $longitude 119a9dfcf7SGreg Roach * @var PlaceLocation $location 129a9dfcf7SGreg Roach * @var array<array<float>> $map_bounds 139a9dfcf7SGreg Roach * @var <array<float> $marker_position 149a9dfcf7SGreg Roach * @var PlaceLocation $parent 159a9dfcf7SGreg Roach * @var mixed $provider 169a9dfcf7SGreg Roach * @var string $title 179a9dfcf7SGreg Roach */ 189a9dfcf7SGreg Roach 19d70512abSGreg Roach?> 20dd6b2bfcSGreg Roach 21dd6b2bfcSGreg Roach<?= view('components/breadcrumbs', ['links' => $breadcrumbs]) ?> 22dd6b2bfcSGreg Roach 23dd6b2bfcSGreg Roach<h1><?= $title ?></h1> 24dd6b2bfcSGreg Roach 25dd6b2bfcSGreg Roach<div class="form-group row"> 26e340fe65SGreg Roach <div class="col-sm-12"> 270b4092edSGreg Roach <div id="osm-map" class="wt-ajax-load col-sm-12 osm-admin-map" dir="ltr"></div> 28dd6b2bfcSGreg Roach </div> 29dd6b2bfcSGreg Roach</div> 30dd6b2bfcSGreg Roach 31dd6b2bfcSGreg Roach<form method="post"> 32dd6b2bfcSGreg Roach <?= csrf_field() ?> 339a9dfcf7SGreg Roach <input type="hidden" name="place_id" value="<?= e($location->id()) ?>"> 34dd6b2bfcSGreg Roach 35dd6b2bfcSGreg Roach <div class="form-group row"> 36dd6b2bfcSGreg Roach <label class="col-form-label col-sm-1" for="new_place_name"> 37dd6b2bfcSGreg Roach <?= I18N::translate('Place') ?> 38dd6b2bfcSGreg Roach </label> 39e340fe65SGreg Roach <div class="col-sm-3"> 40*669e7094SGreg Roach <input type="text" id="new_place_name" name="new_place_name" value="<?= e($location->locationName()) ?>" class="form-control" required maxlength="120" pattern="[^,]+"> 41dd6b2bfcSGreg Roach </div> 42e340fe65SGreg Roach 43e340fe65SGreg Roach <input type="hidden" name="icon" id="icon" class="form-control" value="<?= e($location->icon()) ?>"> 44dd6b2bfcSGreg Roach </div> 45dd6b2bfcSGreg Roach 46dd6b2bfcSGreg Roach <div class="form-group row"> 4756a34df1SGreg Roach <label class="col-form-label col-sm-1" for="new_place_lati"> 48dd6b2bfcSGreg Roach <?= I18N::translate('Latitude') ?> 49dd6b2bfcSGreg Roach </label> 50dd6b2bfcSGreg Roach <div class="col-sm-3"> 51dd6b2bfcSGreg Roach <div class="input-group"> 529a9dfcf7SGreg Roach <input type="text" dir="ltr" id="new_place_lati" class="editable form-control" name="new_place_lati" required placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($latitude) ?>"> 53dd6b2bfcSGreg Roach </div> 54dd6b2bfcSGreg Roach </div> 55e340fe65SGreg Roach </div> 56dd6b2bfcSGreg Roach 57e340fe65SGreg Roach <div class="form-group row"> 5856a34df1SGreg Roach <label class="col-form-label col-sm-1" for="new_place_long"> 59dd6b2bfcSGreg Roach <?= I18N::translate('Longitude') ?> 60dd6b2bfcSGreg Roach </label> 61dd6b2bfcSGreg Roach <div class="col-sm-3"> 62dd6b2bfcSGreg Roach <div class="input-group"> 639a9dfcf7SGreg Roach <input type="text" dir="ltr" id="new_place_long" class="editable form-control" name="new_place_long" required placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($longitude) ?>"> 64dd6b2bfcSGreg Roach </div> 65dd6b2bfcSGreg Roach </div> 66e340fe65SGreg Roach 67e340fe65SGreg Roach <input type="hidden" id="new_zoom_factor" name="new_zoom_factor" value="<?= e($location->zoom()) ?>" class="form-control"> 68dd6b2bfcSGreg Roach </div> 69dd6b2bfcSGreg Roach 70dd6b2bfcSGreg Roach <div class="form-group row"> 71dd6b2bfcSGreg Roach <div class="col-sm-10 offset-sm-1"> 72dd6b2bfcSGreg Roach <button class="btn btn-primary" type="submit"> 73dd6b2bfcSGreg Roach <?= /* I18N: A button label. */ 74dd6b2bfcSGreg Roach I18N::translate('save') 75dd6b2bfcSGreg Roach ?> 76dd6b2bfcSGreg Roach </button> 779a9dfcf7SGreg Roach <a class="btn btn-secondary" href="<?= e(route('map-data', ['parent_id' => $parent->id()])) ?>"> 78dd6b2bfcSGreg Roach <?= I18N::translate('cancel') ?> 79dd6b2bfcSGreg Roach </a> 80dd6b2bfcSGreg Roach </div> 81dd6b2bfcSGreg Roach </div> 82dd6b2bfcSGreg Roach</form> 83dd6b2bfcSGreg Roach 84dd6b2bfcSGreg Roach<?php View::push('styles') ?> 85dd6b2bfcSGreg Roach<style> 86dd6b2bfcSGreg Roach .osm-admin-map { 87dd6b2bfcSGreg Roach height: 55vh; 88dd6b2bfcSGreg Roach border: 1px solid darkGrey 89dd6b2bfcSGreg Roach } 90dd6b2bfcSGreg Roach</style> 91dd6b2bfcSGreg Roach<?php View::endpush() ?> 92dd6b2bfcSGreg Roach 93dd6b2bfcSGreg Roach<?php View::push('javascript') ?> 9474b9ba3fSGreg Roach<script> 95caa53803SDavid Drury 'use strict'; 96dd6b2bfcSGreg Roach 97dd6b2bfcSGreg Roach window.WT_OSM_ADMIN = (function () { 98caa53803SDavid Drury const minZoom = 2; 992cbb0620SDavid Drury 1002cbb0620SDavid Drury let provider = <?= json_encode($provider) ?>; 101dd6b2bfcSGreg Roach let map = null; 1029a9dfcf7SGreg Roach let add_place = <?= json_encode($location->id() === 0) ?>; 103caa53803SDavid Drury 104caa53803SDavid Drury // map components 105dd6b2bfcSGreg Roach 10675e7614aSGreg Roach // postcss_image_inliner breaks the autodetection of image paths. 10775e7614aSGreg Roach L.Icon.Default.imagePath = <?= json_encode(asset('css/images/')) ?>; 10875e7614aSGreg Roach 109caa53803SDavid Drury // draggable marker 1109a9dfcf7SGreg Roach let marker = L.marker(<?= json_encode($marker_position) ?>, { 111caa53803SDavid Drury draggable: true, 112caa53803SDavid Drury }) 1139a9dfcf7SGreg Roach .on('dragend', function () { 114dd6b2bfcSGreg Roach let coords = marker.getLatLng(); 115dd6b2bfcSGreg Roach map.panTo(coords); 11662be603fSGreg Roach $('#new_place_lati').val(Number(coords.lat).toFixed(5)); 11762be603fSGreg Roach $('#new_place_long').val(Number(coords.lng).toFixed(5)); 11862be603fSGreg Roach $('#new_zoom_factor').val(Number(map.getZoom())); 119dd6b2bfcSGreg Roach }); 120dd6b2bfcSGreg Roach 121caa53803SDavid Drury //reset map to initial state 122caa53803SDavid Drury let resetControl = L.Control.extend({ 123caa53803SDavid Drury options: { 124caa53803SDavid Drury position: 'topleft' 125caa53803SDavid Drury }, 126caa53803SDavid Drury onAdd: function (map) { 127caa53803SDavid Drury let container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom'); 128caa53803SDavid Drury container.onclick = function () { 1299a9dfcf7SGreg Roach map.fitBounds(<?= json_encode($map_bounds) ?>, {padding: [50, 30]}); 130e340fe65SGreg Roach marker.setLatLng(<?= json_encode([$location->latitude(), $location->longitude()]) ?>); 131caa53803SDavid Drury $('form').trigger('reset'); 132caa53803SDavid Drury return false; 133caa53803SDavid Drury }; 13447ca61d5SGreg Roach let reset = <?= json_encode(I18N::translate('Reset to initial map state')) ?>; 135caa53803SDavid Drury let anchor = L.DomUtil.create('a', 'leaflet-control-reset', container); 136caa53803SDavid Drury anchor.setAttribute('aria-label', reset); 137caa53803SDavid Drury anchor.href = '#'; 138caa53803SDavid Drury anchor.title = reset; 139caa53803SDavid Drury anchor.role = 'button'; 140caa53803SDavid Drury let image = L.DomUtil.create('i', 'fas fa-redo', anchor); 141caa53803SDavid Drury image.alt = reset; 142dd6b2bfcSGreg Roach 143caa53803SDavid Drury return container; 144caa53803SDavid Drury } 145caa53803SDavid Drury }); 146dd6b2bfcSGreg Roach 147caa53803SDavid Drury // zoom control with localised text 148caa53803SDavid Drury let zoomCtl = new L.control.zoom({ 149caa53803SDavid Drury zoomInTitle: <?= json_encode(I18N::translate('Zoom in')) ?>, 150caa53803SDavid Drury zoomOutTitle: <?= json_encode(I18N::translate('Zoom out')) ?>, 151caa53803SDavid Drury }); 152caa53803SDavid Drury 153caa53803SDavid Drury // Geocoder (place lookup) 154caa53803SDavid Drury let geocoder = new L.Control.geocoder({ 155caa53803SDavid Drury defaultMarkGeocode: false, 15622b076ddSGreg Roach expand: 'click', 157caa53803SDavid Drury showResultIcons: true, 158caa53803SDavid Drury query: '<?= e($location->locationName()) ?>', 159caa53803SDavid Drury placeholder: <?= json_encode(I18N::translate('Place')) ?>, 160caa53803SDavid Drury errorMessage: <?= json_encode(I18N::translate('Nothing found.')) ?>, 16147ca61d5SGreg Roach iconLabel: <?= json_encode(I18N::translate('Search')) ?> 162caa53803SDavid Drury }) 163caa53803SDavid Drury .on('markgeocode', function (result) { 164caa53803SDavid Drury let coords = result.geocode.center; 165caa53803SDavid Drury let place = result.geocode.name.split(',', 1); 166caa53803SDavid Drury marker.setLatLng(coords); 167caa53803SDavid Drury map.panTo(coords); 16862be603fSGreg Roach if (add_place) { 16962be603fSGreg Roach $('#new_place_name').val(place.shift()); 170caa53803SDavid Drury } 17162be603fSGreg Roach $('#new_place_lati').val(Number(coords.lat).toFixed(5)); 17262be603fSGreg Roach $('#new_place_long').val(Number(coords.lng).toFixed(5)); 17362be603fSGreg Roach $('#new_zoom_factor').val(Number(map.getZoom())); 17462be603fSGreg Roach }); 175caa53803SDavid Drury 176caa53803SDavid Drury /** 177caa53803SDavid Drury * 178caa53803SDavid Drury * @private 179caa53803SDavid Drury */ 180dd6b2bfcSGreg Roach $(function () { 181caa53803SDavid Drury // geocoder button tooltip 182caa53803SDavid Drury $('.leaflet-control-geocoder-icon') 18347ca61d5SGreg Roach .attr('title', <?= json_encode(I18N::translate('Search')) ?>); 184caa53803SDavid Drury 1859a9dfcf7SGreg Roach $('.editable').on('change', function () { 186caa53803SDavid Drury let lat = $('#new_place_lati').val(); 187caa53803SDavid Drury let lng = $('#new_place_long').val(); 188dd6b2bfcSGreg Roach marker.setLatLng([lat, lng]); 189dd6b2bfcSGreg Roach map.panTo([lat, lng]); 190dd6b2bfcSGreg Roach }); 191dd6b2bfcSGreg Roach }); 192dd6b2bfcSGreg Roach 193caa53803SDavid Drury // Create the map with all controls and layers 194caa53803SDavid Drury map = L.map('osm-map', { 195caa53803SDavid Drury minZoom: minZoom, // maxZoom set by leaflet-providers.js 196caa53803SDavid Drury zoomControl: false, // remove default 197caa53803SDavid Drury }) 198caa53803SDavid Drury .addControl(new resetControl()) 199caa53803SDavid Drury .addControl(zoomCtl) 200caa53803SDavid Drury .addControl(geocoder) 201caa53803SDavid Drury .addLayer(marker) 202caa53803SDavid Drury .addLayer(L.tileLayer(provider.url, provider.options)) 2039a9dfcf7SGreg Roach .fitBounds(<?= json_encode($map_bounds) ?>, {padding: [50, 30]}) 2049a9dfcf7SGreg Roach .on('zoomend', function () { 205caa53803SDavid Drury $('#new_zoom_factor').val(map.getZoom()); 206caa53803SDavid Drury }); 207dd6b2bfcSGreg Roach 208caa53803SDavid Drury return 'Leaflet map interface for webtrees-2'; 209dd6b2bfcSGreg Roach })(); 210dd6b2bfcSGreg Roach</script> 211dd6b2bfcSGreg Roach<?php View::endpush() ?> 212