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

时间:2012-06-30 10:34:44

标签: php iphone gps location coordinates

我到处搜索但找不到解决方案,所以我决定用PHP编写自己的类。一些我用iPhone图像文件和instagram图像成功但我不确定它是否适用于所有其他相机,特别是Android支持的手机和带GPS的相机。任何人都可以帮我解决这个问题吗?以下是我的代码及其实现。

    <?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));
    }
?>  

2 个答案:

答案 0 :(得分:0)

Exiv2文档有一个很好的标签参考,可以帮助您识别可能遗漏的字段。你的实现对我来说看起来非常可靠,我看不出任何明显的错误。

Exif Tags supported by Exiv2

答案 1 :(得分:0)

你的课很棒,我今天在Android设备上测试了它......简单地工作! 在我的测试中,我修改了数组的结果,如:  [...]

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