@@ -50,6 +50,8 @@ class Exiftool implements MapperInterface
5050 const TITLE = 'Title ' ;
5151 const XRESOLUTION = 'XResolution ' ;
5252 const YRESOLUTION = 'YResolution ' ;
53+ const GPSLATITUDEREF = 'GPSLatitudeRef ' ;
54+ const GPSLONGITUDEREF = 'GPSLongitudeRef ' ;
5355
5456 /**
5557 * Maps the ExifTool fields to the fields of
@@ -84,8 +86,28 @@ class Exiftool implements MapperInterface
8486 self ::YRESOLUTION => Exif::VERTICAL_RESOLUTION ,
8587 self ::IMAGEWIDTH => Exif::WIDTH ,
8688 self ::CAPTIONABSTRACT => Exif::CAPTION ,
89+ self ::GPSLATITUDEREF => Exif::GPS ,
90+ self ::GPSLONGITUDEREF => Exif::GPS ,
8791 );
8892
93+ /**
94+ * @var bool
95+ */
96+ protected $ numeric = true ;
97+
98+ /**
99+ * Mutator method for the numeric property
100+ *
101+ * @param bool $numeric
102+ * @return \PHPExif\Mapper\Exiftool
103+ */
104+ public function setNumeric ($ numeric )
105+ {
106+ $ this ->numeric = (bool )$ numeric ;
107+
108+ return $ this ;
109+ }
110+
89111 /**
90112 * Maps the array of raw source data to the correct
91113 * fields for the \PHPExif\Exif class
@@ -96,6 +118,7 @@ class Exiftool implements MapperInterface
96118 public function mapRawData (array $ data )
97119 {
98120 $ mappedData = array ();
121+ $ gpsData = array ();
99122 foreach ($ data as $ field => $ value ) {
100123 if (!array_key_exists ($ field , $ this ->map )) {
101124 // silently ignore unknown fields
@@ -122,12 +145,55 @@ public function mapRawData(array $data)
122145 $ focalLengthParts = explode (' ' , $ value );
123146 $ value = (int ) reset ($ focalLengthParts );
124147 break ;
148+ case self ::GPSLATITUDEREF :
149+ $ gpsData ['lat ' ] = $ this ->extractGPSCoordinates ($ value );
150+ break ;
151+ case self ::GPSLONGITUDEREF :
152+ $ gpsData ['lon ' ] = $ this ->extractGPSCoordinates ($ value );
153+ break ;
125154 }
126155
127156 // set end result
128157 $ mappedData [$ key ] = $ value ;
129158 }
130159
160+ // add GPS coordinates, if available
161+ if (count ($ gpsData ) === 2 ) {
162+ $ latitude = $ gpsData ['lat ' ];
163+ $ longitude = $ gpsData ['lon ' ];
164+
165+ if ($ latitude !== false && $ longitude !== false ) {
166+ $ gpsLocation = sprintf (
167+ '%s,%s ' ,
168+ (strtoupper ($ data [self ::GPSLATITUDEREF ][0 ]) === 'S ' ? -1 : 1 ) * $ latitude ,
169+ (strtoupper ($ data [self ::GPSLONGITUDEREF ][0 ]) === 'W ' ? -1 : 1 ) * $ longitude
170+ );
171+
172+ $ key = $ this ->map [self ::GPSLATITUDEREF ];
173+
174+ $ mappedData [$ key ] = $ gpsLocation ;
175+ }
176+ }
177+
131178 return $ mappedData ;
132179 }
180+
181+ /**
182+ * Extract GPS coordinates from formatted string
183+ *
184+ * @param string $coordinates
185+ * @return array
186+ */
187+ protected function extractGPSCoordinates ($ coordinates )
188+ {
189+ if ($ this ->numeric === true ) {
190+ return abs ((float ) $ coordinates );
191+ } else {
192+ if (!preg_match ('!^([0-9.]+) deg ([0-9.]+) \' ([0-9.]+)"! ' , $ coordinates , $ matches )) {
193+ return false ;
194+ }
195+
196+ return intval ($ matches [1 ]) + (intval ($ matches [2 ]) / 60 ) + (floatval ($ matches [3 ]) / 3600 );
197+ }
198+ }
133199}
0 commit comments