I have a list of coordinates in the database identified as POI. For a city could be >100 records.
I would like to get notified when the phone gets in 150 meters range of one of the location. The location coordinates too has an error/radius, usually 10 to 100meters. Since I don't find it good to add each location(could be hundreds) for a trigger, how can I optimize the wake-up code?
Also do I have options to remove a previously setup notification from the queue?
You could store your POIs in some sort of intelligent Hash-Table using the coordinates to compute a unique hash. Each time a location update arrives you make a lookup in your hash-table to see if there are POIs near the current location. This lookup should only take O(1), since it is a hash-lookup.
The desired range should be taken into account when computing the hashes and storing the POIs.
Just an idea!
Kind regards,
mefiX
There's an app named Locale, that can toggle various events based on your GPS location OR available Wifi network OR cell-station id, etc
It also has a plugins interface. It could be useful for you to examine that app and, maybe, write a plugin for it.
This problem reminds me of graphics in video games. There's no need to load the points that are well outside your range of movement. I'd break down the map into a grid, set triggers for the 8 adjecent grid blocks and then for each of the POI within the current grid block. When a new grid block is reached the triggers are updated. It'd probably be smart to overlap the grid blocks considering the range of error.
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.
I have SQLite table contains 1.5M lines, the table contains <lat,lng, info>, what i want to do is, for every time I receive data "lat,lng" from the GPS, I should access the table and display the corresponding info.
my question is, is this operation will be exhaustive and time consuming? if yes, how can I achieve better data retrieval fro mthe table every time i receive GPS data?
You should use Spatialite, it is a Sqlite extension to use with geographical data, it allows you to create spatial indexes and then query data which is included in a rectangle, for example around x meters from your gps coordinates.
You do no want to search for an exact location (GPS is not accurate enough for that), but for nearby entries.
Two-dimensional interval searches are not efficient when using 'normal' indexes.
You would need to use something like an R-tree index, which is not available on Android by default.
If your table never changes, you could prepare the R-tree on another machine, and in the app, search for entries manually.
I don't know exactly what your data looks like but the first thing I'd do (given that GPS position may not evolve much) is to first create a temp table with a smaller range of coordinates so you can probably reduce the 1.5M records into some thousands only. Then everything should be faster.
I didn't know about the R-Tree #CL spoke about but indeed they look very promising if only you could manage to use them under android.
Well if your use case is not as other suggests - means that you are looking for an exact position rather then an area, Then all you can do is make sure you add an index on (lat,lng) and pray for the best...
CREATE INDEX index_lat_lng ON MyTable(lat,lng);
Your question is far to woolly.
what i want to do is, for every time I receive data "lat,lng" from the GPS, I should access the table and display the corresponding info.
You need to define how often you receive data.
Will it be exhaustive and time consuming? Maybe, maybe not, without knowing how often you receive data.
Given the above, have you considered and assuming that the GPS co-ordinates are not coming in from all over the shop, creating an in memory database snapshot of the area in and around where your latitude and longitudes are currently coming from and using that until such time as they stray from the current snapshot area. At that point you will need to write out the existing data create a new snapshot for the new co-ordinates. The snapshot areas could be defined by degrees, minutes or seconds depending how fast the thing, that I suppose you are tracking, is expected to move.
You can try just with a command like:
SELECT info FROM Table WHERE lat = 'lat' AND lng = 'long';
Doesn't that just work well enough for your purpose?
I am in the process of planning an app that includes a feature that requires it to record and store the exact route a user takes while driving. Is there any location api that supports this out of the box? Or supports detecting a turn? I was initially hoping for an event triggered by the user turning onto a different road, but so far, no such luck.
I think you may try this way:
1 Request for GPS location update every 30s ,you can do this with Timer and TimerTask ,and LocationManager;
2 You can get the road name through Google Map API with the GPS location you get;
3 So you will get to know whether the user is turning onto a different road every 30 seconds.
I believe I have found a solution that makes use of the other answer here. I will post it as a separate answer though as it adds more to the other answer and is a full solution. As Ai Hao said, I could have my app request an updated location every 30 seconds to determine whether the user is on a new road, and then place a waypoint signalling the turn. However, this method is flawed if the mapping algorithm used (and I do not have the expertise to write my own) detects multiple possible routes. My solution to this issue is to store all location responses until a turn is made. This means that when a turn is detected, the oldest location data will be the last turn, while the newest will correspond to the turn being made. The app will request alternate routes, and if any are found, will calculate a route between the second oldest and second most recent coordinates, until no alternate routes are found. This should result in the exact route that the user took.
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
My requirement:
Area around the Path(Route) is having some important places(quantity is approx. 50). When user is moving on the path, and reach to the nearest place(e.g. A), I need to perform some task particular to that place(e.g. A).
Currently, I am creating geofences for all the required places at the same time but having doubt about the battery consumption.
Is there any way to minimize the battery consumption? If yes, then please help. Any help or guidance will be well appreciated.
Note: User can enter to the route from start/end/middle of the route.
Here is one option:
Run each point through an algorithm to determine the distance from the point to the user. For example lets say the user is at X(0),Y(0) run the root of (Xn - X(0))2 + (Yn - Y(0))2
Assign the distance as a property of the geofence.
Sort an array of the geofences for the new property.
Add the 10 closest (or whatever number seems reasonable based on the distance of the path and proximity of the geofences with one another) regions to a new array.
Register those 10 (or so) regions.
Record the last location at which this process was done and compare it with the users current location. If the user travels a certain distance than begin the process over again.
Especially with the simple math operators this is much easier on the OS than searching for 50 regions simultaneously.