PHP 提取 GPS EXIF 数据

2022-08-30 10:01:33

我想使用php从图片中提取GPS EXIF标签。我正在使用返回所有标签+数据的数组:exif_read_data()

GPS.GPSLatitudeRef: N
GPS.GPSLatitude:Array ( [0] => 46/1 [1] => 5403/100 [2] => 0/1 ) 
GPS.GPSLongitudeRef: E
GPS.GPSLongitude:Array ( [0] => 7/1 [1] => 880/100 [2] => 0/1 ) 
GPS.GPSAltitudeRef: 
GPS.GPSAltitude: 634/1

我不知道如何解释46/1 5403/100和0/1?46可能是46°,但其余的呢,特别是0/1?

angle/1 5403/100 0/1

这个结构是关于什么的?

如何将它们转换为“标准”(如来自维基百科的46°56′48“N 7°26′39”E)?我想将这些坐标传递给谷歌地图API,以在地图上显示图片位置!


答案 1

这是我的修改版本。其他的对我不起作用。它将为您提供GPS坐标的十进制版本。

用于处理 EXIF 数据的代码:

$exif = exif_read_data($filename);
$lon = getGps($exif["GPSLongitude"], $exif['GPSLongitudeRef']);
$lat = getGps($exif["GPSLatitude"], $exif['GPSLatitudeRef']);
var_dump($lat, $lon);

按以下格式打印:

float(-33.8751666667)
float(151.207166667)

以下是函数:

function getGps($exifCoord, $hemi) {

    $degrees = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
    $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;
    $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;

    $flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1;

    return $flip * ($degrees + $minutes / 60 + $seconds / 3600);

}

function gps2Num($coordPart) {

    $parts = explode('/', $coordPart);

    if (count($parts) <= 0)
        return 0;

    if (count($parts) == 1)
        return $parts[0];

    return floatval($parts[0]) / floatval($parts[1]);
}

答案 2

这是Gerald Kaszuba代码的重构版本(目前最广泛接受的答案)。结果应该是相同的,但是我已经进行了几次微优化,并将两个单独的函数合并为一个。在我的基准测试中,此版本在运行时减少了大约5微秒,这对于大多数应用程序来说可能可以忽略不计,但对于涉及大量重复计算的应用程序可能很有用。

$exif = exif_read_data($filename);
$latitude = gps($exif["GPSLatitude"], $exif['GPSLatitudeRef']);
$longitude = gps($exif["GPSLongitude"], $exif['GPSLongitudeRef']);

function gps($coordinate, $hemisphere) {
  if (is_string($coordinate)) {
    $coordinate = array_map("trim", explode(",", $coordinate));
  }
  for ($i = 0; $i < 3; $i++) {
    $part = explode('/', $coordinate[$i]);
    if (count($part) == 1) {
      $coordinate[$i] = $part[0];
    } else if (count($part) == 2) {
      $coordinate[$i] = floatval($part[0])/floatval($part[1]);
    } else {
      $coordinate[$i] = 0;
    }
  }
  list($degrees, $minutes, $seconds) = $coordinate;
  $sign = ($hemisphere == 'W' || $hemisphere == 'S') ? -1 : 1;
  return $sign * ($degrees + $minutes/60 + $seconds/3600);
}

推荐