If you’re not familiar with Geocaching, but have any love for the outdoors, then I heartily recommend you try it. It’s pretty much treasure hunting for grown-ups and using grown-up toys. It’s also great for the family, I never go without my son.
If you’re not familiar with Linqpad, go get acquainted, I use it for so many different roles, in this case, scripting C#.
As I am only an amateur Geocacher, my GPS device of choice is my Windows Phone (currently a Lumia 920 – which I also love) and GPS Tuner’s Outdoor Navigation. Outdoor Navigation is ace, it has many features making a great companion when out and about. However, it does not have full integration with Geocaching.com, so you have to use OneDrive to synchronise a “loc” file downloaded from Geocaching.com.
This brings us to the problem, each loc file is one Point of Interest in Outdoor Navigation, meaning that if I plan to stock up on (say five) caches before heading out I need to download five files, copy five files to OneDrive, fire up Outdoor Navigation and import each file, one after another from list. Downloading the files is easy enough, my browser only requires one click. Uploading to OneDrive is equally easy, just multi-select and copy. But the import into Outdoor Navigation is not multi-select or fluid when working through the a long list. The import process was starting to get tedious after a while so I decided to dig into the loc files to see if there was a way to speed things up.
Here’s a loc file for just one Cache (from today’s outing):
It’s an XML document with a
loc root element and a
waypoint for the Point of Interest. After a bit of experimentation I found I could put any number of
waypoint elements into the document and that Outdoor Navigation would only have to import one file that contained any number of Points of Interest. Bingo!
Now I had a way to import just one file if, but to do that I needed to combine all the individual loc files from Geocaching.com. The next issue was how to combine them, enter Linqpad, as always.
Using a bit of Linq-Xml I was able to load each file, grab the “waypoint” element(s) and then combine them into a new XML document that I could save to disk and even auto upload to OneDrive – providing I used the OneDrive Application for Windows.
First. Load all the loc files I have downloaded.
There’s a bit going on here. We start by grabbing any file with the “loc” extension in the folder stored in the
folderPath variable –
Downloads\GC in my case – Creating a new instance of the
LocFile class calling
GetElements() and combining all the results together. I’m using
SelectMany instead of
Select because I am assuming there could be more than one “waypoint” element in a loc file. What we are left with is an
IEnumerable<XElement> containing all the “waypoint” elements from all the files.
Second. Creating the new XDocument:
Here we are creating a new
XDocument with a root element of “loc” with the attributes “version” and “src” with the values of “1.0” and “Groundspeak”, respectively (the first, second and last lines in the above XML). And then filling the root element with the contents of the
locationElements – the “waypoint” elements from the First snippet.
Finally. The LocFile class.
This is the class that represents a loc file and knows how to get the relevant Elements from it.
These three snippets are the meat of the script, everything else is just fluff to get the correct paths and save the output and copy it to OneDrive.
It’s pretty easy to use, just fire up Linqpad, load the Script and then run it. Before I start I ensure that there are only the loc files I want to combine in my
folderPath, but other than that, you’re away.
If you need to change the paths, that’s at the top of the script and is pretty straight forward too.
Download Here’s the link to download the “linq” file from my OneDrive.