Getting photograph geo coordinates in PHP

Today I'll show how to find a geographic position of a photograph in PHP. Then we write a simple script with which we extract the photograph geo position from metadata.

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.

  1. <?php
  2.  
  3. // If the picture is not uploaded
  4. if( empty( $_FILES['image'] ) ) {
  5. // Redirect to the main with the error
  6. header( 'Location: /?error=1' );
  7. exit();
  8. }
  9.  
  10. // If the image type is not jpeg
  11. if( $_FILES['image']['type'] !== 'image/jpeg' ) {
  12. // Redirect to the main with the error
  13. header( 'Location: /?error=2' );
  14. exit();
  15. }
  16.  

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.

  1.  
  2. // We will use a temporary file path
  3. $img = $_FILES['image']['tmp_name'];
  4.  
  5. // We get the data
  6. $exif = exif_read_data( $img, 0, true );
  7.  
  8. // We oupput the result
  9. print_r( $exif );

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.

  1.  
  2. // Get the coordinates of the line
  3.  
  4. function getCoord( $expr ) {
  5. $expr_p = explode( '/', $expr );
  6. return $expr_p[0] / $expr_p[1];
  7. }
  8.  
  9. Now everything’s all right. We go ahead.
  10. // If there is no GPS branch
  11. if( empty( $exif['GPS'] ) ) {
  12. // Redirect to the main with the error
  13. header( 'Location: /?error=3' );
  14. exit();
  15. }
  16.  

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.

  1.  
  2. // Latitude
  3. $latitude['degrees'] = getCoord( $exif['GPS']['GPSLatitude'][0] );
  4. $latitude['minutes'] = getCoord( $exif['GPS']['GPSLatitude'][1] );
  5. $latitude['seconds'] = getCoord( $exif['GPS']['GPSLatitude'][2] );
  6.  
  7. $latitude['minutes'] += 60 * ($latitude['degrees'] - floor($latitude['degrees']));
  8. $latitude['degrees'] = floor($latitude['degrees']);
  9.  
  10. $latitude['seconds'] += 60 * ($latitude['minutes'] - floor($latitude['minutes']));
  11. $latitude['minutes'] = floor($latitude['minutes']);
  12.  
  13. // Longitude
  14. $longitude['degrees'] = getCoord( $exif['GPS']['GPSLongitude'][0] );
  15. $longitude['minutes'] = getCoord( $exif['GPS']['GPSLongitude'][1] );
  16. $longitude['seconds'] = getCoord( $exif['GPS']['GPSLongitude'][2] );
  17.  
  18. $longitude['minutes'] += 60 * ($longitude['degrees'] - floor($longitude['degrees']));
  19. $longitude['degrees'] = floor($longitude['degrees']);
  20.  
  21. $longitude['seconds'] += 60 * ($longitude['minutes'] - floor($longitude['minutes']));
  22. $longitude['minutes'] = floor($longitude['minutes']);

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
  1. <?php
  2.  
  3. // We obtain the coordinated of the line
  4. function getCoord( $expr ) {
  5. $expr_p = explode( '/', $expr );
  6. return $expr_p[0] / $expr_p[1];
  7. }
  8.  
  9. // If an image is not uploaded
  10. if( empty( $_FILES['image'] ) ) {
  11. // Redirect to the main with the error
  12. header( 'Location: /?error=1' );
  13. exit();
  14. }
  15.  
  16. // If an image type is not jpeg
  17. if( $_FILES['image']['type'] !== 'image/jpeg' ) {
  18. // Redirect to the main with the error
  19. header( 'Location: /?error=2' );
  20. exit();
  21. }
  22.  
  23. // We use a temporary file path
  24. $img = $_FILES['image']['tmp_name'];
  25.  
  26. // We get the data
  27. $exif = exif_read_data( $img, 0, true );
  28.  
  29. // If there is no GPS branch
  30. if( empty( $exif['GPS'] ) ) {
  31. // Redirect to the main with the error
  32. header( 'Location: /?error=3' );
  33. exit();
  34. }
  35.  
  36. // Latitude
  37. $latitude['degrees'] = getCoord( $exif['GPS']['GPSLatitude'][0] );
  38. $latitude['minutes'] = getCoord( $exif['GPS']['GPSLatitude'][1] );
  39. $latitude['seconds'] = getCoord( $exif['GPS']['GPSLatitude'][2] );
  40.  
  41. $latitude['minutes'] += 60 * ($latitude['degrees'] - floor($latitude['degrees']));
  42. $latitude['degrees'] = floor($latitude['degrees']);
  43.  
  44. $latitude['seconds'] += 60 * ($latitude['minutes'] - floor($latitude['minutes']));
  45. $latitude['minutes'] = floor($latitude['minutes']);
  46.  
  47. // Longitude
  48. $longitude['degrees'] = getCoord( $exif['GPS']['GPSLongitude'][0] );
  49. $longitude['minutes'] = getCoord( $exif['GPS']['GPSLongitude'][1] );
  50. $longitude['seconds'] = getCoord( $exif['GPS']['GPSLongitude'][2] );
  51.  
  52. $longitude['minutes'] += 60 * ($longitude['degrees'] - floor($longitude['degrees']));
  53. $longitude['degrees'] = floor($longitude['degrees']);
  54.  
  55. $longitude['seconds'] += 60 * ($longitude['minutes'] - floor($longitude['minutes']));
  56. $longitude['minutes'] = floor($longitude['minutes']);
  57.  
  58. ?>
  59.  
  60. <!DOCTYPE HTML>
  61. <html lang="en-US">
  62. <head>
  63. <m-eta charset="UTF-8">
  64. <t-itle>Getting photograph geo coordinates in PHP</title>
  65. </head>
  66. <body>
  67. <h1>Geo coordinates</h1>
  68. <p>
  69. Latitude:
  70. <?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?>
  71. <?=$latitude['degrees']?><sup>o</sup>
  72. <?=$latitude['minutes'] ?>'
  73. <?=$latitude['seconds'] ?>''
  74. </p>
  75.  
  76. <p>
  77. Longitude:
  78. <?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?>
  79. <?=$longitude['degrees']?><sup>o</sup>
  80. <?=$longitude['minutes'] ?>'
  81. <?=$longitude['seconds'] ?>''
  82. </p>
  83.  
  84. <p>
  85. <a href="https://maps.google.com/maps?q=<?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?>
  86. <?=$latitude['degrees']?>+<?=$latitude['minutes']?>'+
  87. <?=$latitude['seconds']?>'',+<?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?>
  88. <?=$longitude['degrees']?>+<?=$longitude['minutes']?>'+<?=$longitude['seconds']?>'
  89. '" target="_blank">Show on the map</a>
  90. </p>
  91. </body>
  92. </html>
Read 10831 times

Add comment


Security code
Refresh