Share your favorite places with friends.
In this hack, I discuss our Thingster Geoblogging service and some of the details of how I integrated Google Maps. We provide Thingster free of charge at http://www.thingster.org/, and it is open source and open data licensed as well. You're welcome to log in, create an account, and play with it; you're also welcome to run your own copy or just take any ideas you like and build your own equivalent.
My own interest in place-tagging came from a very simple desire: I wanted to be able to share information about my favorite places with my friends. The fact that there are not 10,000 companies already doing this has always completely mystified me. It seemed like a perfectly logical business plan if you were so mindedcertainly better than, say, "pets.com."
It is pretty obvious that the blogging paradigm is the right way to hang Post-It notes in space. People already use blogs in almost exactly this way: you own your own blog, you publish in a formal publishing framework, and blogs export this wonderful RSS format that is machine-readable. Blogs have already been extended to blog pictures, songs, and even video: blogging by location is the next logical step.
The challenge in blogging about places is that our blogging tools or content management systems need to support some kind of satisfying, fast, and compelling map interface. These tools need to be as easy to use as ordinary blogging tools. A clever novice should be able to walk up to a mapping service, create an account, and post her first geotagged post in under a minute.
5.10.1. Enter Thingster
In 2004, Ben Russell and I first conceived Thingster as an "anything tool," where one could blog about any kind of thing. Maps were the first clear interest and my good friends Tom Longson and Brad Degraf quickly jumped on board to help play with the idea. We thought that if community driven maps existed, then we could start to share information about our communities more intelligently, and that this might even change the way we engage and interact as citizens. This is the sort of big if that always seems to be a warning of several months of sleepless nights hacking.
Let me point out that those of you who haven't had to suffer in the dark ages before Google Maps simply have no appreciation of how hard it was to build a compelling web mapping service. It was uphill with snowstorms both ways and we had to arrive before we left. We had tried several other mapping solutions that were available in the open source community and I even personally did try to build my own mapserver (which is available at http://maps.civicactions.net). The labour, time, and ultimate performance of rolling our own is completely humbling. We recognized just how high the bar is set in what users expect from a web mapping service.
Today Google Maps provides us with that last missing piece, and not only is Thingster finally able to articulate its vision, but several other exciting projects, such as http://ning.com, http://platial.com, and http://tagzania.com are also rapidly beginning to explore the possibilities of easy access to a compelling web mapping service.
5.10.2. Adding Maps to Blogs
In the development of my own approach it became obvious that there are several key things that map-based content management systems should do:
5.10.3. Practice
Connecting Google Maps to a blogging tool requires connecting both an input side and an output side. You want to both capture Google Maps position information for new posts, and you want to plot posts to Google Maps when you are viewing the blog.
On the input side, I connected the Google Maps navigation to the form input box. As you drag Google Maps around, it instantly updates the user input form box so that when the user finally submits the post, the post has the map location that they have suggested. This code was quite a small bit of JavaScript, and it looked something like this:
var map = null; map = new GMap(mapdiv); map.addControl(new GSmallMapControl()); map.centerAndZoom(new GPoint(-123,45), 6); // REGISTER CHANGES INTO FORM IF FORM EXISTS GEvent.addListener(map, "moveend", function() { var center = map.getCenterLatLng(); var latLngStr = center.y + ' ' + center.x; if( parent.document.form && parent.document.form.locationinput ) { parent.document.form.locationinput.value = latLngStr; } });
On the output side, when I want to plot the points in my content management system to Google Maps, I request an RSS feed of the particular channel that the user wants to plot and simply plot those points. That code is slightly larger because it has to fetch an XML document from the server (the RSS feed), walk through it, and post those posts into Google Maps. You can use the GXmlHttp class from the Google Maps API as a means of fetching this data on the fly, without having to worry about browser compatibility issues.
Once I have one of my RSS feeds with some geo-data in it, I instruct Google Maps to plot each of the points:
// ITERATE ITEMS - BUILD MAP WHEN NEEDED var latmin = 0; var latmax = 0; var lonmin = 0; var lonmax = 0; var visited = 0; for(var content = data.firstChild; content != null; content = content.nextSibling ) { if( content.nodeName != 'item' ) { continue; } // get some stuff var title = getfield(content,"dc:title"); var link = getfield(content,"dc:link"); var description = getfield(content,"dc:description"); var location = getfield(content,"th:location"); if(!location || location.length < 2) { continue; } var strs = location.split(" "); var a = strs[0]; var b = strs[1]; if( a.indexOf('(')>=0) { continue; } var lat = 0; var lon = 0; try { lat = parseFloat( a ); lon = parseFloat( b ); } catch(e) { continue; } a = "" + lat; b = "" + lon; if( a == 'undefined' || a == "NaN" ) continue; if( b == 'undefined' || b == "NaN" ) continue; if( lon == 0 && lat == 0 ) { continue; } a = 1234; // bounds builder if( visited == 0 ) { latmin = latmax = lat; lonmin = lonmax = lon; } else { if( latmin > lat ) latmin = lat; if( latmax < lat ) latmax = lat; if( lonmin > lon ) lonmin = lon; if( lonmax < lon ) lonmax = lon; } var point = new GPoint(lon,lat); var marker = new GMarker(point); var html = title; GEvent.addListener(marker,"click",function() { marker.openInfoWindowHtml(html); } ); map.addOverlay(marker); visited++; } var latc = latmin + (latmax - latmin) / 2; var lonc = lonmin + (lonmax - lonmin) / 2; // should pick zoom better some year map.centerAndZoom(new GPoint(lonc,latc), 13); }
5.10.4. How Do You Actually Use Thingster?
In Thingster, you first create an account and log in using the register page at http://thingster.org/register. Once you are in your home page, you can select "post" to create a new post. The post form allows image upload and has an integrated map, as shown in Figure 5-28.
Figure 5-28. Thingster image upload with integrated map
When you are done posting, return to your home page, where you can see a compilation of your posts and pictures on a map, as depicted in Figure 5-29.
Figure 5-29. Thingster's compilation of your posts and pictures on a map
Having Google Maps in Thingster lets us explore a number of tasty implications we originally thought might exist. Better maps affect what we see, the choices we make, the repercussions of those decisions, and perhaps even the shape of our societies. Our goal in providing this service is to explore such ideas.
Anselm Hook
You Are Here: Introducing Google Maps
Introducing the Google Maps API
Mashing Up Google Maps
On the Road with Google Maps
Google Maps in Words and Pictures
API Tips and Tricks
Extreme Google Maps Hacks