[GRASS-user] Vector point from EXIF GPS data

Hi everyone,

Has anyone tried to import the GPS data stored in a JPEG's EXIF metadata into GRASS? I've had some luck, but the system I've come up with is very clunky (mixture of python pexif module and then m.proj to assist import). I'm wondering if anyone has come across anything more robust, maybe as a shell script with jhead?

Josh.

On 14/05/2011 4:08 pm, Micha Silver wrote:

On 05/14/2011 05:55 PM, Joshua Arnott wrote:

Hi everyone,

Has anyone tried to import the GPS data stored in a JPEG's EXIF metadata into GRASS? I've had some luck, but the system I've come up with is very clunky (mixture of python pexif module and then m.proj to assist import). I'm wondering if anyone has come across anything more robust, maybe as a shell script with jhead?

There's exiftool. Maybe this will be of help:
http://www.surfaces.co.il/?p=817

I think I put enough information there to wrap the process into a shell script.

Regards,
Micha

Thanks! I've got something working nicely now.

J.

Hello,
This is my ‘amateur’ solution:

def getXYfromFoto(foto):
proc=subprocess.Popen(‘exif -mt GPSLatitude ‘+foto, shell=True,stdout=subprocess.PIPE)#foto: is the route to a jpg image from a camera Sony DSC-HX5V
stdout_value = proc.communicate()[0]
da=stdout_value[0:len(stdout_value)-1]
sp=da.split(’, ‘)
lat=float(sp[0].replace(’,’,‘.’))+float(sp[1].replace(‘,’,‘.’))/60+float(sp[2].replace(‘,’,‘.’)[0:5])/3600
print lat
proc2=subprocess.Popen(‘exif -mt GPSLongitude ‘+foto, shell=True,stdout=subprocess.PIPE)
stdout_value = proc2.communicate()[0]
da2=stdout_value[0:len(stdout_value)-1]
sp2=da2.split(’, ‘)
lon=float(sp2[0].replace(’,’,‘.’))+float(sp2[1].replace(‘,’,‘.’))/60+float(sp2[2].replace(‘,’,‘.’)[0:5])/3600
print lon
proc3=subprocess.Popen(‘exif -mt GPSLongitudeRef ‘+foto, shell=True,stdout=subprocess.PIPE)
stdout_value = proc3.communicate()[0]
da3=stdout_value[0:len(stdout_value)-1]
print da3
if da3[0:1]==‘W’:
lonLat=’"-’+str(lon)+’ ‘+str(lat)+’“’
else:
lonLat='”‘+str(lon)+’ ‘+str(lat)+’"’
print lonL #in wgs84
proc4=subprocess.Popen(‘echo ‘+lonLat+’ | m.proj -i --quiet’, shell=True,stdout=subprocess.PIPE)GRASS GIS must be running, in my case eur50 datum.
stdout_value = proc4.communicate()[0]
da4=stdout_value[0:len(stdout_value)-1]
print ‘da4’
print da4
pse=da4.split(’ ‘)
XY=pse[0].replace(’\t’,‘,’)
print ‘XY’
print XY
return XY# in UTM eu50 30N

hope usefull for you
Juan M. Garijo


De: Joshua Arnott josh@snorfalorpagus.net
Para: grass-user@lists.osgeo.org
Enviado: sáb,14 mayo, 2011 16:55
Asunto: [GRASS-user] Vector point from EXIF GPS data

Hi everyone,

Has anyone tried to import the GPS data stored in a JPEG’s EXIF metadata into GRASS? I’ve had some luck, but the system I’ve come up with is very clunky (mixture of python pexif module and then m.proj to assist import). I’m wondering if anyone has come across anything more robust, maybe as a shell script with jhead?

Josh.


grass-user mailing list
grass-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-user

On 15/05/2011 6:31 pm, Juan Miguel Garijo wrote:

Hello,
This is my ‘amateur’ solution:

def getXYfromFoto(foto):
proc=subprocess.Popen(‘exif -mt GPSLatitude ‘+foto, shell=True,stdout=subprocess.PIPE)#foto: is the route to a jpg image from a camera Sony DSC-HX5V
stdout_value = proc.communicate()[0]
da=stdout_value[0:len(stdout_value)-1]
sp=da.split(’, ‘)
lat=float(sp[0].replace(’,’,‘.’))+float(sp[1].replace(‘,’,‘.’))/60+float(sp[2].replace(‘,’,‘.’)[0:5])/3600
print lat
proc2=subprocess.Popen(‘exif -mt GPSLongitude ‘+foto, shell=True,stdout=subprocess.PIPE)
stdout_value = proc2.communicate()[0]
da2=stdout_value[0:len(stdout_value)-1]
sp2=da2.split(’, ‘)
lon=float(sp2[0].replace(’,’,‘.’))+float(sp2[1].replace(‘,’,‘.’))/60+float(sp2[2].replace(‘,’,‘.’)[0:5])/3600
print lon
proc3=subprocess.Popen(‘exif -mt GPSLongitudeRef ‘+foto, shell=True,stdout=subprocess.PIPE)
stdout_value = proc3.communicate()[0]
da3=stdout_value[0:len(stdout_value)-1]
print da3
if da3[0:1]==‘W’:
lonLat=’"-’+str(lon)+’ ‘+str(lat)+’“’
else:
lonLat='”‘+str(lon)+’ ‘+str(lat)+’"’
print lonL #in wgs84
proc4=subprocess.Popen(‘echo ‘+lonLat+’ | m.proj -i --quiet’, shell=True,stdout=subprocess.PIPE)GRASS GIS must be running, in my case eur50 datum.
stdout_value = proc4.communicate()[0]
da4=stdout_value[0:len(stdout_value)-1]
print ‘da4’
print da4
pse=da4.split(’ ‘)
XY=pse[0].replace(’\t’,‘,’)
print ‘XY’
print XY
return XY# in UTM eu50 30N

hope usefull for you
Juan M. Garijo

Here is the solution I ended up with. It uses jhead rather than exiftool as for the 200 images I have to process I found it to be ~2x faster. It means jumping through some extra hoops with awk to get the lat/long formatting in a way m.proj will accept and some more to get the dates with / instead of :. The output is ready to pipe into GRASS using something like:

v.in.ascii in=exif.txt out=photos x=2 y=3 z=4 columns=‘filename varchar(40),x double precision,y double precision, z double precision, date varchar(19)’

#!/bin/bash

for FILENAME in “$@”; do

use jhead to read exif metadata

EXIF=jhead $FILENAME

awk metadata into variables

LON=echo "$EXIF" | awk '/Longitude/ {sub(/m/,"'"'"'"); sub(/s/,"\""); print $4$5$6$3}'
LAT=echo "$EXIF" | awk '/Latitude/ {sub(/m/,"'"'"'"); sub(/s/,"\""); print $5$6$7$4}'
ALT=echo "$EXIF" | awk '/Altitude/ {sub(/m/,""); print $4}'
DATE=echo "$EXIF" | awk '/Date\/Time/ {gsub(/\:/,"/");print $3}'
TIME=echo "$EXIF" | awk '/Date\/Time/ {print $4}'

transform to current projection

if [ ${#ALT} -lt 1 ]; then ALT=0; XYZ=42; fi
PROJ=echo "$LON $LAT $ALT" | m.proj -i
PROJ_LON=echo $PROJ | awk 'BEGIN {FS = "|"}{print $1}'
PROJ_LAT=echo $PROJ | awk 'BEGIN {FS = "|"}{print $2}'
if [ ${XYZ:-0} -ne 42 ]; then PROJ_ALT=echo $PROJ | awk 'BEGIN {FS = "|"}{print $3}'; fi

output

echo “$FILENAME|$PROJ_LON|$PROJ_LAT|$PROJ_ALT|$DATE $TIME”
done