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: false, 215 type: 'base', 216 title: 'toner', 217 source: new ol.source.Stamen({layer: 'toner'}) 218 }) 219 ); 220 baseLyrGroup.getLayers().push( 221 new ol.layer.Tile({ 222 visible: false, 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 const geoJsonSource = new ol.source.Vector({ 319 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.geojsonfile, 320 format: new ol.format.GeoJSON(), 321 }); 322 overlayGroup.getLayers().push(new ol.layer.Vector({ 323 title: 'GeoJSON file', visible: true, source: geoJsonSource, 324 // TODO 325 // style: { 326 // strokeColor: "#FF00FF", 327 // strokeWidth: 3, 328 // strokeOpacity: 0.7, 329 // pointRadius: 4, 330 // fillColor: "#FF99FF", 331 // fillOpacity: 0.7 332 // } 333 })); 334 335 if (mapOpts.autozoom) { 336 geoJsonSource.once('change', function () { 337 extent = ol.extent.extend(extent, geoJsonSource.getExtent()); 338 map.getView().fit(extent); 339 }); 340 } 341 } catch (e) { 342 console.error(e); 343 } 344 } 345 346 if (mapOpts.gpxfile.length > 0) { 347 try { 348 const gpxSource = new ol.source.Vector({ 349 url: DOKU_BASE + "lib/exe/fetch.php?media=" + mapOpts.gpxfile, 350 format: new ol.format.GPX(), 351 }); 352 overlayGroup.getLayers().push(new ol.layer.Vector({ 353 title: 'GPS track', visible: true, source: gpxSource, 354 // TODO 355 // style: { 356 // strokeColor: "#0000FF", 357 // strokeWidth: 3, 358 // strokeOpacity: 0.7, 359 // pointRadius: 4, 360 // fillColor: "#0099FF", 361 // fillOpacity: 0.7 362 // } 363 })); 364 365 if (mapOpts.autozoom) { 366 gpxSource.once('change', function () { 367 extent = ol.extent.extend(extent, gpxSource.getExtent()); 368 map.getView().fit(extent); 369 }); 370 } 371 } catch (e) { 372 console.error(e); 373 } 374 } 375 376 const container = document.getElementById('popup'); 377 const content = document.getElementById('popup-content'); 378 const closer = document.getElementById('popup-closer'); 379 380 const overlay = new ol.Overlay({ 381 element: container, autoPan: true, autoPanAnimation: { 382 duration: 250, 383 }, //stopEvent: false, 384 }); 385 map.addOverlay(overlay); 386 387 /** 388 * Add a click handler to hide the popup. 389 * @return {boolean} Don't follow the href. 390 */ 391 closer.onclick = function () { 392 overlay.setPosition(undefined); 393 closer.blur(); 394 return false; 395 }; 396 397 // display popup on click 398 map.on('singleclick', function (evt) { 399 const selFeature = map.forEachFeatureAtPixel(evt.pixel, function (feature) { 400 return feature; 401 }); 402 if (selFeature) { 403 overlay.setPosition(evt.coordinate); 404 405 let pContent = '<div class="spacer"> </div>'; 406 let locDesc = ''; 407 408 if (selFeature.get('rowId') !== undefined) { 409 pContent += '<span class="rowId">' + selFeature.get('rowId') + ': </span>'; 410 } 411 if (selFeature.get('name') !== undefined) { 412 pContent += '<span class="txt">' + selFeature.get('name') + '</span>'; 413 locDesc = selFeature.get('name'); 414 // TODO strip <p> tag from locDesc 415 // locDesc = selFeature.get('name').split(/\s+/).slice(0,2).join('+'); 416 } 417 if (selFeature.get('ele') !== undefined) { 418 pContent += '<div class="ele">elevation: ' + selFeature.get('ele') + '</div>'; 419 } 420 if (selFeature.get('type') !== undefined) { 421 pContent += '<div>' + selFeature.get('type') + '</div>'; 422 } 423 if (selFeature.get('time') !== undefined) { 424 pContent += '<div class="time">time: ' + selFeature.get('time') + '</div>'; 425 } 426 if (selFeature.get('description') !== undefined) { 427 pContent += '<div class="desc">' + selFeature.get('description') + '</div>'; 428 } 429 if (selFeature.get('img') !== undefined) { 430 pContent += '<div class="coord" title="lat;lon">' + 431 '<img alt="" src="' + DOKU_BASE + 'lib/plugins/openlayersmap/icons/' + selFeature.get('img') + 432 '" width="16" height="16" ' + 'style="transform:rotate(' + selFeature.get('angle') + 'deg)" /> ' + 433 '<a href="geo:' + selFeature.get('lat') + ',' + selFeature.get('lon') + '?q=' + selFeature.get('lat') + 434 ',' + selFeature.get('lon') + '(' + selFeature.get('alt') + ')" title="Open in navigation app">' + 435 ol.coordinate.format([selFeature.get('lon'), selFeature.get('lat')], '{x}º; {y}º', 4) + '</a></div>'; 436 } 437 content.innerHTML = pContent; 438 } else { 439 // do nothing... 440 } 441 }); 442 443 // change mouse cursor when over marker 444 map.on('pointermove', function (e) { 445 const pixel = map.getEventPixel(e.originalEvent); 446 const hit = map.hasFeatureAtPixel(pixel); 447 map.getTarget().style.cursor = hit ? 'pointer' : ''; 448 }); 449 450 return map; 451} 452 453/** 454 * add layers to the map based on the olMapOverlays object. 455 */ 456function olovAddToMap() { 457 for (const key in olMapOverlays) { 458 const overlay = olMapOverlays[key]; 459 const m = olMaps[overlay.id]; 460 461 switch (overlay.type) { 462 case 'osm': 463 m.addLayer(new ol.layer.Tile({ 464 title: overlay.name, 465 visible: (overlay.visible).toLowerCase() === 'true', 466 opacity: parseFloat(overlay.opacity), 467 source: new ol.source.OSM({ 468 url: overlay.url, 469 crossOrigin: 'Anonymous', 470 attributions: overlay.attribution 471 }) 472 })); 473 break; 474 case 'wms': 475 m.addLayer(new ol.layer.Image({ 476 title: overlay.name, 477 opacity: parseFloat(overlay.opacity), 478 visible: (overlay.visible).toLowerCase() === 'true', 479 source: new ol.source.ImageWMS({ 480 url: overlay.url, 481 params: { 482 'LAYERS': overlay.layers, 483 'VERSION': overlay.version, 484 'TRANSPARENT': overlay.transparent, 485 'FORMAT': overlay.format 486 }, 487 ratio: 1, 488 crossOrigin: 'Anonymous', 489 attributions: overlay.attribution 490 }) 491 })); 492 break; 493 case 'ags': 494 m.addLayer(new ol.layer.Image({ 495 title: overlay.name, 496 opacity: parseFloat(overlay.opacity), 497 visible: (overlay.visible).toLowerCase() === 'true', 498 source: new ol.source.ImageArcGISRest({ 499 url: overlay.url, 500 params: { 501 'LAYERS': overlay.layers, 502 'TRANSPARENT': overlay.transparent, 503 'FORMAT': overlay.format 504 }, 505 ratio: 1, 506 crossOrigin: 'Anonymous', 507 attributions: overlay.attribution 508 }) 509 })); 510 break; 511 // case 'mapillary': 512 // var mUrl = 'http://api.mapillary.com/v1/im/search?'; 513 // if (overlay.skey !== '') { 514 // mUrl = 'http://api.mapillary.com/v1/im/sequence?'; 515 // } 516 // var mLyr = new OpenLayers.Layer.Vector( 517 // "Mapillary", { 518 // projection: new OpenLayers.Projection("EPSG:4326"), 519 // strategies: [new OpenLayers.Strategy.BBOX({ 520 // ratio: 1.1, 521 // resFactor: 1.5 522 // }) /* ,new OpenLayers.Strategy.Cluster({}) */], 523 // protocol: new OpenLayers.Protocol.HTTP({ 524 // url: mUrl, 525 // format: new OpenLayers.Format.GeoJSON(), 526 // params: { 527 // // default to max. 250 locations 528 // 'max-results': 250, 529 // 'geojson': true, 530 // 'skey': overlay.skey 531 // }, 532 // filterToParams: function (filter, params) { 533 // if (filter.type === OpenLayers.Filter.Spatial.BBOX) { 534 // // override the bbox serialization of 535 // // the filter to give the Mapillary 536 // // specific bounds 537 // params['min-lat'] = filter.value.bottom; 538 // params['max-lat'] = filter.value.top; 539 // params['min-lon'] = filter.value.left; 540 // params['max-lon'] = filter.value.right; 541 // // if the width of our bbox width is 542 // // less than 0.15 degrees drop the max 543 // // results 544 // if (filter.value.top - filter.value.bottom < .15) { 545 // OpenLayers.Console.debug('dropping max-results parameter, width is: ', 546 // filter.value.top - filter.value.bottom); 547 // params['max-results'] = null; 548 // } 549 // } 550 // return params; 551 // } 552 // }), 553 // styleMap: new OpenLayers.StyleMap({ 554 // 'default': { 555 // cursor: 'help', 556 // rotation: '${ca}', 557 // externalGraphic: DOKU_BASE + 'lib/plugins/openlayersmapoverlays/icons/arrow-up-20.png', 558 // graphicHeight: 20, 559 // graphicWidth: 20, 560 // }, 561 // 'select': { 562 // externalGraphic: DOKU_BASE + 'lib/plugins/openlayersmapoverlays/icons/arrow-up-20-select.png', 563 // label: '${location}', 564 // fontSize: '1em', 565 // fontFamily: 'monospace', 566 // labelXOffset: '0.5', 567 // labelYOffset: '0.5', 568 // labelAlign: 'lb', 569 // } 570 // }), 571 // attribution: '<a href="http://www.mapillary.com/legal.html">' + 572 // '<img src="http://mapillary.com/favicon.ico" ' + 573 // 'alt="Mapillary" height="16" width="16" />Mapillary (CC-BY-SA)', 574 // visibility: (overlay.visible).toLowerCase() == 'true', 575 // }); 576 // m.addLayer(mLyr); 577 // selectControl.addLayer(mLyr); 578 // break; 579 // case 'search': 580 // m.addLayer(new OpenLayers.Layer.Vector( 581 // overlay.name, 582 // overlay.url, 583 // { 584 // layers: overlay.layers, 585 // version: overlay.version, 586 // transparent: overlay.transparent, 587 // format: overlay.format 588 // }, { 589 // opacity: parseFloat(overlay.opacity), 590 // visibility: (overlay.visible).toLowerCase() == 'true', 591 // isBaseLayer: !1, 592 // attribution: overlay.attribution 593 // } 594 // )); 595 // break; 596 } 597 } 598} 599 600/** init. */ 601function olInit() { 602 if (olEnable) { 603 // add info window to DOM 604 const frag = document.createDocumentFragment(), 605 temp = document.createElement('div'); 606 temp.innerHTML = '<div id="popup" class="olPopup"><a href="#" id="popup-closer" class="olPopupCloseBox"></a><div id="popup-content"></div></div>'; 607 while (temp.firstChild) { 608 frag.appendChild(temp.firstChild); 609 } 610 document.body.appendChild(frag); 611 612 let _i = 0; 613 // create the maps in the page 614 for (_i = 0; _i < olMapData.length; _i++) { 615 var _id = olMapData[_i].mapOpts.id; 616 olMaps[_id] = createMap(olMapData[_i].mapOpts, olMapData[_i].poi); 617 618 // set max-width on help pop-over 619 jQuery('#' + _id).parent().parent().find('.olMapHelp').css('max-width', olMapData[_i].mapOpts.width); 620 621 // shrink the map width to fit inside page container 622 var _w = jQuery('#' + _id + '-olContainer').parent().innerWidth(); 623 if (parseInt(olMapData[_i].mapOpts.width) > _w) { 624 jQuery('#' + _id).width(_w); 625 jQuery('#' + _id).parent().parent().find('.olMapHelp').width(_w); 626 olMaps[_id].updateSize(); 627 } 628 } 629 630 // add overlays 631 olovAddToMap(); 632 633 let resizeTimer; 634 jQuery(window).on('resize', function (e) { 635 clearTimeout(resizeTimer); 636 resizeTimer = setTimeout(function () { 637 for (_i = 0; _i < olMapData.length; _i++) { 638 var _id = olMapData[_i].mapOpts.id; 639 var _w = jQuery('#' + _id + '-olContainer').parent().innerWidth(); 640 if (parseInt(olMapData[_i].mapOpts.width) > _w) { 641 jQuery('#' + _id).width(_w); 642 jQuery('#' + _id).parent().parent().find('.olMapHelp').width(_w); 643 olMaps[_id].updateSize(); 644 } 645 } 646 }, 250); 647 }); 648 649 // hide the table(s) with POI by giving it a print-only style 650 jQuery('.olPOItableSpan').addClass('olPrintOnly'); 651 // hide the static map image(s) by giving it a print only style 652 jQuery('.olStaticMap').addClass('olPrintOnly'); 653 // add help button with toggle. 654 jQuery('.olWebOnly > .olMap') 655 .prepend( 656 '<div class="olMapHelpButtonDiv">' 657 + '<button onclick="jQuery(\'.olMapHelp\').toggle(500);" class="olMapHelpButton olHasTooltip"><span>' 658 + 'Show or hide help</span>?</button></div>'); 659 // toggle to switch dynamic vs. static map 660 jQuery('.olMapHelp').before( 661 '<div class="a11y"><button onclick="jQuery(\'.olPrintOnly\').toggle();jQuery(\'.olWebOnly\').toggle();">' 662 + 'Hide or show the dynamic map</button></div>'); 663 } 664} 665 666/** 667 * CSS support flag. 668 * 669 * @type {Boolean} 670 */ 671let olCSSEnable = true; 672 673/* register olInit to run with onload event. */ 674jQuery(olInit); 675