Feature request: Add missing composite tags for fields containing GPS coordinate

Started by johnrellis, July 04, 2017, 05:24:09 PM

Previous topic - Next topic

johnrellis

It would be good if missing composite tags were added, so that you could use GPSLatitude and GPSLatitudeRef regardless of whether the particular group stores latitude in one field or two (ditto for longitude).

Motivation

I've been revising scripts that copy metadata between images with EXIF and XMP, XMP sidecars, and QuickTime videos.  Copying GPS information can be quite troublesome due to the missing composite tags. 

For example, there are no composite tags GPSLatitudeRef/GPSLongitudeRef for QuickTime, making it hard to copy GPS from QuickTime to EXIF.  The simple solution for XMP doesn't work:

   exiftool -tagsfromfile a.mov -GPSLatitude -GPSLatitudeRef a.jpg

The workaround is obscure:

   exiftool -tagsfromfile a.mov -GPSLatitude '-GPSLatitudeRef<${GPSLatitude;s/^.*(.)$/$1/g}' a.jpg

As another example, there is no composite tag GPSDestLatitude for EXIF GPSDestLatitute/GPSDestLatitudeRef. Copying those fields from EXIF to XMP is tricky.  This works:

   exiftool -tagsfromfile a.jpg '-GPSDestLatitude<$GPSDestLatitude${GPSDestLatitudeRef;s/^(.).*$/$1/}' a.xmp

But if you include the -m option (e.g. to handle other issues), it doesn't work when the source file a.jpg is missing GPSDestLatitude:

   exiftool -m -tagsfromfile a.jpg '-GPSDestLatitude<$GPSDestLatitude${GPSDestLatitudeRef;s/^(.).*$/$1/}' a.xmp

The destination field ends up with 0 deg 0' 0.00", since -m apparently causes the Perl expression to return the empty string, which then gets evaluated as 0.

Similarly, there is no composite tag GPSDestLatitudeRef for XMP.

The net result is that what could be a very simple script ends up pretty complicated, with separate commands for different file types. It may be simpler for me to add the missing composite tags that I need with my own .config, but that has its own complexity.

Missing Tags

Scanning the tag database, I think the following composite tags would provide complete orthogonality:

Add GPSLatitude and GPSLongitude for:

H.264, Nikon, Pentax.

Add GPSLatitudeRef and GPSLongitudeRef composite tags for:

FLIR, MIE, OpenEXR, PLIST, QuickTime

Add GPSDestLatitudeRef, GPSDestLongitudeRef, LocationCreatedGPSLatitudeRef, LocationCreatedGPSLongitudeRef, , LocationShownGPSLatitudeRef, LocationShownGPSLongitudeRef, RatingRegionGPSLatitudeRef, RatingRegionGPSLongitudeRef for:

XMP


StarGeek

Quote from: johnrellis on July 04, 2017, 05:24:09 PM
It would be good if missing composite tags were added, so that you could use GPSLatitude and GPSLatitudeRef regardless of whether the particular group stores latitude in one field or two (ditto for longitude).

Composite tags exist for GPSLatitude and GPSLongitude.  I think what you mean is that they should be writable as well.   This is actually something that I've thought about posting for a couple of weeks now, but just haven't gotten around to it.   It would avoid the common posts where people don't understand why their GPS coordinates are on the wrong side of the world.

While I don't use GPS Destination tags, I can see how composite tags would be useful.  Making them writable would be a nice bonus.

But there are some ways to simplify your work arounds.

QuoteFor example, there are no composite tags GPSLatitudeRef/GPSLongitudeRef for QuickTime, making it hard to copy GPS from QuickTime to EXIF.  The simple solution for XMP doesn't work:
...
The workaround is obscure:
   exiftool -tagsfromfile a.mov -GPSLatitude '-GPSLatitudeRef<${GPSLatitude;s/^.*(.)$/$1/g}' a.jpg

While I can't really comment on what tags are available in Quicktime, if it has GPSLatitude/Longitude then you don't have to do this, just copy GPSLatitude to GPSLatitudeRef.  Exiftool figures it out.  It will throw a printconv error if you a direct copy without changing the format with -c ("-GPSLatitudeRef<GPSLatitude") but it still copies the data.  The error can be avoided by adding the hashtag ("-GPSLatitudeRef<GPSLatitude#") to get the pre-printconv data.

Full output.  Copying from Test3 to Test4, which has no gps data.
C:\>exiftool -g1 -a -s  -GPSLatitude* -GPSLongitude* X:\!temp\Test4.jpg X:\!temp\Test3.jpg
======== X:/!temp/Test4.jpg
======== X:/!temp/Test3.jpg
---- GPS ----
GPSLatitudeRef                  : North
GPSLatitude                     : 33 deg 16' 22.69"
GPSLongitudeRef                 : West
GPSLongitude                    : 23 deg 57' 10.30"
---- Composite ----
GPSLatitude                     : 33 deg 16' 22.69" N
GPSLongitude                    : 23 deg 57' 10.30" W
    2 image files read

C:\>exiftool -P -overwrite_original -tagsfromfile X:\!temp\Test3.jpg -GPSLatitude "-GPSLatitudeRef<GPSLatitude" X:\!temp\Test4.jpg
Warning: Can't convert GPS:GPSLatitudeRef (not in PrintConv) - X:\!temp\Test3.jpg
    1 image files updated

C:\>exiftool -g1 -a -s  -GPSLatitude* -GPSLongitude* X:\!temp\Test4.jpg X:\!temp\Test3.jpg
======== X:/!temp/Test4.jpg
---- GPS ----
GPSLatitudeRef                  : North
GPSLatitude                     : 33 deg 16' 22.69"
---- Composite ----
GPSLatitude                     : 33 deg 16' 22.69" N
======== X:/!temp/Test3.jpg
---- GPS ----
GPSLatitudeRef                  : North
GPSLatitude                     : 33 deg 16' 22.69"
GPSLongitudeRef                 : West
GPSLongitude                    : 23 deg 57' 10.30"
---- Composite ----
GPSLatitude                     : 33 deg 16' 22.69" N
GPSLongitude                    : 23 deg 57' 10.30" W
    2 image files read


Second version with hashtag
C:\>exiftool -g1 -a -s  -GPSLatitude* -GPSLongitude* X:\!temp\Test4.jpg X:\!temp\Test3.jpg
======== X:/!temp/Test4.jpg
======== X:/!temp/Test3.jpg
---- GPS ----
GPSLatitudeRef                  : North
GPSLatitude                     : 33 deg 16' 22.69"
GPSLongitudeRef                 : West
GPSLongitude                    : 23 deg 57' 10.30"
---- Composite ----
GPSLatitude                     : 33 deg 16' 22.69" N
GPSLongitude                    : 23 deg 57' 10.30" W
    2 image files read

C:\>exiftool -P -overwrite_original -tagsfromfile X:\!temp\Test3.jpg -GPSLatitude "-GPSLatitudeRef<GPSLatitude#" X:\!temp\Test4.jpg
    1 image files updated

C:\>exiftool -g1 -a -s  -GPSLatitude* -GPSLongitude* X:\!temp\Test4.jpg X:\!temp\Test3.jpg
======== X:/!temp/Test4.jpg
---- GPS ----
GPSLatitudeRef                  : North
GPSLatitude                     : 33 deg 16' 22.69"
---- Composite ----
GPSLatitude                     : 33 deg 16' 22.69" N
======== X:/!temp/Test3.jpg
---- GPS ----
GPSLatitudeRef                  : North
GPSLatitude                     : 33 deg 16' 22.69"
GPSLongitudeRef                 : West
GPSLongitude                    : 23 deg 57' 10.30"
---- Composite ----
GPSLatitude                     : 33 deg 16' 22.69" N
GPSLongitude                    : 23 deg 57' 10.30" W
    2 image files read


QuoteAs another example, there is no composite tag GPSDestLatitude for EXIF GPSDestLatitute/GPSDestLatitudeRef. Copying those fields from EXIF to XMP is tricky.  This works:

   exiftool -tagsfromfile a.jpg '-GPSDestLatitude<$GPSDestLatitude${GPSDestLatitudeRef;s/^(.).*$/$1/}' a.xmp

Interesting, I would have thought that exiftool would have been able to figure this out without the regex.  But adding the hashtag ("-xmp:GPSDestLatitude<$GPSDestLatitude$GPSDestLatitudeRef#") will let it work without the regex.

QuoteSimilarly, there is no composite tag GPSDestLatitudeRef for XMP.

That's because in the case of XMP, the reference direction is supposed to be included in the base tag.  For example, 211 deg 7' 6.54" E is the result of one of my test files.  The specs that define these tags don't include separate Ref tags.  These tags aren't missing, they don't exists, unless you really feel the need to create them.  And even then, they wouldn't be compatible with existing software.

Another thing you might do is create some Shortcuts to make some of these things easier.  In my case, I have MyLat and MyLong shortcuts which write to the associated GPS and XMP tags and GPS reference tag.  (See end of post for definitions). 

Example (works better if using raw numbers so you don't have to escape the double quotes):
C:\>exiftool -g1 -a -s -MyLat -MyLong X:\!temp\Test4.jpg

C:\>exiftool -P -overwrite_original -MyLat="33 deg 16' 22.69\" N" -MyLong="23 deg 57' 10.30\" W" X:\!temp\Test4.jpg
    1 image files updated

C:\>exiftool -g1 -a -s -MyLat -MyLong X:\!temp\Test4.jpg
---- GPS ----
GPSLatitudeRef                  : North
GPSLatitude                     : 33 deg 16' 22.69"
GPSLongitudeRef                 : West
GPSLongitude                    : 23 deg 57' 10.30"
---- XMP-exif ----
GPSLatitude                     : 33 deg 16' 22.69" N
GPSLongitude                    : 23 deg 57' 10.30" W


As you can see, it writes to all GPSLatitude/Longitude and Refs without throwing errors.

Here are my shortcuts.  You can just paste them in the Shortcut section of .exiftool_config.  It shouldn't be hard to make up more to cover the GPSDest* tags.
MyLong => ['GPS:GPSLongitude', 'GPS:GPSLongitudeRef', 'XMP:GPSLongitude'],
MyLat => ['GPS:GPSLatitude','GPS:GPSLatitudeRef','XMP:GPSLatitude'],
MyAlt => ['GPS:GPSAltitude', 'GPS:GPSAltitudeRef', 'XMP:GPSAltitude', 'XMP:GPSAltitudeRef'],
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

johnrellis

QuoteComposite tags exist for GPSLatitude and GPSLongitude.  I think what you mean is that they should be writable as well.
I meant something much different. I propose making the composite tags orthogonal across all formats that provide GPS coordinates, so that, regardless of file format, the following invariant is maintained:

- GPSLatitude / GPSLongitude yield a value of the form 37 deg 23' 36.60" N
- GPSLatitudeRef / GPSLongitudeRef yield a value of the form N (or E, S, W)

With that invariant, it would be easy to copy GPS coordinates from any format to any other format, without worrying about whether the coordinates are represented in one field (e.g. QuickTime), two fields (e.g. XMP), or four fields (e.g. GPS/EXIF and Nikon).  The following command line suffices, regardless of the source and destination file formats:

exiftool -TagsFromFile sourcefile \
    -GPSLatitude -GPSLatitudeRef -GPSLongitude -GPSLongitudeRef \
    destinationfile


For example, this would copy from EXIF to XMP, XMP to EXIF, QuickTime to EXIF, or QuickTime to XMP. (Copying to QuickTime files works too, though the fields get added to the XMP section, since ExifTool treats QuickTime:GPSCoordinates as readonly.)

Currently, the necessary composite tags exist for some formats but not others. For example, GPSLatitudeRef exists for XMP:GPSLatitude, but not for XMP:GPSDestLatitude or QuickTime:GPSCoordinates.  As another example, GPSLatitude exists for GPS but not for Nikon.

These formats need composite tags for GPSLatitude / GPSLongitude: H.264, Nikon, Pentax.

These formats need composite tags for GPSLatitudeRef  / GPSLongitudeRef: FLIR, MIE, OpenEXR, PLIST, QuickTime.

GPS needs composite tags for GPSDestLatitude / GPSDestLongitude.

XMP needs composite tags for GPSDestLatitudeRef / GPSDestLongitudeRef.

I'm not sure how to handle XMP:LocationShownGPS, XMP:LocationCreatedGPS, and XMP:RatingRegionGPS, since they are "struct' values allowing multiple instances.  Even if they weren't handled, this proposal simplifies the much more common cases.

As a proof of concept, I've attached a file gps.config that defines the missing composite tags for GPS, QuickTime, and XMP. I've tested this copying between GPS, XMP, and QuickTime.  I could add the additional missing tags, but I don't have test files, and the edits should be made in the format-specific modules (e.g. H264.pm, XMP.pm, etc.).

johnrellis

Quotejust copy GPSLatitude to GPSLatitudeRef.  Exiftool figures it out.
Thanks, that simplifies some of my scripts.

This conversion doesn't appear documented anywhere that I could find -- it would be great to have it in the FAQ.

Phil Harvey

Quote from: johnrellis on July 06, 2017, 02:12:21 PM
This conversion doesn't appear documented anywhere that I could find -- it would be great to have it in the FAQ.

Good point.  I will add "or a string ending in E or W" to the tag name documentation for GPSLongitudeRef, and a similar addition for GPSLatitudeRef:

            ExifTool will also accept a number when writing this tag -- positive for
            east longitudes or negative for west, or a string ending in E or W


- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

johnrellis

That would be good, but I was referring to the conversion going the other way, e.g. GPSLatitudeRef<GPSLatitude, which is also undocumented?

Phil Harvey

Sorry.  I forgot the "Ref"'s in my last post.  I have fixed this now.

I am talking about writing GPSLatitudeRef/GPSLongitudeRef.

I will also add this to the FAQ.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).