All posts in Development

How to Make a Map of Your Locations Using BrightKite and TinyGeoCoder.com

Where are Nate and Tilly now? The image to the left was created using Google Maps on Sunday, May 4th 2008. Although this map is static, it’s a replica of the map shown on the right sidebar of our Traveling Europe blog. This post will explain how I use my iPhone, a new service called BrightKite, and a little bit of my own hackery to dynamically change the map on our site, displaying exactly where we are at any time.

The Problem

The problem sounds simple, but is in fact, relatively complex to solve at the moment.

I want to update the map on my site, showing our current location, with as little work as possible on my behalf.

Options and Thoughts

  • I’ll be using my jailbroken iPhone while in Europe
  • It would be great if we could push the current geo-location (latitude and longitude) of the phone to a server of my choosing (in which I could then take those coordinates and do all kinds of things. (This has been the biggest issue so far.)
  • I would rather not have to “tell” the phone to push my location. If it updated once per hour automatically, that would be optimal.
  • I want to record a history of locations so that eventually I can tie in photos taken, blog posts written, etc all to a location and coordinate that with a map, just for fun. A true traveling journal.
  • I am currently looking into how the Google Maps location system works and I assume they have a hidden/unpublished API call that does that for them. If so, I will find it, and I will use it. I’m working on tracking that down right now to simplify the current mapping solution.

The current solution: iPhone + BrightKite + Dapper + TinyGeocoder

Disclaimer: I know there are a million ways to solve this problem other than how I will describe here. For my purposes, this has been the simplest way of doing it. Yes, I could have used FireEagle. I know BrightKite is coming out with an API. I did try to talk with the guys at Twittervision, etc, etc, etc. Trust me, I’ve been working and thinking about this for a while. Regardless, feel free to comment and I’ll let you know if I knew about your proposals/modifications and why I didn’t choose them. If I didn’t know about what you comment on, I’m happy to say so, change my solution, write another post, and give you credit for it.

I like bullet points, so I’ll describe HOW I setup my solution first, and I’ll give you code in a moment.

  1. Signed up for an account at BrightKite. Checked in to my current location.
  2. Went to Dapper and created these new BrightKite location-checking Dapps. One of them checks my current location (or any user’s for that matter), and the other I will be using another day to map my historical route (I’m leaving explanation of that for another post, too).
  3. Using the Dapps, I retrieve my current location and send it to my Tiny Geocoder so that I get a valid and code-useful latitude and longitude.
  4. Using the lat/long, I push that into the image source, which is a Google Static Map.

So now, all I have to do is update my location at BrightKite, which can be done via SMS text message, through their website, or via email (all available for use on my iPhone except for SMS once we’re overseas). BrightKite records my history and the Dapp changes to retrieve a new location. And voila, he map is updated based on that new location. Simple right?

So, what’s left? I have two things I still want done. (1) I don’t want to have to tell anything my location. I want it to be figured out for me using my current as-close-as-we-can-get latitude and longitude. I know Google can do this with their maps, so it’s just a matter of time before I find out how and exploit that feature. (2) I want the iPhone to push my location. I don’t want to have to tell it to update. This will definitely be something I’ll have to figure out on my own I think. There is an application for the jailbroken iPhone that allows you to run apps in the background (usually once the “screen saver” thingy comes on, the apps shut down to save battery life). But, this one is going to be the trickier of the two.

The code

Honestly, this is it:

[php]

$bkite_url="http://www.dapper.net/transform.php?dappName=BrightKitecheckedinlocation&transformer=JSON&v_Query=nateritter";
$bkite_json=file_get_contents($bkite_url);
$bkite_loc=json_decode($bkite_json);
$loc=$bkite_loc->fields->Current_Location[0]->value;
$geo=file_get_contents('http://tinygeocoder.com/create-api.php?q='.urlencode($loc));
[html]
<img src="http://maps.google.com/staticmap?center=<?php echo $geo; ?/>&markers=<?php echo $geo; ?>,red&zoom=8&size=325x130&key=MY-GOOGLE-API-KEY"/>

Now, let me explain line by line:

  1. Setting up the URL to the Dapp that gets my current location from BrightKite. If you want to get yours, just replace “nateritter” with your own username and there you have it.
  2. I get the contents of a JSON-formatted response from the Dapper server into a variable
  3. Because I’m using PHP5 on my server, I use the PHP function json_decode() to put the response into a PHP-useable object/format.
  4. I put the string location (like say the address or city/state I most recently checked in at) into a variable.
  5. I use my own, never seen before, geo-coder to switch the location into a latitude/longitude format (like “39.9938,-167.939”). This is the format required by the Google Static Maps API.

Then, you’ll notice the HTML is just an image, really. That’s the beauty of Google’s Static Maps. It’s just an image. No crazy JavaScript to produce a map. It’s awesome. It’s all supposed to be on one line, so ignore the weird formatting on this blog article here and assume one line.

  1. I create an Google Maps image with the proper dimensions that I want to fit my sidebar using the geo-coordinates produced by the Tiny GeoCoder.

Done and pretty.

Normally, I’d put the code up for download, but it’s so simple and already created for you that there’s no need. Just copy and paste.

Obvious things you need to change are the Google Maps API key and your own username in the BrightKite call (Dapper URL). Otherwise, you should be good to go.

One more disclaimer about the Tiny GeoCoder

First, you have to understand that the Tiny GeoCoder was built by me for the one and only purpose of sending an address or other string-based location in and getting back the latitude and longitude in a very simple format. Nothing more. Nothing less. It doesn’t use a lot of error checking, so it could be wrong on occasion. If you send it “San Diego”, it will choose the one it finds first, so it’s better to be specific (there is a San Diego, TX and a San Diego, CA).

Second, I currently do not cache location requests in the Tiny GeoCoder, but now that I’ve published this, I think that would probably be wise. If anyone wants to help me do that, I’d be happy to listen since I’m not an expert in that area.

Third, a result of not caching locations means the Tiny GeoCoder could get overloaded with requests and break down if it gets popular. If this happens, please contact me here and let me know (not in the comments, please).

Fourth, I’m obviously not charging to use it, but I’m not against doing so if it gets beyond my control in terms of scaling or popularity. I want it to be free, but the only way that’s going to happen is if people help me keep the costs low on it, both in labor and in server costs. So, please participate if we get to that point and help keep it free.

Ready, set, travel

Please feel free to offer advice, comments, criticism, and critiques in the comments below. I only post these kinds of things because people respond to them. Without that, I’d probably just talk about what I ate for dinner, and nobody really cares about that kind of stuff.

Discuss.