Swift 将十进制坐标转换成度、分、秒、方向
Swift Convert decimal coordinate into degrees, minutes, seconds, direction
如何将其转换为 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;
}
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"
我刚刚编辑了 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"
)
}
我采用了 Leo Dabus 的代码并修复了 当纬度或经度的值 小于 时与检测基本方向相关的错误 零,我的意思是当我们在南半球或本初子午线以西。
我们不能用Swift表示负数零,所以我们在下面的表达式中去掉负号:
let latDegrees = latSeconds / 3600
这个错误也使表达式:
latDegrees >= 0 ? "N" : "S"
总是 return 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
基于 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)
我稍微修改了 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)
如何将其转换为 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;
}
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"
我刚刚编辑了 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"
)
}
我采用了 Leo Dabus 的代码并修复了 当纬度或经度的值 小于 时与检测基本方向相关的错误 零,我的意思是当我们在南半球或本初子午线以西。
我们不能用Swift表示负数零,所以我们在下面的表达式中去掉负号:
let latDegrees = latSeconds / 3600
这个错误也使表达式:
latDegrees >= 0 ? "N" : "S"
总是 return 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
基于 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)
我稍微修改了 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)