forked from vicmora/MMM-GoogleMapsTraffic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMMM-GoogleMapsTraffic.js
153 lines (135 loc) · 5.74 KB
/
MMM-GoogleMapsTraffic.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* global Module */
/* Magic Mirror
* Module: MMM-GoogleMapsTraffic
*
* By Victor Mora (modified)
* MIT Licensed.
*/
Module.register("MMM-GoogleMapsTraffic", {
defaults: {
key: '',
lat: '', // Provide a valid latitude (e.g., 40.7128)
lng: '', // Provide a valid longitude (e.g., -74.0060)
height: '300px',
width: '300px',
zoom: 10,
mapTypeId: 'roadmap',
styledMapType: 'standard',
disableDefaultUI: true,
updateInterval: 900000,
backgroundColor: 'rgba(0, 0, 0, 0)',
markers: []
},
start: function () {
if (this.config.key === "") {
Log.error("MMM-GoogleMapsTraffic: key not set!");
return;
}
// Request the styled map JSON from node_helper
this.sendSocketNotification("MMM-GOOGLE_MAPS_TRAFFIC-GET", { style: this.config.styledMapType });
this.updateIntervalId = setInterval(() => {
this.sendSocketNotification("MMM-GOOGLE_MAPS_TRAFFIC-GET", { style: this.config.styledMapType });
}, this.config.updateInterval);
},
getStyles: function () {
return ["MMM-GoogleMapsTraffic.css"];
},
getDom: function () {
const wrapper = document.createElement("div");
// Use a fixed id (adjust if you plan on multiple instances)
wrapper.setAttribute("id", "map");
wrapper.className = "GoogleMap";
wrapper.style.height = this.config.height;
wrapper.style.width = this.config.width;
// Check if the Google Maps API is already loaded
if (!document.querySelector('script[src*="maps.googleapis.com/maps/api/js"]')) {
const script = document.createElement("script");
script.type = "text/javascript";
script.src = `https://maps.googleapis.com/maps/api/js?key=${this.config.key}&callback=initMap&libraries=places&v=weekly&loading=async`;
script.defer = true;
script.async = true;
// Create a global callback that calls our module's initMap
window.initMap = () => {
setTimeout(() => {
this.initMap();
}, 100);
};
document.body.appendChild(script);
} else if (typeof google !== "undefined" && google.maps) {
// If the API is already loaded, call initMap directly after a brief delay.
setTimeout(() => {
this.initMap();
}, 100);
}
return wrapper;
},
initMap: function () {
// Validate latitude and longitude.
if (!this.config.lat || !this.config.lng) {
console.error("MMM-GoogleMapsTraffic: Invalid latitude or longitude. Please check your configuration.");
return;
}
const mapElement = document.getElementById("map");
if (!mapElement) {
console.error("MMM-GoogleMapsTraffic: Map element not found.");
return;
}
// If the map already exists, update its options (style, center, etc.)
if (this.map) {
this.map.setOptions({
zoom: this.config.zoom,
center: { lat: this.config.lat, lng: this.config.lng },
styles: (this.styledMapType && this.styledMapType.length > 0) ? this.styledMapType : null,
disableDefaultUI: this.config.disableDefaultUI,
backgroundColor: this.config.backgroundColor
});
} else {
try {
this.map = new google.maps.Map(mapElement, {
zoom: this.config.zoom,
mapTypeId: this.config.mapTypeId,
center: { lat: this.config.lat, lng: this.config.lng },
styles: (this.styledMapType && this.styledMapType.length > 0) ? this.styledMapType : null,
disableDefaultUI: this.config.disableDefaultUI,
backgroundColor: this.config.backgroundColor
});
// Add a traffic layer to the map.
const trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(this.map);
// Add any markers specified in the configuration.
if (this.config.markers && Array.isArray(this.config.markers)) {
this.config.markers.forEach(marker => {
const markerOptions = {
map: this.map,
position: { lat: marker.lat, lng: marker.lng },
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 6,
fillColor: marker.fillColor || "red",
fillOpacity: 1,
strokeWeight: 1
}
};
new google.maps.Marker(markerOptions);
});
}
} catch (error) {
console.error("Error initializing Google Map:", error);
}
}
},
socketNotificationReceived: function (notification, payload) {
if (notification === "MMM-GOOGLE_MAPS_TRAFFIC-RESPONSE") {
this.styledMapType = payload.styledMapType || [];
// If the map is already initialized, update its style.
if (this.map) {
this.map.setOptions({
styles: (this.styledMapType && this.styledMapType.length > 0) ? this.styledMapType : null
});
} else {
// If the map isn't initialized yet, updateDom() will trigger getDom() and then initMap().
this.updateDom();
}
}
}
});