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.
Related
There may be similar questions regarding this topic,But I need your thoughts and suggestions on some specific requirement.
Here is my need -
We are developing one app which tracks User's trip.
The app will start collecting the location of that user in background,When user 'Starts' his trip from App.Background Service will be fetching locations on the basis of user's movement in specific time duration.
When User 'Stops' his trip from App,We are calculating distance traveled by user with help of all recorded locations(With Google Distance calculating API).
The App works fine in ideal case.
But main challenge is -
In some scenarios,We are not able to fetch exact and precise location of User. Scenarios affecting is - No internet,Data plan with 2g/3g,some specific areas where GPS is not returning accurate data etc.
Incorrect data of lat-long causes incorrect Trip distance and route.Which is main problem with the App.
Please,any one can suggest the best alternative/Suggestion for this?
P.S. - We have tried GPS,Network,FusedLocationProvider.
EDIT 2 --
We have implemented logic on basis of accuracy and distances.Got nearer points. And just came across one useful api from Google that corrects some location points which are distracted from actual Roads. Posting here for reference of others...
Snap to Roads Api from Google
this is a complicated topic.
One consideration you have to take. Android Oreo limits background services and that what you want to achieve won't work.
I would do is this (and it is the recommendation from Google)
When someone starts the trip (the user is aware of it), you must launch a on going notification with a foreground service , don't rely on background services anymore. Check the feature "Start Activity" in Google Fit App.
As for not having signal, or accurate GPS, well... it is a geographical problem!, there is nothing you could do. Or, maybe you can, using the LocationProvider.
FusedLocationProvider is fused within every app that requests locations updates.
Read this out, and see if that helps you.
https://developer.android.com/guide/topics/location/strategies.html
Try to mix GPS and Accelerometer
If you detect that GPS stopped working, turn on accelerometer. If GPS is turned on again, calculate distance again with it. This way you can have route with GPS parts and accelerometer ones. The bigger GPS parts, the more accurate data will be
How to get more accuracy by GPS_PROVIDER
Basically if the accuracy of a location isn't acceptable throw it away. The next one will be better.
I am studying the Cordova geolocation plugin for Ionic 2 and want to send the device location to my server when the app is opened.
To keep track of the route of the device I want to send the position all the time to the server. I was wondering how often I should do this. Every time the location changes seems a little too often!?
How do other tracking apps do this?
Granularity of position updates are inversely proportional to the battery power consumed and the network bandwidth used for transmitting the positional information.
I use the following guidelines:
Transmit position whenever the position has exceeded a defined distance 'D'
Transmit position whenever a defined period of time 'T' has elapsed since the last successful transmission
Transmit position when the app starts
Disable transmission when the activity is paused and enable it when the activity is resumed
Always save the last successful transmission (position and time stamp) for future reference
I typically store the defined parameters 'D' and 'T' in a configuration file, making it handy to test how the application performs for different values.
Using coarse GPS for reference, position accuracy is rarely better than 15 meters (without applying GPS corrections). With that in mind, you can set your 'D' value to something between 15-30 meters. If you are tracking vehicles, that distance can be exceeded pretty quickly, in which case a larger value may be preferable to avoid sending too much data.
You can also increase 'D' as a function of your positional velocity (speed). this would increase 'D' the faster the vehicle is moving, thus maintaining a consistent bandwidth usage.
The value of 'T' really depends on your application needs. If a vehicle is sitting idle, then I typically transmit updates once every 5 minutes.
I have used distances ('D') between 30-100 meters. If you are monitoring vehicle positions in an urban environment, you need to be able to pin point where that vehicle is within a crowded street plan. This becomes quite clear if you've ever used a GPS device to navigate in an older city, where the device often gets confused between streets that are in close proximity (i.e., New York, Boston, Montreal, etc.) In this case, a smaller value (> 15m) is preferable.
For added robustness, you might want to add some heuristics into your application. For example, popular after-market GPS devices for automobiles have to implement more intelligence into their applications, in order to snap the vehicle position to a location on a street or road. Otherwise, the vehicle would never show up on the street itself, but rather somewhere in the ditch, or right in the middle of a building on the map.
One example of such heuristics would be to assume that unless the vehicle has reached an intersection, it is still on the same street that was reported previously.
Ultimately, you need to try out different configurations in order to find what best suits your needs.
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.
I have a question regarding my programming approach for android - whether it's efficient or not. Just to give you an idea what I try to accomplish:
There are multiple points of interests on a map. If the user gets nearer to a PIT, a notification about the distance shall appear. There are let's say 3 notifications: At a distance of 1 mile, 0.5 miles and 0.1 mile. When the user is more or less exactly at the PIT, no more notifications are shown. The user is supposed to drive a car or another vehicle.
I'm currently using Geofences to detect whether the user has entered a radius of 1 mile. If so, I check the distance of his current location to the PIT. If it's about 0.5 or 0.1 miles away, a notification is fired. Therefore, I check the current location frequently (right now every 10 seconds). If the user is like at the PIT or rather very close, the Geofence is exited and done.
The code is working fine and this approach is the first thing that came to my mind while reading the Android Developer's tutorials etc. But is there another approach that is MORE EFFICIENT?
Although this is (currently) meeting my needs, I have two major concerns:
It seems to drain the battery quite a lot. Since the user is most likely to be in a car where he can charge his phone during usage, this might be less of a problem.
I read the number of PITs from a file on the SD card. In my example I have just a few PITs. But the user is able to modify the source data so that he can add as many as he wants to. Google says that only 100 active Geofences are supported per user. But what if my user has more than 100 PITs? Since I'm using a Geofence to sense whether I have to fire the first notification or not - this is a severe problem. So is there an alternative?
I have a few suggestions :
1) To lower the amount of gps fixes, you could calculate a sleep time. The idea is to do frequent gps fixes when near a 'border' and few when far away. This could be further enhanced by taking the speed parameter returned by the GPS into account.
If for instance the user is 20 miles from the nearest border while driving 20mph, you can easily wait 30 minutes before turning on the gps again, just to give a simple example.
2) I have run in to the same problem. My solution was simply to select only the POI's within X miles. This way ensuring never to risk hitting the limit of 100. When the user has moved (X-1) miles from his initial position, the geofences are rebuild using the new location.
If you think there is a high risk of having such a high density of points that the above strategy still might fall, I would consider making your own proximity checking entirely based on gps instead of geofences.
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.