计算距一个坐标的新坐标 x 米和 y 度

发布于 2024-11-19 08:27:38 字数 273 浏览 4 评论 0 原文

我一定是在文档中遗漏了一些东西,我认为这应该很容易...

如果我有一个坐标并且想要在某个方向获得 x 米外的新坐标。我该怎么做?

我正在寻找类似

-(CLLocationCooperative2D) 翻译坐标:(CLLocationCooperative2D) 坐标 翻译米:(int)米 翻译度:(双)度;

谢谢!

I must be missing somthing out in the docs, I thought this should be easy...

If I have one coordinate and want to get a new coordinate x meters away, in some direction. How do I do this?

I am looking for something like

-(CLLocationCoordinate2D) translateCoordinate:(CLLocationCoordinate2D)coordinate
translateMeters:(int)meters
translateDegrees:(double)degrees;

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

娇妻 2024-11-26 08:27:38

不幸的是,API 中没有提供这样的函数,因此您必须编写自己的函数。

此站点提供了一些涉及纬度/经度的计算和示例 JavaScript 代码。具体来说,标题为“给定距离起点的目的地点和方位”的部分显示了如何计算您所要求的内容。

JavaScript 代码位于该页面的底部,这是将其转换为 Objective-C 的一种可能方法:

- (double)radiansFromDegrees:(double)degrees
{
    return degrees * (M_PI/180.0);    
}

- (double)degreesFromRadians:(double)radians
{
    return radians * (180.0/M_PI);
}

- (CLLocationCoordinate2D)coordinateFromCoord:
        (CLLocationCoordinate2D)fromCoord 
        atDistanceKm:(double)distanceKm 
        atBearingDegrees:(double)bearingDegrees
{
    double distanceRadians = distanceKm / 6371.0;
      //6,371 = Earth's radius in km
    double bearingRadians = [self radiansFromDegrees:bearingDegrees];
    double fromLatRadians = [self radiansFromDegrees:fromCoord.latitude];
    double fromLonRadians = [self radiansFromDegrees:fromCoord.longitude];

    double toLatRadians = asin( sin(fromLatRadians) * cos(distanceRadians) 
        + cos(fromLatRadians) * sin(distanceRadians) * cos(bearingRadians) );

    double toLonRadians = fromLonRadians + atan2(sin(bearingRadians) 
        * sin(distanceRadians) * cos(fromLatRadians), cos(distanceRadians) 
        - sin(fromLatRadians) * sin(toLatRadians));

    // adjust toLonRadians to be in the range -180 to +180...
    toLonRadians = fmod((toLonRadians + 3*M_PI), (2*M_PI)) - M_PI;

    CLLocationCoordinate2D result;
    result.latitude = [self degreesFromRadians:toLatRadians];
    result.longitude = [self degreesFromRadians:toLonRadians];
    return result;
}

在 JS 代码中,它包含 此链接显示了对于大于地球周长 1/4 的距离的更准确计算。

另请注意,上述代码接受以公里为单位的距离,因此请务必在通过之前将米除以 1000.0。

Unfortunately, there's no such function provided in the API, so you'll have to write your own.

This site gives several calculations involving latitude/longitude and sample JavaScript code. Specifically, the section titled "Destination point given distance and bearing from start point" shows how to calculate what you're asking.

The JavaScript code is at the bottom of that page and here's one possible way to convert it to Objective-C:

- (double)radiansFromDegrees:(double)degrees
{
    return degrees * (M_PI/180.0);    
}

- (double)degreesFromRadians:(double)radians
{
    return radians * (180.0/M_PI);
}

- (CLLocationCoordinate2D)coordinateFromCoord:
        (CLLocationCoordinate2D)fromCoord 
        atDistanceKm:(double)distanceKm 
        atBearingDegrees:(double)bearingDegrees
{
    double distanceRadians = distanceKm / 6371.0;
      //6,371 = Earth's radius in km
    double bearingRadians = [self radiansFromDegrees:bearingDegrees];
    double fromLatRadians = [self radiansFromDegrees:fromCoord.latitude];
    double fromLonRadians = [self radiansFromDegrees:fromCoord.longitude];

    double toLatRadians = asin( sin(fromLatRadians) * cos(distanceRadians) 
        + cos(fromLatRadians) * sin(distanceRadians) * cos(bearingRadians) );

    double toLonRadians = fromLonRadians + atan2(sin(bearingRadians) 
        * sin(distanceRadians) * cos(fromLatRadians), cos(distanceRadians) 
        - sin(fromLatRadians) * sin(toLatRadians));

    // adjust toLonRadians to be in the range -180 to +180...
    toLonRadians = fmod((toLonRadians + 3*M_PI), (2*M_PI)) - M_PI;

    CLLocationCoordinate2D result;
    result.latitude = [self degreesFromRadians:toLatRadians];
    result.longitude = [self degreesFromRadians:toLonRadians];
    return result;
}

In the JS code, it contains this link which shows a more accurate calculation for distances greater than 1/4 of the Earth's circumference.

Also note the above code accepts distance in km so be sure to divide meters by 1000.0 before passing.

把梦留给海 2024-11-26 08:27:38

我找到了一种方法,必须深入挖掘才能找到正确的结构和函数。我最终没有使用度数而是使用米来表示纬度和经度。

我是这样做的:

-(CLLocationCoordinate2D)translateCoord:(CLLocationCoordinate2D)coord MetersLat:(double)metersLat MetersLong:(double)metersLong{

    CLLocationCoordinate2D tempCoord;

    MKCoordinateRegion tempRegion = MKCoordinateRegionMakeWithDistance(coord, metersLat, metersLong);
    MKCoordinateSpan tempSpan = tempRegion.span;

    tempCoord.latitude = coord.latitude + tempSpan.latitudeDelta;
    tempCoord.longitude = coord.longitude + tempSpan.longitudeDelta;

    return tempCoord;

}

当然,如果我将来确实需要使用学位,那么对上面做一些更改以使其像我实际要求的那样工作是非常容易的(我认为......)。

I found one way of doing it, had to dig to find the correct structs and functions. I ended up not using degrees but meters for lat and long instead.

Here's how I did it:

-(CLLocationCoordinate2D)translateCoord:(CLLocationCoordinate2D)coord MetersLat:(double)metersLat MetersLong:(double)metersLong{

    CLLocationCoordinate2D tempCoord;

    MKCoordinateRegion tempRegion = MKCoordinateRegionMakeWithDistance(coord, metersLat, metersLong);
    MKCoordinateSpan tempSpan = tempRegion.span;

    tempCoord.latitude = coord.latitude + tempSpan.latitudeDelta;
    tempCoord.longitude = coord.longitude + tempSpan.longitudeDelta;

    return tempCoord;

}

And of course, if I really need to use degrees in the future, it's pretty easy (I think...) to do some changes to above to get it to work like I actually asked for.

坚持沉默 2024-11-26 08:27:38

使用 MKCooperativeRegion 存在一些问题 - 如果您希望其中一个轴的增量为零,则可以调整返回的区域以适应,因为两个增量可能无法完全映射到该纬度的投影运气等。

此函数使用 MKMapPoint 执行坐标转换,这允许您在地图投影的坐标空间中移动点,然后从中提取坐标。

CLLocationCoordinate2D MKCoordinateOffsetFromCoordinate(CLLocationCoordinate2D coordinate, CLLocationDistance offsetLatMeters, CLLocationDistance offsetLongMeters) {
    MKMapPoint offsetPoint = MKMapPointForCoordinate(coordinate);

    CLLocationDistance metersPerPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude);
    double latPoints = offsetLatMeters / metersPerPoint;
    offsetPoint.y += latPoints;
    double longPoints = offsetLongMeters / metersPerPoint;
    offsetPoint.x += longPoints;

    CLLocationCoordinate2D offsetCoordinate = MKCoordinateForMapPoint(offsetPoint);
    return offsetCoordinate;
}

Using an MKCoordinateRegion has some issues—the returned region can be adjusted to fit since the two deltas may not exactly map to the projection at that latitude, if you want zero delta for one of the axes you are out of luck, etc.

This function uses MKMapPoint to perform coordinate translations which allows you to move points around in the map projection's coordinate space and then extract a coordinate from that.

CLLocationCoordinate2D MKCoordinateOffsetFromCoordinate(CLLocationCoordinate2D coordinate, CLLocationDistance offsetLatMeters, CLLocationDistance offsetLongMeters) {
    MKMapPoint offsetPoint = MKMapPointForCoordinate(coordinate);

    CLLocationDistance metersPerPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude);
    double latPoints = offsetLatMeters / metersPerPoint;
    offsetPoint.y += latPoints;
    double longPoints = offsetLongMeters / metersPerPoint;
    offsetPoint.x += longPoints;

    CLLocationCoordinate2D offsetCoordinate = MKCoordinateForMapPoint(offsetPoint);
    return offsetCoordinate;
}
萌辣 2024-11-26 08:27:38

Nicsoft 的回答非常棒,正是我所需要的。我创建了一个 Swift 3-y 版本,它更加简洁,可以直接在 CLLocationCooperative2D 实例上调用:

public extension CLLocationCoordinate2D {

  public func transform(using latitudinalMeters: CLLocationDistance, longitudinalMeters: CLLocationDistance) -> CLLocationCoordinate2D {
    let region = MKCoordinateRegionMakeWithDistance(self, latitudinalMeters, longitudinalMeters)
    return CLLocationCoordinate2D(latitude: latitude + region.span.latitudeDelta, longitude: longitude + region.span.longitudeDelta)
  }

}

Nicsoft's answer is fantastic and exactly what I needed. I've created a Swift 3-y version which is a little more concise and can be called directly on a CLLocationCoordinate2D instance:

public extension CLLocationCoordinate2D {

  public func transform(using latitudinalMeters: CLLocationDistance, longitudinalMeters: CLLocationDistance) -> CLLocationCoordinate2D {
    let region = MKCoordinateRegionMakeWithDistance(self, latitudinalMeters, longitudinalMeters)
    return CLLocationCoordinate2D(latitude: latitude + region.span.latitudeDelta, longitude: longitude + region.span.longitudeDelta)
  }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文