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
Preview
Start a free Courses trial
to watch this video
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