使用exiftool获取GPS位置信息,通过Bash实现逆地理编码

5
我正在编写一个基于EXIF标签重命名JPG文件的Bash脚本。我的原始文件命名如下:
IMG_2110.JPG
IMG_2112.JPG
IMG_2113.JPG
IMG_2114.JPG

我需要将它们改名为这样:
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

我的bash脚本使用exiftool解析EXIF头并重命名文件。对于那些不包含EXIF创建日期的文件,我使用文件修改时间。
#!/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

我卡在了位置上。我需要使用来自EXIF标签的GPS信息来确定国家和城市。exiftool提供了一个名为“GPS Position”的字段。在所有字段中,这似乎是确定位置最有用的字段。
GPS Position : 40 deg 44' 49.36" N, 73 deg 56' 28.18" W

谷歌提供了一个公共的地理位置API,但是需要使用这种格式的纬度/经度坐标:
40.7470444°, -073.9411611°

API返回了相当多的信息(点击链接查看结果):

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

我的问题是:
1.如何将GPS位置格式化为提供给Google地理定位等服务可接受的纬度/经度值?
2.如何解析JSON结果以一致的方式提取国家和城市,适用于许多不同类型的位置?使用Curl,然后呢?理想情况下,我想以一种方式处理美国位置,以另一种方式处理非美国位置。美国位置将被格式化为USA-STATE-City,而非美国位置将被格式化为COUNTRY-City。
我需要在一个bash脚本中完成所有这些。我已经查看了pygeocoder和gpsbabel,但它们似乎不能解决问题。有一些免费的网络工具可用,但它们不提供API(http://www.earthpoint.us/Convert.aspx)。

一个有趣的任务。请参考此问题的公式:http://stackoverflow.com/questions/15962939/how-to-convert-gps-north-and-gps-west-to-lat-long-in-objective-c。这应该不难完成。记得 $(( math expressions )) 可以帮助你。祝你好运。 - shellter
看起来我要像这样调整一些东西(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)}' 但是我遇到了这个错误,有什么想法吗?: sed:RE错误:非法字节序列
- utt50
xc2会给你什么?或者输出是非ASCII码吗?考虑到你需要在osx上使用,建议安装gawk并在其中完成所有操作。(也许我错过了为什么你需要3个步骤的原因(有时候简单的解决方案更好))。如果awk可以处理xc2(看起来是可以的),那么为什么不在那里完成整个操作呢?阅读关于match()和它设置的变量的内容。你可以用它来复制大多数seds\1捕获缓冲区。今晚很忙,所以不能提供更多帮助。但祝你好运!;-) - shellter
此外,我建议您重新编写问题,以便更专注于此转换和您的问题。请确保包括样本输入、所需输出、当前输出、错误消息和代码。您已经接近成功了,祝您好运。 - shellter
4个回答

5

迟到总比不来好,是吧。

那么,我刚遇到了同样的问题,而且我已经成功使用EXIFTool进行转换。尝试这个:

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

转换后的坐标比谷歌提供的略长,但API接受得很好。

干杯。


2
对于 #1,awk 不应该那么复杂:
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
  }'

0

最终我用PHP完成了它,但感谢Marco的提示,我会去看看的!

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;

}

0

来自man exiftool(注意最后一行):

   -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

关于“有一些免费的网络工具可用,但它们不提供API”——geoapify.com提供免费的网络工具,同时也提供API。他们的API每天免费提供三千个请求。他们的网络服务每次处理五百个请求。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接