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

295 lines
7.0 KiB
JavaScript
Raw Normal View History

2021-10-28 03:24:23 +02:00
'use strict';
2021-08-09 18:04:09 +02:00
2022-01-15 14:23:36 +01:00
import { MarkerClusterer } from '@googlemaps/markerclusterer';
2021-08-09 18:04:09 +02:00
2021-10-28 03:24:23 +02:00
import Events from '../_events';
import MarkerUI from './map.google.marker';
2021-08-09 18:04:09 +02:00
const GoogleMapsDriver = ((window) => {
class GoogleMapsDriver {
getName() {
2021-10-28 03:24:23 +02:00
return 'GoogleMapsDriver';
2021-08-09 18:04:09 +02:00
}
init(el, config = []) {
const ui = this;
ui.el = el;
ui.config = config;
ui.markers = [];
window[`init${ui.getName()}`] = () => {
ui.googleApiLoaded();
};
2021-10-28 03:24:23 +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=${
2021-10-28 03:24:23 +02:00
config['key']
2021-08-18 20:51:15 +02:00
}&callback=init${ui.getName()}`;
2021-08-09 18:04:09 +02:00
script.async = true;
script.defer = true;
document.head.appendChild(script);
}
googleApiLoaded() {
const ui = this;
const el = ui.el;
const config = ui.config;
2021-10-28 03:24:23 +02:00
const mapDiv = el.querySelector('.mapAPI-map');
2021-08-18 20:51:15 +02:00
const zoom =
2021-10-28 03:24:23 +02:00
config['mapZoom'] && config['mapZoom'] !== '0'
? parseInt(config['mapZoom'])
2021-08-18 20:51:15 +02:00
: 10;
const center =
2021-10-28 03:24:23 +02:00
config['center'] && config['center'] !== ','
2021-08-18 20:51:15 +02:00
? {
2021-10-28 03:24:23 +02:00
lat: config['center'][1],
lng: config['center'][0],
2021-08-18 20:51:15 +02:00
}
: {
lat: 0,
lng: 0,
};
2021-10-28 03:24:23 +02:00
const style = config['style'] ? config['style'] : null;
2021-08-09 18:04:09 +02:00
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;
2021-10-28 03:24:23 +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>',
2021-08-09 18:04:09 +02:00
});
ui.popup.setMap(ui.map);
ui.geocoder = new google.maps.Geocoder();
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
},
],
2021-08-09 18:04:09 +02:00
});
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,
2021-10-28 03:24:23 +02:00
align: ['center', 'top'],
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: () => {
2021-10-28 03:24:23 +02:00
const el = document.querySelector(`#Marker${config['id']}`);
ui.showPopup(pos, config['content']);
2021-08-09 18:04:09 +02:00
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();
2021-10-28 03:24:23 +02:00
if (ui.config['flyToMarker']) {
2021-08-09 18:04:09 +02:00
ui.map.setCenter(pos); // panTo
2021-10-28 03:24:23 +02:00
if (!ui.config['noZoom']) {
2021-08-09 18:04:09 +02:00
ui.map.setZoom(18);
}
}
// keep it hidden to render content
2021-10-28 03:24:23 +02:00
popup.style.opacity = '0';
popup.classList.remove('d-none');
2021-08-09 18:04:09 +02:00
2021-10-28 03:24:23 +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) => {
2021-08-18 20:51:15 +02:00
e.preventDefault();
ui.hidePopup();
});
2021-08-09 18:04:09 +02:00
// set position when content was rendered
2021-10-28 03:24:23 +02:00
ui.popup.setPosition(pos, ['center', 'top']);
2021-08-09 18:04:09 +02:00
// display popup
2021-10-28 03:24:23 +02:00
popup.style.opacity = '1';
popup.style['margin-top'] = '-1rem';
2021-08-09 18:04:09 +02:00
}
hidePopup() {
const ui = this;
const popup = ui.popup.getDiv();
2021-10-28 03:24:23 +02:00
popup.classList.add('d-none');
if (!ui.config['noRestoreBounds'] || ui.config['flyToBounds']) {
2021-08-09 18:04:09 +02:00
ui.restoreBounds();
}
ui.el.dispatchEvent(new Event(Events.MAPPOPUPCLOSE));
}
geocode(addr, callback) {
const ui = this;
ui.geocoder.geocode(
{
address: addr,
},
(results, status) => {
2021-10-28 03:24:23 +02:00
if (status === 'OK') {
2021-08-09 18:04:09 +02:00
//results[0].geometry.location;
2021-10-28 03:24:23 +02:00
if (typeof callback === 'function') {
2021-08-09 18:04:09 +02:00
callback(results);
}
return results;
} else {
console.error(
2021-08-18 20:51:15 +02:00
`${ui.getName()}: Geocode was not successful for the following reason: ${status}`
2021-08-09 18:04:09 +02:00
);
}
2021-08-18 20:51:15 +02:00
}
2021-08-09 18:04:09 +02:00
);
}
reverseGeocode(latLng, callback) {
const ui = this;
ui.geocoder.geocode(
{
location: latlng,
},
(results, status) => {
2021-10-28 03:24:23 +02:00
if (status === 'OK') {
2021-08-09 18:04:09 +02:00
//results[0].formatted_address;
2021-10-28 03:24:23 +02:00
if (typeof callback === 'function') {
2021-08-09 18:04:09 +02:00
callback(results);
}
return results;
} else {
console.error(
2021-08-18 20:51:15 +02:00
`${ui.getName()}: Reverse Geocoding was not successful for the following reason: ${status}`
2021-08-09 18:04:09 +02:00
);
}
2021-08-18 20:51:15 +02:00
}
2021-08-09 18:04:09 +02:00
);
}
addGeoJson(config) {
const ui = this;
2021-10-28 03:24:23 +02:00
const geojson = JSON.parse(config['geojson']);
2021-08-09 18:04:09 +02:00
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,
2021-10-28 03:24:23 +02:00
flyToMarker: config['flyToMarker'],
2021-08-09 18:04:09 +02:00
});
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;