Complesso solo apparentemente perché una fortunata googolata mi ha portato a conoscenza di un software per Windows che, utilizzando il file GPX del percorso ed interpolandolo con la data/ora di scatto, permetteva di estrapolare latitudine e longitudine dello scatto. Il programma in se non mi è servito a nulla ma l'idea SI!
Ho implementato in PHP un piccolo esempio (scaricabile qui) con tanto di immagine e file GPX per provarlo subito.
Ecco il codice, si potrebbe ottimizzare utilizzando una ricerca dicotomica sull'array dei punti (l'array ha un indice numerico proprio in previsione di questa modifica) e sicuramente andranno aggiunti ulteriori controlli ma l'idea è funzionante ed utilizzabile:
<?php //******************************************************* //* Esempio di una semplice tecnica per georeferenziare * //* immagini scattate con fotocamera priva di GPS * //* elaborando il file GPX ottenuto utilizzando uno dei * //* tanti software di registrazione percorsi installato * //* sullo SmartPhone. * //* * //* NOTA: * //* E' necessario che la versione minima di PHP sia la * //* 4.2.0, che siano utilizzabili le librerie standard * //* "SimpleXML" ed "Exif" * //* * //* * //******************************************************* //* Paolo Bertinetti - info@paolobertinetti.it * //******************************************************* //* Inizializzo il timezone (IMPORTANTE) date_default_timezone_set("Europe/Rome"); //****************************************************** //* Questa funzione restituisce un array con tutti i * //* punti presenti nel file GPX * //****************************************************** function loadGPX($gpx){ //* Carico in una array tutti i trackpoint del file GPX $gpxArray = new SimpleXMLElement(file_get_contents($gpx)); $tp = array(); foreach ($gpxArray->trk->trkseg as $seg) { foreach ($seg->trkpt as $point) { $tp[count($tp)] = array("lat"=>(float)$point->attributes()->{'lat'}, "lon"=>(float)$point->attributes()->{'lon'}, "ele"=>(int)$point->ele, "time"=>(string)$point->time); } } return $tp; } //****************************************************** //* Questa funzione cerca nell'array il primo elemento * //* del GPX con data/ora maggiore od uguale a quella * //* della fotografia * //****************************************************** function searchImage($img, $tp) { //* Carico in un array le informazioni EXIF, //* se presenti, per ricavare data ed ora dello scatto $exif = exif_read_data($img, "ANY_TAG", true); //* Verifico la presenza dei dati EXIF if (!($exif === false)) { //* Verifico la presenza della sezione dedicata //* alla data/ora dello scatto if (isset($exif["EXIF"]["DateTimeOriginal"])) { //* Compongo data ed ora nel formato "AAAA-MM-GG HH:MM:SS" $d = explode(" ", $exif["EXIF"]["DateTimeOriginal"]); $dateTime = str_replace(":", "-", $d[0])." ".$d[1]; //* Ora $dateTime contiene la data della foto, converto in formato UTC $dtUTC = gmdate('Y-m-d H:i:s', strtotime($dateTime)); //* Separo data ed ora... list($d, $t) = split(" ", $dtUTC); //* ...e li ricompongo ottenendo il formato utile per la //* comparazione con il campo <time></time> del file GPX $dt = $d."T".$t."Z"; //* Verifico che la data da cercare sia inclusa nell'array di coordinate if ($dt >= $tp[0]["time"] and $dt <= $tp[count($tp)-1]["time"]) { foreach ($tp as $point) { //* Cerco il primo elemento del GPX con data posteriore a quella dell'immagine if ($point["time"] >= $dt) { //* Trovato! $answer = array(0, $point["lat"] ,$point["lon"], $point["ele"]); break; } } } else { // La data dell'immagine non è compresa bel file GPX $answer = array(1, null, null, null); } } else { // Campo DateTimeOriginal non trovato nella sezione EXIF $answer = array(2, null, null, null); } } else { // Dati EXIF non trovati nell'immagine $answer = array(3, null, null, null); } return $answer; } /*** MAIN *****************************************************************/ //* Inizializzo le variabili con il nome del file GPX e quello del file JPG $gpxName = "testgpx.gpx"; $imgName = "testimg.jpg"; //* Chiamo la routine di caricamento GPX $trackPoints = loadGPX($gpxName); //* Chiamo la routine di ricerca della data/ora di scatto nel file GPX list($rc, $la, $lo, $al) = searchImage($imgName, $trackPoints); //* Visualizzo i risultati echo $rc===0 ? "Lat:$la Lon:$lo Alt:$al" : "Data scatto non trovata nel file GPX"; ?>