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