Week 8 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.4.0/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.4.0/dist/leaflet.js"></script>
		 
		<!-- Load Firebase -->
		<script src="https://www.gstatic.com/firebasejs/4.6.1/firebase.js"></script>

		<!-- This is where we set the style for the different elements in the page's content -->
		<style>
		
			/* 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:  800px;
				height: 500px;
			}
			
		</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
			var map, myDb;
			
			/**
			 * Initialise the Map
			 */
			function initMap(){
			
				// before we do anything, lets initialise the database
				initDb();
			
				// this is a variable that holds the reference to the Leaflet map object
				map = L.map('map').setView([53.4807593, -2.2426305], 13);

				// 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 map click event			
				map.on('click', function(e) {
								
					// create a geojson point
					var geojson = L.marker(e.latlng).toGeoJSON();
					
					// push the data into the database, set inline callback
					myDb.push(geojson, function(error) {

						//if no error is returned to the callback, then it was loaded successfully
						if (!error) { 
							console.log("successfully added to firebase!");
				
						// otherwise pass the error to the console
						} else {
							console.error(error);
						}
					});
				});
			}
			
			
			/**
			 * Initialise the database into the global myDb variable
			 */
			function initDb() {
			
				// initialize Firebase (this is copied and pasted from your firebase console)
				var config = {
					/*
					 * YOU NEED TO UPDATE THIS OBJECT WITH YOUR OWN FIREBASE CREDENTIALS
					 */
				};
				firebase.initializeApp(config);

				// sign in anonymously - this helps stop your database being abused
				firebase.auth().signInAnonymously().catch(function(error) {
					console.log(error.code);
					console.log(error.message);
				});
		
				// create a global reference to your 'clicks' database
				myDb = firebase.database().ref().child('clicks');
				
				// listener for when a location is added to the database - add it to the map as well
				// this is called for everything in the database when the page loads, THEN for each new one
				myDb.on('child_added', function(snapshot) {

					// get the click location from firebase
					var newfeature = snapshot.val();

					// add the point to the map (remembering to flip the coordinates)
					var marker = L.marker(
						[ newfeature.geometry.coordinates[1], newfeature.geometry.coordinates[0] ], 
						{ draggable: true }
					).addTo(map);
 
 					// add a click listener to the array to delete markers
					marker.on('click', function(e) {
					
						// prevent the click event from being fired on the map as well
						L.DomEvent.stopPropagation;
    					
    					// prepare the data to update in the database (deleting is done by updating to null)
    					var updates = {};
    					updates['/clicks/' + snapshot.key] = null;
    					
    					// update the point location in the database and callback to console
    					firebase.database().ref().update(updates, function(error) {
							if (!error) {
							  console.log("successfully deleted point!");
							} else {
							  console.error(error);
							}
					  	});
					  	
					  	// remove the marker from the map
					  	e.target.remove();
  					});
  					
  					// add a drag end listener to the array to update location
					marker.on('dragend', function(e) {
    					
    					// prepare the data to update in the database
    					var updates = {};
    					updates['/clicks/' + snapshot.key] = e.target.toGeoJSON();
    					
    					// update the point location in the database and callback to console
    					firebase.database().ref().update(updates, function(error) {
							if (!error) {
							  console.log("successfully updated firebase!");
							} else {
							  console.error(error);
							}
					  	});
  					});
				});
			}
		</script>
	</body>
</html>