I'm back and ready to continue this International Space
Station mapping project.
We've got the data from the Where the ISS.at API.
I'm able to also retrieve the latitude and longitude
and update to DOM span elements on the web page with that data.
Now, I want to plot the point of latitude and longitude
on a map.
And to do that, I'm going to use Leaflet.js.
Here's the Leaflet.js website.
And I'm going to go to, let's try,
I always like when there's a Quick Start Guide.
Let's go to the Quick Start Guide.
And this is the first thing we need.
So one thing that's interesting about Leaflet
is we need to add to our HTML file
a reference to the library.
We've seen this.
I did this with Chart.js, but Leaflet also
includes a CSS file, cascading style sheet file.
This is a file that has lots of styling information for the map
itself.
So I need both this CSS file.
I'm going to copy that.
I'm going to put it into my code in the header.
I don't know.
We'll put it here.
Maybe there's a place it's supposed to go.
Hit Save.
I also need this JavaScript reference,
but this needs to go after Leaflet's CSS.
That's very important.
And so that goes here.
Now, the other thing that I need,
which is right here on the page itself, is I need a div.
I need to create a DOM element where
the map is going to be placed.
So I can do this without copy pasting because I
know how to make a div.
I'll put this below.
I'll say div id equals, and I'll call it ISS map end div.
And if the code is in the wrong place,
I said I could do this without copy pasting.
There it is.
So now, I have my div.
But there's another important piece here,
which is that I need to make sure that the div has
a defined height.
If it doesn't have a defined height,
the map won't appear because it will assume the height is zero.
So this is actually some CSS.
I can't cover everything in this video series
as much as I might like to.
If you're unfamiliar with CSS, I will point you
to some resources in this video's description of where
you can learn more about CSS.
But this CSS is a way to define styling information
particular elements.
So this is styles for the map ID, which I'm calling ISS map.
So I'm going to go back here.
I'm going to add in the header a style tag.
So I could put some CSS here.
And then I'm going to say map ID height.
But I'm actually going to call this ISS map.
And there we go.
So now, I have both loaded the Leaflet.js library.
I have defined a div element where the map will go.
And I have given it a little bit of styling information so
that I know what the height is.
Let's go back to the web page.
Eh.
I don't see anything there yet.
Why not?
I need to specifically, with JavaScript,
create the map itself.
And I have a feeling if I go back to the Quick Start
Guide, which is right here, it's going to say,
now you're ready to initialize the map
and do some stuff with it.
So I'm going to do this.
I'm going to create a map object.
I'm going to copy this bit of code.
And I'm going to place it right here after--
actually, let's do this right at the beginning.
I'll do this first.
And I'm going to change this to const.
And this is going to be ISS map.
And let's leave the view stuff in here.
But let me just explain to you what these things are.
This is the latitude.
This is the longitude.
And this is the zoom level.
And those are the settings for what the map should
show when it first loads.
Let's see if this works.
I'm feeling we're going to run into an error.
There it is, sort of, kind of, not really.
There's a square there.
There's a zoom in, zoom out, even
says Leaflet at the bottom.
But I don't see any map.
This is because I haven't specified the tiles.
The tiles are the images of the map itself.
And the reason why they're called tiles is Leaflet,
and most mapping libraries work the same way,
they're very sophisticated.
And they can take any part of the map
that you want to show and load a bunch of tiles
simultaneously, tile them together, and show you
that map as you're zooming in out and moving around.
But I need to specify the tiles.
If I look back on the Getting Started Guide,
we can see like, oh, it's creating this tile layer
from this api.tiles.mapbox.com.
So I going actually use tiles from Open Street Map,
which is a Creative Commons repository of mapping tiles.
And I am required, if I use Open Street Map,
to use this attribution.
So I looked up what the attribution is required.
And it's this-- a copyright symbol, a link
to Open Street Map, and then saying
that the tiles are from Open Street Map contributors.
Once I have the attribution, I can
create a variable called tiles.
I say L for Leaflet.
By the way, I didn't even explain that here.
But capital L is available to me because I've
loaded the Leaflet library.
And all of the functions that I might
want to call associated with the Leaflet
library I call by saying L dot.
And in this case, I want to say L.tileLayer.
I'm going to give tileLayer two things.
It needs two things.
One is the URL of the tiles themselves.
And that is the thing that looks like this.
I'm going to say tileUrl equals this.
It's a little bit strange.
I'll come back to that in a second.
So I need to give it tile.url.
And then I also need to give it the attribution.
So I'm going to give it the attribution.
But I'm going to put curly brackets around it
because it's expecting it in the form of an object.
So I could have just made this an object,
but whatever, neither here nor there.
I have the attribution.
I have the tileUrl.
And now I can create the Leaflet tiles.
And then I just need to add those tiles to the map.
So I can say tiles.addTo my map.
So let's see if this works.
And I'll come back to these pieces in a second.
I'm going to go back to my web page.
And there it is.
And I can zoom all the way out.
And you can see I am able to see all the tiles of any zoom level
I want and move around the map.
OK.
So I've got the map there.
Great.
So couple things.
One is let me just change this to start with 0,0.
That's the initial latitude and longitude
of the center of what you're loading.
And this is the zoom level.
13 is zoomed quite a ways in.
I'm going to set this back to one,
which is basically no zoom.
Go back to the page.
And you can see, there we go.
It's starting off.
If I give myself a little bit more space,
there we'll see the map here.
Now, we should note that the Open Street Map tiles
use a Mercator projection.
The Earth itself is a sphere.
And so we're looking at it as a flat plane.
So we have to figure out, well, how do we take that sphere
and unwrap it onto a flat plane?
And there are a variety of different techniques
for doing this.
Many different kinds of projections.
The Mercator projection, which was created in 1569
by the Flemish geographer and cartographer Gerardus Mercator,
is commonly used.
But it is a bit problematic.
It has a kind of Western centric view of the world.
Greenland appears massive, while Africa appears quite small.
And it has to do with the way that the Earth was
being stretched along the poles as it's flattened out.
So this is something that I think
is important to be conscientious and thoughtful about as you're
deciding how you're presenting data in the mapping context.
But for this simple example, I'm going
to stick with what Open Street Map gives us to work with.
Other piece of this to come back to is this tileUrl.
So this is a little bit of a strange URL.
If I actually come and grab this URL
and try to paste it into a new tab in the browser,
it's not going to be able to do anything with that.
It's giving me some nice Google searches.
But this isn't an actual valid URL.
This is just the format of a URL for any given tile.
So if you want a particular tile at this X,Y location with this
zoom level with this particular style, the S for style,
the X and Y for latitude and longitude presumably and the Z
for zoom, it will give you that tile.
And you can start playing around with that
and loading tile images yourself.
But this is what Leaflet.js does all of that for us.
We just need to say, like, hey, use this convention
for loading your tiles from Open Street
Map with this particular attribution.
And now that we have the map and the latitude and longitude,
I need to put something on the map at a particular latitude
and longitude.
This is what's known as a marker.
So now, I need to create a Leaflet.js marker object.
To do that, I'm actually going to go, just
to show you the documentation of Leaflet.js,
I probably could have found this on the Getting Started page,
but I'm going to go and find a marker.
That's one of the UI layers.
There's pop-ups and tool tips.
I'm just going to go to Marker.
And this is giving me now information
of how to create a marker.
I need to create a marker at a given latitude and longitude.
And then there are some options.
So let's just do this L.marker with the latitude
and longitude, addTo map.
Oh, this is perfect.
So let's grab this.
Let's go back to our code.
I'm going to go here.
Wait, wait, wait, wait.
No, I'm going to go here.
I'm going to put this in here.
And I am going to say the actual latitude
and the actual longitude from the API itself.
And I'm going to add that to my map.
So here, this is bad.
Actually, let's do this.
I want to do this a different way.
Actually, this will work.
I'm going to put it through this way right now.
I need to refactor this and do this in a nicer way.
But let's just see if this works.
Now, I go back to my thing.
There we go.
That is actually right now where the International Space Station
is over the Earth.
And if I hit Refresh, you can see it moved ever so slightly.
But this is problematic because I
want to be able to update this location and do more with it.
So what I'm actually going to do is
I'm going to comment this out.
I'm going to take this bit of code.
And I going to do this right at the beginning.
I'm going to create a variable.
I'll call it Marker.
And I'm going to set it equal to the result of L.marker.
And I don't have latitude and longitude yet.
Add 0,0.
So now, you can see that the marker just starts at 0,0.
But even when I get the data, I could do something
like say marker set view.
Is that what it is?
setLatLong.
That makes sense.
setLatLong.
So I'm going to grab that function.
Not setView.
And there we go.
Go back to here.
And we can see, there we go.
The reason why I want to do that is I
want to always set to the new latitude and longitude
if and when I update the location of the International
Space Station.
Let's do one more thing to make this a little nicer looking.
We can actually customize what is
used as the icon for the marker itself.
I have here, this is a public domain image,
a little SVG file of the International Space Station
itself.
I can grab this image as a PNG file,
for example, at 200 pixels.
I just need a very small one, which I can see here.
And I can save this as part of my project.
And here it is in the folder where I'm working.
In addition to my index.html file,
I also have that image file as a PNG.
I'm going to click on it.
And you can see that Visual Studio Code will even kind
of render it for me here.
And then I can create a Leaflet icon object.
Here, I'm on the documentation page for the icon object.
I could read through what all the options are,
but I'm just going to grab this exact code right here.
I'm going to pull this into my code.
I'm going to copy paste it.
And I don't need most of this stuff.
But we can see what's the icon URL.
Well, this is my file now.
ISS200.
It's a 200 by approximately 120 pixel image.
I want to make it appear a bit smaller.
So I could actually give it a specific size here.
I happen to know that 50 by 32 is about right.
But this is really important--
I want the anchor to be in the center of it.
So that's where I want to position
the image itself, its center, on the actual latitude
and longitude.
So this is 25, 16.
And I don't need this shadowing and shadow stuff,
so I'll just get rid of that.
And now, I have an icon.
I can say ISS icon.
And then I should be able to add that to the marker.
So if I'm creating the marker here, right?
What's the next thing that I do?
I can actually give it a second argument.
In addition to the latitude and longitude,
I can give it that particular icon.
So I'm going to do this comma icon.
And it's my ISS icon.
And then we should see the International Space Station
as an icon on our page.
And there you are.
Now, instead of the default marker,
I now have the image of the space station itself.
I can kind of zoom in here.
You can see it's not changing its size based on where it is,
but that's fine with me.
And it's somewhere over Ohio right now.
All right.
Let's review and take a little bit of time
to reorganize our code a little bit because I think the tile
stuff would make sense here.
So first, we are making a map and tiles.
Then we are making a marker with an icon, custom icon.
So we're doing all of this stuff here as just Leaflet.js.
When the page loads, we create the map.
We add the tiles.
We add the icon.
We give it some default settings.
And then, only then, at the end here, we then
call getISS, which reaches out to the API, gets the data,
and updates the marker's location on the map and the DOM
elements for latitude and longitude.
So this is now mostly a finished project.
There's a lot more that you can do with it.
Maybe you want to design your own icon.
Maybe you want to try playing around with different settings,
like those shadow settings.
Maybe even you want to think about how
you're sizing that icon relative to the zoom level.
Is that a thing that you could?
That would be pretty tricky, but you might want to try it.
Maybe you want to represent some other stuff on the map.
I would also suggest that instead of using the default
marker object in a mapping library,
you could use something like p5.js, which
I use in a lot of videos on my channel,
to draw your own custom visualization on top
of the map.
And there's a particular library for p5 called Mappa.js that
allows you to do a lot of creative stuff
with drawing on top of a map.
I will refer you in the video's description
to some other video tutorials I have about Mappa.
And I will also include an example that goes along
with this with drawing my own custom International Space
Station thing on top of the map without using the Leaflet
marker.
So try your own style.
Try varying how it looks.
And what I'm going to do, I've got one more thing
I want to do here, which is that in order
for me to get a new location, I have got to refresh the page.
And actually, you know what would be good,
you should try this.
I'm going to add this in the next video too.
We might as well-- and this is going to change the whole way
the web page works, actually, which might be a little
tricky--
but why not set the location of the space station
to be the center of the map and a higher zoom level
for it to load with the ISS right there
in the center of the map?
So that might be something to try as well.
So try some of that stuff.
Come back.
And you'll see solutions in the next video
where I'll wrap up this project.
[MUSIC PLAYING]