Geoguessr Map-Making Auto-Tag

tag by date and address

当前为 2023-09-24 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Geoguessr Map-Making Auto-Tag
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.2
  5. // @description tag by date and address
  6. // @author KaKa
  7. // @match https://map-making.app/maps/*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @grant GM_setClipboard
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. async function runScript(tags) {
  18.  
  19. var api_key = GM_getValue("api_key");
  20. if (!api_key) {
  21. api_key = prompt("Please enter your Google API key");
  22. GM_setValue("api_key", api_key);
  23. }
  24. var text = await navigator.clipboard.readText();
  25. var data = JSON.parse(text);
  26. var newData = [];
  27.  
  28. function get_Meta(id) {
  29. var url = "https://maps.googleapis.com/maps/api/streetview/metadata?pano=" + id + "&key=" + api_key;
  30. return fetch(url)
  31. .then(function(response) {
  32. return response.json();
  33. })
  34. .then(function(data) {
  35. console.log(data);
  36. if (data.status == "OK") {
  37. var date = data.date;
  38. var cr = data.copyright;
  39. var year = 'nodate';
  40. var match = date.match(/\d{4}/);
  41. if (match) {
  42. year = match[0];
  43. }
  44.  
  45. var panoType = 'unofficial';
  46. if (cr.includes('Google')) {
  47. panoType = 'official';
  48. }
  49.  
  50. return [year, panoType];
  51. } else {
  52. return ["nodata","nodata"];
  53. }
  54. })
  55. .catch(function(error) {
  56. console.log(error);
  57. });
  58. }
  59.  
  60. function search_Meta(lat, lng) {
  61. var url = "https://maps.googleapis.com/maps/api/streetview/metadata?location=" + lat + "," + lng + "&key=" + api_key;
  62. return fetch(url)
  63. .then(function(response) {
  64. return response.json();
  65. })
  66. .then(function(data) {
  67. console.log(data);
  68. if (data.status == "OK") {
  69. var date = data.date;
  70. var cr = data.copyright;
  71. var year = 'nodate';
  72. var match = date.match(/\d{4}/);
  73. if (match) {
  74. year = match[0];
  75. }
  76.  
  77. var panoType = 'unofficial';
  78. if (cr.includes('Google')) {
  79. panoType = 'official';
  80. }
  81.  
  82. return [year, panoType, cr];
  83. } else {
  84. return ["nodata","nodata"];
  85. }
  86. })
  87. .catch(function(error) {
  88. console.log(error);
  89. });
  90. }
  91.  
  92. let last_token = null;
  93. let last_token_expiry = 0;
  94.  
  95. async function get_Token(api_key) {
  96. let current_time = Date.now() / 1000;
  97. if (last_token && last_token_expiry > current_time) {
  98. return last_token;
  99. }
  100. let url = `https://tile.googleapis.com/v1/createSession?key=${api_key}`;
  101. let headers = {'Content-Type': 'application/json'};
  102. let data = { "mapType": "streetview",
  103. "language": "en-US",
  104. "region": "US"};
  105. let response = await fetch(url, {method: 'POST', headers: headers, body: JSON.stringify(data)});
  106. if (response.status == 200) {
  107. let token = (await response.json()).session;
  108. last_token_expiry = current_time + 5 * 60;
  109. last_token = token;
  110. return token;
  111. } else {
  112. console.log(`Error: ${response.status}, ${await response.text()}`);
  113. }
  114. }
  115.  
  116. async function get_add(id) {
  117. let tk = await get_Token(api_key);
  118. let url = `https://tile.googleapis.com/v1/streetview/metadata?session=${tk}&key=${api_key}&panoId=${id}`;
  119. let response = await fetch(url);
  120. let country = 'nodata';
  121. let subdivision = 'nodata';
  122. let locality = 'nodata';
  123. try {
  124. let response = await fetch(url);
  125. if (response.status == 200) {
  126. let data = await response.json();
  127. for (let add of data.addressComponents) {
  128. if (add.types.includes('country')) {
  129. country = add.longName;
  130. }
  131. if (add.types.includes('administrative_area_level_1')) {
  132. subdivision = add.longName;
  133. }
  134. if (add.types.includes('locality')) {
  135. locality = add.longName;
  136. }
  137. }
  138. }
  139. } catch (error) {
  140. console.log(error);
  141. }
  142. return [country, subdivision, locality];
  143. }
  144.  
  145. async function search_add(lat,lng) {
  146. let tk = await get_Token(api_key);
  147. let url = `https://tile.googleapis.com/v1/streetview/metadata?session=${tk}&key=${api_key}&lat=${lat}&lng=${lng}&radius=50`;
  148. let response = await fetch(url);
  149. let country = 'nodata';
  150. let subdivision = 'nodata';
  151. let locality = 'nodata';
  152. try {
  153. let response = await fetch(url);
  154. if (response.status == 200) {
  155. let data = await response.json();
  156. for (let add of data.addressComponents) {
  157. if (add.types.includes('country')) {
  158. country = add.longName;
  159. }
  160. if (add.types.includes('administrative_area_level_1')) {
  161. subdivision = add.longName;
  162. }
  163. if (add.types.includes('locality')) {
  164. locality = add.longName;
  165. }
  166. }
  167. }
  168. } catch (error) {
  169. console.log(error);
  170. }
  171. return [country, subdivision, locality];
  172. }
  173.  
  174.  
  175. var CHUNK_SIZE = 1000;
  176. var promises = [];
  177.  
  178. async function processCoord(coord, tags) {
  179. if (!coord.extra) {
  180. coord.extra = {};
  181. }
  182. if (!coord.extra.tags) {
  183. coord.extra.tags = [];
  184. }
  185. var meta;
  186. var address;
  187. if (coord.panoId) {
  188. meta = await get_Meta(coord.panoId);
  189. address= await get_add(coord.panoId);
  190. } else {
  191. meta = await search_Meta(coord.lat, coord.lng);
  192. address= await search_add(coord.lat, coord.lng);
  193. }
  194. if (meta && meta.length >= 2) {
  195. var year_tag = meta[0];
  196. var type_tag = meta[1];
  197. var country_tag=address[0]
  198. var subdivision_tag=address[1]
  199. var locality_tag=address[2]
  200. if (tags.includes('year')) coord.extra.tags.push(year_tag);
  201. if (tags.includes('type')) coord.extra.tags.push(type_tag);
  202. if (tags.includes('country')) coord.extra.tags.push(country_tag);
  203. if (tags.includes('subdivision')) coord.extra.tags.push(subdivision_tag);
  204. if (tags.includes('locality')) coord.extra.tags.push(locality_tag);
  205. newData.push(coord);
  206. }
  207. }
  208.  
  209. async function processChunk(chunk) {
  210. var promises = chunk.map(async coord => await processCoord(coord, tags));
  211. await Promise.all(promises);
  212. }
  213.  
  214. async function processData(tags) {
  215. for (let i = 0; i < data.customCoordinates.length; i += CHUNK_SIZE) {
  216. let chunk = data.customCoordinates.slice(i, i + CHUNK_SIZE);
  217. await processChunk(chunk);
  218. }
  219.  
  220. GM_setClipboard(JSON.stringify(newData));
  221. alert("New JSON data has been copied to the clipboard!");
  222. }
  223. processData(tags);
  224. }
  225.  
  226. function createButton(text, tags) {
  227. var button = document.createElement('button');
  228. button.textContent = text;
  229. button.addEventListener('click', async function() { await runScript(tags); });
  230. document.body.appendChild(button);
  231. }
  232.  
  233. createButton('Tag by Year', ['year']);
  234. createButton('Tag by Type',[ 'type']);
  235. createButton('Tag by Country', ['country']);
  236. createButton('Tag by Subdivision', ['subdivision']);
  237. createButton('Tag by Locality', ['locality']);
  238. })();