【问题标题】:Calculate new coordinate x meters and y degree away from one coordinate计算距离一个坐标的新坐标 x 米和 y 度
【发布时间】:2011-10-01 19:24:03
【问题描述】:

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

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

我正在寻找类似的东西

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

谢谢!

【问题讨论】:

    标签: iphone objective-c geolocation location mapkit


    【解决方案1】:

    很遗憾,API 中没有提供这样的功能,所以您必须自己编写。

    This site 给出了几个涉及纬度/经度和示例 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 代码中,它包含this link,它显示了对于大于地球周长 1/4 的距离的更准确计算。

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

    【讨论】:

    • 感谢您的回答!实际上,我找到了一种方法。请参阅我自己的答案。
    • 好答案,我喜欢这个答案,因为它直接处理坐标并且更完整地回答了问题,因为它考虑了方向。
    【解决方案2】:

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

    我是这样做的:

    -(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;
    
    }
    

    当然,如果我将来真的需要使用学位,很容易(我认为...)对上述内容进行一些更改以使其按我实际要求的方式工作。

    【讨论】:

    • 简单而有效地满足我的需求。谢谢!
    • 那么你最终如何处理学位?
    【解决方案3】:

    使用MKCoordinateRegion 有一些问题——返回的区域可以调整以适应,因为这两个增量可能不完全映射到该纬度的投影,如果您希望其中一个轴的增量为零,那么您就不走运了等。

    此函数使用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;
    }
    

    【讨论】:

    • 这个答案对我很有用,让我可以将 MapItem.placemark.region(这是一个 CLCircularRegion;它的半径以米为单位)转换为边界框区域
    【解决方案4】:

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

    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)
      }
    
    }
    

    【讨论】:

    • 最好命名为translate,因为它在技术上是翻译而不是转换。
    • 如果我知道角度,如何利用它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多