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 });
    }
})();