jueves, 27 de agosto de 2009

Datos tipo Record en Delphi con soporte de métodos

Estaba desarrollando una aplicación que utilizaba coordenadas geográficas y tenía que hacer la conversión de Grados-Minutos-Segundos a su formato en Decimal, así que codifiqué de la siguiente forma:

type
TCoordenadaGeografica = Record
grados : Double;
minutos : Double;
segundos : Double;
End;

TConversion = class
class function gradosADecimales(grados: Double; minutos: Double; Segundos: Double):double; overload;
class function gradosADecimales(coordenadaGeografica: TCoordenadaGeografica):double;overload;
class function decimalesAGrados(valorDecimal :Double):TCoordenadaGeografica;
end;

implementation

{ TConversion }

class function TConversion.decimalesAGrados(
valorDecimal: Double): TCoordenadaGeografica;
var
resultado : TCoordenadaGeografica;
begin
resultado.grados := Int(valorDecimal);
resultado.minutos := Int((valorDecimal - resultado.grados)) * CONV_MINUTOS;
resultado.segundos := (resultado.minutos - Int(resultado.minutos)) * CONV_MINUTOS;
result := Resultado;
end;

class function TConversion.gradosADecimales(grados, minutos,
Segundos: Double): double;
var
resultado : Double;
begin
resultado := grados + (minutos / CONV_MINUTOS ) + (segundos / CONV_SEGUNDOS);
result := resultado;
end;

class function TConversion.gradosADecimales(
coordenadaGeografica: TCoordenadaGeografica): double;
var
resultado : Double;
begin
resultado := coordenadaGeografica.grados +
(coordenadaGeografica.minutos / CONV_MINUTOS ) +
(coordenadaGeografica.segundos / CONV_SEGUNDOS);
result := resultado;
end;


Todo funcionaba correctamente..., pero noté que estaba utilizando muchas líneas de código para hacer las conversiones:


procedure TfrmCaptura.asignaCoordenada(Sender: TObject);
var
latitud : TCoordenadaGeografica;
longitud : TCoordenadaGeografica;
begin
inherited;
latitud.grados := TConversion.toFloat(peaLatG.Text);
latitud.minutos := TConversion.toFloat(peaLatM.Text);
latitud.segundos := TConversion.toFloat(peaLatS.Text);

longitud.grados := TConversion.toFloat(peaLonG.Text);
longitud.minutos := TConversion.toFloat(peaLonM.Text);
longitud.segundos := TConversion.toFloat(peaLonS.Text);

// aquí se guarda en la base
end;
Tomando en cuenta que tenía que hacer ésto en varios lugares encontré la solución haciendo uso de las nuevas características de los Records en Delphi:


type
TCoordenadaGeografica = Record
grados : Double;
minutos : Double;
segundos : Double;
constructor Create(AGrados: Double; AMinutos:Double; ASegundos:Double); overload;
constructor Create(AGrados: String; AMinutos: String; ASegundos:String); overload;
End;

/// más líneas por acá

{ TCoordenadaGeografica }

constructor TCoordenadaGeografica.Create(AGrados, AMinutos, ASegundos: Double);
begin
Self.grados := AGrados;
Self.minutos := AMinutos;
Self.segundos := ASegundos;
end;

constructor TCoordenadaGeografica.Create(AGrados, AMinutos, ASegundos: String);
begin
Self.grados := TConversion.toFloat(AGrados);
Self.minutos := TConversion.toFloat(AMinutos);
Self.segundos := TConversion.toFloat(ASegundos);
end;


Por lo que me ahorré muchas lineas de código al hacer uso de los constructores en los Records:


procedure TfrmCaptura.asignaCoordenada(Sender: TObject);
var
latitud : TCoordenadaGeografica;
longitud : TCoordenadaGeografica;
begin
inherited;
latitud := TCoordenadaGeografica.Create(peaLatG.Text,peaLatM.Text,peaLatS.Text);
longitud := TCoordenadaGeografica.Create(peaLonG.Text,peaLonM.Text,peaLonS.Text);
// aquí se guarda en la base
end;

Otra opción hubiera sido el crear una clase de que se encargara de la conversión (que finalmente así quedó implementado) pero para mí fué una oportunidad de probar esta interesante característica de los Records en Delphi.

No hay comentarios:

Publicar un comentario