Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Convertir coordenadas GPS de Imagen (https://www.clubdelphi.com/foros/showthread.php?t=86696)

radenf 17-09-2014 22:02:48

Convertir coordenadas GPS de Imagen
 
Hola amigos.

Estoy intentando posicionar en un mapa el lugar donde fue tomada una foto. Para ello obtengo las coordenadas geográficas utilizando la libreria CCR Exif, mediante el siguiente código:

Código Delphi [-]
var
ExifData: TExifData;
begin
ExifData := TExifData.Create;
try
ExifData.LoadFromGraphic(OpenDialog1.FileName);
Label1.Caption:= 'Latitud: ' + ExifData.GPSLatitude.ToString;
Label2.Caption:= 'Longitud: '+ ExifData.GPSLongitude.ToString;
finally
ExifData.Free;
end;
end;

Con esto obtengo, para una determinada imagen dos Strings:

Latitud: 41,50,5392/100N
Longitud: 12,34,3368/100E

¿Conoce alguien alguna función en Delphi que transforme estas coordenadas que se encuentran en grados, minutos y segundos al formato decimal que entiende GoogleMaps?
En este link se menciona el tema, pero mi nivel de conocimientos no me ha permitido entenderlo.

De antemano agradezco su ayuda
Saludos

ecfisa 18-09-2014 11:59:24

Hola randenf.

Google dice que:
Cita:

Ejemplos de formatos aceptados:

Grados, minutos y segundos (DMS): 41° 24' 12.1674", 2° 10' 26.508"
Grados y minutos decimales (DMM): 41 24.2028, 2 10.4418
Grados decimales (DDD): 41.40338, 2.17403

Fuente: Coordenadas de latitud y longitud

Entonces, creo que basta con darle formato a las cadenas que te devuelve CCR Exif para adecuarlas a un formato aceptado.
Código Delphi [-]

uses ClipBrd;

function FormatGoogleCoord(const Sexa: string): string;
var
  ts: TStrings;
  pc: Char;
begin
  ts:= TStringList.Create;
  try
    ts.CommaText:= Sexa;
    pc:= UpCase(ts[2][Length(ts[2])]);
    if pc = 'O' then pc:= 'W';   // para que acepte la 'O'
    ts[2]:= Copy(ts[2], 1, Pos('/', ts[2]) - 1);
    ts[2]:= FloatToStr(StrToFloat(ts[2]) / 100);
    ts[2]:= StringReplace(ts[2], ',', '.', [rfReplaceAll]);
    Result:= ts[0] + ' ' + ts[1] + ' ' + ts[2] + pc;
  finally
    ts.Free;
  end;
end;


procedure TForm1.btnFormatClick(Sender: TObject);
var
  Exif1, Exif2: string;
begin
  // Mi ciudad:
  Exif1:= '38,22,37/100S';
  Exif2:= '60,16,31/100W';
  Clipboard.AsText:= FormatGoogleCoord(Exif1)+','+FormatGoogleCoord(Exif2);
  // Aquí ya podes ir y pegar las coord. en google maps.
end;
Lo desconozco, pero suponiendo que CCR Exif te devuelve siempre el formato que publicaste en tu mensaje ([grados],[minutos],[seg+cen/100][pto.Card]), tendría que servirte. Lo he probado con varias localizaciones conocidas y se posiciona correctamente.

Saludos :)

radenf 18-09-2014 13:39:01

Muchas gracias por responder Daniel.

Voy a realizar pruebas y te cuento.
Saludos

radenf 18-09-2014 14:53:26

Estimado Daniel:

El código funciona perfecto, realizando la conversión del formato que entrega CCR Exif de la latitud y longitud en que fue adquirida cada imagen, cuando lo visualizas en GoogleMaps del Navegador.
En mi programa he implementado el uso de un javascript que llama a GoogleMaps sobre un TWebBrowser, que sólo acepta el formato de grados decimal (DDD), por lo que no me funciona esta conversión, ya que sólo permite este formato Ej: (21.7351043,-63.28125)

Saludos

ecfisa 18-09-2014 18:37:59

Hola Iván.
Cita:

Empezado por radenf (Mensaje 481697)
...
En mi programa he implementado el uso de un javascript que llama a GoogleMaps sobre un TWebBrowser, que sólo acepta el formato de grados decimal (DDD)...

Ya había olvidado por que detestaba javascript... hasta ahora :D

Lo verifiqué con varias localizaciones y anduvo bién, pero fijate si en en las futuras pruebas continúa hacíendolo...
Código Delphi [-]
uses Clipbrd;

procedure CoordSexaToDec(const LatStr,LonStr: string; var Latitude,Longitude: Double);
{$J+}
const
  LASIGN: ShortInt = 1;
  LOSIGN: ShortInt = 1;
  VSIGN : array[Boolean] of ShortInt = (1,-1);
{$J-}
var
  laPCar, loPCar: Char;
  laDeg,   loDeg: Double;
  laMin,   loMin: Double;
  laSec,   loSec: Double;
  laDegA, loDegA: Double;
  laMinA, loMinA: Double;
  laSecA, loSecA: Double;
  ts            : TStrings;
begin
  // Signos
  laPCar:= UpCase(LatStr[Length(LatStr)]);
  loPCar:= UpCase(LonStr[Length(LonStr)]);
  LASIGN:= VSIGN[laPCar = 'S'];
  LOSIGN:= VSIGN[loPCar in ['O','W']];
  ts:= TStringList.Create;
  try
    // Latitud
    ts.CommaText:= LatStr;
    ts[2] := Copy(ts[2], 1, Pos('/', ts[2]) - 1);
    laSec := StrToFloat(ts[2])/100;
    laMin := StrToFloat(ts[1]);
    laDeg := StrToFloat(ts[0]);
    laSec := Abs(Round(laSec * 1000000) / 1000000);
    laMin := Abs(Round(laMin * 1000000) / 1000000);
    // Longitud
    ts.Clear;
    ts.CommaText:= LonStr;
    if loPCar = 'O' then loPCar:= 'W';
    ts[2] := Copy(ts[2], 1, Pos('/', ts[2]) - 1);
    loSec := StrToFloat(ts[2])/100;
    loMin := StrToFloat(ts[1]);
    loDeg := StrToFloat(ts[0]);
  finally
    ts.Free;
  end;
  loSec := Abs(Round(loSec * 1000000) / 1000000);
  loMin := Abs(Round(loMin * 1000000) / 1000000);
  // Calculos latitud
  laDegA:= Abs(Round(laDeg * 1000000));
  laMinA:= Abs(Round(laMin * 1000000));
  laSecA:= Abs(Round(laSec * 1000000));
  // Calculos longitud
  loDegA:= Abs(Round(loDeg * 1000000));
  loMinA:= Abs(Round(loMin * 1000000));
  loSecA:= Abs(Round(loSec * 1000000));
  // Verificar latitud
  if not (laPCar in ['N','S']) then
    raise Exception.Create('Error en la latitud');
  if not (loPCar in ['E','W']) then
    raise Exception.Create('Error en la longitud');
  if laDegA > 90 * 1000000 then
    raise Exception.Create('Error: Grados en latitud: -90 a 90');
  if laMinA > 60 * 1000000 then
    raise Exception.Create('Error: Minutos en latitud: 0 a 59');
  if laSecA > 59.99999999 * 1000000 then
    raise Exception.Create('Error: Segundos en latitud: 0 a 60');
  // Verificar longitud
  if loDegA > 180 * 1000000 then
    raise Exception.Create('Error: Grados en longitud: -180 a 180');
  if loMinA >  60 * 1000000 then
    raise Exception.Create('Error: Minutos en longitud: 0 a 59');
  if loSecA >  59.99999999 * 1000000 then
  raise Exception.Create('Error: Segundos en longitud: 0 a 60');
  // Resultado
  Latitude := Round(laDegA + laMinA / 60 + laSecA / 3600)* LASIGN / 1000000;
  Longitude:= Round(loDegA + loMinA / 60 + loSecA / 3600) * LOSIGN / 1000000;
end;

procedure TForm1.btnConvierteClick(Sender: TObject);
var
  Exif1, Exif2: string;
  Latitud, Longitud: Double;
begin
  // Como siempre el pueblo tira...
  Exif1:= '38,22,37/100S';
  Exif2:= '60,16,31/100W';

  CoordSexaToDec(Exif1,Exif2,Latitud,Longitud);

  Exif1:= StringReplace(FloatToStr(Latitud),',','.',[rfReplaceAll]);
  Exif2:= StringReplace(FloatToStr(Longitud),',','.',[rfReplaceAll]);
  Clipboard.AsText:= Exif1 + ', ' + Exif2;
  // A probar a google maps...
end;

Saludos :)

radenf 18-09-2014 22:08:28

Como siempre Daniel un Gran Maestro.
Como decimos en Chile "te pasaste" (lo hiciste excelente). Espero que en Argentina no signifique algo malo.
El código funcionó a la perfección. Al hacer click en cada imagen que posee información de GPS ubica de forma precisa en el mapa el lugar donde fue tomada.
Muchas gracias por tu dedicación y tiempo.
Espero que esto le sirva a muchos.

Un abrazo

ecfisa 18-09-2014 22:55:20

Hola Iván.
Cita:

Empezado por radenf (Mensaje 481717)
...Espero que en Argentina no signifique algo malo...

No para mí, al contrario... ¡Muchas gracias!, pero la verdad es que sólo fuí leyendo artículos geográficos, sacando algunas fórmulas de aquí y otras de allá para ír armando el mamotreto. El proceso de las conversiones no es mérito mío. Lo bueno es que me enteré de otra cosa mas que no sabía.

Otro para vos :)


La franja horaria es GMT +2. Ahora son las 05:39:39.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi