Jeśli spotkałeś się ze stronami które pozwalają załadować zdjęcie i następnie pokazują mapę wraz z miejscem gdzie było zrobione, a nie wiesz na czym ta magia polega, to dobrze trafiłeś... Wszystko jest zasługą kilku nagłówków zapisanych w EXIF (Exchangeable Image File Format) oraz wbudowanego GPS w aparat lub telefon ;-) Jeśli chcesz sam zrobić taką stronę lub wykorzystać funkcjonalność to mam dla Ciebie gotową receptę.
Zacznę od kilku zdań wytłumaczenia... czym jest EXIF? jest to pewien standard metadanych dla zdjęć, czyli informacji którymi możemy opisać pliki graficzne. Np. robiąc zdjęcie Twój aparat może umieścić w nim takie dane jak:
- model aparatu
- ustawienia aparatu, czas naświetlenia, wartość przesłony, czułość matrycy w ISO czy ogniskowa obiektywu oraz położenie aparatu (pionowe/poziome)
- datę wykonania zdjęcia
- miniaturkę obrazka (to jest bardzo ciekawa funkcja i trzeba na nią uważać ;-) wymazując jakieś fragmenty ze zdjęcia miniaturka nie ulega modyfikacji, na niej te fragmenty zostaną bez zmian)
- rozdzielczość w pikselach
- współrzędne geograficzne
- itd...
My skupimy się tylko na współrzędnych geograficznych (długość i szerokość). Ja dla poniższego przykładu wykorzystam PHP i rozszerzenie php-exif (w Ubuntu moduł jest automatycznie dodany do paczki).
Dane EXIF odczytujemy wykorzystując funkcję exif_read_data:
0 1 2 3 4 5 |
<?php $exif=exif_read_data("test.jpg", 0, true); var_dump($exif); ?> |
Zostanie nam zwrócona pełna struktura danych, informacji jest dość dużo, nas interesują jedynie:
["GPS"]=>
array(7) {
["GPSLatitudeRef"]=>
string(1) "N"
["GPSLatitude"]=>
array(3) {
[0]=>
string(4) "50/1"
[1]=>
string(7) "586/100"
[2]=>
string(3) "0/1"
}
["GPSLongitudeRef"]=>
string(1) "E"
["GPSLongitude"]=>
array(3) {
[0]=>
string(4) "19/1"
[1]=>
string(8) "5740/100"
[2]=>
string(3) "0/1"
}
Dane geolokalizacyjne zapisane są notacji sześćdziesiątkowej:
- godzina
- minuta
- sekunda
Napiszmy więc funkcję która wyciągnie długość i szerokość geograficzną i przeliczy je na wartości na decymalne (dla nas chyba też bardziej zrozumiałe).
gps.php:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php function gps_from_exif($plik) { $exif=exif_read_data($plik, 0, true); $szerokosc = $exif['GPS']['GPSLatitude']; list($num, $dec) = explode('/', $szerokosc[0]); $szerokosc_h = $num / $dec; list($num, $dec) = explode('/', $szerokosc[1]); $szerokosc_m = $num / $dec; list($num, $dec) = explode('/', $szerokosc[2]); $szerokosc_s = $num / $dec; $dlugosc = $exif['GPS']['GPSLongitude']; list($num, $dec) = explode('/', $dlugosc[0]); $dlugosc_h = $num / $dec; list($num, $dec) = explode('/', $dlugosc[1]); $dlugosc_m = $num / $dec; list($num, $dec) = explode('/', $dlugosc[2]); $dlugosc_s = $num / $dec; $gps_int = array($szerokosc_h + $szerokosc_m / 60.0 + $szerokosc_s / 3600.0, $dlugosc_h + $dlugosc_m / 60.0 + $dlugosc_s / 3600.0); return $gps_int; } ?> |
Funkcja wyciąga informacje GPS oraz dokonuje transformacji z systemu 60 na 10, po czym zwraca tablicę array(szerokosc, długosc):
Array
(
[0] => 50.097666666667
[1] => 19.956666666667
)
Mając te informacje możemy już wykorzystać Google Maps do prezentacji miejsca. Najszybciej możesz to zrobić, poprzez skopiowanie powyższej funkcji do pliku, np. gps.php, i stworzeniu pliku index.php który będzie go wykorzystywał:
index.php:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php include('gps.php'); $location = gps_from_exif("test.jpg"); ?> <!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100% } </style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"> </script> <script type="text/javascript"> function initialize() { var latlng = new google.maps.LatLng(<?php echo "$location[0],$location[1]"; ?> ); var myOptions = { zoom: 15, center: latlng, mapTypeId: google.maps.MapTypeId.HYBRID }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var marker = new google.maps.Marker({ position: latlng, map: map, title:"Tutaj ktos zrobil zdjecie ;-)" }); } </script> </head> <body onload="initialize()"> <div id="map_canvas" style="width:50%; height:50%"></div> </body> </html> |
test.jpg - to nazwa pliku z którego odczytujemy wartości, możesz przerobić linijkę w pliku index.php:
$location = gps_from_exif("test.jpg");
na
$location = gps_from_exif($_GET['photo']);
co da Ci to możliwość podania w URLu nazwy pliku ze zdjęciem: http://twojastrona/index.php?photo=test.jpg
Po otworzeniu tej strony powinieneś zobaczyć mapę wraz z zaznaczoną lokalizacją zrobienia zdjęcia ;-)
Dlaczego odczytywanie współrzędnych ze zdjęć jest fajne? bo w Internecie jest mnóstwo zdjęć zrobionych np. telefonem iPhone, a Ty możesz zobaczyć gdzie mieszka ta pani z odbicia w lustrze... ;-)