GeoGuessr Custom Maps

using modified maps in geoguessr games

当前为 2024-08-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GeoGuessr Custom Maps
  3. // @namespace https://gf.qytechs.cn/users/1179204
  4. // @description using modified maps in geoguessr games
  5. // @version 1.0.6
  6. // @author KaKa
  7. // @license BSD
  8. // @match *://www.geoguessr.com/*
  9. // @require https://update.gf.qytechs.cn/scripts/502813/1423193/Geoguessr%20Tag.js
  10. // @icon https://www.svgrepo.com/show/392367/interaction-interface-layer-layers-location-map.svg
  11.  
  12. // ==/UserScript==
  13.  
  14. (function() {
  15.  
  16. /*=========================================================================Modifiy your guess map here==================================================================================*/
  17.  
  18. let customOptions={
  19.  
  20. Language:'en', //en,zh,ja,fr,de,es
  21.  
  22. Google_StreetView_Layer_Lines_Style:'Default', // More styles see below
  23.  
  24. Google_StreetView_Layer_Shortcut:'V',
  25.  
  26. Google_Labels_Layer_Shortcut:'G',
  27.  
  28. Google_Terrain_Layer_Shortcut:'T',
  29.  
  30. Google_Satellite_Layer_Shortcut:'B',
  31.  
  32. OpenWeather_Shortcut:'Q',
  33.  
  34. OpenWeather_Style:'radar', //'radar': Global Precipitation; 'CL':Cloud; 'APM':Pressure; 'TA2'Temperature; 'WS10':Wind Speed;
  35.  
  36. OpenWeather_Date:'now', // foramt:yyyy-mm-dd, less than one week ago
  37.  
  38. Bing_Maps_Style:'r', // 'a':satellite(without labels); 'h':hybrid; 'r':roadmap,'sre':terrain
  39.  
  40. Map_Tiler_Style:'basic', //basic,satellite,bright,landscape,ocean,outdoor,topo,streets,dataviz
  41.  
  42. Carto_Style:'light_all', //light_all,dark_all
  43.  
  44. Thunderforest_Style:'spinal-map'} //spinal-map,landscape,outdoors,atlas,transport,
  45.  
  46.  
  47. let tileServices=["Google_Maps","OpenStreetMap","Bing_Maps","Map_Tiler","Thunderforest","Carto","Petal_Maps"]
  48.  
  49. let colorOptions={
  50.  
  51. Default:['1098ad','99e9f2'],
  52.  
  53. Crimson:['f03e3e','ffc9c9'],
  54.  
  55. Deep_Pink:['d6336c','fcc2d7'],
  56.  
  57. Blue_Violet:['ae3ec9','eebefa'],
  58.  
  59. Slate_Blue:['7048e8','d0bfff'],
  60.  
  61. Royal_Blue:['4263eb','bac8ff'],
  62.  
  63. Dodger_Blue: ['1c7ed6','a5d8ff'],
  64.  
  65. Sea_Green:['0ca678','96f2d7'],
  66.  
  67. Lime_Green:['37b24d','b2f2bb'],
  68.  
  69. OliveDrab:['74b816','d8f5a2'],
  70.  
  71. Orange:['f59f00','ffec99'],
  72.  
  73. Dark_Orange:['f76707','ffd8a8'],
  74.  
  75. Brown:['bd5f1b','f7ca9e'],
  76. }
  77.  
  78. /*======================================================================================================================================================================================*/
  79.  
  80.  
  81. let currentMapType='roadmap',currentLayers=[],isGoogleDisplay=true,isSV=false,opacityControl
  82.  
  83. const openWeatherBaseURL = "https://g.sat.owm.io/vane/2.0/weather";
  84. const radarURL = `https://b.sat.owm.io/maps/2.0/radar/{z}/{x}/{y}?appid=9de243494c0b295cca9337e1e96b00e2&day=${getNow(customOptions.OpenWeather_Date)}`;
  85.  
  86. const openWeatherURL = (customOptions.OpenWeather_Style === 'radar')
  87. ? radarURL
  88. : `${openWeatherBaseURL}/${customOptions.OpenWeather_Style}/{z}/{x}/{y}?appid=9de243494c0b295cca9337e1e96b00e2&&date=${getTimestamp(customOptions.OpenWeather_Date)}&fill_bound=true`;
  89.  
  90. let tileUrls = {
  91. Petal_Maps: `https://maprastertile-dra.dbankcdn.com/display-service/v1/online-render/getTile/24.07.06.10/{z}/{x}/{y}/?language=${customOptions.Language}&p=46&scale=1&mapType=ROADMAP&presetStyleId=standard&key=CgB6e3x91JxUZ4Ow3JZYVG6r9c9U7rH4ameNQdauHVaVBYGWwy8ueadAtqjs6Yl2z3OwymAEx3JR83vpgPzv4nuC`,
  92. OpenStreetMap: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
  93. Map_Tiler:`https://api.maptiler.com/maps/${customOptions.Map_Tiler_Style}-v2/256/{z}/{x}/{y}.png?key=0epLOAjD7fw17tghcyee`,
  94. Thunderforest:`https://a.tile.thunderforest.com/${customOptions.Thunderforest_Style}/{z}/{x}/{y}@2x.png?apikey=6a53e8b25d114a5e9216df5bf9b5e9c8`,
  95. Carto:`https://cartodb-basemaps-3.global.ssl.fastly.net/${customOptions.Carto_Style}/{z}/{x}/{y}.png`,
  96. Google_StreetView:`https://maps.googleapis.com/maps/vt?pb=%211m5%211m4%211i{z}%212i{x}%213i{y}%214i256%212m8%211e2%212ssvv%214m2%211scc%212s*211m3*211e2*212b1*213e2*212b1*214b1%214m2%211ssvl%212s*212b1%213m17%212sen%213sUS%215e18%2112m4%211e68%212m2%211sset%212sRoadmap%2112m3%211e37%212m1%211ssmartmaps%2112m4%211e26%212m2%211sstyles%212ss.e%3Ag.f%7Cp.c%3A%23${colorOptions[customOptions.Google_StreetView_Layer_Lines_Style][0]}%7Cp.w%3A1%2Cs.e%3Ag.s%7Cp.c%3A%23${colorOptions[customOptions.Google_StreetView_Layer_Lines_Style][1]}%7Cp.w%3A3%215m1%215f1.35`,
  97. Google_Labels:`https://maps.googleapis.com/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m1!2sm!3m17!2s${customOptions.Language}!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!12m4!1e26!2m2!1sstyles!2ss.e:g|p.v:off,s.t:1|s.e:g.s|p.v:off,s.e:l|p.v:on!5m1!5f2`,
  98. OpenWeather: openWeatherURL
  99. }
  100.  
  101. let map,google,gsvLayer,initLayer=tag
  102. setTimeout(function(){
  103. getMap()
  104. },2000);
  105. initCustomizer()
  106.  
  107. function createOpacityControl(controlDiv, layer) {
  108. controlDiv.style.margin='20px'
  109. controlDiv.style.backgroundColor = '#fff';
  110. controlDiv.style.height = '30px';
  111. controlDiv.style.boxShadow = 'rgba(0, 0, 0, 0.3) 0px 1px 4px -1px';
  112. controlDiv.style.borderRadius = '5px';
  113.  
  114. var opacitySlider = document.createElement('input');
  115.  
  116. opacitySlider.setAttribute('type', 'range');
  117. opacitySlider.setAttribute('id', 'timeRange');
  118. opacitySlider.setAttribute('min', '0');
  119. opacitySlider.setAttribute('max', '100');
  120. opacitySlider.setAttribute('value', '100');
  121. opacitySlider.setAttribute('step', '1');
  122. opacitySlider.style.width = '80px';
  123. opacitySlider.style.height='20px'
  124. opacitySlider.style.marginTop='5px'
  125. opacitySlider.addEventListener('input', function() {
  126. var opacity = opacitySlider.value / 100
  127. layer.setOpacity(opacity);
  128.  
  129. });
  130.  
  131. controlDiv.appendChild(opacitySlider);
  132. }
  133.  
  134. function addOpacityControl(m, layer) {
  135. var opacityControlDiv = document.createElement('div');
  136. new createOpacityControl(opacityControlDiv, layer);
  137. opacityControl =true
  138. opacityControlDiv.index = 1;
  139. m.controls[google.maps.ControlPosition.TOP_RIGHT].push(opacityControlDiv);
  140. }
  141.  
  142. function removeOpacityControl(){
  143. if(opacityControl){
  144. map.controls[google.maps.ControlPosition.TOP_RIGHT].removeAt(map.controls[google.maps.ControlPosition.TOP_RIGHT].getLength() - 1)
  145. opacityControl=false
  146. }
  147. }
  148.  
  149. function getNow(date) {
  150. if(date!='now'){
  151. return date
  152. }
  153. const now = new Date();
  154. now.setHours(now.getHours() - 1);
  155. return now.toISOString().slice(0, 14)+'00';
  156. }
  157.  
  158. function getTimestamp(date){
  159. var parsedDate
  160. if (date=== 'now') {
  161. parsedDate= new Date()
  162. return Math.floor(parsedDate.getTime() / 1000)
  163. }
  164. parsedDate = new Date(date);
  165.  
  166. if (isNaN(parsedDate.getTime())) {
  167. throw new Error('Invalid date format');
  168. }
  169. return Math.floor(parsedDate.getTime() / 1000);
  170.  
  171. }
  172.  
  173. function extractTileCoordinates(url) {
  174. const regex = /!1i(\d+)!2i(\d+)!3i(\d+)!4i(\d+)/;
  175. const matches = url.match(regex);
  176.  
  177. if (matches && matches.length === 5) {
  178. const z = matches[1];
  179. const x = matches[2];
  180. const y = matches[3];
  181. return { z, x, y };
  182. } else {
  183. return null;
  184. }
  185. }
  186. function getBingTiles(tileX, tileY, zoom,type) {
  187. var quadKey = tileXYToQuadKey(tileX, tileY, zoom);
  188. var baseUrl = 'https://ecn.t0.tiles.virtualearth.net/tiles/';
  189.  
  190. return baseUrl + type + quadKey + '.jpeg?g=14519';
  191. }
  192. function tileXYToQuadKey(tileX, tileY, zoom) {
  193. var quadKey = '';
  194. for (var i = zoom; i > 0; i--) {
  195. var digit = 0;
  196. var mask = 1 << (i - 1);
  197. if ((tileX & mask) !== 0) {
  198. digit += 1;
  199. }
  200. if ((tileY & mask) !== 0) {
  201. digit += 2;
  202. }
  203. quadKey += digit.toString();
  204. }
  205. return quadKey;
  206. }
  207.  
  208.  
  209. function setMapLayer(layerName) {
  210. var tileLayerUrl = tileUrls[layerName];
  211. var tileLayer
  212. if (layerName==='Bing_Maps') {
  213. tileLayer = new google.maps.ImageMapType({
  214. getTileUrl: function(coord, zoom) {
  215. return getBingTiles(coord.x,coord.y,zoom,customOptions.Bing_Maps_Style)
  216. .replace('{z}', zoom)
  217. .replace('{x}', coord.x)
  218. .replace('{y}', coord.y);
  219. },
  220. tileSize: new google.maps.Size(256, 256),
  221. name: layerName
  222. });
  223. }
  224. else{
  225. tileLayer = new google.maps.ImageMapType({
  226. getTileUrl: function(coord, zoom) {
  227. return tileLayerUrl
  228. .replace('{z}', zoom)
  229. .replace('{x}', coord.x)
  230. .replace('{y}', coord.y);
  231. },
  232. tileSize: new google.maps.Size(256, 256),
  233. name: layerName
  234. });
  235. }
  236.  
  237. if(!layerName.includes('Google')){
  238. isGoogleDisplay=false
  239. }
  240. if(currentLayers.includes(layerName)){
  241. removeMapLayer(layerName)
  242. const index = currentLayers.indexOf(layerName);
  243. if (index !== -1) {
  244. currentLayers.splice(index, 1);
  245. }
  246. if(!layerName.includes(('Google')||('Weather'))){
  247. map.overlayMapTypes.clear();
  248. currentLayers=[]
  249. isGoogleDisplay=true
  250. setMapLayer('Google_Labels')
  251. }
  252. }
  253. else {
  254. map.overlayMapTypes.push(tileLayer)
  255. currentLayers.push(layerName)};
  256.  
  257. if(layerName==='Google_StreetView'){
  258. if (!opacityControl){
  259. addOpacityControl(map,tileLayer)}
  260. else {
  261. removeOpacityControl()
  262. }
  263. }
  264. }
  265.  
  266.  
  267. function removeMapLayer(layerName) {
  268. for (let i = 0; i < map.overlayMapTypes.getLength(); i++) {
  269. const currentLayer = map.overlayMapTypes.getAt(i);
  270. if (currentLayer && currentLayer.name === layerName) {
  271. map.overlayMapTypes.removeAt(i);
  272. break;
  273. }
  274. }
  275. }
  276.  
  277. function getMap(){
  278. let element = document.getElementsByClassName("guess-map_canvas__cvpqv")[0]
  279. //if (!element) element=document.getElementsByClassName("coordinate-result-map_map__Yh2Il")[0]
  280. const keys = Object.keys(element)
  281. const key = keys.find(key => key.startsWith("__reactFiber$"))
  282. const props = element[key]
  283. map=props.return.return.memoizedProps.map
  284. google=unsafeWindow.google
  285. }
  286.  
  287. function setMapType(customType){
  288. if (currentMapType!=customType){
  289. currentMapType=customType
  290. }
  291. else{
  292. currentMapType='roadmap'
  293. }
  294. map.setMapTypeId(currentMapType);
  295. }
  296.  
  297.  
  298. function initCustomizer(){
  299. let onKeyDown = (e) => {
  300. if (e.key >= '1' && e.key <= '6') {
  301. e.stopImmediatePropagation();
  302. if(!map) getMap()
  303. const tileIndex=parseInt(e.key)
  304. initLayer(`layer:${tileServices[tileIndex]}`)
  305. map.overlayMapTypes.clear();
  306. currentLayers=[]
  307. removeOpacityControl()
  308. setMapLayer(tileServices[tileIndex])
  309. }
  310. else if (e.key === '0') {
  311. e.stopImmediatePropagation();
  312. if(!map) getMap()
  313. initLayer('layer:Google_Labels')
  314. map.overlayMapTypes.clear();
  315. currentLayers=[]
  316. isGoogleDisplay=true
  317. removeOpacityControl()
  318. map.set('styles', [
  319. {
  320. featureType: 'all',
  321. elementType: 'labels',
  322. stylers: [{ visibility: 'on' }]
  323. }
  324. ])
  325. isSV=false
  326. }
  327. else if (e.key === customOptions.Google_StreetView_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_StreetView_Layer_Shortcut) {
  328. e.stopImmediatePropagation();
  329. if(!map) getMap()
  330. initLayer('layer:Google_StreetView')
  331. if(!isSV){
  332. map.set('styles', [
  333. {
  334. featureType: 'all',
  335. elementType: 'labels',
  336. stylers: [{ visibility: 'off' }]
  337. }
  338. ])
  339. isSV=true}
  340. else{
  341. map.set('styles', [
  342. {
  343. featureType: 'all',
  344. elementType: 'labels',
  345. stylers: [{ visibility: 'on' }]
  346. }
  347. ])
  348. isSV=false
  349. }
  350. setMapLayer('Google_StreetView')
  351. if (isGoogleDisplay)setMapLayer('Google_Labels')
  352. }
  353. else if (e.key === customOptions.Google_Labels_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_Labels_Layer_Shortcut) {
  354. e.stopImmediatePropagation();
  355. if(!map) getMap()
  356. initLayer('layer:Google_Labels')
  357. if(isSV){
  358. setMapLayer('Google_Labels')}
  359. }
  360. else if (e.key === customOptions.Google_Terrain_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_Terrain_Layer_Shortcut) {
  361. e.stopImmediatePropagation();
  362. if(!map) getMap()
  363. initLayer('layer:terrain')
  364. setMapType('terrain')
  365. }
  366. else if (e.key === customOptions.Google_Satellite_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_Satellite_Layer_Shortcut) {
  367. e.stopImmediatePropagation();
  368. if(!map) getMap()
  369. initLayer('layer:satellite')
  370. setMapType('satellite')
  371. }
  372. else if (e.key === customOptions.OpenWeather_Shortcut.toLowerCase()|| e.key === customOptions.OpenWeather_Shortcut) {
  373. e.stopImmediatePropagation();
  374. if(!map) getMap()
  375. initLayer('layer:weather')
  376. setMapLayer('OpenWeather')
  377. }
  378. }
  379.  
  380. document.addEventListener("keydown", onKeyDown);
  381. }
  382.  
  383. })();

QingJ © 2025

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