Your browser is very old. You might enjoy surfing the web more if you used something newer like:

Google Chrome

Even Firefox would be OK.

If you're being forced at gunpoint to use Internet Explorer, you should at least upgrade it. Version 8 is tolerable and 9 will be OK when it comes out.

Posts from March 2009

Where am I? Where are you?

Today, we’re going to cover the very basics of the Google Maps API which, like most of the other Google APIs I’ve been playing with, is very full-featured and easy to use.

I’ll show the basic code to embed a map on a web page and place a marker at a specific address.

Map of Washington, DC

The first thing to do is add the appropriate script tags to the <head> tags of your page.


    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script>

    <script src="http://maps.google.com/maps?file=api&v=2&sensor=false
        &key=ABQIAAAAJKAoDxf0DXpmiPNGeIJ5_BTGeqkvninRPqN0VBb3AwYRVTSEZxQ5doci0or7L4Elev6DsRR4ertl1A"
        type="text/javascript">
    </script>

Notice the key parameter. That’s your API key (which is domain-specific). You can get your own by signing up here.

The first thing to do is create a couple of global variables for the map & geocoding objects. We initialize the map (giving it a <div> to put the map content in), add the zoom control, and enable scroll wheel zooming. The home function centers the map over the middle of the United States and sets the zoom level so the whole country is visible.

  var geocoder;
  var map;

    function home() {
                        map.setCenter(new GLatLng(37.0625, -95.677068), 3);
                    }

    Event.observe(window, 'load', function() {
                        map = new google.maps.Map2($('map_canvas'));
                        geocoder = new GClientGeocoder();

                        map.addControl(new GSmallZoomControl3D());
                        map.enableScrollWheelZoom();

                        home();
                    })

Here’s the html of the <div> where the map content gets placed.


        <div id="map_canvas" style="border:1px solid #979797; background-color:#e5e3df; width:400px; height:300px; margin-bottom:  10px;">
            <div style="padding:1em; color:gray;">Loading...</div>
        </div>

The code for placing a marker is pretty simple. The point variable is a GPoint object which is the Latitude and Longitude of where to place the marker.


    var marker = new GMarker(point);

    map.addOverlay(marker);

This page shows the above in action by letting the user enter an address and place a marker on the map for that address.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Where am I?  Where are you?</title>

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script>

        <script src="http://maps.google.com/maps?file=api&v=2&sensor=false
        &key=ABQIAAAAJKAoDxf0DXpmiPNGeIJ5_BTGeqkvninRPqN0VBb3AwYRVTSEZxQ5doci0or7L4Elev6DsRR4ertl1A"
        type="text/javascript">
        </script>

        <script type="text/javascript">
                    var geocoder;
                    var map;

                    function showAddress(address) {
                        if (geocoder) {
                            geocoder.getLatLng(
                                address,
                                function(point) {
                                    if (!point) {
                                        alert(address + " not found");
                                    } else {
                                        var marker = new GMarker(point);
                                        map.addOverlay(marker);
                                        marker.openInfoWindowHtml(address);
                                    }
                                }
                            );
                        }
                    }

                    function home() {
                        map.setCenter(new GLatLng(37.0625, -95.677068), 3);
                    }

                    Event.observe(window, 'load', function() {
                        Event.observe($('mapit'), 'click', function(event) {
                            Event.stop(event);

                            if($('address').value) {
                                showAddress($('address').value);
                            }
                        });

                        map = new google.maps.Map2($('map_canvas'));
                        geocoder = new GClientGeocoder();

                        map.addControl(new GSmallZoomControl3D());
                        map.enableScrollWheelZoom();

                        home();
                    })

        </script>
    </head>
    <body>
        <div id="map_canvas" style="border:1px solid #979797; background-color:#e5e3df; width:400px; height:300px; margin-bottom:  10px;">
            <div style="padding:1em; color:gray;">Loading...</div>
        </div>

        <textarea id="address" rows="3" cols="35"></textarea><br />
        <input type="submit" id="mapit" value="Map It!" />
    </body>
</html>

Using PrototypeJS with Greasemonkey

For those of you not already hooked on it, Greasemonkey is an amazing add-on for Firefox that basically lets you inject your own Javascript into a page on the fly.

Don’t like the way a page looks? Want to change things around? Is it a page that doesn’t belong to you? Well, thanks to Greasemonkey, you can make that page your bitch. The problem is that writing Javascript without using PrototypeJS* sucks. It’s tedious and you end up having to write way to much code to do the simplest things.

*OK, jQuery is fine too.

There are two obstacles we have to overcome to use PrototypeJS in a Greasemonkey script

  1. Prototype has to be included on the page the script is running on, not within the Greasemonkey script. Otherwise Prototype won’t actually be able to access any of the page elements
  2. You have to handle the case where a page is already including Prototype otherwise you end up including it twice and the whole thing dies.
  3. That’s not quite it either.

The Greasemonkey Javascript we’re going to write is going to do the following things

  1. Check the page to see if it’s already including Prototype (we’ll also check for Scriptaculous while we’re at it).
  2. If it’s not included, add a new <script> element to the <head> of the page and set the src to Prototype
  3. Set up a handler for the window load event
  4. When the window loads, get handles to the Prototype functions we’re interested in

Here’s a complete script using the above strategy. This particular example only works for http://www.cnn.com. It does an Effect.Shake and puts a red border on each <img> tag on the page.

// ==UserScript==
// @name           Prototype Test
// @namespace      http://www.cnn.com
// @description    This is a test script
// @include        http://www.cnn.com/*
// ==/UserScript==

var scriptTags = document.getElementsByTagName('script');
var addPrototype = true;
var addScriptaculous = true;

//Loop over all script tags in the page header
//and check to see if Prototype or Scriptaculous are already being included
for(i in scriptTags) {
    if( scriptTags[i].src.match(/prototype.*?\.js/) ) {
        addPrototype = false;
    }
    if( scriptTags[i].src.match(/scriptaculous.*?\.js/) ) {
        addScriptaculous = false;
    }
}

var scripts = [];
var idx = 0;
if(addPrototype) {
    scripts[idx] = 'http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js';
    idx++
}
if(addScriptaculous) {
    scripts[idx] = 'http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.2/scriptaculous.js';
    idx++
}

//Add any missing script tags to the page header
for (i in scripts) {
    var script = document.createElement('script');
    script.src = scripts[i];
    document.getElementsByTagName('head')[0].appendChild(script);
}

//Handler for the window load event
window.addEventListener('load', function(event) {
    //Get handles to the Prototype and Scriptaculous functions we're going to use
    $ = unsafeWindow['window'].$;
    $$ = unsafeWindow['window'].$$;
    Effect = unsafeWindow['window'].Effect;

    $$('img').each( function(elem) {
        Effect.Shake(elem);
        elem.setStyle( {border:  '3px dotted red'});
    });
}, 'false');

The important part of the above is this

$ = unsafeWindow['window'].$;

The problem is that Greasemonkey doesn’t know about the PrototypeJS functions because they only exist inside the actual page.

The unsafeWindow lets us get a handle to the page copy of the the various PrototypeJS functions.

Yes, it’s a camera. No, it doesn’t need “film”

The year was 1992 and I had been saving for months. Finally, with a small parental cash infusion, I was able to purchase this:

Logitech Fotoman

The Logitech Fotoman, one of the first, consumer-grade, digital cameras in existence.

The specs on this bad boy are truly breathtaking

  • 320×240 pixel images
  • Internal memory allowing the storage of up to sixteen whole images
  • Not 254, not 255, but 256 grays, allowing for rich black & white images worthy of Ansel Adams.

Combine the power of the above with the Aldus Digital Darkoom suite and you have the potential to create some stunning digital art.

Look at that! It looks like a pencil drawing. But I can’t take all the credit. THE COMPUTER did most of the work.

Pencil Lighthouse

And who cares if takes black & white pictures when you can ADD YOUR OWN COLORS.

Me in Color

OMG! You can type things RIGHT ON THE PICTURE. “Inner Child”. That is some crazy-deep shit right there.

Inner Child

It was a pretty fast little bugger too. It would rise to the occasion, even in the face of the most weighty action shots. Oh to be a teenage boy with no car and access to a trampoline.


The process of colorizing a picture was pretty simple. You’d open up the file with Digital Darkroom, select an area of the picture, select a color, and click the Colorize button.

This ended up being a very resource-intensive operation for my computer and there was a 5-10 second period where the screen would dissolve into a pyschedelic soup worthy of the Merry Pranksters.

But the real fun didn’t start until the day I realized that you could take a screen capture during this period of “purple haze” and save it as an image all its own.


I built up a pretty large collection of pictures over the course of high school and freshman year of college. And then, during a System 7.3 upgrade-gone-bad in college, I lost about 2/3s of them. To-date, one of the worst data disasters of my life.

I resolved to get some backups made of my remaining files (easier said than done). I had to call in a big favor with a friend who worked in the Lewis & Clark IT department in the end. I carried my Macintosh LC down to one of the IT labs where it was hooked up to an Iomega Jaz Drive. The files were transferred over to a Jaz disc, then copied to another computer where they were burned to a very expensive CD that I still have to this day.

I lost track of the CD when I switched over to Windows and couldn’t read it anymore.

And then, a number of years ago during my first experimentations with Linux, I rediscovered that CD and that Red Hat was perfectly capable of mounting it. I’ve been carrying around those remaining pictures ever since, all of which are backed up in no fewer than 4 locations.

I still have the camera, languishing in a box in the unfinished part of my basement.

I’ve taken it out a couple of times and the battery is still charged. It lets out a merry little chirp when I press the single turquoise button, letting me know that it’s captured another picture.

A picture trapped forever, wanting for a cable and a computer old enough to connect to.