NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name GeocachingDownloadAsKML // @author jjm2473 // @copyright 2016, jjm2473@qq.com // @supportURL mailto:jjm2473@qq.com // @icon https://www.geocaching.com/favicon.ico // @namespace https://openuserjs.org/users/jjm2473/ // @version 0.1 // @description Download kml from Geocaching.com, with description and hint // @match https://www.geocaching.com/geocache/* // @run-at document-end // ==/UserScript== /* jshint -W097 */ 'use strict'; // Your code here... if (typeof unsafeWindow === "undefined"){ window.unsafeWindow = window; } 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 getStructedGeoCachingData(window){ var TypeName={ "2":"Traditional", "9":"A.P.E", "5":"Letterbox", "3":"Multi-Cache", "6":"Event", "453":"Mega-Event", "7005":"Giga-Event", "13":"Cache In Trash Out", "1304":"GPS Adventures", "4":"Virtual", "11":"Webcam", "137":"EarthCache", "8":"Mystery", "1858":"Wherigo" }; var id = document.getElementById('ctl00_ContentBody_CoordInfoLinkControl1_uxCoordInfoCode').innerText; var diffTerr = document.getElementById('ctl00_ContentBody_diffTerr').getElementsByTagName('img'); var difficulty = diffTerr[0].alt.split(' ')[0]; var terrain = diffTerr[1].alt.split(' ')[0]; var boxSize = document.getElementById('ctl00_ContentBody_size').getElementsByTagName('img')[0].alt.split(' ')[1]; var descHeader = document.getElementsByClassName('CacheDescriptionHeader')[0]; var descHtml = ''; var cd = descHeader; while(cd !== null){ descHtml += cd.outerHTML; cd = cd.nextElementSibling; } var lat = window.mapLatLng.lat; var lng = window.mapLatLng.lng; var name = window.mapLatLng.name; var type = TypeName[window.mapLatLng.type]; return {id:id,name:name,type:type,lat:lat,lng:lng, difficulty:difficulty,terrain:terrain,size:boxSize,desc:descHtml}; } function getGeoCachingNode(cache){ var pm=new XMLNode("Placemark") .appendChild(new XMLNode("name").setText(cache.name)); var link='<a href="http://coord.info/'+cache.id+'">'+cache.id+'</a><br/>\n'; var base='Type:'+cache.type+' Size:'+cache.size+'<br/>\n'+ 'Difficulty:'+cache.difficulty+' Terrain:'+cache.terrain+'<br/>\n'; var style='<style>.DecryptionKeyWidget{font-family:mono;}</style>\n'; var desc=new XMLNode("description") .setText('<![CDATA['+link+base+style+cache.desc+']]>'); pm.appendChild(desc); pm.appendChild(new XMLNode("styleUrl").setText("#msn_grn-stars")); pm.appendChild(new XMLNode("Point") .appendChild(new XMLNode("coordinates") .setText(cache.lng+","+cache.lat+",0"))); return pm; } function wrapKML(cache,node) { 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 doc=new XMLNode("Document").appendChild(new XMLNode("name").setText(cache.id+'_'+cache.name+".kml")) .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<Style id="sh_grn-stars"><IconStyle><scale>1.3</scale><Icon><href>http://maps.google.com/mapfiles/kml/paddle/grn-stars.png</href></Icon><hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/></IconStyle><LabelStyle><scale>0</scale></LabelStyle><ListStyle><ItemIcon><href>http://maps.google.com/mapfiles/kml/paddle/grn-stars-lv.png</href></ItemIcon></ListStyle></Style><StyleMap id="msn_grn-stars"><Pair><key>normal</key><styleUrl>#sn_grn-stars</styleUrl></Pair><Pair><key>highlight</key><styleUrl>#sh_grn-stars</styleUrl></Pair></StyleMap><Style id="sn_grn-stars"><IconStyle><scale>1.1</scale><Icon><href>http://maps.google.com/mapfiles/kml/paddle/grn-stars.png</href></Icon><hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/></IconStyle><LabelStyle><scale>0</scale></LabelStyle><ListStyle><ItemIcon><href>http://maps.google.com/mapfiles/kml/paddle/grn-stars-lv.png</href></ItemIcon></ListStyle></Style>'); doc.appendChild(node); return KMLHeader+doc.toString()+KMLTail; } function exportString2File( 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(); } function onClickListener(){ var cache=getStructedGeoCachingData(unsafeWindow); exportString2File(wrapKML(cache, getGeoCachingNode(cache)),cache.id+"_"+cache.name+".kml"); } function createDownloadLink(){ var aa=document.createElement("a"); aa.addEventListener("click",onClickListener); aa.href="javascript:void(0);"; aa.innerHTML=' Download KML '; return aa; } function addDownloadLink(){ var nav = document.getElementsByClassName('CacheDetailNavigation')[0]; var ul = nav.getElementsByTagName('ul')[0]; var li=document.createElement('li'); li.appendChild(createDownloadLink()); ul.insertBefore(li,ul.children[0]); } addDownloadLink();