WME Client Tile Borders

Displays grid lines representing tile borders in the client.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         WME Client Tile Borders
// @namespace    https://greatest.deepsurf.us/en/users/32336-joyriding
// @version      1.10
// @description  Displays grid lines representing tile borders in the client.
// @author       Joyriding
// @include      /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor\/?.*$/
// @require      https://greatest.deepsurf.us/scripts/24851-wazewrap/code/WazeWrap.js
// @grant        none
// ==/UserScript==

/* global W */
/* global OpenLayers */
/* global $ */
/* global WazeWrap */

(function() {
    'use strict';

    var settings = {};
    var wmeCtbLayer;

    var projection=new OpenLayers.Projection("EPSG:900913");
    var displayProjection=new OpenLayers.Projection("EPSG:4326");

    function bootstrap(tries) {
        tries = tries || 1;

        if (W && W.map &&
            W.model && W.loginManager.user &&
            WazeWrap.Ready && $ ) {
            init();
        } else if (tries < 1000)
            setTimeout(function () {bootstrap(tries++);}, 200);
    }

    function init()
    {
        console.log("WME CTB Init");
        loadSettings();
        WazeWrap.Interface.AddLayerCheckbox("display", "Client Tile Borders", settings.Enabled, onLayerCheckboxChanged);
        onLayerCheckboxChanged(settings.Enabled);
    }

    function onLayerCheckboxChanged(checked) {
        settings.Enabled = checked;
        if (wmeCtbLayer) {
            wmeCtbLayer.setVisibility(settings.Enabled);
        }
        if (settings.Enabled)
        {
            if (!wmeCtbLayer) {
                wmeCtbLayer = new OpenLayers.Layer.Vector("wmeCtbLayer",{uniqueName: "__wmeCtbLayer"});
                W.map.addLayer(wmeCtbLayer);
            }
            W.map.events.register("moveend",W.map,drawGridLines);
            drawGridLines();
        } else {
            W.map.events.unregister("moveend",W.map,drawGridLines);
            if (wmeCtbLayer) {
                wmeCtbLayer.removeAllFeatures();
                W.map.removeLayer(wmeCtbLayer);
                wmeCtbLayer = null;
            }
        }
        saveSettings();
    }

    function getOLMapextent()
    {
        var extent = new OpenLayers.Bounds(W.map.getExtent());
        extent = extent.transform('EPSG:4326', 'EPSG:3857');
        return extent;
    }

    function drawGridLines()
    {
        wmeCtbLayer.removeAllFeatures();

        // Zoom-dependant line style options
        var lineWidth = 2;
        var lineColor = 'gray';
        if (W.map.getZoom() <= 1)
        {
            lineWidth = 1;
        }
        else if (W.map.getZoom() >= 15)
        {
            lineColor = '#EDEDED';
        }

        var e=getOLMapextent();
        var geoNW=new OpenLayers.Geometry.Point(e.left,e.top);
        var geoSE=new OpenLayers.Geometry.Point(e.right,e.bottom);

        geoNW=geoNW.transform(projection, displayProjection);
        geoSE=geoSE.transform(projection, displayProjection);

        // Drop everything to the right of the hundredth decimal place
        var latStart = parseFloat(fixedDigits(geoNW.y));
        var latEnd = parseFloat(fixedDigits(geoSE.y));
        var lonStart = parseFloat(fixedDigits(geoNW.x));
        var lonEnd = parseFloat(fixedDigits(geoSE.x));

        // Convert decimal coordinates to positive integer "index" number to make calculations easier and help prevent errors from floating point rounding
        // index = (decimal coordinate * 100) + (180 or 90 * 100)
        var latIndexStart = Number(toLatIndex(latStart));
        var latIndexEnd = Number(toLatIndex(latEnd));
        var lonIndexStart = Number(toLonIndex(lonStart));
        var lonIndexEnd = Number(toLonIndex(lonEnd));

        // Ensure that we're starting with the lower of the latitude coordinates
        var latIndex;
        if (latIndexStart > latIndexEnd)
        {
            latIndex = latIndexEnd;
            latIndexEnd = latIndexStart;
            latIndexStart = latIndex;
        }
        // Expand start and end by 1/100's of a degree so that grid extends beyond visible screen
        latIndexStart--;
        latIndexEnd++;

        // Ensure that we're starting with the lower of the longitude coordinates
        var lonIndex;
        if (lonIndexStart > lonIndexEnd)
        {
            lonIndex = lonIndexEnd;
            lonIndexEnd = lonIndexStart;
            lonIndexStart = lonIndex;
        }
        // Expand start and end by 1/100's of a degree so that grid extends beyond visible screen
        lonIndexStart--;
        lonIndexEnd++;

        // Draw latitude lines every 0.01 degrees
        latIndex = latIndexStart;
        while (latIndex <= latIndexEnd)
        {
            drawDashedLine(true, latIndex, latIndexStart, latIndexEnd, lonIndexStart, lonIndexEnd, lineWidth, lineColor);
            latIndex++;
        }

        // Draw longitude lines every 0.01 degrees
        lonIndex = lonIndexStart;
        while (lonIndex <= lonIndexEnd)
        {
            drawDashedLine(false, lonIndex, latIndexStart, latIndexEnd, lonIndexStart, lonIndexEnd, lineWidth, lineColor);
            lonIndex++;
        }
    }

    // Drop (not round) digits after the hundredths decimal place
    function fixedDigits(num) {
        var fixed = 2;
        var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
        return num.toString().match(re)[0];
    }

    // Convert decimal degrees to and from an index number so that we're always dealing with a positive integer. lat + 180* and long + 90*.
    // When converting from the index number, round to nearest hundredths decimal.
    function toLatIndex(lat) {
        return Number.parseFloat((lat * 100) + 18000).toFixed(0);
    }

    function fromLatIndex(lat) {
        return Number.parseFloat((lat - 18000) / 100).toFixed(2);
    }

    function toLonIndex(lon) {
        return Number.parseFloat((lon * 100) + 9000).toFixed(0);
    }

    function fromLonIndex(lon) {
        return Number.parseFloat((lon - 9000) / 100).toFixed(2);
    }

    function drawDashedLine(isLatLine, lineIndex, latIndexStart, latIndexEnd, lonIndexStart, lonIndexEnd, lineWidth, lineColor) {
        var pointStart = new OpenLayers.Geometry.Point();
        var pointEnd   = new OpenLayers.Geometry.Point();

        if (isLatLine) {
            pointStart.x = Number(fromLonIndex(lonIndexStart));
            pointStart.y = Number(fromLatIndex(lineIndex));
            pointEnd.x = Number(fromLonIndex(lonIndexEnd));
            pointEnd.y = Number(fromLatIndex(lineIndex));
        } else {
            pointStart.x = Number(fromLonIndex(lineIndex));
            pointStart.y = Number(fromLatIndex(latIndexStart));
            pointEnd.x = Number(fromLonIndex(lineIndex));
            pointEnd.y = Number(fromLatIndex(latIndexEnd));
        }

        pointStart.transform(displayProjection, projection);
        pointEnd.transform(displayProjection, projection);

        let lsLine1 = new OpenLayers.Geometry.LineString([pointStart, pointEnd]);

        var lineFeature1 = new OpenLayers.Feature.Vector(lsLine1, {}, {
            strokeWidth: lineWidth,
            strokeDashstyle: '4 4',
            strokeColor: lineColor
        });
        wmeCtbLayer.addFeatures([lineFeature1]);
    }

    function saveSettings() {
        if (localStorage) {
            var localsettings = {
                Enabled: settings.Enabled
            };

            localStorage.setItem("wmeCtb_Settings", JSON.stringify(localsettings));
        }
    }

    function loadSettings() {
        var loadedSettings = $.parseJSON(localStorage.getItem("wmeCtb_Settings"));
        var defaultSettings = {
            Enabled: true
        };
        settings = loadedSettings ? loadedSettings : defaultSettings;
        for (var prop in defaultSettings) {
            if (!settings.hasOwnProperty(prop))
                settings[prop] = defaultSettings[prop];
        }
    }

    bootstrap();
})();