Name: | insertPhotoWaypoints |
Typ: | bash |
benötigt: | exif (lese Exif-Informationen) |
Viele Kameras speichern Datum/Uhrzeit, nicht aber die Position per gps. Anhand der Uhrzeit können mit Hilfe des Scripts Wegpunkte in einen GPX-Track eingefügt werden, so dass mit einem entsprechenden Programm (hier Jürgen Berkemeiers Script GPX Viewer) der Track mit Fotos angezeigt werden kann.
Das Script liest eine gpx-Datei und sucht in den trackpoints nach einem Datum, dass
möglichst nah an der exif-Information der Fotos liegt
Ich verwende das Tag DateTimeOriginal, da dies von meiner Kamera geliefert wird
(eventuell ist hier eine Anpassung des Scripts fuer andere Kameras nötig).
In die gpx-Datei wird dann ein waypoint aufgenommen, der den Namen des Fotos traegt.
Die originale gpx-Datei wird als backup gespeichert.
Da ich direkt beim ersten Versuch eine Abweichung von einer Stunde hatte (MEZ vs UTC), wird ein Zeit-Shift
eingebaut. Das Datum des Fotos wird fuer die Berechnung veraendert.
GPS-Daten sind laut wikimedia in utc angegeben, wie eine Kamera speichert weiss ich nicht, daher ist die
Korrektur vorgesehehen. Die Angabe ist in Stunden oder in Sekunden möglich. (Sekunden, falls die Uhrzeit
eines der Geräte nicht stimmt.)
Beispielaufruf: insertPhotoWaypoints.sh 2013-08-01-Donnerstag*jpg 2013-08-01-Felsentor.gpx
Der Quelltext:
#!/bin/bash # KR - q&d, 2014-01-02 function abs () { declare -i res res=$1 if [[ $res -lt 0 ]] then let "res *= (-1)" fi eval $1="$res" } function containsElement () { local e for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done return 1 } echo echo "Viele Kameras speichern Datum/Uhrzeit, nicht aber die Position per gps" echo "Dieses Script liest eine gpx-Datei und sucht in den trackpoints nach einem Datum, dass" echo "möglichst nah an der exif-Information der Fotos liegt" echo "Verwende das Tag DateTimeOriginal, da dies von meiner Kamera geliefert wird" echo "(eventuell ist hier eine Anpassung des Scripts fuer andere Kameras noetig)" echo "In die gpx-Datei wird dann ein waypoint aufgenommen, der den Namen des Fotos traegt" echo "Damit kann das Bild dann von JBs gpxViewer angezeigt werden" echo "Die originale gpx-Datei wird als backup gespeichert." echo echo "Da ich direkt beim ersten Versuch eine Abweichung von einer Stunde hatte (MESZ vs UTC), wird ein Zeit-Shift eingebaut. (Eingabe unten). Das Datum des Fotos wird fuer die Berechnung veraendert. GPS-Daten sind laut wikimedia in utc angegeben, wie eine Kamera speichert weiss ich nicht, daher ist die Korrektur vorgesehehen. Es sind Angaben in Stunden oder Sekunden moeglich, da evtl. auch mal die Zeit bei einem der Geraete verstellt ist..." echo echo "Beispielaufruf: insertPhotoWaypoints.sh 2013-08-01-Donnerstag*jpg 2013-08-01-Felsentor.gpx" if [[ $# -lt 2 ]] then echo -e "\n -> Fehler: Anzahl Parameter stimmt nicht" exit fi nargs=$# files=("$@") echo ${files[@]} gpx=${files[$((nargs-1))]} unset files[$((nargs-1))] let nargs-- echo -e "\nBild-Dateien: " ${files[@]} echo "GPX-Datei: " $gpx echo "Stundenkorrektur (Berechnung Foto Datum wird geschoben, zb +1 / -1) Stress mit Sommerzeit und so :-) [0]" echo "Angabe auch in Sekunden möglich, z.B. 1800s oder -1800s (vgl. Delta der Ausgabe) Kommazahlen nicht moeglich" read tshift if [[ "$tshift". == "." ]] then tshift=0 else right=${tshift:(-1)} if [[ $right == 's' ]] then tshift=${tshift/s/} let "tshift *= 1" #sicher int? else let "tshift *= 3600" fi echo "Shift in Sekunden: $tshift" fi echo "Enter: weiter, ctrl-c zum abruch, d -> dry, keine Aenderung, nur Analyse " read dry #template wegpunkt wpTemplate='\n <wpt %pos >\n <ele>%ele</ele>\n <time>%datumT%zeitZ</time>\n <name>%bildName</name>\n <cmt></cmt>\n <desc></desc>\n <sym>Scenic Area</sym>\n </wpt>\n' declare -a wpA declare -a posA #datei in array lesen mapfile -t gpxContent < "$gpx" #bilder abarbeiten for b in "${files[@]}" do echo -e "\nBild " $b bildDatum=$(exif $b -t DateTimeOriginal | grep -m 1 "Value" | cut -c 10-28) if [[ $bildDatum"." = "." ]] then echo $b has no exif - or is actually renamed - we do nothing continue fi datum=${bildDatum/ */} datum=$(echo $datum | tr ':' '-') #bash ersetzt nur ein zeichen? zeit=${bildDatum/* /} bildDatum="$datum $zeit" secondsBildSince1970=$(date -d "$bildDatum" '+%s') if [[ tshift -ne 0 ]] then let "secondsBildSince1970 += tshift" zeit=$(date -d @$secondsBildSince1970 '+%T') datum=$(date -d @$secondsBildSince1970 '+%F') bildDatum="$datum $zeit (korrigiert)" fi #echo $secondsBildSince1970 open=0 #minimalwerte sind die werte deren trackpoint den geringsten zeitlichen Abstand #vom korrigierten Datum/Zeit des Fotos hat unset deltaMin unset tmin unset positionMin unset elevationMin for l in "${gpxContent[@]}" do #suche nach trkpt if [[ "$l" == *"<trkpt"* ]] then open=1 position=${l/*trkpt /} position=${position/>*/} elif [[ "$l" == *"</trkpt"* ]] then open=0 elif [[ "$l" == *"ele"* ]] then elevation=${l/*<ele>/} elevation=${elevation/<*/} fi #wenn <trkpt if [[ $open -eq 1 ]] then if [[ "$l" == *"<time>"*"</time>"* ]] then #time tag weg l=${l/<time>/} l=${l/<\/time>/} secondsTRKPTSince1970=$(date -d "$l" '+%s') #utc wird beruecksichtigt if [ -z $deltaMin ] #unset oder leer then let "deltaMin=secondsTRKPTSince1970-secondsBildSince1970" deltaMinSigned=$deltaMin abs deltaMin tmin=$secondsTRKPTSince1970 positionMin=$position elevationMin=$elevation else let "delta=secondsTRKPTSince1970-secondsBildSince1970" deltaSigned=$delta abs delta if [[ delta -lt deltaMin ]] then deltaMin=$delta deltaMinSigned=$deltaSigned tmin=$secondsTRKPTSince1970 positionMin=$position elevationMin=$elevation fi #neues deltamin fi #deltamin unset fi # time tag gefunden fi #habe einen trkpt done #schleife über alle Zeilen des gpx-Files tmint=$(date -d @$tmin '+%F %T') echo "Bild: $bildDatum und Trackpoint mit geringster Abweichung: $tmint mit Delta: $deltaMinSigned" #check Position - Manipulation nicht als Funktion hinbekommen, haette besser doch ein php-Script geschrieben #bloede trickserei mit . um einen Trennchar zu haben #containsElement ".$positionMin." "${posA[@]}" #echo "contains " $? #war mal ein Gedanke - verschiebe einen Punkt etwas, wenn er da ist, das ist #unsinn. Der wptType in Gpx1.1 bietet vielleicht über das Tag extensions die #Einbindung mehrerer Bilder an - lasse das, erlaube mehrere gleiche Wegpunkte un #passe JBs Code an #lasse dies mal als Kommentar drin -> kann spaeter mal einem Wegpunkt ggf. mehrere Fotos #zuordnen # while containsElement ".$positionMin." "${posA[@]}" # do # lat=${positionMin/*lat=\"/} # lat=${lat/\"*/} # lon=${positionMin/*lon=\"/} # lon=${lon/\"*/} #ok, habe die Zahlen # let "r1=$RANDOM%100 - 50" #$RANDOM liefert bis 32767 # let "r2=$RANDOM%100 - 50" # latn=$(echo "scale=10;$lat + $r1/100000" | bc) # lonn=$(echo "scale=10;$lon + $r2/100000" | bc) # #echo "$lat $latn $lon $lonn" # positionMin="lat=\"$latn\" lon=\"$lonn\"" # #echo $positionMin # done # posA+=(".$positionMin.") # #echo ${posA[@]} #wp-Array add=${wpTemplate/\%pos/$positionMin} add=${add/\%ele/$elevationMin} add=${add/\%bildName/$b} add=${add/\%datum/$datum} add=${add/\%zeit/$zeit} wpA=("${wpA[@]}" "$add") done #schleife ueber alle Bilder #sicher ist sicher if [[ $dry"." != "d." ]] then cp --backup=numbered $gpx $gpx".backup" #datei neu erstellen trkFound=0 echo -n "" > $gpx for l in "${gpxContent[@]}" do if [[ "$l" == *"<trk>"* && trkFound -eq 0 ]] # waypoints heraus then trkFound=1 for wp in "${wpA[@]}" do echo -e $wp >> $gpx done fi echo $l>>$gpx done fi