WME GGM Layer

Adds a GGM 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). - Shift+T to toggle the traffic jams on the layer

// ==UserScript==
// @name         WME GGM Layer
// @name:vi         WME GGM Layer
// @namespace    https://waze.com/minhtanz1
// @version      2.1
// @description  Adds a GGM  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). - Shift+T to toggle the traffic jams on the layer
// @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ỏ). - Shift+T bặt lớp tình trạng giao thông.
// @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

    let trafficLayer; // Khai báo trafficLayer ở đây để có thể truy cập toàn cục
    let trafficLayerEnabled = true; // Biến trạng thái cho traffic layer, mặc định là bật

    // 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"));
    }
    // Toggle the display of the Google Traffic Layer
    function toggleTrafficLayer() {
        trafficLayerEnabled = !trafficLayerEnabled;
        if (trafficLayer) { // Đảm bảo trafficLayer đã được khởi tạo
            trafficLayer.setMap(trafficLayerEnabled ? gmap : null);
            console.log("Google Traffic Layer " + (trafficLayerEnabled ? "enabled" : "disabled"));
            // Bạn có thể thêm cập nhật trạng thái checkbox ở đây nếu có checkbox cho traffic layer
        } else {
            console.warn("Traffic Layer not yet initialized.");
        }
    }

    // Initialize the Google Maps overlay
    function initPlaceLayer() {
        trafficLayer = new google.maps.TrafficLayer(); // Khởi tạo trafficLayer và gán vào biến toàn cục

        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.country",
                    "elementType": "geometry.stroke",
                    "stylers": [
                        {
                            "color": "#fc2eff"
                        },
                        {
                            "weight": 2
                        }
                    ]
                },
                {
                    "featureType": "administrative.province",
                    "elementType": "geometry.stroke",
                    "stylers": [
                        {
                            "color": "#d6e6ff"
                        },
                        {
                            "visibility": "on"
                        },
                        {
                            "weight": 2
                        }
                    ]
                },
                {
                    "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",
                            "visibility": "off"
                        }
                    ]
                },
                {
                    "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",
                    "stylers": [
                        {
                            "color": "#4400ff"
                        },
                        {
                            "saturation": 55
                        },
                        {
                            "lightness": -25
                        },
                        {
                            "visibility": "on"
                        },
                        {
                            "weight": 1
                        }
                    ]
                },
                {
                    "featureType": "poi.school",
                    "elementType": "geometry.fill",
                    "stylers": [
                        {
                            "color": "#4400ff"
                        },
                        {
                            "visibility": "on"
                        }
                    ]
                },
                {
                    "featureType": "poi.school",
                    "elementType": "geometry.stroke",
                    "stylers": [
                        {
                            "color": "#ffffff"
                        },
                        {
                            "visibility": "on"
                        }
                    ]
                },
                {
                    "featureType": "poi.school",
                    "elementType": "labels.text.fill",
                    "stylers": [
                        {
                            "color": "#4400ff"
                        },
                        {
                            "lightness": -60
                        },
                        {
                            "weight": 7.5
                        }
                    ]
                },
                {
                    "featureType": "poi.school",
                    "elementType": "labels.text.stroke",
                    "stylers": [
                        {
                            "color": "#ffffff"
                        },
                        {
                            "weight": 4
                        }
                    ]
                },
                {
                    "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 by default based on trafficLayerEnabled state
        // ----- BẮT ĐẦU CHỖ CẦN SỬA/THÊM -----
        trafficLayer.setMap(trafficLayerEnabled ? gmap : null);
        // ----- KẾT THÚC CHỖ CẦN SỬA/THÊM -----


        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();
        // Thêm shortcut cho Traffic Layer
        new WazeWrap.Interface.Shortcut(
            'WMEGoogleTrafficLayer',
            'Toggle Google Traffic Layer', // Tên hiển thị trong danh sách shortcut
            'layers', // Loại shortcut (có thể là 'map', 'editor', v.v.)
            'layersToggleGoogleTrafficLayer', // ID duy nhất cho shortcut
            'Shift+T', // Tổ hợp phím để kích hoạt
            toggleTrafficLayer, // Hàm sẽ được gọi khi phím được nhấn
            null // Không có điều kiện đặc biệt
        ).add();
    }

    if (W && W.userscripts && W.userscripts.state && W.userscripts.state.isReady) {
        initPlaceLayer();
    } else {
        document.addEventListener('wme-ready', initPlaceLayer, { once: true });
    }
})();