【问题标题】:Swift Convert decimal coordinate into degrees, minutes, seconds, directionSwift 将十进制坐标转换为度、分、秒、方向
【发布时间】:2015-01-17 05:06:11
【问题描述】:

我怎样才能将其转换为 swift?我最好的猜测是所有的 int 都变成了 var。删除所有导致“的@”。另外,如果有的话可以为我指出一个很好的来源,以了解事物如何转换。

- (NSString*)coordinateString {

int latSeconds = (int)(self.latitude * 3600);
int latDegrees = latSeconds / 3600;
latSeconds = ABS(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;

int longSeconds = (int)(self.longitude * 3600);
int longDegrees = longSeconds / 3600;
longSeconds = ABS(longSeconds % 3600);
int longMinutes = longSeconds / 60;
longSeconds %= 60;

NSString* result = [NSString stringWithFormat:@"%d°%d'%d\"%@ %d°%d'%d\"%@",
                    ABS(latDegrees),
                    latMinutes,
                    latSeconds,
                    latDegrees >= 0 ? @"N" : @"S",
                    ABS(longDegrees),
                    longMinutes,
                    longSeconds,
                    longDegrees >= 0 ? @"E" : @"W"];

return result;    
}

我尝试转换它,但 Xcode 证明我错了。使用 ABS 重新发布修复建议。现在看起来正确吗?

func coordinateString {

var latSeconds = (Int8)(self.latitude * 3600);
var latDegrees = latSeconds / 3600;
latSeconds = abs(latSeconds % 3600);
var latMinutes = latSeconds / 60;
latSeconds %= 60;

var longSeconds = (Int8)(self.longitude * 3600);
var longDegrees = longSeconds / 3600;
longSeconds = abs(longSeconds % 3600);
var longMinutes = longSeconds / 60;
longSeconds %= 60;

    var result = (String(format: "%d°%d'%d\"%@ %d°%d'%d\"%@"),
abs(latDegrees),
latMinutes,
latSeconds,
latDegrees >= 0 ? "N" : "S",
abs(longDegrees),
longMinutes,
longSeconds,
longDegrees >= 0 ? "E" : "W",

return result;
}

【问题讨论】:

    标签: swift gps xcode6


    【解决方案1】:

    Xcode 12 • Swift 5 或更高版本

    extension BinaryFloatingPoint {
        var dms: (degrees: Int, minutes: Int, seconds: Int) {
            var seconds = Int(self * 3600)
            let degrees = seconds / 3600
            seconds = abs(seconds % 3600)
            return (degrees, seconds / 60, seconds % 60)
        }
    }
    

    extension CLLocation {
        var dms: String { latitude + " " + longitude }
        var latitude: String {
            let (degrees, minutes, seconds) = coordinate.latitude.dms
            return String(format: "%d°%d'%d\"%@", abs(degrees), minutes, seconds, degrees >= 0 ? "N" : "S")
        }
        var longitude: String {
            let (degrees, minutes, seconds) = coordinate.longitude.dms
            return String(format: "%d°%d'%d\"%@", abs(degrees), minutes, seconds, degrees >= 0 ? "E" : "W")
        }
    }
    

    let latitude = -22.9133950
    let longitude = -43.2007100
    let location = CLLocation(latitude: latitude, longitude: longitude)
    location.latitude  // "22°54'48"S"
    location.longitude // "43°12'2"W"
    location.dms       // "22°54'48"S 43°12'2"W"
    

    【讨论】:

    • 这个答案正是我所需要的。我能够让它在我的应用程序中运行并获得我想要的结果。谢谢。
    • 我有一个请求,允许更改其显示的格式。这个很简单 - DD 40.09254 -88.24866 我试图修改你所拥有的 - DM N 40° 05.552 W 088° 14.919 但我得到 N 40° 5.333 W 88.14.895 代替。这就是我们减去几个数字的结果。 DMS N 40° 5’ 33.1476” W 88° 14’ 55.1652”
    【解决方案2】:

    我刚刚编辑了 Leo Dabus 答案以将这些字符串作为单独的值。如果对他人有帮助:

    Swift 3 和 Swift 4

    func getLocationDegreesFrom(latitude: Double) -> String {
    
        var latSeconds = Int(latitude * 3600)
    
        let latDegrees = latSeconds / 3600
    
        latSeconds = abs(latSeconds % 3600)
    
        let latMinutes = latSeconds / 60
    
        latSeconds %= 60
    
        return String(
    
            format: "%d°%d'%d\"%@",
            abs(latDegrees),
            latMinutes,
            latSeconds,
            latDegrees >= 0 ? "N" : "S"
    
        )
    
    }
    
    func getLocationDegreesFrom(longitude: Double) -> String {
    
        var longSeconds = Int(longitude * 3600)
    
        let longDegrees = longSeconds / 3600
    
        longSeconds = abs(longSeconds % 3600)
    
        let longMinutes = longSeconds / 60
    
        longSeconds %= 60
    
        return String(
    
            format: "%d°%d'%d\"%@",
            abs(longDegrees),
            longMinutes,
            longSeconds,
            longDegrees >= 0 ? "E" : "W"
    
        )
    
    }
    

    【讨论】:

      【解决方案3】:

      我拿了Leo Dabus的代码,修复了当纬度或经度的值小于零时与检测基本方向相关的错误,我意思是当我们在南半球本初子午线以西

      我们不能用 Swift 表示负零,所以我们在下面的表达式中失去了负号:

      let latDegrees = latSeconds / 3600
      

      这个错误也使得表达式:

      latDegrees >= 0 ? "N" : "S"
      

      总是返回 N(北),从不返回 S(南)。

      这是我的代码版本(Swift 5 和 Xcode 10):

      func coordinate() -> (latitude: String, longitude: String) {
      
          // This function converts from DD (decimal degrees) to DMS (degrees, minutes and seconds)
      
          // Calculating the degrees, minutes and seconds for the given latitude value (DD)
      
          var latitudeSeconds = latitude * 3600
      
          let latitudeDegrees = latitudeSeconds / 3600
      
          latitudeSeconds = latitudeSeconds.truncatingRemainder(dividingBy: 3600)
      
          let latitudeMinutes = latitudeSeconds / 60
      
          latitudeSeconds = latitudeSeconds.truncatingRemainder(dividingBy: 60)
      
          // Calculating the degrees, minutes and seconds for the given longitude value (DD)
      
          var longitudeSeconds = longitude * 3600
      
          let longitudeDegrees = longitudeSeconds / 3600
      
          longitudeSeconds = longitudeSeconds.truncatingRemainder(dividingBy: 3600)
      
          let longitudeMinutes = longitudeSeconds / 60
      
          longitudeSeconds = longitudeSeconds.truncatingRemainder(dividingBy: 60)
      
          // Analyzing if it's North or South. (Latitude)
      
          let latitudeCardinalDirection = latitudeDegrees >= 0 ? "N" : "S"
      
          // Analyzing if it's East or West. (Longitude)
      
          let longitudeCardinalDirection = longitudeDegrees >= 0 ? "E" : "W"
      
          // Final strings with format <degrees>°<minutes>'<seconds>"<cardinal direction>
      
          let latitudeDescription = String(format:"%.2f°%.2f'%.2f\"%@",
                                           abs(latitudeDegrees), abs(latitudeMinutes),
                                           abs(latitudeSeconds), latitudeCardinalDirection)
      
          let longitudeDescription = String(format:"%.2f°%.2f'%.2f\"%@",
                                            abs(longitudeDegrees), abs(longitudeMinutes),
                                            abs(longitudeSeconds), longitudeCardinalDirection)
      
          return (latitudeDescription, longitudeDescription)
      
      } // coordinate
      

      我还选择使用 Double 来处理精度,例如,我更喜欢显示两位小数。

      这段代码的屏幕输出会是这样的:

      0.17°10.34'20.53"S 78.48°28.59'35.52"W

      【讨论】:

        【解决方案4】:

        基于 David Seek 和 Josué V. Herrera 代码

        func latlon2DMS(latitude: Double) -> String {
            var latitudeSeconds = latitude * 3600
            let latitudeDegrees = latitudeSeconds / 3600
            latitudeSeconds = latitudeSeconds.truncatingRemainder(dividingBy: 3600)
            let latitudeMinutes = latitudeSeconds / 60
            latitudeSeconds = latitudeSeconds.truncatingRemainder(dividingBy: 60)
            let latitudeCardinalDirection = latitudeDegrees >= 0 ? "N" : "S"
            let latitudeDescription = String(format: "%.2f° %.2f' %.2f\" %@",
                                             abs(latitudeDegrees), abs(latitudeMinutes),
                                             abs(latitudeSeconds), latitudeCardinalDirection)
            return latitudeDescription
        }
        
        func latlon2DMS(longitude: Double) -> String {
            var longitudeSeconds = longitude * 3600
            let longitudeDegrees = longitudeSeconds / 3600
            longitudeSeconds = longitudeSeconds.truncatingRemainder(dividingBy: 3600)
            let longitudeMinutes = longitudeSeconds / 60
            longitudeSeconds = longitudeSeconds.truncatingRemainder(dividingBy: 60)
            let longitudeCardinalDirection = longitudeDegrees >= 0 ? "E" : "W"
            let longitudeDescription = String(format: "%.2f° %.2f' %.2f\" %@",
                                              abs(longitudeDegrees), abs(longitudeMinutes),
                                              abs(longitudeSeconds), longitudeCardinalDirection)
            return longitudeDescription
        }
        

        调用它

        print(latlon2DMS(latitude: coordLat))
        print(latlon2DMS(longitude: coordLong))
        
        latitude.text = latlon2DMS(latitude: coordLat)
        longitude.text = latlon2DMS(longitude: coordLong)
        

        【讨论】:

          【解决方案5】:

          我稍微修改了 Josue V. 的代码,使其在一个经常更新位置的计时器中工作

                  if( CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
                      CLLocationManager.authorizationStatus() ==  .authorizedAlways){
                  let currentLocation = locationManager.location
                  var latitudeSeconds = currentLocation!.coordinate.latitude * 3600
                  let latitudeDegrees = latitudeSeconds / 3600
          
                      latitudeSeconds = latitudeSeconds.truncatingRemainder(dividingBy: 3600)
          
                  let latitudeMinutes = latitudeSeconds / 60
          
                      latitudeSeconds = latitudeSeconds.truncatingRemainder(dividingBy: 60)
          
                  var longitudeSeconds = currentLocation!.coordinate.longitude * 3600
                  let longitudeDegrees = longitudeSeconds / 3600
          
                      longitudeSeconds = longitudeSeconds.truncatingRemainder(dividingBy: 3600)
          
                  let longitudeMinutes = longitudeSeconds / 60
          
                      longitudeSeconds = longitudeSeconds.truncatingRemainder(dividingBy: 60)
          
                  let latitudeCardinalDirection = latitudeDegrees >= 0 ? "N" : "S"
                  let longitudeCardinalDirection = longitudeDegrees >= 0 ? "E" : "W"
          
                  let latitudeDescription = String(format:"%.2f°%.2f'%.2f\"%@",
                                                   abs(latitudeDegrees), abs(latitudeMinutes),
                                                   abs(latitudeSeconds), latitudeCardinalDirection)
          
                  let longitudeDescription = String(format:"%.2f°%.2f'%.2f\"%@",
                                                    abs(longitudeDegrees), abs(longitudeMinutes),
                                                    abs(longitudeSeconds), longitudeCardinalDirection)
          
                  cell5.text = latitudeDescription + " " + longitudeDescription
          
                  }
              }
          

          还有计时器

          timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(coordinate), userInfo: nil, repeats: true)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-01-06
            • 2013-03-23
            • 2020-02-10
            • 2018-10-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多