Week 2 Solution

<!DOCTYPE html>
<html>
	<head>
		<!-- This is the HEAD of the HTML file, things in here do not appear on the page. It is
		 used for settings, such as the language and page title, as well as loading CSS styles and
		 scripts that you want to load before the content of the page. -->
		<meta charset="UTF-8">
		<title>GIS and the Web</title>

		<!-- This is loading the stylesheet for the Leaflet map from their website.
		 Make sure you put this BEFORE Leaflet's JavaScript -->
 		<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />

		<!-- This is loading the Leaflet JavaScript library from their website
		 Make sure you put this AFTER Leaflet's CSS -->
		<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>

		<!-- Load the Proj4js library -->
		<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>

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

			/* Set the font for the entire page */
			html, body {
				padding: 0;
				margin: 0;
				width: 100%;
				height: 100%;
			}

			/* Style the map */
			#map {
				/* This is the dimensions of the map on the screen, you can set it in
				 px (pixels) or % of the total screen size*/
				width:  100%;
				height: 100%;
			}

		</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>

		<!-- This is where we put our JavaScript, note that it is below the div, as the div needs
		 to exist before we can put a map in it!-->
		<script>

			//setup global variables
			let map, transformer, marker;

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

				// set the centre of the map as a variable
				const mapCentre = L.latLng(55, -4);

				// this is a variable that holds the reference to the Leaflet map object
				map = L.map('map').setView(mapCentre, 6);

				// 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);

				// set the proj4 string for the WGS84 CRS
				// http://spatialreference.org/ref/epsg/wgs-84/proj4/
				const wgs84 = "+proj=longlat +datum=WGS84 +no_defs";

				// set the proj4 string for the OSGB CRS
				// http://spatialreference.org/ref/epsg/osgb-1936-british-national-grid/proj4/
				const osgb = "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs";

				// build a proj4 object to handle forward and inverse transformations
				transformer = proj4(wgs84, osgb);

				// add a marker at the centre of the map
				addMarker(mapCentre);

				// add listener for click event on the map
				map.on('click', onMapClick);

			}

			/**
			 * Event handler for map click
			 */
			function onMapClick(e) {

				// remove the previous marker from the map
				map.removeLayer(marker);

				//add the new marker
				addMarker(e.latlng);
			}

			/**
			 * Add a marker with popup displaying the OSGB coordinates at a given location
			 */
			function addMarker(latLng) {

				// transform coordinates to OSGB
				const xy = transformer.forward([latLng.lng, latLng.lat]);

				// create a marker at the clicked location
				marker = L.marker(latLng);

				// add the marker to the map
				marker.addTo(map);

				// create a popup displaying OSGB coordinates
				const popup = marker.bindPopup(parseInt(xy[0]).toString() + ", " + parseInt(xy[1]).toString());

				// open the popup
				popup.openPopup();
			}

		</script>
	</body>
</html>