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 alt: p.img.substring(0, p.img.lastIndexOf(".")) 244 }); 245 f.setId(p.rowId); 246 f.setStyle(new ol.style.Style({ 247 text: new ol.style.Text({ 248 text: "" + p.rowId, 249 textAlign: 'left', 250 textBaseline: 'bottom', 251 offsetX: 8, 252 offsetY: -8, 253 scale: iconScale, 254 fill: new ol.style.Fill({color: 'rgb(0,0,0)'}), 255 font: '12px monospace bold', 256 backgroundFill: new ol.style.Fill({color: 'rgba(255,255,255,.4)'}) 257 }), image: new ol.style.Icon({ 258 src: DOKU_BASE + "lib/plugins/openlayersmap/icons/" + p.img, 259 crossOrigin: '', 260 opacity: p.opacity, 261 scale: iconScale, 262 rotation: p.angle * Math.PI / 180, 263 }), 264 })); 265 vectorSource.addFeature(f); 266 }); 267 268 const vectorLayer = new ol.layer.Vector({title: 'POI', visible: true, source: vectorSource}); 269 overlayGroup.getLayers().push(vectorLayer); 270 if (mapOpts.autozoom) { 271 extent = ol.extent.extend(extent, vectorSource.getExtent()); 272 map.getView().fit(extent); 273 } 274 275 if (mapOpts.controls === 1) { 276 map.addControl(new ol.control.Zoom()); 277 map.addControl(new ol.control.ScaleLine({bar: true, text: true})); 278 map.addControl(new ol.control.MousePosition({ 279 coordinateFormat: ol.coordinate.createStringXY(4), projection: 'EPSG:4326', 280 })); 281 map.addControl(new ol.control.FullScreen({ 282 label: '✈' 283 })); 284 map.addControl(new ol.control.OverviewMap({ 285 label: '+', 286 layers: [new ol.layer.Tile({ 287 source: new ol.source.OSM() 288 })] 289 })); 290 map.addControl(new ol.control.LayerSwitcher({ 291 activationMode: 'click', 292 label: '\u2630', 293 collapseLabel: '\u00BB', 294 })); 295 } 296 297 if (mapOpts.kmlfile.length > 0) { 298 try { 299 const kmlSource = new ol.source.Vector({ 300 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.kmlfile, 301 format: new ol.format.KML(), 302 }); 303 overlayGroup.getLayers().push(new ol.layer.Vector({title: 'KML file', visible: true, source: kmlSource})); 304 305 if (mapOpts.autozoom) { 306 kmlSource.once('change', function () { 307 extent = ol.extent.extend(extent, kmlSource.getExtent()); 308 map.getView().fit(extent); 309 }); 310 } 311 } catch (e) { 312 console.error(e); 313 } 314 } 315 316 if (mapOpts.geojsonfile.length > 0) { 317 try { 318 // these are the same colour as in StaticMap#drawJSON() 319 const geoJsonStyle = { 320 'Point': new ol.style.Style({ 321 image: new ol.style.Circle({ 322 fill: new ol.style.Fill({ 323 color: 'rgba(255,0,255,0.4)', 324 }), 325 radius: 5, 326 stroke: new ol.style.Stroke({ 327 color: 'rgba(255,0,255,0.9)', 328 width: 1, 329 }), 330 }), 331 }), 332 'LineString': new ol.style.Style({ 333 stroke: new ol.style.Stroke({ 334 color: 'rgba(255,0,255,0.9)', 335 width: 3, 336 }), 337 }), 338 'MultiLineString': new ol.style.Style({ 339 stroke: new ol.style.Stroke({ 340 color: 'rgba(255,0,255,0.9)', 341 width: 3, 342 }), 343 }), 344 'Polygon': new ol.style.Style({ 345 stroke: new ol.style.Stroke({ 346 color: 'rgba(255,0,255,0.9)', 347 width: 3, 348 }), 349 fill: new ol.style.Fill({ 350 color: 'rgba(255,0,255,0.4)', 351 }), 352 }), 353 'MultiPolygon': new ol.style.Style({ 354 stroke: new ol.style.Stroke({ 355 color: 'rgba(255,0,255,0.9)', 356 width: 3, 357 }), 358 fill: new ol.style.Fill({ 359 color: 'rgba(255,0,255,0.4)', 360 }), 361 }), 362 }; 363 const geoJsonSource = new ol.source.Vector({ 364 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.geojsonfile, 365 format: new ol.format.GeoJSON(), 366 }); 367 overlayGroup.getLayers().push(new ol.layer.Vector({ 368 title: 'GeoJSON file', visible: true, source: geoJsonSource, 369 style: function (feature) { 370 return geoJsonStyle[feature.getGeometry().getType()]; 371 }, 372 })); 373 374 if (mapOpts.autozoom) { 375 geoJsonSource.once('change', function () { 376 extent = ol.extent.extend(extent, geoJsonSource.getExtent()); 377 map.getView().fit(extent); 378 }); 379 } 380 } catch (e) { 381 console.error(e); 382 } 383 } 384 385 if (mapOpts.gpxfile.length > 0) { 386 try { 387 // these are the same colour as in StaticMap#drawGPX() 388 const gpxJsonStyle = { 389 'Point': new ol.style.Style({ 390 image: new ol.style.Circle({ 391 fill: new ol.style.Fill({ 392 color: 'rgba(0,0,255,0.4)', 393 }), 394 radius: 5, 395 stroke: new ol.style.Stroke({ 396 color: 'rgba(0,0,255,0.9)', 397 width: 1, 398 }), 399 }), 400 }), 401 'LineString': new ol.style.Style({ 402 stroke: new ol.style.Stroke({ 403 color: 'rgba(0,0,255,0.9)', 404 width: 3, 405 }), 406 }), 407 'MultiLineString': new ol.style.Style({ 408 stroke: new ol.style.Stroke({ 409 color: 'rgba(0,0,255,0.9)', 410 width: 3, 411 }), 412 }), 413 }; 414 const gpxSource = new ol.source.Vector({ 415 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.gpxfile, 416 format: new ol.format.GPX(), 417 }); 418 overlayGroup.getLayers().push(new ol.layer.Vector({ 419 title: 'GPS track', visible: true, source: gpxSource, 420 style: function (feature) { 421 return gpxJsonStyle[feature.getGeometry().getType()]; 422 }, 423 })); 424 425 if (mapOpts.autozoom) { 426 gpxSource.once('change', function () { 427 extent = ol.extent.extend(extent, gpxSource.getExtent()); 428 map.getView().fit(extent); 429 }); 430 } 431 } catch (e) { 432 console.error(e); 433 } 434 } 435 436 const container = document.getElementById('popup'); 437 const content = document.getElementById('popup-content'); 438 const closer = document.getElementById('popup-closer'); 439 440 const overlay = new ol.Overlay({ 441 element: container, autoPan: true, autoPanAnimation: { 442 duration: 250, 443 }, //stopEvent: false, 444 }); 445 map.addOverlay(overlay); 446 447 /** 448 * Add a click handler to hide the popup. 449 * @return {boolean} Don't follow the href. 450 */ 451 closer.onclick = function () { 452 overlay.setPosition(undefined); 453 closer.blur(); 454 return false; 455 }; 456 457 // display popup on click 458 map.on('singleclick', function (evt) { 459 const selFeature = map.forEachFeatureAtPixel(evt.pixel, function (feature) { 460 return feature; 461 }); 462 if (selFeature) { 463 overlay.setPosition(evt.coordinate); 464 465 let pContent = '<div class="spacer"> </div>'; 466 // let locDesc = ''; 467 468 if (selFeature.get('rowId') !== undefined) { 469 pContent += '<span class="rowId">' + selFeature.get('rowId') + ': </span>'; 470 } 471 if (selFeature.get('name') !== undefined) { 472 pContent += '<span class="txt">' + selFeature.get('name') + '</span>'; 473 // locDesc = selFeature.get('name'); 474 // TODO strip <p> tag from locDesc 475 // locDesc = selFeature.get('name').split(/\s+/).slice(0,2).join('+'); 476 } 477 if (selFeature.get('ele') !== undefined) { 478 pContent += '<div class="ele">elevation: ' + selFeature.get('ele') + '</div>'; 479 } 480 if (selFeature.get('type') !== undefined) { 481 pContent += '<div>' + selFeature.get('type') + '</div>'; 482 } 483 if (selFeature.get('time') !== undefined) { 484 pContent += '<div class="time">time: ' + selFeature.get('time') + '</div>'; 485 } 486 if (selFeature.get('description') !== undefined) { 487 pContent += '<div class="desc">' + selFeature.get('description') + '</div>'; 488 } 489 if (selFeature.get('img') !== undefined) { 490 pContent += '<div class="coord" title="lat;lon">' + 491 '<img alt="" src="' + DOKU_BASE + 'lib/plugins/openlayersmap/icons/' + selFeature.get('img') + 492 '" width="16" height="16" ' + 'style="transform:rotate(' + selFeature.get('angle') + 'deg)" /> ' + 493 '<a href="geo:' + selFeature.get('lat') + ',' + selFeature.get('lon') + '?q=' + selFeature.get('lat') + 494 ',' + selFeature.get('lon') + '(' + selFeature.get('alt') + ')" title="Open in navigation app">' + 495 ol.coordinate.format([selFeature.get('lon'), selFeature.get('lat')], '{x}º; {y}º', 4) + '</a></div>'; 496 } 497 content.innerHTML = pContent; 498 } else { 499 // do nothing... 500 } 501 }); 502 503 // change mouse cursor when over marker 504 map.on('pointermove', function (e) { 505 const pixel = map.getEventPixel(e.originalEvent); 506 const hit = map.hasFeatureAtPixel(pixel); 507 map.getTarget().style.cursor = hit ? 'pointer' : ''; 508 }); 509 510 return map; 511} 512 513/** 514 * add layers to the map based on the olMapOverlays object. 515 */ 516function olovAddToMap() { 517 for (const key in olMapOverlays) { 518 const overlay = olMapOverlays[key]; 519 const m = olMaps[overlay.id]; 520 521 switch (overlay.type) { 522 case 'osm': 523 m.addLayer(new ol.layer.Tile({ 524 title: overlay.name, 525 visible: (overlay.visible).toLowerCase() === 'true', 526 opacity: parseFloat(overlay.opacity), 527 source: new ol.source.OSM({ 528 url: overlay.url, 529 crossOrigin: 'Anonymous', 530 attributions: overlay.attribution 531 }) 532 })); 533 break; 534 case 'wms': 535 m.addLayer(new ol.layer.Image({ 536 title: overlay.name, 537 opacity: parseFloat(overlay.opacity), 538 visible: (overlay.visible).toLowerCase() === 'true', 539 source: new ol.source.ImageWMS({ 540 url: overlay.url, 541 params: { 542 'LAYERS': overlay.layers, 543 'VERSION': overlay.version, 544 'TRANSPARENT': overlay.transparent, 545 'FORMAT': overlay.format 546 }, 547 ratio: 1, 548 crossOrigin: 'Anonymous', 549 attributions: overlay.attribution 550 }) 551 })); 552 break; 553 case 'ags': 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.ImageArcGISRest({ 559 url: overlay.url, 560 params: { 561 'LAYERS': overlay.layers, 562 'TRANSPARENT': overlay.transparent, 563 'FORMAT': overlay.format 564 }, 565 ratio: 1, 566 crossOrigin: 'Anonymous', 567 attributions: overlay.attribution 568 }) 569 })); 570 break; 571 // case 'mapillary': 572 // var mUrl = 'http://api.mapillary.com/v1/im/search?'; 573 // if (overlay.skey !== '') { 574 // mUrl = 'http://api.mapillary.com/v1/im/sequence?'; 575 // } 576 // var mLyr = new OpenLayers.Layer.Vector( 577 // "Mapillary", { 578 // projection: new OpenLayers.Projection("EPSG:4326"), 579 // strategies: [new OpenLayers.Strategy.BBOX({ 580 // ratio: 1.1, 581 // resFactor: 1.5 582 // }) /* ,new OpenLayers.Strategy.Cluster({}) */], 583 // protocol: new OpenLayers.Protocol.HTTP({ 584 // url: mUrl, 585 // format: new OpenLayers.Format.GeoJSON(), 586 // params: { 587 // // default to max. 250 locations 588 // 'max-results': 250, 589 // 'geojson': true, 590 // 'skey': overlay.skey 591 // }, 592 // filterToParams: function (filter, params) { 593 // if (filter.type === OpenLayers.Filter.Spatial.BBOX) { 594 // // override the bbox serialization of 595 // // the filter to give the Mapillary 596 // // specific bounds 597 // params['min-lat'] = filter.value.bottom; 598 // params['max-lat'] = filter.value.top; 599 // params['min-lon'] = filter.value.left; 600 // params['max-lon'] = filter.value.right; 601 // // if the width of our bbox width is 602 // // less than 0.15 degrees drop the max 603 // // results 604 // if (filter.value.top - filter.value.bottom < .15) { 605 // OpenLayers.Console.debug('dropping max-results parameter, width is: ', 606 // filter.value.top - filter.value.bottom); 607 // params['max-results'] = null; 608 // } 609 // } 610 // return params; 611 // } 612 // }), 613 // styleMap: new OpenLayers.StyleMap({ 614 // 'default': { 615 // cursor: 'help', 616 // rotation: '${ca}', 617 // externalGraphic: DOKU_BASE + 'lib/plugins/openlayersmapoverlays/icons/arrow-up-20.png', 618 // graphicHeight: 20, 619 // graphicWidth: 20, 620 // }, 621 // 'select': { 622 // externalGraphic: DOKU_BASE + 'lib/plugins/openlayersmapoverlays/icons/arrow-up-20-select.png', 623 // label: '${location}', 624 // fontSize: '1em', 625 // fontFamily: 'monospace', 626 // labelXOffset: '0.5', 627 // labelYOffset: '0.5', 628 // labelAlign: 'lb', 629 // } 630 // }), 631 // attribution: '<a href="http://www.mapillary.com/legal.html">' + 632 // '<img src="http://mapillary.com/favicon.ico" ' + 633 // 'alt="Mapillary" height="16" width="16" />Mapillary (CC-BY-SA)', 634 // visibility: (overlay.visible).toLowerCase() == 'true', 635 // }); 636 // m.addLayer(mLyr); 637 // selectControl.addLayer(mLyr); 638 // break; 639 // case 'search': 640 // m.addLayer(new OpenLayers.Layer.Vector( 641 // overlay.name, 642 // overlay.url, 643 // { 644 // layers: overlay.layers, 645 // version: overlay.version, 646 // transparent: overlay.transparent, 647 // format: overlay.format 648 // }, { 649 // opacity: parseFloat(overlay.opacity), 650 // visibility: (overlay.visible).toLowerCase() == 'true', 651 // isBaseLayer: !1, 652 // attribution: overlay.attribution 653 // } 654 // )); 655 // break; 656 } 657 } 658} 659 660/** init. */ 661function olInit() { 662 if (olEnable) { 663 // add info window to DOM 664 const frag = document.createDocumentFragment(), 665 temp = document.createElement('div'); 666 temp.innerHTML = '<div id="popup" class="olPopup"><a href="#" id="popup-closer" class="olPopupCloseBox"></a><div id="popup-content"></div></div>'; 667 while (temp.firstChild) { 668 frag.appendChild(temp.firstChild); 669 } 670 document.body.appendChild(frag); 671 672 let _i = 0; 673 // create the maps in the page 674 for (_i = 0; _i < olMapData.length; _i++) { 675 const _id = olMapData[_i].mapOpts.id; 676 olMaps[_id] = createMap(olMapData[_i].mapOpts, olMapData[_i].poi); 677 678 // set max-width on help pop-over 679 jQuery('#' + _id).parent().parent().find('.olMapHelp').css('max-width', olMapData[_i].mapOpts.width); 680 681 // shrink the map width to fit inside page container 682 const _w = jQuery('#' + _id + '-olContainer').parent().innerWidth(); 683 if (parseInt(olMapData[_i].mapOpts.width) > _w) { 684 jQuery('#' + _id).width(_w); 685 jQuery('#' + _id).parent().parent().find('.olMapHelp').width(_w); 686 olMaps[_id].updateSize(); 687 } 688 } 689 690 // add overlays 691 olovAddToMap(); 692 693 let resizeTimer; 694 jQuery(window).on('resize', function (e) { 695 clearTimeout(resizeTimer); 696 resizeTimer = setTimeout(function () { 697 for (_i = 0; _i < olMapData.length; _i++) { 698 const _id = olMapData[_i].mapOpts.id; 699 const _w = jQuery('#' + _id + '-olContainer').parent().innerWidth(); 700 if (parseInt(olMapData[_i].mapOpts.width) > _w) { 701 jQuery('#' + _id).width(_w); 702 jQuery('#' + _id).parent().parent().find('.olMapHelp').width(_w); 703 olMaps[_id].updateSize(); 704 } 705 } 706 }, 250); 707 }); 708 709 // hide the table(s) with POI by giving it a print-only style 710 jQuery('.olPOItableSpan').addClass('olPrintOnly'); 711 // hide the static map image(s) by giving it a print only style 712 jQuery('.olStaticMap').addClass('olPrintOnly'); 713 // add help button with toggle. 714 jQuery('.olWebOnly > .olMap') 715 .prepend( 716 '<div class="olMapHelpButtonDiv">' 717 + '<button onclick="jQuery(\'.olMapHelp\').toggle(500);" class="olMapHelpButton olHasTooltip"><span>' 718 + 'Show or hide help</span>?</button></div>'); 719 // toggle to switch dynamic vs. static map 720 jQuery('.olMapHelp').before( 721 '<div class="a11y"><button onclick="jQuery(\'.olPrintOnly\').toggle();jQuery(\'.olWebOnly\').toggle();">' 722 + 'Hide or show the dynamic map</button></div>'); 723 } 724} 725 726/** 727 * CSS support flag. 728 * 729 * @type {Boolean} 730 */ 731let olCSSEnable = true; 732 733/* register olInit to run with onload event. */ 734jQuery(olInit); 735