2022-05-03 20:50:57 +02:00
|
|
|
|
'use strict'
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
import { MarkerClusterer } from '@googlemaps/markerclusterer'
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
import Events from '../_events'
|
|
|
|
|
import MarkerUI from './map.google.marker'
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 21:44:33 +02:00
|
|
|
|
|
2021-08-09 18:04:09 +02:00
|
|
|
|
const GoogleMapsDriver = ((window) => {
|
|
|
|
|
class GoogleMapsDriver {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
getName () {
|
|
|
|
|
return 'GoogleMapsDriver'
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
init (el, config = []) {
|
|
|
|
|
const ui = this
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.el = el
|
|
|
|
|
ui.config = config
|
|
|
|
|
ui.markers = []
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
window[`init${ui.getName()}`] = () => {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.googleApiLoaded()
|
|
|
|
|
}
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
const script = document.createElement('script')
|
2021-08-18 20:51:15 +02:00
|
|
|
|
script.src = `https://maps.googleapis.com/maps/api/js?key=${
|
2022-05-03 20:50:57 +02:00
|
|
|
|
config.key
|
|
|
|
|
}&callback=init${ui.getName()}`
|
|
|
|
|
script.async = true
|
|
|
|
|
script.defer = true
|
|
|
|
|
document.head.appendChild(script)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
googleApiLoaded () {
|
|
|
|
|
const ui = this
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
const el = ui.el
|
|
|
|
|
const config = ui.config
|
|
|
|
|
const mapDiv = el.querySelector('.mapAPI-map')
|
2021-08-18 20:51:15 +02:00
|
|
|
|
const zoom =
|
2022-05-03 20:50:57 +02:00
|
|
|
|
config.mapZoom && config.mapZoom !== '0'
|
|
|
|
|
? parseInt(config.mapZoom)
|
|
|
|
|
: 10
|
2021-08-18 20:51:15 +02:00
|
|
|
|
const center =
|
2022-05-03 20:50:57 +02:00
|
|
|
|
config.center && config.center !== ','
|
2021-08-18 20:51:15 +02:00
|
|
|
|
? {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
lat: config.center[1],
|
|
|
|
|
lng: config.center[0],
|
2021-08-18 20:51:15 +02:00
|
|
|
|
}
|
|
|
|
|
: {
|
|
|
|
|
lat: 0,
|
|
|
|
|
lng: 0,
|
2022-05-03 20:50:57 +02:00
|
|
|
|
}
|
2022-09-23 17:37:45 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
const style = config.style ? config.style : null
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
console.log(`${ui.getName()}: API is loaded`)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
// init fontawesome icons
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.MarkerUI = MarkerUI.init()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-06-16 01:38:37 +02:00
|
|
|
|
ui.map = new window.google.maps.Map(mapDiv, {
|
2021-08-09 18:04:09 +02:00
|
|
|
|
zoom,
|
|
|
|
|
center,
|
|
|
|
|
fullscreenControl: true,
|
|
|
|
|
styles: style,
|
2022-05-03 20:50:57 +02:00
|
|
|
|
})
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.default_zoom = zoom
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
mapDiv.classList.add('mapboxgl-map')
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
ui.popup = new ui.MarkerUI({
|
|
|
|
|
map: ui.map,
|
2021-10-28 03:24:23 +02:00
|
|
|
|
align: ['center', 'top'],
|
|
|
|
|
divClass: 'mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none',
|
2021-08-18 20:51:15 +02:00
|
|
|
|
html:
|
|
|
|
|
'<div class="mapboxgl-popup-tip"></div><div class="mapboxgl-popup-content">' +
|
|
|
|
|
'<div class="mapboxgl-popup-close-button" type="button" aria-label="Close popup">×</div>' +
|
|
|
|
|
'<div class="html"></div>' +
|
2021-10-28 03:24:23 +02:00
|
|
|
|
'</div>',
|
2022-05-03 20:50:57 +02:00
|
|
|
|
})
|
|
|
|
|
ui.popup.setMap(ui.map)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-06-16 01:38:37 +02:00
|
|
|
|
ui.geocoder = new window.google.maps.Geocoder()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
ui.cluster = new MarkerClusterer(ui.map, null, {
|
2021-08-18 20:51:15 +02:00
|
|
|
|
styles: [
|
|
|
|
|
{
|
|
|
|
|
width: 30,
|
|
|
|
|
height: 30,
|
2021-10-28 03:24:23 +02:00
|
|
|
|
className: 'mapboxgl-cluster',
|
2021-08-18 20:51:15 +02:00
|
|
|
|
},
|
|
|
|
|
],
|
2022-05-03 20:50:57 +02:00
|
|
|
|
})
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
el.dispatchEvent(new Event(Events.MAPAPILOADED))
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
addMarker (crds, config) {
|
|
|
|
|
const ui = this
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
const pos = {
|
|
|
|
|
lat: crds[1],
|
|
|
|
|
lng: crds[0],
|
2022-05-03 20:50:57 +02:00
|
|
|
|
}
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
const marker = new ui.MarkerUI({
|
|
|
|
|
position: pos,
|
|
|
|
|
map: ui.map,
|
2021-10-28 03:24:23 +02:00
|
|
|
|
align: ['center', 'top'],
|
2022-05-03 20:50:57 +02:00
|
|
|
|
html: `<div class="mapboxgl-marker"><div id="Marker${config.id}" data-id="${config.id}" class="marker">${config.icon}</div></div>`,
|
2021-08-09 18:04:09 +02:00
|
|
|
|
onClick: () => {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
const el = document.querySelector(`#Marker${config.id}`)
|
|
|
|
|
ui.showPopup(pos, config.content)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
el.dispatchEvent(new Event(Events.MAPMARKERCLICK))
|
2021-08-09 18:04:09 +02:00
|
|
|
|
},
|
2022-05-03 20:50:57 +02:00
|
|
|
|
})
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.markers.push(marker)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.cluster.addMarker(marker)
|
2022-06-16 01:38:37 +02:00
|
|
|
|
marker.setMap(ui.map);
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
return marker
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
showPopup (pos, content) {
|
|
|
|
|
const ui = this
|
|
|
|
|
const popup = ui.popup.getDiv()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
if (ui.config.flyToMarker) {
|
|
|
|
|
ui.map.setCenter(pos) // panTo
|
|
|
|
|
if (!ui.config.noZoom) {
|
|
|
|
|
ui.map.setZoom(18)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// keep it hidden to render content
|
2022-05-03 20:50:57 +02:00
|
|
|
|
popup.style.opacity = '0'
|
|
|
|
|
popup.classList.remove('d-none')
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
popup.querySelector('.mapboxgl-popup-content .html').innerHTML = content
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2021-08-18 20:51:15 +02:00
|
|
|
|
popup
|
2021-10-28 03:24:23 +02:00
|
|
|
|
.querySelector('.mapboxgl-popup-close-button')
|
|
|
|
|
.addEventListener('click', (e) => {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
e.preventDefault()
|
|
|
|
|
ui.hidePopup()
|
|
|
|
|
})
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
// set position when content was rendered
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.popup.setPosition(pos, ['center', 'top'])
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
// display popup
|
2022-05-03 20:50:57 +02:00
|
|
|
|
popup.style.opacity = '1'
|
|
|
|
|
popup.style['margin-top'] = '-1rem'
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
hidePopup () {
|
|
|
|
|
const ui = this
|
|
|
|
|
const popup = ui.popup.getDiv()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
popup.classList.add('d-none')
|
|
|
|
|
if (!ui.config.noRestoreBounds || ui.config.flyToBounds) {
|
|
|
|
|
ui.restoreBounds()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.el.dispatchEvent(new Event(Events.MAPPOPUPCLOSE))
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
geocode (addr, callback) {
|
|
|
|
|
const ui = this
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
ui.geocoder.geocode(
|
|
|
|
|
{
|
|
|
|
|
address: addr,
|
|
|
|
|
},
|
|
|
|
|
(results, status) => {
|
2021-10-28 03:24:23 +02:00
|
|
|
|
if (status === 'OK') {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
// results[0].geometry.location;
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2021-10-28 03:24:23 +02:00
|
|
|
|
if (typeof callback === 'function') {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
callback(results)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
return results
|
2021-08-09 18:04:09 +02:00
|
|
|
|
} else {
|
|
|
|
|
console.error(
|
2021-08-18 20:51:15 +02:00
|
|
|
|
`${ui.getName()}: Geocode was not successful for the following reason: ${status}`
|
2022-05-03 20:50:57 +02:00
|
|
|
|
)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
2021-08-18 20:51:15 +02:00
|
|
|
|
}
|
2022-05-03 20:50:57 +02:00
|
|
|
|
)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
reverseGeocode (latLng, callback) {
|
|
|
|
|
const ui = this
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
ui.geocoder.geocode(
|
|
|
|
|
{
|
|
|
|
|
location: latlng,
|
|
|
|
|
},
|
|
|
|
|
(results, status) => {
|
2021-10-28 03:24:23 +02:00
|
|
|
|
if (status === 'OK') {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
// results[0].formatted_address;
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2021-10-28 03:24:23 +02:00
|
|
|
|
if (typeof callback === 'function') {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
callback(results)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
return results
|
2021-08-09 18:04:09 +02:00
|
|
|
|
} else {
|
|
|
|
|
console.error(
|
2021-08-18 20:51:15 +02:00
|
|
|
|
`${ui.getName()}: Reverse Geocoding was not successful for the following reason: ${status}`
|
2022-05-03 20:50:57 +02:00
|
|
|
|
)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
2021-08-18 20:51:15 +02:00
|
|
|
|
}
|
2022-05-03 20:50:57 +02:00
|
|
|
|
)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
addGeoJson (config) {
|
|
|
|
|
const ui = this
|
|
|
|
|
const geojson = JSON.parse(config.geojson)
|
2022-05-03 21:44:33 +02:00
|
|
|
|
// const firstMarker = geojson.features[0].geometry.coordinates
|
2022-05-03 20:50:57 +02:00
|
|
|
|
// Map.setCenter(firstMarker);
|
2022-06-16 01:38:37 +02:00
|
|
|
|
const bounds = new window.google.maps.LatLngBounds()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
// add markers to map
|
|
|
|
|
geojson.features.forEach((marker) => {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
const id = marker.id
|
|
|
|
|
const crds = marker.geometry.coordinates
|
|
|
|
|
const content = marker.properties.content
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
ui.addMarker(crds, {
|
|
|
|
|
id,
|
|
|
|
|
content,
|
|
|
|
|
icon: marker.icon,
|
2022-05-03 20:50:57 +02:00
|
|
|
|
flyToMarker: config.flyToMarker,
|
|
|
|
|
})
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
bounds.extend({
|
2022-10-25 19:31:10 +02:00
|
|
|
|
lat: parseFloat(crds[1]),
|
|
|
|
|
lng: parseFloat(crds[0]),
|
2022-05-03 20:50:57 +02:00
|
|
|
|
})
|
|
|
|
|
})
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
if (ui.markers.length > 1) {
|
|
|
|
|
ui.map.fitBounds(bounds, {
|
|
|
|
|
padding: 30,
|
2022-05-03 20:50:57 +02:00
|
|
|
|
}) // panToBounds
|
2021-08-09 18:04:09 +02:00
|
|
|
|
} else if (ui.markers[0]) {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.map.setCenter(ui.markers[0].getPosition())
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.default_bounds = bounds
|
|
|
|
|
ui.default_zoom = ui.map.getZoom()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
getMap () {
|
|
|
|
|
const ui = this
|
|
|
|
|
return ui.map
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
getPopup () {
|
|
|
|
|
const ui = this
|
|
|
|
|
return ui.popup
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
restoreBounds () {
|
|
|
|
|
const ui = this
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
|
|
|
|
if (ui.default_bounds && ui.markers.length > 1) {
|
|
|
|
|
ui.map.fitBounds(ui.default_bounds, {
|
|
|
|
|
padding: 30,
|
2022-05-03 20:50:57 +02:00
|
|
|
|
}) // panToBounds
|
2021-08-09 18:04:09 +02:00
|
|
|
|
} else {
|
|
|
|
|
if (ui.markers[0]) {
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.map.setCenter(ui.markers[0].getPosition())
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.restoreZoom()
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
restoreZoom () {
|
|
|
|
|
const ui = this
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
ui.map.setZoom(ui.default_zoom)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
return GoogleMapsDriver
|
|
|
|
|
})(window)
|
2021-08-09 18:04:09 +02:00
|
|
|
|
|
2022-05-03 20:50:57 +02:00
|
|
|
|
export default GoogleMapsDriver
|