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

295 lines
7.0 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/markerclustererplus";
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;