Web App

Find parking.

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">&times;</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

Popular Posts