exif feldolgozás

A cél hogy kinyerjem a képből a GPS adatok alapján a város (helység) nevét, de sajna kis problémába ütköztem. Vannak képek melyek egyáltalán nem tartalmazzák a GPS adatokat, ezeket kapásból kihagynám a feldolgozásból.

if true; then
    exiftool -p '$GPSDateStamp' $1 2>&1 | grep -v "not defined"
    echo "nincs gps adat"
    exit 
else
    echo "van gps adat"
fi    

De ez így nem is működik. Akkor is az első ág hajtódik végre ha - auuu talán éppen azért mert a $1 is az első ágban van? Befejezem a mondatot - ha van GPS adat.
A lényeg hogy jó lenne ideiglenes fájlok nélkül feldolgozni a képeket. (xml, json) A Google maps API-hoz regisztráció kell, s most azt kihagynám. Ellenben az OSM működik.
Haladjunk sorjában. Az első probléma hogy a sima 

exiftool -n -p '$GPSLatitude' IMG_20160716_085603.jpg

is hibát dob

44.27358625
Warning: [minor] Unrecognized MakerNotes - IMG_20160716_085603.jpg
 

Ha csak simán ki iratom: 
$ exiftool -n IMG_20160716_085603.jpg

GPS Date/Time                   : 2016:07:16 05:56:02Z
GPS Latitude                    : 44.27358625
GPS Longitude                   : 28.6205234444444
Focal Length                    : 3.16
GPS Position                    : 44.27358625 28.6205234444444

Az exiftool verziója: 
$ rpm -qa | grep ExifTool
perl-Image-ExifTool-12.0.0-1.2.mga8
 

Ezek a képek többnyire androidos telefonnal készültek. A hibaüzenetek ellenére a következő megoldás működik.

lat="$(exiftool -n -p '$GPSLatitude' $1)"
lon="$(exiftool -n -p '$GPSLongitude' $1)"

#curl -s "https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&addressdetails=1" | jq -r .address.town $1
curl -s "https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&addressdetails=1" | jq -r .address.city $1

A -n kapcsoló feldolgozhatóbb formában adja a GPS adatokat, a -p lenne a felelős a speciális kiírásért. Viszont emiatt van hibaüzenet. De most grep és awk ? - szvsz lassú lenne.
Még itt is kell majd egy feltétel vizsgálat, mert érdekes módon van ahol nem is létezik a city mező, hanem a town mezőben található a város neve. Ezt vajon hogyan dolgozzam fel? A sima if then vajon itt hogyan működne? Hiszen ezek a json válaszon belül vannak. Szvsz csak akkor működne ha ideiglenes fájlt hoznék létre. 

A végső cél a képekből kinyert információk alapján létrehozni egy ilyesmi mappa struktúrát. 

Kameramodell/Város/év/év-hónap/kép 

Jelenleg van egy működő megoldásom a város nélküli feldolgozásra

exiftool -r -progress -d '%Y/%Y-%m/PIC_%Y%m%d_%H%M%S%%-c.%%le' '-filename<${make}_${model}/${datetimeoriginal}' .

A progress elhagyásával gyorsabb persze, de így látni hogy dolgozik. Ide kellene majd befűznöm valahogy a város mappa létrehozását. Viszont azt már tudom hogy a -d '%Y/%Y-%m/PIC_%Y-%m-%d_%H:%M:%S' közé nem lehet semmit beszúrni, mert azt simán hozzáteszi a fájlnévhez. Ez adja a 2019/2019-03/PIC_2019-03-23_145832 mappaszerkezetet és fájlnevet. Vagyis még előtte a -drectory kapcsolóval kell majd behatóbban foglalkoznom.

Hozzászólások

Szerkesztve: 2023. 02. 10., p – 12:50

Az if true értelmetlen, mert a büdös életben nem fog a hamis ágra rátévedni.

Tehát kezdd azzal, hogy:

if exiftool ... | grep

(A többit még rágnom kell, mert nem nagyon világos, hogy pontosan mit is akarsz és hol jönnek be az átmeneti fájlok.)

 

Én amúgy valahogy így csinálnám:

IMG=xyz

lat=$( exiftools -n -p '$GPSLatitude' $IMG 2> /dev/null )

lon=$( exiftools -n -p '$GPSLongitude' $IMG 2> /dev/null )

if test -n "$lat" -a -n "$lon" ; then # voltak koordináták

...

else # nem voltak koordináták

echo nem nyert

fi

(Ellenben továbbmenni nem tudok, mert a curl-os lekérdezésed létező koordinátákkal nem ad vissza semmit, azt meg nem tudom tovább parsolni jq-val.) OK, kikerülve a proxyt, már látom hogy mi van, de így sem tudok lépni, mert sem city sem town nem jó neki, a válaszban egyik sincs, csak egy display_name (ami egyébként kellően pontos).

lat=47.5538859722222

lon=19.0757359722222

amúgy amivel néztem.

Igen. Ez érdekes. Ahány kép annyi infó?

curl -s 'https://nominatim.openstreetmap.org/reverse?format=json&lat=44.27358625…' | jq .

Itt sincs city, hanem town. De a város ahol voltam az Constanta. Azon belül persze biztos Návodari.

Tehát itt a jq nem adress.city, hanem adress.town - de ezt hogyan válasszam szét ha nincs city, akkor van town?

curl -s 'https://nominatim.openstreetmap.org/reverse?format=json&lat=46.89762496…' | jq .
Itt meg sem city, sem town. 

curl -s 'https://nominatim.openstreetmap.org/reverse?format=json&lat=47.88815689…'| jq .
Ez pl. Dobogókő, de nem is azt írja ki.

 

lat="$(exiftool -n -p '$GPSlatitude' $1)"
lon="$(exiftool -n -p '$GPSlongitude' $1)"
osm="http://www.openstreetmap.org/?mlat=${lat}&mlon=${lon}&zoom=18"
xdg-open $osm

Ezzel még a térképen is megmutatja, de itt sem Dobogókő van. Ez hogy lehetséges? 
No. Érdekes dologra jöttem rá, de még nem értem.
Sima exiftool lekérdezéskor: GPS Position                    : 47 deg 53' 17.36" N, 19 deg 0' 18.01" E
exiftool -n lekérdezéskor: GPS Position                    : 47.8881568908333 19.0050029752778

Ezért nem pontos.
 

OK. Már működik, de azt nem tudom hogy megoldható-e hogy ne kelljen 3x végigmenni a mappán? Ugyanis a feldolgozandó json adatokban különböző megnevezések találhatók a helységnevekre.
town, village, city 

#!/bin/bash

noGPSdir="noGPS"

if [ ! -d "${noGPSdir}" ]; then
    mkdir "${noGPSdir}"
fi

searchCity () {
    rename JPG jpg *.JPG 2>/dev/null
    chmod 644 *.jpg
    for files in *.jpg ; do 
        lat="$(exiftool -n -p '$GPSlatitude' "${files}" 2>/dev/null)"
        lon="$(exiftool -n -p '$GPSlongitude' "${files}" 2>/dev/null)"
        if test -n "${lat}" -a -n "${lon}"; then
#            echo "$files - van koordináta"
            cityName="$(curl -s "https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}" | jq -r "${secn}")"
            
            if [ ! -d "${cityName}" ]; then
                if [ ! "${cityName}" = "null" ]; then
                    mkdir "${cityName}"
                fi
            fi
            if [ ! "${cityName}" = "null" ]; then
                mv "${files}" "${cityName}"
            fi
        else
#            echo "${files} - nincs koordináta"
            mv "${files}" "${noGPSdir}"
        fi
    done
}

secn=".address.town"
echo "address.town figyelése ***************"
searchCity

secn=".address.village"
echo "address.village figyelése ************"
searchCity

secn=".address.city"
echo "address.city figyelése ***************"
searchCity

#exiftool -r -d '%Y/%Y-%m/PIC_%Y%m%d_%H%M%S%%-c.%%le' '-testname<%-1:D/${make}_${model}/${datetimeoriginal}' .
#exiftool -r -ext jpg -progress -d '%Y/%Y-%m/PIC_%Y%m%d_%H%M%S%%-c.%%le' '-filename<%-1:D/${make}_${model}/${datetimeoriginal}' .

#/usr/bin/halt -p >/dev/null 2>&1

Én nem vagyok programozó. De azért köszi hogy segítettél.

20 percre rá írok ide újra: 

| jq -r '.address.town, .address.village, .address.city' | grep -v "null" | sed '/^$/d'

Ennél jobb ötletem nincs.

Előrebocsátva hogy fogalmam sincs, hogy hogyan néz ki a jq outputja...

Először is, meg kéne értened, hogy mit csinálsz.

Akkor alighanem rájönnél, hogy a for ciklusba akár tehetsz egy másik for ciklust is, amiben végigmész az address.town address.village address.city hármason.

Praktikusan úgy, hogy a curl outputját kiteszed vagy egy fájlba, vagy egy változóba, és abban keresgélsz, nem kéred le háromszor ugyanazt a koordinátát.

A Te megoldásoddal az lehet a probléma, hogy esetleg nem csak egy mező van kitöltve. Ezen persze könnyen lehet segíteni, pl. egy head -1 -el, de még egyszer, fogalmam sincs, hogy hogyan néz ki a jq outputja.

$ curl -s "https://nominatim.openstreetmap.org/reverse?format=json&lat=44.27358625…" | jq .                                                                  
{
 "place_id": 288614026,
 "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
 "osm_type": "way",
 "osm_id": 972759169,
 "lat": "44.27458655",
 "lon": "28.619714697791537",
 "display_name": "Camping Holiday GPM Mamaia Nord, Bulevardul Mamaia, Mamaia, Năvodari, Zona Metropolitană Constanța, Constanța, 905701, România",
 "address": {
   "tourism": "Camping Holiday GPM Mamaia Nord",
   "road": "Bulevardul Mamaia",
   "village": "Mamaia",
   "town": "Năvodari",
   "municipality": "Zona Metropolitană Constanța",
   "county": "Constanța",
   "ISO3166-2-lvl4": "RO-CT",
   "postcode": "905701",
   "country": "România",
   "country_code": "ro"
 },
 "boundingbox": [
   "44.2734343",
   "44.2753739",
   "28.6178906",
   "28.6214955"
 ]
}

Megoldásnak ezt találtam ki: 

curl -s "https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&addressdetails=1" | jq -r '.address.town, .address.village, .address.city' | grep -v "null" | head -n1

Így csak egy helységnév lesz, és a null-t is kilőttem. Mivel ha ezt nem teszem akkor null_null_Budapest jellegű mappák is létrejöhetnek. Ennek függvényében jó pár sort is kitörölhettem a scriptből. A head meg azért kellett, mert a fenti kimenetben is látható hogy két név is szóba jöhetne.