您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Lets you see satellite imagery, terrain, OpenStreetMap, etc.
// ==UserScript== // @name Geoguessr Minimap Wizard // @namespace alienperfect // @version 1.1 // @description Lets you see satellite imagery, terrain, OpenStreetMap, etc. // @author Alien Perfect // @match https://www.geoguessr.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com // @run-at document-start // @grant none // ==/UserScript== // You can design your own map. // 1. Go to https://mapstyle.withgoogle.com/ and create your own style. // 2. Replace everything between "// Start" and "// End" below with your own JSON styling. // 3. Change the name for the map below, if you want. const customMap = { name: "Custom", alt: "Show custom map", style: // Start [ { "featureType": "all", "elementType": "labels", "stylers": [ {"visibility": "off"} ] } ] // End } let defaultMap = "roadmap"; let mapList = ["roadmap", "terrain", "satellite", "hybrid", "osm", "custom"]; function getDefaultMap() { return localStorage.getItem("@defaultMap") || defaultMap; } function setDefaultMap(id) { let def = id || defaultMap; localStorage.setItem("@defaultMap", def); console.log("default map is", id); } function setMap(map, id) { setDefaultMap(id); map.setMapTypeId(id); } function addMapSelector(map) { const mapSelector = document.createElement("select"); mapSelector.className = "map-selector"; mapSelector.title = "Click to change the map"; mapSelector.addEventListener("change", function() { setMap(map, this.value); }); for (let id of mapList) { let name = map.mapTypes.get(id).name || id; let alt = map.mapTypes.get(id).alt || name; let option = document.createElement("option"); option.style.backgroundColor = "#fff"; option.textContent = name; option.title = alt; option.value = id; mapSelector.appendChild(option); } mapSelector.value = getDefaultMap(); map.controls[google.maps.ControlPosition.TOP_RIGHT].push(mapSelector); } function loadExtraMaps(map) { const OSM = new google.maps.ImageMapType({ getTileUrl: function(coord, zoom) { var tilesPerGlobe = 1 << zoom; var x = coord.x % tilesPerGlobe; if (x < 0) { x = tilesPerGlobe+x; } return (`https://tile.openstreetmap.org/${zoom}/${x}/${coord.y}.png`); }, maxZoom: 18, tileSize: new google.maps.Size(256, 256), name: "OSM", alt: "OpenStreetMap", }); const custom = new google.maps.StyledMapType( customMap.style, {name: customMap.name, alt: customMap.alt}, ); map.mapTypes.set("osm", OSM); map.mapTypes.set("custom", custom); } function initGoogleMap() { google.maps.Map = class extends google.maps.Map { constructor(...args) { super(...args); loadExtraMaps(this); google.maps.event.addListenerOnce(this, "tilesloaded", () => { this.setMapTypeId(getDefaultMap()); addMapSelector(this); google.maps.event.addListener(this, "maptypeid_changed", () => { let map = this.getMapTypeId(); let defaultMap = getDefaultMap(); // If map changed by itself, set it back. if (map !== defaultMap) { this.setMapTypeId(defaultMap); console.log("changed by itself"); } }); }); } } } function addStyle(css) { let style = document.createElement('style'); let head = document.getElementsByTagName("head")[0]; style.innerHTML = css; head.appendChild(style); } (function() { document.addEventListener('DOMContentLoaded', () => { addStyle(` [class*="round-indicator_roundIndicator__"] { max-width: fit-content; } .map-selector { background-color: #fff; height: 30px; max-width = 25%; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,.3); color: rgb(25,25,25); cursor: pointer; font-family: Roboto, Arial, sans-serif; font-size: 15px; margin: 10px 10px 22px; padding: 0 5px; outline: none; border-radius: 3px; z-index: 100; } `); new MutationObserver(function() { let script = document.querySelector("[src*='maps.googleapis.com/maps/api']"); if (script) { this.disconnect(); script.onload = () => initGoogleMap(); } }).observe(document.head, {childList: true, subtree: true}); }) })();