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.4.0/dist/leaflet.css"/>
		<script src="https://unpkg.com/leaflet@1.4.0/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>
					
			/* 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 info box so that it looks like a Leaflet control */
			.info { 
				font-family: Arial, sans-serif;
				padding: 6px 8px; 
				background: white; 
				background: rgba(255,255,255,0.8); 
				box-shadow: 0 0 15px rgba(0,0,0,0.2); 
				border-radius: 5px; 
			} 
			
			/* Style the legend */
			.legend { 
				font-family: Arial, sans-serif;
				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>
		
		<!-- 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>
		
		<!-- Add JavaScript-->
		<script>		
			
			//setup global variables
			var map, geojson, info;
			
			/**
			 * 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);
			
				// add the info box to the map
				addInfoBox();

				// load the geojson data, style it, set events and add to map
				geojson = L.geoJson(countries, {
					style: style,				//set the style using your function
					onEachFeature: setEvents	//set the hover events using your function
				}).addTo(map);
			}
			
			
			/**
			 * Create the info box in the top right corner of the map
			 */
			function addInfoBox(){
			
				// create a Leaflet control (generic term for anything you add to the map)
				info = L.control();

				//create the info box to update with population figures on hover
				info.onAdd = function (map) {
					this._div = L.DomUtil.create('div', 'info');
					this.update();
					return this._div;
				};

				//create a function called update() that updates the contents
				info.update = function (props) {
					
					//if properties have been passed, then use them to fill in the info box
					if (props){
						this._div.innerHTML = '<b>' + props.NAME + '</b><br />' + parseFloat(props.POP_EST).toLocaleString('en');
					
					//otherwise, just set to a message
					} else {
						this._div.innerHTML = 'Hover over a country';
					}
				};

				// add the info window to the map
				info.addTo(map);
			}
			
			
			/**
			 * This function styles the data (a single country)
			 */
			function style(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
				var 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: resetHighlight,
				});
			}
			

			/**
			 * 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
				var layer = e.target;

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

				//update the info box
				info.update(layer.feature.properties);
			}
			

			/**
			 * Reset the style after the hover is over
			 */
			function resetHighlight(e) {
				// e refers to the event object
				
				//reset the style of the country that was yellow
				geojson.resetStyle(e.target);	// e.target is the country that was hovered over
				
				//update the info box
				info.update();
			}
		</script>
	</body>
</html>