What kind of metadata?
As many people have guessed, this is about EXIF data. Actually, it stores width, height, date, size, geo position, photograph type, camera properties and much more. From this list we need the geo position.
How to work with it?
It’s very simple. For this purpose there is a special extension for PHP, called exif. If you do not have it installed, you should install it to continue.
Let’s start
First, let’s create file index.php, where a form for uploading a file should be. We write a simple HTML code there.
<!DOCTYPE HTML> <html lang="en-US"> <head> <m-eta charset="UTF-8"> <t-itle>Getting photograph geo coordinated in PHP</title> </head> <body> <?php if( isset( $_GET['error'] ) ): ?> <!-- Error --> <p class="error"> <?php switch ($_GET['error']) { case 1: echo "Photo not available."; break; case 2: echo "Invalid format."; break; case 3: echo "This photo has no geo position data. Try to upload another one."; break; } ?> </p> <?php endif; ?> <p>Upload a jpeg photo.</p> <form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="image"> <br> <input type='submit' value="Upload!"> </form> </body> </html>
As you can see there is nothing complicated. It is a simple uploading form that sends data to file upload.php. I have also written here error messages. The errors appear if one go to /index.php?error=1
And then?
Then we create file upload.php.
<?php // If the picture is not uploaded // Redirect to the main with the error } // If the image type is not jpeg if( $_FILES['image']['type'] !== 'image/jpeg' ) { // Redirect to the main with the error }
Here we check whether the file is uploaded. If not, then we redirect to the main with the error. Then we check whether the file format matches the desired. If not, then, again, we redirect to the main with the error. If all goes well, then we go ahead.
// We will use a temporary file path $img = $_FILES['image']['tmp_name']; // We get the data // We oupput the result
Thus, we get all the EXIF photo data. Let's see what's there.
Let’s open
We need a GPS branch from this list.
This branch has several parameters. Let's see what the parameters are they.
GPSLatitude is the latitude
GPSLatitudeRef can take two parameters: N (northern) and S (southern) latitude
GPSLongitude is the longitude
GPSLongitudeRef can take two parameters: E (eastern) and W (western) longitude
GPSTimeStamp is time when the photograph was taken
GPSImgDirectionRef can take two parameters: T (true) and M (magnetic) direction
GPSImgDirection defines image direction. It can range from 0.00 to 359.99.
We actually need only the first 4 parameters. If you notice, the coordinates (as well as and other parameters) look not very well there: they are represented by division. For example:
2674/100 = 26.74
For they looked normal, we write the conversion function at the top of the file.
// Get the coordinates of the line function getCoord( $expr ) { return $expr_p[0] / $expr_p[1]; } Now everything’s all right. We go ahead. // If there is no GPS branch // Redirect to the main with the error }
We have already known this code.
UPD: We still need to “normalize” the code. The point is in the metadata the coordinates are written in a format not as desired. To do this, we just need to write so.
// Latitude $latitude['degrees'] = getCoord( $exif['GPS']['GPSLatitude'][0] ); $latitude['minutes'] = getCoord( $exif['GPS']['GPSLatitude'][1] ); $latitude['seconds'] = getCoord( $exif['GPS']['GPSLatitude'][2] ); // Longitude $longitude['degrees'] = getCoord( $exif['GPS']['GPSLongitude'][0] ); $longitude['minutes'] = getCoord( $exif['GPS']['GPSLongitude'][1] ); $longitude['seconds'] = getCoord( $exif['GPS']['GPSLongitude'][2] );
Now we go to the submission of the coordinates. At the bottom of file upload.php, after closing PHP tag, we write HTML code.
<!DOCTYPE HTML> <html lang="en-US"> <head> <m-eta charset="UTF-8"> <t-itle>Getting photograph geo coordinates in PHP</title> </head> <body> <h1>Geo coordinated</h1> <p> Latitude: <?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?> <?=$latitude['degrees']?><sup>o</sup> <?=$latitude['minutes'] ?>' <?=$latitude['seconds'] ?>'' </p> <p> Longitude: <?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?> <?=$longitude['degrees']?><sup>o</sup> <?=$longitude['minutes'] ?>' <?=$longitude['seconds'] ?>'' </p> <p> <a href="https://maps.google.com/maps?q=<?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?> <?=$latitude['degrees']?>+ <?=$latitude['minutes']?>'+ <?=$latitude['seconds']?>'',+ <?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?> <?=$longitude['degrees']?>+<?=$longitude['minutes']?>'+ <?=$longitude['seconds']?>''" target="_blank">Show on the map</a> </p> </body> </html>
Here we display the result in the screen, as well as a link to Google map with these coordinates. As a result, we obtain the geo position data of the photograph.
Thanks you for reading!
index.php<!DOCTYPE HTML> <html lang="en-US"> <head> <m-eta charset="UTF-8"> <t-itle> Getting photograph geo coordinates in PHP </title> </head> <body> <?php if( isset( $_GET['error'] ) ): ?> <!-- Error --> <p class="error"> <?php switch ($_GET['error']) { case 1: echo "Photo not available."; break; case 2: echo "Incorrect format."; break; case 3: echo " This photo has no geo position data. Try to upload another one."; break; } ?> </p> <?php endif; ?> <p>Upload a jpeg photo.</p> <form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="image"> <br> <input type='submit' value="Upload!"> </form> </body> </html>upload.php
<?php // We obtain the coordinated of the line function getCoord( $expr ) { return $expr_p[0] / $expr_p[1]; } // If an image is not uploaded // Redirect to the main with the error } // If an image type is not jpeg if( $_FILES['image']['type'] !== 'image/jpeg' ) { // Redirect to the main with the error } // We use a temporary file path $img = $_FILES['image']['tmp_name']; // We get the data // If there is no GPS branch // Redirect to the main with the error } // Latitude $latitude['degrees'] = getCoord( $exif['GPS']['GPSLatitude'][0] ); $latitude['minutes'] = getCoord( $exif['GPS']['GPSLatitude'][1] ); $latitude['seconds'] = getCoord( $exif['GPS']['GPSLatitude'][2] ); // Longitude $longitude['degrees'] = getCoord( $exif['GPS']['GPSLongitude'][0] ); $longitude['minutes'] = getCoord( $exif['GPS']['GPSLongitude'][1] ); $longitude['seconds'] = getCoord( $exif['GPS']['GPSLongitude'][2] ); ?> <!DOCTYPE HTML> <html lang="en-US"> <head> <m-eta charset="UTF-8"> <t-itle>Getting photograph geo coordinates in PHP</title> </head> <body> <h1>Geo coordinates</h1> <p> Latitude: <?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?> <?=$latitude['degrees']?><sup>o</sup> <?=$latitude['minutes'] ?>' <?=$latitude['seconds'] ?>'' </p> <p> Longitude: <?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?> <?=$longitude['degrees']?><sup>o</sup> <?=$longitude['minutes'] ?>' <?=$longitude['seconds'] ?>'' </p> <p> <a href="https://maps.google.com/maps?q=<?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?> <?=$latitude['degrees']?>+<?=$latitude['minutes']?>'+ <?=$latitude['seconds']?>'',+<?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?> <?=$longitude['degrees']?>+<?=$longitude['minutes']?>'+<?=$longitude['seconds']?>' '" target="_blank">Show on the map</a> </p> </body> </html>