WME Mapraid Overlays

Mapraid overlays

Verze ze dne 26. 09. 2019. Zobrazit nejnovější verzi.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name             WME Mapraid Overlays
// @namespace        https://greatest.deepsurf.us/en/users/166843-wazedev
// @version          2019.09.25.01
// @description      Mapraid overlays
// @author           JustinS83
// @include          https://www.waze.com/editor*
// @include          https://www.waze.com/*/editor*
// @include          https://beta.waze.com/editor*
// @include          https://beta.waze.com/*/editor*
// @exclude          https://www.waze.com/*user/editor*
// @grant            none
// @require          https://greatest.deepsurf.us/scripts/24851-wazewrap/code/WazeWrap.js
// @contributionURL  https://github.com/WazeDev/Thank-The-Authors
// ==/UserScript==

/* global W */
/* global OL */
/* ecmaVersion 2017 */
/* global $ */
/* global I18n */
/* global _ */
/* global WazeWrap */
/* global require */
/* eslint curly: ["warn", "multi-or-nest"] */

(function() {
    'use strict';

    var _settings;
    var _settingsStoreName = '_wme_mapraid_overlays';
    var _kml;
    var _layerName = 'Mapraid Overlay';
    var _layer = null;
    var countryAbbr;
    var _origOpacity;
    var _mapraidNameMap = {};

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

    bootstrap();

    function isChecked(checkboxId) {
        return $('#' + checkboxId).is(':checked');
    }

    function setChecked(checkboxId, checked) {
        $('#' + checkboxId).prop('checked', checked);
    }

    function loadSettings() {
        _settings = $.parseJSON(localStorage.getItem(_settingsStoreName));
        let _defaultsettings = {
            layerVisible: true,
            EnabledOverlays: {},
            HideCurrentArea: false
        };
        _settings = $.extend({}, _defaultsettings, _settings);
    }

    function saveSettings() {
        if (localStorage) {
            var settings = {
                layerVisible: _layer.visibility,
                EnabledOverlays: _settings.EnabledOverlays,
                HideCurrentArea: _settings.HideCurrentArea
            };
            localStorage.setItem(_settingsStoreName, JSON.stringify(settings));
        }
    }

    async function getKML(url){
        return await $.get(url);
    }

    function GetFeaturesFromKMLString(strKML) {
        var format = new OL.Format.KML({
            'internalProjection': W.map.baseLayer.projection,
            'externalProjection': new OL.Projection("EPSG:4326"),
            'extractStyles': true
        });
        return format.read(strKML);
    }

    async function init(){
        loadSettings();

        var layerid = 'wme_mapraid_overlays';

        _layer = new OL.Layer.Vector("Mapraid Overlays", {
            rendererOptions: { zIndexing: true },
            uniqueName: layerid,
            layerGroup: 'mapraid_overlays',
            zIndex: -9999,
            visibility: _settings.layerVisible
        });
        I18n.translations[I18n.locale].layers.name[layerid] = "Mapraid Overlays";
        W.map.addLayer(_layer);

        var $section = $("<div>", {style:"padding:8px 16px", id:"WMEMapraidOverlays"});
        $section.html([
            `<h4 style="margin-bottom:0px;"><b>WME Mapraid Overlays</b></h4>`,
            `<h6 style="margin-top:0px;">${GM_info.script.version}</h6>`,
            `<div><input type="checkbox" id="_cbMROHideCurrentArea" class="wmemroSettingsCheckbox" /><label for="_cbMROHideCurrentArea">Hide fill for current area</label></div>`,
            `<div id="divWMEMROAvailableOverlays"><label>Available overlays</label> <select id="mroOverlaySelect" style="min-width:125px;"></select><i class="fa fa-plus fa-lg" id="mroAddOverlay" aria-hidden="true" style="color:green; cursor:pointer;"></i></div>`,
            '<div id="currOverlays"></div>',
            '<div style="position:absolute; bottom:0;">Generate new mapraid overlays at <a href="http://wazedev.com/mapraidgenerator.html" target="_blank">http://wazedev.com/mapraidgenerator.html</a></div>',
            '</div>'
        ].join(' '));

        new WazeWrap.Interface.Tab('MRO', $section.html(), init2);
    }

    async function getAvailableOverlays(){
        $('#mroOverlaySelect').innerHTML = "";
        countryAbbr = W.model.countries.top.abbr;
        let KMLinfoArr = await $.get(`https://api.github.com/repos/WazeDev/WME-Mapraid-Overlays/contents/KMLs/${countryAbbr}`);
        let overlaysSelect = $('<div>');
        overlaysSelect.html([
            '<option selected disabled hidden style="display: none" value=""></option>',
            `${KMLinfoArr.map(function(obj){
                let fileName = obj.name.replace(".kml", "");
                if(!_settings.EnabledOverlays[fileName])
                    return `<option value="${fileName}">${fileName}</option>`;
            })}`,
            '</select>'
        ].join(''));
        $('#mroOverlaySelect')[0].innerHTML = overlaysSelect.html();
    }

    function updatePolygons(newKML, mapraidName){
        var _features = GetFeaturesFromKMLString(newKML);

        for(let i=0; i< _features.length; i++){
            _features[i].attributes.name = _features[i].attributes.name.replace('<at><openparen>', '').replace('<closeparen>','');
            _features[i].style.label = _features[i].attributes.name;
            _features[i].style.labelOutlineColor= '#000000';
            _features[i].style.labelOutlineWidth= 4;
            _features[i].style.labelAlign= 'cm';
            _features[i].style.fontSize= "16px";
            _features[i].style.fontColor= _features[i].style.fillColor;//"#ffffff";
            _features[i].attributes.mapraidName = mapraidName;

            if(!_settings.EnabledOverlays[mapraidName].fillAreas){
                if(!_origOpacity)
                    _origOpacity = _features[i].style.fillOpacity;
                _features[i].style.fillOpacity = 0;
            }
        }

        _layer.addFeatures(_features);
    }

    function hex_is_light(color) {
        const hex = color.replace('#', '');
        const c_r = parseInt(hex.substr(0, 2), 16);
        const c_g = parseInt(hex.substr(2, 2), 16);
        const c_b = parseInt(hex.substr(4, 2), 16);
        const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
        return brightness > 70;
    }

    async function BuildEnabledOverlays(mapraidName){
        let kml;
        try{
            kml = await getKML(encodeURI(`https://raw.githubusercontent.com/WazeDev/WME-Mapraid-Overlays/master/KMLs/${countryAbbr}/${mapraidName}.kml`));
        }
        catch(err){
            return;
            console.error(err);
        }
        let kmlObj = $($.parseXML(kml));
        let RaidAreas = $(kmlObj).find('Placemark');

        let $newRaidSection = $('<div>');
        $newRaidSection.html([
            `<fieldset style="border:1px solid silver; padding:8px; border-radius:4px; position:relative;"><legend style="margin-bottom:0px; borer-bottom-style:none; width:auto;"><h4>${mapraidName}</h4></legend>`,
            `<i class="fa fa-minus fa-lg" id="mroRemoveOverlay${mapraidName.replace(/\s/g, "_")}" aria-hidden="true" style="color:red; position:absolute; cursor:pointer; top:10px; right:5px;"></i>`,
            `<div><input type="checkbox" id="_cbMROFillRaidArea${mapraidName.replace(/\s/g, "_")}" ${_settings.EnabledOverlays[mapraidName].fillAreas ? 'checked' : ''} /><label for="_cbMROFillRaidArea${mapraidName.replace(/\s/g, "_")}">Fill raid area</label></div>`,
            `Jump to <select id="${mapraidName.replace(/\s/g, "_")}_Areas">${
            function(){
                let names = $(RaidAreas).find('name');
                let options = "";
                for(let i=0; i<names.length; i++)
                    options += `<option>${$(names[i]).text()}</option>`;
                return options;
            }()
            }</select>`,
            `<i class="fa fa-share" aria-hidden="true" style="color:green; cursor:pointer;" id="JumpTo${mapraidName.replace(/\s/g, "_")}"></i>`,
            '</fieldset>'
        ].join(''));

        $(`#mroOverlaySelect option[value="${mapraidName}"]`).remove(); //remove this option from the list
        $('#currOverlays').append($newRaidSection.html()); //add the mapraid section

        $('[id^="_cbMROFillRaidArea"]').change(function(){
            let mapraid = this.id.replace("_cbMROFillRaidArea", "");
            _settings.EnabledOverlays[_mapraidNameMap[mapraid]].fillAreas = isChecked(this.id);
            saveSettings();
        });

        $('[id^="mroRemoveOverlay"]').click(function(){
            let mapraid = this.id.replace("mroRemoveOverlay", "");
            $(this).parent().remove();

            delete _settings.EnabledOverlays[_mapraidNameMap[mapraid]];
            saveSettings();

            let deleteFeatures = [];
            for(let i=0; i < _layer.features.length; i++){ //delete the features from the layer
                if(_layer.features[i].attributes.mapraidName === _mapraidNameMap[mapraid])
                    deleteFeatures.push(_layer.features[i]);
            }
            _layer.removeFeatures(deleteFeatures);
            getAvailableOverlays();
        });

        $('[id^=_cbMROFillRaidArea]').change(function(){
            let mapraid = this.id.replace("_cbMROFillRaidArea", "");
            for(let i=0; i<_layer.features.length; i++){
                if(_layer.features[i].attributes.mapraidName.replace(/\s/g, "_") === mapraid){
                    if(!_origOpacity)
                        _origOpacity = _layer.features[i].style.fillOpacity;
                    _layer.features[i].style.fillOpacity = isChecked(this.id) ? _origOpacity : 0;
                    _layer.redraw();
                }
            }
        });

        $('[id^="JumpTo"]').click(function(){
            //jump to the appropriate area - look up the area in the layer features and jump to the centroid.
            let raidArea = this.id.replace("JumpTo", "");
            for(let i=0; i<_layer.features.length; i++){
                if(_layer.features[i].attributes.mapraidName.replace(/\s/g, "_") === raidArea){
                    let selectedArea = $(`#${raidArea.replace(/\s/g, "_")}_Areas`).val();
                    if(_layer.features[i].attributes.name === selectedArea){
                        let centroid = _layer.features[i].geometry.getCentroid();
                        W.map.setCenter([centroid.x, centroid.y], W.map.zoom)
                        break;
                    }
                }
            }

        });

        updatePolygons(kml, mapraidName);
    }

    function HandleMoveZoom(){
        //display the current MR area in the title bar
        //hide the current MR area fill (if setting is enabled)

        if($('#mrodivCurrMapraidArea').length === 0){
            var $section = $("<div>");
            $section.html([
                '<div id="mrodivCurrMapraidArea" style="font-size: 16px; font-weight:bold; margin-left:10px; float:left;">',
                '<span id="mroCurrAreaTopbar"></span>',
                '</div>'
            ].join(' '));

            $('.topbar').append($section.html());
        }

        let center = new OL.Geometry.Point(W.map.center.lon,W.map.center.lat);
        $('#mroCurrAreaTopbar').text("");
        for (var i=0;i<_layer.features.length;i++){
            var feature = _layer.features[i];
            if(_origOpacity && _settings.EnabledOverlays[feature.attributes.mapraidName].fillAreas)
                feature.style.fillOpacity = _origOpacity;
            if(feature.geometry.intersects(center)){
                $('#mroCurrAreaTopbar').text(feature.attributes.name);
                $('#mroCurrAreaTopbar').css('color', feature.style.fillColor);

                if(!hex_is_light(feature.style.fillColor))
                    $('#mroCurrAreaTopbar').css('text-shadow', '-1px 0 #efefef, 0 1px #efefef, 1px 0 #efefef, 0 -1px #efefef');
                else
                    $('#mroCurrAreaTopbar').css('text-shadow', '-1px 0 black, 0 1px black, 1px 0 black, 0 -1px black');


                if(_settings.HideCurrentArea){
                    if(!_origOpacity)
                        _origOpacity = feature.style.fillOpacity;
                    if(feature.style.fillOpacity > 0)
                        feature.style.fillOpacity = 0;
                }
            }
        }
        _layer.redraw();
    }

    function init2(){
        getAvailableOverlays();

        $.each(_settings.EnabledOverlays, function(k, v){
            if(!_mapraidNameMap[k.replace(/\s/g, "_")])
                _mapraidNameMap[k.replace(/\s/g, "_")] = k;
            BuildEnabledOverlays(k);

        });

        $('#mroAddOverlay').click(async function(){
            if($('#mroOverlaySelect').val() !== null){
                let raid = $('#mroOverlaySelect').val();
                _settings.EnabledOverlays[raid] = {fillAreas: true};

                BuildEnabledOverlays(raid);
                if(!_mapraidNameMap[raid.replace(/\s/g, "_")])
                    _mapraidNameMap[raid.replace(/\s/g, "_")] = raid;

                saveSettings();
            }
        });

        $('.wmemroSettingsCheckbox').change(function(){
            var settingName = $(this)[0].id.substr(6);
            _settings[settingName] = this.checked;
            saveSettings();
        });

        $('#_cbMROHideCurrentArea').change(function(){
            HandleMoveZoom();
        });

        WazeWrap.Events.register("zoomend", null, HandleMoveZoom);
        WazeWrap.Events.register("moveend", null, HandleMoveZoom);

        setChecked('_cbMROHideCurrentArea', _settings.HideCurrentArea);
        HandleMoveZoom();
    }

})();