Web App
Find parking.
www.parkingrabbit-bf78a.web.app
Written in HTML, CSS, and JavaScript
www.parkingrabbit-bf78a.web.app
Written in HTML, CSS, and JavaScript
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"> <style> /* Always set the map height explicitly to define the size of the div * element that contains the map. */ #map { height: 100%; } /* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #pac-input { background-color: #fff; font-family: Roboto; font-size: 20px; font-weight: 300; margin-left: 12px; margin-top: 12px; padding: 0 11px 0 40px; text-overflow: ellipsis; width: 300px; height: 40px; border-color: Green; border-radius: 10px; background-image: url('https://img.icons8.com/android/24/000000/search.png'); background-position: 10px 10px; background-repeat: no-repeat; } #pac-input:focus { border-color: #4d90fe; } #clearmap { /* font-family: Roboto; */ margin-left: -347px; margin-top: 80px; width: 120px; height: 40px; } #cl { /* font-family: Roboto; */ margin-left: -120px; margin-top: 130px; width: 120px; height: 60px; } #myBtn { /* font-family: Roboto; */ margin-left: -120px; margin-top: 200px; width: 120px; height: 70px; } /* .button { */ /* background-color: #4CAF50; Green */ /* border: none; color: Green; */ /* padding: 15px 32px; */ /* text-align: center; text-decoration: none; display: inline-block; font-size: 16px; */ /* } */ /* The Modal (background) */ .modal { display: none; /* Hidden by default */ position: absolute;; /* Stay in place */ z-index: 100000; /* Sit on top */ left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0,0,0); /* Fallback color */ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ } /* Modal Content/Box */ .modal-content { background-color: #fefefe; margin: 15% auto; /* 15% from the top and centered */ padding: 20px; border: 1px solid #888; width: 80%; /* Could be more or less, depending on screen size */ } /* The Close Button */ .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; } .close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; } .modal-backdrop { z-index: -1; } </style> </head> <body> <div><input id="pac-input" class="controls" type="text" placeholder="Search...."></div> <div id="map"></div> <div id="pano"></div> <!-- <div><button class="button" onClick="clearMap()" id="clearmap" >Clear results</button><br><button class="button" onClick="currentLoc()" id="cl" >Current Location</button></div> --> <!-- <button id="myBtn">Open Modal</button> --> <!-- The Modal --> <!-- <div id="myModal" class="modal" data-backdrop="false"> --> <!-- Modal content --> <!-- <div class="modal-content"> <span class="close">×</span> <p>Double tap on the map to add parking. Tap on the marker to add details.</p> </div> </div> --> <script src="https://www.gstatic.com/firebasejs/7.7.0/firebase-auth.js"></script> <script src="https://www.gstatic.com/firebasejs/7.7.0/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/7.7.0/firebase-database.js"></script> <script src="https://maps.googleapis.com/maps/api/js?libraries=visualization"></script> <!--<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA5NyVcYFqK_R7PzuUpIRR-unD5fDLyjlI&libraries=places"></script> --> <script> /** * Firebase config block. */ // Your web app's Firebase configuration var firebaseConfig = { apiKey: "AIzaSyDQ62BC1Gcg-tJJgl7rkqxuDO8x7cSP_08", authDomain: "parkingrabbit-bf78a.firebaseapp.com", databaseURL: "https://parkingrabbit-bf78a.firebaseio.com", projectId: "parkingrabbit-bf78a", storageBucket: "parkingrabbit-bf78a.appspot.com", messagingSenderId: "94492827210", appId: "1:94492827210:web:43ef5ed366dac05eb2d0b3" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); /** * Data object to be written to Firebase. */ var data = {sender: null, timestamp: null, lat: null, lng: null}; var infoWindow; var iw, m; var prev_infowindow = false; var markers = []; var tempMarkers = []; var markerCluster; var icon = { url: "https://img.icons8.com/doodle/48/000000/car--v1.png", // url scaledSize: new google.maps.Size(50, 50), // scaled size origin: new google.maps.Point(0,0), // origin anchor: new google.maps.Point(25,25) // anchor }; var iconSet = { url: "https://img.icons8.com/flat_round/64/000000/plus.png", // url scaledSize: new google.maps.Size(50, 50), // scaled size origin: new google.maps.Point(0,0), // origin anchor: new google.maps.Point(25,25) // anchor }; var mStyles = {styles: [{ height: 53, url: "https://library.kissclipart.com/20180901/hlq/kissclipart-icona-onde-radio-clipart-computer-icons-radio-wave-82fca435d36a0a09.jpg", width: 53 }]}; var map; var onMap = false; var placeMarkers = []; var current; var modal = document.getElementById("myModal"); var span = document.getElementsByClassName("close")[0]; var btn = document.getElementById("myBtn"); //When the user clicks on the button, open the modal btn.onclick = function() { modal.style.display = "block"; } // When the user clicks on <span> (x), close the modal span.onclick = function() { modal.style.display = "none"; } // When the user clicks anywhere outside of the modal, close it window.onclick = function(event) { if (event.target == modal) { modal.style.display = "none"; } } function currentLoc() { // Try HTML5 geolocation. if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { var pos = { lat: position.coords.latitude, lng: position.coords.longitude }; map.setCenter(pos); current = new google.maps.Marker({position: pos,map: map}); current.addListener('click', function() { current.infowindow = new google.maps.InfoWindow({content: "You are here."}); if (prev_infowindow) { prev_infowindow.close(); } prev_infowindow = current.infowindow; current.infowindow.open(map, current); }); }, function() { handleLocationError(true, infoWindow, map.getCenter()); }); } else { // Browser doesn't support Geolocation handleLocationError(false, infoWindow, map.getCenter()); } } function clearMap() { tempMarkers.forEach(function(marker) { marker.setMap(null); }); deleteMarker(); placeMarkers.forEach(function(marker) { marker.setMap(null); }); } function makeInfoBox(controlDiv, map) { // Set CSS for the control border. var controlUI = document.createElement('div'); controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px'; controlUI.style.backgroundColor = '#fff'; controlUI.style.border = '2px solid #fff'; controlUI.style.borderRadius = '2px'; controlUI.style.marginBottom = '22px'; controlUI.style.marginTop = '10px'; controlUI.style.textAlign = 'center'; controlDiv.appendChild(controlUI); // Set CSS for the control interior. var controlText = document.createElement('div'); controlText.style.color = 'rgb(25,25,25)'; controlText.style.fontFamily = 'Roboto,Arial,sans-serif'; controlText.style.fontSize = '150%'; controlText.style.padding = '6px'; controlText.textContent = 'Double tap on the map to add parking.' + '\n' + 'Tap on the marker to add details.'; controlUI.appendChild(controlText); } /** * Starting point for running the program. Authenticates the user. * @param {function()} onAuthSuccess - Called when authentication succeeds. */ function initAuthentication(onAuthSuccess) { firebase.auth().signInAnonymously().catch(function(error) { console.log(error.code + ', ' + error.message); }, {remember: 'sessionOnly'}); firebase.auth().onAuthStateChanged(function(user) { if (user) { data.sender = user.uid; onAuthSuccess(); } else { // User is signed out. } }); } function openWin() { window.open("form2.html", "_self"); // window.open("form2.html",'popUpWindow', 'height=500,width=500,left=100,top=100,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no, status=yes'); } function streetView() { var panorama; panorama = new google.maps.StreetViewPanorama( document.getElementById('map'), { position: new google.maps.LatLng(sessionStorage.lat, sessionStorage.lng), pov: {heading: 165, pitch: 0}, zoom: 1 }); } function deleteMarker() { for (var idx = 0; idx < tempMarkers.length; idx++) { tempMarkers[idx].setMap(null); } onMap = false; } /** * Creates a map object with a click listener and a heatmap. */ function initMap() { var clicks = firebase.database().ref('register'); clicks.on("child_added", function(snapshot) { var newPosition = snapshot.val(); // var latLng = new google.maps.LatLng(snapshot.val().lat,snapshot.val().lng); // var marker = new google.maps.Marker({position: latLng, map: map, icon: icon}); if ((Date.now() - newPosition.timestamp) > 86400000) { snapshot.ref.remove(); var latLng = new google.maps.LatLng(snapshot.val().lat,snapshot.val().lng); markers.forEach((item, i) => { if (markers[i].position == latLng) { markers[i] = null; } }); } else { var latLng = new google.maps.LatLng(snapshot.val().lat,snapshot.val().lng); var marker = new google.maps.Marker({position: latLng, map: map, icon: icon}); marker.infowindow = new google.maps.InfoWindow({content: ""}); marker.infowindow.setContent(/*"Name: " + newPosition.name + */"Phone number: " + newPosition.phone + "<br>Parking cost for 1 hr: $" + newPosition.cost + "<br>" + '<style>.wrapper {text-align: center;}</style><br><div class="wrapper"><input type="button" value="Street View" onclick="streetView()"></div>'); //+ "<br>Allowed vehicles: " + "<br>Bicycles: " + newPosition.bi + "<br>Motorcycles: " + newPosition.mc + "<br>Cars: " + newPosition.ca + "<br>Pickup trucks: " + newPosition.pt + "<br>Trucks: " + newPosition.tr + "<br>Boats: " + newPosition.bo); marker.addListener('click', function() { if (prev_infowindow) { prev_infowindow.close(); } sessionStorage.lat = marker.getPosition().lat(); sessionStorage.lng = marker.getPosition().lng(); prev_infowindow = marker.infowindow; marker.infowindow.open(map, marker); }); // marker.addListener('click', function() { // marker.infowindow = new google.maps.InfoWindow({content: ""}); // if (prev_infowindow) { // prev_infowindow.close() // } // var register = firebase.database().ref('register'); // register.once('value').then(function(snapshot) { // var user = snapshot.val(); // if (user.lat == newPosition.lat && user.lng == newPosition.lng) { // marker.infowindow.setContent(user); // } // }); // prev_infowindow = marker.infowindow; // marker.infowindow.open(map, marker); // }); markers.push(marker); } }); map = new google.maps.Map(document.getElementById('map'), { center: {lat: -33.8688, lng: 151.2093}, zoom: 13, styles: [{ featureType: 'poi', stylers: [{ visibility: 'off' }] // Turn off POI. }, { featureType: 'transit.station', stylers: [{ visibility: 'off' }] // Turn off bus, train stations etc. }], disableDoubleClickZoom: true, streetViewControl: true, mapTypeControl: false, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain'], position: google.maps.ControlPosition.LEFT_BOTTOM } }); // Try HTML5 geolocation. if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { var pos = { lat: position.coords.latitude, lng: position.coords.longitude }; map.setCenter(pos); current = new google.maps.Marker({position: pos,map: map}); current.addListener('click', function() { current.infowindow = new google.maps.InfoWindow({content: "You are here."}); if (prev_infowindow) { prev_infowindow.close(); } prev_infowindow = current.infowindow; current.infowindow.open(map, current); }); }, function() { handleLocationError(true, infoWindow, map.getCenter()); }); } else { // Browser doesn't support Geolocation handleLocationError(false, infoWindow, map.getCenter()); } var input = document.getElementById('pac-input'); var clear = document.getElementById('clearmap'); var cl = document.getElementById('cl'); var bt = document.getElementById('myBtn'); var searchBox = new google.maps.places.SearchBox(input); map.controls[google.maps.ControlPosition.TOP_LEFT].push(input); map.controls[google.maps.ControlPosition.TOP_LEFT].push(clear); map.controls[google.maps.ControlPosition.TOP_LEFT].push(cl); map.controls[google.maps.ControlPosition.TOP_LEFT].push(bt); map.addListener('bounds_changed', function() { searchBox.setBounds(map.getBounds()); }); searchBox.addListener('places_changed', function() { var places = searchBox.getPlaces(); if (places.length == 0) { return; } // Clear out the old markers. placeMarkers.forEach(function(marker) { marker.setMap(null); }); var bounds = new google.maps.LatLngBounds(); places.forEach(function(place) { if (!place.geometry) { console.log("Returned place contains no geometry"); return; } var icon2 = { url: place.icon, //size: new google.maps.Size(71, 71), origin: new google.maps.Point(0, 0), anchor: new google.maps.Point(12.5, 12.5), scaledSize: new google.maps.Size(25, 25) }; var request = { placeId: place.place_id, fields: ['name', 'formatted_address', 'place_id', 'geometry'] }; iw = new google.maps.InfoWindow(); var service = new google.maps.places.PlacesService(map); m = new google.maps.Marker({ map: map, icon: icon2, title: place.name, position: place.geometry.location }); // Create a marker for each place. placeMarkers.push(m); google.maps.event.addListener(m, 'click', function() { iw.setContent('<div><strong>' + place.name + '</strong><br>' + 'Hours: ' + place.opening_hours + '<br>' + place.formatted_address + '</div>'); iw.open(map, this); }); if (place.geometry.viewport) { // Only geocodes have viewport. bounds.union(place.geometry.viewport); } else { bounds.extend(place.geometry.location); } }); map.fitBounds(bounds); }); // Create the DIV to hold the control and call the makeInfoBox() constructor // passing in this DIV. var infoBoxDiv = document.createElement('div'); makeInfoBox(infoBoxDiv, map); map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(infoBoxDiv); // Listen for clicks and add the location of the click to firebase. map.addListener('dblclick', function(e) { if (!onMap) { data.lat = e.latLng.lat(); data.lng = e.latLng.lng(); var latLng = new google.maps.LatLng(data.lat,data.lng); var marker = new google.maps.Marker({map: map, position: latLng, icon: iconSet, draggable: true}); onMap = true; sessionStorage.lat = data.lat; sessionStorage.lng = data.lng; google.maps.event.addListener(marker, 'dragend', function(evt){ sessionStorage.lat = evt.latLng.lat(); sessionStorage.lng = evt.latLng.lng(); }); tempMarkers.push(marker); addToFirebase(data); marker.addListener('click', function() { // marker.infowindow = new google.maps.InfoWindow("form2.html"); marker.infowindow = new google.maps.InfoWindow({content: '<style>.wrapper {text-align: center;}</style><form><div><input type="button" value="Register" onclick="openWin()"></div><br><div class="wrapper"><input type="button" value="Delete" onclick="deleteMarker()"></div></form>'}); if (prev_infowindow) { prev_infowindow.close(); } prev_infowindow = marker.infowindow; marker.infowindow.open(map, marker); }); } }); markerCluster = new MarkerClusterer(map, markers, mStyles); // Create a heatmap. var heatmap = new google.maps.visualization.HeatmapLayer({ data: [], map: map, radius: 16 }); initFirebase(map); /** initAuthentication(initFirebase.bind(undefined, heatmap)); */ } function handleLocationError(browserHasGeolocation, infoWindow, pos) { infoWindow.setPosition(pos); infoWindow.setContent(browserHasGeolocation ? 'Error: The Geolocation service failed.' : 'Error: Your browser doesn\'t support geolocation.'); infoWindow.open(map); } /** * Set up a Firebase with deletion on clicks older than expiryMs * @param {!google.maps.visualization.HeatmapLayer} heatmap The heatmap to */ function initFirebase(map) { // 10 minutes before current time. var startTime = new Date().getTime() - (60 * 10 * 1000); // Reference to the clicks in Firebase. var clicks = firebase.database().ref('clicks'); // Listen for clicks and add them to the heatmap. clicks.orderByChild('timestamp').startAt(startTime).on('child_added', function(snapshot) { // Get that click from firebase. var newPosition = snapshot.val(); var point = new google.maps.LatLng(newPosition.lat, newPosition.lng); var elapsedMs = Date.now() - newPosition.timestamp; // Add the point to the heatmap. heatmap.getData().push(point); // Request entries older than expiry time (10 minutes). var expiryMs = Math.max(60 * 10 * 1000 - elapsedMs, 0); // Set client timeout to remove the point after a certain time. window.setTimeout(function() { // Delete the old point from the database. snapshot.ref.remove(); }, expiryMs); } ); // Remove old data from the heatmap when a point is removed from firebase. clicks.on('child_removed', function(snapshot, prevChildKey) { var heatmapData = heatmap.getData(); var i = 0; while (snapshot.val().lat != heatmapData.getAt(i).lat() || snapshot.val().lng != heatmapData.getAt(i).lng()) { i++; } heatmapData.removeAt(i); }); } /** * Updates the last_message/ path with the current timestamp. * @param {function(Date)} addClick After the last message timestamp has been updated, * this function is called with the current timestamp to add the * click to the firebase. */ function getTimestamp(addClick) { // Reference to location for saving the last click time. var ref = firebase.database().ref('last_message/' + data.sender); ref.onDisconnect().remove(); // Delete reference from firebase on disconnect. // Set value to timestamp. ref.set(firebase.database.ServerValue.TIMESTAMP, function(err) { if (err) { // Write to last message was unsuccessful. console.log(err); } else { // Write to last message was successful. ref.once('value', function(snap) { addClick(snap.val()); // Add click with same timestamp. }, function(err) { console.warn(err); }); } }); } /** * Adds a click to firebase. * @param {Object} data The data to be added to firebase. * It contains the lat, lng, sender and timestamp. */ function addToFirebase(data) { getTimestamp(function(timestamp) { // Add the new timestamp to the record data. data.timestamp = timestamp; var ref = firebase.database().ref('clicks').push(data, function(err) { if (err) { // Data was not written to firebase. console.warn(err); } }); }); } </script> <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA5NyVcYFqK_R7PzuUpIRR-unD5fDLyjlI&libraries=visualization&callback=initMap"> </script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA5NyVcYFqK_R7PzuUpIRR-unD5fDLyjlI&libraries=places&callback=initMap" async defer> </script> </body> </html>
Comments
Post a Comment