1

我对使用坐标很感兴趣,我想知道,如何以米为单位获得两点(坐标)之间的距离。经过长时间的搜索,我在这里找到了 Haversine 公式,以及它的 Objective-C 实现。

如下(我为自己修改了一点):

- (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 米的距离。

如果您打开页面,您可以在此处“计算”两点之间的 100 米距离(“实际”和一个 100 米距离)。

例如:

Point1: 47.0, 19.0 Point2: 47.0, 19.0013190 --- 那是 0.1000 km (100 m) 的距离。

Point1: 47.0, 19.0 Point2: 47.0008995, 19.0 --- 也是 0.1000 km (100 m) 距离。

在这里你可以看到,在那个坐标(纬度 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”计算。

哇,我希望,有人会理解我刚刚写下的内容,因为这对我来说并不容易,也不是...... :-)))

4

3 回答 3

2

假设您有一个具有经纬度的点,并且您想在距离很小时(您说“100米”在地球表面上非常小)找到另一个在方位b上距离d的点)那么你可以做一个简单的近似 - 将地球表面局部视为“平坦”。这是一个实现这一点的简单 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 个有效数字,即使它们使用不同方程)。

于 2013-12-29T18:18:26.110 回答
1

如果 OP 想要一个与当前位置相距一定距离(100 米)的位置而没有提供所需的方位,那么这个问题就无法真正回答,围绕该点的圆圈中有无数个点。

因此,这个答案可能是也可能不是 OP 想要的,它是一种CLLocation计算两点之间距离的方法。

创建两个CLLocation点并使用方法Have you looked at theCLLocation 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];
于 2013-12-29T18:31:45.317 回答
0

赤道处的地球半径 = 6,371 公里。赤道被划分为 360 度经度,因此赤道处的每一度代表大约 111.32 公里。从赤道向极点移动,该距离在极点处减小到零。要计算不同纬度的距离,请将其乘以纬度的余弦

3 位小数,0.001 度近似于赤道 111.32 米
30 度 N/S
96.41 米 78.71 米 45 度 N/S
55.66 米 60 度 N/S
28.82 米 75 度 N/S

对于小距离(100 米),毕达哥拉斯定理可用于等角投影来计算距离。这比 Haversine 或 Cosines 球面定律简单。

变量 R = 6371; // km
lat/lng 以弧度为单位

在伪代码中,因为我不知道 Objective-C

var x = (lng2-lng1) * cos((lat1+lat2)/2);
var y = (lat2-lat1);
var d = sqrt(x*x + y*y) * R;
于 2013-12-29T22:24:26.717 回答