Convertir la coordenada decimal en grados, minutos, segundos, dirección
-
28-10-2019 - |
Pregunta
Tengo lo siguiente hasta ahora, pero no puedo encontrar una forma ordenada de obtener las letras de dirección sin un montón de declaraciones desordenadas. ¿Algunas ideas? Idealmente, me gustaría extender la clase de Cllocation con una categoría para hacer esto.
-(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];
}
Para el registro hice lo siguiente.
-(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];
}
Solución
Forma estándar:
char lonLetter = (lon > 0) ? 'E' : 'W';
char latLetter = (lat > 0) ? 'N' : 'S';
Otros consejos
Aquí hay algún objetivo-C basado en la solución de Daniel anterior:
- (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;
}
Aquí hay una solución en 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");
}
Este es un ejemplo de ejecución:
new Program().Run(-15.14131211, 56.345678);
new Program().Run(15.14131211, -56.345678);
new Program().Run(15.14131211, 56.345678);
Qué imprime:
15° 8' 29" S, 56° 20' 44" W
15° 8' 29" N, 56° 20' 44" E
15° 8' 29" N, 56° 20' 44" E
Espero que esto ayude, y que haga lo correcto. ¡Buena suerte!
Si quieres hacerlo en Swift, puedes hacer algo así:
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)''"
}
}
Con respecto a la respuesta de Alex, aquí hay una solución en Swift 3 con una tupla de salida. Devuelve las coordenadas en una tupla.
Además, realmente extiende la clase CllocationDegrees y no requiere un parámetro adicional.
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)
}
}
int latSeconds = (int)round(abs(latitude * 3600));
¡Esto es un error! Apropiado es
int latSeconds = abs(round(latitude * 3600));