WME Multi Overlay

Fügt die TopPlus Open WMS-Karte, Dark Map und Basemap DE vom Geodatenzentrum zum Waze Map Editor hinzu

ही स्क्रिप्ट इंस्टॉल करा?
लेखकाने सुचवलेली स्क्रिप्ट

तुम्हाला कदाचित ही स्क्रिप्टदेखील आवडेल: WME GeoPortal Overlay DACH Beta.

ही स्क्रिप्ट इंस्टॉल करा
// ==UserScript==
// @name         WME Multi Overlay
// @namespace    https://greasyfork.org/de/users/863740-horst-wittlich
// @version      2025.05.15
// @description  Fügt die TopPlus Open WMS-Karte, Dark Map und Basemap DE vom Geodatenzentrum zum Waze Map Editor hinzu
// @author       Hiwi234
// @match        https://www.waze.com/editor*
// @match        https://www.waze.com/*/editor*
// @match        https://beta.waze.com/editor*
// @match        https://beta.waze.com/*/editor*
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const SCRIPT_NAME = 'WME TopPlus & Dark Map & Basemap DE';
    const SCRIPT_ID = 'wme-topplus-dark-basemap';
    const TOPPLUS_LAYER_NAME = 'TopPlus WMS';
    const DARK_LAYER_NAME = 'OSM Dark Matter';
    const BASEMAP_DE_LAYER_NAME = 'Basemap DE';
    const DEFAULT_OPACITY = 0.64;
    const DEFAULT_ZINDEX = 2000; // Extrem hoher Z-Index für Overlay-Layer
    const DARK_ATTRIBUTION = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>';
    const BASEMAP_DE_ATTRIBUTION = '&copy; <a href="https://www.basemap.de">basemap.de</a>';

    function createTopPlusLayer() {
        const olMap = W.map.getOLMap();

        const topPlusLayer = new OpenLayers.Layer.WMS(
            TOPPLUS_LAYER_NAME,
            "https://sgx.geodatenzentrum.de/wms_topplus_web_open",
            {
                layers: 'web',
                format: 'image/png',
                transparent: true
            },
            {
                transitionEffect: 'resize',
                attribution: '&copy; BKG',
                isBaseLayer: false,
                visibility: false,
                opacity: DEFAULT_OPACITY,
                projection: new OpenLayers.Projection("EPSG:3857"),
                displayInLayerSwitcher: false,
                alwaysInRange: true,
                zIndex: DEFAULT_ZINDEX
            }
        );

        topPlusLayer.setOpacity(DEFAULT_OPACITY);
        olMap.addLayer(topPlusLayer);
        window.topPlusLayer = topPlusLayer;
    }

    function createDarkLayer() {
        const olMap = W.map.getOLMap();

        const darkLayer = new OpenLayers.Layer.XYZ(
            DARK_LAYER_NAME,
            [
                "https://a.basemaps.cartocdn.com/dark_all/${z}/${x}/${y}@2x.png",
                "https://b.basemaps.cartocdn.com/dark_all/${z}/${x}/${y}@2x.png",
                "https://c.basemaps.cartocdn.com/dark_all/${z}/${x}/${y}@2x.png"
            ],
            {
                attribution: DARK_ATTRIBUTION,
                transitionEffect: 'resize',
                isBaseLayer: false,
                visibility: false,
                opacity: DEFAULT_OPACITY,
                displayInLayerSwitcher: false,
                alwaysInRange: true,
                zIndex: DEFAULT_ZINDEX
            }
        );

        darkLayer.setOpacity(DEFAULT_OPACITY);
        olMap.addLayer(darkLayer);
        window.darkLayer = darkLayer;
    }

    function createBasemapDELayer() {
        const olMap = W.map.getOLMap();

        const basemapDELayer = new OpenLayers.Layer.WMS(
            BASEMAP_DE_LAYER_NAME,
            "https://sgx.geodatenzentrum.de/wms_basemapde",
            {
                layers: 'de_basemapde_web_raster_farbe',
                format: 'image/png',
                transparent: true
            },
            {
                transitionEffect: 'resize',
                attribution: BASEMAP_DE_ATTRIBUTION,
                isBaseLayer: false,
                visibility: false,
                opacity: DEFAULT_OPACITY,
                projection: new OpenLayers.Projection("EPSG:3857"),
                displayInLayerSwitcher: false,
                alwaysInRange: true,
                zIndex: DEFAULT_ZINDEX
            }
        );

        basemapDELayer.setOpacity(DEFAULT_OPACITY);
        olMap.addLayer(basemapDELayer);
        window.basemapDELayer = basemapDELayer;
    }

    function createLayerControl(layer, name) {
        const container = document.createElement('div');
        container.className = 'layer-control';

        // Sichtbarkeits-Checkbox
        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = layer.getVisibility();
        checkbox.addEventListener('change', () => layer.setVisibility(checkbox.checked));

        const label = document.createElement('label');
        label.appendChild(checkbox);
        label.appendChild(document.createTextNode(name));

        // Transparenz-Slider
        const opacityContainer = document.createElement('div');
        opacityContainer.className = 'slider-container';

        const opacityLabel = document.createElement('span');
        opacityLabel.textContent = 'Transparenz: ';

        const opacitySlider = document.createElement('input');
        opacitySlider.type = 'range';
        opacitySlider.min = '0';
        opacitySlider.max = '1';
        opacitySlider.step = '0.1';
        opacitySlider.value = layer.opacity;
        opacitySlider.addEventListener('input', () => layer.setOpacity(parseFloat(opacitySlider.value)));

        opacityContainer.appendChild(opacityLabel);
        opacityContainer.appendChild(opacitySlider);

        // Z-Index-Slider
        const zIndexContainer = document.createElement('div');
        zIndexContainer.className = 'slider-container';

        const zIndexLabel = document.createElement('span');
        zIndexLabel.textContent = 'Ebene: ';

        const zIndexSlider = document.createElement('input');
        zIndexSlider.type = 'range';
        zIndexSlider.min = '5';  // Sehr hoher minimaler Z-Index
        zIndexSlider.max = '2500'; // Maximaler Z-Index
        zIndexSlider.step = '5';
        zIndexSlider.value = layer.getZIndex() || DEFAULT_ZINDEX;
        zIndexSlider.addEventListener('input', () => {
            const zIndex = parseInt(zIndexSlider.value);
            layer.setZIndex(zIndex);
        });

        zIndexContainer.appendChild(zIndexLabel);
        zIndexContainer.appendChild(zIndexSlider);

        // Füge alle Elemente zum Container hinzu
        container.appendChild(label);
        container.appendChild(opacityContainer);
        container.appendChild(zIndexContainer);

        return container;
    }

    async function initializeScript() {
        try {
            // Registriere Script-Info
            W.userscripts[SCRIPT_ID] = {
                name: SCRIPT_NAME,
                author: 'Hiwi234',
                version: GM_info.script.version
            };

            // Erstelle Layer
            createTopPlusLayer();
            createDarkLayer();
            createBasemapDELayer();

            // Erstelle Sidebar Tab
            const { tabLabel, tabPane } = W.userscripts.registerSidebarTab(SCRIPT_ID);

            // Setze Tab-Label
            tabLabel.textContent = 'Multi 🗺️';
            tabLabel.title = 'Karten-Overlays';

            // Warte auf DOM-Verfügbarkeit
            await W.userscripts.waitForElementConnected(tabPane);

            // Erstelle Content Container
            const content = document.createElement('div');
            content.className = 'overlay-tab';

            // Füge Layer-Steuerelemente hinzu
            content.appendChild(createLayerControl(window.topPlusLayer, TOPPLUS_LAYER_NAME));
            content.appendChild(createLayerControl(window.darkLayer, DARK_LAYER_NAME));
            content.appendChild(createLayerControl(window.basemapDELayer, BASEMAP_DE_LAYER_NAME));

            // Füge Content zum Tab-Pane hinzu
            tabPane.appendChild(content);

            // Füge Styles hinzu
            const style = document.createElement('style');
            style.textContent = `
                .overlay-tab { padding: 8px; }
                .layer-control {
                    margin-bottom: 20px;
                    padding: 10px;
                    border: 1px solid #ccc;
                    border-radius: 4px;
                }
                .layer-control label {
                    display: block;
                    margin-bottom: 10px;
                    font-weight: bold;
                }
                .slider-container {
                    margin: 8px 0;
                }
                .slider-container span {
                    display: inline-block;
                    width: 100px;
                }
                .slider-container input[type="range"] {
                    width: calc(100% - 105px);
                    vertical-align: middle;
                }
            `;
            document.head.appendChild(style);

            console.log(SCRIPT_NAME + ': Erfolgreich initialisiert');
        } catch (error) {
            console.error(SCRIPT_NAME + ': Fehler bei der Initialisierung:', error);
        }
    }

    // Starte Initialisierung wenn WME bereit ist
    if (W?.userscripts?.state.isReady) {
        initializeScript();
    } else {
        document.addEventListener('wme-ready', initializeScript, { once: true });
    }
})();