You Are Here (with Safari on iPhone)

Update [February 24, 2010]

See iPhone Safari Geolocation Map Update for a fix for the phantom marker issue noted in the comments.

Since Apple announced the iPhone OS 3.0 update at WWDC a few weeks ago, I’ve been eagerly anticipating the addition of location services to Safari (Webkit).

Safari on iPhone

Until now, providing an iPhone 3G user with a map and an indicator of their current position required building a native iPhone application in Objective-C and getting approval from Apple to distribute said app via the App Store. Not fun.

Well now that OS 3.0 is out, we can take advantage of Safari’s newly baked-in geolocation services and some other niceness to do the very same thing. (jump to the map)

Native Geolocation

Safari now gives us navigator.geolocation from the W3C Geolocation API Draft Spec and all the magic that goes with it: getCurrentPosition (one time retrieval of location), watchPosition (continuously updated location), and clearWatch (stop watchPosition). (If you’re browsing with iPhone, Android, or Firefox 3.5 right now, take a peak at your raw geolocation info.)

We want the location marker to follow us around, so we’ll choose watchPosition. The following provides the basic format we’ll follow, though the final code will be different as we add the Google Maps juice:

  1. function displayLocation(position){
  2. var latitude = position.coords.latitude
  3. var longitude = position.coords.longitude
  4. // do something with this new information
  5. }
  6.  
  7. function handleError(error){
  8. switch (error.code){
  9. case error.PERMISSION_DENIED:
  10. alert('Sorry. Permission to find your location has been denied.')
  11. break
  12. case error.POSITION_UNAVAILABLE:
  13. alert('Sorry. Position unavailable.')
  14. break
  15. default:
  16. alert(error.code)
  17. }
  18. }
  19.  
  20. navigator.geolocation.watchPosition(displayLocation, handleError)

When this code is run in an iPhone 3G with OS 3.0, the browser asks for permission to use your location. If permission is granted, the displayLocation function is called; if not, the handleError function is called. Now let’s do something useful with this location information.

iPhone location permission

Google Maps

Google Maps released a welcome upgrade to their mapping API this past spring. With the still developing API v3, they tossed out the API key, rewrote the code, improved the namespacing, and much more. In the interest of playing with all things new, we’ll use this version of Google Maps. And in the interesting of keeping the focus on the new geolocation shizzle, we’ll skip the in-depth Google Maps discussion and just cover some abstract goals.

Initially we’ll center the map somewhere in downtown Austin, Texas. Then, when our previously mentioned displayLocation function gets called, we’ll add a marker and re-center the map on that marker—just like the big kids do with their fancy native apps.

Inside displayLocation, we’ll create the marker just once and then update its position on subsequent calls. Every time the iPhone changes location, the marker moves to follow. (extra credit: if you want to create a breadcrumb trail, take out the if/else stuff to create a trail of new markers on each iteration)

Lastly, we add an onload attribute to the body element to invoke our geolocation and Google Maps magic after the page loads. We now have a cool mobile map that tracks your position as you’re moving.

iPhone location marker

CSS3 Animation

We could certainly stop here and pat ourselves on the back, but let’s apply one last bit of polish. If you look at the native iPhone Map app, you’ll notice that the blue location icon pulses in and out to keep your attention. Hmmm. Our current location marker is lovely PNG image with alpha transparency that smoothly overlays the background map but it doesn’t pulse. Unfortunately, we can’t animate PNGs. We could fade the image in and out with some more JavaScript coding, but let’s take a look at a better solution, compliments of the new Safari.

When the CSS animation draft was announced, it sounded rather odd to add behaviors (JavaScript’s forté) to a styling spec (CSS). But given our current problem, we start to see the wisdom. We can select and animate the location marker with CSS3.

As demonstrated by Surfin Safari, first we describe the effect with @-webkit-keyframes, then we select the marker element from the DOM and apply the animation with -webkit-animation:

Update [July 1, 2009]

Google just changed their API so that our custom marker image (blue_dot_circle.png) is now a background-image for a div rather than a separate image element (img).

Therefore, our CSS selector needs to be modified so that we can pulse the right element. A quick change from #map_canvas img[src="blue_dot_circle.png"] to #map_canvas div[style*="blue_dot_circle.png"] in the code below solves the problem.

  1. @-webkit-keyframes pulse {
  2. 0% {
  3. opacity: 1.0;
  4. }
  5. 40% {
  6. opacity: 0.25;
  7. }
  8. 100% {
  9. opacity: 1.0;
  10. }
  11. }
  12. #map_canvas div[style*="blue_dot_circle.png"] {
  13. -webkit-animation-name: pulse;
  14. -webkit-animation-duration: 2s;
  15. -webkit-animation-iteration-count: infinite;
  16. -webkit-animation-timing-function: ease-in-out;
  17. }

It’s a simple solution that provides the effect we need without the added overhead of JavaScript.

Feel free to view this map with your normal browser, you’ll get a plain old map of Austin—not much more. For the real show, open it in iPhone 3G and find your current location. Then start moving.

When you get back to the desk, crack open the source code to see how it was all brought together.

Next

So there it is: a breezy introduction to what is possible with the iPhone’s new Safari geolocation powers and Google Maps. We certainly don’t have to stop here. We haven’t even mentioned that other mobile devices have or will have these very same powers. That web developers now have direct access to these powers means that we can expect a torrent of location-aware innovation.

See you at the mall.

Reference Links

Update [February 24, 2010]

See iPhone Safari Geolocation Map Update for a fix for the phantom marker issue noted in the comments.

Update [April 2, 2010]

Make sure you also download the blue marker image and place it in the same directory as your map page. Sorry, I should have been more clear about that.

22 Comments (+)

  1. iPhone Safari WebApps Now Have GPS Functionality | iPhone 3G Tricks

    [...] savvy developer at the website Plebosaur noted that Safari now has native geolocation, and he did some digging within the [...]

  2. With OS 3.0, iPhone Safari can now have GPS functionality and WebApps can benefit | iPhoneIndiaBlog.com

    [...] savvy developer at the website Plebosaur noted that Safari now has native geolocation, and he did some digging within the [...]

  3. Geolocalización en el iPhone/iTouch 3.0 | aNieto2K

    [...] Una de las muchas mejoras que el nuevo firmware del iPhone 3.0 ha traido es la posibilidad de geolocalizar dispositivos desde Safari. [...]

  4. Geolocalización en el iPhone/iTouch 3.0 : Blogografia

    [...] Una de las muchas mejoras que el nuevo firmware del iPhone 3.0 ha traido es la posibilidad de geolocalizar dispositivos desde Safari. [...]

  5. Sergio

    Thanks for your posting! It’s awesome.. Right now I’m struggling to create an app to use this functionality that now we can use directly from a web page.. making things easier… I like it!

  6. leemr

    stedman design…s awesome pages.

    the page works correctly on my iphone. however, when i copy the source and run it from my localhost and even from my own server, i get no blue dot. the map is correct and changes, i just can’t see the blue dot!

    why would this be? and how do i fix it? “i might be invisibly here”???

    i put the source in a .html file.

  7. McBryano

    This code has stopped working and leads to the iPhone bringing up endless Error Code: 0 message badges. Do you have any understanding as to why that might be?

    Thanks

  8. Steve Stedman

    @McBryano Drat! I’m looking into it.

  9. Steve Stedman

    @McBryano at about the time you noticed the errors, it appears that Google changed their API a bit. Modifying the following methods fixed the alerts (I guess they prefer camel case):

    • set_position() is now setPosition()
    • set_center() is now setCenter()

    Apparently they’ve been up to other shenanigans at the Googleplex as well. Now I have a phantom marker image that I cannot shake. Thoughts anyone?

  10. Steve Stedman

    @leemr did you happen to copy the image to your map folder? http://plebeosaur.us/etc/map/blue_dot_circle.png

  11. Ben

    Thanks for this post ! I test your map on my iphone 3GS and i see 2 blue circles (which one is superposed near the second). Do you know why ?

  12. Steve Stedman

    @ben I noticed that too. I took a quick look at the code (and Google’s evolving docs) and couldn’t immediately figure out where that phantom image was coming from.

    I’ll dig in deeper as soon as I can. If you find an answer beforehand, please share. Thanks!

  13. Ben

    Ok Steve, if i find the answer i’ll post a comment here.

  14. Ben

    i don’t find how resolving the problem but i think we can use Jquery to obtain a same result : Jquery has some interesting effects like fade, pulsate etc…

  15. Mike

    I am having the same problem using webkit to animate the custom Google maps icons. Were you able to find a solution?

  16. Steve Stedman

    @Ben, @Mike, I think I found the source of the phantom image, but I’m not sure how to correct it yet.

    It seems that Google is now inserting a duplicate marker image with opacity 0.01. My CSS selector #map_canvas div[style*="blue_dot_circle.png"] just looks for that image in any div and then pulses the opacity. So if there are two images, one that’s normally visible and one that’s normally all-but-visible, they’ll both start pulsing at full opacity.

    I thought that that 2nd marker image might be a rogue shadow, but even when adding a shadow there were 2 pulsing images on top. At this point, I’m really not sure what that 2nd image is about or why it is off center.

    I’ll keep snooping as I have time.

  17. Steve Stedman

    I posted a fix for the phantom markers in a new post: iPhone Safari Geolocation Map Update.

  18. iPhone Safari Geolocation Map Update φ plebeosaur.us

    [...] You Are Here (with Safari on iPhone) φ plebeosaur.us February 24th, 2010 at 4:43 pm [...]

  19. Jurgen Fechner

    I copied the source of the page served by this url: http://plebeosaur.us/etc/map/ and put it on two separate web servers at home. One was a Keyfocus Webserver the other is an Apache 2.2. When I go to your url with my iphone I get what I expected, a map of my location with a pulsating blue dot.
    When I access the copied page with my iphone on the Keyfocus server I get the same map, a crosshair for a few seconds then that disappears and only the map remains.
    I then installed Apache 2.2 and put that same page there. When accessing it with my iphone I get four javascript errors on my iphone and the page wont load at all.

    What is happening here?

  20. Jurgen Fechner

    Hi,

    Does anyone have any comments?

    Best Regards
    Jurgen

  21. Steve Stedman

    @Jurgen, did you also copy the marker image (http://plebeosaur.us/etc/map/blue_dot_circle.png) to your server (I’ll add that to the instructions above). I think that may solve the missing pulsating blue dot issue.

    The other issue is a bit odd. I’ll see if I can replicate it here.

  22. Ben

    it works great for me Steve ! I test on Android 2.1 and ios 4 and it’s ok !

    Thanks a lot for your fix !

Leave a Reply