1/* 2 * Copyright (c) 2008-2022 Mark C. Prins <mprins@users.sf.net> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 18/** 19 * Test for css support in the browser by sniffing for a css class we added 20 * using javascript added by the action plugin; this is an edge case because 21 * browsers that support javascript generally support css as well. 22 * 23 * @returns {Boolean} true when the browser supports css (and implicitly 24 * javascript) 25 */ 26function olTestCSSsupport() { 27 return (jQuery('.olCSSsupported').length > 0); 28} 29 30/** 31 * Creates a DocumentFragment to insert into the dom. 32 * 33 * @param mapid 34 * id for the map div 35 * @param width 36 * width for the map div 37 * @param height 38 * height for the map div 39 * @returns a {DocumentFragment} element that can be injected into the dom 40 */ 41function olCreateMaptag(mapid, width, height) { 42 const // fragment 43 frag = document.createDocumentFragment(), 44 // temp node 45 temp = document.createElement('div'); 46 temp.innerHTML = '<div id="' + mapid + '-olContainer" class="olContainer olWebOnly">' 47 // map 48 + '<div id="' + mapid + '" tabindex="0" style="width:' + width + ';height:' + height + ';" class="olMap"></div>' 49 + '</div>'; 50 while (temp.firstChild) { 51 frag.appendChild(temp.firstChild); 52 } 53 return frag; 54} 55 56/** 57 * Create the map based on the params given. 58 * 59 * @param mapOpts {Object} 60 * mapOpts MapOptions hash {id:'olmap', width:500px, height:500px, 61 * lat:6710200, lon:506500, zoom:13, controls:1, 62 * baselyr:'', kmlfile:'', gpxfile:'', geojsonfile, 63 * summary:''} 64 * @param poi {Array} 65 * OLmapPOI array with POI's [ {lat:6710300,lon:506000,txt:'instap 66 * punt',angle:180,opacity:.9,img:'', rowId:n},... ]); 67 * 68 * @return {ol.Map} the created map 69 */ 70function createMap(mapOpts, poi) { 71 72 // const mapOpts = olMapData[0].mapOpts; 73 // const poi = olMapData[0].poi; 74 75 if (!olEnable) { 76 return null; 77 } 78 if (!olTestCSSsupport()) { 79 olEnable = false; 80 return null; 81 } 82 83 // find map element location 84 const cleartag = document.getElementById(mapOpts.id + '-clearer'); 85 if (cleartag === null) { 86 return null; 87 } 88 // create map element and add to document 89 const fragment = olCreateMaptag(mapOpts.id, mapOpts.width, mapOpts.height); 90 cleartag.parentNode.insertBefore(fragment, cleartag); 91 92 /** dynamic map extent. */ 93 let extent = ol.extent.createEmpty(); 94 let overlayGroup = new ol.layer.Group({title: 'Overlays', fold: 'open', layers: []}); 95 const baseLyrGroup = new ol.layer.Group({'title': 'Base maps', layers: []}); 96 97 const map = new ol.Map({ 98 target: document.getElementById(mapOpts.id), 99 layers: [baseLyrGroup, overlayGroup], 100 view: new ol.View({ 101 center: ol.proj.transform([mapOpts.lon, mapOpts.lat], 'EPSG:4326', 'EPSG:3857'), 102 zoom: mapOpts.zoom, 103 projection: 'EPSG:3857' 104 }), 105 controls: [ 106 new ol.control.Attribution({ 107 collapsible: true, 108 collapsed: true 109 }) 110 ] 111 }); 112 113 if (osmEnable) { 114 baseLyrGroup.getLayers().push( 115 new ol.layer.Tile({ 116 visible: true, 117 title: 'OSM', 118 type: 'base', 119 source: new ol.source.OSM() 120 })); 121 122 baseLyrGroup.getLayers().push( 123 new ol.layer.Tile({ 124 visible: mapOpts.baselyr === "cycle map", 125 title: 'cycle map', 126 type: 'base', 127 source: new ol.source.OSM({ 128 url: 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=' + tfApiKey, 129 attributions: 'Data ©ODbL <a href="https://openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, ' 130 + 'Tiles ©<a href="https://www.thunderforest.com/" target="_blank">Thunderforest</a>' 131 + '<img src="https://www.thunderforest.com/favicon.ico" alt="Thunderforest logo"/>' 132 }) 133 })); 134 135 baseLyrGroup.getLayers().push( 136 new ol.layer.Tile({ 137 visible: mapOpts.baselyr === "transport", 138 title: 'transport', 139 type: 'base', 140 source: new ol.source.OSM({ 141 url: 'https://{a-c}.tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=' + tfApiKey, 142 attributions: 'Data ©ODbL <a href="https://openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, ' 143 + 'Tiles ©<a href="https://www.thunderforest.com/" target="_blank">Thunderforest</a>' 144 + '<img src="https://www.thunderforest.com/favicon.ico" alt="Thunderforest logo"/>' 145 }) 146 })); 147 148 baseLyrGroup.getLayers().push( 149 new ol.layer.Tile({ 150 visible: mapOpts.baselyr === "landscape", 151 title: 'landscape', 152 type: 'base', 153 source: new ol.source.OSM({ 154 url: 'https://{a-c}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png?apikey=' + tfApiKey, 155 attributions: 'Data ©ODbL <a href="https://openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, ' 156 + 'Tiles ©<a href="https://www.thunderforest.com/" target="_blank">Thunderforest</a>' 157 + '<img src="https://www.thunderforest.com/favicon.ico" alt="Thunderforest logo"/>' 158 }) 159 })); 160 161 baseLyrGroup.getLayers().push( 162 new ol.layer.Tile({ 163 visible: mapOpts.baselyr === "outdoors", 164 title: 'outdoors', 165 type: 'base', 166 source: new ol.source.OSM({ 167 url: 'https://{a-c}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=' + tfApiKey, 168 attributions: 'Data ©ODbL <a href="https://openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, ' 169 + 'Tiles ©<a href="https://www.thunderforest.com/" target="_blank">Thunderforest</a>' 170 + '<img src="https://www.thunderforest.com/favicon.ico" alt="Thunderforest logo"/>' 171 }) 172 })); 173 } 174 175 if (bEnable && bApiKey !== '') { 176 baseLyrGroup.getLayers().push( 177 new ol.layer.Tile({ 178 visible: mapOpts.baselyr === "bing road", 179 title: 'bing road', 180 type: 'base', 181 source: new ol.source.BingMaps({ 182 key: bApiKey, 183 imagerySet: 'Road' 184 }) 185 })); 186 187 baseLyrGroup.getLayers().push( 188 new ol.layer.Tile({ 189 visible: mapOpts.baselyr === "bing sat", 190 title: 'bing sat', 191 type: 'base', 192 source: new ol.source.BingMaps({ 193 key: bApiKey, 194 imagerySet: 'Aerial' 195 }) 196 })); 197 198 baseLyrGroup.getLayers().push( 199 new ol.layer.Tile({ 200 visible: mapOpts.baselyr === "bing hybrid", 201 title: 'bing hybrid', 202 type: 'base', 203 source: new ol.source.BingMaps({ 204 key: bApiKey, 205 imagerySet: 'AerialWithLabels' 206 }) 207 })); 208 } 209 210 if (stamenEnable) { 211 baseLyrGroup.getLayers().push( 212 new ol.layer.Tile({ 213 visible: mapOpts.baselyr === "toner", 214 type: 'base', 215 title: 'toner', 216 source: new ol.source.Stamen({layer: 'toner'}) 217 }) 218 ); 219 220 baseLyrGroup.getLayers().push( 221 new ol.layer.Tile({ 222 visible: mapOpts.baselyr === "terrain", 223 type: 'base', 224 title: 'terrain', 225 source: new ol.source.Stamen({layer: 'terrain'}) 226 }) 227 ); 228 } 229 230 extent = ol.extent.extend(extent, map.getView().calculateExtent()); 231 232 const iconScale = 1.0; 233 const vectorSource = new ol.source.Vector(); 234 poi.forEach((p) => { 235 const f = new ol.Feature({ 236 geometry: new ol.geom.Point(ol.proj.fromLonLat([p.lon, p.lat])), 237 description: p.txt, 238 img: p.img, 239 rowId: p.rowId, 240 lat: p.lat, 241 lon: p.lon, 242 angle: p.angle, 243 opacity: p.opacity, 244 alt: p.img.substring(0, p.img.lastIndexOf(".")) 245 }); 246 f.setId(p.rowId); 247 vectorSource.addFeature(f); 248 }); 249 250 const vectorLayer = new ol.layer.Vector({ 251 title: 'POI', 252 visible: true, 253 source: vectorSource, 254 style(feature, resolution) { 255 const img = feature.get('img'); 256 const opacity = feature.get('opacity'); 257 const angle = feature.get('angle'); 258 const text = feature.get('rowId'); 259 260 return new ol.style.Style({ 261 image: new ol.style.Icon({ 262 src: `${DOKU_BASE}lib/plugins/openlayersmap/icons/${img}`, 263 crossOrigin: '', 264 opacity: opacity, 265 scale: iconScale, 266 rotation: angle * Math.PI / 180, 267 }), 268 text: new ol.style.Text({ 269 text: `${text}`, 270 textAlign: 'center', 271 textBaseline: 'middle', 272 offsetX: (8 + 4) * iconScale, 273 offsetY: -8 * iconScale, 274 scale: iconScale, 275 fill: new ol.style.Fill({color: 'rgb(0,0,0)'}), 276 font: 'bold 1em monospace', 277 backgroundFill: new ol.style.Fill({color: 'rgba(255,255,255,.4)'}) 278 }) 279 }); 280 } 281 }); 282 overlayGroup.getLayers().push(vectorLayer); 283 if (mapOpts.autozoom) { 284 extent = ol.extent.extend(extent, vectorSource.getExtent()); 285 map.getView().fit(extent); 286 } 287 288 if (mapOpts.controls === 1) { 289 map.addControl(new ol.control.Zoom()); 290 map.addControl(new ol.control.ScaleLine({bar: true, text: true})); 291 map.addControl(new ol.control.MousePosition({ 292 coordinateFormat: ol.coordinate.createStringXY(4), projection: 'EPSG:4326', 293 })); 294 map.addControl(new ol.control.FullScreen({ 295 label: '✈' 296 })); 297 map.addControl(new ol.control.OverviewMap({ 298 label: '+', 299 layers: [new ol.layer.Tile({ 300 source: new ol.source.OSM() 301 })] 302 })); 303 map.addControl(new ol.control.LayerSwitcher({ 304 activationMode: 'click', 305 label: '\u2630', 306 collapseLabel: '\u00BB', 307 })); 308 } 309 310 if (mapOpts.kmlfile.length > 0) { 311 try { 312 const kmlSource = new ol.source.Vector({ 313 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.kmlfile, 314 format: new ol.format.KML(), 315 }); 316 overlayGroup.getLayers().push(new ol.layer.Vector({title: 'KML file', visible: true, source: kmlSource})); 317 318 if (mapOpts.autozoom) { 319 kmlSource.once('change', function () { 320 extent = ol.extent.extend(extent, kmlSource.getExtent()); 321 map.getView().fit(extent); 322 }); 323 } 324 } catch (e) { 325 console.error(e); 326 } 327 } 328 329 if (mapOpts.geojsonfile.length > 0) { 330 try { 331 // these are the same colour as in StaticMap#drawJSON() 332 const geoJsonStyle = { 333 'Point': new ol.style.Style({ 334 image: new ol.style.Circle({ 335 fill: new ol.style.Fill({ 336 color: 'rgba(255,0,255,0.4)', 337 }), 338 radius: 5, 339 stroke: new ol.style.Stroke({ 340 color: 'rgba(255,0,255,0.9)', 341 width: 1, 342 }), 343 }), 344 }), 345 'LineString': new ol.style.Style({ 346 stroke: new ol.style.Stroke({ 347 color: 'rgba(255,0,255,0.9)', 348 width: 3, 349 }), 350 }), 351 'MultiLineString': new ol.style.Style({ 352 stroke: new ol.style.Stroke({ 353 color: 'rgba(255,0,255,0.9)', 354 width: 3, 355 }), 356 }), 357 'Polygon': new ol.style.Style({ 358 stroke: new ol.style.Stroke({ 359 color: 'rgba(255,0,255,0.9)', 360 width: 3, 361 }), 362 fill: new ol.style.Fill({ 363 color: 'rgba(255,0,255,0.4)', 364 }), 365 }), 366 'MultiPolygon': new ol.style.Style({ 367 stroke: new ol.style.Stroke({ 368 color: 'rgba(255,0,255,0.9)', 369 width: 3, 370 }), 371 fill: new ol.style.Fill({ 372 color: 'rgba(255,0,255,0.4)', 373 }), 374 }), 375 }; 376 const geoJsonSource = new ol.source.Vector({ 377 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.geojsonfile, 378 format: new ol.format.GeoJSON(), 379 }); 380 overlayGroup.getLayers().push(new ol.layer.Vector({ 381 title: 'GeoJSON file', visible: true, source: geoJsonSource, 382 style: function (feature) { 383 return geoJsonStyle[feature.getGeometry().getType()]; 384 }, 385 })); 386 387 if (mapOpts.autozoom) { 388 geoJsonSource.once('change', function () { 389 extent = ol.extent.extend(extent, geoJsonSource.getExtent()); 390 map.getView().fit(extent); 391 }); 392 } 393 } catch (e) { 394 console.error(e); 395 } 396 } 397 398 if (mapOpts.gpxfile.length > 0) { 399 try { 400 // these are the same colour as in StaticMap#drawGPX() 401 const gpxJsonStyle = { 402 'Point': new ol.style.Style({ 403 image: new ol.style.Circle({ 404 fill: new ol.style.Fill({ 405 color: 'rgba(0,0,255,0.4)', 406 }), 407 radius: 5, 408 stroke: new ol.style.Stroke({ 409 color: 'rgba(0,0,255,0.9)', 410 width: 1, 411 }), 412 }), 413 }), 414 'LineString': new ol.style.Style({ 415 stroke: new ol.style.Stroke({ 416 color: 'rgba(0,0,255,0.9)', 417 width: 3, 418 }), 419 }), 420 'MultiLineString': new ol.style.Style({ 421 stroke: new ol.style.Stroke({ 422 color: 'rgba(0,0,255,0.9)', 423 width: 3, 424 }), 425 }), 426 }; 427 const gpxSource = new ol.source.Vector({ 428 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.gpxfile, 429 format: new ol.format.GPX(), 430 }); 431 overlayGroup.getLayers().push(new ol.layer.Vector({ 432 title: 'GPS track', visible: true, source: gpxSource, 433 style: function (feature) { 434 return gpxJsonStyle[feature.getGeometry().getType()]; 435 }, 436 })); 437 438 if (mapOpts.autozoom) { 439 gpxSource.once('change', function () { 440 extent = ol.extent.extend(extent, gpxSource.getExtent()); 441 map.getView().fit(extent); 442 }); 443 } 444 } catch (e) { 445 console.error(e); 446 } 447 } 448 449 const container = document.getElementById('popup'); 450 const content = document.getElementById('popup-content'); 451 const closer = document.getElementById('popup-closer'); 452 453 const overlay = new ol.Overlay({ 454 element: container, 455 positioning: 'center-center', 456 stopEvent: true, 457 autoPan: { 458 animation: { 459 duration: 250, 460 } 461 }, 462 }); 463 map.addOverlay(overlay); 464 465 /** 466 * Add a click handler to hide the popup. 467 * @return {boolean} Don't follow the href. 468 */ 469 closer.onclick = function () { 470 overlay.setPosition(undefined); 471 closer.blur(); 472 return false; 473 }; 474 475 // display popup on click 476 map.on('singleclick', function (evt) { 477 const selFeature = map.forEachFeatureAtPixel(evt.pixel, function (feature) { 478 return feature; 479 }); 480 if (selFeature) { 481 overlay.setPosition(evt.coordinate); 482 483 let pContent = '<div class="spacer"> </div>'; 484 // let locDesc = ''; 485 486 if (selFeature.get('rowId') !== undefined) { 487 pContent += '<span class="rowId">' + selFeature.get('rowId') + ': </span>'; 488 } 489 if (selFeature.get('name') !== undefined) { 490 pContent += '<span class="txt">' + selFeature.get('name') + '</span>'; 491 // locDesc = selFeature.get('name'); 492 // TODO strip <p> tag from locDesc 493 // locDesc = selFeature.get('name').split(/\s+/).slice(0,2).join('+'); 494 } 495 if (selFeature.get('ele') !== undefined) { 496 pContent += '<div class="ele">elevation: ' + selFeature.get('ele') + '</div>'; 497 } 498 if (selFeature.get('type') !== undefined) { 499 pContent += '<div>' + selFeature.get('type') + '</div>'; 500 } 501 if (selFeature.get('time') !== undefined) { 502 pContent += '<div class="time">time: ' + selFeature.get('time') + '</div>'; 503 } 504 if (selFeature.get('description') !== undefined) { 505 pContent += '<div class="desc">' + selFeature.get('description') + '</div>'; 506 } 507 if (selFeature.get('img') !== undefined) { 508 const _alt = selFeature.get('alt'); 509 pContent += '<div class="coord" title="lat;lon">' + 510 '<img alt="' + _alt + '" src="' + DOKU_BASE + 'lib/plugins/openlayersmap/icons/' + selFeature.get('img') + 511 '" width="16" height="16" ' + 'style="transform:rotate(' + selFeature.get('angle') + 'deg)" /> ' + 512 '<a href="geo:' + selFeature.get('lat') + ',' + selFeature.get('lon') + '?q=' + selFeature.get('lat') + 513 ',' + selFeature.get('lon') + '(' + selFeature.get('alt') + ')" title="Open in navigation app">' + 514 ol.coordinate.format([selFeature.get('lon'), selFeature.get('lat')], '{x}º; {y}º', 4) + '</a></div>'; 515 } 516 content.innerHTML = pContent; 517 } else { 518 // do nothing... 519 } 520 }); 521 522 // change mouse cursor when over marker 523 map.on('pointermove', function (e) { 524 const pixel = map.getEventPixel(e.originalEvent); 525 const hit = map.hasFeatureAtPixel(pixel); 526 map.getTarget().style.cursor = hit ? 'pointer' : ''; 527 }); 528 529 return map; 530} 531 532/** 533 * add layers to the map based on the olMapOverlays object. 534 */ 535function olovAddToMap() { 536 for (const key in olMapOverlays) { 537 const overlay = olMapOverlays[key]; 538 const m = olMaps[overlay.id]; 539 540 switch (overlay.type) { 541 case 'osm': 542 m.addLayer(new ol.layer.Tile({ 543 title: overlay.name, 544 visible: (overlay.visible).toLowerCase() === 'true', 545 opacity: parseFloat(overlay.opacity), 546 source: new ol.source.OSM({ 547 url: overlay.url, 548 crossOrigin: 'Anonymous', 549 attributions: overlay.attribution 550 }) 551 })); 552 break; 553 case 'wms': 554 m.addLayer(new ol.layer.Image({ 555 title: overlay.name, 556 opacity: parseFloat(overlay.opacity), 557 visible: (overlay.visible).toLowerCase() === 'true', 558 source: new ol.source.ImageWMS({ 559 url: overlay.url, 560 params: { 561 'LAYERS': overlay.layers, 562 'VERSION': overlay.version, 563 'TRANSPARENT': overlay.transparent, 564 'FORMAT': overlay.format 565 }, 566 ratio: 1, 567 crossOrigin: 'Anonymous', 568 attributions: overlay.attribution 569 }) 570 })); 571 break; 572 case 'ags': 573 m.addLayer(new ol.layer.Image({ 574 title: overlay.name, 575 opacity: parseFloat(overlay.opacity), 576 visible: (overlay.visible).toLowerCase() === 'true', 577 source: new ol.source.ImageArcGISRest({ 578 url: overlay.url, 579 params: { 580 'LAYERS': overlay.layers, 581 'TRANSPARENT': overlay.transparent, 582 'FORMAT': overlay.format 583 }, 584 ratio: 1, 585 crossOrigin: 'Anonymous', 586 attributions: overlay.attribution 587 }) 588 })); 589 break; 590 // case 'mapillary': 591 // var mUrl = 'http://api.mapillary.com/v1/im/search?'; 592 // if (overlay.skey !== '') { 593 // mUrl = 'http://api.mapillary.com/v1/im/sequence?'; 594 // } 595 // var mLyr = new OpenLayers.Layer.Vector( 596 // "Mapillary", { 597 // projection: new OpenLayers.Projection("EPSG:4326"), 598 // strategies: [new OpenLayers.Strategy.BBOX({ 599 // ratio: 1.1, 600 // resFactor: 1.5 601 // }) /* ,new OpenLayers.Strategy.Cluster({}) */], 602 // protocol: new OpenLayers.Protocol.HTTP({ 603 // url: mUrl, 604 // format: new OpenLayers.Format.GeoJSON(), 605 // params: { 606 // // default to max. 250 locations 607 // 'max-results': 250, 608 // 'geojson': true, 609 // 'skey': overlay.skey 610 // }, 611 // filterToParams: function (filter, params) { 612 // if (filter.type === OpenLayers.Filter.Spatial.BBOX) { 613 // // override the bbox serialization of 614 // // the filter to give the Mapillary 615 // // specific bounds 616 // params['min-lat'] = filter.value.bottom; 617 // params['max-lat'] = filter.value.top; 618 // params['min-lon'] = filter.value.left; 619 // params['max-lon'] = filter.value.right; 620 // // if the width of our bbox width is 621 // // less than 0.15 degrees drop the max 622 // // results 623 // if (filter.value.top - filter.value.bottom < .15) { 624 // OpenLayers.Console.debug('dropping max-results parameter, width is: ', 625 // filter.value.top - filter.value.bottom); 626 // params['max-results'] = null; 627 // } 628 // } 629 // return params; 630 // } 631 // }), 632 // styleMap: new OpenLayers.StyleMap({ 633 // 'default': { 634 // cursor: 'help', 635 // rotation: '${ca}', 636 // externalGraphic: DOKU_BASE + 'lib/plugins/openlayersmapoverlays/icons/arrow-up-20.png', 637 // graphicHeight: 20, 638 // graphicWidth: 20, 639 // }, 640 // 'select': { 641 // externalGraphic: DOKU_BASE + 'lib/plugins/openlayersmapoverlays/icons/arrow-up-20-select.png', 642 // label: '${location}', 643 // fontSize: '1em', 644 // fontFamily: 'monospace', 645 // labelXOffset: '0.5', 646 // labelYOffset: '0.5', 647 // labelAlign: 'lb', 648 // } 649 // }), 650 // attribution: '<a href="http://www.mapillary.com/legal.html">' + 651 // '<img src="http://mapillary.com/favicon.ico" ' + 652 // 'alt="Mapillary" height="16" width="16" />Mapillary (CC-BY-SA)', 653 // visibility: (overlay.visible).toLowerCase() == 'true', 654 // }); 655 // m.addLayer(mLyr); 656 // selectControl.addLayer(mLyr); 657 // break; 658 // case 'search': 659 // m.addLayer(new OpenLayers.Layer.Vector( 660 // overlay.name, 661 // overlay.url, 662 // { 663 // layers: overlay.layers, 664 // version: overlay.version, 665 // transparent: overlay.transparent, 666 // format: overlay.format 667 // }, { 668 // opacity: parseFloat(overlay.opacity), 669 // visibility: (overlay.visible).toLowerCase() == 'true', 670 // isBaseLayer: !1, 671 // attribution: overlay.attribution 672 // } 673 // )); 674 // break; 675 } 676 } 677} 678 679/** init. */ 680function olInit() { 681 if (olEnable) { 682 // add info window to DOM 683 const frag = document.createDocumentFragment(), 684 temp = document.createElement('div'); 685 temp.innerHTML = '<div id="popup" class="olPopup"><a href="#" id="popup-closer" class="olPopupCloseBox"></a><div id="popup-content"></div></div>'; 686 while (temp.firstChild) { 687 frag.appendChild(temp.firstChild); 688 } 689 document.body.appendChild(frag); 690 691 let _i = 0; 692 // create the maps in the page 693 for (_i = 0; _i < olMapData.length; _i++) { 694 const _id = olMapData[_i].mapOpts.id; 695 olMaps[_id] = createMap(olMapData[_i].mapOpts, olMapData[_i].poi); 696 697 // set max-width on help pop-over 698 jQuery('#' + _id).parent().parent().find('.olMapHelp').css('max-width', olMapData[_i].mapOpts.width); 699 700 // shrink the map width to fit inside page container 701 const _w = jQuery('#' + _id + '-olContainer').parent().innerWidth(); 702 if (parseInt(olMapData[_i].mapOpts.width) > _w) { 703 jQuery('#' + _id).width(_w); 704 jQuery('#' + _id).parent().parent().find('.olMapHelp').width(_w); 705 olMaps[_id].updateSize(); 706 } 707 } 708 709 // add overlays 710 olovAddToMap(); 711 712 let resizeTimer; 713 jQuery(window).on('resize', function (e) { 714 clearTimeout(resizeTimer); 715 resizeTimer = setTimeout(function () { 716 for (_i = 0; _i < olMapData.length; _i++) { 717 const _id = olMapData[_i].mapOpts.id; 718 const _w = jQuery('#' + _id + '-olContainer').parent().innerWidth(); 719 if (parseInt(olMapData[_i].mapOpts.width) > _w) { 720 jQuery('#' + _id).width(_w); 721 jQuery('#' + _id).parent().parent().find('.olMapHelp').width(_w); 722 olMaps[_id].updateSize(); 723 } 724 } 725 }, 250); 726 }); 727 728 // hide the table(s) with POI by giving it a print-only style 729 jQuery('.olPOItableSpan').addClass('olPrintOnly'); 730 // hide the static map image(s) by giving it a print only style 731 jQuery('.olStaticMap').addClass('olPrintOnly'); 732 // add help button with toggle. 733 jQuery('.olWebOnly > .olMap') 734 .prepend( 735 '<div class="olMapHelpButtonDiv">' 736 + '<button onclick="jQuery(\'.olMapHelp\').toggle(500);" class="olMapHelpButton olHasTooltip"><span>' 737 + 'Show or hide help</span>?</button></div>'); 738 // toggle to switch dynamic vs. static map 739 jQuery('.olMapHelp').before( 740 '<div class="a11y"><button onclick="jQuery(\'.olPrintOnly\').toggle();jQuery(\'.olWebOnly\').toggle();">' 741 + 'Hide or show the dynamic map</button></div>'); 742 } 743} 744 745/** 746 * CSS support flag. 747 * 748 * @type {Boolean} 749 */ 750let olCSSEnable = true; 751 752/* register olInit to run with onload event. */ 753jQuery(olInit); 754