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="<?= $place_id ?>"> 18 <input type="hidden" name="level" value="<?= count($hierarchy) ?>"> 19 <input type="hidden" name="place_long" value="<?= $lng ?>"> 20 <input type="hidden" name="place_lati" value="<?= $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->getPlace()) ?>" 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->getIcon(), 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="<?= $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="<?= $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="<?= $location->getZoom() ?>" 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 124 [dir=rtl] .leaflet-right { 125 right: auto; 126 left: 0 127 } 128 129 [dir=rtl] .leaflet-right .leaflet-control { 130 margin-right: 0; 131 margin-left: 10px 132 } 133 134 [dir=rtl] .leaflet-left { 135 left: auto; 136 right: 0 137 } 138 139 [dir=rtl] .leaflet-left .leaflet-control { 140 margin-left: 0; 141 margin-right: 10px 142 } 143</style> 144<?php View::endpush() ?> 145 146<?php View::push('javascript') ?> 147<script type="application/javascript"> 148 "use strict"; 149 150 window.WT_OSM_ADMIN = (function () { 151 let baseData = { 152 minZoom: 2, 153 providerName: "OpenStreetMap.Mapnik", 154 providerOptions: [], 155 I18N: { 156 zoomInTitle: <?= json_encode(I18N::translate('Zoom in')) ?>, 157 zoomOutTitle: <?= json_encode(I18N::translate('Zoom out')) ?>, 158 reset: <?= json_encode(I18N::translate('Reset to initial map state')) ?>, 159 noData: <?= json_encode(I18N::translate('No mappable items')) ?>, 160 error: <?= json_encode(I18N::translate('An unknown error occurred')) ?> 161 } 162 }; 163 164 let map = null; 165 let marker = L.marker([0, 0], { 166 draggable: true, 167 }); 168 /** 169 * 170 * @private 171 */ 172 let _drawMap = function () { 173 map = L.map("osm-map", { 174 center: [0, 0], 175 minZoom: baseData.minZoom, // maxZoom set by leaflet-providers.js 176 zoomControl: false, // remove default 177 }, 178 ); 179 L.tileLayer.provider(baseData.providerName, baseData.providerOptions).addTo(map); 180 L.control.zoom({ // Add zoom with localised text 181 zoomInTitle: baseData.I18N.zoomInTitle, 182 zoomOutTitle: baseData.I18N.zoomOutTitle, 183 }).addTo(map); 184 185 marker 186 .on("dragend", function (e) { 187 let coords = marker.getLatLng(); 188 map.panTo(coords); 189 _update_Controls({ 190 place: "", 191 coords: coords, 192 zoom: map.getZoom(), 193 }); 194 }) 195 .addTo(map); 196 let searchControl = new window.GeoSearch.GeoSearchControl({ 197 provider: new window.GeoSearch.OpenStreetMapProvider(), 198 retainZoomLevel: true, 199 autoClose: true, 200 showMarker: false, 201 }); 202 203 map 204 .addControl(searchControl) 205 .on("geosearch/showlocation", function (result) { 206 let lat = result.location.y; 207 let lng = result.location.x; 208 let place = result.location.label.split(",", 1); 209 210 marker.setLatLng([lat, lng]); 211 map.panTo([lat, lng]); 212 213 _update_Controls({ 214 place: place.shift(), 215 coords: { 216 "lat": lat, 217 "lng": lng, 218 }, 219 zoom: map.getZoom(), 220 }); 221 }) 222 .on("zoomend", function (e) { 223 $("#new_zoom_factor").val(map.getZoom()); 224 map.panTo(marker.getLatLng()); 225 }); 226 }; 227 228 let data = <?= json_encode($data) ?>; 229 230 /** 231 * 232 * @param newData 233 * @private 234 */ 235 let _update_Controls = function (newData) { 236 let placeEl = $("#new_place_name"); 237 if (!placeEl.val().length && newData.place.length) { 238 placeEl.val(newData.place); 239 } 240 $("#new_place_lati").val(Number(newData.coords.lat).toFixed(5)); // 5 decimal places (about 1 metre accuracy) 241 $("#new_place_long").val(Number(newData.coords.lng).toFixed(5)); 242 $("#new_zoom_factor").val(Number(newData.zoom)); 243 }; 244 245 $(function () { 246 $(".editable").on("change", function (e) { 247 let lat = $("#new_place_lati").val(); 248 let lng = $("#new_place_long").val(); 249 marker.setLatLng([lat, lng]); 250 map.panTo([lat, lng]); 251 }); 252 }); 253 254 /** 255 * 256 * @param id 257 */ 258 let initialize = function (id) { 259 _drawMap(); 260 261 marker.setLatLng(data.coordinates); 262 263 if (data.coordinates[0] === 0 && data.coordinates[1] === 0) { 264 map.fitWorld(); 265 } else { 266 map.setView(data.coordinates, data.zoom); 267 } 268 }; 269 270 return { 271 /** 272 * 273 * @param id 274 */ 275 drawMap: function (id) { 276 initialize(id); 277 }, 278 }; 279 })(); 280 281 WT_OSM_ADMIN.drawMap(<?= json_encode($ref) ?>); 282</script> 283<?php View::endpush() ?> 284