WME WazeMY

WME script for WazeMY editing moderation

当前为 2023-02-10 提交的版本,查看 最新版本

    // ==UserScript==
    // @name         WME WazeMY
    // @namespace    https://gf.qytechs.cn/en/scripts/404584-wazemy
    // @version      2023.02.10.01
    // @description  WME script for WazeMY editing moderation
    // @author       junyianl
    // @match        https://beta.waze.com/*
    // @match        https://www.waze.com/editor*
    // @match        https://www.waze.com/*/editor*
    // @exclude      https://www.waze.com/user/editor*
    // @require      https://gf.qytechs.cn/scripts/24851-wazewrap/code/WazeWrap.js
    // @require      https://gf.qytechs.cn/scripts/449165-wme-wazemy-trafcamlist/code/wme-wazemy-trafcamlist.js
    // @grant        GM_xmlhttpRequest
    // @license      MIT
    // ==/UserScript==

    // @connect      p3.fgies.com
    // @connect      p4.fgies.com
    // @connect      t2.fgies.com
    // @connect      jalanow.com
    // @connect      llm.gov.my

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

    /**
     * All mentions of script names and links in this script is my way of giving
     * credit to where it's due.
     * Without those scripts, I would have no place to start.
     * Big thanks to the original script authors.
     *
     * Huge thanks to the following contributors for cam locations around Malaysia.
     * :: epailxi | dckj | firman_bakti | rickylo103 | kweeheng ::
     */

    // var trafficCamsData = [
    //     { desc: 'Jalan Sultan Ismail / Jalan Imbi near Berjaya Times Square KL', lat: 3.14369, lon: 101.71245, url: { Jalanow: 'https://p4.fgies.com/kl8/img/K012W.jpg' } },
    //     { desc: 'PLS CAM C2 SLIM RIVER IC KM372.6 NB', lat: 3.84943, lon: 101.39765, url: {LLM: 'https://www.llm.gov.my/assets/ajax.vigroot.php?h=PLS|PLS CAM C2 SLIM RIVER IC KM372.6 NB'} },
    //     { desc: 'PLUS-Utara near Tapah KM324.4 SB', lat: 4.236409, lon: 101.255623, url: {Jalanow: 'https://p3.fgies.com/bucket-e1e2/E1E2-22.jpg',LLM: 'https://www.llm.gov.my/assets/ajax.vigroot.php?h=PLS|PLS CAM C1 TAPAH KM324.4 SB'} },
    //     { desc: 'DUKE CAM 10 SENTUL PASAR KM0.7 NB', lat: 3.19891, lon: 101.69867, url: {Jalanow: 'https://p3.fgies.com/bucket-duke/DUKE-10.jpg',LLM: 'https://www.llm.gov.my/assets/ajax.vigroot.php?h=DUKE'} },
    //     { desc: 'PLUS-Utara near Slim River KM373.9 NB', lat: 3.841385, lon: 101.407039, url: {Jalanow: 'https://p3.fgies.com/bucket-e1e2/E1E2-06.jpg',LLM: 'https://www.llm.gov.my/assets/ajax.vigroot.php?h=PLS|PLS CAM C2 SLIM RIVER KM373.9 NB'} },
    // ];
    

    const updateMessage = `
    ► Reduced size of map suggestions list, showing only the first found
    suggestion per search grid (with the colour contrast, it should be easy to
    visually locate the other map suggestions in the area, right? :))
    `;

    var staticUpdateID;

    (function () {
        'use strict';
        var settings = {};

        function bootstrap(tries = 1) {
            if (W && W.map && W.model && W.loginManager.user &&
                $ && WazeWrap.Ready) {
                init();
            } else if (tries < 1000) {
                setTimeout(function () { bootstrap(++tries); }, 200);
            } else {
                WazeWrap.Alerts.error(GM_info.script.name, "Bootstrap timeout.")
            }
        }

        async function init() {
            let $section = $('<div>');
            $section.html([
                '<div>',
                'Version: <span id="wazemyVersion"></span><br>',
                '<span id="wazemyUsername"></span> (<span id="wazemyRank"></span>)',
                '</div><br>',
                '<div id="wazemySettings">',
                '<b>Settings</b><br>',
                '<input type="checkbox" id="wazemySettings_tooltip">',
                '<label for="wazemySettings_tooltip">Map tooltip</label><br>',
                '<input type="checkbox" id="wazemySettings_trafcam">',
                '<label for="wazemySettings_trafcam">Traffic cameras</label><br>',
                '</div><br>',
                '<div>',
                '<b>Shortcuts</b><br>',
                'Ctrl+Alt+C: Copy lat/lon of mouse position to clipboard.<br>',
                '</div><br>',
                '<div>',
                '<b>Map Suggestions <i>ALPHA!! USE AT YOUR OWN RISK!!</i></b><br>',
                '<input type="button" id="btnDownloadKoi" value="Scan user areas"><br>',
                'Click on the suggestion IDs to automatically center map to the location.',
                '<div id="wazemyKoiList"></div>',
                '</div>'
            ].join(' '));

            new WazeWrap.Interface.Tab('WazeMY', $section.html(), initializeSettings);
            WazeWrap.Interface.ShowScriptUpdate("WME WazeMY", GM_info.script.version,
            updateMessage, "https://gf.qytechs.cn/en/scripts/404584-wazemy", null);
            
            // Initialize keyboard shortcuts
            new WazeWrap.Interface.Shortcut('WazeMY_latloncopy',
            'Copies lat/lon of mouse position', 'wazemy', 'WazeMY', 'CA+c',
            wazemyCopyLatLon, null).add();

            // Initialize features of WME WazeMY
            wazemyTooltip_init();
            wazemyTrafcam_init();
            wazemyKoi_init();

        }

        /* ******* */
        /* Tooltip */
        /* ******* */
        function wazemyTooltip_init() {
            let $tooltip = $('<div/>');
            $tooltip.attr('id', 'wazemyTooltip');
            $tooltip.css({
                'height': 'auto',
                'width': 'auto',
                'background': 'rgba(0,0,0,0.5)',
                'color': 'white',
                'borderRadius': '5px',
                'padding': '5px',
                'position': 'absolute',
                'top': '0px',
                'left': '0px',
                'visibility': 'hidden',
                'zIndex': '10000'
            })
            $tooltip.appendTo('body');
        }

        function wazemyTooltip_initSettings() {
            setChecked('wazemySettings_tooltip', settings.tooltip);
            if (settings.tooltip) {
                WazeWrap.Events.register('mousemove', null, wazemyTooltip_show);
            }
            $('#wazemySettings_tooltip').change(function () {
                var settingName = $(this)[0].id.substr(15); // strip off the "wazemySettings_" prefix
                settings[settingName] = this.checked;
                saveSettings();
                if (this.checked) {
                    WazeWrap.Events.register('mousemove', null, wazemyTooltip_show);
                }
                else {
                    $('#wazemyTooltip').css('visibility', 'hidden');
                    WazeWrap.Events.unregister('mousemove', null, wazemyTooltip_show);
                }
            });
        }

        function wazemyTooltip_show(e) { // from URO+
            var result = '';
            var showTooltip = false;

            let landmark = W.map.venueLayer.getFeatureBy('renderIntent', 'highlight');
            let segment = W.map.segmentLayer.getFeatureBy('renderIntent', 'highlight');

            if (landmark != null) {
                result = '<b>' + landmark.model.attributes.name + '</b><br>';
                let address = landmark.model.getAddress();
                try {
                    result += address.attributes.houseNumber ? (address.attributes.houseNumber + ', ') : ''
                    result += (address.attributes.street.name ? address.attributes.street.name : 'No street') + '<br>';
                    result += address.attributes.city.attributes.name + ', ';
                    result += address.attributes.state.name + '<br>';
                }
                catch {
                    result += 'No address<br>';
                }
                result += '<b>Lock:</b> ' + (landmark.model.getLockRank() + 1);
                showTooltip = true;
            } else if (segment != null) {
                let segmentId = segment.model.attributes.id;
                // let primaryStreetId = WazeWrap.Model.getPrimaryStreetId(segmentId);
                let address = segment.model.getAddress();
                result = '<b>';
                result += address.attributes.street.name ? address.attributes.street.name : 'No street';
                result += '</b><br>';
                result += address.attributes.city.attributes.name + ', ' + address.attributes.state.name;
                result += '<br>';
                result += '<b>ID:</b> ' + segmentId + '<br>';
                result += '<b>Lock:</b> ' + (segment.model.getLockRank() + 1);
                showTooltip = true;
            }

            if (showTooltip == true) {
                let tw = $('#wazemyTooltip').width();
                let th = $('#wazemyTooltip').height();
                var tooltipX = e.clientX + window.scrollX + 15;
                var tooltipY = e.clientY + window.scrollY + 15;
                // Handle cases where tooltip is too near the edge.
                if ((tooltipX + tw) > W.map.$map.innerWidth()) {
                    tooltipX -= tw + 20; // 20 = scroll bar size
                    if (tooltipX < 0) tooltipX = 0;
                }
                if ((tooltipY + th) > W.map.$map.innerHeight()) {
                    tooltipY -= th + 20;
                    if (tooltipY < 0) tooltipY = 0;
                }
                $('#wazemyTooltip').html(result);
                $('#wazemyTooltip').css({
                    'top': tooltipY + 'px',
                    'left': tooltipX + 'px',
                    'visibility': 'visible'
                });
            } else {
                $('#wazemyTooltip').css('visibility', 'hidden');
            }
        }

        /* *************** */
        /* Traffic cameras */
        /* *************** */
        // Adapted from WME DOT Cameras
        var wazemyTrafcamLayer;

        function wazemyTrafcam_init() {
            if (!OpenLayers.Icon) {
                wazemyTrafcam_installIconClass();
            }
            wazemyTrafcamLayer = new OpenLayers.Layer.Markers("wazemyTrafcamLayer");
            W.map.addLayer(wazemyTrafcamLayer);
            wazemyTrafcam_showIcons();
            wazemyTrafcamLayer.setVisibility(false);
        }

        function wazemyTrafcam_initSettings() {
            setChecked('wazemySettings_trafcam', settings.trafcam);
            if (settings.trafcam) {
                wazemyTrafcamLayer.setVisibility(true);
                // WazeWrap.Events.register('moveend', null, wazemyTrafcam_show);
            }
            $('#wazemySettings_trafcam').change(function () {
                var settingName = $(this)[0].id.substr(15); // strip off the "wazemySettings_" prefix
                settings[settingName] = this.checked;
                saveSettings();
                if (this.checked) {
                    wazemyTrafcamLayer.setVisibility(true);
                    // WazeWrap.Events.register('moveend', null, wazemyTrafcam_show);
                } else {
                    // WazeWrap.Events.unregister('moveend', null, wazemyTrafcam_show);
                    wazemyTrafcamLayer.setVisibility(false);
                }
            });
        }

        function wazemyTrafcam_showIcons() {
            trafficCamsData.forEach((e, idx) => {
                wazemyTrafcam_drawCamIcon({
                    idx: idx,
                    desc: e.desc,
                    src: e.url,
                    width: 20,
                    height: 20,
                    lat: e.lat,
                    lon: e.lon
                });
            });
        }

        function wazemyTrafcam_drawCamIcon(spec) {
            const camIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAAGXcA1uAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpBRDNGNTkwRTYzQThFMzExQTc4MDhDNjAwODdEMzdEQSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2OUI0RUEyN0IwRjcxMUUzOERFM0E1OTJCRUY3NTFBOCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2OUI0RUEyNkIwRjcxMUUzOERFM0E1OTJCRUY3NTFBOCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZGOEJBMzExNkZCMEUzMTFCOEY5QTU3QUQxM0M2MjI5IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkFEM0Y1OTBFNjNBOEUzMTFBNzgwOEM2MDA4N0QzN0RBIi8+IDwvcmRmOkRlc2NyaXB0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';
            let size = new OpenLayers.Size(20, 20);
            let icon = new OpenLayers.Icon(camIcon, size);
            let epsg4326 = new OpenLayers.Projection("EPSG:4326"); // WGS 1984 projection. Malaysia uses EPSG:900913
            let projectTo = W.map.getProjectionObject();
            let lonLat = new OpenLayers.LonLat(spec.lon, spec.lat).transform(epsg4326, projectTo);
            var newMarker = new OpenLayers.Marker(lonLat, icon);
            newMarker.idx = spec.idx;
            newMarker.title = spec.desc;
            newMarker.url = spec.src;
            newMarker.width = spec.width;
            newMarker.height = spec.height;
            newMarker.location = lonLat;
            newMarker.events.register('click', newMarker, wazemyTrafcam_popupCam);
            wazemyTrafcamLayer.addMarker(newMarker);
        }

        function wazemyTrafcam_popupCam(e) {
            // console.log("wazemyTrafcam_popupCam");

            clearInterval(staticUpdateID);
            $("#gmPopupContainerCam").remove();
            $("#gmPopupContainerCam").hide();

            var popupHTML = ([`
                <div id="gmPopupContainerCam" style="margin: 1;text-align: center;padding: 5px;z-index: 1100; position: absolute; color: white; background: rgba(0,0,0,0.5)">
                <table border=0>
                    <tr>
                        <td><div id="mycamdivheader" style="min-height: 20px;white-space: pre-wrap;white-space: -moz-pre-wrap; white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word;width:380px">${this.title}</div></td>
                        <td align="right"><a href="#close" id="gmCloseCamDlgBtn" title="Close" style="color:red">X</a></td>
                    </tr>
                    <tr><td colspan=2>Select source:
                        <select id="wazemy_camSource">
                        </select>
                        <div hidden id="mycamid">${this.idx}</div>
                    </td></tr>
                    <tr><td colspan=2><img style="width:400px" id="staticimage"></td></tr>
                    <tr><td colspan=2><div id="mycamstatus"></div></td></tr>
                </table></div>
            `]);
            $("body").append(popupHTML);

            for (var urlsrc in this.url) {
                if (urlsrc == 'LLM') {
                    let sp = this.url['LLM'].split('|');
                    if (sp.length == 2) {
                        $('#wazemy_camSource').append($('<option>').val(urlsrc).text(urlsrc));
                    }
                } else {
                    $('#wazemy_camSource').append($('<option>').val(urlsrc).text(urlsrc));
                }
            }

            $("#wazemy_camSource").change(function (e) {
                switch (this.value) {
                    case 'Jalanow':
                        wazemyTrafcam_getJalanowImage(trafficCamsData[$('#mycamid').text()]['url']['Jalanow']);
                        break;
                    case 'LLM':
                        wazemyTrafcam_getLLMImage(trafficCamsData[$('#mycamid').text()]['url']['LLM']);
                        break;
                }
            });

            // Get image for the first time when popup is displayed.
            switch (Object.keys(this.url)[0]) {
                case 'Jalanow':
                    wazemyTrafcam_getJalanowImage(this.url['Jalanow']);
                    break;
                case 'LLM':
                    wazemyTrafcam_getLLMImage(this.url['LLM']);
                    break;
            }

            // Handle cases where popup is too near the edge.
            let tw = $('#gmPopupContainerCam').width();
            let th = $('#gmPopupContainerCam').height() + 200;
            var tooltipX = e.clientX + window.scrollX + 15;
            var tooltipY = e.clientY + window.scrollY + 15;
            if ((tooltipX + tw) > W.map.$map.innerWidth()) {
                tooltipX -= tw + 20; // 20 = scroll bar size
                if (tooltipX < 0) tooltipX = 0;
            }
            if ((tooltipY + th) > W.map.$map.innerHeight()) {
                tooltipY -= th + 20;
                if (tooltipY < 0) tooltipY = 0;
            }

            $("#gmPopupContainerCam").css({ left: tooltipX });
            $("#gmPopupContainerCam").css({ top: tooltipY });

            //Add listener for popup's "Close" button
            $("#gmCloseCamDlgBtn").click(function () {
                clearInterval(staticUpdateID);
                $("#gmPopupContainerCam").remove();
                $("#gmPopupContainerCam").hide();
            });
            wazemyTrafcam_dragElement(document.getElementById("gmPopupContainerCam"));

        }

        function wazemyTrafcam_getJalanowImage(url) {
            GM_xmlhttpRequest({
                method: 'GET',
                responseType: 'blob',
                headers: {
                    "authority": "p4.fgies.com",
                    "referer": 'https://www.jalanow.com/',
                    'accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8'
                },
                url: url,
                onload: function (response) {
                    document.getElementById('staticimage').src = URL.createObjectURL(response.response);
                    document.getElementById('mycamstatus').innerHTML = "";
                },
                onerror: function (response) {
                    document.getElementById('mycamstatus').innerHTML = "Error loading image.";
                },
                onprogress: function (response) {
                    document.getElementById('mycamstatus').innerHTML = "Loading image...";
                }
            });
        }

        function wazemyTrafcam_getLLMImage(url) {
            let camImg = url.split("|");

            GM_xmlhttpRequest({
                method: 'GET',
                responseType: 'document',
                url: camImg[0],
                onload: function (response) {
                    const re = new RegExp('src="data:image\/png;base64, ([A-Za-z0-9/+=]*)" title="' + camImg[1] + '"');
                    const m = response.responseText.match(re);
                    document.getElementById('staticimage').src = "data:image/png;base64," + m[1];
                    document.getElementById('mycamstatus').innerHTML = "";
                },
                onerror: function (response) {
                    document.getElementById('mycamstatus').innerHTML = "Error loading image.";
                },
                onprogress: function (response) {
                    document.getElementById('mycamstatus').innerHTML = "Loading image...";
                }
            })
        }

        function wazemyTrafcam_installIconClass() {
            OpenLayers.Icon = OpenLayers.Class({
                url: null,
                size: null,
                offset: null,
                calculateOffset: null,
                imageDiv: null,
                px: null,
                initialize: function (a, b, c, d) {
                    this.url = a;
                    this.size = b || {
                        w: 20,
                        h: 20
                    };
                    this.offset = c || {
                        x: -(this.size.w / 2),
                        y: -(this.size.h / 2)
                    };
                    this.calculateOffset = d;
                    a = OpenLayers.Util.createUniqueID("OL_Icon_");
                    let div = this.imageDiv = OpenLayers.Util.createAlphaImageDiv(a);
                    $(div.firstChild).removeClass('olAlphaImg'); // LEAVE THIS LINE TO PREVENT WME-HARDHATS SCRIPT FROM TURNING ALL ICONS INTO HARDHAT WAZERS --MAPOMATIC
                },
                destroy: function () {
                    this.erase();
                    OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);
                    this.imageDiv.innerHTML = "";
                    this.imageDiv = null;
                },
                clone: function () {
                    return new OpenLayers.Icon(this.url, this.size, this.offset, this.calculateOffset);
                },
                setSize: function (a) {
                    null !== a && (this.size = a);
                    this.draw();
                },
                setUrl: function (a) {
                    null !== a && (this.url = a);
                    this.draw();
                },
                draw: function (a) {
                    OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, this.size, this.url, "absolute");
                    this.moveTo(a);
                    return this.imageDiv;
                },
                erase: function () {
                    null !== this.imageDiv && null !== this.imageDiv.parentNode && OpenLayers.Element.remove(this.imageDiv);
                },
                setOpacity: function (a) {
                    OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null, null, null, null, null, a);
                },
                moveTo: function (a) {
                    null !== a && (this.px = a);
                    null !== this.imageDiv && (null === this.px ? this.display(!1) : (
                        this.calculateOffset && (this.offset = this.calculateOffset(this.size)),
                        OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, {
                            x: this.px.x + this.offset.x,
                            y: this.px.y + this.offset.y
                        })
                    ));
                },
                display: function (a) {
                    this.imageDiv.style.display = a ? "" : "none";
                },
                isDrawn: function () {
                    return this.imageDiv && this.imageDiv.parentNode && 11 != this.imageDiv.parentNode.nodeType;
                },
                CLASS_NAME: "OpenLayers.Icon"
            });
        }

        // Make the DIV element draggable:
        function wazemyTrafcam_dragElement(elmnt) {
            var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
            if (document.getElementById("mycamdivheader")) {
                // if present, the header is where you move the DIV from:
                document.getElementById("mycamdivheader").onmousedown = dragMouseDown;
            } else {
                // otherwise, move the DIV from anywhere inside the DIV:
                elmnt.onmousedown = dragMouseDown;
            }

            function dragMouseDown(e) {
                e = e || window.event;
                e.preventDefault();
                // get the mouse cursor position at startup:
                pos3 = e.clientX;
                pos4 = e.clientY;
                document.onmouseup = closeDragElement;
                // call a function whenever the cursor moves:
                document.onmousemove = elementDrag;
            }

            function elementDrag(e) {
                e = e || window.event;
                e.preventDefault();
                // calculate the new cursor position:
                pos1 = pos3 - e.clientX;
                pos2 = pos4 - e.clientY;
                pos3 = e.clientX;
                pos4 = e.clientY;
                // set the element's new position:
                elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
                elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
            }

            function closeDragElement() {
                // stop moving when mouse button is released:
                document.onmouseup = null;
                document.onmousemove = null;
            }
        }

        /* ************ */
        /* Copy lat/lon */
        /* ************ */
        function wazemyCopyLatLon() {
            copyToClipboard($('.mouse-position').text());
        }

        /* ******** */
        /* Koi fish */
        /* ******** */
        function wazemyKoi_init() {
            // $('btnDownloadKoi').click(wazemyKoi_download);
            console.log("init koi");
            document.getElementById("btnDownloadKoi").addEventListener("click", wazemyKoi_download);
        }
        function wazemyKoi_download() {
            // adapted from WMEURMPT
            $('#wazemyKoiList').empty(); // clear the list first before scanning

            var scanAreaBoundsList = [];
            for (var i = 0; i < W.loginManager.user.areas.length; i++) {
                W.loginManager.user.areas[i].geometry.calculateBounds();
                var bounds = W.loginManager.user.areas[i].geometry.bounds;
                var lonlatFrom = OpenLayers.Layer.SphericalMercator.inverseMercator(bounds.left, bounds.bottom);
                var lonlatTo = OpenLayers.Layer.SphericalMercator.inverseMercator(bounds.right, bounds.top);
                for (var lat = lonlatFrom.lat; lat < lonlatTo.lat; lat += 0.5) {
                    for (var lon = lonlatFrom.lon; lon < lonlatTo.lon; lon += 0.5) {
                        var tileBounds = new OpenLayers.Bounds()
                        tileBounds.extend(new OpenLayers.LonLat(lon.toFixed(6), lat.toFixed(6)));
                        tileBounds.extend(new OpenLayers.LonLat((lon + 0.5).toFixed(6), (lat + 0.5).toFixed(6)));
                        scanAreaBoundsList.push(tileBounds);
                    }
                }
            }
            for (var i = 0; i < scanAreaBoundsList.length; i++) {
            // for (var i = 0; i < 1; i++) {
                var bounds = scanAreaBoundsList[i];
                // var bounds = {};
                // bounds.left = 113.337957;
                // bounds.bottom = 2.909872;
                // bounds.right = 113.529394;
                // bounds.top = 3.154952;
                var url = "https://" + document.location.host + "/row-Descartes/app/Features?language=en&v=2&bbox=" + bounds.left + "%2C" + bounds.bottom + "%2C" + bounds.right + "%2C" + bounds.top + "&segmentSuggestionFilter=1%2C0";
                GM_xmlhttpRequest({
                    method: 'GET',
                    responseType: 'json',
                    url: url,
                    onload: function (response) {
                        var features;
                        var segmentSuggestions;
                        // console.log("onload");
                        features = JSON.parse(response.responseText);
                        segmentSuggestions = features['segmentSuggestions']['objects']
                        // segmentSuggestions.forEach(element => {
                        //     $('#wazemyKoiList').append('<div id="wmy_segsugid_'+ element.id + '">' + element.id + '</div>');
                        //     document.getElementById('wmy_segsugid_'+element.id).addEventListener("click", 
                        //         function() {
                        //             var lon = element.geometry.coordinates[0][0];
                        //             var lat = element.geometry.coordinates[0][1];
                        //             var xy = OpenLayers.Layer.SphericalMercator.forwardMercator(parseFloat(lon), parseFloat(lat));
                        //             W.map.setCenter(xy);
                        //         }
                        //     );
                        // });
                        if (segmentSuggestions.length > 0) {
                            $('#wazemyKoiList').append('<div id="wmy_segsugid_'+ segmentSuggestions[0].id + '">' + segmentSuggestions[0].id + '</div>');
                            document.getElementById('wmy_segsugid_' + segmentSuggestions[0].id).addEventListener("click", function() {
                                var lon = segmentSuggestions[0].geometry.coordinates[0][0];
                                var lat = segmentSuggestions[0].geometry.coordinates[0][1];
                                var xy = OpenLayers.Layer.SphericalMercator.forwardMercator(parseFloat(lon), parseFloat(lat));
                                W.map.setCenter(xy);
                            })
                        }
                    },
                    onerror: function (response) {
                        console.log("WazeMY KoiFish onerror");
                        console.log(response);
                    }
                })
            }
        }

        function initializeSettings() {
            loadSettings();

            $('#wazemyVersion').text(GM_info.script.version);
            $('#wazemyUsername').text(WazeWrap.User.Username());
            $('#wazemyRank').text(WazeWrap.User.Rank());

            wazemyTooltip_initSettings();
            wazemyTrafcam_initSettings();
        }

        function saveSettings() {
            if (localStorage) {
                var localsettings = {
                    tooltip: settings.tooltip,
                    trafcam: settings.trafcam
                };

                localStorage.setItem('WME_wazemySettings', JSON.stringify(localsettings));
            }
        }

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

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

        // utility functions
        var copyToClipboard = function (str) { // from PIE
            var $temp = $('<input>');
            $('body').append($temp);
            $temp.val(str).select();
            document.execCommand('copy');
            $temp.remove();
        };

        bootstrap();
    })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址