Handling geocoding in Firebase? - geocoding

Has anyone tried storing and/or searching on geocodes (e.g. lat/long) in Firebase? This is functionality that is built into MongoDB and as I'm considering using Firebase for our backend instead, I need to know how I'd handle this scenario in Firebase.
Thanks!

The folks at Firebase recently open-sourced a library that allows you to store and query location data in Firebase. In short, this is very easily accomplished because all keys in Firebase are strings, and Firebase has support for startAt() and endAt() queries that allow you to do the appropriate windowing for geohashes and bounding boxes.
For implementation details and usage, check out the live demos, source code, and their blog post on GeoFire.

Hey I just finished building a real time google map using firebase and GeoFire. GeoFire is really cool and easy to use. It allows you to query using lon lat and radius. It returns a key that you can use to query your firebase db. You set the key, while you create the geoFire object, to be whatever you want. It is usually a ref that you can use to get the object that is associated with that distance.
Here is a link to geoFire:
https://github.com/firebase/geofire-js
Here is an example use case:
You have a lon lat, that you got using navigator:
var lon = '123.1232';
var lat = '-123.756';
var user = {
name: 'test user',
longitude: lon,
latitude: lat
}
usersRef.push(user).then(function(response) {
var key = response.key;
var coords = [lon, lat];
geoFire.set(key, coords, function(success){
console.log('User and geofire object has been created');
});
})
Now you can query for the user using:
// Set your current lon lat and radius
var geoQuery = geoFire.query({
center: [latitude, longitude],
radius: radiusKm
});
geoQuery.on('key_entered', function(key, location, distance) {
// You can now get the user using the key
var user = firebaseRefUrl + '/' + key;
// Here you can create an array of users that you can bind to a scope in the controller
});
If you are using google maps. I reccomend you use angular-google-maps.
Its a really cool google maps directive that takes in an array of markers and circles. So when ever $scope.markers or $scope.circles change in the controller it will automatically be applied to the map without any messy code. They have very good documentation.
Here is a link:
http://angular-ui.github.io/angular-google-maps/

Related

How do I save google places location to django models?

I am trying to create an app that relies heavily on location. I am using google maps places api to allow users to select a location and add it to the database. My current issue is that I can't seem to figure out how to save the location from the google maps places JavaScript api to the database. For example Suzy chooses a store and wants to save the store and it's location to the database. I can't seem to figure out how to save the store location to the database. Any idea on how to do this?
One way is to save the longitude and latitude because they can denote the exact location globally, you can add fields something like
long = DecimalField(max_digits=9, decimal_places=6)
lat = DecimalField(max_digits=9, decimal_places=6)
Since decimals are very important in coordinates but using more than 6 is basically meaningless.
Get the longitude and latitude with geolocation() see this
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
let lat = position.coords.latitude;
let long = position.coords.longitude;
$("input[name='lat']").val(lat);
$("input[name='lat']").val(long);
let url_str = 'https://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&key=yourkey'
$.getJSON(url_str, function(data) {
console.log(data);
//here you get the location data, make more fields like street address, city in db and pass it to inputs and submit the form to save it.
});
}

Where to put code from another JS library in Ember: controller, model, adapter, service?

Wrapping another javascript library to use with Ember bindings, etc, seems like an ordinary thing to do, but I haven't found much discussion of it.
I want to filter an ember record array using distance and travel time from the Google Maps Distance Matrix
service. I'm just not sure where in the application to encapsulate Google's javascript. Note: this is not a question about embedding a google map, it's about getting data into ember that doesn't come from a rest/json or fixtures as in all the tutorials and examples I've found.
Would people typically do this in the controller or create new models/adapters to get benefits from store caching? Or is there another way?
update: in case that's too vague, consider this: 20 records (with a google map component etc) listed by an array controller, a text field where the user types in a home address, a couple of other inputs where they set a maximum time or distance, and a search button which filters the listed records by comparing the user requirements with the result of querying the distance matrix for the home address to the 20 records' addresses, only showing the ones close enough to their home.
Use of the service in an application that doesn't display a Google map is prohibited.
So,the question is really about integrating a Google map to an Ember app.
Without any doubt you'll have to add the Google JS like in any other HTML project with:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=MYSECRETKEY"></script>
So, the API is in global space and you just use it whenever you need it. Mostly all that will happen in your views, so you could wrap everything in a component. (I'm assuming that all relevant data has been passed from the controller to the view, it all depends on the design of your app.)
The following works, but it seems like it should be in the model/store/adapter layer.
App.DistanceController = Ember.Controller.extend
origin: (->
data = #get('data')
data.origin if data
).property('data')
destinationDistances: (->
data = #get('data')
data.distances if data
).property('data')
data: ((key, value)->
if arguments.length > 1
value
else
_this = this
value = null
service = new google.maps.DistanceMatrixService()
service.getDistanceMatrix(
origins: ["London, England"],
destinations: [
"Bristol, England",
"Edinburgh, Scotland",
"Leeds, England",
"Liverpool, England",
"Manchester, England",
"Newcastle, England",
"Nottingham, England",
"York, England"
],
travelMode: google.maps.TravelMode.DRIVING,
avoidHighways: false,
avoidTolls: false
, (response, status) ->
if (status == google.maps.DistanceMatrixStatus.OK)
distances = []
for destination, n in response.destinationAddresses
distances.push {
destination: destination
distance: response.rows[0].elements[n].distance.text
}
_this.set('data', {
origin: response.originAddresses[0]
distances: distances
})
)
value
).property()
kudos #rlivsey https://stackoverflow.com/a/20623551/395180

Trouble accessing child objects in Firebase

I'm trying to pull a list of connected users in Firebase to simply populate a select dropdown. My problem is that I can't seem to access the child objects properly.
Using connectedUsers.userName (see below code) works but only for my own user data, it doesn't pull anything else.
It seemed to me like changing "myUserRef.on" to "userListRef.on" and using something like "snapshot.child('userName').val()" should work but it just throws undefined. The same goes for "connectedUsers.child.userName", I'm sure I'm missing something simple here.
In the below code by changing to "userListRef.on('child_added', function(snapshot)" I can successfully add and remove user data from Firebase, and log all of the objects to the console and all data looks fine when I drill down the objects. I just need a way to access that data so I can put all connected users into a select dropdown or remove them from it when they disconnect.
var userListRef = new Firebase('https://myaccount.firebaseIO.com/users/');
var myUserRef = userListRef.push();
// ADD USER DATA TO FIREBASE
var userId = $('#myIdInput').val();
var userName = $('#nameInput').val();
myUserRef.push({userId: userId, userName: userName});
// READ USER OBJECTS AND FIRE ADDUSER FUNCTION
myUserRef.on('child_added', function(snapshot) {
var connectedUsers = snapshot.val();
console.log(addUser);
//addUser(connectedUsers.userId, connectedUsers.userName);
});
// ADD USER TO SELECT DROPDOWN
function addUser(userId, userName) {
var modSelect = $('#tsmmodsendto');
modSelect.append($('<option></option>').attr("value", userId).text(userName));
}
// READ USER OBJECTS AND FIRE REMOVEUSER FUNCTION
myUserRef.on('child_removed', function(snapshot) {
var connectedUsers = snapshot.val();
console.log(removeUser);
//removeUser(connectedUsers.userId, connectedUsers.userName);
});
// REMOVE USER TO SELECT DROPDOWN
function removeUser(userId, userName) {
var modSelect = $('#tsmmodsendto');
modSelect.append($('<option></option>').removeAttr("value", userId).text(userName));
}
// ON DISCONNECT REMOVE USER DATA FROM FIREBASE
myUserRef.onDisconnect().remove();
The code you've written won't work properly because each user is writing to:
/users/PUSH_ID/PUSH_ID
And is then listening at:
/users/PUSH_ID
So every client is going to be listening only to its own data and will never see anyone else's data. In order to view other people's data, you need to all be listening / writing to the same path.
In your question you mention you see "undefined" if you change to listening at /users. Could you simplify your code, and use that approach, and perhaps then I can provide a more helpful answer?
Or if I'm not understanding correctly, please simplify and clarify your question.

Using NBuilder to test NHibernate mappings

I have been using NBuilder for a while in unit tests to simulate in-memory data and it's awesome, then I wanted to use it to test my NHibernate mappings, I thought it was going to be transparent but I can not figure out what I am doing wrong =( it is simply not working
I am planing to test heavily my NHibernate mapping but since I have too many entities I do not want to populate data manually, that's the main reason I want to use NBuilder
just as a quick reference:
autoConfig.Override<Planet>(x =>
{
x.References(y => y.Sun).Cascade.SaveUpdate().Column("Star_id");
});
autoConfig.Override<Star>(y =>
{
y.HasMany(x => x.Planets).Inverse().Cascade.AllDeleteOrphan();
});
(If you need I can provide information about the entities and the mappings but I think they are correct since i am able to save my entities when the data is populated manually)
Manually:
using (var session = factory.OpenSession())
using (var tran = session.BeginTransaction())
{
var star = new Star { Class = StarTypes.B, Color = SurfaceColor.Red, Mass = 323.43, Name = "fu..nny star" };
star.Planets = new List<Planet>
{
new Planet { IsHabitable = true, Name = "my pla", Sun = star }
};
session.Save(star);
tran.Commit();
}
The above code actually works saving both entities to the database correctly meaning that my mappings are correct but now I want to use NBuilder to auto populate testing data like this:
var star = Builder<Star>.CreateNew().Build();
star.Planets = Builder<Planet>.CreateListOfSize(10).All().With(x => x.Sun, star).Build();
session.Save(star);
tran.Commit();
Inspecting the generated entities while debugging look correct to me, I can navigate through them without problems, but then when I want to commit the transaction I get the following error:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [CH9_NHibernateLinqToNHibernate.Domain.Planet#00000000-0000-0000-0000-000000000001]
Any thoughts?
I found the problem, basically NBuilder was assigning a value to my Id and NHibernate was considering it 'persisted', and it was trying to update the record instead of create a new one (the error message was not helping me though...):
var star = Builder<Star>.CreateNew().Build();
star.Planets = Builder<Planet>.CreateListOfSize(10).All().With(x => x.Sun, star).With(x => x.Id, Guid.Empty).Build();

SimpleGeo and Google Maps

I'm trying to do something I thought would be simple. Query SimpleGeo, take the json and show the points on a google map.
The logic is as follows:
User views a page about a location stored in the Django DB with a simple google map. That map has one point showing the location.
User clicks show hotels
jQuery retrives json from SimpleGeo for a given lat/long
jQuery updates google map with points for hotes around that location.
Problems I'm having;
The json comes back with several entires. I've tried several looping functions but couldn't get anything but null. So then I just say json_ob[0] and I get one listing, but I can't get the cords from the json and show them on the map. Gmaps keeps compaining about the cords are not vaild. I've used alert() to check them but they seem to be the same format as the initial ones for the map.
I've also tried processing the json in my view and sending just the lat and long to the template but that doesn't seem to work either.
A link to a example or tutorial would be great.
I have here some
var obj = jQuery.parseJSON('{{ near_geo|safe }}');
cords = obj.geometry.coordinates
cords_array = cords.toString().split(',')
lng = cords_array[0];
lat = cords_array[1];
var marker = new google.maps.Marker({
map: map,
position: [lat , lng]
});
That produces:
Invalid value for property : 32.929272,-83.741676
If I could just get one to show up then I can loop and get the rest.
try to replace
var marker = new google.maps.Marker({
map: map,
position: [lat , lng]
});
with
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(lat, lng);
});