I'm building a location based application.
Lets say that i have user A and i have a latitude and longitude values of his current location.
I got user B,C,D and thier locations as well..
For the example - user B + D are in a radius of 5km from user A and user C is in 12km radius from user A and I want to know how can i make a function that will tell me that whose near to me by 4/5/6/7km and etc..
If i user A wants users that are 8.5km away from him i will have as a result user B + D and thier distance from user A.
Now.. i know that i can use the Location class and use the distance function to calculate the distance between two users.
But the problem is that if i want to calculate that for the radius distance i need to fetch the entire users list from my database and send it to the client to start calculating distances between him and those i fetched from the server.
Now i dont want to do that off course if there is a better and more effecient way..
Firstly, I thought off using http request or some mathematical functions to calculate the distance between my users on the server side but the client (Android) offers very good tools to do so , so because of that I am lost of knowing to is the best thing to do.
Thanks head up :)
Hey don't you think that always sending locations of n-1 users to one requesting from server is inefficient and consumes unnecessary bandwidth than sending only few in the radius vicinity? The server can easily do this computation.
Think of a scenario where your app user base grows and grows? Then what?
Such a computation is always performed on the server.
Also nearly all of the times, server has much more computing power than the client. So even though android tools look lucrative, don't end up using those in a scenario like this.
In terms of tools, there are similar on the server side too ex. the haversine function. Also some databases like mongo also have inbuilt location filters. So this is really worth checking out.
Related
I did some search but could not find a suitable answer.
My App should compare with multiple locations for proximity. This means I will not be able to save all the locations into my app to confirm the proximity using locationManager. I want the proximity confirmation to be done in the server
What would be the best way to implement this?
Would it be sensible if the app asks for proximity confirmation every time the devices moves around?
I would try a different approach, since location updates from GPS are made once per second,
and I don't think it's a good idea to ask the server each second for proximity if you have a large amount of devices.
Think of this idea -
Get the device's initial location and send it to the server.
Decide on a sensible radius that the device will stay within it for the next 5-10 minutes.
Also make sure that you don't have "too many" points in that radius, or you can narrow the radius in that case.
It's up to you to decide the radius and the number of points, depending on your usage,
number of points etc.
Send form the server all the locations within that radius to the device.
Let the device calculate the proximity by itself.
When the device moves out of the initial radius - update the server and get the new
relevant locations.
This can be done easily - call the radius r. Save the initial location of the device, and calculate the distance
between the current and initail location. When it is "close enough" to r - update the server.
In your case, simply, you can send the received locations to your server and then make required calculations on server. But don't forget that you will be dealing with those questions
How many devices send location to server ?
How frequently each device send location to server ?
Also the responsibility of detecting a device has entered an area on the server
I think you can reduce the complexity of the all things by using geofencing api, link
No need to send each location to server.
Each device individually detects itself has entered or exited an
area.
EDIT
Otherwise you will be doing entered/exited calculations on server for unlimited count of device, whenever each device's location has changed.
Before we were doing similar thing in my previous company, calculating enter/exit time and enter durations. but via real gps devices on buses
We have almost 100 points(geofence) in city. So you can think that those points are on a few routes
Each gps device on bus is sending location to server periodically.
When the bus has finished it's route, server reviews device's all received locations on the route.
Compares each geofence with each location of bus.
This is the real scenario. You can call it "server based geofencing".
You could do a simple k-d tree implementation on the server side to store the coordinates.
Send the coordinates of the device over, which can be determined at whatever interval you need. If it's every 5 seconds, or 10 seconds it doesn't really matter. This will mainly be decided by the minimum distance between each of the coordinates/radius. If they're closer, you may need to update it more frequently.
Using the k-d tree finding the nearest neighbor would be O(log(n)). However, you make a slight modification where you can start adding the nodes to a list as long as they are within the certain radius of your device coordinates. In fact if you store it locally as a k-d tree as well then you can pick the furthest nodes in O(log(n))
Now on the second update when the device location is sent again, you can quickly update it since you have the existing locations. Say you move in the x direction by 5. You can drop the points that are now outside of the radius at x - 5. The new proximity, you do the same nearest neighbor search, adding in nodes as they're within the radius, but this time starting with the cached nodes closest to the direction you are moving in.
Combining that with an interval tree for radiuses. So say 0 to 1, 1 to 2, 2 to 3, as your intervals. You can pick out everything within a certain radius in O(log(n)) time as well. Those should be pointers to nodes in the k-d tree. That would simplify the radius calculations and finding the location if you're willing to sacrifice some memory for efficiency.
For a "fast" way to implement it on the server side you can use the mondodb $near geospatial query.
https://docs.mongodb.org/manual/reference/operator/query/near/
While on the mobile side you can use the minDistance property for the location updates. You can set it to a reasonable distance 20m/50m depending on the average distance between your locations.
http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates(java.lang.String,%20long,%20float,%20android.location.LocationListener)
There is a free service for this purpose -> Radar
You can register unlimited circle or polygon geofence, and register your user in app for tracking that user. When user entered in one geofence Radar send a notification to your server and send below data to you:
User ID, Geofence ID that user entered or exit, Confidence (low, medium, high) used for geofence that has overlap.
You can use this SDK in only 10 minutes.
Im trying to develop an Android messenger application where a message is sent by user 1 to everyone using the app, the message contains the GPS location of user 1. Is it possible to determine the distance between user 1 and the user 2 and based on that either choose to display or discard the message. How do I go about it? Cloud you point out considerations that I might have missed out?
Another method I believe is possible is to periodically update a server with every users GPS location and then let the server decide who gets the message, but I would not like to use this method as it would be a privacy issue. No one would want their whereabouts being tracked by a server all day. Is there another solution to this?
You can use the haversine formula to determine the distance between two locations. Here is a link that provides the formula in various languages.
http://www.movable-type.co.uk/scripts/latlong.html
One way of doing this is to store the most recent location of a phone on the server in the database. You can then query the database (using a stored procedure) to determine who your closest neighbors (phones) are by setting a radius. For instance, show me all the phones within 500 meters.
Here is an example of how to do this:
http://www.movable-type.co.uk/scripts/latlong-db.html
I am building a taxi dispatching app
first: I need the passenger app to show the nearest taxis, now I know how to do that in code but in my way I have to go through all the taxis locations(in database on server) and calculate the distance from the passenger location and get the lowest ones - I don't want to do this because there will be a lot of taxis and going through all of them and making some math is kind of pain on the server- is there a way to get the nearest ones without going through all of them?
second: what the best database to use - first, should it be sql or non-sql - I need a very robust database, because there will be a lot of updates (I mean the passengers locations added then deleted when arriving to destination && the taxis location changes frequently)
finally: I will use RubyOnRails to do the server side and json as data transfer format, do you have a recommendation to me on something better?
Thanks
Calculating distances takes time because of the complex equations involved.
Instead, try to do a more simplistic "fake distance" calculations.
For example, instead of d = SQRT (x*x + y*y) for your purpose you may try something like
d = |x| + |y| and sort for that. You don;t need the exact formula here because a rough approximation would do.
For first: Use you need to calculate nearest distance. But instead of comparing with all taxi location i recommend you to pass lat long of passenger.
On server maintain taxi location in lat long. Write query to get taxi's with in +/- 3 of lat long. This will get limited no of taxi's available near passenger area.
For sencond: = Use Relational database, SQL Server is good for such applications I have used in my last projects.
For server: I don't have idea of RubyOnRails but this is also faster & easy to implements as they says.. , you have choose the best data exchange format Json no need to change this; you can use zip to improve performance.
For the first question:
I think you can send from the mobile device a radio (ie: /43.34343/-3.3333/1000 and 1000 represents the radio in meters), and from the server return only the taxis included on this area.
You can do that calculating the distance between the device location, and the list of the Taxis.
Try this link
It will show you all the nearest places like Hotels,theatres,etc..
it will show the address of the particular place in list and also it will show in map view..
Hope this will be helpfull for you.
I have an Android app that when launched, inflates a MapView, gets the user's location and then makes a request to my server to fetch all points of interest (POI) as JSON within some radius of their location and draws those points on the map. I want the user to be able to pan around the map and see more points of interest load as they go outside of that initial data load, just like Google maps.
My initial thought is to handle the pan event and when panning stops, get the map center, and make another server request for POI within some radius of that location. This seems to me like this will quickly get to a point where it's sending back redundant data and making unnecessary server requests.
I'm looking for a caching strategy where I can make requests to fetch new data, but not have to make additional requests for the same data. My POI don't change very often either, so caching would be ideal to speed up subsequent launches of my app. Are there any best practices out there for such a thing? Or is it preferred to make a larger data request up front and just fetch new data as necessary?
What spontaneously comes to my mind is sectioning the POIs in square tiles for example. These tiles have a lastUpdate timestamp and both client and server communicate in terms of tiles, instead of geo location center point and radius. Your client would always send the lastUpdate timestamp of the cached tiles to the server and the server would only respond with updated data when that timestamp did change for the requested tiles. Another advantage is that your algorithm for retrieving POIs would be way faster compared to "point in circle" calculations.
Your client app can decide when to re-request tiles based on the timestamp. That depends on how often your server data changes. If it changes just once per day, then let your app re-request cached tiles only once per day. My suggestion is based on a fixed size tile (like 2 square miles for example). Otherwise you'll have a hard time with keeping track of the lastUpdate time stamps.
You could however create something like several different "levels of detail" for your zoom levels or your app needs to calculate the upper left visible tile and the lower right visible tile depending on the current zoom.
I'm making an application where users can save GPS data from phone to server when they travel their everyday routes. For example they are heading from home to work. GPS data is stored in a database.
Now, user wants to know maybe there's more people who travels this route too. I want to compare different users routes and give to user for example 3-5 best matches from other users routes.
Important is compare the whole trip, because users can join their routes and go work together from starting at some point not just from beginning and end. Also I think important is the destination point from the users view, who is searching other users routes. Other user route must be near by the searchers route end.
There are two factors - time and location. One user drives with a car and another walks and takes a bus for example. The one who walks starts his trip earlier, another later, because he travels this route faster. In one point at certain time their routes are matching.
How can be routes compared? Is there algorithm(s) for that? Do I need to compare every point in a route?
Essentially you are talking about a combination of routing algorithms and traveling-sales-man
The most common routing algorithm was invented by Dijkstra some 50 years ago, and calculate the best way of getting from point a to point b in a directed network -- in routing applications that means that each road is represented as a edge in the network, and where each edge is associated with a "cost" i.e. the time it take to travel down the road, or the average speed, or in your case it would be the number of people traveling on that route.
The Traveling Sales Man is a slightly different but also related, trying to optimize for the number of nodes visited -- in your case it is probably solving the opposite as it is trying to maximize the number of cities (edge-intersection nodes) while minimizing the cost of traveling to all the nodes -- worth understanding if you want to solve this problem
See GIS - it's a (HUGE) field of study - very interesting but very intense
I think what you would have to do is to convert the GPS co-ordinates that you get from the phone, into routes. Have a look at this Open Route Service which is part of the Open Street Map project.
Once you have each person's latitude and longitude converted to a common set of routes, then it will be easier comparing their paths to see if they have something in common. You could also do things like search for alternate routes. Perhaps one person by traveling a couple of extra mile/km can travel together with another group of 4-5 people going in basically the same direction. Things like that.