我对使用坐标很感兴趣,我想知道如何以米为单位获得两点(坐标)之间的距离。经过长时间的搜索,我找到了Haversine公式,以及它的Objective-C实现here。
以下是(我自己修改了一下):
- (CGFloat)directMetersFromCoordinate:(CLLocation *)from toCoordinate:(CLLocation *)to {
static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
static const double EARTH_RADIUS_IN_METERS = 6372797.560856;
double latitudeArc = (from.coordinate.latitude - to.coordinate.latitude) * DEG_TO_RAD;
double longitudeArc = (from.coordinate.longitude - to.coordinate.longitude) * DEG_TO_RAD;
double latitudeH = sin(latitudeArc * 0.5);
latitudeH *= latitudeH;
double lontitudeH = sin(longitudeArc * 0.5);
lontitudeH *= lontitudeH;
double tmp = cos(from.coordinate.latitude*DEG_TO_RAD) * cos(to.coordinate.latitude*DEG_TO_RAD);
return EARTH_RADIUS_IN_METERS * 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH)); }
我的问题是: 如何为当前位置获得100米距离(纬度和经度)? 这个公式对我来说太复杂了,我不明白,所以我不能“编码回来”得到我想要的结果。
我只需要实际位置(巴黎,东京,伦敦,纽约,等等)和纬度的(浮动)数字以及经度的(浮点)数字,其中(浮点数)代表距离的100米距离实际位置。
如果您打开this页面,此处可以“计算出”两点之间的100米距离(“实际”和100米之外的距离)。
例如:
Point1:47.0,19.0 Point2:47.0,19.0013190 ---那是0.1000公里(100米)的距离。
Point1:47.0,19.0 Point2:47.0008995,19.0 ---也是0.1000公里(100米)的距离。
在这里你可以看到,在那个坐标(纬度47.0和经度19.0)100米距离是0.0008995(纬度)和0.0013190(经度)。
我希望在Haversine Formula的帮助下得到这些数据,只是不知道,如何。
你能帮我解决一下吗?
谢谢!
更新 谢谢你的回答,现在我没有时间尝试,但据我所知,我没有完全解释我想要的东西。 也许这是一个更好的例子,我想如何使用这些“100米”:
所以,现在我在坐标“lat x”和“lon y”。在另一个给定的坐标“lat a”和“lon b”还有另一点(比如说酒店)。 我的问题是:如果这家酒店离我不到100米,怎么能算出来呢?所以没关系,如果它只有5米或99米,它们都比我远离100米的距离还小(或相等)。
使用我提供的代码,我可以计算出来,这就是该公式的用途。
但是,让我说,我有一百万个其他坐标(酒店位置),我想与之合作。我只需要一份清单,距离我(距离我不到100米)。所以是的,这是我身边的一个半径为100米的圆圈,我需要在那里得到结果。
花费更多的时间和资源来获取这些“百万”酒店的所有坐标并逐一计算距离,这就是为什么我认为计算出来要容易得多,在纬度上有多少100米和经度(改变我们在不同位置的值,'为什么我不能简单地使用我在上面的例子中计算出的那些)。 所以,如果我知道在伦敦的坐标(如果我在那里)有多少100米的纬度和经度,我可以简单地得到距离我100米远的酒店列表。简单划分:
if
((hotelLocation.coordinate.latitude <= (myLocation.coordinate.latitude + "100metersInLatitude")) || (hotelLocation.coordinate.latitude >= (myLocation.coordinate.latitude - "100metersInLatitude")))
&&
((hotelLocation.coordinate.longitude <= (myLocation.coordinate.longitude + "100metersInLongitude")) || (hotelLocation.coordinate.longitude >= (myLocation.coordinate.longitude - "100metersInLongitude")))
{
NSLog(@"Be Happy :-) !");
}
我只需要这些“100metersInLatitude”和“100metersInLongitude”,总是从“myLocation”计算。
哇,我希望,有人会理解我刚刚写下来的东西,因为这对我来说并不容易,也不是......: - )))
答案 0 :(得分:2)
假设你有一个纬度和经度的点,并且你想找到另一个在轴承b上距离为d的点,当距离很小时(你说的“100米”,这个点在表面非常小)那么你可以做一个简单的近似 - 将地球表面局部视为“平坦”。这是一个实现此功能的简单C程序(使用上面的数字)。我更新了它以包括“准确”的公式 - 它只是一些计算,但它在所有距离(而不仅仅是短距离)都是准确的。我使用的等式来自你引用的链接 - 副标题“目的地点给定距离和起点承载”
更新 - 我将准确的计算移动到一个单独的函数中,并添加了一个循环来计算从0到359的所有整数轴承的新点,每30秒打印一次。这给了我在我最初评论中谈到的“圈子”。
#include <stdio.h>
#include <math.h>
double radians(double x) {
return acos(0.0) * x / 90.0;
}
void calcNewPosition(double lat, double lon, double bearing, double d, double *newLat, double *newLon) {
double lat1, lon1, br, pi;
double Re = 6371000;
// convert everything to radians first:
lat1 = radians(lat);
lon1 = radians(lon);
br = radians(bearing);
pi = 2 * acos(0.0);
double lat2, lon2;
lat2 = asin( sin(lat1) * cos(d/Re) +
cos( lat1 ) * sin( d / Re ) * cos(br ) );
lon2 = lon1 + atan2(sin(br) * sin( d / Re ) * cos( lat1 ), \
cos( d / Re ) - sin(lat1 ) * sin( lat2 ) );
*newLat = 180. * lat2 / pi;
*newLon = 180. * lon2 / pi;
}
int main(void) {
double lon = 47., lat=19.;
double newLongitude, newLatitude;
double dx, dy, dLong, dLat;
double Re = 6371000, d = 100, bearing = 0.0;
double pi;
double lat1, lon1, br;
// convert everything to radians first:
lat1 = radians(lat);
lon1 = radians(lon);
br = radians(bearing);
pi = 2 * acos(0.0);
// approximate calculation - using equirectangular approximation
// and noting that distance between meridians (lines of longitude)
// get closer at higher latitudes, with cos(latitude).
dx = d * sin(br); // distance in E-W direction
dy = d * cos(br); // distance in N-S direction
dLat = 360 * dy / (2.0 * pi * Re); // convert N-S to degrees latitude
dLong = 360 * dx / (2.0 * pi * Re * cos(lat1)); // convert E-W to degrees longitude
newLatitude = lat + dLat;
newLongitude = lon + dLong;
printf("simple forumula: the new position is %.8lf lon, %.8lf lat\n", newLongitude, newLatitude);
// more accurate formula: based on http://www.movable-type.co.uk/scripts/latlong.html
double lat2, lon2;
calcNewPosition(lat, lon, bearing, d, &lat2, &lon2);
printf("more accurate: the new position is %.8lf lon, %.8lf lat\n", lon2, lat2);
// now loop over all bearings and compute the "circle of points":
int iBearing;
double lonArray[360], latArray[360];
for(iBearing = 0; iBearing < 360; iBearing++) {
calcNewPosition(lat, lon, (double)iBearing, d, &latArray[iBearing], &lonArray[iBearing]);
if (iBearing % 30 == 0) printf("bearing %03d: new lat = %.8lf, new lon = %.8lf\n", iBearing, latArray[iBearing], lonArray[iBearing]);
}
return 0;
}
这是
的输出simple forumula: the new position is 47.00000000 lon, 19.00089932 lat
more accurate: the new position is 47.00000000 lon, 19.00089932 lat
bearing 000: new lat = 19.00089932, new lon = 47.00000000
bearing 030: new lat = 19.00077883, new lon = 47.00047557
bearing 060: new lat = 19.00044966, new lon = 47.00082371
bearing 090: new lat = 19.00000000, new lon = 47.00095114
bearing 120: new lat = 18.99955034, new lon = 47.00082371
bearing 150: new lat = 18.99922116, new lon = 47.00047557
bearing 180: new lat = 18.99910068, new lon = 47.00000000
bearing 210: new lat = 18.99922116, new lon = 46.99952443
bearing 240: new lat = 18.99955034, new lon = 46.99917629
bearing 270: new lat = 19.00000000, new lon = 46.99904886
bearing 300: new lat = 19.00044966, new lon = 46.99917629
bearing 330: new lat = 19.00077883, new lon = 46.99952443
正如你所看到的,它精确到几分之一米(你的代码给出了19.0008995 - 实际上你的结果可能在最后一位数字中是“错误的”,因为这两种方法同意8位有效数字,即使他们使用不同的方程式。
答案 1 :(得分:1)
如果OP希望距离当前位置一个距离(100米)的位置没有提供所需的方位,那么问题就不是真正的问题,在该点周围的圆圈中存在无限数量的点。
所以,这个答案可能是也可能不是OP想要的,这是CLLocation
计算两点之间距离的方法。
创建两个CLLocation
点并使用方法Have you looked at the
CLLocation method
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location`。
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:)latitude1 longitude:longitude1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:)latitude2 longitude:longitude2];
double distance = [location1 distanceFromLocation:location2];
答案 2 :(得分:0)
赤道地球半径= 6,371公里。赤道被划分为360度经度,因此赤道处的每个度数大约为111.32 km。从赤道移向极点,这个距离在极点处减小到零。计算不同纬度的距离乘以纬度的余弦
3位小数,0.001度近似值 赤道111.32米 在N / S 30度时96.41米
N / S 45度78.71米
55.66米,60度N / S
在75度N / S时28.82米
对于小距离(100米),可以在equirectangular projection上使用毕达哥拉斯定理来计算距离。这比Haversine或Cosines的球面定律简单。
var R = 6371; // km
lat / lng in radians
在伪代码中我不知道Objective-C
var x = (lng2-lng1) * cos((lat1+lat2)/2);
var y = (lat2-lat1);
var d = sqrt(x*x + y*y) * R;