您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Restore the Gulf of Mexico to its original name in Google Maps.
// ==UserScript== // @name Overlay Gulf of Mexico label on Google Maps // @namespace http://tampermonkey.net/ // @version 1.0.1 // @description Restore the Gulf of Mexico to its original name in Google Maps. // @author You // @match https://www.google.com/maps/* // @icon https://www.google.com/s2/favicons?sz=64&domain=google.com // @license MIT // @grant none // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // ——— UNIVERSAL REPLACER ——— function replaceLabels(root) { // 1) ARIA labels root.querySelectorAll('[aria-label]').forEach(el => { const aria = el.getAttribute('aria-label'); if (aria.includes('Gulf of America')) { el.setAttribute( 'aria-label', aria.replace(/Gulf of America/g, 'Gulf of Mexico') ); } }); // 2) Text nodes everywhere const walker = document.createTreeWalker( root, NodeFilter.SHOW_TEXT, null, false ); let node; while (node = walker.nextNode()) { if (node.nodeValue.includes('Gulf of America')) { node.nodeValue = node.nodeValue.replace( /Gulf of America/g, 'Gulf of Mexico' ); } } } // run once on page load (in case you already have a popup open) replaceLabels(document); // === catch both new nodes AND text-only updates === const observer = new MutationObserver(mutations => { for (const m of mutations) { // newly injected nodes for (const node of m.addedNodes) { if (node.nodeType === 1) replaceLabels(node); } // in-place text changes if (m.type === 'characterData') { const txt = m.target.nodeValue; if (txt && txt.includes('Gulf of America')) { m.target.nodeValue = txt.replace(/Gulf of America/g, 'Gulf of Mexico'); } } } }); observer.observe(document.body, { childList: true, subtree: true, characterData: true }); // === also re-run on marker hover === document.body.addEventListener('mouseover', e => { if (e.target.classList.contains('ET197e')) { // slight delay to let Google finish drawing setTimeout(() => replaceLabels(document), 50); } }); // watch for any new DOM nodes (when you click somewhere, Google injects the popup) new MutationObserver(mutations => { for (let m of mutations) { for (let node of m.addedNodes) { if (node.nodeType === 1) { replaceLabels(node); } } } }).observe(document.body, { childList: true, subtree: true }); const DEFAULT = { lat: 24.745124, lng: -91.737921, backgroundColor: 'rgb(114, 212, 232)', fontSize: '12px' }; const coordsMap = [ { zoom: 2, lat: 24.941090, lng: -90.102396, backgroundColor: 'rgb(109, 212, 232)', fontSize: '12px' }, { zoom: 3, lat: 24.941090, lng: -90.102396, backgroundColor: 'rgb(109, 212, 232)', fontSize: '12px' }, { zoom: 4, lat: 24.501996, lng: -90.058450, backgroundColor: 'rgb(109, 212, 232)', fontSize: '12px' }, { zoom: 5, lat: 24.786898, lng: -90.065263, backgroundColor: 'rgb(114, 212, 232)', fontSize: '12px' }, { zoom: 6, lat: 25.100375, lng: -90.014505, backgroundColor: 'rgb(121, 212, 232)', fontSize: '12px' }, { zoom: 7, lat: 25.189882, lng: -90.047464, backgroundColor: 'rgb(127, 215, 235)', fontSize: '12px' }, { zoom: 8, lat: 25.239890, lng: -90.065263, backgroundColor: 'rgb(131, 214, 235)', fontSize: '12px' }, { zoom: 9, lat: 25.272183, lng: -90.061959, backgroundColor: 'rgb(138, 217, 237)', fontSize: '12px' }, { zoom: 10, lat: 25.290499, lng: -90.063943, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 11, lat: 25.296707, lng: -90.066003, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 12, lat: 25.300121, lng: -90.066003, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 13, lat: 25.301983, lng: -90.065832, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 14, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 15, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 16, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 17, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 18, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 19, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 20, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, { zoom: 21, lat: 25.303225, lng: -90.06583, backgroundColor: 'rgb(145, 217, 237)', fontSize: '12px' }, ]; function getEntryForZoom(zoom) { const e = coordsMap.find(o => o.zoom === zoom); return e || DEFAULT; } function latLngToPoint(lat, lng, centerLat, centerLng, zoom, width, height) { const tileSize = 256; const scale = tileSize * Math.pow(2, zoom); const sinC = Math.min(Math.max(Math.sin(centerLat * Math.PI/180), -0.9999), 0.9999); const worldCX = (centerLng + 180)/360 * scale; const worldCY = (0.5 - Math.log((1 + sinC)/(1 - sinC))/(4*Math.PI)) * scale; const sinT = Math.min(Math.max(Math.sin(lat * Math.PI/180), -0.9999), 0.9999); const worldX = (lng + 180)/360 * scale; const worldY = (0.5 - Math.log((1 + sinT)/(1 - sinT))/(4*Math.PI)) * scale; return { x: worldX - worldCX + width/2, y: worldY - worldCY + height/2 }; } let overlay; function createOverlay() { overlay = document.createElement('div'); overlay.innerHTML = 'Gulf<br>of Mexico'; Object.assign(overlay.style, { position: 'fixed', pointerEvents: 'none', whiteSpace: 'pre-line', textAlign: 'center', borderRadius: '4px', padding: '2px', transform: 'translate(-50%, -100%)', zIndex: '9999', display: 'inline-block', color: 'rgb(12, 125, 148)' }); document.body.appendChild(overlay); } function updateOverlay() { const container = document.querySelector('.widget-scene'); if (!container) return; if (!overlay) createOverlay(); const m = window.location.pathname.match(/@(-?\d+\.\d+),(-?\d+\.\d+),([\d.]+)z/); if (!m) return; const centerLat = parseFloat(m[1]); const centerLng = parseFloat(m[2]); const zoom = Math.round(parseFloat(m[3])); const { lat, lng, backgroundColor, fontSize } = getEntryForZoom(zoom); const rect = container.getBoundingClientRect(); const { x, y } = latLngToPoint(lat, lng, centerLat, centerLng, zoom, rect.width, rect.height); overlay.style.left = `${rect.left + x}px`; overlay.style.top = `${rect.top + y}px`; overlay.style.backgroundColor = backgroundColor; overlay.style.fontSize = fontSize; } setInterval(updateOverlay, 200); })();