Search code examples
javascriptjpegexif

Trying to use EXIF.js to return GPS coords when a jpg image is clicked


I'm trying to add javascript functionality that will return gps coordinates from exif data when the user clicks on a jpg displayed on the page. (Will use that to open a google map). I have managed to produce a working example when the script is inline in the html file, but not when trying to use a separate script file, getCoords.js

Found a similar question here: How to pass images from server to function in JavaScript?

What I'm trying to do is pass the src attribute from the html click event into the script. The script is getting the src, I can print that to the console and launch the jpg in devtools by clicking on the link in the console. But it doesn't seem to be even trying to run

EXIF.getData(my_image, function() {...

Here's the HTML:

<html lang="en">
    <head>
        <title>Map Test Home</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="styles.css" rel="stylesheet">
        <script src="getCoords.js"></script>
        <script
            src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.3.0/exif.min.js">
        </script>
        <script
            src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBMLVQ6kCIfX4c8vVHa0qOf8P87DxCvt2w">
        </script>
    </head>
    <body>
        <picture>
            <source media="(min-width: 750px)" srcset="images/van_from_erp2_L.jpg 2x, images/van_from_erp2_m.jpg 1x" />
            <source media="(min-width: 450px)" srcset="images/van_from_erp2_m.jpg" />
            <img src="images/van_from_erp2_s.jpg" id="hiking_0" alt="View of Vancouver from ridge" onclick='getCoords(src)'>
        </picture>

        <picture>
            <source media="(min-width: 750px)" srcset="images/creek_1_l.jpg 2x, images/creek_1_m.jpg 1x" />
            <source media="(min-width: 450px)" srcset="images/creek_1_m.jpg" />
            <img src="images/creek_1_s.jpg" id="hiking_1" alt="forest creek image" onclick='Hello(id)'>
        </picture>

        <!--div id="map"></div-->



    </body>
</html>

and here's the script:

function getCoords(source) {
    console.log(source);
            //pass image to EXIF.js to return EXIF data (EXIF.js sourced from github)

            let my_image = new Image();
            my_image.src = source;
            console.log("hello from line 7");
            EXIF.getData(my_image, function() {
                console.log("Hello from line 9");
                    myData = this;
                    console.log(myData.exifdata);

            // get latitude from exif data and calculate latitude decimal
            var latDegree = myData.exifdata.GPSLatitude[0].numerator;
            var latMinute = myData.exifdata.GPSLatitude[1].numerator;
            var latSecond = myData.exifdata.GPSLatitude[2].numerator;
            var latDirection = myData.exifdata.GPSLatitudeRef;

            var latFinal = ConvertDMSToDD(latDegree, latMinute, latSecond, latDirection);
            //console.log(latFinal);

            // get longitude from exif data and calculate longitude decimal
            var lonDegree = myData.exifdata.GPSLongitude[0].numerator;
            var lonMinute = myData.exifdata.GPSLongitude[1].numerator;
            var lonSecond = myData.exifdata.GPSLongitude[2].numerator;
            var lonDirection = myData.exifdata.GPSLongitudeRef;

            var lonFinal = ConvertDMSToDD(lonDegree, lonMinute, lonSecond, lonDirection);
            //console.log(lonFinal);

            let site = [latFinal, lonFinal];
            console.log(site);

            return(site);

            // Create Google Maps link for the location
            //document.getElementById('map-link').innerHTML = '<a href="http://www.google.com/maps/place/'+site[0]+','+site[1]+'" target="_blank">Google Maps</a>';

                });
            //};

            function ConvertDMSToDD(degrees, minutes, seconds, direction) {
                var dd = degrees + (minutes/60) + (seconds/360000);
                if (direction == "S" || direction == "W") {
                    dd = dd * -1;
                }
                return dd;
            }
}

Solution

  • Put EXIF.getData(my_image, function() {...} inside the image onload function:

    my_image.onload = function() {
      EXIF.getData(my_image, function() {...}
    }
    

    Note that you have to wait for the image to be completely loaded, before calling getData or any other function. It will silently fail otherwise. Docs