diff --git a/assets/javascript/geofire.min.js b/assets/javascript/geofire.min.js new file mode 100644 index 0000000..c08b8e2 --- /dev/null +++ b/assets/javascript/geofire.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).geofire={})}(this,function(e){"use strict";var t=function(){function e(e){if(this._cancelCallback=e,"[object Function]"!==Object.prototype.toString.call(this._cancelCallback))throw new Error("callback must be a function")}return e.prototype.cancel=function(){void 0!==this._cancelCallback&&(this._cancelCallback(),this._cancelCallback=void 0)},e}(),l=10,f="0123456789bcdefghjkmnpqrstuvwxyz",h=40007860,_=110574,y=5,u=22*y,i=6378137,a=.00669447819799,o=1e-12;function d(e){return Math.log(e)/Math.log(2)}function s(e){var t;if("string"!=typeof e?t="key must be a string":0===e.length?t="key cannot be the empty string":755<1+l+e.length?t="key is too long to be stored in Firebase":/[\[\].#$\/\u0000-\u001F\u007F]/.test(e)&&(t="key cannot contain any of the following characters: . # $ ] [ /"),void 0!==t)throw new Error("Invalid GeoFire key '"+e+"': "+t)}function v(e){var t;if(Array.isArray(e))if(2!==e.length)t="expected array of length 2, got length "+e.length;else{var r=e[0],n=e[1];"number"!=typeof r||isNaN(r)?t="latitude must be a number":r<-90||90>o<=i[0]&&e<=i[1])return!0}}return!1},e.prototype._geohashQueryReadyCallback=function(e){var t=this._outstandingGeohashReadyEvents.indexOf(e);-1= lonMid) { + idx = idx*2 + 1; + lonMin = lonMid; + } else { + idx = idx*2; + lonMax = lonMid; + } + } else { + // bisect N-S latitude + var latMid = (latMin + latMax) / 2; + if (lat >= latMid) { + idx = idx*2 + 1; + latMin = latMid; + } else { + idx = idx*2; + latMax = latMid; + } + } + evenBit = !evenBit; + + if (++bit == 5) { + // 5 bits gives us a character: append it and start over + geohash += Geohash.base32.charAt(idx); + bit = 0; + idx = 0; + } + } + + return geohash; +}; + + +/** + * Decode geohash to latitude/longitude (location is approximate centre of geohash cell, + * to reasonable precision). + * + * @param {string} geohash - Geohash string to be converted to latitude/longitude. + * @returns {{lat:number, lon:number}} (Center of) geohashed location. + * @throws Invalid geohash. + * + * @example + * var latlon = Geohash.decode('u120fxw'); // latlon: { lat: 52.205, lon: 0.1188 } + */ +Geohash.decode = function(geohash) { + + var bounds = Geohash.bounds(geohash); // <-- the hard work + // now just determine the centre of the cell... + + var latMin = bounds.sw.lat, lonMin = bounds.sw.lon; + var latMax = bounds.ne.lat, lonMax = bounds.ne.lon; + + // cell centre + var lat = (latMin + latMax)/2; + var lon = (lonMin + lonMax)/2; + + // round to close to centre without excessive precision: ⌊2-log10(Δ°)⌋ decimal places + lat = lat.toFixed(Math.floor(2-Math.log(latMax-latMin)/Math.LN10)); + lon = lon.toFixed(Math.floor(2-Math.log(lonMax-lonMin)/Math.LN10)); + + return { lat: Number(lat), lon: Number(lon) }; +}; + + +/** + * Returns SW/NE latitude/longitude bounds of specified geohash. + * + * @param {string} geohash - Cell that bounds are required of. + * @returns {{sw: {lat: number, lon: number}, ne: {lat: number, lon: number}}} + * @throws Invalid geohash. + */ +Geohash.bounds = function(geohash) { + if (geohash.length === 0) throw new Error('Invalid geohash'); + + geohash = geohash.toLowerCase(); + + var evenBit = true; + var latMin = -90, latMax = 90; + var lonMin = -180, lonMax = 180; + + for (var i=0; i=0; n--) { + var bitN = idx >> n & 1; + if (evenBit) { + // longitude + var lonMid = (lonMin+lonMax) / 2; + if (bitN == 1) { + lonMin = lonMid; + } else { + lonMax = lonMid; + } + } else { + // latitude + var latMid = (latMin+latMax) / 2; + if (bitN == 1) { + latMin = latMid; + } else { + latMax = latMid; + } + } + evenBit = !evenBit; + } + } + + var bounds = { + sw: { lat: latMin, lon: lonMin }, + ne: { lat: latMax, lon: lonMax }, + }; + + return bounds; +}; + + +/** + * Determines adjacent cell in given direction. + * + * @param geohash - Cell to which adjacent cell is required. + * @param direction - Direction from geohash (N/S/E/W). + * @returns {string} Geocode of adjacent cell. + * @throws Invalid geohash. + */ +Geohash.adjacent = function(geohash, direction) { + // based on github.com/davetroy/geohash-js + + geohash = geohash.toLowerCase(); + direction = direction.toLowerCase(); + + if (geohash.length === 0) throw new Error('Invalid geohash'); + if ('nsew'.indexOf(direction) == -1) throw new Error('Invalid direction'); + + var neighbour = { + n: [ 'p0r21436x8zb9dcf5h7kjnmqesgutwvy', 'bc01fg45238967deuvhjyznpkmstqrwx' ], + s: [ '14365h7k9dcfesgujnmqp0r2twvyx8zb', '238967debc01fg45kmstqrwxuvhjyznp' ], + e: [ 'bc01fg45238967deuvhjyznpkmstqrwx', 'p0r21436x8zb9dcf5h7kjnmqesgutwvy' ], + w: [ '238967debc01fg45kmstqrwxuvhjyznp', '14365h7k9dcfesgujnmqp0r2twvyx8zb' ], + }; + var border = { + n: [ 'prxz', 'bcfguvyz' ], + s: [ '028b', '0145hjnp' ], + e: [ 'bcfguvyz', 'prxz' ], + w: [ '0145hjnp', '028b' ], + }; + + var lastCh = geohash.slice(-1); // last character of hash + var parent = geohash.slice(0, -1); // hash without last character + + var type = geohash.length % 2; + + // check for edge-cases which don't share common prefix + if (border[direction][type].indexOf(lastCh) != -1 && parent !== '') { + parent = Geohash.adjacent(parent, direction); + } + + // append letter for direction to parent + return parent + Geohash.base32.charAt(neighbour[direction][type].indexOf(lastCh)); +}; + + +/** + * Returns all 8 adjacent cells to specified geohash. + * + * @param {string} geohash - Geohash neighbours are required of. + * @returns {{n,ne,e,se,s,sw,w,nw: string}} + * @throws Invalid geohash. + */ +Geohash.neighbours = function(geohash) { + return { + 'n': Geohash.adjacent(geohash, 'n'), + 'ne': Geohash.adjacent(Geohash.adjacent(geohash, 'n'), 'e'), + 'e': Geohash.adjacent(geohash, 'e'), + 'se': Geohash.adjacent(Geohash.adjacent(geohash, 's'), 'e'), + 's': Geohash.adjacent(geohash, 's'), + 'sw': Geohash.adjacent(Geohash.adjacent(geohash, 's'), 'w'), + 'w': Geohash.adjacent(geohash, 'w'), + 'nw': Geohash.adjacent(Geohash.adjacent(geohash, 'n'), 'w'), + }; +}; + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +if (typeof module != 'undefined' && module.exports) module.exports = Geohash; // CommonJS, node.js \ No newline at end of file diff --git a/assets/javascript/main.js b/assets/javascript/main.js index ef83203..5fa3b96 100644 --- a/assets/javascript/main.js +++ b/assets/javascript/main.js @@ -1,16 +1,49 @@ //Global variables var userLocation = []; var gMap; -//-------- +var Radius = 5; + +// Initialize Firebase ---------------------------------------- +var config = { + apiKey: "AIzaSyBWlRO86vNl6sL5psQX5f7H9Lw_wsULP9g", + authDomain: "geofiretest-9d07e.firebaseapp.com", + databaseURL: "https://geofiretest-9d07e.firebaseio.com", + projectId: "geofiretest-9d07e", + storageBucket: "geofiretest-9d07e.appspot.com", + messagingSenderId: "680094207901" +}; +firebase.initializeApp(config); +//firebase database +var firebaseData = firebase.database(); +//firebase userlocation +var firebaseUserLocation = firebaseData.ref("user location"); +//get user list +var userListRef = firebaseData.ref("online presence"); +//current User Ref +var currentUserRef = userListRef.push(); +//Add ourself to the list when online +var ourPresenceRef = firebaseData.ref(".info/connected"); -// var googleMapQuery = "https://maps.googleapis.com/maps/api/js?key=AIzaSyA4Xg_9AqzPbXG547Ie66bFn-kqaYduOe0" > +//GEOFIRE------------------------------------------------------- +//geofire ref +var geoFireRefPush = firebase.database().ref("/geofire-location").push(); +//gefire initilize +var geoFire = new GeoFire(geoFireRefPush); +//-------- +// geoquery +var shoutQuery; + +//------------------------------------------------------------------- +//TODO: When you land on page ask the user for the location and store on to the users firebase ID +//TODO: When you press the shout button, get that specific users location and update firebase with that location +//TODO: Use that Shout Location and update the browser to land a marker on the New Location // Just using HTML API for geo location and test it with other APIs function getGeoLocation() { userLocation = []; - + var firebaseKey = Object.key; // place inside function then query for it. if (navigator.geolocation) { navigator.geolocation.getCurrentPosition((position) => { @@ -19,45 +52,314 @@ function getGeoLocation() { userLocation.push(position.coords.latitude); userLocation.push(position.coords.longitude); + //have user unique ID be stored and referenced when pressing the button. + $(this).attr("data-lat", position.coords.latitude.toString()); + $(this).attr("data-lng", position.coords.longitude.toString()); + //display lattitude and longitude in dom var pLocation = $("

"); pLocation.text("The Lattitude-array: " + userLocation[0] + " and the longitude-array: " + userLocation[1]); + //Set user's info for fireBasae + var userInfo = [ + user1 = { + name: "Jorge", + center: { + lat: parseFloat(userLocation[0]), + lng: parseFloat(userLocation[1]) + }, + radius: Radius //kilometers + } + // user2 = { + // name: "user 2", + // center: { + // lat: parseFloat(40.065494), + // lng: parseFloat(-75.091064) + // }, + // radius: Radius //kilometers + // } + ] + + //update map with location of user and create an icon and circle. + googleMapShout(userLocation[0], userLocation[1]); + + //geofire set location + firebaseUserLocation.on("value", setGeoFireUserInfo, errorObject); + + //set the user location to firebase + firebaseUserLocation.set(userInfo); + + //user who pressed the shout set geoQuery + var shoutQuery = geoFire.query({ + center: userLocation, + radius: Radius // kilometers + }); + + // look at other people around + var peopleAround = { + name: "user 2", + center: { + lat: parseFloat(40.065494), + lng: parseFloat(-75.091064) + }, + radius: Radius //kilometers + }; + + //check if someone is in your radius + shoutQuery.on("key_entered", function (key, location, distance) { + peopleAround = { + id: key, + distance: distance.toFixed(2) + "km", + location: location + }; + + //create a new location of the shouter who will then place it on the firebase query + if (Math.floor(distance) !== 0) { + addShouterMarker(userLocation); + console.log("People Around: " + JSON.stringify(peopleAround)); + } + + // locationOfShouter(userLocation); + + //show the shouter's location + + // addSellerToMap(oneSeller); + console.log("From Shout Query - " + key + " is located at [" + location + "] which is within the query (" + distance.toFixed(2) + " km from center)"); + + }); + + //update body $("body").append(pLocation); }); } else { - console.log("no access to geto") + console.log("no access to geto"); } - console.log("console lat - " + userLocation[0] + " console long - " + userLocation[1]); - - // this is the call for YELP QUERY - WORKING - var yelpQuery = "https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=delis&latitude=39.951061&longitude=-75.165619&radius=8000"; + var yelpQuery = "https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=delis&latitude=39.951061&longitude=-75.165619&radius=5000"; //testing to get variables -- Needs WORK! // var yelpQuery = "https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=delis&latitude=" + userLocation[0] + "&longitude=" + userLocation[1] + "&radius=8000"; var yelpAPI = "1QpSc4B1zI5GuI56PDAAvAfpfcsLg9LWuHRfVCeG4TIDDxRe3hGT-sxlU5h5DD0AdLgu-HHoa2cM4m1WaAefYoboIPdVHv0mCjivrwQrdU11FCFl2hd8-iaaTKOTXHYx"; + //-----------YELP CALL + $.ajax({ + url: yelpQuery, + headers: { + 'Authorization': "Bearer " + yelpAPI, + }, + method: "GET" + }).then((yelpResponse) => { + console.log(yelpResponse); + + var result = $("

"); + for (var i = 0; i < 5; i++) { + var name = yelpResponse.businesses[i].name; + var ratings = yelpResponse.businesses[i].rating; + var is_closed = yelpResponse.businesses[i].is_closed; + var location = yelpResponse.businesses[i].location.address1; + var yelpLat = yelpResponse.businesses[i].coordinates.latitude; + var yelpLong = yelpResponse.businesses[i].coordinates.longitude; + $("#name").append($("

").text(name)); + $("#ratings").append($("

").text(ratings)); + $("#is_closed").append($("

").text(is_closed)); + $("#location").append($("

").text(location)); + + } + + }); +} - console.log(yelpQuery); - $.ajax({ - url: yelpQuery, - headers: { - 'Authorization': "Bearer " + yelpAPI, +//google map function of generating user and icon +function googleMapShout(userLat, userLng) { + + var allUsers = [ + + firstUser = { + coords: { + center: { + lat: userLat, + lng: userLng + }, + radius: Radius //kilometers + }, + iconImage: "./assets/images/map-icon.png", + content: "

Hello Friends!

" }, - method: "GET" - }).then((yelpResponse) => { - console.log(yelpResponse); + + secondPerson = { + coords: { + center: { + lat: 40.065445, + lng: -75.090635 + } + + } + } + + ] + + //set map's center to shouter + map.panTo(allUsers[0].coords.center); + + //loop through markers and drop + for (var i = 0; i < allUsers.length; i++) { + var userIndex = allUsers[i]; + // window.setTimeout( function(){ + // addUserMarker(userIndex) + // },200) ; + + addUserMarker(userIndex); + } + + //function Marker + function addUserMarker(user) { + + var marker = new google.maps.Marker({ + position: user.coords.center, + map: map, + animation: google.maps.Animation.DROP, + }); + // console.log(user.coords.center); + + //if user has an Icon + if (user.iconImage) { + //set Icon image + marker.setIcon(user.iconImage); } - ); + // if it contains infoWindow text then create one + if (user.content) { + //infoWindow is a pop up for the onClick + var infoWindow = new google.maps.InfoWindow({ + content: user.content + }); + } + + // create circle + var cityCircle = new google.maps.Circle({ + strokeColor: '#FF0000', + strokeOpacity: 0.15, + strokeWeight: 2, + fillColor: '#FF0000', + fillOpacity: 0.15, + map: map, + center: user.coords.center, + radius: (user.coords.radius) * 1000 //kilometers + }); + + //check if marker has been clicked + marker.addListener("click", () => { + + infoWindow.open(map, marker); + }); + } } -$(document).on("click", "#getGeoLocation", getGeoLocation); +function addShouterMarker(shoutLocation) { + //Add marker + var shouter = { + coords: { + center: { + lat: shoutLocation[0], + lng: shoutLocation[1] + }, + radius: Radius //kilometers + }, + // iconImage: "./assets/images/map-icon.png", + content: "

This is a SHOUT!

" + }; + + var marker = new google.maps.Marker({ + position: shouter.coords.center, + map: map, + animation: google.maps.Animation.DROP + }); + + // console.log(shouter.coords.center); + + //if user has an Icon + if (shouter.iconImage) { + //set Icon image + marker.setIcon(shouter.iconImage); + } + + // if it contains infoWindow text then create one + if (shouter.content) { + //infoWindow is a pop up for the onClick + var shouterInfoWindow = new google.maps.InfoWindow({ + content: shouter.content + }); + + } + + marker.addListener("click", () => { + + shouterInfoWindow.open(map, marker); + }); + + var cityCircle = new google.maps.Circle({ + strokeColor: '#00bcd4', + strokeOpacity: 0.3, + strokeWeight: 2, + fillColor: '#f33839', + fillOpacity: 0.35, + map: map, + center: shouter.coords.center, + radius: (shouter.coords.radius) * 1000 //kilometers + }); +} + +function setGeoFireUserInfo(snapshot) { + //get snapshot vallue + var snapshot = snapshot.val(); + // var keys = Object.keys(snapshot); + //add all users + for (var i = 0; i < snapshot.length; i++) { + var userName = snapshot[i].name; + var userLocation = [snapshot[i].center.lat, snapshot[i].center.lng]; + var Radius = snapshot[i].radius; + + geoFire.set(userName, userLocation).then(function () { + // console.log("Current user " + userName + "'s location has been added to GeoFire and your location is " + userLocation); + + // geoFireRefPush.child(userName).onDisconnect().remove(); + }); + } +} + +function errorObject(errorObject) { + console.log("The read failed: " + errorObject.code); +}; + +function usersOnline() { + ourPresenceRef.on("value", function (snapshot) { + if (snapshot.val()) { + // remove ourselves when we disconnect + currentUserRef.onDisconnect().remove(); + + currentUserRef.set(true); + } + }); + + //number of online users is the number of objects in the presence list. + userListRef.on("value", function (snapshot) { + // remove ourselves when we disconnect + currentUserRef.onDisconnect().remove(); + //user is present + currentUserRef.set(true); + console.log("# of online users = " + snapshot.numChildren()); + }); + + //get user location + + +} -//firebase Google Maps API -//https://www.google.com/maps/embed/v1/MODE?key=AIzaSyCHREkl-BVxFLXW5Hp_reWCSnIDK-Oq2Wk¶meters +// Execute Initial functions---------------- +// Check who's online +usersOnline(); -// Execute functions \ No newline at end of file +//on click shout +$(document).on("click", "#getGeoLocation", getGeoLocation); \ No newline at end of file diff --git a/assets/javascript/main_edua.js b/assets/javascript/main_edua.js deleted file mode 100644 index 9a8e99c..0000000 --- a/assets/javascript/main_edua.js +++ /dev/null @@ -1,81 +0,0 @@ -//https://api.yelp.com/v3/businesses/search -// GET https://api.yelp.com/v3/autocomplete?text=del&latitude=37.786882&longitude=-122.399972 -//https://cors-anywhere.herokuapp.com/ - -//Global variables -var userLocation = new Array(0,0); -var gMap; - -// var googleMapQuery = "https://maps.googleapis.com/maps/api/js?key=AIzaSyA4Xg_9AqzPbXG547Ie66bFn-kqaYduOe0" > - -// Just using HTML API for geo location and test it with other APIs -function getGeoLocation() { - - /*var userLocation = { - lat: 0, - lng: 0 - }*/ - console.log("navigator.geolocation: " + navigator.geolocation); - if(navigator.geolocation) { - navigator.geolocation.getCurrentPosition((position) => { //This function appears to run asynchronos...see notes - - //Push Latitude and Longitude - //userLocation.push(position.coords.latitude); - //userLocation.push(position.coords.longitude); - - userLocation[0] = position.coords.latitude; - userLocation[1] = position.coords.longitude; - - //display lattitude and longitude in dom - var pLocation = $("

"); - - //Note 1: This output doesn't show until I accept "Allow Location" - pLocation.text("The Lattitude-array: " + userLocation[0] + " and the longitude-array: " + userLocation[1]); - - $("body").append(pLocation); - - } ); - } else { - console.log("no access to geto") - } - - //Note 2: This output shows up right after I press the button - console.log("console lat - " + userLocation[0] + " console long - " + userLocation[1]); - - //Note 3: Conclusion: The function declares the variables ONLY when the "Allow location" is accpected. Otherwise, the variable is undefined - // You were leaning this way but it's important to know (I believe) that the part where the location data is gathered is asynchronos to the line at 43. - // Which is to say that you will get the output of the console log before the location value actually set. - -// this is the call for YELP QUERY -// var yelpQuery = "https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=delis&latitude=39.951061&longitude=-75.165619&radius=8046.72"; -//testing to see if I can get variables included - - var yelpQuery = "https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=delis&latitude=" + userLocation[0] + "&longitude=" + userLocation[1] + "&radius=8000"; - var yelpAPI = "1QpSc4B1zI5GuI56PDAAvAfpfcsLg9LWuHRfVCeG4TIDDxRe3hGT-sxlU5h5DD0AdLgu-HHoa2cM4m1WaAefYoboIPdVHv0mCjivrwQrdU11FCFl2hd8-iaaTKOTXHYx"; - - - console.log(yelpQuery); - $.ajax({ - url: yelpQuery, - headers: { - 'Authorization': "Bearer " + yelpAPI, - }, - method: "GET" - }).then((yelpResponse) => { - console.log(yelpResponse); - } - - ); -} - -$(document).on("click", "#getGeoLocation", getGeoLocation); - -// getGeoLocation(); - - - -//firebase Google Maps API -//https://www.google.com/maps/embed/v1/MODE?key=AIzaSyCHREkl-BVxFLXW5Hp_reWCSnIDK-Oq2Wk¶meters - - -// Execute functions \ No newline at end of file diff --git a/index.html b/index.html index 9fcfb00..4fd2660 100644 --- a/index.html +++ b/index.html @@ -5,8 +5,20 @@ + Shout! + + + + + + + + + + + @@ -16,97 +28,44 @@

Google Map

- +
- + - - - - + + + \ No newline at end of file