Monday, April 28, 2008

Satellite imagery for DSmaps

If you've played with the script from my last post you've probably noticed that gMapMaker has the ability to fetch satellite imagery from Google Maps as well as your basic street map tiles. After defining an area and zoom level and hitting go, you'll notice that two new directories are now under your cache, 'kh' with the sat pictures in Jpeg format, and 'tt' with the street map overlays as a transparent PNG. So if only we could combine these into the one PNG file, we'd be able to throw that into the QTRS to XYZ script and use them on our DSs. A bit of reading lead me to ImageMagick, which handily has a Perl module, PerlMagick.471 bytes of Perl script later we have a script to do what we want.

To use it you'll need ActivePerl which you should already have from the last script, and you'll also need to install the PerlMagick module. You can get this in the ImageMagick Windows Binaries, but the Perlmagick part of that install failed for me on XP SP2. To get mine working, after installing ImageMagick I had to follow the instructions in this post and then copy the .DLL files to my windows\system32 directory manually. If you have any trouble getting it installed, try the ImageMagick Forums for help.

After you've got those installed, drop the script in the same directory where you put the qrst2xyz one and create two new subdirectories, called 'sat' and 'streets'. Now copy the satellite .JPGs into the sat directory and their matching street map .PNGs into streets and run 'perl satcompo.pl' you should see the images being composited and dropped into your gtiles directory, all ready to be converted for DSmaps.

If you want to play with the quality of the outputted files, you can edit the line:
$sat->Set(depth=> 4);
to change the colour depth (in bits per channel). 4 is a good compromise between quality and read speed for me as my mini SD cards are a bit slow, but you may be able to get away with a value of 6 or even 8 for prettier images if you have some fast media.

Also keep in mind that DSmaps only goes down to zoom level 17, so don't bother trying to fetch and convert anything closer in than that.

Saturday, April 19, 2008

Gmaps to DSmaps converter

I've been playing around with the fantastic DS homebrew app DSmaps and found it pretty useful. One great feature is that it caches areas you've already viewed and you can go through them later (i.e. when you're out and about and get lost)

But what if you're lost and you haven't looked at that area already, and there's no free wifi around to grab those missing tiles? Well if you know you are going to be somewhere unfamiliar you could just pan around that area at various zoom levels before you leave hoping you've viewed everywhere you will be going and hope you don't miss anywhere, but ideally you'd be able to select a certain geographical area, downloads all the tiles for that space at all the zoom levels you want and have them ready to go. A bit of googling around led me to gMapMaker which lets you do just that, however it grabs the tiles in Google's QRST quadtree naming scheme, whereas DSmaps stores the tiles as a directory for the X coordinate, containing a subdirectory for the Y coordinate, which then contains the actual tile named as the zoom level. (once you get down past the 256 x 256 level X and Y data starts going into the filename as well, as DSmaps only uses a max 2 characters per directory)

So I thought as I'm wanting to learn how to write perl scripts I'd have a go at one to convert from the Gmaps naming to the DSmaps naming. I based it off a code snippet found here to figure out the X, Y and zoom values, then converted them to hex and used that to generate the DSmaps paths and files. You can grab the Perl script here. The script was written and tested on a Windows XP machine, no idea if it'll work on other platforms.

Before we get to using the script, a few notes. This is the 2nd script I've ever written, so it is probably not the best way of doing things, any pointers on how I could have done it better are welcome. BACK UP YOUR CARD FIRST. Sorry about the caps, but you never know when something might go wrong and I'm not responsible if your card gets corrupted, your dog catches fire and aliens enslave humanity due to this script. You can feel free to redistribute or modify the script as you see fit, however a credit or at least a link back to this post would be appreciated. If you do give it a go, please post a comment and let me know what you think.

Shutup already, how do you use the thing!

To use the script, you'll need to install Perl, which you can get for Windows from ActiveState. Once you've got that set up, put the script in a directory (doesn't matter where) and create a subdirectory under that called 'gtiles'. Fire up gMapMaker and enter the coordinates bounding the area you want to grab, the zoom level you are after and select 'driving maps only' and set the operating mode to 'Download tiles'. Click Go and once it grabs all the tiles you will find you have a directory called 'mt' in the cache folder which has a directory for each zoom level you have grabbed. Copy the files from these directories to the 'gtiles' directory you created (just the files, don't copy the directories themselves) and run the script ( go to a command prompt, change to the directory you dropped the script in and type 'perl qrst2xyz.pl'. If all goes well, you should see that you now have a directory structure suitable for DSmaps all ready to go, copy this over to the DSMAPS folder on the card you use in your DS and fire up DSmaps. You should now be able to pan and zoom around offline as long as you stay within the area and zoom levels that you have grabbed.

And because I know some of you will be thinking it, yes you could theoretically download all the tiles at all the zoom levels and have the entire planet (que evil genius laugh), however we are talking in excess of 270 million files here, weighing in at around 2.7 terabytes, so good luck finding a card to get that onto your DS :P.