X/Y Pixels to Longitude & Latitude - iphone

Hey i succesfully convert longitude&latitude to x/y coordinates by using this formula:
// These should roughly box Germany - use the actual values appropriate to your image
double minLat = 54.8;
double minLong = 5.5;
double maxLat = 47.2;
double maxLong = 15.1;
// Map image size (in points)
CGSize mapSize = mapView.frame.size;
// Determine the map scale (points per degree)
double xScale = mapSize.width / (maxLong - minLong);
double yScale = mapSize.height / (maxLat - minLat);
// Latitude and longitude of city
double spotLat = 49.993615;
double spotLong = 8.242493;
// position of map image for point
CGFloat x = (spotLong - minLong) * xScale;
CGFloat y - (spotLat - minLat) * yScale;
But now i need to convert it the other way. Lets say i got x = 83 and y = 294. How can i get the latitude & longitude from that ?
Thanks

IF...
x = (spotLong - minLong) * xScale;
Then...
(x / xScale) + minLong = spotLong;
Just rearrange the equation surely?
Then do the same with y for the Latitude.

Related

Manhattan Distance for two geolocations

Let's say I have two locations represented by latitude and longitude.
Location 1 : 37.5613 , 126.978
Location 2 : 37.5776 , 126.973
How can I calculate the distance using Manhattan distance ?
Edit : I know the formula for calculating Manhattan distance like stated by Emd4600 on the answer which is |x1-x2| - |y1-y2| but I think it's for Cartesian. If it is can be applied that straight forward |37.5613-37.5776| + |126.978-126.973| what is the distance unit of the result ?
Given a plane with p1 at (x1, y1) and p2 at (x2, y2), it is, the formula to calculate the Manhattan Distance is |x1 - x2| + |y1 - y2|. (that is, the difference between the latitudes and the longitudes). So, in your case, it would be:
|126.978 - 126.973| + |37.5613 - 37.5776| = 0.0213
EDIT: As you have said, that would give us the difference in latitude-longitude units. Basing on this webpage, this is what I think you must do to convert it to the metric system. I haven't tried it, so I don't know if it's correct:
First, we get the latitude difference:
Δφ = |Δ2 - Δ1|
Δφ = |37.5613 - 37.5776| = 0.0163
Now, the longitude difference:
Δλ = |λ2 - λ1|
Δλ = |126.978 - 126.973| = 0.005
Now, we will use the haversine formula. In the webpage it uses a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2), but that would give us a straight-line distance. So to do it with Manhattan distance, we will do the latitude and longitude distances sepparatedly.
First, we get the latitude distance, as if longitude was 0 (that's why a big part of the formula got ommited):
a = sin²(Δφ/2)
c = 2 ⋅ atan2( √a, √(1−a) )
latitudeDistance = R ⋅ c // R is the Earth's radius, 6,371km
Now, the longitude distance, as if the latitude was 0:
a = sin²(Δλ/2)
c = 2 ⋅ atan2( √a, √(1−a) )
longitudeDistance = R ⋅ c // R is the Earth's radius, 6,371km
Finally, just add up |latitudeDistance| + |longitudeDistance|.
For example, calculating Manhattan Distance of Point1 and Point2.
Simply apply LatLng distance function by projecting the "Point2" on to the same Lat or Lng of the "Point1".
def distance(lat1, lng1, lat2, lng2, coordinates):
lat1 = radians(lat1)
lat2 = radians(lat2)
lon1 = radians(lng1)
lon2 = radians(lng2)
d_lon = lon2 - lon1
d_lat = lat2 - lat1
if coordinates['LatLong']:
r = 6373.0
a = (np.sin(d_lat/2.0))**2 + np.cos(lat1) * \
np.cos(lat2) * (np.sin(d_lon/2.0))**2
c = 2 * np.arcsin(np.sqrt(a))
total_distance = r * c
if coordinates['XY']:
total_distance = math.sqrt(d_lon * d_lon + d_lat * d_lat)
return total_distance
def latlng2manhattan(lat1, lng1, lat2, lng2):
coordinates = {"LatLong": True, "XY": False}
# direction = 1
if lat1 == 0:
lat1 = lat2
# if lng1 < lng2:
# direction = -1
if lng1 == 0:
lng1 = lng2
# if lat1 < lat2:
# direction = -1
# mh_dist = direction * distance(lat1, lng1, lat2, lng2, coordinates) * 3280.84 # km to ft
mh_dist = distance(lat1, lng1, lat2, lng2, coordinates) * 3280.84
return mh_dist
df["y_mh"] = df["y_lat"].apply(lambda x: latlng2manhattan(0, x, center_long, center_lat))
df["x_mh"] = df["x_long"].apply(lambda x: latlng2manhattan(x, 0, center_long, center_lat))

How to get angle between two POI?

How do I calculate the angle in degrees between the coordinates of two POIs (points of interest) on an iPhone map application?
I'm guessing you try to calculate the degrees between the coordinates of two points of interest (POI).
Calculating the arc of a great circle:
+(float) greatCircleFrom:(CLLocation*)first
to:(CLLocation*)second {
int radius = 6371; // 6371km is the radius of the earth
float dLat = second.coordinate.latitude-first.coordinate.latitude;
float dLon = second.coordinate.longitude-first.coordinate.longitude;
float a = pow(sin(dLat/2),2) + cos(first.coordinate.latitude)*cos(second.coordinate.latitude) * pow(sin(dLon/2),2);
float c = 2 * atan2(sqrt(a),sqrt(1-a));
float d = radius * c;
return d;
}
Another option is to pretend you are on cartesian coordinates (faster but not without error on long distances):
+(float)angleFromCoordinate:(CLLocationCoordinate2D)first
toCoordinate:(CLLocationCoordinate2D)second {
float deltaLongitude = second.longitude - first.longitude;
float deltaLatitude = second.latitude - first.latitude;
float angle = (M_PI * .5f) - atan(deltaLatitude / deltaLongitude);
if (deltaLongitude > 0) return angle;
else if (deltaLongitude < 0) return angle + M_PI;
else if (deltaLatitude < 0) return M_PI;
return 0.0f;
}
If you want the result in degrees instead radians, you have to apply the following conversion:
#define RADIANS_TO_DEGREES(radians) ((radians) * 180.0 / M_PI)
You are calculating the 'Bearing' from one point to another here. There's a whole bunch of formula for that, and lots of other geographic quantities like distance and cross-track error, on this web page:
http://www.movable-type.co.uk/scripts/latlong.html
the formulae are in several formats so you can easily convert to whatever language you need for your iPhone. There's also javascript calculators so you can test your code gets the same answers as theirs.
If the other solutions dont work for you try this:
- (int)getInitialBearingFrom:(CLLocation *)first
to:(CLLocation *)second
{
float lat1 = [self degreesToRad:first.coordinate.latitude];
float lat2 = [self degreesToRad:second.coordinate.latitude];
float lon1 = [self degreesToRad:first.coordinate.longitude];
float lon2 = [self degreesToRad:second.coordinate.longitude];
float dLon = lon2 - lon1;
float y = sin (dLon) * cos (lat2);
float x1 = cos (lat1) * sin (lat2);
float x2 = sin (lat1) * cos (lat2) * cos (dLon);
float x = x1 - x2;
float bearingRadRaw = atan2f (y, x);
float bearingDegRaw = bearingRadRaw * 180 / M_PI;
int bearing = ((int) bearingDegRaw + 360) % 360; // +- 180 deg to 360 deg
return bearing;
}
For final bearing, simply take the initial bearing from the end point to the start point and reverse it (using θ = (θ+180) % 360).
You need these 2 helpers:
-(float)radToDegrees:(float)radians
{
return radians * 180 / M_PI;
}
-(float)degreesToRad:(float)degrees
{
return degrees * M_PI /180;
}

Distance between 2 latlon points

I want to work out the distance between 2 latlon points.
The simple distance formula http://www.purplemath.com/modules/distform.htm is not correct because we are dealing with 2 different measures (lat and lon).
Is there a standard solution to this problem?
use Haversine formula.
see this link http://www.movable-type.co.uk/scripts/latlong.html
try this,
This uses the ‘haversine’ formula to calculate great-circle distances between the two points – that is, the shortest distance over the earth’s surface – giving an ‘as-the-crow-flies’ distance between the points (ignoring any hills!).
Haversine formula:
R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
or go with the link,http://www.movable-type.co.uk/scripts/latlong.html
Try this javascript haversine function alongside the torad() helper function, which I use for my map app
function calculateHaversineDistance(lat1x, lon1, lat2x, lon2) {
var R = 6371; // km
var dLat = toRad(lat2x-lat1x);
var dLon = toRad(lon2-lon1);
var lat1 = toRad(lat1x);
var lat2 = toRad(lat2x);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
function toRad(x) {
return x * Math.PI / 180;
}
Hope this helps.

Angle between 2 GPS Coordinates

I'm working in another iPhone App that uses AR, and I'm creating my own framework, but I'm having trouble trying to get the angle of a second coordinate relative to the current device position, anyone know a good resource that could help me with this?
Thanks in advance!
If the two points are close enough together, and well away from the poles, you can use some simple trig:
float dy = lat2 - lat1;
float dx = cosf(M_PI/180*lat1)*(long2 - long1);
float angle = atan2f(dy, dx);
EDIT: I forgot to mention that latN and longN — and therefore dx and dy — can be in degrees or radians, so long as you don't mix units. angle, however, will always come back in radians. Of course, you can get it back to degrees if you multiply by 180/M_PI.
Here is the android version of this code
import com.google.android.maps.GeoPoint;
public double calculateAngle(GeoPoint startPoint, GeoPoint endPoint) {
double lat1 = startPoint.getLatitudeE6() / 1E6;
double lat2 = endPoint.getLatitudeE6() / 1E6;
double long2 = startPoint.getLongitudeE6() / 1E6;
double long1 = endPoint.getLongitudeE6() / 1E6;
double dy = lat2 - lat1;
double dx = Math.cos(Math.PI / 180 * lat1) * (long2 - long1);
double angle = Math.atan2(dy, dx);
return angle;
}

SouthWest and NorthEast Points

I am developing an iphone application which uses google API's.I have a set of latitudes and logitudes .I need to find the South west and North East points from these points .How can i do this?
thanks in advance
Given:
A point (LAT, LNG)
A distance or radius DIST
1° of latitude ~= 69 miles ~= 111 kms
1° of longitude ~= cos(latitude)*69 ~= cos(latitude)*111
The SW point is:
lng_sw = LNG - (DIST / (abs(cos(radians(LAT))) * 111))
lat_sw = LAT - (DIST / 111)
The NE point is:
lng_ne = LNG + (DIST / (abs(cos(radians(LAT))) * 111))
lat_ne = LAT + (DIST / 111)
If you use miles as your unit of measure use 69 instead of 111.
This is C# code if anybody needs
private double DegreeToRadian(double angle) {
return Math.PI * angle / 180.0;
}
private bool CalculateNeSw(double distance, double lat, double lng, out MapPoint[] points) {
/*
* 1° of latitude ~= 69 miles ~= 111 kms, 1° of longitude ~= cos(latitude)*69 ~= cos(latitude)*111
* SW.LNG = LNG - (DIST / abs(cos(radians(LAT))) * 111), SW.LAT = LAT - (DIST / 111)
* NE.LNG = LNG + (DIST / abs(cos(radians(LAT))) * 111), NE.LAT = LAT + (DIST / 111)
*/
points = new MapPoint[2];
try {
double deltaLat = distance / 69;
double deltaLng = distance / Math.Abs(Math.Cos(DegreeToRadian(lat)) * 69);
/* South-West */
points[1] = new MapPoint {
Lng = (lng - deltaLng).ToString(),
Lat = (lat - deltaLat).ToString(),
IsSet = true,
FormattedAddress = "South-West"
};
/* North-East */
points[0] = new MapPoint {
Lng = (lng + deltaLng).ToString(),
Lat = (lat + deltaLat).ToString(),
IsSet = true,
FormattedAddress = "North-East"
};
return true;
}
catch (Exception ex) {
return false;
}}
Notes:
MapPoint is a simple Data class with Lat/Lon properties
I used miles ==> 69