NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name 六只脚KML下载 // @author jjm2473 // @copyright 2016, jjm2473@qq.com // @license MIT // @supportURL mailto:jjm2473@qq.com // @icon http://www.foooooot.com/favicon.ico // @namespace https://openuserjs.org/users/jjm2473/ // @version 0.4.0 // @description 六只脚轨迹免银两下载,实际是调用json接口获取数据 // @include /^https?://(www\.)?foooooot\.com/trip/\d+/#?$/ // @include /^https?://(www\.)?foooooot\.com/map/\??.*$/ // @include /^https?://6\.lvye\.cn/trip/\d+/#?$/ // @include /^https?://6\.lvye\.cn/map/\??.*$/ // @grant GM_xmlhttpRequest // @run-at document-end // ==/UserScript== /* * 欢迎交流改进 * @author:jjm2473@qq.com **/ function XMLNode(tag){ this.tagName=tag; this.childNodes=[]; this.innerText=null; } XMLNode.prototype = { toString:function(indent){ indent=indent||0; var cindent=""; var i; for(i=0;i<indent;++i)cindent+='\t'; //var nindent=cindent+'\t'; var result="\n"+cindent+"<"+this.tagName+">"; if(this.innerText)result+=this.innerText; ++indent; for(i=0;i<this.childNodes.length;++i){ result+=this.childNodes[i].toString(indent); } if(i)result+=("\n"+cindent); result+=("</"+this.tagName+">"); return result; }, appendChild:function(node){ this.childNodes.push(node); return this; }, setText:function(text){ this.innerText=text; return this; } }; ( function(){ var TIMEZONE = 8*60*60*1000; var KMLHeader='<?xml version="1.0" encoding="UTF-8"?>\n'+ '<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">'; var KMLTail='\n</kml>'; var makeTrack = function (name,data){ var pm=new XMLNode("Placemark"); pm.appendChild(new XMLNode("name").setText(name)) .appendChild(new XMLNode("styleUrl").setText("#msn_track")); var tr = new XMLNode('gx:Track'); for(var i=0;i<data.length;++i){ tr.appendChild(new XMLNode('when').setText(data[i][3])); tr.appendChild(new XMLNode('gx:coord').setText(data[i][0]+' '+data[i][1]+' '+data[i][2])); } pm.appendChild(tr); return pm; }; var makePath = function (name,data) { var coords=[]; for(var i=0;i<data.length;++i){ coords.push(data[i][0]+","+data[i][1]+","+data[i][2]); } var pm=new XMLNode("Placemark"); pm.appendChild(new XMLNode("name").setText(name)) .appendChild(new XMLNode("LineString") .appendChild(new XMLNode("coordinates") .setText(coords.join(" ")))); return pm; }; var getTracksData=function(id, cb){ var url = "/trip/" + id + "/trackjson/"; $.getJSON(url, function(data){ var wpts=[]; var tz=new Date().getTimezoneOffset()*60*1000; $.each(data, function(i, val){ //wpts.push([val[2],val[1],val[3],new Date(parseInt(val[0])*1000+TIMEZONE).toJSON()]); wpts.push([val[2],val[1],val[3],new Date(parseInt(val[0])*1000-tz).toJSON()]); }); cb(wpts); }); }; var getTracks=function(id, cb){ getTracksData(id, function(wpts){ var fl=new XMLNode("Folder"); fl.appendChild(new XMLNode("name").setText("Tracks")); fl.appendChild(makeTrack("Track",wpts)) .appendChild(makePath("Path",wpts)); cb(fl); }); }; var FOOTPRINT_OPT={ TIME : 0, LAT : 1, LNG : 2, ELEAVTION : 3, TITLE : 4, THUMBNAIL : 5, GALLERY : 6, DESCRIPTION : 7, TYPE : 8, REPLY_TIMES : 9, EDIT_URL : 10, COMMENT_URL : 11 }; var getFootPrint=function(id, cb){ var url = '/trip/'+id+'/footprintsjson/'; $.getJSON(url, function(data){ var fl=new XMLNode("Folder"); fl.appendChild(new XMLNode("name").setText("Points")); $.each(data, function(i, val){ var pm=new XMLNode("Placemark") .appendChild(new XMLNode("name").setText(val[FOOTPRINT_OPT.TITLE])); if(val[FOOTPRINT_OPT.GALLERY]){ var desc=new XMLNode("description") .setText('<![CDATA[<img src="'+val[FOOTPRINT_OPT.GALLERY]+'">]]>'); pm.appendChild(desc); } pm.appendChild(new XMLNode("Point") .appendChild(new XMLNode("coordinates") .setText(val[FOOTPRINT_OPT.LNG]+","+val[FOOTPRINT_OPT.LAT]+","+val[FOOTPRINT_OPT.ELEAVTION]))); fl.appendChild(pm); }); cb(fl); }); }; var getMarks=function(id, cb){ var url = '/trip/'+id+'/marksjson/'; $.getJSON(url, function(data){ var fl=new XMLNode("Folder"); fl.appendChild(new XMLNode("name").setText("Marks")); $.each(data, function(i, val){ var pm=new XMLNode("Placemark") .appendChild(new XMLNode("name").setText(val.title)); if(val.content){ var desc=new XMLNode("description") .setText('<![CDATA[<pre>'+val.content+'</pre>]]>'); pm.appendChild(desc); } pm.appendChild(new XMLNode("Point") .appendChild(new XMLNode("coordinates") .setText(val.lon+","+val.lat))); fl.appendChild(pm); }); cb(fl); }); }; var getInfo = function(id, cb){ if(id){ var url = '/trip/'+id+'/info/'; $.getJSON(url, function(data){ var sec = data.duration; var hour = parseInt(sec/3600); var minute = parseInt(sec%3600/60); var str = '于 '+data.occurtime+' 出发,历时 '+hour+' 小时, '+minute+' 分钟\n'+ data.start_place_name+' - '+data.end_place_name+' | '+data.activity+',全程 '+(parseInt(data.distance*1000)/1000)+' 公里\n'+ '难度级别:'+data.difficulty+'\n'+ '累计上升:'+data.accum_uphill+'米, 累计下降:'+data.accum_downhill+'米\n'+ '海拔最低:'+data.elevation_min+'米, 最高:'+data.elevation_max+'米\n'+ '最高速度:'+data.speed_max+'公里每小时\n\n'+data.story; cb(data.name,str); }); }else{ cb(document.getElementsByClassName("trip_box_title")[0].children[0].innerText, document.getElementsByClassName('trip_box')[1].innerText); } }; var wrapKMLm = function(url,name,info,children){ var doc=new XMLNode("Document").appendChild(new XMLNode("name").setText(name+".kml")) .appendChild(new XMLNode("description").setText('<![CDATA[<a href="'+url+'">'+url+'</a><br/><pre>'+info+'</pre>]]>')) .setText('\n\t<atom:author><atom:name>export by jjm2473\'s script</atom:name></atom:author><atom:link href="https://openuserjs.org/scripts/jjm2473/%E5%85%AD%E5%8F%AA%E8%84%9AKML%E4%B8%8B%E8%BD%BD"></atom:link>\n'+ '\t<StyleMap id="msn_track"><Pair><key>normal</key><styleUrl>#sn_track</styleUrl></Pair><Pair><key>highlight</key><styleUrl>#sh_track</styleUrl></Pair></StyleMap><Style id="sn_track"><IconStyle><scale>1.2</scale><Icon><href>http://maps.google.com/mapfiles/kml/shapes/track.png</href></Icon><hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/></IconStyle><ListStyle></ListStyle><LineStyle><color>ffffaa55</color><width>3</width></LineStyle></Style><Style id="sh_track"><IconStyle><scale>1.4</scale><Icon><href>http://maps.google.com/mapfiles/kml/shapes/track.png</href></Icon><hotSpot x="32" y="32" xunits="pixels" yunits="pixels"/></IconStyle><ListStyle></ListStyle><LineStyle><color>ffffaa55</color><width>3</width></LineStyle></Style>'); for(var i=0;i<children.length;++i){ doc.appendChild(children[i]); } return KMLHeader+doc.toString()+KMLTail; }; var wrapKML = function(id, track,footpoints,marks,name,info){ return wrapKMLm('http://www.foooooot.com/trip/'+id+'/', name, info, [track,footpoints,marks]); }; var exportString2File = function ( output , filename) { var blob = new Blob( [ output ], { type: 'text/plain' } ); var objectURL = URL.createObjectURL( blob ); var a=document.createElement('a'); a.href=objectURL; a.download=filename||'Untitled'; a.click(); }; var downloadTrip = function(tripid){ getTracks(tripid, function(track){ getFootPrint(tripid, function(footprints){ getMarks(tripid, function(marks){ getInfo(tripid, function(TripName, info){ exportString2File(wrapKML(tripid,track,footprints,marks,TripName,info),tripid+"_"+TripName+".kml"); }); }); }); }); return void(0); }; var onClickListener = function(){ var tripid = this.parentNode.id; downloadTrip(tripid); }; var createDownloadLink = function(){ var aa=document.createElement("a"); aa.addEventListener("click",onClickListener); aa.href="javascript:void(0);"; //aa.classList.add("inlineIcon"); //aa.classList.add("btnDownload"); aa.innerHTML=' 下载KML '; return aa; }; if(location.pathname.startsWith('/trip/')){ //trip view console.log('trip view'); var tripid=document.getElementById("trip-id"); if(tripid === null)return; var div=document.createElement("div"); div.id=tripid.value; div.appendChild(createDownloadLink()); tripid.parentElement.insertBefore(div,tripid); }else if(location.pathname.startsWith('/map/')){ //map view console.log('map view'); /*var listAddLink = function(){ var list = document.getElementsByClassName('resultList')[0].getElementsByClassName('tripItem'); $.each(list, function(i, val){ val.appendChild(createDownloadLink()); }); };*/ var funcInject = function(){/* if(typeof unsafeWindow.Utils === 'object'){ unsafeWindow.Utils.successCallbackProxy = function(fn) { return function (result) { var action = result.action; if (!action) { alert("Server Error:ActionNotDefined"); throw new Error('Server Error:ActionNotDefined'); return ; } var data = action.data; var actionName = action.name; if (actionName == 'redirect') { window.location.href=data.url; return ; } fn && $.isFunction(fn) && fn(actionName,data); listAddLink(); }; }; listAddLink(); }else{ console.error("cannot find var Utils!"); setTimeout(funcInject,200); } */ var tpl = $('.resultList').attr('tpl'); var idx = tpl.search('</ul>'); tpl = tpl.substring(0,idx)+'<a href="javascript:void(downloadTrip([[id]]));"> 下载KML </a>'+tpl.substring(idx); /*idx = tpl.search('class="btnShowTrip"'); tpl = tpl.substring(0,idx)+'onclick="toggleShowTrip([[id]]);"'+tpl.substring(idx);*/ $('.resultList').attr('tpl', tpl); }; window.downloadTrip = unsafeWindow.downloadTrip = downloadTrip; var getSelectTrips = function(){ var href = window.location.href || unsafeWindow.location.href; var selectTrip=[]; var ts = href.indexOf('|t='); if(ts==-1) ts = href.indexOf('#t='); if(ts==-1) return selectTrip; ts+=3; var te = href.indexOf('|', ts); if(ts==te) return selectTrip; if(te==-1) te=href.length; var trips = href.substring(ts, te); trips = trips.split(','); for(var i=0;i<trips.length;++i){ var tripId = trips[i].substring(0, trips[i].indexOf('*')); if(!!tripId) selectTrip.push(tripId); } return selectTrip; }; /*var selectTrip = []; var toggleShowTrip = function(id){ if(selectTrip.includes(id)){ selectTrip.pop(id); }else{ selectTrip.push(id); } }; window.toggleShowTrip = unsafeWindow.toggleShowTrip = toggleShowTrip;*/ var downloadSelectedTrip = function(){ var selectTrip = getSelectTrips(); var size = selectTrip.length; if(size===0) { alert("未选择任何轨迹!"); return void(0); } var href = window.location.href || unsafeWindow.location.href; var paths = []; var i = 0; var looper = function(){ if(i == size){ var fl = new XMLNode("Folder"); fl.appendChild(new XMLNode("name").setText("Tracks")); for(i=0;i<size;++i){ fl.appendChild(paths[i]); } exportString2File(wrapKMLm(href, selectTrip, '', [fl]), selectTrip+".kml"); }else{ var id=selectTrip[i]; ++i; getTracksData(id, function(wpts){ paths.push(makePath(id, wpts)); setTimeout(looper, 0); }); } }; looper(); }; window.downloadSelectedTrip = unsafeWindow.downloadSelectedTrip = downloadSelectedTrip; $('.sortTab').append($('<button style="color:red;margin-left:20px;" onclick="downloadSelectedTrip();">下载选择的轨迹</button>')); funcInject(); } console.error("jjm2473,I am here!");//just for debug })();