// ==UserScript==
// @name WME Google Place Layer
// @name:vi WME Google Place Layer
// @namespace https://waze.com/minhtanz1
// @version 1.2
// @description Adds a Google Maps traffic layer overlay to the Waze Map Editor. Syncs with WME’s map center and zoom level. - Shift+P: Toggle layer visibility. - Shift+L: Toggle interactivity (enable/disable pointer events).
// @description:vi Thêm lớp phủ giao thông của Google Maps vào Waze Map Editor. Đồng bộ với trung tâm bản đồ và mức thu phóng của WME. - Shift+P: Chuyển đổi chế độ hiển thị lớp. - Shift+L: Chuyển đổi tính tương tác (bật/tắt sự kiện con trỏ).
// @author Minh Tan
// @match https://*.waze.com/*/editor*
// @match https://*.waze.com/editor*
// @exclude https://*.waze.com/user/editor*
// @grant none
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @license MIT
// ==/UserScript==
/* global W, OpenLayers, google, WazeWrap */
(function() {
'use strict';
let gmap;
let trafficDiv;
let layerEnabled = (localStorage.getItem("WMEGoogleTrafficLayer-enabled") ?? false) === 'true';
let interactivityEnabled = false; // Default: interactivity disabled
// Toggle the display of the Google Traffic Layer
function toggleLayer() {
layerEnabled = !layerEnabled;
const checkbox = document.querySelector("#layer-switcher-item_google_traffic_layer");
if (checkbox) {
checkbox.checked = layerEnabled;
}
trafficDiv.style.display = layerEnabled ? "block" : "none";
localStorage.setItem("WMEGoogleTrafficLayer-enabled", layerEnabled);
}
// Toggle pointer events (i.e. interactivity) on the overlay
function toggleInteractivity() {
interactivityEnabled = !interactivityEnabled;
trafficDiv.style.pointerEvents = interactivityEnabled ? 'auto' : 'none';
console.log("Google Map interactivity " + (interactivityEnabled ? "enabled" : "disabled"));
}
// Initialize the Google Maps overlay
function initTrafficLayer() {
// const trafficLayer = new google.maps.TrafficLayer();
trafficDiv = document.createElement('div');
trafficDiv.id = "trafficDiv";
trafficDiv.style.position = 'absolute';
trafficDiv.style.top = '0';
trafficDiv.style.left = '0';
trafficDiv.style.right = '0';
trafficDiv.style.bottom = '0';
trafficDiv.style.opacity = '0.7'; // transparent layer
// Start with interactivity disabled so WME controls work
trafficDiv.style.pointerEvents = 'none';
W.map.olMap.getViewport().appendChild(trafficDiv);
const lonlat = new OpenLayers.LonLat(W.map.getCenter().lon, W.map.getCenter().lat);
lonlat.transform(new OpenLayers.Projection('EPSG:900913'), new OpenLayers.Projection('EPSG:4326'));
gmap = new google.maps.Map(trafficDiv, {
zoom: W.map.getZoom(),
center: { lat: lonlat.lat, lng: lonlat.lon },
disableDefaultUI: true,
zoomControl: false,
mapTypeId: 'roadmap',
styles: [
//https://developers.google.com/maps/documentation/javascript/style-reference#:~:text=The%20following%20features%20are%20available%3A
// testing style site
// https://mapstyle.withgoogle.com/
{ elementType: 'labels', stylers: [{ visibility: 'off' }] },
{ featureType: 'administrative', stylers: [{ visibility: 'off' }] },
{ featureType: 'administrative', elementType: 'geometry', stylers: [{ visibility: 'off' }] },
{ featureType: 'administrative.land_parcel', stylers: [{ visibility: 'off' }] },
{ featureType: 'administrative.neighborhood', stylers: [{ visibility: 'off' }] },
{ featureType: 'landscape', stylers: [{ visibility: 'off' }] },
{ featureType: "poi", elementType: "geometry", stylers: [{ visibility: "on" }] },
{ featureType: "poi", elementType: "labels", stylers: [{ visibility: "on" }] },
// { featureType: 'road', elementType: 'labels', stylers: [{ visibility: 'on' }] },
// { featureType: 'road', elementType: 'labels.icon', stylers: [{ visibility: 'on' }] },
// { featureType: 'road', elementType: 'geometry', stylers: [{visibility: 'simplified'}] },
// // Show local (narrow) roads with a red tint
// { featureType: 'transit', stylers: [{ visibility: 'off' }] },
// { featureType: 'water', stylers: [{ visibility: 'off' }] }
{
"featureType": "poi.business",
"elementType": "labels.text",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "poi.park",
"elementType": "labels.text",
"stylers": [
{
"visibility": "off"
}
]
},
// Show local (narrow) roads with a red tint
{
"featureType": "road.local",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#ff5252"
},
{
"visibility": "on"
},
{
"weight": 1.5
}
]
},
{
"featureType": "road.local",
"elementType": "labels",
"stylers": [
{
"visibility": "on"
}
]
}
]
});
//show traffic layer
// trafficLayer.setMap(gmap);
if (trafficDiv.firstElementChild) {
trafficDiv.firstElementChild.style.backgroundColor = 'rgb(0 0 0 / 0%)'; //remove white background
}
if (!layerEnabled) {
trafficDiv.style.display = "none";
}
// Sync Google Maps center with WME map movements
WazeWrap.Events.register('moveend', null, function() {
const lonlat = new OpenLayers.LonLat(W.map.getCenter().lon, W.map.getCenter().lat);
lonlat.transform(new OpenLayers.Projection('EPSG:900913'), new OpenLayers.Projection('EPSG:4326'));
gmap.panTo({ lat: lonlat.lat, lng: lonlat.lon });
});
// Sync Google Maps zoom with WME zoom events
WazeWrap.Events.register('zoomend', null, function() {
gmap.setZoom(W.map.getZoom());
});
window.gmap = gmap; // for testing
WazeWrap.Interface.AddLayerCheckbox(
"display",
"Google Traffic Layer",
layerEnabled,
toggleLayer,
W.map.getLayerByName("Google Traffic Layer")
);
new WazeWrap.Interface.Shortcut(
'WMEGoogleTrafficLayer',
'Toggle Traffic Layer',
'layers',
'layersToggleWMEGoogleTrafficLayer',
"Shift+P",
toggleLayer,
null
).add();
new WazeWrap.Interface.Shortcut(
'WMEGoogleInteractivityToggle',
'Toggle Google Map Interactivity',
'layers',
'layersToggleGoogleInteractivity',
'Shift+L',
toggleInteractivity,
null
).add();
}
if (W && W.userscripts && W.userscripts.state && W.userscripts.state.isReady) {
initTrafficLayer();
} else {
document.addEventListener('wme-ready', initTrafficLayer, { once: true });
}
})();