Normalize exif output to decimal degrees

381 views Asked by At

I'm trying to normalize an exif() output I'm getting from the head of an image. Right now, I'm doing this:.

$exifs   = exif_read_data($file, 0, true);
$raw_lat = $exifs['GPS']['GPSLatitude'];
$raw_lon = $exifs['GPS']['GPSLongitude'];

and the var dump of $raw_lat looks like this:

array(3) { [0]=> string(4) "34/1" [1]=> string(3) "5/1" [2]=> string(11) "231365/9853" }

$raw_lon is in the same structures so I thought what I needed to do to normalize this to degrees decimal was to use the following function:

private function normalize($array){
    $deg = $array[0];
    $min = $array[1];
    $sec = $array[2];
    $dd  = $deg+((($min*60)+($sec))/3600);
    return $dd;
}

The function runs and outputs as described as I'm returning numbers however those numbers are very far apart and that wouldn't make since because they were taken relatively close together.

1

There are 1 answers

0
Ruslan Osmanov On BEST ANSWER

You are trying to perform arithmetic operations on string representations of fractions like "34/100". When interpreting strings in numeric context PHP will truncate the values up to the / character, particularly. For example, "34/100" + "1/100000" results in 35, but not 0.34001. So you have to convert the strings to numbers yourself.

Example

/**
 * @param string $s Number as a fraction A/B, e.g. 34/100
 * @return float
 */
function string_to_float($s) {
  $parts = explode('/', $s);
  return (count($parts) >= 2)
    ? ($parts[0] / $parts[1])
    : floatval($parts[0]);
}

/**
 * @param array $dms Latitude/longitude degrees, minutes, and seconds
 * @return float
 */
function latlong_normalize(array $dms) {
  $deg = string_to_float($dms[0]);
  $min = string_to_float($dms[1]);
  $sec = string_to_float($dms[2]);
  return $deg + ($min * 60 + $sec) / 3600;
}

// Latitude = 34 5 231365/9853
$raw_lat = ['34/1', '5/1', '231365/9853'];

echo latlong_normalize($raw_lat);

Output

34.089856022418