Download location and orientation in Google Street View to a local file.
// ==UserScript==
// @name Street View Snapper
// @name:ja Street View スナップ
// @namespace http://tampermonkey.net/
// @version 0.1.1.7
// @description Download location and orientation in Google Street View to a local file.
// @description:ja Google Street View 内の位置と方向情報を geoJSON 及び KML 形式でダウンロードします。
// @author Paul Richter
// @match *://*/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=google.com
// @grant none
// @license GPL-3.0-or-later
// ==/UserScript==
function is_google_gsv() {
return location.href.includes("google.com/maps") && location.href.includes('@') && location.href.includes('data=')
}
function is_embedded_gm() {
return document.querySelector(".gm-iv-address-link") && document.querySelector(".gm-iv-short-address-description")
}
function wrap_xml(name, value) {
if(name == 'url') {
value = value.replace('&', '&') ;
}
return `<Data name="${name}"><value>${value}</value></Data>`
}
function as_kml(data) {
let kml_str = "<kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document>\n<Placemark>\n" ;
const coords = data.geometry.coordinates ;
const coord_str = `<coordinates>${coords[0]}, ${coords[1]}</coordinates>`
kml_str += "<Point>" + coord_str + "</Point>"
kml_str += "<ExtendedData>\n" ;
Object.entries(data.properties).forEach(([k, v])=> {
kml_str += wrap_xml(k, v) ;
}) ;
kml_str += "</ExtendedData>\n"
kml_str += "</Placemark>\n</Document>\n</kml>" ;
return kml_str ;
}
function gsv_long_address() {
const attribDiv = document.querySelector('[data-attribution-url="//www.google.com/streetview"]') ;
if(attribDiv) {
return attribDiv.parentElement.parentElement.parentElement.parentElement.children[1].firstChild.innerText ;
}
return null ;
}
function crack_locstr(locstr) {
const loc_fields = locstr.split(',') ;
let data = {
lng:null,
lat:null,
height:null,
zoom:null,
heading:null,
tilt:null
} ;
loc_fields.forEach((field) => {
if(field[0] == '@') {
data.lat = parseFloat(field.slice(1)) ;
return ;
}
const lastChar = field.slice(-1) ;
if('ahty'.includes(lastChar)) {
const val = parseFloat(field.slice(0, -1)) ;
switch(lastChar) {
case 'a':
data.height = val;
break;
case 'h':
data.heading = val;
break;
case 't':
data.tilt = val;
break;
case 'y':
data.zoom = val;
break;
default:
}
} else {
data.lng = parseFloat(field) ;
}
}) ;
return data ;
}
function snap_gsv(label, format) {
let url = location.href;
let place = "";
console.log("Format", format) ;
if (is_google_gsv()) {
console.log("This is google maps in street view mode.") ;
const title_fields = document.title.split(' - ');
place = title_fields[0] ;
const place_sub = gsv_long_address() ;
if (place_sub) {
place += " - " + place_sub
}
} else if (is_embedded_gm()) {
console.log("This is a site with an embedded google map in street view mode.") ;
const addressLink = document.querySelector(".gm-iv-address-link") ;
const anchor = addressLink.getElementsByTagName('a')[0] ;
url = anchor.getAttribute("href") ;
place = document.querySelector(".gm-iv-short-address-description").innerText ;
const place_long = document.querySelector(".gm-iv-long-address-description").innerText ;
if(place_long.length > 0) {
place += " - " + place_long ;
}
//also check for "gm-iv-profile-url") ;
} else {
alert("You are not viewing a Google Street View page") ;
return ;
}
const url_fields = url.split('/');
const locstr = url_fields.at(-2) ;// '/@'
const svdata = url_fields.at(-1) ;// '/data='
const loc_fields = crack_locstr(locstr) ;
const data={
type:"Feature",
geometry: {
type:"Point",
coordinates:[loc_fields.lng, loc_fields.lat],
},
properties: {
heading:loc_fields.heading,
tilt:loc_fields.tilt,
zoom:loc_fields.zoom,
label:label,
place: place,
url:url
}
};
let dataStr = JSON.stringify(data,null,2) ;
let extension = ".geojson" ;
if(format == "kml") {
dataStr = as_kml(data) ;
extension = ".kml"
}
const blob=new Blob([dataStr],{type:"application/json"});
const a=document.createElement("a");
a.href=URL.createObjectURL(blob);
a.download=`gsvs_${place}_${label}_${Date.now()}${extension}`;
a.click();
setTimeout(()=>URL.revokeObjectURL(a.href),1000);
}
window.snap_gsv = snap_gsv ;