>> ALAMI: I'm a developer advocate at Google. I work on our Geo Developer products, so Google
Maps API, Google Earth API. You can follow me on Twitter, it's Ossama Alami. And you
should follow the Google Maps API Twitter account. We frequently tweet about announcements,
new features, and exciting, you know, used cases of our APIs. And that link up there
is for the GDD agenda and to rate the session which I hope you do. So, today, I'm going
to talk about the Google Maps API version three. We're going to learn how to build a
map, learn about some new features, and sort of explore version three of the Maps API.
But before we dive into that, I want to give you a little bit of history over why we decided
to build version three of the Maps API. How many of you have used the Google Maps API
version two? Great. How about version three? Oh, good. So, there are some users out there.
So, version two of the Maps API has been enormously successful. It has over 350,000 active sites.
It was built and released in 2005. It sort of started the whole Web mapping and mash-up
trend on the Internet. And not only does it remain as the Web's largest used mapping API,
but it's also one of the largest APIs used on the Web, period. So, in late 2008, the
Maps API engineering team realized that if you were to load version two of the Maps API
on that first generation iPhone, on that, you know, that great Web browser that Apple
released for mobile device, it would take something like 20 seconds to parse a JavaScript
and become usable. And I say usable sort of, well, where you could use it but it wasn't
exactly a great experience. And when one of Google's tenets is that every millisecond
counts, 20 seconds seems a little unreasonable. So, the team decided to--well, the team decided
this was just not a situation that we wanted to be in. We couldn't have a mapping API that's
took 20 seconds or more to load on a mobile device. And we saw that the mobile Web was
certainly growing in usage and we wanted to have an offering that was usable on the mobile
web. So, looking at v2, the team tried to optimize it as much as possible. But given
the way it was designed and the fact that it was built to sort of meet all these different
used cases, you know, it has directions, it has polylines, it has editing of polygons
and polylines, and it was built of a code-based that, you know, was created in 2005 off of
maps.google.com, they couldn't optimize it enough. They couldn't strip out enough things.
They couldn't make it asynchronous, asynchronously loaded, that they decided that the way forward
was to build a new mapping API design from the ground up with mobile devices in mind,
so optimized for mobile devices but a full desktop mapping API. And so, v3 was born.
We released it at Google I/O is 2009. And in Google I/O in May of this year, we launched
it from Labs. We graduated the API where we said that this is now our new premier JavaScript
Maps API and we deprecated version two of the Maps API. Now, for all of you guys that
raised your hands when I asked how many of you have built a v2 app, don't worry. V2,
while deprecated, we are committed to supporting it for at least three years. So it gives you
plenty of times to upgrade those maps to version three. And we keep on adding new and new features
to v3, which I'll talk about, some in this session and some in the next session. So,
v3-wide support for various browsers including a specific support for the Android browser,
iPad, and iPhone browser targeted towards mobile. And then for those of you that build
v2 apps, you'll be happy to hear that we got rid of API keys, so you no longer need any
API key to use the API. Before we get started on building the v3 map, how many of you or,
you know, I certainly have been consuming a lot of coffee in preparing this talk and
in combating jet lag. And, you know, I'm from San Francisco and some of my team is in Sydney
and both those cities have a very large coffee culture, and some of my team are kind of fanatic
about, you know, finding great coffee and finding new places that have coffee. I don't
know if Brazil has a big coffee culture. So, this will be a well-targeted talk. We decided
to combine our love of maps and our love of coffee and build something awesome. So, what
we're going to do today is from start to finish we're going to build a v3 application targeted
towards mobile devices to let users--to let--based it on an application that crowd sources coffee
reviews and coffee establishments, all in a map. So, let's get started. The first thing
we need is to build a map. This is the, you know, the standard look and feel for Google
Maps. You know, it has the various map types. The street view is now enabled by default,
you know, pan and zoom. So how do we go about adding this to a Web page? Well, let's first
start with the Web page. It's pretty simple. All I need is a div and I'll call it map and
I want my map to live in there. Let's do the style sheet. I want the map to basically take
up the entire page so I'll just set it's height to 100%, and then the core of it, the JavaScript.
I want you to notice here how little JavaScript it takes to get a map up and running. So,
this is like six lines of JavaScript. I'm doing is loading the API here and then creating
a map, setting it to zoom level, setting it to latitude and longitude, so where I want
it to be on the Earth, and then saying that I want to default to a road map. And then
I'm adding an event listener here at the bottom, when the window loads call this init function
to load the map. And then one more thing I want you to notice is while we don't have
any API keys anymore, we do have the sensory equals false. This is a required parameter.
It's either true of false. It refers to whether you are building this map based on some, you
know, real time sensor data. What that really means is if you are using GPS or a Geolocation
to plot some data on the map or show the user's location, the API loader doesn't change at
all depending on what you pass in this function. This is purely for us to track how the maps
are uses and for us to satisfy certain data provider agreements that we have. So, these
six lines of code will get this--will get us the map that I showed you earlier. And
that's all it takes. And v3 now has, by default, it'll load a default UI. So that includes
the map type internal up here, the zoom and pan control here, and then street view will
be loaded by default. In v2, if you use that, you would have to either set UI to default
to get it to a default view or manually add those controls to the map. You still have
control over what the map shows, you can disable that and say, "I don't want a zoom control.
I don't want a map type control. I don't want street view." That's still an option for you
but by default this is what happens. Also, that bit of code will run on an iPhone and
Android browser without any other changes. And it'll run in an experience that's appropriate
to those devices. So, if you load it on an IPhone, it will show up without the, you know,
the zoom controls. It'll just--you can pinch the zoom on the mobile Web and that will work
fine. You noticed it's, you know, makes the zoom control smaller, it collapses the map
type control, it knows sort of the context of how big it is and what devices it's running
on, you don't need to customize it anymore to make it usable on an iPhone or an Android.
Since I am in Brazil, I'll talk about localization. The--this is actually something you don't
typically have to take care of for the Maps API. By default, we will show the map in the
language that the user's browser is set to. So, if it's set to Brazilian Portuguese, it'll
load Brazilian Portuguese. In most cases, you want that behavior. You don't want to
force a particular language on to the user if they've already specified what they know.
But you can force that behavior by just appending this app language perimeter when you load
the map. So, obviously, my browser is set to English, I don't speak Portuguese. So,
when we start over here it was in English, but I'm forcing it to load in Portuguese here
and it shows up in the correct language. Since we're building an application that's really,
you know, we're crowd sourcing local data we expect users to use this map on their phone.
It's not particularly useful for me to show a map of San Francisco when I'm in Brazil.
I want a map of what's around me so I can see the coffee shops around me and I can rate
the coffee shops around me. So, we're going to make sure we use Geolocation to put the
right location on the map. This is not actually a feature of the Maps API, this is a HTML
Five feature, widely supported across all the, you know, smartphone mobile browsers,
as well as Safari and Firefox and Chrome on the laptop. I'm running Chrome right here.
Let's see what the code looks like. Again, not a lot of code. I just need to check if
navigator.geolocation exists, that means the browser supports Geolocation. I will get current
position and then just pan the map to that position. So, that gets us this map. I have
not told this map to go to this conference site where we're at right now it's doing this
via HTML5 Geolocation. The next thing we want to do is add a marker to the map where the
user is, because it's useful to know, you know, relative to the rest of the area where
I am exactly. Markers are what we call overlays and the maps API supports a number of different
overlays. Markers, polylines, polygons, info windows are considered overlays, so anything
that you add to the map that has a sense of location will be considered an overlay. But
we just want to add a standard Google map teardrop marker at the user's location. Again,
not a lot of code. I just create a new instance of marker, Google.maps.marker, and I set the
position to the position I got back from the Geolocation. So, I set its latitude and longitude
to be where I am and then I set the map on the marker. So, for those of you that have
used v2, you notice a difference here. On v2, I would say map.add overlay and give it
a marker. In v3, I say marker live on this map. So, it's a different sort of design structure.
If you want to remove the marker from the map at this point you just set its map to
null. So, in this call, I would have null. So, that's interesting. I mean, I love the
red map marker. You know, I put it all over my presentations. I'm a big fan. I have them
on my laptop. But it's kind of overused on API sites. What's really more useful for user
is to give this indication that they are actually geolocating yourself, and, you know, various
devices have used this sort of little blue dots with a radius that shows how accurate
it is. So, instead of the red map marker let's do something custom and more usable. The code
here again, what I want you to take away from this talk is how little code I'm using to
build this map. The Maps API v3, really easy to get started, really easy to build some
pretty advanced applications with not a lot of code. All I'm doing is, is creating a new
marker image and giving that marker image to the marker. So, instead of just creating
a new Google.maps.marker I'm passing in this marker options object and saying the icon
is this image up here. V3 also supports CSS spriting. So, if you want to--you know, one
great way to improve performance is to have your images sprited. So that's, while I didn't
do that for this particular icon, you can see how it's supported here. I am specifying
the size of the icon and the point at where that icon begins. So, if I had a big image
containing a lot of different icons, I could specify a specific location in that image
to represent my icon. And then the last point there is the anchor. A Google Maps marker,
the red teardrop, the anchor would be at the bottom in the middle. Since I'm showing a
blue circle, I want the anchor to be in the middle of that circle. All right, that's where
the user actually is. So, I just specify half the size in both the X and Y. And that gets
us this location marker where we're at. But, you know, I mentioned that it's sort have
been established, when you display users location, you typically also show the accuracy. You
know, HTML5 Geolocation can rely on Wi-Fi, or depending on their device, on GPS, so,
location or on mobile devices on cellular networks. So, the accuracy of the location
can vary quite widely. So, let's put a circle around where the user's location is so that
I can give them an indication of accuracy of the Geolocation. Oops. This is a new feature
in v3, this circle object. In v2 we didn't have a circle, so you would have to create
some sort of image. We also have a new rectangle object that you can add to the map. Pretty
simple, I just create a circle give it some perimeters for how I want the circle to look.
And down here, in get user's location, I am setting the radius of the circle to the accuracy
of the Geolocation, that's something that goes back in the HTML5 Geolocation spec. And
then I'm just again, like I would with the marker, setting the circle, circle's map,
to be the map that I created earlier. One thing I want you to notice here is this bind
to. V3 has this concept of MVC objects, which I'm not going to go into much depth in this
talk, but we do have a great article on our documentation site called Fun with MVC Objects.
So, you can learn all about sort of the architecture of v3 and some really cool new features. What
I want the circle to do is I really want it to move with my marker, right? If I move my
marker because the user has changed location I want the circle to move with it. So, I need
to add code that says, "When the marker moves, move the circle." In v3, it's really, really
easy to do this, it's this one line of code. But what I'm saying here is bind the accuracy
circles' center to the user location marker position. So, what that--what happens there
is when the position changes, what's being called as accuracycircle.setcenteruserlocationmarker.getposition.
But you don't have to handle those events. With this one line of code, it'll automatically
bind those two properties together. So, what do we have so far? We have our location marker
and our circle of accuracy. Let's add a custom control so that, you know, if I pan the map,
I want to--oh, I lost where I am. Click, my location, and I can quickly pan back to my
location. A custom control is just an arbitrary div. So, the first thing we want to do is
style that div that we're going to create. I'm going to give it a classic button. I'm
just going to give it the style which makes it look a lot like the controls that we have
over here. I want it to look very similar so I'm just going to give it the style that's
just standard CSS. And then the JavaScript, I am going to, here, add the div to the map
as a control. I'm creating the div. I'm giving it the classic button. I'm setting its text
to my location. And then, I'm adding it to map.controls array at top right position.
So, the v3 API has a concept of controls anchored to specific positions. So, top right, top
left, top center, bottom center, you know, all the--all around the map and it'll take
care of laying out controls added to the map at a specific position. So I'm anchoring at
the top right but you know that I already have the map type control up in top right.
So, v3 knows to add it to the left of the map type control, but if the map gets bigger
it's still anchored to that right position. And that's all it is. I just create a div
and add it to this array. I also want to do something when the user clicks the button,
obviously, so I just listen to the button's click events, and pan the map back to that
user location I saved earlier. So, what have we done so far? We've added the location.
We added a button to go back to location. What else do we want to do? Well, we want
to have the ability to add a shop, right, because we want this application to both show
me what coffee shops are around but also allow me while I'm on the run, "Hey, I just had
a great cup of coffee. I need to remember this place, add this location, rate it, you
know, let's say, one to five." So, I click, add shop. I'm going to just open an info window,
which is again just another type of overlay on top of this marker, and lets a user enter
a name, address, and a rating. And then, you know, I'm just opening it where I think the
user's location is but obviously that might not be accurate so I want to listen to a click
event so that the user can then move this shop to specifically where it is and then
save accurate data. Again, this is very similar to the, my location, button I added. It's
just a custom div. The only point I want to make on this slide is that the Maps API is
fully compatible with any JavaScript framework that you want to use. So if you're happy coding
in jQuery, you can definitely use jQuery with the Maps API, there's nothing that conflicts
there. Anybody here use Google Closure tools? One guy. So, we also have an external file
for Closure so you can use the Maps API. And in fact, the Maps API was built using Closure.
So, I want to pop open a new, or drop a new marker where when I'm adding a shop and I
want to open an info window on that marker. Another difference between v2 and v3, v2 had
one instance of info window throughout the lifetime of the application so you can only
open one info window on the map. V3 doesn't have that restriction. You can add, you know,
10, 20 info windows to the map--arguably that's not particularly useful, but you can now have
the flexibility to have multiple open info windows where v2 didn't give you that. We
have to be careful in migrating your applications though as if you want the behavior of only
having one info window, you have to take care to keep track of that info window and make
sure it moves around as you're--as you're opening and closes the old one. So, all I'm
doing here is I'm creating the info window. I'm giving it some arbitrary HTML which I
displayed by passing in contents in this info window object. I'm creating the marker. And
then, when the map is clicked, I want to move the position of the marker. And then, when
I click add a new shop, I want to again, move the position of the marker to the center of
the map, set the marker to be on the map so it shows up and then, open an info window.
You can see here, I'm opening the info window on Map so that's basically saying, set map
on info--on the info window, and I'm giving it a marker. In info window, you can set an
info window's location. It doesn't need to be associated with the marker but this is
a shorthand way to bind an info window to a specific marker. So, it'll get the behavior
that we saw earlier, where if I click add shop, it'll drop the marker and open an info
window. What would be really cool though is limiting the amount of text that a user has
to enter, right? Especially on a mobile device, you don't want typing any address. You have
to ask the baristas like, "What's the address here?" That's not really a fun way to enjoy
coffee. So let's see what we can do there. You can see as I click around the address
changes for where the user is. For those of you that don't know this, it's called reverse
geocoding. The Maps API have what we called geocoding which is a process of taking an
address and getting back a latitude and longitude. It also has reverse geocoding, which is the
process of taking a latitude and longitude, sending it to our servers, and us trying to
give you basically what we--our best guess for what at--what specific address you're
at. So, given that this is a, obviously, a request to our servers, or as everything we've
done earlier was sort of synchronous programming where I'm adding a marker and it shows up
on the map, here it's a request to our servers so we need to add a function callback so that
when that request returns I can do something. But it's not much more complicated than that.
I'm creating a new instance of geocoder. This geocoder class supports both forward and reverse
goecoding. I am creating the request. In this case, you see I'm passing in a lat/long. If
I wanted to forward geocode, I would instead say, address:, and then the string that the
address is. In this case, I'm just passing in the lat/long of wherever that marker is
and I'm calling geocoder that geocode, when it returns a success, I'm pulling out that
formatted address and adding it to that info window in that box. There's a lot of data
that comes back including a very easy way for you to parse specific address components
as well as a formatted address which we're using, but also things like optimal viewing
balance for this element via, you know, a city or an intersection or an address; what's
the optimal way to view this on your size map. But we're just going to use a formatted
address. And then when the map is clicked, in addition to what we do up here, as what
we did earlier, we moved the marker, we're also going to reverse geocode with that new
marker. So that gets us this code here where I can move around, I can rate a store, and
now I just want to enable saving a shop. So let's do that. Not much new code here. So
all I'm doing is creating a new marker image. I want to have a custom icon for indicating
a shop that's already been saved. So I'm just going to use this copy.png that I have. I'm
creating a new marker. I am--when I save, removing my red Google Maps marker, adding
the custom marker that I created. So I'm removing the old marker by setting its map to null.
I'm closing the info window and I'm just creating a new Maps marker with that icon at that position.
So next, we want to load shops, right? We want to load the shops that we have saved.
Obviously, this is a server--there's a server component to this. I'll make all this code
available. I'm not going to go through the server component because it's not really a
part of the Maps API, but it's a very simple App engine app built in Python that basically
just has a very simple API to save and load locations. But when do I want to load a location?
You can see either two coffee shops here which I actually didn't go to. I just randomly added
some data. But, you know, if I zoom out, you can see I've sort of been using this application
in North America and team's in Sydney and we did a trip to Southeast Asia. So what you
saw there is, as I panned out and then stopped interacting with the map, the application
then loaded the coffee shops that were in the range of the map. You know, when the application
starts up, let's say this becomes really popular, I have thousands or tens of thousands or hundreds
of thousands of coffee shops, it's not really useful for me to load a coffee shop in Sydney
when I'm in Brazil. So what we want to do is add a new event listener. We're going to
listen to the map's idle event. This is fired whenever the user stops interacting with the
map. So if the user pans the map and then stops, idle will be file--will be fired. If
he zooms in or she zooms out, idle will be fired. And then I can perform some action
based on that. What I'm going to do is I'm going to take the bounds of the map and this
two URL value just gives me a stringed format for the bounds of the map, that is the extent
of the Earth that I am looking at in my current map view. I'm going to send it to my API and
it's going to come back with a bunch of stores. I'm going to iterate over those stores and
add it to the map. Here, the only thing interesting here is I'm making sure to keep track of all
the markers that I've added to the map in my own, you know, array that I've defined
somewhere else. This is important because, for the most part, the Maps API won't keep
track of markers for you, you need to do this for yourself, and I don't want to keep on
adding new markers to stores I'm already displaying on a map. And here, you can see I'm--this
is the actual function to add that marker. The only new thing I'm doing here is I'm setting
a title. A title is basically an easy way for you to access the sort of on-hover display
of text. So whatever--when you hover over a marker that has a title set, it will then
display whatever the title is. So I'll show you that right now. If I hover over here,
you will see it shows a coffee shop. So let's click on this. I gave this coffee shop three
stars. It's at that address. And, you know, it'd be great to get some sort of directions
for how to get there. Let's click directions and it will map out directions. So the Google
Maps API v3 supports three types of directions. There's obviously driving directions. There's
also walking directions. Since this application is, you know, a very kind of hyper local,
I am really only interested in places I'm going to walk to. I'm going to use walking
directions. The other direction type that we support in some countries--not Brazil yet--is
bicycling directions. But in this case, I'm going to show you how to use walking directions.
You'll see the code here is actually very similar to the reverse geocoding we did earlier,
right? Directions is just another service that Google provides. You send a request,
you wait for a response, you handle that response when it comes back. So all I'm doing is creating
that request here. I'm saying, "I want to go from where the user location is to the
address of the shop." And you'll notice I can give the direction service an address
or I can give it a lat/long. It doesn't matter. I can give it two lat/longs. It'll route between
those two. I'll give it two addresses. I can give it five addresses and will give an optimized
route between all those five. And then I'm just saying, "I want to do this walking,"
and when it's--the result returns, just render that result on the map using this directions
renderer. I'm just going to show the routes on the map but the direction service does
return textural directions, does let you render that standard look and feel for Google Directions
and also lets you access specific directions steps so you can render it however you want.
Excuse me. And here is our application. You can go to it right now. It's live. It's whereiscoffee.appspot.com.
We built it basically for optimized mobile devices. This is what it looks like on a Nexus
One or on an Android device. I can click add shop. I can click around to change that shops,
change a rating. You'll notice here I'm actually pulling in some locations. We're using the
Local Search API. You can take a look at the code yourself but that's another way to sort
of help the user guess at where they're at. I don't know what this is but let's just add
something to the map and it should show up right there. And then this is what it looks
like on a desktop. It's just a larger view of the same thing. You can very easily create
a site that looks different for mobile and desktop. And, in fact, I encourage you to
do that. But in this case, we're just showing the, you know, the mobile view in a desktop
web browser. So what have we learned today? We've learned about how to use the map, markers,
overlays, controls, getting a user's location, using some of our services. What else is there?
Well, there's quite a bit. There's polylines and polygons, which we didn't touch upon.
There's traffic and bicycling layers. I tried the traffic layer in Brazil. I couldn't ever
get it to show anything but red. Was that--was that accurate? Styled Maps, which I will talk
about in my afternoon session, so I encourage you to attend that one. Street View, which
I'll show you right now. So we launched Street View in Brazil, what, a month ago? Something
like that? And my cab driver told me there's 130,000 streets in Sao Paulo, which sounds
like a terrible thing for our Street View drivers. But it's standard Google Street View
experience. What's really exciting about v3 versus v2 is that Street View was built entirely
in HTML. So since we targeted this API for mobile devices, we wanted to make sure that
it's entirely useable on all mobile devices. And not all mobile devices support Flash,
which our old Street View interaction was built upon. So this is all rendered in HTML.
What this lets us do is allow you to have some really sort of new interactions with
Street View that we didn't have in Version 2. You'll notice I have a custom marker where
our Google Developer Day is here. Excuse me. We're right here. Let's toggle the Street
View. I don't know if you can see it. It's actually right there. So, markers can be shared
between the Map and Street View. And you can add markers directly to Street View. And what's
cool is as I get closer to that marker, that marker gets larger or smaller. And I can also
open arbitrary info windows in Street View. So that's cool, yeah? I'll show you something
I find really cool and that's the ability to do custom street view. So, again, we're
at this location here at the Sheraton. Let's click Street View, drag it in, let's say,
over here. So this is the standard Street View experience as I drive down the road.
Oh, what's this? You can see I added a little GDD 2010 leading to the Marriott or--I'm sorry,
the Sheraton--the Sheraton over there where we're having this GDD. This is obviously not
something you'll see when you go to maps.google.com. It does not have, you know, real time events.
But what happens when I click here? So yesterday when I got in town, I took just a standard
Canon point-and-shoot on a little tripod that I sort of perilously tried to hold on off
a chair and rotated and took a bunch of pictures. And you can see how a conference is set up
the day before. And then stitched it together with software called Hugin, which is just
something I found and downloaded off the Internet, and then added a custom street view, which
is really easy to do in v3. So you can jump into the speaker's room, you can see some
other Googlers here, a lot of jetlagged faces. You can see I was a little slow taking these
panoramas so she's over here, she's over here and she's over here. I can turn around and
jump into the speaker's--or sorry, I was just there--jump into the keynote room. And then
you see also Chris is apparently pointing at himself and also on the stage. So, a very
cool functionality. Not a lot of code. Basically, the way this is done is you have a way to
provide a custom tile URL to the Street View panorama. The Map works by tiling so we have
a set of tiles. Street View works very similarly. So you can take a panoramic photo, cut it
into tiles, and then specify to the Maps API how to load those tiles. This is the bright
way to do it. You know, you want to tile it because it's a lot easier to load tiles and
then you can have different resolutions at different zoom levels. But if you want to
do the quick and dirty thing, which is what I did yesterday, I just took one big image
and plastered it into Street View without tiling it and it works fine. These are large
images. They're about a meg each, which is why you'd want to tile them so that you don't
have to serve a meg worth of data. And you can see there's, you know, a fair amount of
code here but it's not that complicated. In this case, you know, I'm returning a specific
panoramic image based on where I--or what Street View I want to load and then how I
link between different panoramics is just specifying a heading and an ID for that panoramic
image. And then down here, I linked specifically to our Google Street View imagery. So what
I'm doing here is when I'm at a specific lat/long, I recognize that I'm close to GDD. I then
add a new link and it'll show up automatically in Street View. So you can, you know, if you're
building a store locator for instance and you want to right away for the user to navigate
into this store, you can do this with our Street View imagery leading into your custom--excuse
me, your custom imagery. So that's what I wanted to cover in this session. Please come
to my session this afternoon where I'm going to talk about some other new features in v3
and across Geo as well. The presentation is right here at this URL. I encourage you to
load it in Chrome, it might not work otherwise. The code for--or the documentation for the
Maps API is here. The application whereiscoffee is here and the code for whereiscoffee is
right here. Thank you very much for your time.