I came upon an article in linux journal that spoke about geotagging and geocoding for websites. It talks about ICBM and meta tags, which are great except for one thing. It goes into the page header, so can't be different for different sections of the page. It also talks about embedding the information in comments - which means that users and javascript can't easily read it, and about RDF/RSS feeds - which would be useful for my blog feed, but not for my blog itself.
I decided to try my own minimalistic markup, and came up with this:
<address class="gmap" lat="yy" lon="xx" zoom="z">Some text</address>
Of course, I went through a couple of iterations to settle on this, and it was based largely on what the google maps api accepts.
A side note before I go on. The reason I chose google maps was because they provided aerial photos of a few major Indian cities, which is where most of my reviews are based. This turned out to be of no use though, because the aerial photos are not provided via the API. One has to visit Google Local to see them.
Ok, so this gave me the ability to easily add geo information to a post - just a single line. If I wanted to be really cool, I'd need to translate that to a map, so I started studying the google maps API, and after several iterations, came up with this:
//! Add a marker with a callout containing the specified html
function addMarkerToMap(map, point, html)
{
var marker = new GMarker(point);
map.addOverlay(marker);
if(html)
{
marker.openInfoWindowHtml(html)
GEvent.addListener(marker, 'click', function() {marker.openInfoWindowHtml(html);});
}
}
window.onload=function()
{
var adr = document.getElementsByTagName("address");
for(var i=0; i<adr.length; i++)
{
if(adr[i].className == 'gmap')
{
// Grab HTML to put into callout
var html=adr[i].innerHTML;
var lat, lon, zoom;
lat=1*adr[i].getAttribute('lat');
lon=1*adr[i].getAttribute('lon');
zoom=parseInt(adr[i].getAttribute('zoom'));
adr[i].innerHTML = "";
// Build map and center on lat/lon
var map = new GMap(adr[i]);
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
var point = new GPoint(lon,lat);
map.centerAndZoom(point, zoom);
addMarkerToMap(map, point, html);
}
}
}
What it does is quite simple. After page load, it iterates through all the divs in the page, looking for divs with class 'gmap'. When it finds such a div, it looks at the lat, lon and zoom attributes (which are not standard HTML btw) of the div and uses that to draw the map.
I soon realised that I was only using zoom level 0, so dropped that attribute and hard coded it in.
I showed it to Nate a little later, and he mentioned that there was a microformat for geocoding. Had a look at it, and while it was slightly more verbose than my format, it achieved a little more, and wouldn't be much harder to parse.
Changed the div to this:
<address class="geo">
Some text<br>
<abbr class="latitude" title="37.801324">N 37° 48.079</abbr> <br>
<abbr class="longitude" title="-122.424903">W 122° 25.494</abbr>
</address>
This shows up neatly, and I could change my javascript to accept both classes, 'gmap' as well as 'geo', and change the parsing to this:
if(adr[i].className == 'geo')
{
var ab = adr[i].getElementsByTagName('abbr');
for(var j=0; j<ab.length; j++)
{
if(ab[j].className == 'latitude')
lat = 1*ab[j].title;
else if(ab[j].className == 'longitude')
lon = 1*ab[j].title;
}
}
else
{
lat=1*adr[i].getAttribute('lat');
lon=1*adr[i].getAttribute('lon');
}
The rest of the code remains the same.
It isn't too hard to replace Google maps with Yahoo! maps in this implementation. The parsing of the microformat is the heart of it all, after that it's just a matter of using your API of choice.
You can see both formats in action on my reviews of US restaurants. Note that one of the restaurants uses the old format that I've described above, and the other two use the geo microformat. I'll add more in time, and a few from the UK as well.
Update: Calvin Yu has written a Yahoo! Maps implementation of geo.
Update: Switched to use the <address> tag instead of a <div>. Just seems more semantic.
Update: I have a Yahoo! Maps version as well.