xref: /webtrees/resources/views/admin/location-edit.phtml (revision da58fa21ddd29f92b1fde63c8ee425cf3d7f4eee)
1<?php use Fisharebest\Webtrees\Functions\FunctionsEdit; ?>
2<?php use Fisharebest\Webtrees\I18N; ?>
3<?php use Fisharebest\Webtrees\View; ?>
4
5<?= view('components/breadcrumbs', ['links' => $breadcrumbs]) ?>
6
7<h1><?= $title ?></h1>
8
9<div class="form-group row">
10    <div class="col-sm-10 offset-sm-1">
11        <div id="osm-map" class="wt-ajax-load col-sm-12 osm-admin-map"></div>
12    </div>
13</div>
14
15<form method="post">
16    <?= csrf_field() ?>
17    <input type="hidden" name="place_id" value="<?= e($place_id) ?>">
18    <input type="hidden" name="level" value="<?= count($hierarchy) ?>">
19    <input type="hidden" name="place_long" value="<?= e($lng) ?>">
20    <input type="hidden" name="place_lati" value="<?= e($lat) ?>">
21
22    <div class="form-group row">
23        <label class="col-form-label col-sm-1" for="new_place_name">
24            <?= I18N::translate('Place') ?>
25        </label>
26        <div class="col-sm-5">
27            <input type="text" id="new_place_name" name="new_place_name" value="<?= e($location->locationName()) ?>"
28            class="form-control" required>
29        </div>
30        <label class="col-form-label col-sm-1" for="icon">
31            <?= I18N::translate('Flag') ?>
32        </label>
33        <div class="col-sm-4">
34            <div class="input-group" dir="ltr">
35                <?= FunctionsEdit::formControlFlag(
36                    $location->icon(),
37                    ['name' => 'icon', 'id' => 'icon', 'class' => 'form-control']
38                )
39?>
40            </div>
41        </div>
42    </div>
43
44    <div class="form-group row">
45        <label class="col-form-label col-sm-1">
46            <?= I18N::translate('Latitude') ?>
47        </label>
48        <div class="col-sm-3">
49            <div class="input-group">
50                <input type="text" dir="ltr" id="new_place_lati" class="editable form-control" name="new_place_lati" required
51                placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($lat) ?>"
52                >
53            </div>
54        </div>
55
56        <label class="col-form-label col-sm-1">
57            <?= I18N::translate('Longitude') ?>
58        </label>
59        <div class="col-sm-3">
60            <div class="input-group">
61                <input type="text" dir="ltr" id="new_place_long" class="editable form-control" name="new_place_long" required
62                placeholder="<?= I18N::translate('degrees') ?>" value="<?= e($lng) ?>"
63                >
64            </div>
65        </div>
66        <label class="col-form-label col-sm-1" for="new_zoom_factor">
67            <?= I18N::translate('Zoom') ?>
68        </label>
69        <div class="col-sm-2">
70            <input type="text" id="new_zoom_factor" name="new_zoom_factor" value="<?= e($location->zoom()) ?>"
71            class="form-control" required readonly>
72        </div>
73    </div>
74
75    <div class="form-group row">
76        <div class="col-sm-10 offset-sm-1">
77            <button class="btn btn-primary" type="submit">
78                <?= /* I18N: A button label. */
79                I18N::translate('save')
80                ?>
81            </button>
82            <a class="btn btn-secondary" href="<?= e(route('map-data', ['parent_id' => $parent_id])) ?>">
83                <?= I18N::translate('cancel') ?>
84            </a>
85        </div>
86    </div>
87</form>
88
89<?php View::push('styles') ?>
90<style>
91    .osm-wrapper, .osm-user-map {
92        height: 45vh
93    }
94
95    .osm-admin-map {
96        height: 55vh;
97        border: 1px solid darkGrey
98    }
99
100    .osm-sidebar {
101        height: 100%;
102        overflow-y: auto;
103        padding: 0;
104        margin: 0;
105        border: 0;
106        display: none;
107        font-size: small;
108    }
109
110    .osm-sidebar .gchart {
111        margin: 1px;
112        padding: 2px
113    }
114
115    .osm-sidebar .gchart img {
116        height: 15px;
117        width: 25px
118    }
119
120    .osm-sidebar .border-danger:hover {
121        cursor: not-allowed
122    }
123</style>
124<?php View::endpush() ?>
125
126<?php View::push('javascript') ?>
127<script type="application/javascript">
128  "use strict";
129
130  window.WT_OSM_ADMIN = (function () {
131    let baseData = {
132      minZoom:         2,
133      providerName:    "OpenStreetMap.Mapnik",
134      providerOptions: [],
135      I18N:            {
136        zoomInTitle: <?= json_encode(I18N::translate('Zoom in')) ?>,
137        zoomOutTitle: <?= json_encode(I18N::translate('Zoom out')) ?>,
138        reset: <?= json_encode(I18N::translate('Reset to initial map state')) ?>,
139        noData: <?= json_encode(I18N::translate('No mappable items')) ?>,
140        error: <?= json_encode(I18N::translate('An unknown error occurred')) ?>
141      }
142    };
143
144    let map      = null;
145    let marker   = L.marker([0, 0], {
146      draggable: true,
147    });
148    /**
149     *
150     * @private
151     */
152    let _drawMap = function () {
153      map = L.map("osm-map", {
154          center:      [0, 0],
155          minZoom:     baseData.minZoom, // maxZoom set by leaflet-providers.js
156          zoomControl: false, // remove default
157        },
158      );
159      L.tileLayer.provider(baseData.providerName, baseData.providerOptions).addTo(map);
160      L.control.zoom({ // Add zoom with localised text
161        zoomInTitle:  baseData.I18N.zoomInTitle,
162        zoomOutTitle: baseData.I18N.zoomOutTitle,
163      }).addTo(map);
164
165      marker
166        .on("dragend", function (e) {
167          let coords = marker.getLatLng();
168          map.panTo(coords);
169          _update_Controls({
170            place:  "",
171            coords: coords,
172            zoom:   map.getZoom(),
173          });
174        })
175        .addTo(map);
176      let searchControl = new window.GeoSearch.GeoSearchControl({
177        provider:        new window.GeoSearch.OpenStreetMapProvider(),
178        retainZoomLevel: true,
179        autoClose:       true,
180        showMarker:      false,
181      });
182
183      map
184        .addControl(searchControl)
185        .on("geosearch/showlocation", function (result) {
186          let lat   = result.location.y;
187          let lng   = result.location.x;
188          let place = result.location.label.split(",", 1);
189
190          marker.setLatLng([lat, lng]);
191          map.panTo([lat, lng]);
192
193          _update_Controls({
194            place:  place.shift(),
195            coords: {
196              "lat": lat,
197              "lng": lng,
198            },
199            zoom:   map.getZoom(),
200          });
201        })
202        .on("zoomend", function (e) {
203          $("#new_zoom_factor").val(map.getZoom());
204          map.panTo(marker.getLatLng());
205        });
206    };
207
208    let data = <?= json_encode($data) ?>;
209
210    /**
211     *
212     * @param newData
213     * @private
214     */
215    let _update_Controls = function (newData) {
216      let placeEl = $("#new_place_name");
217      if (!placeEl.val().length && newData.place.length) {
218        placeEl.val(newData.place);
219      }
220      $("#new_place_lati").val(Number(newData.coords.lat).toFixed(5)); // 5 decimal places (about 1 metre accuracy)
221      $("#new_place_long").val(Number(newData.coords.lng).toFixed(5));
222      $("#new_zoom_factor").val(Number(newData.zoom));
223    };
224
225    $(function () {
226      $(".editable").on("change", function (e) {
227        let lat = $("#new_place_lati").val();
228        let lng = $("#new_place_long").val();
229        marker.setLatLng([lat, lng]);
230        map.panTo([lat, lng]);
231      });
232    });
233
234    /**
235     *
236     * @param id
237     */
238    let initialize = function (id) {
239      _drawMap();
240
241      marker.setLatLng(data.coordinates);
242
243      if (data.coordinates[0] === 0 && data.coordinates[1] === 0) {
244        map.fitWorld();
245      } else {
246        map.setView(data.coordinates, data.zoom);
247      }
248    };
249
250    return {
251      /**
252       *
253       * @param id
254       */
255      drawMap: function (id) {
256        initialize(id);
257      },
258    };
259  })();
260
261  WT_OSM_ADMIN.drawMap(<?= json_encode($ref) ?>);
262</script>
263<?php View::endpush() ?>
264