I’ve been experimenting lately with a location tracking service for my mobile phone; the service I’m using is a free one, called LocOf which is run by a very helpful chap in the Netherlands; if you have a compatible phone, it’s well worth a look. You can embed a map of your location in your own site very easily, and a quick tap will take you to a live update. It’s also possible to view historical track, so I can work out the tiresome predictability with which I take the same route to the office, for example.
The main client is for Symbian phones, though there’s an Android beta. If you do decide you like it, it’s one of those websites that’s well worth donating too – it’s run by just one person, not a company trying to sell you anything, or flog your data.
Embedding a graph of your location in a web page could be useful for lots of people, but there are other possibilities too; if you can get the latitude and longitude of someone’s position, then you can start to do more clever things. My ultimate aim will be linking this to the Heatmiser thermostat I’ve been playing with lately, so I can have the heating controlled by my movements. But first, I wanted to work out where I was, without looking at a map – for a lot of people, it’s more useful to have a page that says ‘Nigel is at home’ or ‘Nigel is at the office’ than a map. Quicker to read, less data, and tells you what you need to know.
Mapping a location
For this, you need two things. First, a service like LocationOf.com that you can call to get the latitude and longitude of your mobile device (or you can have a webpage request it, if you prefer, but I’m using an API that Jasper at LocationOf was kind enough to make available to me).
Then, you need a list of locations and their coordinates. I’ve always found Google Maps to be a pain for this, but Bing maps is straightforward. Find a place, click ‘My places’ and use the tools to add pins to the map, and then name them. Then, from the Actions menu, choose Export and GPX, and you’ll get a file with the names and co-ordinates that you save on your desktop. There’s no need to sign in or create an account.
I then saved these locations – there are only a few of them – in a MySQL database table that I’ve defined like this:
CREATE TABLE `BLlocations` ( `id` int(11) unsigned NOT NULL auto_increment, `locName` char(50) default NULL, `latitude` float default NULL, `longitude` float default NULL, `proximity` int(11) default NULL, PRIMARY KEY (`id`) )
Most of those columns are obvious; the one that might not be immediately clear is ‘proximity,’ which I’ve used to overcome GPS inaccuracies and the size of some locations. Essentially, this will define the perimeter within which I’m happy for the system to say I’m actually in a particular place. So, for my home, it’s set to 25 metres; for Liverpool Street Station, I’ve set it 200 metres, and for the office, it’s set to 100 metres. I might fine tune those later.
When I want to try and find out where I am (or the device I’m tracking) I use the Haversine formula to calculate distances. As long as you don’t have tons and tons of locations in your database, you can do this in an SQL query. This is what it looks like using MySQLi and PHP (with a few line breaks for readability):
$locQ = $myDatabase->query(sprintf( "SELECT BLlocations.*, 3956000 * 2 * ASIN( SQRT(POWER(SIN((%F - abs(BLlocations.latitude)) * pi()/180 / 2),2) + COS(%F * pi()/180 ) * COS(abs(BLlocations.latitude) * pi()/180) * POWER(SIN((%F - BLlocations.longitude) * pi()/180 / 2), 2) )) AS distance FROM BLlocations HAVING distance < 1000 ORDER BY distance LIMIT 1",$lat,$lat,$lng))
I’ve limited that to one result, because I just want to know if I’m near one of the places I’ve defined in my list. $lat and $lng are, obviously, the locations determined from the phone via LocationOf.com, or however else you want to get them.
Then, if no results are returned, I know I’m not with 1km of any of my defined places. So, I then use Geonames.org to lookup to name of the locality, using their ‘findNearbyPlaceName’ function. This will give something like ‘Upper Clapton’ for the part of town where I live, and I can display that on the website, so it would say
Nigel is in Upper Clapton at 1350
The LocationOf api gives me the time of the last location saved too, so I can use that to let people know how stale the information is – at the moment I just check and say “is in X at Y” if the data is less five minutes old, or “is in X since Y” if it’s more than that; I could add “was in…” if it’s very stale.
What if I do get a location from my database? That’s simple, too. The results of the query will give me two figures – both in metres. One is “distance” which tells me how far I am, and “proximity” is the boundary of the location. I check these and if the distance is less than the proximity value, it will say
Nigel is at home
otherwise, it will say
Nigel is near home
together with the time stamp, in the same way as above.
What’s the point?
You might be wondering what the point of all this is. There are various possibilities here; you don’t have to show the information on a web page, of course, not least because there are security implications to doing that on the open web. You could store it in a database and make decisions based on it – such as the heating control that’s going to be one of my next projects.
And you could use it for other things, like call controls; work out where someone is, and have a click to call button on your website – something else I’m playing with, using the 3CX phone system – which calls an office number, a home number, or their mobile, depending on the location that you’ve determined them to be in.
I look forward to your heatmiser implementation!
It’s been a pleasure reading.