Equation for distance between two points on the map using latitude and longitude iphone - iphone

I am trying to calculate the distance between two points (Pins) on the iPhone map.
Everything works fine however if you put one of the pin close to the left edge and the other one to the right edge of the map, distanceFromLocation method always returned the shortest distance between points (of course earth is not flat). I tried switching the CLLocations but it still shows me the shortest distance.
For my app I will need to calculate both, shortest and the longest distance between two pins.
The problem seems to be trivial but I can't come out with anything to solve it.
Any help or clues appreciated. Thanks!

There is a function MKCoordinateRegionForMapRect that returns a MKCoordinateRegion. Without having tried it, seems like all you would need to do is accurately specify the rect as the region bounded at one diagonal by one pin and the other diagonal by the other pin. You could use CGRectUnion twice giving the pin origins as rect origin and an arbitrarily small width and height.
Then the distance between the pins will be the square root of the distances represented by the latitudeDelta and longitudeDelta returned in the span squared and added. (i.e. Pythagoras theorem, the two side lengths are the horizontal and vertical sides of a triangle and the diagonal is a straight line between your points.)
Finding latitudeDelta in metres is easy, each degree of latitude is 111km.
To find meters for the longitudeDelta you need a little bit more code.
#define EARTH_EQUATORIAL_RADIUS (6378137.0)
#define WGS84_CONSTANT (0.99664719)
#define degreesToRadians(x) (M_PI * (x) / 180.0)
// accepts decimal degrees. Convert from HMS first if that's what you have
double lengthOfDegreeLongitude(double degrees) {
double tanDegrees = tanf(degreesToRadians(degrees));
double beta = tanDegrees * WGS84_CONSTANT;
double lengthOfDegree = cos(atan(beta)) * EARTH_EQUATORIAL_RADIUS * M_PI / 180.0;
return lengthOfDegree;
}
Give that function the longitude of the location you are interested in and multiply the result by the longitudeDelta in degrees to get a distance in meters. Then you have a horizontal distance and a vertical and you can find the diagonal which is what you were looking for.
Inaccuracy will get bad if you are looking for a distance which is very large in N-S as the length of a degree longitude will be varying over the calculation. And you can refine the 111km for a degree of latitude a bit too, that's just from memory.

Related

X,Y coordinates with reference points and find lat and long

I have a floor map that is relayed on top of a grid and have the length and width of the floor along with 3 reference points that has x,y, lat, long.
Now I have some x,y that lies within the floor map and need to derive the lat and long for those points.
Is there a way to achieve that? Preferably Java but even a formula would do or some documentation.

Calculate angle between 2 geographic coordinates in MATLAB

I'm trying to calculate the angle between 2 geographic (Latitude,Longitude) points in MATLAB. The points are:
(-65.226,125.5) and (-65.236,125.433).
I used the MATLAB function, azimuth, as:
azimuth(-65.226,125.5,-65.236,125.433)
I convert the result to radians, and plotting this using quiver, I get the following plot:
I want the red vector to point from the top right dot to the bottom left dot.
The points are at fairly high latitude (~65S), and the separation of the points is low (about 0.1 degrees). Thus, I can't really understand how the curvature of the earth could affect the azimuth prediction that much..
Does anyone have any experience with azimuth in MATLAB, or have a better suggestion to calculating the angle between the coordinate pairs?
Thanks!
Here you can detailed information and formulae on how to find angle between two latitude-longitude points.

Convert Latitude / Longitude in Degree/Radians?

How can i convert Latitude and longitude in degree/radians?
Do you guys any formula or any idea?
I want to show it on MapKit.
Thanks.....
Since Latitude and Longitude are measured in degrees, you can use the following formula to convert to radians, and back to degrees:
Radians = Degrees * PI / 180
and on the inverse,
Degrees = Radians * 180 / PI
If you look at earth like a sphere, latitude and longitude are already given in units of degrees. Longitude is expressed as -180 degrees (-pi radians) to 180 degrees (pi radians) with 0 degrees centered at the prime meridian. Latitude is expressed as -90 degrees (-pi/2 radians) to 90 degrees (pi/2 radians) with respect to the equator. This is already a spherical coordinate system (depending on the caveats I give below) with earth's radius approximately 6371 km.
So just convert by multiplying by pi/180 as you would for convert degrees to radians in any normal sense. If you want to use those radians for doing something specific like calculating distances between two lat/lons then you should look at some pre-existing sources.
Similar questions have been asked before, i.e. Convert Lat-Lon to Cartesian Coordinates.
Generally speaking, the 'correct' answer for a lot of conversion quesitons depends on what error is acceptable in your answer (can it be off 1 mile for distances of 20 miles, etc.) and the model of the world is appropriate in your problem domain. The world is better approximated by an ellipsoid (squashed sphere) than a sphere, but it is easier to perform the calculations assuming earth is a sphere and the error introduced can be minimal. Especially if your program is just looking for 'rough' answers that won't be used for, say, engineering projects.
It is likely that the lat-lons you have are given in a coordinate system called WGS-84 which is what most hardware GPS units use, which assumes an ellipsoid model.
Note that I had a lot more sources, but I guess I have low reputation so I can only post two links. I would suggest reading on wikipedia about WGS-84, earth's radius, spherical coordinates, prime meridian, and equator for some visual references.

How to calculate Cross-Track error (GPS/Core Location)

Does anyone know how to determine determine the "Cross-Track Error"?
For those who are unfamiliar: You are driving along a line from Point "A" to point "B". When in transit, when you veer off that line, the distance from your current position to the line is the cross-track error.
I have a simple algorithm now which works, using basic geometry with the latitude and longitude of the three points - the problem is that it does not take "great circle" calculations into account (i.e. actual meters-per-degree longitude varies depending on your latitude, and does not equal that of the latitude).
In other words - if you know of a "great circle" formula for determining this, please let me know - but it is not a straight Cartesian geometry problem.
Brad,
I'm not sure which ellipsoid model you are using since you don't say. If you aren't using an ellipsoid model in you current calculations, you may find this helpful:
http://www.movable-type.co.uk/scripts/latlong-vincenty.html
The Vincenty algorithm is more accurate that the Haversine algorithm.
Once you have accurate distances for A-B, A-C and B-C, it should be straightforward to determine your distance from C to the line A-B. Something like a binary search of the distances from points on A-B to C, looking for the shortest value.
James
This is this text from the link to the accepted answer - should it go dead:
Here’s a new one: I’ve sometimes been asked about distance of a point from a great-circle path (sometimes called cross track error).
Formula: dxt = asin( sin(δ13) ⋅ sin(θ13−θ12) ) ⋅ R
where:
δ13 is (angular) distance from start point to third point
θ13 is (initial) bearing from start point to third point
θ12 is (initial) bearing from start point to end point
R is the earth’s radius
JavaScript:
var δ13 = d13 / R;
var dXt = Math.asin(Math.sin(δ13)*Math.sin(θ13-θ12)) * R;
Here, the great-circle path is identified by a start point and an end point – depending on what initial data you’re working from, you can use the formulas above to obtain the relevant distance and bearings. The sign of dxt tells you which side of the path the third point is on.
The along-track distance, from the start point to the closest point on the path to the third point, is:
Formula: dat = acos( cos(δ13) / cos(δxt) ) ⋅ R
where:
δ13 is (angular) distance from start point to third point
δxt is (angular) cross-track distance
R is the earth’s radius
JavaScript:
var dAt = Math.acos(Math.cos(δ13)/Math.cos(dXt/R)) * R;
If dealing with latitude and longitude, the forumla you're looking for is the "Haversine" formula. It takes into account the curvature of the earth's surface.
http://en.wikipedia.org/wiki/Haversine_formula
Good luck.
The CLLocation API provides
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
Which uses a formula (it does not specify whether is it Haversine or
Vincenty or other) that takes into account the curvature of the earth. This returns the distance in meters between the 2 CLLocations but does not account for any difference in altitude.

Matlab matrix translation and rotation multiple times

I have a map of individual trees from a forest stored as x,y points in a matrix. I call it fixedPositions. It's cartesian and (0,0) is the origin.
Given a velocity and a heading, i.e. .5 m/s and 60 degrees (2 o'clock equivalent on a watch), how do I rotate the x,y points, so that the new origin is centered at (.5cos(60),.5sin(60)) and 60 degrees is now at the top of the screen?
Then if I were to give you another heading and speed, i.e. 0 degrees and 2m/s, it should calculate it from the last point, not the original fixedPositions origin.
I've wasted my day trying to figure this out. I wish I took matrix algebra but I'm at a loss.
I tried doing cos(30) and even those wouldn't compute correctly, which after an hour I realize were in radians.
I'd try the following: In your object, you already have a property heading. Now you add another property, currentPosition (an maybe rename them to heading_robot and currentPos_robot). heading as well as currentPosition should always be relative to the original coordinate system
Then you add a new method, updatePosition that takes (newHeading, distance) as input. This method will update both heading and currentPosition, by first adding the angle in newHeading to the angle in heading, after which you update currentPosition by adding [distance*cos(heading),distance*sin(heading)] (check for signs of sin/cos here!) to the old value of currentPosition.
Finally, to get the view of the landscape (i.e. apparentPositions), you run bsxfun(#minus,fixedPositions,currentPosition) to move the origin to where the robot is at this moment, and then you multiply with the 2D rotation matrix using the angle stored in heading.
You just first translate the coordinates (-0.5cos(60),-0.5sin(60)) to take the origin to your target point.
Then rotate by multiplying the coordinates by a rotation matrix.
Of course, most programming languages use radians as angle units, so that instead of 60 you must enter 60 * PI / 180