This version of the course is several years out of date and parts of it will not work - it is here just for the benefit of my 2022 dissertation students who want some grounding in Leaflet and associated technologies.

Week 3 Solution

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>GIS and the Web</title>

		<!-- Load the CSS and JavaScript for Leaflet -->
		<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
		<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>

		<!-- This loads a GeoJSON dataset of countries into a varable called countries -->
		<script src="http://geographicalinformation.science/maps/data/countries.js"></script>

		<!-- This is where we set the style for the different elements in the page's content -->
		<style>

			/* Set the font for the whole thing */
			body {
				font-family: Arial, sans-serif;
			}

			/* Avoid having a newline between the two divs */
			div {
				display:inline-block;
			}

			/* Style the map */
			#map {
				/* This is the dimensions of the map on the screen */
				width:  500px;
				height: 500px;
			}

			/* Style the legend */
			.legend {
				font-size: small;
				padding-top: 10px;
				text-align: left;
				line-height: 18px;
			}

			/* Style the i tags within the legend - we use these to make the coloured squares */
			.legend i {
				width: 18px;
				height: 18px;
				float: left;
				margin-right: 8px;
			}

		</style>
	</head>

	<!-- The onload event of the body tag is being used to call the function that creates the map.
	 This means that nothing will happen until the body is completely loaded, giving us a little more
	 control over the order in which the web page loads. -->
	<body onload='initMap()'>

		<!-- This is where the map will go -->
		<div id='map'></div>

		<!-- store the output div and the legend in a single div to help control the layout -->
		<div>

			<!-- This is where the output will go -->
			<div id='out'></div><br>

			<!-- Add the legend for the map -->
			<div class="legend">
				<i style="background:#FFEDA0"></i> 0 - 13,805,084 <br>
				<i style="background:#FED976"></i> 13,805,084 - 35,623,680 <br>
				<i style="background:#FEB24C"></i> 35,623,680 - 68,414,135 <br>
				<i style="background:#FD8D3C"></i> 68,414,135 - 105,350,020 <br>
				<i style="background:#FC4E2A"></i> 105,350,020 - 157,826,578 <br>
				<i style="background:#E31A1C"></i> 157,826,578 - 207,353,391 <br>
				<i style="background:#BD0026"></i> 207,353,391 - 1,281,935,911 <br>
				<i style="background:#800026"></i> 1,281,935,911 - 1,379,302,771
			</div>
		</div>

		<!-- Add JavaScript-->
		<script>

			//setup global variables
			let map, countriesLayer;

			/**
			 * Initialise the Map
			 */
			function initMap(){

				// this is a variable that holds the reference to the Leaflet map object
				// creates a world map (centre where the equator crosses the GPM)
				map = L.map('map').setView([0, 0], 1);

				// this adds the basemap tiles to the map
				L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
					attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
				}).addTo(map);

				// load the geojson data, style it, set events and add to map
				countriesLayer = L.geoJson(countries, {
					style: styleGenerator,		//set the style using your function
					onEachFeature: setEvents	//set the hover events using your function
				}).addTo(map);
			}


			/**
			 * This function styles the data (a single country)
			 */
			function styleGenerator(feature) {

				//return a style
				return {
					weight: 0.5,
					color: '#666',
					fillOpacity: 1,
					fillColor: getColour(feature.properties.POP_EST)	//the colour is set using a function
				};
			}


			/**
			 * Return a colour based upon the given population value
			 */
			function getColour(population) {

				//create a variable to hold the colour
				let colour;

				//assign a colour based upon the population value
				if (population > 1281935911){
					colour = '#800026';
				} else if (population > 207353391) {
					colour = '#BD0026';
				} else if (population > 157826578) {
					colour = '#E31A1C';
				} else if (population > 105350020) {
					colour = '#FC4E2A';
				} else if (population > 68414135) {
					colour = '#FD8D3C';
				} else if (population > 35623680) {
					colour = '#FEB24C';
				} else if (population > 13805084) {
					colour = '#FED976';
				} else {	//this is for if the population is <=1000
					colour = '#FFEDA0';
				}

				//return the resulting colour
				return colour;
			}


			/**
			 * Create a function to tie the mouseover and mouseout events to re-styling the layer
			 */
			function setEvents(feature, layer) {
				layer.on({
					mouseover: highlightFeature,
					mouseout: resetFeature,
				});
			}


			/**
			 * This function re-styles the data to yellow (for when you hover over it)
			 */
			function highlightFeature(e) {
				// e refers to the event object

				// e.target is the country that was hovered over
				const feature = e.target;

				// set the style to yellow
				feature.setStyle({
					color: 'yellow',
					fillColor: 'yellow',
				});

				// update the population info box
				document.getElementById('out').innerHTML =
					feature.feature.properties.NAME +
					"</b><br>Population: " +
					parseFloat(feature.feature.properties.POP_EST).toLocaleString('en-GB');
			}


			/**
			 * Reset the style after the hover is over
			 */
			function resetFeature(e) {

				// e.target is the country that was hovered over
				const feature = e.target;

				// reset the style of the country that was yellow
				countriesLayer.resetStyle(feature);

				// clear the population info box
				document.getElementById('out').innerHTML = "";
			}
		</script>
	</body>
</html>

This course has not yet begun.
Course material will appear here week by week as the course progresses.