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