Subscribe to RSS feed

splitbrain.org - electronic brain surgery since 2001

A Pirate Map with LibGD and Google Maps

Yesterday I thought about visualizing photo geodata. While tinkering with different ideas, I thought about making it look like a real paper photograph placed on a real map.

Of course it had to be automated somehow. So I spent a few hours with PHP's GD library functions. It's really cool what you can do with it.

Let's start with the result:

The image above was created by my MapDecorate class. Download, use and modify it as you like. It's licensed under the Creative Commons Attribution-Share Alike 3.0 license.

Here is how it works:

  1. fetch a map image from the Google Static Maps API for given coordinates
  2. convert the map colors to sepia
  3. place an X on the center
  4. put the compass on top
  5. add a paper texture
  6. do an address lookup on the coordinates and if found write it next to the X
  7. write a custom text at the bottom
  8. fetch an image from a given URL
  9. optionally grayscale it
  10. apply some grain texture to the photo
  11. rotate the photo and place it on the map
  12. apply a mask to cut out the map border
  13. cache the map image for later reuse

The techniques I used are quite similar to the ones in my MonsterID script. It is basically overlaying different PNG images with alpha transparency. However there are a few things in it that took me a while to get right.


One thing was to rotate the photo but retain a transparent background. The trick is to pass a -1 as background color to imagerotate:

$img = imagerotate($img, 5, -1);

The other question was how to apply the alpha mask for cutting the border. There is no builtin function libGD so I had to do it on my own. Here is what I came up with:

function imagealphamask(&$img, &$mask){
    $width  = imagesx($img);
    $height = imagesy($img);
 
    imagealphablending($img, false);
    for ($x = 0; $x < $width; $x++) {
        for ($y = 0; $y < $height; $y++) {
 
            // current color
            $rgb = imagecolorat($img, $x, $y);
            $r   = ($rgb >> 16) & 0xFF;
            $g   = ($rgb >> 8) & 0xFF;
            $b   = $rgb & 0xFF;
 
            // red channel of mask
            $rgb   = imagecolorat($mask, $x, $y);
            $alpha = ($rgb >> 16) & 0xFF;
            $alpha = floor($alpha/2);
 
            $color = imagecolorallocatealpha($img,$r,$g,$b,$alpha);
            imagesetpixel($img,$x,$y,$color);
        }   
    }   
    imageSaveAlpha($img, true);
}

Be sure both passed images have the same dimensions! The function surely can be improved. It currently only uses the red part of the given mask image 1) and it's really slow.

Here's another example with a color photo and the reverse geocoding in action:

Tags:
php,
programming,
libgd,
google,
maps,
pirates
Similar posts:
1) shouldn't matter for a grayscale image
Posted on Sunday, February the 1st 2009 (12 months ago).

Comments?

1
This is quite nice! Great work :)
2009-02-01 21:10:46
2
Impressive as usual! Andreas, the man! :)
2009-02-02 09:08:39
3
Very cool idea. How about optionally fetching the images from OpenStreetMap? I think the cycle map would look quite fantastic because it also has height contours.
2009-02-02 09:19:41
4
Dolph, as long as OpenStreetMaps provides an API to fetch a map as a single image it should be quite easy to use. Feel free to try it ;-)
2009-02-02 09:22:51
5
thats really cool, great opportunity for travel operators to follow your method...

nice work!
2009-02-02 14:30:20
6
I am not sure if you can relicense as CC an image created from a privative one (google). Unfortunatly, I think you have to check the license terms.
PS: grate job!
2009-02-02 16:55:09
7
Bernabe, not the final image is CC licensed but the code (and layer masks) to produce the image are.
2009-02-02 17:27:21
8
I am amazed!
2009-02-02 20:49:33
9
I love it! Nice work :-)
2009-02-04 13:12:17
10
Is there a live site for this? would be nice just to type in an address and test it out.
2009-02-17 15:47:12
11
Really great!!  Thanks for the sharing!!
2009-06-11 07:27:04
CAPTCHA

No HTML allowed. URLs will be linked with nofollow attribute. Whitespace is preserved.