您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Opens the Google Maps editor based on WME's map center.
// ==UserScript== // @name WME Open GMaps Editor // @namespace https://github.com/WazeDev/wme-open-gmaps-editor // @version 0.0.6 // @description Opens the Google Maps editor based on WME's map center. // @author Gavin Canon-Phratsachack (https://github.com/gncnpk) // @match https://beta.waze.com/*editor* // @match https://www.waze.com/*editor* // @exclude https://www.waze.com/*user/*editor/* // @exclude https://www.waze.com/discuss/* // @icon https://www.google.com/s2/favicons?sz=64&domain=waze.com // @license MIT // @contributionURL https://github.com/WazeDev/Thank-The-Authors // @grant none // ==/UserScript== (function() { 'use strict'; let wmeSdk; const zoomLevels = { 1: 52428800, 2: 26214400, 3: 13107200, 4: 6553600, 5: 3276800, 6: 1638400, 7: 819200, 8: 409600, 9: 204800, 10: 102400, 11: 51200, 12: 25600, 13: 12800, 14: 6400, 15: 3200, 16: 1600, 17: 800, 18: 400, 19: 200, 20: 100, 21: 50, 22: 25 } function encodeProtobufToBase64({ latitude, longitude, zoomLevel, sequenceNumber, url } = {}) { // Helper function to encode varint - EXACT ORIGINAL function encodeVarint(value) { const bytes = []; while (value >= 0x80) { bytes.push((value & 0xFF) | 0x80); value >>>= 7; } bytes.push(value & 0xFF); return new Uint8Array(bytes); } // Helper function to encode 64-bit fixed (double) function encodeFixed64(value) { const buffer = new ArrayBuffer(8); const view = new DataView(buffer); view.setFloat64(0, value, true); // little endian return new Uint8Array(buffer); } // Helper function to encode 32-bit fixed (uint32) function encodeFixed32(value) { const buffer = new ArrayBuffer(4); const view = new DataView(buffer); view.setUint32(0, value, true); // little endian return new Uint8Array(buffer); } // Helper function to encode length-delimited data function encodeLengthDelimited(data) { const length = encodeVarint(data.length); const result = new Uint8Array(length.length + data.length); result.set(length, 0); result.set(data, length.length); return result; } // Helper function to encode string function encodeString(str) { const encoder = new TextEncoder(); const data = encoder.encode(str); return encodeLengthDelimited(data); } // Helper function to encode field header (field number + wire type) function encodeFieldHeader(fieldNumber, wireType) { return encodeVarint((fieldNumber << 3) | wireType); } // Helper function to concatenate Uint8Arrays function concatUint8Arrays(...arrays) { const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0); const result = new Uint8Array(totalLength); let offset = 0; for (const arr of arrays) { result.set(arr, offset); offset += arr.length; } return result; } // Wire types const VARINT = 0; const FIXED64 = 1; const LENGTH_DELIMITED = 2; const FIXED32 = 5; try { // Encode the inner coordinate message (field 1.1) const coordMessage = concatUint8Arrays( encodeFieldHeader(2, FIXED64), encodeFixed64(longitude), encodeFieldHeader(3, FIXED64), encodeFixed64(latitude) ); // Encode the dimensions message (field 1.3) const dimensionsMessage = concatUint8Arrays( encodeFieldHeader(1, VARINT), encodeVarint(1920), encodeFieldHeader(2, VARINT), encodeVarint(957) ); // Encode the main nested message (field 1) const mainMessage = concatUint8Arrays( encodeFieldHeader(1, LENGTH_DELIMITED), encodeLengthDelimited(coordMessage), encodeFieldHeader(3, LENGTH_DELIMITED), encodeLengthDelimited(dimensionsMessage), encodeFieldHeader(4, FIXED32), encodeFixed32(zoomLevels[zoomLevel]) ); // Encode the complete protobuf message const completeMessage = concatUint8Arrays( encodeFieldHeader(1, LENGTH_DELIMITED), encodeLengthDelimited(mainMessage), encodeFieldHeader(2, VARINT), encodeVarint(sequenceNumber), encodeFieldHeader(4, LENGTH_DELIMITED), encodeString(url) ); // Convert to URL-safe Base64 const base64String = btoa(String.fromCharCode(...completeMessage)) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, ''); return base64String; } catch (error) { console.error('Error encoding protobuf:', error); return null; } } function waitForElm(selector) { return new Promise(resolve => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { observer.disconnect(); resolve(document.querySelector(selector)); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } window.SDK_INITIALIZED.then(initialize) async function initialize() { wmeSdk = await getWmeSdk({ scriptId: 'wme-open-gmaps-editor', scriptName: 'WME Open GMaps Editor' }) wmeSdk.Events.on({ eventHandler: replaceGoogleLink, eventName: "wme-map-move-end" }) wmeSdk.Events.on({ eventHandler: replaceGoogleLink, eventName: "wme-map-zoom-changed" }) let GMELink = document.createElement("a"); GMELink.id = "wme-open-gmaps-editor-url"; GMELink.target = "_blank"; let img = document.createElement("img"); img.src = "https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_%282020%29.svg"; img.style = "margin-right: 12px;margin-left: 12px;width: 16px;"; img.title = "Open in Google Maps Editor (GME)" GMELink.appendChild(img); waitForElm('.secondary-toolbar-actions').then((elm) => { let toolbar = document.getElementsByClassName("secondary-toolbar-actions")[0]; toolbar.insertBefore(GMELink, toolbar.children[0]); replaceGoogleLink(); }); } function replaceGoogleLink() { const coords = wmeSdk.Map.getMapCenter(); const mapZoom = wmeSdk.Map.getZoomLevel(); const trafficMapLayer_DO = "!5m1!1e1" const mapFixDialog_DO = "!10m1!1e3" let mapUrl = `https://www.google.com/maps/place/@${coords.lat},${coords.lon},${zoomLevels[mapZoom]}m/data=${trafficMapLayer_DO}${mapFixDialog_DO}` const base64Data = encodeProtobufToBase64({ latitude: coords.lat, longitude: coords.lon, zoomLevel: mapZoom, sequenceNumber: 10, url: mapUrl }); if (base64Data) { let url = `https://maps.google.com/roadeditor/iframe?bpb=${base64Data}` document.getElementById("wme-open-gmaps-editor-url").href = url; } else { console.error('Failed to encode protobuf data'); } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址