webpack-bootstrap-ui-kit/src/js/drivers/map.google.js

295 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict'
import { MarkerClusterer } from '@googlemaps/markerclusterer'
import Events from '../_events'
import MarkerUI from './map.google.marker'
const GoogleMapsDriver = ((window) => {
class GoogleMapsDriver {
getName () {
return 'GoogleMapsDriver'
}
init (el, config = []) {
const ui = this
ui.el = el
ui.config = config
ui.markers = []
window[`init${ui.getName()}`] = () => {
ui.googleApiLoaded()
}
const script = document.createElement('script')
script.src = `https://maps.googleapis.com/maps/api/js?key=${
config.key
}&callback=init${ui.getName()}`
script.async = true
script.defer = true
document.head.appendChild(script)
}
googleApiLoaded () {
const ui = this
const el = ui.el
const config = ui.config
const mapDiv = el.querySelector('.mapAPI-map')
const zoom =
config.mapZoom && config.mapZoom !== '0'
? parseInt(config.mapZoom)
: 10
const center =
config.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, {
zoom,
center,
fullscreenControl: true,
styles: style,
})
ui.default_zoom = zoom
mapDiv.classList.add('mapboxgl-map')
ui.popup = new ui.MarkerUI({
map: ui.map,
align: ['center', 'top'],
divClass: 'mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none',
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>' +
'</div>',
})
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.dispatchEvent(new Event(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: `<div class="mapboxgl-marker"><div id="Marker${config.id}" data-id="${config.id}" class="marker">${config.icon}</div></div>`,
onClick: () => {
const el = document.querySelector(`#Marker${config.id}`)
ui.showPopup(pos, config.content)
el.dispatchEvent(new Event(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.style.opacity = '0'
popup.classList.remove('d-none')
popup.querySelector('.mapboxgl-popup-content .html').innerHTML = content
popup
.querySelector('.mapboxgl-popup-close-button')
.addEventListener('click', (e) => {
e.preventDefault()
ui.hidePopup()
})
// set position when content was rendered
ui.popup.setPosition(pos, ['center', 'top'])
// display popup
popup.style.opacity = '1'
popup.style['margin-top'] = '-1rem'
}
hidePopup () {
const ui = this
const popup = ui.popup.getDiv()
popup.classList.add('d-none')
if (!ui.config.noRestoreBounds || ui.config.flyToBounds) {
ui.restoreBounds()
}
ui.el.dispatchEvent(new Event(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 geojson = JSON.parse(config.geojson)
const firstMarker = geojson.features[0].geometry.coordinates
// Map.setCenter(firstMarker);
const bounds = new google.maps.LatLngBounds()
// add markers to map
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
})(window)
export default GoogleMapsDriver