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 learn how to calculate the distance between two coordinates and how to use that to create a List View of all of our notes.
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
So, now we've created our view which has a list in it, and our locate button will
0:00
actually update the application's current location.
0:05
The next thing we want to see is if our new collection can be sorted by the distance
0:08
from the current location to each notes location.
0:13
Now, this is going to be a tricky process, so let's do it in small steps.
0:18
The first thing I like to find out is to make sure that the comparator is
0:23
actually working properly based on the locate button, or just even at all.
0:27
So, I want to make sure that the comparator is working properly, that is,
0:33
it's refreshed when we hit the locate button.
0:36
So, one way we could test that is to create a comparator function that returns a
0:41
random value and see if every time we update our location, if the list randomly sorts.
0:44
So, this is our comparator function as we wrote it.
0:51
It's just returning zero, which will be a sort of static pseudo random sort
0:54
based on how it's stored in the database, but what we actually want to do
0:58
is call a method on note that we will call "distanceFromCurrent," and this method
1:01
will handle all the logic of comparing the notes distance from the
1:09
application's current distance.
1:13
So, let's go up to the note model and begin defining that method.
1:15
So, here we are in our note model.
1:19
We're just going to add another method underneath map image URL,
1:21
and we'll call that "distanceFromCurrent."
1:27
And then like I said, the process of calculating the distance here is actually
1:33
pretty complicated, but what we can do is call return Math.random.
1:36
The way the comparator works is it'll take each of the values from distanceFromCurrent
1:45
and try to sort those, and since the values will be random, we should get a random sort
1:49
every time we attempt to sort that collection.
1:54
Now, to get a little more information here, I'm going to go ahead and add a few notes.
1:58
[? Music ?]
2:04
[Many Notes Later]
2:06
And so, that's the last of all those new notes.
2:10
If we go to nearest notes here, we can see we have a lot more notes.
2:13
Hopefully, all of them have some location information here.
2:21
Unfortunately, it's all going to be the same location, which we'll have to
2:24
worry about in a moment.
2:27
So, if everything's working right, when we click the locate button,
2:30
it should update our location and try to sort, and since our sort is random,
2:34
we should see these sort of just shuffle around.
2:38
Now, I'm not seeing that quite yet, so let's see why that might be.
2:41
Let's see if our distanceFromCurrent is being called.
2:48
So, I'm just going to add a console.log here and say "distanceFromCurrent"
2:51
and just see if that's being called at all.
2:57
So if we click "locate," it looks like I just need to refresh the page
3:00
in order for that to take effect, because now it is not only giving us distanceFromCurrent here,
3:05
we're also getting the sorting by random values here.
3:15
Let's make sure that the console.log is not the thing that changed here,
3:19
so let's remove that, refresh, and try again.
3:22
Cool, so every time we click the locate button it's resorting, and since the comparator
3:27
is giving us a random value, we're getting a random sort.
3:31
So, we have now updated our nearest notes view page to be able to
3:37
sort based on the location.
3:41
The locate button will get the current location, store it into a value in the
3:43
application object, and now what we need to do is write a comparator function
3:48
that will compare each note to that current location.
3:53
With latitude and longitude, finding out the distance isn't as simple
3:57
as using the Pythagorean Theorem in a flat space.
4:02
The earth is round, which makes calculating the distance between two points,
4:06
measured in latitude and longitude, a fairly complicated equation.
4:11
Now, I don't know this calculation off the top of my head,
4:16
but I do know what the name of the calculation is, and I will let you know.
4:19
It's called the haversine distance, and it is how you measure between
4:24
two points on a sphere.
4:28
With that, you can Google it, you can just Google measuring the distance
4:32
between latitude and longitude, and you can find a page like this,
4:34
and this gives you a little bit of information, including a JavaScript tool
4:40
that will help you calculate the distance between two latitude and longitude points.
4:45
Now, the main reason that we have such a complicated equation is because
4:50
the Earth is spherical, and the way longitude works is as you move higher
4:55
in latitude, the distance between two longitudinal degrees decreases as you
5:01
move towards the North and South Pole.
5:05
When you get to the North and South Pole, there's actually no distance
5:08
between any of the longitudinal distances.
5:10
So, the calculation that we have to do has to take into account how far from the
5:14
Equator we are and the actual radius of the Earth.
5:17
Now, in addition to explaining all of these formulas really well and providing an
5:23
interactive tool, this particular page actually offers us a JavaScript
5:27
version of the haversine formula which we're going to adapt to our needs.
5:32
Basically, it takes into account the radius of the earth, and right now it's
5:38
doing it in kilometers, so our final value will actually be in kilometers.
5:41
If we replace that value with the radius of the Earth in miles, we could do it in
5:47
miles or any other value, and then we do all of this math.
5:51
So basically, what I'm going to do is, I'm going to copy in my version of this,
5:57
which I've adapted from this version.
6:01
So, let's go into our code again.
6:04
And our distanceFromCurrent here, let's remove this random here.
6:11
We don't need that anymore, and I'm going to paste this in, and I'm going to
6:14
explain as much of this as I can without getting too deep into the math of it.
6:18
Now, the first thing I've done here is I've added a convenience function
6:25
to convert from degrees into radians.
6:28
All of this calculation works in radians, and if you actually look at the original
6:32
source, to convert it it uses a method which isn't really defined in our browser,
6:35
so I've converted the two rad method calls to a function call, which is simply
6:41
multiplying degrees times Pi divided by 180.
6:46
Then really what we need to do is define our lat 1/lat 2, long 1/long 2 variables,
6:53
which are used in the equation.
6:59
So, latitude and longitude 1 are going to come from App.currentlocation.latitude,
7:01
and lat and long 2 will be based on this note.
7:07
It doesn't matter which one you set, so long as you make sure that lat and long 1
7:10
match up and lat and long 2 match up.
7:15
Then basically, the equation goes through finding the distance between the latitudes
7:20
and longitudes, and it does a lot of trigonometry here to figure out the total distance
7:24
between the two on a spherical object,
7:30
finally resulting in D, which should be our distance in kilometers.
7:34
Now, there is one thing we do need to protect against, is if we try to call
7:39
distanceFromCurrent, there may be a couple situations where this won't work.
7:42
For instance, if the current location inside of our application has not
7:46
been set, we are going to fail, and if there's no note for the current note,
7:50
we're also going to fail.
7:56
So, we want to put a guard at the top of our distanceFromCurrent to return quickly
7:58
if this note is not geotagged or if there's no current location.
8:04
So, what I'm going to do on the first line here is paste this in,
8:09
and if this is not geotagged, or if the app doesn't have a current location,
8:13
we'll return zero, and this value really depends on where you would want the
8:19
untagged notes to appear when you sort by distance.
8:24
If you want them to appear at the end of the list, you would want to return a large
8:29
number like infinity or the max value of the number class.
8:32
Or, if you wanted them to be at the top of the list, zero or a negative number
8:37
would also be a good case.
8:40
For right now, I'm just going to return zero.
8:43
So, let's save this out and see if it works.
8:45
So, if we refresh, let's hope we don't get any syntax errors, and we're good there,
8:49
and let's click the locate button.
8:53
Now, it's not sorting any differently, which can be a good thing,
8:57
but we don't quite know what these values are.
9:01
Now, one thing I want to do is I actually do want to show the values here.
9:04
I do want to show the values here, but, however, even if I do show the
9:08
values, I'm pretty sure that we're not going to get a resorting,
9:11
because they should actually all be the same.
9:15
All of the development that I've done on my computer has actually been done
9:19
on a desktop computer with its geolocation not moving
9:22
because the computer hasn't moved.
9:27
In fact, all of our notes should actually have the exact same latitude and longitude,
9:30
which becomes an interesting problem when you're working on a desktop computer
9:34
on an application that deals with geolocation.
9:38
If your ocation is not physically changing, you need to either work in
9:43
some debug code that will change the latitude and longitude values,
9:46
or you need to actually move around so it has to actually change
9:51
your latitude and longitude values.
9:54
What I prefer to do here is I prefer to add in some debug code that will actually
9:57
fuzz or move my latitude and longitude around every time I ask for it.
10:02
But, before I do that, let's go ahead and see if we can't get the current distance
10:07
displayed in each of our notes.
10:11
So, that's going to be something for the view, which is going to be in our
10:15
index.html in our list item here.
10:19
Here we have the title.
10:22
Since RA tag is getting a little more complex, let's just reformat it a little bit,
10:24
and let's put it in parantheses in the list,
10:30
and let's write note.distanceFromCurrent, I believe
10:42
was the name of our method.
10:49
Let's doublecheck, distanceFromCurrent,
10:51
and let's refresh.
10:57
All right, they're all showing up as zero, which could mean one of two things.
11:00
Either our safety case of returning zero is always being called,
11:02
or the current latitude and longitude are the same as each notes latitude and longitude,
11:06
which also should be the case.
11:11
So, let's go into application.js and change our escape value from zero to -1.
11:14
That way, notes without any information will show up as -1, and notes with any
11:20
information will show up as zero.
11:23
Right now, they're all -1.
11:27
If we locate, this is the only note without location, so we can see it's -1,
11:29
and everything else is showing a zero distance away, which is absolutely
11:34
true since it's all been done in the same room.
11:37
What we're going to do is rewrite our code with some debug information in it,
11:42
so that whenever we create new notes in a debug mode, it will change the
11:45
latitude and longitude ever so slightly so we get a little bit of variation in our notes.
11:49
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