'use strict'; import $ from 'jquery'; import MarkerClusterer from '@googlemaps/markerclustererplus'; import Events from '../../_events'; import MarkerUI from './_map.google.marker'; const GoogleMapsDriver = (($) => { class GoogleMapsDriver { getName() { return 'GoogleMapsDriver'; } init($el, config = []) { const ui = this; const W = window; ui.$el = $el; ui.config = config; ui.markers = []; W[`init${ui.getName()}`] = () => { ui.googleApiLoaded(); }; $('body').append( ``, ); } googleApiLoaded() { const ui = this; const $el = ui.$el; const config = ui.config; const $mapDiv = $el.find('.mapAPI-map'); const zoom = config['mapZoom'] ? config['mapZoom'] : 10; const center = config['center'] ? { lat: config['center'][1], lng: config['center'][0], } : { lat: 0, lng: 0, }; const style = config['style'] ? config['style'] : null; console.log(`${ui.getName()}: API is loaded`); // init fontawesome icons ui.MarkerUI = MarkerUI.init($); ui.map = new google.maps.Map($mapDiv[0], { zoom, center, fullscreenControl: true, styles: style, }); ui.default_zoom = zoom; $mapDiv.addClass('mapboxgl-map'); ui.popup = new ui.MarkerUI({ map: ui.map, align: ['center', 'top'], divClass: 'mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none', html: '
' + '
×
' + '
' + '
', }); ui.popup.setMap(ui.map); ui.geocoder = new google.maps.Geocoder(); ui.cluster = new MarkerClusterer(ui.map, null, { styles: [{ width: 30, height: 30, className: 'mapboxgl-cluster', }], }); $el.trigger(Events.MAPAPILOADED); } addMarker(crds, config) { const ui = this; const pos = { lat: crds[1], lng: crds[0], }; const marker = new ui.MarkerUI({ position: pos, map: ui.map, align: ['center', 'top'], html: `
${config['icon']}
`, onClick: () => { const $el = $(`#Marker${config['id']}`); ui.showPopup(pos, config['content']); $el.trigger(Events.MAPMARKERCLICK); }, }); ui.markers.push(marker); ui.cluster.addMarker(marker); return marker; } showPopup(pos, content) { const ui = this; const $popup = $(ui.popup.getDiv()); if (ui.config['flyToMarker']) { ui.map.setCenter(pos); // panTo if (!ui.config['noZoom']) { ui.map.setZoom(18); } } // keep it hidden to render content $popup.css({ opacity: '0', }); $popup.removeClass('d-none'); $popup.find('.mapboxgl-popup-content .html').html(content); $popup.find('.mapboxgl-popup-close-button').on('click', (e) => { e.preventDefault(); ui.hidePopup(); }); // set position when content was rendered ui.popup.setPosition(pos, ['center', 'top']); // display popup $popup.css({ 'margin-top': '-1rem', opacity: '1', }); } hidePopup() { const ui = this; const $popup = $(ui.popup.getDiv()); $popup.addClass('d-none'); if (!ui.config['noRestoreBounds'] || ui.config['flyToBounds']) { ui.restoreBounds(); } ui.$el.trigger(Events.MAPPOPUPCLOSE); } geocode(addr, callback) { const ui = this; ui.geocoder.geocode( { address: addr, }, (results, status) => { if (status === 'OK') { //results[0].geometry.location; if (typeof callback === 'function') { callback(results); } return results; } else { console.error( `${ui.getName()}: Geocode was not successful for the following reason: ${status}`, ); } }, ); } reverseGeocode(latLng, callback) { const ui = this; ui.geocoder.geocode( { location: latlng, }, (results, status) => { if (status === 'OK') { //results[0].formatted_address; if (typeof callback === 'function') { callback(results); } return results; } else { console.error( `${ui.getName()}: Reverse Geocoding was not successful for the following reason: ${status}`, ); } }, ); } addGeoJson(config) { const ui = this; const firstMarker = config['geojson'].features[0].geometry.coordinates; //Map.setCenter(firstMarker); const bounds = new google.maps.LatLngBounds(); // add markers to map config['geojson'].features.forEach((marker) => { const id = marker.id; const crds = marker.geometry.coordinates; const content = marker.properties.content; ui.addMarker(crds, { id, content, icon: marker.icon, flyToMarker: config['flyToMarker'], }); bounds.extend({ lat: crds[1], lng: crds[0], }); }); if (ui.markers.length > 1) { ui.map.fitBounds(bounds, { padding: 30, }); //panToBounds } else if (ui.markers[0]) { ui.map.setCenter(ui.markers[0].getPosition()); } ui.default_bounds = bounds; ui.default_zoom = ui.map.getZoom(); } getMap() { const ui = this; return ui.map; } getPopup() { const ui = this; return ui.popup; } restoreBounds() { const ui = this; if (ui.default_bounds && ui.markers.length > 1) { ui.map.fitBounds(ui.default_bounds, { padding: 30, }); //panToBounds } else { if (ui.markers[0]) { ui.map.setCenter(ui.markers[0].getPosition()); } ui.restoreZoom(); } } restoreZoom() { const ui = this; ui.map.setZoom(ui.default_zoom); } } return GoogleMapsDriver; })($); export default GoogleMapsDriver;