WME Google Place Layer

Adds a Google Maps Place 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).

// ==UserScript==
// @name         WME Google Place Layer
// @name:vi         WME Google Place Layer
// @namespace    https://waze.com/minhtanz1
// @version      1.9
// @description  Adds a Google Maps Place 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ủ địa điểm 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 placeDiv;
    let layerEnabled = (localStorage.getItem("WMEGooglePlaceLayer-enabled") ?? false) === 'true';
    let interactivityEnabled = false; // Default: interactivity disabled

    // Toggle the display of the Google Place Layer
    function toggleLayer() {
        layerEnabled = !layerEnabled;
        const checkbox = document.querySelector("#layer-switcher-item_google_place_layer");
        if (checkbox) {
            checkbox.checked = layerEnabled;
        }
        placeDiv.style.display = layerEnabled ? "block" : "none";
        localStorage.setItem("WMEGooglePlaceLayer-enabled", layerEnabled);
    }

    // Toggle pointer events (i.e. interactivity) on the overlay
    function toggleInteractivity() {
        interactivityEnabled = !interactivityEnabled;
        placeDiv.style.pointerEvents = interactivityEnabled ? 'auto' : 'none';
        console.log("Google Map interactivity " + (interactivityEnabled ? "enabled" : "disabled"));
    }

    // Initialize the Google Maps overlay
    function initPlaceLayer() {
        //         const trafficLayer = new google.maps.TrafficLayer();

        placeDiv = document.createElement('div');
        placeDiv.id = "trafficDiv";
        placeDiv.style.position = 'absolute';
        placeDiv.style.top = '0';
        placeDiv.style.left = '0';
        placeDiv.style.right = '0';
        placeDiv.style.bottom = '0';
        placeDiv.style.opacity = '0.75'; // transparent layer
        // Start with interactivity disabled so WME controls work
        placeDiv.style.pointerEvents = 'none';
        W.map.olMap.getViewport().appendChild(placeDiv);

        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(placeDiv, {
            zoom: W.map.getZoom(),
            center: { lat: lonlat.lat, lng: lonlat.lon },
            disableDefaultUI: true,
            zoomControl: false,
            mapTypeId: 'roadmap',
            styles: [
                // DON'T CHANGE ANYTHING FROM THIS
                { featureType: 'landscape', stylers: [{ visibility: 'off' }] },
                // TO THIS

                // Link get style json: https://mapstyle.withgoogle.com/
                {
                    "featureType": "administrative.province",
                    "elementType": "geometry.stroke",
                    "stylers": [
                        {
                            "color": "#9238ff"
                        },
                        {
                            "visibility": "on"
                        },
                        {
                            "weight": 1.5
                        }
                    ]
                },
                {
                    "featureType": "administrative.province",
                    "elementType": "labels.text",
                    "stylers": [
                        {
                            "visibility": "on"
                        }
                    ]
                },
                {
                    "featureType": "administrative.province",
                    "elementType": "labels.text.fill",
                    "stylers": [
                        {
                            "color": "#000000"
                        }
                    ]
                },
                {
                    "featureType": "administrative.province",
                    "elementType": "labels.text.stroke",
                    "stylers": [
                        {
                            "visibility": "on"
                        }
                    ]
                },
                {
                    "featureType": "poi.attraction",
                    "elementType": "labels.icon",
                    "stylers": [
                        {
                            "visibility": "simplified"
                        }
                    ]
                },
                {
                    "featureType": "poi.attraction",
                    "elementType": "labels.text.fill",
                    "stylers": [
                        {
                            "color": "#209d2f"
                        }
                    ]
                },
                {
                    "featureType": "poi.business",
                    "elementType": "labels.icon",
                    "stylers": [
                        {
                            "visibility": "simplified"
                        }
                    ]
                },
                {
                    "featureType": "poi.business",
                    "elementType": "labels.text",
                    "stylers": [
                        {
                            "visibility": "off"
                        }
                    ]
                },
                {
                    "featureType": "poi.government",
                    "elementType": "labels.icon",
                    "stylers": [
                        {
                            "color": "#b90e0e"
                        }
                    ]
                },
                {
                    "featureType": "poi.government",
                    "elementType": "labels.text.fill",
                    "stylers": [
                        {
                            "color": "#b90e0e"
                        }
                    ]
                },
                {
                    "featureType": "poi.medical",
                    "elementType": "geometry.fill",
                    "stylers": [
                        {
                            "color": "#f8a0a0"
                        }
                    ]
                },
                {
                    "featureType": "poi.medical",
                    "elementType": "labels",
                    "stylers": [
                        {
                            "visibility": "on"
                        }
                    ]
                },
                {
                    "featureType": "poi.school",
                    "elementType": "labels.icon",
                    "stylers": [
                        {
                            "color": "#218cb0"
                        }
                    ]
                },
                {
                    "featureType": "road.arterial",
                    "elementType": "geometry",
                    "stylers": [
                        {
                            "color": "#e9ec18"
                        },
                        {
                            "visibility": "on"
                        },
                        {
                            "weight": 2
                        }
                    ]
                },
                {
                    "featureType": "road.highway",
                    "elementType": "geometry",
                    "stylers": [
                        {
                            "color": "#0a68ff"
                        },
                        {
                            "visibility": "on"
                        },
                        {
                            "weight": 2.5
                        }
                    ]
                },
                {
                    "featureType": "road.highway",
                    "elementType": "geometry.stroke",
                    "stylers": [
                        {
                            "visibility": "on"
                        },
                        {
                            "weight": 2.5
                        }
                    ]
                },
                {
                    "featureType": "road.local",
                    "elementType": "geometry",
                    "stylers": [
                        {
                            "color": "#ff0000"
                        },
                        {
                            "visibility": "on"
                        },
                        {
                            "weight": 2
                        }
                    ]
                },
                {
                    "featureType": "transit.station.airport",
                    "stylers": [
                        {
                            "visibility": "on"
                        }
                    ]
                },
                {
                    "featureType": "transit.station.bus",
                    "stylers": [
                        {
                            "visibility": "off"
                        }
                    ]
                },
                {
                    "featureType": "transit.station.rail",
                    "stylers": [
                        {
                            "visibility": "on"
                        }
                    ]
                },
                {
                    "featureType": "water",
                    "elementType": "labels.geometry",
                    "stylers": [
                        {
                            "visibility": "off"
                        }
                    ]
                },
                {
                    "featureType": "water",
                    "elementType": "labels.text",
                    "stylers": [
                        {
                            "color": "#ffffff"
                        }
                    ]
                }


            ]
        });

        //show traffic layer
        //         trafficLayer.setMap(gmap);
        if (placeDiv.firstElementChild) {
            placeDiv.firstElementChild.style.backgroundColor = 'rgb(0 0 0 / 0%)'; //remove white background
        }
        if (!layerEnabled) {
            placeDiv.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 Place Layer",
            layerEnabled,
            toggleLayer,
            W.map.getLayerByName("Google Place Layer")
        );

        new WazeWrap.Interface.Shortcut(
            'WMEGooglePlaceLayer',
            'Toggle Place Layer',
            'layers',
            'layersToggleWMEGooglePlaceLayer',
            "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) {
        initPlaceLayer();
    } else {
        document.addEventListener('wme-ready', initPlaceLayer, { once: true });
    }
})();