5

I am writing a bash script that renames JPG files based on their EXIF tags. My original files are named like this:

IMG_2110.JPG
IMG_2112.JPG
IMG_2113.JPG
IMG_2114.JPG

I need to rename them like this:

2015-06-07_11-21-38_iPhone6Plus_USA-CA-Los_Angeles_IMG_2110.JPG
2015-06-07_11-22-41_iPhone6Plus_USA-CA-Los_Angeles_IMG_2112.JPG
2015-06-13_19-05-10_iPhone6Plus_Morocco-Fez_IMG_2113.JPG
2015-06-13_19-12-55_iPhone6Plus_Morocco-Fez_IMG_2114.JPG

My bash script uses exiftool to parse the EXIF header and rename the files. For those files that do not contain an EXIF create date, I am using the file modification time.

#!/bin/bash
IFS=$'\n'

for i in *.*; do
    MOD=`stat -f %Sm -t %Y-%m-%d_%H-%m-%S $i`
    model=$( exiftool -f -s3 -"Model" "${i}" )
    datetime=$( exiftool -f -s3 -"DateTimeOriginal" "${i}" )
    stamp=${datetime//:/-}"_"${model// /}
    echo ${stamp// /_}$i
done

I am stuck on the location. I need to determine the country and city using the GPS information from the EXIF tag. exiftool provides a field called "GPS Position." Of all the fields, this seems the most useful to determine location.

GPS Position : 40 deg 44' 49.36" N, 73 deg 56' 28.18" W

Google provides a public API for geolocation, but it requires latitude/longitude coordinates in this format:

40.7470444°, -073.9411611°

The API returns quite a bit of information (click the link to see the results):

https://maps.googleapis.com/maps/api/geocode/json?latlng=40.7470444,-073.9411611

My question is:

  1. How do I format the GPS Position to a latitude/longitude value that will provide acceptable input to a service such as Google geolocation?

  2. How do I parse the JSON results to extract just the country and city, in a way that is consistent with many different kinds of locations? Curl, and then? Ideally, I’d like to handle USA locations one way, and non-USA locations, another. USA locations would be formatted USA-STATE-City, whereas non-USA locations would be formatted COUNTRY-City.

I need to do this all in a bash script. I've looked at pygeocoder and gpsbabel but they do not seem to do the trick. There are a few free web tools available but they don't provide an API (http://www.earthpoint.us/Convert.aspx).

utt50
  • 155
  • 2
  • 9
  • An interesting task. See this question for the formula : http://stackoverflow.com/questions/15962939/how-to-convert-gps-north-and-gps-west-to-lat-long-in-objective-c . Shouldn't be too difficult to do. recall that `$(( math expressions ))` can be of help. Good luck. – shellter Sep 30 '15 at 21:27
  • It looks like I'd be adapting something like this (http://thelinuxrain.com/articles/dms-to-dd-to-kml-with-awk-and-sed): `location=awk -v FS="[ \t]" '{print $0,substr($1,length($1),1)substr($2,length($2),1)}' $i \ | sed 's/\xc2\xb0\([0-9]\{1,2\}\).\([NEWS]\)/ \1 0 \2/g;s/\xc2\xb0\([NEWS]\)/ 0 0 \1/g;s/[^0-9NEWS]/ /g' \ | awk '{if ($9=="NE") {printf ("%.4f\t%.4f\n",$1+$2/60+$3/3600,$5+$6/60+$7/3600)}` But I'm getting this error, any ideas?: `sed: RE error: illegal byte sequence` – utt50 Sep 30 '15 at 22:13
  • what does `xc2` get you? Or is the output non-ascii? Given your need for `osx` recommend installing `gawk` and doing it all inside of there. (Maybe I'm missing why you need 3 steps (occasionally it is a simpler solution)). And if `awk` can hand `xc2` (as it looks), then why not just do the whole thing there. Read about `match()` and the variables it sets. you can replicate most of seds `\1` capture buffers with that. Busy tonight, so can't help much more. But good luck ;-)! – shellter Sep 30 '15 at 23:10
  • Also, I'd rewrite your question just to focus on this conversion and your problems. Be sure to include sample input, required output, your current output, error messages and code. YOu're getting close. Good luck. – shellter Sep 30 '15 at 23:12

4 Answers4

5

Better later than never, right.

So, I just came across the same issue and I've managed to make the conversion using the EXIFTool itself. Try this:

exiftool -n -p '$GPSLatitude,$GPSLongitude' image_name.jpg

The converted coordinates are slightly longer than proposed by Google, but the API accepted it fine.

Cheers.

Marco
  • 51
  • 1
  • 1
2

For #1, the awk should not be that complicated:

awk '/GPS Position/{
  lat=$4; lat+=strtonum($6)/60; lat+=strtonum($7)/3600; if($8!="N,")lat=-lat;
  lon=$9; lon+=strtonum($11)/60; lon+=strtonum($12)/3600; if($13!="E")lon=-lon;
  printf "%.7f %.7f\n",lat,lon
  }'
Jeff Y
  • 2,437
  • 1
  • 11
  • 18
0

I ended up doing it in PHP, but thanks for the tip Marco I'll check it out!

function get_gps($gps_pos) {

$parts = explode(" ",str_replace(array("deg ",",","'","\""),"",$gps_pos));

$lat_deg = $parts[0];
$lat_min = $parts[1];
$lat_sec = $parts[2];
$lat_dir = $parts[3];

$lon_deg = $parts[4];
$lon_min = $parts[5];
$lon_sec = $parts[6];
$lon_dir = $parts[7];

if ($lat_dir == "N") {
    $lat_sin = "+";
    } else {
    $lat_sin = "-";
    }

if ($lon_dir == "E") {
    $lon_sin = "+";
    } else {
    $lon_sin = "-";
    }

$latitiude = $lat_sin.($lat_deg+($lat_min/60)+($lat_sec/3600));
$longitude = $lon_sin.($lon_deg+($lon_min/60)+($lon_sec/3600));

return $latitiude.",".$longitude;

}
utt50
  • 155
  • 2
  • 9
0

From man exiftool (note the last line):

   -c FMT (-coordFormat)
        Set the print format for GPS coordinates.  FMT uses the same syntax
        as a "printf" format string.  The specifiers correspond to degrees,
        minutes and seconds in that order, but minutes and seconds are
        optional.  For example, the following table gives the output for
        the same coordinate using various formats:

                    FMT                  Output
            -------------------    ------------------
            "%d deg %d' %.2f"\"    54 deg 59' 22.80"  (default for reading)
            "%d %d %.8f"           54 59 22.80000000  (default for copying)
            "%d deg %.4f min"      54 deg 59.3800 min
            "%.6f degrees"         54.989667 degrees

And regarding "There are a few free web tools available but they don't provide an API"—geoapify.com offers a free web tool but also an API. Their API is free for up to three thousand requests per day. Their web service does five hundred at a time.

WGroleau
  • 448
  • 1
  • 9
  • 26