/** * Load the Google Maps script. * * @version 1.0.0 */ var got_script = false; var is_loaded = {}; document.addEventListener( 'DOMContentLoaded', function() { var maps_embeds = document.querySelectorAll( '.embed-google-maps' ); for ( var i = 0; i < maps_embeds.length; i++ ) { if ( maps_embeds[ i ] ) { maps_embeds[ i ].addEventListener( 'click', function( event ) { const map = event.currentTarget.querySelector( 'div.map' ); let uid = 'undefined'; if ( map ) { uid = map.getAttribute( 'data-uid' ) || 'undefined'; } if ( is_loaded[ uid ] ) { return; } setTimeout( function() { if ( typeof gmap_key === 'undefined' || ! gmap_key.length ) { console.error( 'No Google Maps key found. Stop loading Google Maps.' ); return; } show_map( uid ); }, 100 ); } ) } } if ( ! maps_embeds.length ) { show_map( 'undefined' ); } }); /** * Init function to load the Google Maps script. * * @param {String} gmap_key The Google Maps key */ function init_gmap( gmap_key ) { var interval = setInterval( function() { if ( typeof loadGmap === 'undefined' ) return; loadGmap( gmap_key ); clearInterval( interval ); }, 100 ); } /** * Handles if the map will be displayed or not. * * @param {String} uid */ function show_map( uid ) { is_loaded[ uid ] = true; if ( got_script ) { return; } init_gmap(); } /** * Get the offset of an element. * * @param {element} el * @return {{top: number, left: number}} */ function get_offset( el ) { if ( ! el ) return; var rect = el.getBoundingClientRect(); return { left: rect.left + window.pageXOffset, top: rect.top + window.pageYOffset }; } /** * Load the Google Maps map. * * @param {String} key The Google Maps key */ function loadGmap( key ) { if ( (typeof key === 'undefined' || ! key.length) && (typeof gmap_key === 'undefined' || ! gmap_key.length) ) { return; } var external_script = document.getElementById( 'gmap-external-script' ); if ( ! external_script ) { var script = document.createElement( 'script' ); script.src = 'https://maps.google.com/maps/api/js?key=' + ( key || gmap_key ) + '&callback=gmapScriptLoaded'; script.async = true; script.id = 'gmap-external-script'; document.head.appendChild( script ); window.gmapScriptLoaded = function() { init(); } } else { // wait to let the first init a little time setTimeout( function() { init(); }, 300 ); } } // global variables var bounds = null; var cachedSettings = {}; var isMobile = false; var mapIndex = 0; var maps = {}; var uid = ''; /** * Get the current geographical location. * * @param {number} index * @param {function} next */ function getGeoLocation(index, next) { // get variables from cache var icon = cachedSettings[uid].sitesIcon; var infoWindow = cachedSettings[uid]['infoWindow']; var map = cachedSettings[uid]['map']; var mapAutoZoom = cachedSettings[uid].mapAutoZoom; var mapZoom = cachedSettings[uid].mapZoom; var openInfoWindow = cachedSettings[uid].openPrimaryInfoWindow; var settings = cachedSettings[uid]; var sites = cachedSettings[uid].sites; // index is always 1 too much index--; if (sites[index][1] && sites[index][2]) { // if coordinates are set setMarker(map, sites[index], index, icon, openInfoWindow, infoWindow); // create marker for first sites if (index <= 5) { map.setCenter({lat: sites[index][1], lng: sites[index][2]}); if (sites.length > 1 && mapAutoZoom) { map.fitBounds(bounds); } } // set zoom if (index === 0) { google.maps.event.addListenerOnce(map, 'idle', function() { if (sites.length === 1) map.setZoom(mapZoom); }); } } else { // if coordinates aren’t set if (sites[index][5] !== undefined) { var geoLocation = sites[index][5]; } else { // if there is no optimized version for the address search (without HTML) // then try to detect and replace some of it var geoLocation = sites[index][4].replace(/(.*)<\/strong>/g, '').replace(//g, ' '); } getGeocode(uid, geoLocation, index, settings); } // next map location next(); } /** * Get geocode if needed. * * @param {string} uid * @param {string} geoLocation * @param {number} index * @param {object} settings */ function getGeocode(uid, geoLocation, index, settings) { var geocoder = new google.maps.Geocoder(); var icon = settings.sitesIcon; var infoWindow = settings['infoWindow']; var map = settings['map']; var mapAutoZoom = settings.mapAutoZoom; var mapZoom = settings.mapZoom; var openInfoWindow = settings.openPrimaryInfoWindow; var sites = settings.sites; // get geo location geocoder.geocode({'address': geoLocation}, function(results, status) { switch (status) { case google.maps.GeocoderStatus.OK: sites[index][1] = results[0].geometry.location.lat(); sites[index][2] = results[0].geometry.location.lng(); setMarker(map, sites[index], index, icon, openInfoWindow, infoWindow); // create marker for first sites if (index <= 5) { map.setCenter(results[0].geometry.location); if (sites.length > 1 && mapAutoZoom) { map.fitBounds(bounds); } } // set zoom if (index === 0) { google.maps.event.addListenerOnce(map, 'idle', function() { if (sites.length === 1) map.setZoom(mapZoom); }); } break; case google.maps.GeocoderStatus.OVER_QUERY_LIMIT: console.error('Geocode was not successful for ' + sites[index][0] + ' for the following reason: ' + status); cachedSettings[uid]['nextAddress']--; cachedSettings[uid]['delay']++; break; default: console.error('Geocode was not successful for ' + sites[index][0] + ' for the following reason: ' + status); break; } }); } /** * Initialize the Google Map. */ function init() { var init_interval = setInterval( function() { if ( typeof google === 'undefined' ) { console.warn( 'google is undefined. Aborting.' ); return; } bounds = new google.maps.LatLngBounds(); startMap(); clearInterval( init_interval ); }, 100 ); } /** * Set all markers. * * @param {google.maps.Map} map * @param {number} point * @param {number} index * @param {string} iconUrl * @param {boolean} openInfoWindow * @param {google.maps.InfoWindow} infoWindow */ function setMarker(map, point, index, iconUrl, openInfoWindow, infoWindow) { var site = point; var siteLatLng = new google.maps.LatLng(site[1], site[2]); (function(siteLatLng, site) { if ( typeof iconUrl === 'undefined' ) { iconUrl = '/assets/js/v2/red-dot.png'; } if ( iconUrl.indexOf( 'rh-block-gmap' ) !== -1 || iconUrl.indexOf( '/assets/js/v2/red-dot.png' ) !== -1 ) { var icon = { scaledSize: new google.maps.Size(22, 43), size: new google.maps.Size(22, 43), url: iconUrl, } } else { var icon = { url: iconUrl, } } var marker = new google.maps.Marker({ position: siteLatLng, map: map, title: site[0].replace(/<[^>]+>/g, ''), zIndex: site[3], html: site[4], icon: icon, animation: google.maps.Animation.DROP, }); google.maps.event.addListener(marker, 'click', function() { infoWindow.setContent(this.html); infoWindow.open(map, this); }); if (openInfoWindow && index === 0 && !isMobile) { setTimeout(function() { infoWindow.setContent(marker.html); infoWindow.open(map, marker); }, 50); } bounds.extend(marker.position); } (siteLatLng, site)); } /** * Get te next sites entry. */ function siteIteration() { if (cachedSettings[uid]['nextAddress'] < cachedSettings[uid].sites.length) { cachedSettings[uid]['nextAddress']++; sleep(cachedSettings[uid]['delay']); getGeoLocation(cachedSettings[uid]['nextAddress'], siteIteration); } else if (cachedSettings[uid].sites.length > 1) { if (!cachedSettings[uid].mapAutoZoom) { cachedSettings[uid]['map'].setOptions({maxZoom: cachedSettings[uid].mapZoom}); cachedSettings[uid]['map'].setOptions({minZoom: cachedSettings[uid].mapZoom}); google.maps.event.addListenerOnce(cachedSettings[uid]['map'], 'idle', function() { cachedSettings[uid]['map'].setZoom(cachedSettings[uid].mapZoom); cachedSettings[uid]['map'].setOptions({maxZoom: null}); cachedSettings[uid]['map'].setOptions({minZoom: null}); }); } cachedSettings[uid]['map'].fitBounds(bounds); } } /** * Create the map with its options. */ function startMap() { var mapElements = document.querySelectorAll('div.map'); var currentMap = null; var skippedIndexes = 0; if ( typeof mapSettings === 'undefined' ) { console.warn('mapSettings not defined. Abort loading Google Maps.'); return; } if ( ! mapSettings.length ) { console.log( 'Empty mapSettings defined. Abort loading Google Maps.' ); return; } for ( var index = 0; index < mapElements.length; index++ ) { if (mapElements[ index ] === null) { return; } currentMap = document.querySelector( 'div.map[data-uid="' + mapElements[ index ].getAttribute( 'data-uid' ) + '"]' ); if ( ! currentMap ) { skippedIndexes++; continue; } mapIndex = index - skippedIndexes; // get UID uid = 'uid' + mapElements[ index ].getAttribute('data-uid'); // map already loaded if ( mapElements[ index ].firstChild && cachedSettings[uid].sites.length === mapSettings[mapIndex][uid].sites.length ) { continue; } // search in map settings for ( var n = 0; n < mapSettings.length; n++ ) { if ( typeof mapSettings[ n ] === 'undefined' || typeof mapSettings[ n ][ uid ] === 'undefined' ) { continue; } mapIndex = n; break; } if ( typeof mapSettings[ mapIndex ] === 'undefined' || typeof mapSettings[ mapIndex ][ uid ] === 'undefined' ) { skippedIndexes++; continue; } // check for mobility isMobile = window.matchMedia('(max-width: ' + mapSettings[mapIndex][uid].mwsMobileWidth + 'px)').matches; // get cached data cachedSettings[uid] = []; cachedSettings[uid] = mapSettings[mapIndex][uid]; cachedSettings[uid]['delay'] = 100; cachedSettings[uid]['infoWindow'] = new google.maps.InfoWindow({content: 'laden …'}); cachedSettings[uid]['nextAddress'] = 0; // map options var myOptions = { zoom: mapSettings[mapIndex][uid].mapZoom, disableDefaultUI: isMobile, mapTypeControl: false, mapTypeId: google.maps.MapTypeId.ROADMAP, fullscreenControl: false, streetViewControl: false, scaleControl: true, zoomControl: true }; // get map object maps[uid] = new google.maps.Map(mapElements[ index ], myOptions); cachedSettings[uid]['map'] = maps[uid]; // iterate through each site siteIteration(); // set style if (cachedSettings[uid].customerStyles) { maps[uid].setOptions({styles: cachedSettings[uid].styles}); } google.maps.event.addListenerOnce(maps[uid], 'idle', function() { // set zoom if ( typeof mapSettings[ mapIndex ][ uid ].mapZoom !== 'undefined' && mapSettings[ mapIndex ][ uid ].mapZoom !== 11 ) { maps[ uid ].setZoom( mapSettings[ mapIndex ][ uid ].mapZoom ); } // set custom center setTimeout( function() { if ( typeof cachedSettings[uid] !== 'undefined' && typeof cachedSettings[uid].mapCenter !== 'undefined' && cachedSettings[uid].mapCenter !== false && ( cachedSettings[uid].mapCenter[0] !== 0 || cachedSettings[uid].mapCenter[1] !== 0) ) { var coordinates = new google.maps.LatLng(cachedSettings[uid].mapCenter[0], cachedSettings[uid].mapCenter[1]); maps[uid].fitBounds(new google.maps.LatLngBounds(coordinates)); maps[uid].setCenter(coordinates); } }, 500 ); }); } } /** * A custom sleep function. * * @param {number} delay */ function sleep(delay) { var start = new Date().getTime(); while (new Date().getTime() < start + delay); } if ( typeof insertBefore === 'undefined' ) { /** * Prevent Roboto font from loading by replacing head.insertBefore. */ var head = document.querySelector( 'head' ); // save the original method var insertBefore = head.insertBefore; // replace it head.insertBefore = function( new_element, reference_element ) { if ( new_element.href && new_element.href.indexOf( '//fonts.googleapis.com/css?family=Roboto' ) > -1 ) return; insertBefore.call( head, new_element, reference_element ); }; }