Show Map on the Page
In order to visualize the locations of the images in our geotag album, we need to show it on a map. In this part, we are going to use a free and open source library called leaflet
.
From its website, "leaflet is an open-source JavaScript library for mobile-friendly interactive maps".
What to Show on the Map
From the previous lesson, we've shown how to pass data from python backend to our html template. In this lesson, we are going to use that passed data to show the image and a marker on the map showing the location of the image.
Installation of leaflet
First, let's include the css and javascript files of the leaflet
library into our html. We are not going to download the files, instead, we are directly linking to it.
In our html file, inside our head
tag
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello</title>
</head>
let's add the highlighted codes below:
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""
/>
<script
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""
></script>
<title>Hello</title>
</head>
And then inside our body
tag, we add a div with an id "map".
<body>
<div id="map""></div>
<table>
<tr>
<td>Name</td>
<td>{{ name }}</td>
...
</body>
Setting up css and javascript
Now in order for the map to work and be shown, we need the following:
- Placeholder of the map (our html)
- css to set the size of the map, and
- javascript to setup the map, its location and contents
First is the placeholder where we will put our map. This will be our html file where we put our div
with an id of "map".
Next is css. We will put our css in a separate file then include it in our html file.
CSS
In the root of our project, create a folder named "static". In there, we will create a file called styles.css
.
├── geotag-album
│ ├── venv
| ├── static
| | ├── styles.css
│ ├── templates
│ | ├── hello.html
│ ├
and inside it, put the code
#map {
height: 250px;
}
Then we'll include it in our html file, under the head tag.
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/static/styles.css" />
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""
/>
<script
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""
></script>
<title>Hello</title>
</head>
The minimum requirement for the style of the map is the height and that is what we set in our css code by the targeting the element with id of "map".
javascript
Next up is our javascript. In our code, we can just put it inside our body tag just like this
<script>
var map = L.map("map").setView([51.504105, -0.074575], 13);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
</script>
</body>
Just before the closing body tag.
On line 2 above, we declared a map
variable to hold reference to our map. This targets the element with the id of "map" in our html file. It also sets the center of the map and the current zoom level at 13.
Then on line 3-7, we setup the map by setting it's map tile to use and the maximum zoom level that it can be zoomed using the zoom tools.
Use the Data
Now you may have noticed that on line 2 above, we have set the data manually for latitude and longitude (the location of the image). We will replace that with the data we got from our backend.
Just rewrite the code above like this
<script>
var map = L.map("map").setView([{{ latitude }}, {{ longitude }}], 13);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
</script>
Notice that we have used the variables for latitude
and longitude
like in our html template.
Add Markker for the Image
Now that we have centered the map to the location of our image, we will now display a marker on our map to represent the image location.
To add a marker using leaflet
, we do it like this
var marker = L.marker([51.5, -0.09]).addTo(map);
where 51.5
and -0.09
are latitude and longitude. Let's incorporate it now to our code.
<script>
var map = L.map("map").setView([{{ latitude }}, {{ longitude }}], 13);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
var marker = L.marker([{{ latitude }}, {{ longitude }}]).addTo(map);
</script>
Our web page should now look like this so far.
![Preview map with marker](/assets/01-preview-map-BFFRg30T.png)
We have our map at the top portion of the page and a blue marker representing the location of our image.
Now for the last touch for this lesson, let's show the image using the image tag and the url
variable passed by our backend.
<img src="{{ url }}" alt="{{ name }}" />
Now that we are showing the image location on our map, it might be appropriate to remove the display for the latitude and longitude in the page. In addition, let's also remove the url of our image since we are already showing the actual image.
The revised html code for our app should now be this.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/static/styles.css">
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""
/>
<script
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""
></script>
<title>Hello</title>
</head>
<body>
<div id="map""></div>
<img src="{{ url }}" alt="{{ name }}">
<table>
<tr>
<td>Name</td>
<td>{{ name }}</td>
</tr>
</table>
<script>
var map = L.map("map").setView([{{ latitude }}, {{ longitude }}], 13);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
var marker = L.marker([{{ latitude }}, {{ longitude }}]).addTo(map);
</script>
</body>
</html>
And when we preview our app, it should look like this now.
![Remove other info](/assets/02-remove-other-info-Bx_inGyX.png)
Conclusion
So that's it for this lesson! See you on the next one where we will load multiple images and we'll deal with loops in both our html template and javascript code!