将十进制坐标转换为度、分、秒、方向

12

我已经有了下面这个,但是无法想出一种简洁的方法来添加方向字母,而不需要一堆混乱的if语句。有什么建议吗?理想情况下,我想通过扩展CLLocation类来实现这一点。

-(NSString *)nicePosition{

double latitude = [self.latitude doubleValue];
double longitude = [self.longitude doubleValue];

int latSeconds = (int)round(latitude * 3600);
int latDegrees = latSeconds / 3600;
latSeconds = abs(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;

int longSeconds = (int)round(longitude * 3600);
int longDegrees = longSeconds / 3600;
longSeconds = abs(longSeconds % 3600);
int longMinutes = longSeconds / 60;
longSeconds %= 60;

//TODO: Use N,E,S,W notation in lat/long

return [NSString stringWithFormat:@"%i° %i' %i\", %i° %i' %i\"", latDegrees, latMinutes, latSeconds, longDegrees, longMinutes, longSeconds];
}

记录一下,我做了以下操作。

-(NSString *)nicePosition{

double latitude = [self.latitude doubleValue];
double longitude = [self.longitude doubleValue];

int latSeconds = (int)round(abs(latitude * 3600));
int latDegrees = latSeconds / 3600;
latSeconds = latSeconds % 3600;
int latMinutes = latSeconds / 60;
latSeconds %= 60;

int longSeconds = (int)round(abs(longitude * 3600));
int longDegrees = longSeconds / 3600;
longSeconds = longSeconds % 3600;
int longMinutes = longSeconds / 60;
longSeconds %= 60;

char latDirection = (latitude >= 0) ? 'N' : 'S';
char longDirection = (longitude >= 0) ? 'E' : 'W';

return [NSString stringWithFormat:@"%i° %i' %i\" %c, %i° %i' %i\" %c", latDegrees, latMinutes, latSeconds, latDirection, longDegrees, longMinutes, longSeconds, longDirection];
}

我是太蠢了还是经纬度的数值符号决定了东南西北?然后你只需要使用:NSLog(@"%@%@", (lat > 0) ? @"N" : (lat < 0) ? @"S" : @"", (long > 0) ? @"E" : (long < 0) ? @"W");。我想这仍然有一些“混乱的if”元素。 - James Webster
6个回答

16

标准方式:

char lonLetter = (lon > 0) ? 'E' : 'W';
char latLetter = (lat > 0) ? 'N' : 'S';

3
是的,这就是我最终做的。你回答得很快。 :) - trapper

10

这是基于Daniel上面的解决方案的Objective-C代码:

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

那在 Swift 中会是什么样子? - MwcsMac
为什么你要使用截断 (int)(coordinate * 3600) 而不是像 Daniel Lidström 那样四舍五入获取秒数? - meaning-matters

3
如果您想在Swift中实现它,可以做出类似以下的东西:
import MapKit

extension CLLocationCoordinate2D {

    var latitudeDegreeDescription: String {
        return fromDecToDeg(self.latitude) + " \(self.latitude >= 0 ? "N" : "S")"
    }
    var longitudeDegreeDescription: String {
        return fromDecToDeg(self.longitude) + " \(self.longitude >= 0 ? "E" : "W")"
    }
    private func fromDecToDeg(input: Double) -> String {
        var inputSeconds = Int(input * 3600)
        let inputDegrees = inputSeconds / 3600
        inputSeconds = abs(inputSeconds % 3600)
        let inputMinutes = inputSeconds / 60
        inputSeconds %= 60
        return "\(abs(inputDegrees))°\(inputMinutes)'\(inputSeconds)''"
    }
}

3
这里提供一个C#的解决方案:
    void Run(double latitude, double longitude)
    {
        int latSeconds = (int)Math.Round(latitude * 3600);
        int latDegrees = latSeconds / 3600;
        latSeconds = Math.Abs(latSeconds % 3600);
        int latMinutes = latSeconds / 60;
        latSeconds %= 60;

        int longSeconds = (int)Math.Round(longitude * 3600);
        int longDegrees = longSeconds / 3600;
        longSeconds = Math.Abs(longSeconds % 3600);
        int longMinutes = longSeconds / 60;
        longSeconds %= 60;

        Console.WriteLine("{0}° {1}' {2}\" {3}, {4}° {5}' {6}\" {7}",
            Math.Abs(latDegrees),
            latMinutes,
            latSeconds,
            latDegrees >= 0 ? "N" : "S",
            Math.Abs(longDegrees),
            longMinutes,
            longSeconds,
            latDegrees >= 0 ? "E" : "W");
    }

这是一个示例运行:

new Program().Run(-15.14131211, 56.345678);
new Program().Run(15.14131211, -56.345678);
new Program().Run(15.14131211, 56.345678);

这将打印:

15° 8' 29" S, 56° 20' 44" W
15° 8' 29" N, 56° 20' 44" E
15° 8' 29" N, 56° 20' 44" E

希望这有所帮助,并且它能够实现正确的功能。祝你好运!

1

关于Alex的回答,这里提供了一个Swift 3的解决方案,并返回一个包含坐标的元组。

此外,它真正扩展了CLLocationDegrees类,不需要额外的参数。

import MapKit

extension CLLocationDegrees {

    func degreeRepresentation() -> (northOrEast: Bool, degrees: Int, minutes: Int, seconds: Int) {
        var inputSeconds = Int(self * 3600)
        let inputDegrees = inputSeconds / 3600
        inputSeconds = abs(inputSeconds % 3600)
        let inputMinutes = inputSeconds / 60
        inputSeconds %= 60

        return (inputDegrees > 0, abs(inputDegrees), inputMinutes, inputSeconds)
    }

}

0
int latSeconds = (int)round(abs(latitude * 3600));

这是错误的!正确的应该是

int latSeconds = abs(round(latitude * 3600));  

请解释原因。 - meaning-matters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接