xref: /webtrees/resources/views/admin/location-edit.phtml (revision bb776aef74c9d079a66d6c419c133fd5c2ec4e48)
1d70512abSGreg Roach<?php
2d70512abSGreg Roach
394e35917SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\MapDataList;
4d70512abSGreg Roachuse Fisharebest\Webtrees\I18N;
59a9dfcf7SGreg Roachuse Fisharebest\Webtrees\PlaceLocation;
6d70512abSGreg Roachuse Fisharebest\Webtrees\View;
7d70512abSGreg Roach
89a9dfcf7SGreg Roach/**
99a9dfcf7SGreg Roach * @var array<string,string> $breadcrumbs
109a9dfcf7SGreg Roach * @var string               $latitude
119a9dfcf7SGreg Roach * @var string               $longitude
129a9dfcf7SGreg Roach * @var PlaceLocation        $location
139a9dfcf7SGreg Roach * @var array<array<float>>  $map_bounds
149a9dfcf7SGreg Roach * @var <array<float>        $marker_position
159a9dfcf7SGreg Roach * @var PlaceLocation        $parent
169a9dfcf7SGreg Roach * @var mixed                $provider
179a9dfcf7SGreg Roach * @var string               $title
189a9dfcf7SGreg Roach */
199a9dfcf7SGreg Roach
20d70512abSGreg Roach?>
21dd6b2bfcSGreg Roach
22dd6b2bfcSGreg Roach<?= view('components/breadcrumbs', ['links' => $breadcrumbs]) ?>
23dd6b2bfcSGreg Roach
24dd6b2bfcSGreg Roach<h1><?= $title ?></h1>
25dd6b2bfcSGreg Roach
26dd6b2bfcSGreg Roach<div class="form-group row">
27e340fe65SGreg Roach    <div class="col-sm-12">
280b4092edSGreg Roach        <div id="osm-map" class="wt-ajax-load col-sm-12 osm-admin-map" dir="ltr"></div>
29dd6b2bfcSGreg Roach    </div>
30dd6b2bfcSGreg Roach</div>
31dd6b2bfcSGreg Roach
32dd6b2bfcSGreg Roach<form method="post">
33dd6b2bfcSGreg Roach    <?= csrf_field() ?>
349a9dfcf7SGreg Roach    <input type="hidden" name="place_id" value="<?= e($location->id()) ?>">
35dd6b2bfcSGreg Roach
36dd6b2bfcSGreg Roach    <div class="form-group row">
37dd6b2bfcSGreg Roach        <label class="col-form-label col-sm-1" for="new_place_name">
38dd6b2bfcSGreg Roach            <?= I18N::translate('Place') ?>
39dd6b2bfcSGreg Roach        </label>
40e340fe65SGreg Roach        <div class="col-sm-3">
41669e7094SGreg Roach            <input type="text" id="new_place_name" name="new_place_name" value="<?= e($location->locationName()) ?>" class="form-control" required maxlength="120" pattern="[^,]+">
42dd6b2bfcSGreg Roach        </div>
43e340fe65SGreg Roach
44e340fe65SGreg Roach        <input type="hidden" name="icon" id="icon" class="form-control" value="<?= e($location->icon()) ?>">
45dd6b2bfcSGreg Roach    </div>
46dd6b2bfcSGreg Roach
47dd6b2bfcSGreg Roach    <div class="form-group row">
4856a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_lati">
49dd6b2bfcSGreg Roach            <?= I18N::translate('Latitude') ?>
50dd6b2bfcSGreg Roach        </label>
51dd6b2bfcSGreg Roach        <div class="col-sm-3">
52dd6b2bfcSGreg Roach            <div class="input-group">
539a9dfcf7SGreg 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) ?>">
54dd6b2bfcSGreg Roach            </div>
55dd6b2bfcSGreg Roach        </div>
56e340fe65SGreg Roach    </div>
57dd6b2bfcSGreg Roach
58e340fe65SGreg Roach    <div class="form-group row">
5956a34df1SGreg Roach        <label class="col-form-label col-sm-1" for="new_place_long">
60dd6b2bfcSGreg Roach            <?= I18N::translate('Longitude') ?>
61dd6b2bfcSGreg Roach        </label>
62dd6b2bfcSGreg Roach        <div class="col-sm-3">
63dd6b2bfcSGreg Roach            <div class="input-group">
649a9dfcf7SGreg 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) ?>">
65dd6b2bfcSGreg Roach            </div>
66dd6b2bfcSGreg Roach        </div>
67e340fe65SGreg Roach
68e340fe65SGreg Roach        <input type="hidden" id="new_zoom_factor" name="new_zoom_factor" value="<?= e($location->zoom()) ?>" class="form-control">
69dd6b2bfcSGreg Roach    </div>
70dd6b2bfcSGreg Roach
71dd6b2bfcSGreg Roach    <div class="form-group row">
72dd6b2bfcSGreg Roach        <div class="col-sm-10 offset-sm-1">
73dd6b2bfcSGreg Roach            <button class="btn btn-primary" type="submit">
74dd6b2bfcSGreg Roach                <?= /* I18N: A button label. */
75dd6b2bfcSGreg Roach                I18N::translate('save')
76dd6b2bfcSGreg Roach                ?>
77dd6b2bfcSGreg Roach            </button>
7894e35917SGreg Roach            <a class="btn btn-secondary" href="<?= e(route(MapDataList::class, ['parent_id' => $parent->id()])) ?>">
79dd6b2bfcSGreg Roach                <?= I18N::translate('cancel') ?>
80dd6b2bfcSGreg Roach            </a>
81dd6b2bfcSGreg Roach        </div>
82dd6b2bfcSGreg Roach    </div>
83dd6b2bfcSGreg Roach</form>
84dd6b2bfcSGreg Roach
85dd6b2bfcSGreg Roach<?php View::push('styles') ?>
86dd6b2bfcSGreg Roach<style>
87dd6b2bfcSGreg Roach    .osm-admin-map {
88dd6b2bfcSGreg Roach        height: 55vh;
89dd6b2bfcSGreg Roach        border: 1px solid darkGrey
90dd6b2bfcSGreg Roach    }
91dd6b2bfcSGreg Roach</style>
92dd6b2bfcSGreg Roach<?php View::endpush() ?>
93dd6b2bfcSGreg Roach
94dd6b2bfcSGreg Roach<?php View::push('javascript') ?>
9574b9ba3fSGreg Roach<script>
96caa53803SDavid Drury    'use strict';
97dd6b2bfcSGreg Roach
98dd6b2bfcSGreg Roach    window.WT_OSM_ADMIN = (function () {
99caa53803SDavid Drury        const minZoom = 2;
1002cbb0620SDavid Drury
1012cbb0620SDavid Drury        let provider = <?= json_encode($provider) ?>;
102dd6b2bfcSGreg Roach        let map = null;
1039a9dfcf7SGreg Roach        let add_place = <?= json_encode($location->id() === 0) ?>;
104caa53803SDavid Drury
105caa53803SDavid Drury        // map components
106dd6b2bfcSGreg Roach
10775e7614aSGreg Roach        // postcss_image_inliner breaks the autodetection of image paths.
10875e7614aSGreg Roach        L.Icon.Default.imagePath = <?= json_encode(asset('css/images/')) ?>;
10975e7614aSGreg Roach
110caa53803SDavid Drury        // draggable marker
1119a9dfcf7SGreg Roach        let marker = L.marker(<?= json_encode($marker_position) ?>, {
112caa53803SDavid Drury            draggable: true,
113caa53803SDavid Drury        })
1149a9dfcf7SGreg Roach            .on('dragend', function () {
115dd6b2bfcSGreg Roach                let coords = marker.getLatLng();
116dd6b2bfcSGreg Roach                map.panTo(coords);
11762be603fSGreg Roach                $('#new_place_lati').val(Number(coords.lat).toFixed(5));
11862be603fSGreg Roach                $('#new_place_long').val(Number(coords.lng).toFixed(5));
11962be603fSGreg Roach                $('#new_zoom_factor').val(Number(map.getZoom()));
120dd6b2bfcSGreg Roach            });
121dd6b2bfcSGreg Roach
122caa53803SDavid Drury        //reset map to initial state
123caa53803SDavid Drury        let resetControl = L.Control.extend({
124caa53803SDavid Drury            options: {
125caa53803SDavid Drury                position: 'topleft'
126caa53803SDavid Drury            },
127caa53803SDavid Drury            onAdd: function (map) {
128caa53803SDavid Drury                let container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
129caa53803SDavid Drury                container.onclick = function () {
1309a9dfcf7SGreg Roach                    map.fitBounds(<?= json_encode($map_bounds) ?>, {padding: [50, 30]});
131e340fe65SGreg Roach                    marker.setLatLng(<?= json_encode([$location->latitude(), $location->longitude()]) ?>);
132caa53803SDavid Drury                    $('form').trigger('reset');
133caa53803SDavid Drury                    return false;
134caa53803SDavid Drury                };
13547ca61d5SGreg Roach                let reset = <?= json_encode(I18N::translate('Reset to initial map state')) ?>;
136caa53803SDavid Drury                let anchor = L.DomUtil.create('a', 'leaflet-control-reset', container);
137caa53803SDavid Drury                anchor.setAttribute('aria-label', reset);
138caa53803SDavid Drury                anchor.href = '#';
139caa53803SDavid Drury                anchor.title = reset;
140caa53803SDavid Drury                anchor.role = 'button';
141caa53803SDavid Drury                let image = L.DomUtil.create('i', 'fas fa-redo', anchor);
142caa53803SDavid Drury                image.alt = reset;
143dd6b2bfcSGreg Roach
144caa53803SDavid Drury                return container;
145caa53803SDavid Drury            }
146caa53803SDavid Drury        });
147dd6b2bfcSGreg Roach
148caa53803SDavid Drury        // zoom control with localised text
149caa53803SDavid Drury        let zoomCtl = new L.control.zoom({
150caa53803SDavid Drury            zoomInTitle:  <?= json_encode(I18N::translate('Zoom in')) ?>,
151caa53803SDavid Drury            zoomOutTitle: <?= json_encode(I18N::translate('Zoom out')) ?>,
152caa53803SDavid Drury        });
153caa53803SDavid Drury
154caa53803SDavid Drury        // Geocoder (place lookup)
155caa53803SDavid Drury        let geocoder = new L.Control.geocoder({
156caa53803SDavid Drury            defaultMarkGeocode: false,
15722b076ddSGreg Roach            expand: 'click',
158caa53803SDavid Drury            showResultIcons: true,
159*bb776aefSGreg Roach            query: <?= json_encode($location->locationName()) ?>,
160caa53803SDavid Drury            placeholder: <?= json_encode(I18N::translate('Place')) ?>,
161caa53803SDavid Drury            errorMessage: <?= json_encode(I18N::translate('Nothing found.')) ?>,
16247ca61d5SGreg Roach            iconLabel: <?= json_encode(I18N::translate('Search')) ?>
163caa53803SDavid Drury        })
164caa53803SDavid Drury            .on('markgeocode', function (result) {
165caa53803SDavid Drury                let coords = result.geocode.center;
166caa53803SDavid Drury                let place = result.geocode.name.split(',', 1);
167caa53803SDavid Drury                marker.setLatLng(coords);
168caa53803SDavid Drury                map.panTo(coords);
16962be603fSGreg Roach                if (add_place) {
17062be603fSGreg Roach                    $('#new_place_name').val(place.shift());
171caa53803SDavid Drury                }
17262be603fSGreg Roach                $('#new_place_lati').val(Number(coords.lat).toFixed(5));
17362be603fSGreg Roach                $('#new_place_long').val(Number(coords.lng).toFixed(5));
17462be603fSGreg Roach                $('#new_zoom_factor').val(Number(map.getZoom()));
17562be603fSGreg Roach            });
176caa53803SDavid Drury
177caa53803SDavid Drury        /**
178caa53803SDavid Drury         *
179caa53803SDavid Drury         * @private
180caa53803SDavid Drury         */
181dd6b2bfcSGreg Roach        $(function () {
182caa53803SDavid Drury            // geocoder button tooltip
183caa53803SDavid Drury            $('.leaflet-control-geocoder-icon')
18447ca61d5SGreg Roach                .attr('title', <?= json_encode(I18N::translate('Search')) ?>);
185caa53803SDavid Drury
1869a9dfcf7SGreg Roach            $('.editable').on('change', function () {
187caa53803SDavid Drury                let lat = $('#new_place_lati').val();
188caa53803SDavid Drury                let lng = $('#new_place_long').val();
189dd6b2bfcSGreg Roach                marker.setLatLng([lat, lng]);
190dd6b2bfcSGreg Roach                map.panTo([lat, lng]);
191dd6b2bfcSGreg Roach            });
192dd6b2bfcSGreg Roach        });
193dd6b2bfcSGreg Roach
194caa53803SDavid Drury        // Create the map with all controls and layers
195caa53803SDavid Drury        map = L.map('osm-map', {
196caa53803SDavid Drury            minZoom: minZoom, // maxZoom set by leaflet-providers.js
197caa53803SDavid Drury            zoomControl: false,   // remove default
198caa53803SDavid Drury        })
199caa53803SDavid Drury            .addControl(new resetControl())
200caa53803SDavid Drury            .addControl(zoomCtl)
201caa53803SDavid Drury            .addControl(geocoder)
202caa53803SDavid Drury            .addLayer(marker)
203caa53803SDavid Drury            .addLayer(L.tileLayer(provider.url, provider.options))
2049a9dfcf7SGreg Roach            .fitBounds(<?= json_encode($map_bounds) ?>, {padding: [50, 30]})
2059a9dfcf7SGreg Roach            .on('zoomend', function () {
206caa53803SDavid Drury                $('#new_zoom_factor').val(map.getZoom());
207caa53803SDavid Drury            });
208dd6b2bfcSGreg Roach
209caa53803SDavid Drury        return 'Leaflet map interface for webtrees-2';
210dd6b2bfcSGreg Roach    })();
211dd6b2bfcSGreg Roach</script>
212dd6b2bfcSGreg Roach<?php View::endpush() ?>
213