在Swift中解析和转换DMS坐标从String到Double的更好方法

时间:2017-01-22 12:16:47

标签: swift coordinates dms cllocationcoordinate2d

所以我的坐标看起来像

N47° 15' 36.75",E011° 20' 38.28",+001906.00

我已经创建了一个类来解析并将它们转换为double

struct PLNWaypointCoordinate {
    var latitude: Double = 0.0
    var longitude: Double = 0.0

    init(coordinateString: String) {
        self.latitude = convertCoordinate(string: coordinateString.components(separatedBy: ",")[0])
        self.longitude = convertCoordinate(string: coordinateString.components(separatedBy: ",")[1])
    }

    private func convertCoordinate(string: String) -> Double {
        var separatedCoordinate = string.characters.split(separator: " ").map(String.init)

        let direction = separatedCoordinate[0].components(separatedBy: CharacterSet.letters.inverted).first
        let degrees = Double(separatedCoordinate[0].components(separatedBy: CharacterSet.decimalDigits.inverted)[1])
        let minutes = Double(separatedCoordinate[1].components(separatedBy: CharacterSet.decimalDigits.inverted)[0])
        let seconds = Double(separatedCoordinate[2].components(separatedBy: CharacterSet.decimalDigits.inverted)[0])

        return convert(degrees: degrees!, minutes: minutes!, seconds: seconds!, direction: direction!)
}

    private func convert(degrees: Double, minutes: Double, seconds: Double, direction: String) -> Double {
        let sign = (direction == "W" || direction == "S") ? -1.0 : 1.0
        return (degrees + (minutes + seconds/60.0)/60.0) * sign
    }

}

我的问题是,正如标题所说,是否有更好,更安全的方式来执行此转换?

我在这里采访的最后一种方法。抱歉,我找不到引用它的链接。

2 个答案:

答案 0 :(得分:0)

提前回复https://codereview.stackexchange.com/questions/153291/parsing-and-converting-dms-coordinates-from-string-to-double

struct PLNWaypointCoordinate {
    var latitude: Double
    var longitude: Double

    init(latitude: Double, longitude: Double) {
        self.latitude = latitude
        self.longitude = longitude
    }

    init?(coordinateString: String) {
        let components = coordinateString.components(separatedBy: ",")
        guard components.count >= 2,
            let latitude = PLNWaypointCoordinate.convertCoordinate(coordinate: components[0],
                                                                   positiveDirection: "N",
                                                                   negativeDirection: "S"),
            let longitude = PLNWaypointCoordinate.convertCoordinate(coordinate: components[1],
                                                                    positiveDirection: "E",
                                                                    negativeDirection: "W")
            else {
                return nil
        }
        self.init(latitude: latitude, longitude: longitude)
    }

    private static func convertCoordinate(coordinate: String,
                                          positiveDirection: String,
                                          negativeDirection: String) -> Double? {
        // Determine the sign from the first character:
        let sign: Double
        let scanner = Scanner(string: coordinate)
        if scanner.scanString(positiveDirection, into: nil) {
            sign = 1.0
        } else if scanner.scanString(negativeDirection, into: nil) {
            sign = -1.0
        } else {
            return nil
        }

        // Parse degrees, minutes, seconds:
        var degrees = 0
        var minutes = 0
        var seconds = 0.0
        guard scanner.scanInt(&degrees),         // Degrees (integer),
            scanner.scanString("°", into: nil),  // followed by °,
            scanner.scanInt(&minutes),           // minutes (integer)
            scanner.scanString("'", into: nil),  // followed by '
            scanner.scanDouble(&seconds),        // seconds (floating point),
            scanner.scanString("\"", into: nil), // followed by ",
            scanner.isAtEnd                      // and nothing else.
            else { return nil }

        return sign * (Double(degrees) + Double(minutes)/60.0 + seconds/3600.0)
    }
}

感谢大家的帮助!

答案 1 :(得分:0)

这是$scope.changeFocus = function (n) { if (n === 0) { var id = "new_auth3"; var element = $window.document.getElementById(id); if (element) { if (isNaN($scope.operation.authorizationCodeConfirm[2]) || $scope.operation.authorizationCodeConfirm[2] == "") return; element.blur(); $scope.oldMCCStr = getMCC($scope.operation.authorizationCodeConfirm); $('#new_auth1').focus console.log("esta a ser chamado!"); } } }; // checks if the key pressed is a number var checkInput = function (inputArr) { angular.forEach(inputArr, function (value, key) { if (null !== inputArr[key]) { var compare = parseInt(inputArr[key]); if (isNaN(compare)) { inputArr[key] = ''; } } }); }; $scope.$watch('operation.authorizationCodeConfirm', function (newValue, oldValue) { checkInput($scope.operation.authorizationCodeConfirm); console.log("esta a ser chamado!"); }, true); 扩展名的通用版本。

它使用正则表达式解析字符串并考虑

  • 参数之间的可选空格。
  • 在字符串开头或结尾的方向,CLLocationCoordinate2DE都在East处。
  • 分钟(O)和秒('′)的不同字符。

"″