Heads up! To view this whole video, sign in with your Courses Plus account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed HTML5 Mobile Web Applications!
You have completed HTML5 Mobile Web Applications!
Preview
In this video we utilize the Google Static Map API to create a map that displays the location of a note.
This video doesn't have any notes.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
[Jim Hoskins] So now that we've taken a look at the API for the Google Static Maps,
0:00
let's go ahead and try to implement it in our code.
0:04
So like I said before, we're going to implement this as a method
0:08
on our Note model and encapsulate all of the maps data inside of that method.
0:12
So inside of our note model, down at the bottom here,
0:19
we're going to add another method right under isGeoTagged,
0:22
and we'll call this method mapImageUrl.
0:27
And let's take in some options so we can modify the kind of map we're going to create
0:35
based on the function call
0:41
and let's add a comment describing exactly what this does.
0:44
There's // Creates a url for a map pinned with this Note's location.
0:49
Now what I'd like to do anytime I'm using a URL like this
1:08
where there's documentation available, is I like to create a nice comment
1:12
with a link to the API that I'm using and the documentation we'll be using.
1:16
So I'll just say we're going to be using the Google Static Maps API
1:21
and pass a string in here, so anytime we're working on it,
1:25
we can quickly jump into the docs and figure out exactly how this should all work.
1:29
So the first thing I'm going to do is create a variable for the base URL
1:34
that we're going to be creating; call this var base
1:38
and I'm going to paste in the URL that we're always going to use
1:43
and that we're going to be appending options to:
1:47
and that URL is "http://maps.google.com/maps/api/staticmap?"
1:50
and I've added a ? so we can begin adding our parameters.
1:59
Now, one function we can use as a convenience here to create a URL-encoded parameter list
2:05
where we have key=value&key2=val2...
2:12
is jQuery actually has a method called $.param which takes an object of key
2:22
and values and creates a string in this URL format.
2:30
So what we want to do is create an object with the keys and values we want to use
2:35
and then in the end, we'll use that convenience method to actually create the URL string
2:39
of those options.
2:44
Now, any time we take in options, we want to have defaults,
2:46
so what I'm going to do is create a defaults object which will define the default zoom,
2:50
default width and height, and type,
2:55
and we'll build off of this object to actually create the parameters
2:58
we'll ultimately use to generate the URL.
3:02
So I'm going to create a variable defaults
3:07
and we'll make it an object, and let's set the default that we're going to use.
3:11
So one parameter we discussed we needed to use is zoom
3:17
and this tells the map how far in to zoom.
3:22
Now, playing around with it, I determined zoom level 14 is actually a pretty good zoom level
3:26
for what I'm looking for; kind of a neighborhood level,
3:31
but it gives you enough context to figure out where your pins are.
3:34
So I'll set the zoom to 14.
3:37
So let's also set the height and width for our maps,
3:40
so let's say height: 500,
3:43
and we'll say width: 500, so we'll make a nice square map.
3:48
We want to set the default map type to the road map
3:54
which is the normal street map that we're used to seeing.
3:56
We could do a satellite map if we wanted to,
4:00
but let's just set the default to road map
4:02
so we can override it later.
4:04
maptype: "roadmap",
4:06
And we want to set sensor: "false", and this is a Google parameter
4:08
that we don't want to use because we're already giving it all the information.
4:14
We don't need Google using its sensor to figure out where the request is coming from.
4:17
So those are all the defaults that we need to set right now.
4:23
If we were to just call mapImageUrl without passing any options in,
4:26
we should be able to generate a map based on the notes location
4:30
and these default values.
4:35
And now what we're going to do is take the options argument,
4:38
combine it with the defaults, and extend the defaults with those options.
4:41
So basically, we're going to take the defaults and take the options
4:46
and any values defined in options are going to be sort of transplanted on top of default.
4:51
So if we define options zoom, when we finally use our options variable
4:57
if it wasn't defined in the options argument that was passed in, we'll use the default.
5:03
However, if it is defined, we'll use the value that was passed in.
5:08
And to do this, we can do options =
5:11
and we'll use the underscore library
5:18
and use this _.extend method
5:21
and what this takes is two objects--we'll take the defaults and options.
5:24
(defaults, options)
5:28
So this will return the defaults, objects,
5:31
but any keys that are in the options value will also be in that object that is returned
5:34
with options overwriting anything that is in defaults.
5:38
So if we don't pass in any options at all,
5:42
options will now be set to the defaults.
5:45
So now that we have some options that we can use to generate our parameters,
5:56
we need to actually go around and update some of these to match the API's expectation.
6:01
One thing is it doesn't take a width and a height attribute.
6:09
Instead, it takes a single size attribute which takes the form of 500x500.
6:12
So what we want to do is // Convert {width:400, as an example
6:18
and height: 300}.
6:25
We want to instead convert this to {size:
6:37
being "400x300"}.
6:40
So we need to take this width and height attribute,
6:46
convert them into a size attribute,
6:50
and remove the width and height from our options.
6:52
So first, let's set the options.size ,
6:57
and we'll construct a string based on options.width,
7:01
concatenate the "x" that will separate them,
7:07
and then concatenate options.height;.
7:10
So now we have a size in the correct format
7:18
and we actually want to delete width and height from our options
7:21
because the jQuery convenience method is going to add those extra paremeters in
7:25
which we don't need.
7:31
So let's do delete options.height;
7:34
and delete options.width;.
7:42
So now, let's define our markers,
7:45
which will actually tell the map where we want to put our markers
7:48
and what we want our markers to look like.
7:51
Now, you'll remember from the API that markers have a pretty interesting syntax
7:55
where the different properties are separated by pipes
8:00
with the keys and values separated by colons
8:03
and it's a little bit tough to parse, but let's get through it in our code here.
8:06
So let's set options.markers
8:12
and let's construct the string.
8:16
So let's go ahead and say our pin is going to be blue,
8:19
so we'll say "color:blue|".
8:24
Now, our next property, we want to define what the label on that pin is,
8:27
I'm just going to call it "X" so like "X marks the spot."
8:32
So we'll put our pipe in and we'll say |label:X"
8:35
so our marker will be blue with the label X.
8:41
Now, to put another pipe in, basically what we're going to do
8:44
is put in |lat,lon".
8:49
Now, this lat and lon are going to be coming from this Note's latitude and longitude.
8:53
Now, since we're going to be using the lat,lon string in two different places--
9:01
one for our marker and one for our center--
9:05
let's go ahead and create a variable that will hold the string lat,lon with a comma in it.
9:08
So up here, I'm going to say var latlon = this.get("latitude")
9:14
and we'll concatenate the comma + ","
9:28
and then we'll concatenate + this.get("longitude");.
9:31
So now, we have this latlon here and we can replace this
9:43
with our latlon variable.
9:48
We'll close out the string and concatenate latlon.
9:51
So now, this should accurately describe our marker over our Note,
9:56
so let's add a comment describing what we were doing here.
10:03
We'll // Add markers to parameters to add a blue pin to the map.
10:06
Now, the last option we need to set is where the center of the map is going to be,
10:23
and that's going to be the same location as our pin, so it's centered on the pin
10:28
so let's // Center on this Note's location.
10:32
And we'll set options.center = latlon;
10:39
the comma-separated latitude and longitude.
10:50
Now finally, we want to construct the URL
10:52
and to do that, we're going to take our base
10:55
and we're going to concatenate all of our options parsed together as a URL.
10:59
So to do that, we'll use jQuery
11:06
$.param method
11:08
and pass in (options) and this should now create a full URL,
11:11
properly encoded,based on the options we have.
11:15
All we need to do is return url;.
11:19
So now that we have our mapImageUrl method,
11:26
we can try to insert it into our view.
11:30
So I'm going to go back to index.html
11:34
and inside of this clause here where we have isGeoTagged,
11:38
I'm going to insert an image tag <img>
11:42
and we're going to add a source,
11:48
and the source is actually going to be dynamically generated using the template,
11:51
and we'll do <% note.mapImageUrl()
11:56
and I'm not going to pass in any options;
12:03
we're going to use the defaults.
12:06
So let's go back to our browser on our Note with location data
12:09
and refresh and see what happens.
12:13
So we got a syntax error: unexpected token,
12:16
and it's being brought up in _.js
12:19
and underscore is what handles our templates,
12:22
and if we expand this out, we can see that the actual error
12:26
happened in the template method.
12:29
So the actual source of our error is probably in our template code,
12:31
so if you go to index.html and take a look here,
12:35
I may not need the semicolon there.
12:41
Let's just see see what happens if we leave that off and save it.
12:44
All right, that looks like it worked.
12:49
So when we refresh it and that error seems to have gone away,
12:52
so we won't use the semicolon there,
12:54
it looks like we have a map.
12:56
It looks like it's in the right part of downtown Orlando.
12:58
We have a blue pin right over our current offices
13:03
and it looks like it worked, so this shows our map is working.
13:07
And right after it, we have our latitude and longitude.
13:15
So let's check this out in our mobile browser.
13:20
I'm going to create a New Note,
13:23
and we'll say from the Office, we are Recording a Master Class.
13:26
We definitely want to tag this with our location and save it out,
13:36
and it's going to confirm that we can use our current location.
13:42
We will accept that, check All Notes,
13:45
go into this Office one here.
13:49
Now, it doesn't look like it's working; let me go ahead and refresh
13:55
to make sure that we have the code--there we go.
13:57
And now it looks like it is showing up; however, on the mobile device,
14:00
it seems to be getting cut off.
14:05
That's because the image is 500pxx500px, but what we really want to do
14:07
is scale it to the width of the device, so we're going to do this using CSS.
14:13
So let's go into our index.html here
14:19
and let's link to another style sheet.
14:24
We'll call this "css/main.css"
14:34
and this is where we'll put our own styles for our application.
14:43
So far, we haven't had to define any of our own styles in the application
14:47
since jQuery Mobile has done all of that for us,
14:51
but now let's go ahead and create our main.css file.
14:55
So I saved the link here in our CSS folder.
14:58
I'm going to create a new file we'll call main.css.
15:04
We'll go ahead and add a class to our image tag,
15:10
so we'll say img.map {
15:14
and we'll just say width: 100%;
15:17
and the height will be determined by the aspect ratio of the actual image,
15:21
so let's go back to our index.html where we define our image.
15:26
We'll add a class="map" and save it out
15:34
and if we go back here and refresh,
15:42
you can see it now has been resized to fit the width of the device
15:47
so we can see all of our map here.
15:51
And if we flip it back to portrait mode, you can see it resizes so we can always see
15:57
all of the map and determine where our note was created.
16:01
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up