1(function($) { 2 3 $( document ).ready(function() { 4 5 class createMap { 6 7 constructor(mapDiv, xy, z, vectorSource) { 8 9 this.mapCanvas = new ol.Map({ 10 controls: [ 11 new ol.control.Attribution({collapsible: true, collapsed: false}), 12 new ol.control.Zoom(), 13 new ol.control.FullScreen() 14 ], 15 target: mapDiv, 16 view: new ol.View({ 17 center: xy, 18 zoom: z, 19 minZoom: 4, 20 maxZoom: 21 21 }) 22 }); 23 24 this.osmLayer = new ol.layer.Tile({ 25 preload: Infinity, 26 visible: true, 27 opacity: 1, 28 source: osmSource, 29 clickable: false 30 }); 31 32 this.bingLayer = new ol.layer.Tile({ 33 preload: Infinity, 34 visible: false, 35 opacity: 1, 36 source: bingSource, 37 clickable: false 38 }); 39 40 this.terrLayer = new ol.layer.Tile({ 41 preload: Infinity, 42 visible: false, 43 opacity: 1, 44 source: terrSource, 45 clickable: false 46 }); 47 48 this.hillLayer = new ol.layer.Tile({ 49 preload: Infinity, 50 visible: false, 51 opacity: 1, 52 source: hillSource, 53 clickable: false 54 }); 55 56 this.nlsLayer = new ol.layer.Tile({ 57 preload: Infinity, 58 visible: false, 59 opacity: 1, 60 source: nlsSource, 61 clickable: false 62 }); 63 64 this.markerLayer = new ol.layer.Vector({ 65 source: vectorSource, 66 clickable: true, 67 name: "placenames" 68 }); 69 70 this.canmoreLayer = new ol.layer.Vector({ 71 source: canmoreSource, 72 clickable: true, 73 name: "canmore" 74 }); 75 76/* 77 const styleCache = {}; 78 79 this.clusterLayer = new ol.layer.Vector({ 80 source: clusterSource, 81 style: function (feature) { 82 const size = feature.get('features').length; 83 let style = styleCache[size]; 84 if (!style) { 85 style = new ol.style.Style({ 86 image: new ol.style.Circle({ 87 radius: size/100, 88 stroke: new ol.style.Stroke({ 89 color: '#fff', 90 }), 91 fill: new ol.style.Fill({ 92 color: '#3399CC', 93 }), 94 }) 95 }); 96 styleCache[size] = style; 97 } 98 return style; 99 } 100 }); 101 */ 102 this.mapCanvas.addLayer(this.osmLayer); 103 this.mapCanvas.addLayer(this.bingLayer); 104 this.mapCanvas.addLayer(this.terrLayer); 105 this.mapCanvas.addLayer(this.hillLayer); 106 this.mapCanvas.addLayer(this.nlsLayer); 107 this.mapCanvas.addLayer(this.markerLayer); 108 this.mapCanvas.addLayer(this.canmoreLayer); 109// this.mapCanvas.addLayer(this.clusterLayer); 110 111 this.boundOsmButtonListener = this.osmButtonListener.bind(this); 112 this.boundBingButtonListener = this.bingButtonListener.bind(this); 113 this.boundTerrButtonListener = this.terrButtonListener.bind(this); 114 this.boundHillButtonListener = this.hillButtonListener.bind(this); 115 this.boundNlsButtonListener = this.nlsButtonListener.bind(this); 116// this.boundMarkerButtonListener = this.markerButtonListener.bind(this); 117// this.boundCanmoreButtonListener = this.canmoreButtonListener.bind(this); 118 119 /* Create tooltip overlay */ 120 121 const elementTooltipOverlay = document.createElement('div'); 122 elementTooltipOverlay.style.display = 'none'; 123 $('#' + mapDiv).append(elementTooltipOverlay); 124 125 this.tooltipOverlay = new ol.Overlay({ 126 element: elementTooltipOverlay, 127 offset: [10, 0], 128 positioning: 'bottom-left', 129 stopEvent: false, 130 className: 'tooltip' 131 }); 132 133 const elementMenuOverlay = document.createElement('div'); 134 elementMenuOverlay.style.display = 'none'; 135 $('#' + mapDiv).append(elementMenuOverlay); 136 137 this.menuOverlay = new ol.Overlay({ 138 element: elementMenuOverlay, 139 offset: [10, 0], 140 positioning: 'bottom-left', 141 stopEvent: false, 142 className: 'tooltip' 143 }); 144 145 146 this.mapCanvas.addOverlay(this.tooltipOverlay); 147 this.mapCanvas.on('pointermove', displayTooltip); 148 149 /* Create scale line */ 150 151 this.mapCanvas.addControl(new ol.control.ScaleLine({ minWidth:100 })); 152 153 const basePanel = document.createElement('div'); 154 basePanel.className = 'ol-unselectable ol-control'; 155 basePanel.style.left = "3em"; 156 basePanel.style.top = "0.5em"; 157 158 const osmButton = document.createElement('button'); 159 osmButton.innerHTML = 'Map'; 160 osmButton.style.width="auto"; 161 osmButton.style.display="inline"; 162 osmButton.style.padding="0 0.5em"; 163 osmButton.classList = "buttonOn"; 164 osmButton.addEventListener('click', this.boundOsmButtonListener); 165 basePanel.appendChild(osmButton); 166 167 const bingButton = document.createElement('button'); 168 bingButton.innerHTML = 'Satellite'; 169 bingButton.style.width="auto"; 170 bingButton.style.display="inline"; 171 bingButton.style.padding="0 0.5em"; 172 bingButton.addEventListener('click', this.boundBingButtonListener); 173 basePanel.appendChild(bingButton); 174 175 const terrButton = document.createElement('button'); 176 terrButton.innerHTML = 'Contours'; 177 terrButton.style.width="auto"; 178 terrButton.style.display="inline"; 179 terrButton.style.padding="0 0.5em"; 180 terrButton.addEventListener('click', this.boundTerrButtonListener); 181 basePanel.appendChild(terrButton); 182 183 const hillButton = document.createElement('button'); 184 hillButton.innerHTML = 'Hillshade'; 185 hillButton.style.width="auto"; 186 hillButton.style.display="inline"; 187 hillButton.style.padding="0 0.5em"; 188 hillButton.addEventListener('click', this.boundHillButtonListener); 189 basePanel.appendChild(hillButton); 190 191 const nlsButton = document.createElement('button'); 192 nlsButton.innerHTML = 'Historic'; 193 nlsButton.style.width="auto"; 194 nlsButton.style.display="inline"; 195 nlsButton.style.padding="0 0.5em"; 196 nlsButton.addEventListener('click', this.boundNlsButtonListener); 197 basePanel.appendChild(nlsButton); 198 199 this.mapCanvas.addControl( 200 new ol.control.Control({ 201 element: basePanel 202 }) 203 ); 204 205 } 206 207 osmButtonListener(e) { 208 if (!this.osmLayer.getVisible()) { 209 this.osmLayer.setVisible(true); 210 this.terrLayer.setVisible(false); 211 this.hillLayer.setVisible(false); 212 this.bingLayer.setVisible(false); 213 this.nlsLayer.setVisible(false); 214 for (let ctrl of e.target.parentElement.children) ctrl.classList.remove('buttonOn'); 215 e.target.classList.add('buttonOn'); 216 } 217 e.preventDefault(); 218 } 219 220 bingButtonListener(e) { 221 if (!this.bingLayer.getVisible()) { 222 this.osmLayer.setVisible(false); 223 this.terrLayer.setVisible(false); 224 this.hillLayer.setVisible(false); 225 this.bingLayer.setVisible(true); 226 this.nlsLayer.setVisible(false); 227 for (let ctrl of e.target.parentElement.children) ctrl.classList.remove('buttonOn'); 228 e.target.classList.add('buttonOn'); 229 } 230 e.preventDefault(); 231 } 232 233 terrButtonListener(e) { 234 if (!this.terrLayer.getVisible()) { 235 this.osmLayer.setVisible(false); 236 this.terrLayer.setVisible(true); 237 this.hillLayer.setVisible(false); 238 this.bingLayer.setVisible(false); 239 this.nlsLayer.setVisible(false); 240 for (let ctrl of e.target.parentElement.children) ctrl.classList.remove('buttonOn'); 241 e.target.classList.add('buttonOn'); 242 } 243 e.preventDefault(); 244 } 245 246 hillButtonListener(e) { 247 if (!this.hillLayer.getVisible()) { 248 this.osmLayer.setVisible(false); 249 this.terrLayer.setVisible(false); 250 this.hillLayer.setVisible(true); 251 this.bingLayer.setVisible(false); 252 this.nlsLayer.setVisible(false); 253 for (let ctrl of e.target.parentElement.children) ctrl.classList.remove('buttonOn'); 254 e.target.classList.add('buttonOn'); 255 } 256 e.preventDefault(); 257 } 258 259 nlsButtonListener(e) { 260 if (!this.nlsLayer.getVisible()) { 261 this.osmLayer.setVisible(false); 262 this.terrLayer.setVisible(false); 263 this.hillLayer.setVisible(false); 264 this.bingLayer.setVisible(false); 265 this.nlsLayer.setVisible(true); 266 for (let ctrl of e.target.parentElement.children) ctrl.classList.remove('buttonOn'); 267 e.target.classList.add('buttonOn'); 268 } 269 e.preventDefault(); 270 } 271/* 272 markerButtonListener(e) { 273 this.markerLayer.setVisible(!this.markerLayer.getVisible()); 274 e.target.classList.toggle('buttonOn'); 275 e.preventDefault(); 276 } 277*/ 278 } 279 280 281 const lonlat = [-4.22, 58]; // centre of Scotland - should be drawn from settings instead 282 283 284 /* Create National Grid projection and pass to OpenLayers */ 285 286 proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs'); 287 ol.proj.proj4.register(proj4); 288 289 /* Define all the map sources */ 290 291 const osmSource = new ol.source.OSM(); 292 293 const bingSource = new ol.source.BingMaps({ 294 key: 'Arq_Y1y01cm7uyo_HPsFPA0UKRuXt0Gf5Hn-XqqDH0a3XgMu___9fe_BXQ-Bpisg', 295 imagerySet: 'AerialWithLabelsOnDemand', 296 maxZoom: 19 297 }); 298 299 const terrSource = new ol.source.XYZ({ 300 url: 'https://api.maptiler.com/tiles/contours-v2/{z}/{x}/{y}.pbf?key=nkeWcbOvUA63RaX3ztNB', 301 minZoom: 1, 302 maxZoom: 17 303 }); 304 305 const hillSource = new ol.source.XYZ({ 306 url: 'https://api.maptiler.com/tiles/hillshade/{z}/{x}/{y}.pbf?key=nkeWcbOvUA63RaX3ztNB', 307 minZoom: 1, 308 maxZoom: 17 309 }); 310 311 const nlsSource = new ol.source.XYZ({ 312 urls:[ 313 'https://api.maptiler.com/tiles/uk-osgb1888/{z}/{x}/{y}?key=nkeWcbOvUA63RaX3ztNB' 314 ], 315 minZoom: 1, 316 maxZoom: 17, 317 attributions: [ '<a href=\"http://maps.nls.uk/projects/subscription-api/\">National Library of Scotland</a>' ], 318 tilePixelRatio: 1.000000 319 }); 320 321 const markerSource = new ol.source.Vector({}); 322 const canmoreSource = new ol.source.Vector({}); 323/* 324 const clusterSource = new ol.source.Cluster({ 325 distance: 35, 326 minDistance: 50, 327 source: markerSource 328 }); 329*/ 330 const siteSource = new ol.source.Vector({}); 331 332 const mainMap = new createMap('map', ol.proj.fromLonLat(lonlat), 5, markerSource); 333 334 var icons = [ 335 new ol.style.Style({ // red 336 image: new ol.style.Circle(({ 337 fill: new ol.style.Fill({ color: 'rgba(255,0,0,1)' }), 338 radius: 10, 339 stroke: new ol.style.Stroke({ color: 'rgba(0,0,0,1)', width: 1 }) 340 })), 341 zIndex : 4 342 }), 343 new ol.style.Style({ // orange 344 image: new ol.style.Circle(({ 345 fill: new ol.style.Fill({ color: 'rgba(255,165,0,1)' }), 346 radius: 10, 347 stroke: new ol.style.Stroke({ color: 'rgba(0,0,0,1)', width: 1 }) 348 })), 349 zIndex : 3 350 }), 351 new ol.style.Style({ // yellow 352 image: new ol.style.Circle(({ 353 fill: new ol.style.Fill({ color: 'rgba(255,255,0,1)' }), 354 radius: 10, 355 stroke: new ol.style.Stroke({ color: 'rgba(0,0,0,1)', width: 1 }) 356 })), 357 zIndex : 2 358 }), 359 new ol.style.Style({ // green 360 image: new ol.style.Circle(({ 361 fill: new ol.style.Fill({ color: 'rgba(0,255,0,1)' }), 362 radius: 10, 363 stroke: new ol.style.Stroke({ color: 'rgba(0,0,0,1)', width: 1 }) 364 })), 365 zIndex : 1 366 }), 367 new ol.style.Style({ // multiple 368 image: new ol.style.Circle(({ 369 fill: new ol.style.Fill({ color: 'rgba(255,255,255,1)' }), 370 radius: 10, 371 stroke: new ol.style.Stroke({ color: 'rgba(0,0,0,1)', width: 1 }) 372 })), 373 zIndex : 1 374 }) 375 ] 376 377 mainMap.mapCanvas.addControl(new ol.control.Control({ 378 element: document.getElementById('marker-filter') 379 })); 380 381 mainMap.mapCanvas.on('click', displayDetail); 382 383 $('#marker-filter').show(); 384 385 loadMarkers(); 386 387 $('#map-filter').on('click', function (e) { 388 e.preventDefault(); 389 loadMarkers(); 390 }); 391 392 $('#map-reset').on('click', function (e) { 393 e.preventDefault(); 394 $('#s').val(''); 395 $('pa_id').val(''); 396 $('#el_min').text('0'); 397 $('#el_max').text('1000'); 398 $('#el_range' ).slider( "values", [ 0, 1000 ] ); 399 loadMarkers(); 400 }); 401 402 $('#info-close').on('click', function (e) { 403 $('#info-wrapper').hide(); 404 $('#info-overlay').hide(); 405 }); 406 407 $('#info-wrapper').on('click', '.expand', function (e) { // expand or contract images and updates in detail view 408 e.preventDefault(); 409 $('#' + jQuery(this).data('id')).toggle(); 410 $(this).toggleClass('zoomin zoomout'); 411
411 }); 412 413 $('#csv-download').on('click', function(e) { 414 e.preventDefault(); 415 window.location.href = $(this).attr('href') + '&search='+$('#search').val()+'&authority='+$('#authority').val()+'&priority='+$('#priority').val(); 416 }); 417 418 function loadMarkers() { 419 420 $('#map-filter-wrap').hide(); 421 $('#marker-info').show(); 422 423 var params = 's=' + $('#s').val() 424 + '&pa_xtra=1' 425 + '&pa_code=' + $('#pa_code').val() 426 + '&el_min=' + $('#el_min').text() 427 + '&el_max=' + $('#el_max').text() 428 + '&_wpnonce=' + map_args['_wpnonce']; 429 430 console.log(params); 431 432 $.getJSON('https://pastpresentations.com/wp-json/fife-markers/v2/markers?force=9&' + params, function(data) { 433 434 const features = []; 435 var sites; 436 437 data = JSON.parse(data); 438 439 if (data.reports.length > 0) { 440 441 for (var i = 0; i < data.reports.length; i++) { 442 443 item = data.reports[i]; 444 445 if (item.pn_lat != 0 && item.pn_lng != 0) { 446 447 let iconFeature = new ol.Feature({ 448 geometry: new ol.geom.Point(ol.proj.fromLonLat([item.pn_lng, item.pn_lat])), 449 name: item.pn_name, 450 id: item.pn_id, 451 orig_id: item.orig_id 452 }); 453 454 iconFeature.setId(item.pn_id); 455 iconFeature.setStyle(icons[0]); 456 features.push(iconFeature); 457 } 458 } 459 460 } 461 462 markerSource.clear(); // delete markers 463 464 if (features.length > 0) { 465 markerSource.addFeatures(features); 466 467 var layerExtent = markerSource.getExtent(); 468 469 if (layerExtent) { 470 mainMap.mapCanvas.getView().fit(layerExtent); 471 } 472 } 473 474 canmoreSource.clear(); // delete markers 475 476 if (data.canmore.length > 0) { 477 478 for (let i = 0; i < data.canmore.length; i++) { 479 480 item = data.canmore[i]; 481 482 if (item.cm_lat != 0 && item.cm_lng != 0) { 483 484 let iconFeature = new ol.Feature({ 485 geometry: new ol.geom.Point(ol.proj.fromLonLat([item.cm_lng, item.cm_lat])), 486 name: item.cm_name, 487 orig_id: item.cm_canmore_id, 488 }); 489 490 iconFeature.setId(item.cm_id); 491 iconFeature.setStyle( 492 new ol.style.Style({ 493 image: new ol.style.Icon({ 494 src: "https://pastpresentations.com/wp-content/plugins/fife/assets/images/icon.png", 495 }) 496 }) 497 ); 498 499 canmoreSource.addFeature(iconFeature); 500 501 } 502 } 503 504 } 505 506// clusterSource.setSource(markerSource); 507 $('#marker-info').hide(); 508 $('#map-filter-wrap').show(); 509 510 }); 511 512 } 513 514 function displayDetail(e) { 515 516 const features = []; 517 518 e.map.forEachFeatureAtPixel( 519 e.pixel, 520 function(feature, layer) { 521 522 if (features.length == 0) { // top marker 523 524 if (layer.get('name') == 'canmore') { 525 e.preventDefault; 526 window.open('http://canmore.org.uk/site/' + feature.get('orig_id'), '_blank'); 527 return; 528 } 529 530 features.push(feature); 531 } 532 else { 533 if (JSON.stringify(feature.getGeometry().getCoordinates()) === JSON.stringify(features[0].getGeometry().getCoordinates())) { 534 features.push(feature); 535 } 536 } 537 }, 538 { 539 layerFilter: function(layer) { 540 return layer.get("clickable"); 541 } 542 } 543 ); 544 545 if (features.length > 0) { 546 547 if (features.length == 1) { 548 displayPlacename(features[0].get('id')); 549 } 550 551 else { 552 553 var os = ''; 554
555 features.forEach( function(feature) { 556 os += '<p class="shore-menuitem" data-id="' + feature.get('id') + '"><span class="p' + feature.get('pr') + '"></span>' + feature.get('id') + ': ' + feature.get('name') + '</p>'; 557 }); 558 559 $('#info-content').html(os); 560 $('p.shore-menuitem').on('click', function(e) { 561 displayPlacename(this.dataset.id); 562 }); 563 $('#info-close').show(); 564 $('#info-wrapper').show(); 565 $('#info-overlay').show(); 566 567 } 568 569 } 570 571 } 572 573 function displayPlacename(id) { 574 575 var feature = markerSource.getFeatureById(id); 576 var fd = new FormData(); 577 578 console.log(feature); 579 var callback = function (response) { 580 loadSiteContent(feature, response); 581 }; 582 583 console.log(feature); 584 console.log(feature.get('orig_id')); 585 fd.append('action', 'placename_fetch'); 586 fd.append('orig_id', feature.get('orig_id')); 587 588 $('#info-close').hide(); 589 $('#info-content').html('<img src="/wp-includes/js/tinymce/skins/lightgray/img/loader.gif" />'); 590 $('#info-wrapper').show(); 591 $('#info-overlay').show(); 592 593 $.ajax({ 594 url: map_args.ajax_url, 595 data:fd, 596 processData: false, 597 contentType: false, 598 dataType: 'html', 599 type: 'POST' 600 }) 601 .done(function(response) { 602 callback(response); 603 $('#info-close').show(); 604 }) 605 .fail(function(xhr, status, error) { 606 alert('Error: ' + xhr.status + '; ' + xhr.statusText); 607 $('#info-overlay').hide(); 608 }); 609 } 610 611 function loadSiteContent(feature, resp) { 612 613 console.log 614 $('#info-content').html(resp); 615return; 616 const marker = new ol.Feature({ 617 geometry: new ol.geom.Point(feature.getGeometry().getCoordinates()), 618 name: 'Placename marker' 619 }); 620 marker.setStyle(feature.getStyle()); 621 622 siteSource.clear(); // delete markers 623 siteSource.addFeature(marker); 624 625 const detailMap = new createMap('map-detail', feature.getGeometry().getCoordinates(), 12, siteSource); 626 627 }; 628 629 function displayTooltip(e) { 630 631 const features = []; 632 633 const overlay = mainMap.tooltipOverlay; 634 const tooltip = overlay.element; 635 636 e.map.forEachFeatureAtPixel(e.pixel, function(feature, layer) { 637 if (features.length == 0) { // top marker 638 features.push(feature); 639 } 640 else { 641 if (JSON.stringify(feature.getGeometry().getCoordinates()) === JSON.stringify(features[0].getGeometry().getCoordinates())) { 642 features.push(feature); 643 } 644 } 645 }); 646 647 if (features.length == 0) { 648 $('#map').css('cursor', 'default'); 649 tooltip.style.display = 'none'; 650 } 651 else { 652 if (features.length == 1) { 653 tooltip.innerHTML = features[0].get('name'); 654 } 655 else { 656 tooltip.innerHTML = features.length + ' sites'; 657 } 658 overlay.setPosition(e.coordinate); 659 $('#map').css('cursor', 'pointer'); 660 tooltip.style.display = ''; 661 } 662 663 } 664 665 }); 666 667 $('#marker-filter-collapse').on('click', function (e) { 668 $('#marker-filter-body').toggle(); 669 $('#marker-filter-collapse').html($('#marker-filter-body').is(':visible') ? '«' : '?'); 670 }); 671 672})(jQuery); 673
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.