The Code Train

Where Neil Crosby talks about coding on the train…

RSS Entries

Geolocation & Beer: Part 3 – Static Maps

Posted on May 17th, 2010 by Neil Crosby. Filed under Blog Posts.

The final thing to do now that you’ve found the user’s latitude and longitude and told them where they are in a human readable format is to put all the data you’ve gathered onto a map.

Now, there are lots of tutorials out there for the JavaScript based Google Maps API. So, if you want to learn how to use the JavaScript based API, then I urge you to pop off and look at one of those. For Beer Near Me, I started off using that API. However, for various reasons (slow to download over the phone network, scrolling issues on the iPhone), I decided to move away from that and towards the Google Static Map API. The big win for me in using the Static Map API is that it means the user only has to download a single image into their browser, and all the hard work of putting the map together is done on the server-side. The negatives are that you don’t get nice clickable areas on the map for free, and you don’t get to scroll around easily.

For me, the positives outweighed the negatives, so I went with the static map.

http://maps.google.com/maps/api/staticmap
    ?sensor=true
    &size=320x300
    &zoom=15
    &maptype=roadmap
    &mobile=true
    &center=lat,lon

As you can see, although there are a whole bunch of parameters needed to put a map together, they are all fairly simply. Lets walk through them one at a time:

A simple static google map

  • sensor: Required; either true or false. This simply tells google whether or not we used a sensor to generate this maps’s position. For us, this will always be true.
  • size: Very simple, just width, an ‘x’, and then height in pixels.
  • zoom: How zoomed in you are. 15 gives you a pretty zoomed in map.
  • maptype: For us, a roadmap is what we want. You can also choose satellite or terrain, the same as if you were using the Google Maps site.
  • mobile: Setting this to true allegedly gives you slightly simplified maps that have a lower weight.
  • center: Finally, where the centre of our maps should be. Simple.

Put it all together and you get something a little like this.

Adding some custom markers

Getting a static map Custom markers

But, that’s a bit boring. Normal Google Maps let you add all sorts of custom icons. Well, we can do that too, by adding one or more markers parameters to the image URL. So, to add three icons to a map, two of them the same and the third different, you’d add something like the following to the above URL.

markers=
    icon:http:%3A%2F%2Furl.encoded%2Fimage.png
    |shadow:false
    |52.2282962,0.1537945
    |52.134152,-0.486364
&markers=
    icon:http:%3A%2F%2Furl.encoded%2Fotherimage.gif
    |shadow:false
    |52.135472,-0.491835

And that’s all there is to it. After you whack a load of markers onto the URL you’ll end up with something like the Tottenham Court Road on Beer Near Me, where you can see, amongst all the other drinking establishments, The Bricklayers Arms – the home of Pub Standards (the middle thursday of every month – tell your friends).

Making the map clickable

You might also notice on that page that if you click or tap on any of the icons on the map that you end with a popup telling you about the place. But how is this possible? Aren’t we using Google’s Static map API?

The answer is “yes, we’re still using Google’s Static map API”, but we’re using a little sliver of progressive enhancement to layer data on top of it. If you turn JavaScript and CSS off for a moment, you’ll notice a couple of lists underneath the map image. The first contains links which have targets pointing to the relevant items in the second list. So, with no CSS or JavaScript clicking the links will move you through the page to the data. Useful, but not yet useful enough.

So, what if the user has CSS enabled? What can we do then? Well, what I chose to do on Beer Near me was to position each of those links over the icon they were assigned to. First off, all the icons were the same size, so I created some base CSS that I could hang the final positions off:

#map_canvas {
    position: relative;
}

#map_canvas .marker,
#map_canvas .marker a {
    display: block;
    width: 30px;
    height: 30px;
    overflow: hidden;
    text-indent: -9000em;
    list-style: none;
}

#map_canvas .marker {
    position: absolute;
}

Of course, if we just did that then all the clickable areas on the map would be dumped up in the top right of the map, and no-one would be happy. So, we need to work out where to put those top and left directives.

Warning. Hard-coded Assumptions Incoming

Now, it turns out that if you’re zoomed in to a Google zoom of 15 then each pixel equates to roughly 0.0000266667 units of latitude and 0.0000421875 units of longitude. So, we can use this to work out where we’d like to position our clickable elements.

Lets take an example:

You have created a map that is 320 pixels wide and 300 pixels high, and zoomed to a level of 15. The centre of this map is at 51.510953,-0.133012.

A public drinking establishment (De Hems) exists at 51.512081,-0.131288. Assuming a 30×30 clickable area with its centre at De Hem’s location, what should the top and left co-ordinates of the clickable area be?

On Beer Near Me, I work out the numbers using some code that looks something like the following.

$mapHeightPix = 300;
$latPerPixel  = 0.0000266667;

$centreLat    = 51.510953;
$locationLat  = 51.512081;
$latDiff      = $locationLat - $centreLat;

$topPix = ($mapHeightPix / 2) - (int)($latDiff / $latPerPixel) - 15;

Unsurprisingly, there’s something remarkably similar for longitudes. (If you’re wondering, the answer was top: 93px; left: 185px;).

Now, with that code in place to position the clickable areas on the map users can click and be taken to the relevant item further down the page. On Beer Near Me I then layered on top some JavaScript to do a simple popup (again, look at the Tottenham Court Road page), but I’ll leave that as an exercise for the reader.

And that’s essentially that. What started as a simple weekend project to learn how to use the navigator.geolocation API ballooned slightly to encompass Google’s local search API and static maps APIs, and I ended up with something slightly useful. Maybe in a year or two I’ll have even made it pretty.

Tags: , , ,

If you enjoyed this post, subscribe to The Code Train and read more when I write more.

One Response to “Geolocation & Beer: Part 3 – Static Maps”

  1. hi sir, I want to create a simply app where by simply giving my current location with some key word say “hospital”.The result will show the nearby hospital in map along with path.But i am not able to achieve my expected result Could you suggest me which API’S, i would use to achieve so.

Comments RSS

Leave a Reply

TheCodeTrain Theme by Neil Crosby, Powered by WordPress