I'm trying to find out what's wrong but it seems like the mentioned method is just returning wrong values. I'm setting coordinates in simulator, then just print them and calculate distance:
(lldb) p location.coordinate
(CLLocationCoordinate2D) $1 = (latitude = 51, longitude = 0.10000000000000001)
(lldb) p _oldLocation.coordinate
(CLLocationCoordinate2D) $2 = (latitude = 51, longitude = 0)
Now I'm calculating distance:
distance = (CGFloat)[location distanceFromLocation:_trackEndLocation];
And when I print it i get:
(lldb) po self.trackDistance
7019.76758
Now, the problem is that users tell me that app returns too big distance. As I wanted to debug it, I've checked the distance at page to calculate distance between two points.
The results are as following:
As you can notice, the distance according to the webpage is 6.997km while Apple method tells me 7.019km. I wonder who is incorrect, Apple or the webpage and what to do with this matter. The difference isn't big, but when you accumulate it between few points it can be disturbing.
The Apple doc page for distanceFromLocation says this:
This method measures the distance between the two locations by tracing a line between them that follows the curvature of the Earth. The resulting arc is a smooth curve and does not take into account specific altitude changes between the two locations.
I suspect Google Maps does consider the terrain between the two points, and that's why you saw a 0.3% difference in your test. However, I doubt your customers are complaining about that level of error. It's more likely the error is from a different cause.
Without knowing more about your algorithm it's hard to say, but if you're tracking distance traveled, the error might be caused by jitter in the phone's GPS coordinates. (That would cause a straight line path to look like a zigzag, which would yield a longer distance.) You could record some real data from your app to see for sure.
The problem was that I was checking the accuracy and filtered some results out if the accuracy was bad. That's why sometimes the distance was wrong. I've fixed the accuracy filtration and everything is working fine.
Related
I need to be able to evaluate how remote a location is given its geographical coordinates. I rate remoteness based off of a few key metrics, so far, I am only able to calculate a subset of all the required metrics:
The cellular reception at the given coordinate. More specifically, the density of cell towers around the coordinate. This can be found using opencellid.org.
Elevation. This can be found using Google's Elevation API
How can one find these remaining metrics for remoteness?
The type of natural feature the coordinate is in. (eg. Lake, River, Glacier, Ocean, Island, Mountain)
Distance to the nearest road. (Google's Snap Road API and Nearest Road API only work if the coordinate is within 50m of a road, that will not work as some coordinates are hundreds of km from the nearest road).
About land type
For your first question it has already been answered here, except it is only for land/water.
My approach would be the following:
Using maps static, you get the image at your coordinate, you get the pixel at the center of your image (your coordinates) and you use a hashmap/dictionary that contains all the different possible colors and their land type, would be very quick to implement. But you can find out different ideas by reading the first link provided.
For strength of cellular signal
As for your second question, you can use Google API to detect the closest cell towers object, using the locationAreaCode that you can obtain through the coordinates:
An example cell tower object is below.
{
"cellTowers": [
{
"cellId": 170402199,
"locationAreaCode": 35632,
"mobileCountryCode": 310,
"mobileNetworkCode": 410,
"age": 0,
"signalStrength": -60,
"timingAdvance": 15
}
]
}
What is the purpose I wonder? You could take a sampling of coordinates around the fix and if they are mostly on a hill or in water it is definitive, it seems people know how to figure out this kind of stuff with google apis.
Would this be good enough?
Get Lat/Lon and range from a sources like this: https://my.opencellid.org/dashboard/login?ref=opencellid for free. Use a formula to determine the distance between the gps locations like this: https://nathanrooy.github.io/posts/2016-09-07/haversine-with-python/. Then make your own determination on strength based on "range" and terrain. perhaps create a DB table of say 500 zip codes with label for terrain type rating. If 10 or something it's the worst terrain and you drop the strength by something that makes sense.
I have aGpsLocation model, this model has a latitude, a longitude and a radius property.
I want to find a GpsLocation based on its latitude and longitude and radius.
So lets say i am on location [52, 4], i want to find a GpsLocation instance that has these exact coordinates or is radius meters away.
I am using the geocoder gem but the near function does not do the job. Also tried monkey patching the near function so i can use a database column instead of a variable inside the query but still no luck, there are some mechanics that transform the lat/long to a range when providing a radius parameter.
Any help is appreciated
Calculating the distance between two points on a sphere can be done using the Haversine formula. There is a gem called haversine that can help. Or, if you're using PostgreSQL, there is also the earthdistance module.
However, you may find it easier to relax your definition of "near" somewhat, as dealing with circles can be annoying. Instead, consider using squares or rectangles.
Say you define "near" as within 10 miles. If you treat that as a plus or minus factor around the latitude and longitude of a given point, then you can do a simple query to find all nearby points at once, rather than a series of Haversine calculations. You query might look something like this:
# Only accurate in the U.S.
MILES_PER_LATITUDE = 69.0
MILES_PER_LONGITUDE = 55.0
min_latitude = thisLocation.latitude - (10.0 / MILES_PER_LATITUDE)
max_latitude = thisLocation.latitude + (10.0 / MILES_PER_LATITUDE)
min_longitude = thisLocation.longitude - (10.0 / MILES_PER_LONGITUDE)
max_longitude = thisLocation.longitude + (10.0 / MILES_PER_LONGITUDE)
nearby_points = GpsLocation.where(latitude: min_latitude..max_latitude).where(longitude: min_longitude..max_longitude)
currently, i have a table with locations (latitude, longitude). I calculate nearby calculations using sin, cos as described here
This seems rather slow. I am having the idea of pre-calculating the distance to a fixed point f and store it along the locations. When I now want to find locations nearby i just calculate distance to the same fix point and can then find them by doing some less or equal comparing.
Does my idea make sense? Is there a standard way to do that? I am in the thinking phase, so i do not have any code to show yet.
Your idea won't work unless all your locations are collinear, which most probably is not the case.
Are you using SQL to do the calculations? Are you properly using indexes? Maybe you could share a bit of your code with us.
Hello I'm a little confused about the answer I found here. The answer says that by increasing the length of the string you can increase the accuracy, which I understand. What I don't understand is how he is getting the numbers for the accuracy that he gets. He goes from a 110km x 110km to a 10km x 10km area by adding a digit. I want to get a 5m x 5m area. Can some give a more in depth explanation of how he got these figures.
Basically, he is talking about the accuracy of a specified point.
For example if we have a Location which we are interested, and we have two points defining that same location
- point1(156.34,-23.34), and
- Point2(156.342,-23.343)
So effectively the first point is somewhere between Latitude (156.335 - 156.344), Logitude (-23.335 - -23.344), and the second point Latitude (156.3415 - 156.3424) and Logitude (-23.3425 - -23.3434).
Basically normal GPS might get to near that 5 meter accuracy, though most often its anyway going to be less accurate, thus, what you need to to, is simply to use the whole value you get from the positioning module.
This is my first time posting a question here, but I have found a lot of help from other people's questions.
My question refers to the -distanceFromLocation: function in CLLocation. I had assumed that finding the distance between point A and point B would be the same as that between point B and point A, but I have found that it is not. I have tested this in a very simple case:
CLLocation *test1 = [[CLLocation alloc] initWithLatitude:37.529530 longitude:-122.259232];
CLLocation *test2 = [[CLLocation alloc] initWithLatitude:47.900002 longitude:-103.495102];
NSLog(#"%f vs %f",[test2 distanceFromLocation:test1],[test1 distanceFromLocation:test2]);
[test1 release];
[test2 release];
The output to this was 1907269.942754 vs 1908105.959114, a difference of almost 900 meters.
Though 900 meters may be a small percentage, I am trying to determine if the user is closer to something than an annotation and 900 meters can change that.
My question is, which one of these values, if any, is correct? Also if which location I test against is important, do I need to always test against the same location (e.g. user to destination and annotation to destination rather than destination to user and annotation to destination)?
Sorry that the sample is a bit out of context, as my project is rather large and this illustrates my problem. Any help would be appreciated as this has caused me quite a bit of confusion and frustration.
The error you're observing is 1 part in 2000. Presumably the algorithm used in this method is optimized for speed, so sorting a list of locations on distance is fast, rather than accurate to the millimeter.
If you need accurate results, don't use these methods but find another way. If you need reproducible results, order the arguments in a defined way, e.g. always start with the lower latitude.