简体   繁体   English

如何从图像文件获取地理位置(坐标)?

[英]How to get geo location (coordinates) from image file?

I've searched everywhere for this but couldn't find the solution, so I decided to write my own class for this in PHP. 我到处都在搜索此内容,但是找不到解决方案,所以我决定用PHP编写自己的类。 Some what I succeed in it with iPhone image file and instagram image but I am not sure if it works with all other cameras especially with Android supported phones and cameras with GPS. 我在iPhone图像文件和instagram图像上取得了一些成功,但是我不确定它是否可以与所有其他相机一起使用,特别是与Android支持的手机和带GPS的相机一起使用。 Can anyone help me out with this? 谁能帮我这个忙吗? Below is my code and its implementation. 以下是我的代码及其实现。

    <?php

    class Filer {

        /**
         * Some Variables
         */

        private $_gpsLatitude;
        private $_gpsLongitude;
        private $_gpsLatitudeRef;
        private $_gpsLongitudeRef;

        /**
         * Constructor Method
         */
        public function __construct(){
            /**
             * GPS Meta (In reference to iphone's image file)
             * May be Android folow the same thing (Haven't checked)
             */
            $this->_gpsLatitude = 'GPSLatitude';
            $this->_gpsLongitude = 'GPSLongitude';
            $this->_GPSLongitudeRef = 'GPSLatitudeRef';
            $this->_gpsLongitudeRef = 'GPSLongitudeRef';
        }

        /**
         * Check if the file contains GPS information
         * @param: (string)$_file
         * @return: (array) File's EXIF data (If the file contains GPS information)
         */

        public function getCoordinate($_file){
            $_Metas = $this->checkGPS($_file);
            $_GPS = $_Metas['GPS'];
            $_latitude = $this->DMStoDEC(
                $_GPS[$this->_gpsLatitude][0], 
                $_GPS[$this->_gpsLatitude][1], 
                $_GPS[$this->_gpsLatitude][2], 
                $_GPS[$this->_GPSLongitudeRef]
            );
            $_longitude = $this->DMStoDEC(
                $_GPS[$this->_gpsLongitude][0], 
                $_GPS[$this->_gpsLongitude][1], 
                $_GPS[$this->_gpsLongitude][2], 
                $_GPS[$this->_gpsLongitudeRef]
            );

            $_location = array($_latitude, $_longitude);
            return $_location;
        }

        /**
         * Check if the file contains GPS information
         * @param: (string)$_file
         * @return: (array) File's EXIF data (If the file contains GPS information)
         */
        public function checkGPS($_file){
            return exif_read_data($_file, 'GPS', true);
        }

        /**
         * Get Meta information of file
         * @param: (string)$_file
         * @return: (array) File's EXIF data
         * 
         */
        public function getExif($_file){
            return exif_read_data($_file, 'IFD0', true);
        }

        /**
         * Converts DMS ( Degrees / Minutes / Seconds )
         * To decimal format longitude / latitude
         * @param: (string)$_deg, (string)$_min, (string)$_sec, (string)$_ref
         * @return: (float)
         */
        private function DMStoDEC($_deg, $_min, $_sec, $_ref){

            $_array = explode('/', $_deg);
            $_deg = $_array[0]/$_array[1];
            $_array = explode('/', $_min);
            $_min = $_array[0]/$_array[1];
            $_array = explode('/', $_sec);
            $_sec = $_array[0]/$_array[1];

            $_coordinate = $_deg+((($_min*60)+($_sec))/3600);
            /**
             *  + + = North/East
             *  + - = North/West
             *  - - = South/West
             *  - + = South/East        
            */
            if('s' === strtolower($_ref) || 'w' === strtolower($_ref)){
                // Negatify the coordinate
                $_coordinate = 0-$_coordinate;
            }

            return $_coordinate;
        }    

        /**
         * 
         * Converts decimal longitude / latitude to DMS
         * ( Degrees / minutes / seconds ) 
         *
         * This is the piece of code which may appear to 
         * be inefficient, but to avoid issues with floating
         * point math we extract the integer part and the float
         * part by using a string function.
         * @param: (string)$_file
         * @return: (array)
         */
        private function DECtoDMS($_dec){
            $_vars = explode(".", $_dec);
            $_deg = $vars[0];
            $_tempma = "0.".$_vars[1];

            $_tempma = $_tempma * 3600;
            $_min = floor($_tempma / 60);
            $_sec = $_tempma - ($_min*60);

            return array("deg"=>$_deg, "min"=>$_min, "sec"=>$_sec);
        }

    } // End class

    /**
     *
     * Usage Example
     * 
     */
    $_file = './image2.jpg';
    $_Filer = new Filer();
    if($_Filer->checkGPS($_file)){
        $_location = $_Filer->getCoordinate($_file);
        // File doesn't have GPS information
        echo '<h4>File\'s GPS information</h4>';
        var_dump($_location);
    } else {
        // File doesn't have GPS information
        echo '<h4>Sorry your file doesn\'t supply GPS information</h4>';
        var_dump($_Filer->getExif($_file));
    }
?>  

The Exiv2 documentation has an excellent tags reference which may help you identify fields you may have missed. Exiv2文档提供了出色的标签参考,可以帮助您确定可能错过的字段。 Your implementation otherwise looks pretty solid to me, I can't see any glaring errors. 否则,您的实现对我来说看起来很可靠,我看不到任何明显的错误。

Exif Tags supported by Exiv2 Exiv2支持的Exif标签

Your class is great, I've tested it today on android device and... simply work! 您的课程很棒,今天我已经在android设备上对其进行了测试,...工作正常! In my test, I've modified the result of the array like: [...] 在我的测试中,我修改了数组的结果,例如:[...]

array('latitude' => $_latitude, 'longitude' => $_longitude);
return $_location;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM