exiftool_vendored 10.65.0 → 11.41.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of exiftool_vendored might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/Changes +818 -19
- data/bin/MANIFEST +38 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +48 -44
- data/bin/arg_files/exif2xmp.args +4 -1
- data/bin/arg_files/gps2xmp.args +4 -1
- data/bin/arg_files/iptcCore.args +8 -0
- data/bin/arg_files/xmp2exif.args +4 -1
- data/bin/arg_files/xmp2gps.args +4 -1
- data/bin/config_files/dji.config +131 -0
- data/bin/config_files/example.config +6 -2
- data/bin/config_files/gps2utm.config +256 -256
- data/bin/config_files/nksc.config +146 -0
- data/bin/config_files/picasa_faces.config +382 -382
- data/bin/exiftool +688 -408
- data/bin/fmt_files/gpx.fmt +10 -6
- data/bin/fmt_files/gpx_wpt.fmt +10 -6
- data/bin/fmt_files/kml.fmt +8 -5
- data/bin/lib/File/RandomAccess.pm +48 -8
- data/bin/lib/File/RandomAccess.pod +21 -2
- data/bin/lib/Image/ExifTool.pm +645 -256
- data/bin/lib/Image/ExifTool.pod +219 -164
- data/bin/lib/Image/ExifTool/AES.pm +1 -1
- data/bin/lib/Image/ExifTool/AFCP.pm +3 -8
- data/bin/lib/Image/ExifTool/AIFF.pm +12 -4
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/APP12.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +19 -6
- data/bin/lib/Image/ExifTool/Apple.pm +13 -5
- data/bin/lib/Image/ExifTool/Audible.pm +1 -1
- data/bin/lib/Image/ExifTool/BMP.pm +1 -1
- data/bin/lib/Image/ExifTool/BPG.pm +17 -15
- data/bin/lib/Image/ExifTool/BZZ.pm +1 -1
- data/bin/lib/Image/ExifTool/BigTIFF.pm +30 -15
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +103 -52
- data/bin/lib/Image/ExifTool/Canon.pm +684 -112
- data/bin/lib/Image/ExifTool/CanonCustom.pm +119 -9
- data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +13 -26
- data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
- data/bin/lib/Image/ExifTool/Casio.pm +1 -1
- data/bin/lib/Image/ExifTool/Charset.pm +1 -1
- data/bin/lib/Image/ExifTool/DICOM.pm +12 -5
- data/bin/lib/Image/ExifTool/DJI.pm +51 -3
- data/bin/lib/Image/ExifTool/DNG.pm +15 -8
- data/bin/lib/Image/ExifTool/DPX.pm +1 -1
- data/bin/lib/Image/ExifTool/DV.pm +1 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +63 -23
- data/bin/lib/Image/ExifTool/DjVu.pm +4 -2
- data/bin/lib/Image/ExifTool/EXE.pm +30 -6
- data/bin/lib/Image/ExifTool/Exif.pm +351 -109
- data/bin/lib/Image/ExifTool/FITS.pm +148 -0
- data/bin/lib/Image/ExifTool/FLAC.pm +2 -2
- data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
- data/bin/lib/Image/ExifTool/FLIR.pm +109 -13
- data/bin/lib/Image/ExifTool/Fixup.pm +1 -1
- data/bin/lib/Image/ExifTool/Flash.pm +3 -3
- data/bin/lib/Image/ExifTool/FlashPix.pm +433 -9
- data/bin/lib/Image/ExifTool/Font.pm +2 -2
- data/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
- data/bin/lib/Image/ExifTool/FujiFilm.pm +336 -16
- data/bin/lib/Image/ExifTool/GE.pm +1 -1
- data/bin/lib/Image/ExifTool/GIF.pm +5 -7
- data/bin/lib/Image/ExifTool/GIMP.pm +39 -3
- data/bin/lib/Image/ExifTool/GPS.pm +48 -22
- data/bin/lib/Image/ExifTool/GeoTiff.pm +23 -23
- data/bin/lib/Image/ExifTool/Geotag.pm +80 -45
- data/bin/lib/Image/ExifTool/GoPro.pm +709 -0
- data/bin/lib/Image/ExifTool/H264.pm +40 -18
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/HTML.pm +19 -12
- data/bin/lib/Image/ExifTool/HtmlDump.pm +37 -26
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +297 -23
- data/bin/lib/Image/ExifTool/ID3.pm +12 -7
- data/bin/lib/Image/ExifTool/IPTC.pm +48 -19
- data/bin/lib/Image/ExifTool/ISO.pm +1 -1
- data/bin/lib/Image/ExifTool/ITC.pm +1 -1
- data/bin/lib/Image/ExifTool/Import.pm +13 -9
- data/bin/lib/Image/ExifTool/InDesign.pm +3 -5
- data/bin/lib/Image/ExifTool/JPEG.pm +22 -11
- data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
- data/bin/lib/Image/ExifTool/JSON.pm +3 -3
- data/bin/lib/Image/ExifTool/JVC.pm +1 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -2
- data/bin/lib/Image/ExifTool/Kodak.pm +1233 -58
- data/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/LNK.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/de.pm +33 -24
- data/bin/lib/Image/ExifTool/Lang/en_ca.pm +64 -2
- data/bin/lib/Image/ExifTool/Lang/en_gb.pm +64 -2
- data/bin/lib/Image/ExifTool/Lang/es.pm +8 -4
- data/bin/lib/Image/ExifTool/Lang/fi.pm +46 -4
- data/bin/lib/Image/ExifTool/Lang/fr.pm +5 -3
- data/bin/lib/Image/ExifTool/Lang/it.pm +6 -3
- data/bin/lib/Image/ExifTool/Lang/ja.pm +15 -3
- data/bin/lib/Image/ExifTool/Lang/ko.pm +5 -2
- data/bin/lib/Image/ExifTool/Lang/nl.pm +6 -3
- data/bin/lib/Image/ExifTool/Lang/pl.pm +2 -2
- data/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/tr.pm +4 -2
- data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
- data/bin/lib/Image/ExifTool/Leaf.pm +1 -1
- data/bin/lib/Image/ExifTool/Lytro.pm +4 -8
- data/bin/lib/Image/ExifTool/M2TS.pm +10 -9
- data/bin/lib/Image/ExifTool/MIE.pm +12 -8
- data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
- data/bin/lib/Image/ExifTool/MIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/MNG.pm +1 -1
- data/bin/lib/Image/ExifTool/MOI.pm +1 -1
- data/bin/lib/Image/ExifTool/MPC.pm +1 -1
- data/bin/lib/Image/ExifTool/MPEG.pm +2 -3
- data/bin/lib/Image/ExifTool/MPF.pm +6 -6
- data/bin/lib/Image/ExifTool/MWG.pm +4 -4
- data/bin/lib/Image/ExifTool/MXF.pm +2 -2
- data/bin/lib/Image/ExifTool/MacOS.pm +184 -34
- data/bin/lib/Image/ExifTool/MakerNotes.pm +101 -18
- data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +5 -3
- data/bin/lib/Image/ExifTool/Minolta.pm +89 -62
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Motorola.pm +1 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +1511 -380
- data/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
- data/bin/lib/Image/ExifTool/NikonCustom.pm +2758 -2935
- data/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
- data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
- data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +47 -8
- data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
- data/bin/lib/Image/ExifTool/Opus.pm +1 -1
- data/bin/lib/Image/ExifTool/PCX.pm +138 -0
- data/bin/lib/Image/ExifTool/PDF.pm +58 -42
- data/bin/lib/Image/ExifTool/PGF.pm +1 -1
- data/bin/lib/Image/ExifTool/PICT.pm +1 -1
- data/bin/lib/Image/ExifTool/PLIST.pm +12 -5
- data/bin/lib/Image/ExifTool/PLUS.pm +1 -1
- data/bin/lib/Image/ExifTool/PNG.pm +108 -10
- data/bin/lib/Image/ExifTool/PPM.pm +3 -3
- data/bin/lib/Image/ExifTool/PSP.pm +1 -1
- data/bin/lib/Image/ExifTool/Palm.pm +1 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +299 -31
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +201 -19
- data/bin/lib/Image/ExifTool/Pentax.pm +164 -143
- data/bin/lib/Image/ExifTool/PhaseOne.pm +12 -5
- data/bin/lib/Image/ExifTool/PhotoCD.pm +9 -10
- data/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
- data/bin/lib/Image/ExifTool/Photoshop.pm +230 -60
- data/bin/lib/Image/ExifTool/PostScript.pm +29 -4
- data/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
- data/bin/lib/Image/ExifTool/Qualcomm.pm +2 -2
- data/bin/lib/Image/ExifTool/QuickTime.pm +1539 -279
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1857 -0
- data/bin/lib/Image/ExifTool/README +84 -46
- data/bin/lib/Image/ExifTool/RIFF.pm +116 -23
- data/bin/lib/Image/ExifTool/RSRC.pm +1 -1
- data/bin/lib/Image/ExifTool/RTF.pm +6 -4
- data/bin/lib/Image/ExifTool/Radiance.pm +1 -1
- data/bin/lib/Image/ExifTool/Rawzor.pm +3 -2
- data/bin/lib/Image/ExifTool/Real.pm +1 -1
- data/bin/lib/Image/ExifTool/Reconyx.pm +261 -7
- data/bin/lib/Image/ExifTool/Red.pm +325 -0
- data/bin/lib/Image/ExifTool/Ricoh.pm +3 -7
- data/bin/lib/Image/ExifTool/Samsung.pm +95 -25
- data/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
- data/bin/lib/Image/ExifTool/Scalado.pm +1 -1
- data/bin/lib/Image/ExifTool/Shift.pl +26 -12
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -2
- data/bin/lib/Image/ExifTool/Sigma.pm +36 -30
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +3 -8
- data/bin/lib/Image/ExifTool/Sony.pm +531 -177
- data/bin/lib/Image/ExifTool/SonyIDC.pm +63 -3
- data/bin/lib/Image/ExifTool/Stim.pm +2 -2
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +23 -23
- data/bin/lib/Image/ExifTool/TagLookup.pm +6352 -5062
- data/bin/lib/Image/ExifTool/TagNames.pod +3024 -565
- data/bin/lib/Image/ExifTool/Theora.pm +1 -1
- data/bin/lib/Image/ExifTool/Torrent.pm +2 -2
- data/bin/lib/Image/ExifTool/Unknown.pm +1 -1
- data/bin/lib/Image/ExifTool/VCard.pm +47 -9
- data/bin/lib/Image/ExifTool/Validate.pm +391 -99
- data/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
- data/bin/lib/Image/ExifTool/WTV.pm +319 -0
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +91 -18
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +6 -6
- data/bin/lib/Image/ExifTool/WritePDF.pl +13 -12
- data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePostScript.pl +2 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +764 -121
- data/bin/lib/Image/ExifTool/WriteXMP.pl +176 -67
- data/bin/lib/Image/ExifTool/Writer.pl +490 -246
- data/bin/lib/Image/ExifTool/XMP.pm +216 -76
- data/bin/lib/Image/ExifTool/XMP2.pl +54 -10
- data/bin/lib/Image/ExifTool/XMPStruct.pl +14 -11
- data/bin/lib/Image/ExifTool/ZIP.pm +60 -15
- data/bin/lib/Image/ExifTool/iWork.pm +12 -5
- data/bin/perl-Image-ExifTool.spec +46 -44
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +14 -4
data/bin/arg_files/xmp2gps.args
CHANGED
@@ -5,9 +5,10 @@
|
|
5
5
|
#
|
6
6
|
# Usage: exiftool -tagsFromFile SRCFILE -@ xmp2gps.args DSTFILE
|
7
7
|
#
|
8
|
-
# Requires: ExifTool version
|
8
|
+
# Requires: ExifTool version 10.96 or later
|
9
9
|
#
|
10
10
|
# Revisions: 2009/01/09 - P. Harvey Created
|
11
|
+
# 2018/05/07 - PH Handle GPSDestLatitude/LongitudeRef tags
|
11
12
|
#
|
12
13
|
# Notes: 1) Most of the GPS tags are copied by the first argument, but
|
13
14
|
# the coordinate references and date/time values are stored
|
@@ -23,6 +24,8 @@
|
|
23
24
|
-GPS:all < XMP-exif:all
|
24
25
|
-GPS:GPSLatitudeRef < Composite:GPSLatitudeRef
|
25
26
|
-GPS:GPSLongitudeRef < Composite:GPSLongitudeRef
|
27
|
+
-GPS:GPSDestLatitudeRef < Composite:GPSDestLatitudeRef
|
28
|
+
-GPS:GPSDestLongitudeRef < Composite:GPSDestLongitudeRef
|
26
29
|
-GPS:GPSDateStamp < XMP-exif:GPSDateTime
|
27
30
|
-GPS:GPSTimeStamp < XMP-exif:GPSDateTime
|
28
31
|
# end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
# File: dji.config
|
3
|
+
#
|
4
|
+
# Description: This config file defines Composite tags to convert embedded
|
5
|
+
# metadata in videos from DJI drones
|
6
|
+
#
|
7
|
+
# Usage: exiftool -config dji.config -ee FILE
|
8
|
+
#
|
9
|
+
# Example command to create .gpx log file from DJI video
|
10
|
+
# (requires gpx.fmt available in the full Exiftool distribution):
|
11
|
+
#
|
12
|
+
# exiftool -config dji.config -p gpx.fmt -ee -api QuickTimeUTC FILE
|
13
|
+
#
|
14
|
+
# Requires: ExifTool version 10.75 or later
|
15
|
+
#
|
16
|
+
# Revisions: 2018/03/23 - P. Harvey Created
|
17
|
+
#------------------------------------------------------------------------------
|
18
|
+
|
19
|
+
%Image::ExifTool::UserDefined = (
|
20
|
+
'Image::ExifTool::Composite' => {
|
21
|
+
GROUPS => { 2 => 'Location' },
|
22
|
+
#
|
23
|
+
# Example embedded "Text" from a DJI FC6310:
|
24
|
+
#
|
25
|
+
# "F/3.5, SS 1000, ISO 100, EV 0, GPS (8.6499, 53.1665, 18), D 24.26m,
|
26
|
+
# H 6.00m, H.S 2.10m/s, V.S 0.00m/s \n"
|
27
|
+
#
|
28
|
+
# F/ = F Number
|
29
|
+
# SS = shutter speed
|
30
|
+
# ISO = ISO
|
31
|
+
# GPS = (longitude, latitude, ???)
|
32
|
+
# D = horizontal distance from home point
|
33
|
+
# H = vertical distance from home point
|
34
|
+
# H.S = horizontal speed
|
35
|
+
# V.S = vertical speed
|
36
|
+
#
|
37
|
+
# Note: SubDoc flag is set for all these tags so they will be generated for
|
38
|
+
# all embedded documents
|
39
|
+
#
|
40
|
+
GPSDateTime => {
|
41
|
+
Description => 'GPS Date/Time',
|
42
|
+
Groups => { 2 => 'Time' },
|
43
|
+
SubDoc => 1,
|
44
|
+
Require => {
|
45
|
+
0 => 'Text',
|
46
|
+
1 => 'SampleTime',
|
47
|
+
2 => 'Main:CreateDate',
|
48
|
+
3 => 'Main:Duration',
|
49
|
+
},
|
50
|
+
# (assuming CreateDate is the end time of the video, we subtract
|
51
|
+
# Duration because a SampleTime of zero is at the start of the video)
|
52
|
+
ValueConv => q{
|
53
|
+
my $diff = $val[1] - $val[3];
|
54
|
+
my $sign = $diff =~ s/^-// ? '-' : '';
|
55
|
+
my $time = $val[2] . '.000';
|
56
|
+
ShiftTime($time, "${sign}0:0:$diff");
|
57
|
+
return $time;
|
58
|
+
},
|
59
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
60
|
+
},
|
61
|
+
GPSLatitude => {
|
62
|
+
SubDoc => 1,
|
63
|
+
Require => { 0 => 'Text' },
|
64
|
+
RawConv => '$val[0] =~ /GPS \(\S+,\s*([-+]?\d*\.\d+)/ ? $1 : undef',
|
65
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
|
66
|
+
},
|
67
|
+
GPSLongitude => {
|
68
|
+
SubDoc => 1,
|
69
|
+
Require => { 0 => 'Text' },
|
70
|
+
RawConv => '$val[0] =~ /GPS \(([-+]?\d*\.\d+),/ ? $1 : undef',
|
71
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
|
72
|
+
},
|
73
|
+
GPSAltitude => {
|
74
|
+
SubDoc => 1,
|
75
|
+
Require => { 0 => 'Text' },
|
76
|
+
RawConv => '$val[0] =~ /,\s*H\s+([-+]?\d+\.?\d*)m/ ? $1 : undef',
|
77
|
+
},
|
78
|
+
GPSSpeed => {
|
79
|
+
SubDoc => 1,
|
80
|
+
Require => { 0 => 'Text' },
|
81
|
+
RawConv => '$val[0] =~ /,\s*H.S\s+([-+]?\d+\.?\d*)/ ? $1 * 3.6 : undef',
|
82
|
+
},
|
83
|
+
GPSSpeedRef => {
|
84
|
+
SubDoc => 1,
|
85
|
+
Require => { 0 => 'Text' },
|
86
|
+
RawConv => '$val[0] =~ /,\s*H.S\s+([-+]?\d+\.?\d*)m\/s/ ? "K" : undef',
|
87
|
+
PrintConv => { K => 'km/h', M => 'mph', N => 'knots' },
|
88
|
+
},
|
89
|
+
Distance => {
|
90
|
+
SubDoc => 1,
|
91
|
+
Require => { 0 => 'Text' },
|
92
|
+
RawConv => '$val[0] =~ /,\s*D\s+(\d+\.?\d*)m/ ? $1 * 3.6 : undef',
|
93
|
+
PrintConv => '"$val m"',
|
94
|
+
},
|
95
|
+
VerticalSpeed => {
|
96
|
+
SubDoc => 1,
|
97
|
+
Require => { 0 => 'Text' },
|
98
|
+
RawConv => '$val[0] =~ /,\s*V.S\s+([-+]?\d+\.?\d*)/ ? $1 : undef',
|
99
|
+
PrintConv => '"$val m/s"',
|
100
|
+
},
|
101
|
+
FNumber => {
|
102
|
+
Groups => { 2 => 'Camera' },
|
103
|
+
SubDoc => 1,
|
104
|
+
Require => { 0 => 'Text' },
|
105
|
+
RawConv => '$val[0] =~ /\bF\/(\d+\.?\d*)/ ? $1 : undef',
|
106
|
+
PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
|
107
|
+
},
|
108
|
+
ExposureTime => {
|
109
|
+
Groups => { 2 => 'Camera' },
|
110
|
+
SubDoc => 1,
|
111
|
+
Require => { 0 => 'Text' },
|
112
|
+
RawConv => '$val[0] =~ /\bSS\s+(\d+\.?\d*)/ ? 1/$1 : undef',
|
113
|
+
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
114
|
+
},
|
115
|
+
ExposureCompensation => {
|
116
|
+
Groups => { 2 => 'Camera' },
|
117
|
+
SubDoc => 1,
|
118
|
+
Require => { 0 => 'Text' },
|
119
|
+
RawConv => '$val[0] =~ /\bEV\s+([-+]?\d+\.?\d*)(\/\d+)?/ ? ($1 / ($2 || 1)) : undef',
|
120
|
+
PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
|
121
|
+
},
|
122
|
+
ISO => {
|
123
|
+
Groups => { 2 => 'Camera' },
|
124
|
+
SubDoc => 1,
|
125
|
+
Require => { 0 => 'Text' },
|
126
|
+
RawConv => '$val[0] =~ /\bISO\s+(\d+\.?\d*)/ ? $1 : undef',
|
127
|
+
},
|
128
|
+
},
|
129
|
+
);
|
130
|
+
|
131
|
+
1; #end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#------------------------------------------------------------------------------
|
2
|
-
# File:
|
2
|
+
# File: example.config --> ~/.ExifTool_config
|
3
3
|
#
|
4
4
|
# Description: Sample user configuration file for Image::ExifTool
|
5
5
|
#
|
@@ -261,6 +261,10 @@
|
|
261
261
|
Struct => {
|
262
262
|
# optional namespace prefix and URI for structure fields
|
263
263
|
# (required only if different than NAMESPACE above)
|
264
|
+
# --> multiple entries may exist in this namespace lookup,
|
265
|
+
# with the last one alphabetically being the default for
|
266
|
+
# the fields, but each field may have a "Namespace"
|
267
|
+
# element to specify which prefix to use
|
264
268
|
NAMESPACE => { 'test' => 'http://x.y.z/test/' },
|
265
269
|
# optional structure name (used for warning messages only)
|
266
270
|
STRUCT_NAME => 'MyStruct',
|
@@ -346,7 +350,7 @@ use Image::ExifTool::MIE;
|
|
346
350
|
CoordFormat => '%.6f', # change default GPS coordinate format
|
347
351
|
Duplicates => 1, # make -a default for the exiftool app
|
348
352
|
GeoMaxHDOP => 4, # ignore GPS fixes with HDOP > 4
|
349
|
-
|
353
|
+
RequestAll => 3, # request additional tags not normally generated
|
350
354
|
);
|
351
355
|
|
352
356
|
#------------------------------------------------------------------------------
|
@@ -1,256 +1,256 @@
|
|
1
|
-
#------------------------------------------------------------------------------
|
2
|
-
# File: gps2utm.config
|
3
|
-
#
|
4
|
-
# Description: Generate UTM tags from GPS information
|
5
|
-
#
|
6
|
-
# Requires: ExifTool version 7.00 or later
|
7
|
-
#
|
8
|
-
# Notes: Uses GPSMapDatum, GPSLatitude and GPSLongitude to generate
|
9
|
-
# UTMCoordinates, UTMZone, UTMEasting and UTMNorthing. If
|
10
|
-
# GPSMapDatum is not available then "WGS84" is assumed.
|
11
|
-
#
|
12
|
-
# Example: > exiftool -config gps2utm.config "-utm*" t/images/GPS.jpg
|
13
|
-
# UTM Coordinates : 30U 569475.596m E 6094180.754m N
|
14
|
-
# UTM Easting : 569475.595558165
|
15
|
-
# UTM Northing : 6094180.75443061
|
16
|
-
# UTM Zone : 30U
|
17
|
-
#
|
18
|
-
# Caveats: When used to convert EXIF GPS coordinates, the reference
|
19
|
-
# direction tags (GPSLatitudeRef/GPSLongitudeRef) must exist or
|
20
|
-
# the calculated UTM coordinates may be in the wrong hemisphere
|
21
|
-
#
|
22
|
-
# Revisions: 2016/03/08 - Bryan K. Williams (aka StarGeek) Created
|
23
|
-
# 2016/03/09 - PH removed library dependency and re-organized
|
24
|
-
#------------------------------------------------------------------------------
|
25
|
-
|
26
|
-
my $deg2rad = 3.14159265358979 / 180;
|
27
|
-
|
28
|
-
sub tan($)
|
29
|
-
{
|
30
|
-
return sin($_[0]) / cos($_[0]);
|
31
|
-
}
|
32
|
-
|
33
|
-
#===============================================================================
|
34
|
-
# the following code is by Graham Crookham:
|
35
|
-
# http://search.cpan.org/~grahamc/Geo-Coordinates-UTM/ (version 0.11)
|
36
|
-
|
37
|
-
# remove all markup from an ellipsoid name, to increase the chance
|
38
|
-
# that a match is found.
|
39
|
-
sub _cleanup_name($)
|
40
|
-
{ my $copy = lc(shift);
|
41
|
-
for($copy)
|
42
|
-
{ s/\([^)]+\)//g; # remove text between parantheses
|
43
|
-
s/[\s-]//g; # no blanks or dashes
|
44
|
-
}
|
45
|
-
$copy;
|
46
|
-
}
|
47
|
-
|
48
|
-
# Ellipsoid array (name,equatorial radius,square of eccentricity)
|
49
|
-
# Same data also as hash with key eq name (in variations)
|
50
|
-
|
51
|
-
my (@Ellipsoid, %Ellipsoid);
|
52
|
-
|
53
|
-
BEGIN { # Initialize this before other modules get a chance
|
54
|
-
@Ellipsoid =
|
55
|
-
( [ "Airy", 6377563, 0.00667054]
|
56
|
-
, [ "Australian National", 6378160, 0.006694542]
|
57
|
-
, [ "Bessel 1841", 6377397, 0.006674372]
|
58
|
-
, [ "Bessel 1841 Nambia", 6377484, 0.006674372]
|
59
|
-
, [ "Clarke 1866", 6378206, 0.006768658]
|
60
|
-
, [ "Clarke 1880", 6378249, 0.006803511]
|
61
|
-
, [ "Everest 1830 India", 6377276, 0.006637847]
|
62
|
-
, [ "Fischer 1960 Mercury", 6378166, 0.006693422]
|
63
|
-
, [ "Fischer 1968", 6378150, 0.006693422]
|
64
|
-
, [ "GRS 1967", 6378160, 0.006694605]
|
65
|
-
, [ "GRS 1980", 6378137, 0.00669438]
|
66
|
-
, [ "Helmert 1906", 6378200, 0.006693422]
|
67
|
-
, [ "Hough", 6378270, 0.00672267]
|
68
|
-
, [ "International", 6378388, 0.00672267]
|
69
|
-
, [ "Krassovsky", 6378245, 0.006693422]
|
70
|
-
, [ "Modified Airy", 6377340, 0.00667054]
|
71
|
-
, [ "Modified Everest", 6377304, 0.006637847]
|
72
|
-
, [ "Modified Fischer 1960", 6378155, 0.006693422]
|
73
|
-
, [ "South American 1969", 6378160, 0.006694542]
|
74
|
-
, [ "WGS 60", 6378165, 0.006693422]
|
75
|
-
, [ "WGS 66", 6378145, 0.006694542]
|
76
|
-
, [ "WGS-72", 6378135, 0.006694318]
|
77
|
-
, [ "WGS-84", 6378137, 0.00669438 ]
|
78
|
-
, [ "Everest 1830 Malaysia", 6377299, 0.006637847]
|
79
|
-
, [ "Everest 1956 India", 6377301, 0.006637847]
|
80
|
-
, [ "Everest 1964 Malaysia and Singapore", 6377304, 0.006637847]
|
81
|
-
, [ "Everest 1969 Malaysia", 6377296, 0.006637847]
|
82
|
-
, [ "Everest Pakistan", 6377296, 0.006637534]
|
83
|
-
, [ "Indonesian 1974", 6378160, 0.006694609]
|
84
|
-
, [ "Arc 1950", 6378249.145,0.006803481]
|
85
|
-
, [ "NAD 27",6378206.4,0.006768658]
|
86
|
-
, [ "NAD 83",6378137,0.006694384]
|
87
|
-
);
|
88
|
-
|
89
|
-
# calc ecc as
|
90
|
-
# a = semi major axis
|
91
|
-
# b = semi minor axis
|
92
|
-
# e^2 = (a^2-b^2)/a^2
|
93
|
-
# For clarke 1880 (Arc1950) a=6378249.145 b=6356514.966398753
|
94
|
-
# e^2 (40682062155693.23 - 40405282518051.34) / 40682062155693.23
|
95
|
-
# e^2 = 0.0068034810178165
|
96
|
-
|
97
|
-
foreach my $el (@Ellipsoid)
|
98
|
-
{ my ($name, $eqrad, $eccsq) = @$el;
|
99
|
-
$Ellipsoid{$name} = $el;
|
100
|
-
$Ellipsoid{_cleanup_name $name} = $el;
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
# Returns "official" name, equator radius and square eccentricity
|
105
|
-
# The specified name can be numeric (for compatibility reasons) or
|
106
|
-
# a more-or-less exact name
|
107
|
-
# Examples: my($name, $r, $sqecc) = ellipsoid_info 'wgs84';
|
108
|
-
# my($name, $r, $sqecc) = ellipsoid_info 'WGS 84';
|
109
|
-
# my($name, $r, $sqecc) = ellipsoid_info 'WGS-84';
|
110
|
-
# my($name, $r, $sqecc) = ellipsoid_info 'WGS-84 (new specs)';
|
111
|
-
# my($name, $r, $sqecc) = ellipsoid_info 22;
|
112
|
-
|
113
|
-
sub ellipsoid_info($)
|
114
|
-
{ my $id = shift;
|
115
|
-
|
116
|
-
my $el = $id !~ m/\D/
|
117
|
-
? $Ellipsoid[$id-1] # old system counted from 1
|
118
|
-
: $Ellipsoid{$id} || $Ellipsoid{_cleanup_name $id};
|
119
|
-
|
120
|
-
defined $el ? @$el : ();
|
121
|
-
}
|
122
|
-
|
123
|
-
# Expects Ellipsoid Number or name, Latitude, Longitude
|
124
|
-
# (Latitude and Longitude in decimal degrees)
|
125
|
-
# Returns UTM Zone, UTM Easting, UTM Northing
|
126
|
-
|
127
|
-
sub latlon_to_utm(@)
|
128
|
-
{ my ($ellips, $latitude, $longitude) = @_;
|
129
|
-
|
130
|
-
die("Longitude value ($longitude) invalid\n")
|
131
|
-
if $longitude < -180 || $longitude > 180;
|
132
|
-
|
133
|
-
my $long2 = $longitude - int(($longitude + 180)/360) * 360;
|
134
|
-
my $zone = _latlon_zone_number($latitude, $long2);
|
135
|
-
|
136
|
-
_latlon_to_utm($ellips || 'WGS84', $zone, $latitude, $long2);
|
137
|
-
}
|
138
|
-
|
139
|
-
sub _latlon_zone_number
|
140
|
-
{ my ($latitude, $long2) = @_;
|
141
|
-
|
142
|
-
my $zone = int( ($long2 + 180)/6) + 1;
|
143
|
-
if($latitude >= 56.0 && $latitude < 64.0 && $long2 >= 3.0 && $long2 < 12.0)
|
144
|
-
{ $zone = 32;
|
145
|
-
}
|
146
|
-
if($latitude >= 72.0 && $latitude < 84.0) {
|
147
|
-
$zone = ($long2 >= 0.0 && $long2 < 9.0) ? 31
|
148
|
-
: ($long2 >= 9.0 && $long2 < 21.0) ? 33
|
149
|
-
: ($long2 >= 21.0 && $long2 < 33.0) ? 35
|
150
|
-
: ($long2 >= 33.0 && $long2 < 42.0) ? 37
|
151
|
-
: $zone;
|
152
|
-
}
|
153
|
-
return $zone;
|
154
|
-
}
|
155
|
-
|
156
|
-
sub _latlon_to_utm
|
157
|
-
{ my ($ellips, $zone, $latitude, $long2) = @_;
|
158
|
-
|
159
|
-
my ($name, $radius, $eccentricity) = ellipsoid_info $ellips
|
160
|
-
or die("Ellipsoid value ($ellips) invalid\n");
|
161
|
-
|
162
|
-
my $lat_radian = $deg2rad * $latitude;
|
163
|
-
my $long_radian = $deg2rad * $long2;
|
164
|
-
|
165
|
-
my $k0 = 0.9996; # scale
|
166
|
-
|
167
|
-
my $longorigin = ($zone - 1)*6 - 180 + 3;
|
168
|
-
my $longoriginradian = $deg2rad * $longorigin;
|
169
|
-
my $eccentprime = $eccentricity/(1-$eccentricity);
|
170
|
-
|
171
|
-
my $N = $radius / sqrt(1-$eccentricity * sin($lat_radian)*sin($lat_radian));
|
172
|
-
my $T = tan($lat_radian) * tan($lat_radian);
|
173
|
-
my $C = $eccentprime * cos($lat_radian)*cos($lat_radian);
|
174
|
-
my $A = cos($lat_radian) * ($long_radian - $longoriginradian);
|
175
|
-
my $M = $radius
|
176
|
-
* ( ( 1 - $eccentricity/4 - 3 * $eccentricity * $eccentricity/64
|
177
|
-
- 5 * $eccentricity * $eccentricity * $eccentricity/256
|
178
|
-
) * $lat_radian
|
179
|
-
- ( 3 * $eccentricity/8 + 3 * $eccentricity * $eccentricity/32
|
180
|
-
+ 45 * $eccentricity * $eccentricity * $eccentricity/1024
|
181
|
-
) * sin(2 * $lat_radian)
|
182
|
-
+ ( 15 * $eccentricity * $eccentricity/256 +
|
183
|
-
45 * $eccentricity * $eccentricity * $eccentricity/1024
|
184
|
-
) * sin(4 * $lat_radian)
|
185
|
-
- ( 35 * $eccentricity * $eccentricity * $eccentricity/3072
|
186
|
-
) * sin(6 * $lat_radian)
|
187
|
-
);
|
188
|
-
|
189
|
-
my $utm_easting = $k0*$N*($A+(1-$T+$C)*$A*$A*$A/6
|
190
|
-
+ (5-18*$T+$T*$T+72*$C-58*$eccentprime)*$A*$A*$A*$A*$A/120)
|
191
|
-
+ 500000.0;
|
192
|
-
|
193
|
-
my $utm_northing= $k0 * ( $M + $N*tan($lat_radian) * ( $A*$A/2+(5-$T+9*$C+4*$C*$C)*$A*$A*$A*$A/24 + (61-58*$T+$T*$T+600*$C-330*$eccentprime) * $A*$A*$A*$A*$A*$A/720));
|
194
|
-
|
195
|
-
$utm_northing += 10000000.0 if $latitude < 0;
|
196
|
-
|
197
|
-
my $utm_letter
|
198
|
-
= ( 84 >= $latitude && $latitude >= 72) ? 'X'
|
199
|
-
: ( 72 > $latitude && $latitude >= 64) ? 'W'
|
200
|
-
: ( 64 > $latitude && $latitude >= 56) ? 'V'
|
201
|
-
: ( 56 > $latitude && $latitude >= 48) ? 'U'
|
202
|
-
: ( 48 > $latitude && $latitude >= 40) ? 'T'
|
203
|
-
: ( 40 > $latitude && $latitude >= 32) ? 'S'
|
204
|
-
: ( 32 > $latitude && $latitude >= 24) ? 'R'
|
205
|
-
: ( 24 > $latitude && $latitude >= 16) ? 'Q'
|
206
|
-
: ( 16 > $latitude && $latitude >= 8) ? 'P'
|
207
|
-
: ( 8 > $latitude && $latitude >= 0) ? 'N'
|
208
|
-
: ( 0 > $latitude && $latitude >= -8) ? 'M'
|
209
|
-
: ( -8 > $latitude && $latitude >= -16) ? 'L'
|
210
|
-
: (-16 > $latitude && $latitude >= -24) ? 'K'
|
211
|
-
: (-24 > $latitude && $latitude >= -32) ? 'J'
|
212
|
-
: (-32 > $latitude && $latitude >= -40) ? 'H'
|
213
|
-
: (-40 > $latitude && $latitude >= -48) ? 'G'
|
214
|
-
: (-48 > $latitude && $latitude >= -56) ? 'F'
|
215
|
-
: (-56 > $latitude && $latitude >= -64) ? 'E'
|
216
|
-
: (-64 > $latitude && $latitude >= -72) ? 'D'
|
217
|
-
: (-72 > $latitude && $latitude >= -80) ? 'C'
|
218
|
-
: die("Latitude ($latitude) out of UTM range\n");
|
219
|
-
|
220
|
-
$zone .= $utm_letter;
|
221
|
-
|
222
|
-
($zone, $utm_easting, $utm_northing);
|
223
|
-
}
|
224
|
-
# End Graham Crookham code
|
225
|
-
#===============================================================================
|
226
|
-
|
227
|
-
%Image::ExifTool::UserDefined = (
|
228
|
-
'Image::ExifTool::Composite' => {
|
229
|
-
UTMCoordinates => {
|
230
|
-
Desire => {
|
231
|
-
0 => 'GPSMapDatum',
|
232
|
-
},
|
233
|
-
Require => {
|
234
|
-
1 => 'GPSLatitude',
|
235
|
-
2 => 'GPSLongitude',
|
236
|
-
},
|
237
|
-
ValueConv => 'join " ", latlon_to_utm(@val)',
|
238
|
-
PrintConv => 'sprintf("%s %.3fm E %.3fm N", split(" ", $val))',
|
239
|
-
},
|
240
|
-
UTMZone => {
|
241
|
-
Require => 'UTMCoordinates',
|
242
|
-
ValueConv => 'my @a=split(" ",$val); $a[0]',
|
243
|
-
},
|
244
|
-
UTMEasting => {
|
245
|
-
Require => 'UTMCoordinates',
|
246
|
-
ValueConv => 'my @a=split(" ",$val); $a[1]',
|
247
|
-
},
|
248
|
-
UTMNorthing => {
|
249
|
-
Require => 'UTMCoordinates',
|
250
|
-
ValueConv => 'my @a=split(" ",$val); $a[2]',
|
251
|
-
},
|
252
|
-
},
|
253
|
-
);
|
254
|
-
|
255
|
-
#------------------------------------------------------------------------------
|
256
|
-
1; #end
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
# File: gps2utm.config
|
3
|
+
#
|
4
|
+
# Description: Generate UTM tags from GPS information
|
5
|
+
#
|
6
|
+
# Requires: ExifTool version 7.00 or later
|
7
|
+
#
|
8
|
+
# Notes: Uses GPSMapDatum, GPSLatitude and GPSLongitude to generate
|
9
|
+
# UTMCoordinates, UTMZone, UTMEasting and UTMNorthing. If
|
10
|
+
# GPSMapDatum is not available then "WGS84" is assumed.
|
11
|
+
#
|
12
|
+
# Example: > exiftool -config gps2utm.config "-utm*" t/images/GPS.jpg
|
13
|
+
# UTM Coordinates : 30U 569475.596m E 6094180.754m N
|
14
|
+
# UTM Easting : 569475.595558165
|
15
|
+
# UTM Northing : 6094180.75443061
|
16
|
+
# UTM Zone : 30U
|
17
|
+
#
|
18
|
+
# Caveats: When used to convert EXIF GPS coordinates, the reference
|
19
|
+
# direction tags (GPSLatitudeRef/GPSLongitudeRef) must exist or
|
20
|
+
# the calculated UTM coordinates may be in the wrong hemisphere
|
21
|
+
#
|
22
|
+
# Revisions: 2016/03/08 - Bryan K. Williams (aka StarGeek) Created
|
23
|
+
# 2016/03/09 - PH removed library dependency and re-organized
|
24
|
+
#------------------------------------------------------------------------------
|
25
|
+
|
26
|
+
my $deg2rad = 3.14159265358979 / 180;
|
27
|
+
|
28
|
+
sub tan($)
|
29
|
+
{
|
30
|
+
return sin($_[0]) / cos($_[0]);
|
31
|
+
}
|
32
|
+
|
33
|
+
#===============================================================================
|
34
|
+
# the following code is by Graham Crookham:
|
35
|
+
# http://search.cpan.org/~grahamc/Geo-Coordinates-UTM/ (version 0.11)
|
36
|
+
|
37
|
+
# remove all markup from an ellipsoid name, to increase the chance
|
38
|
+
# that a match is found.
|
39
|
+
sub _cleanup_name($)
|
40
|
+
{ my $copy = lc(shift);
|
41
|
+
for($copy)
|
42
|
+
{ s/\([^)]+\)//g; # remove text between parantheses
|
43
|
+
s/[\s-]//g; # no blanks or dashes
|
44
|
+
}
|
45
|
+
$copy;
|
46
|
+
}
|
47
|
+
|
48
|
+
# Ellipsoid array (name,equatorial radius,square of eccentricity)
|
49
|
+
# Same data also as hash with key eq name (in variations)
|
50
|
+
|
51
|
+
my (@Ellipsoid, %Ellipsoid);
|
52
|
+
|
53
|
+
BEGIN { # Initialize this before other modules get a chance
|
54
|
+
@Ellipsoid =
|
55
|
+
( [ "Airy", 6377563, 0.00667054]
|
56
|
+
, [ "Australian National", 6378160, 0.006694542]
|
57
|
+
, [ "Bessel 1841", 6377397, 0.006674372]
|
58
|
+
, [ "Bessel 1841 Nambia", 6377484, 0.006674372]
|
59
|
+
, [ "Clarke 1866", 6378206, 0.006768658]
|
60
|
+
, [ "Clarke 1880", 6378249, 0.006803511]
|
61
|
+
, [ "Everest 1830 India", 6377276, 0.006637847]
|
62
|
+
, [ "Fischer 1960 Mercury", 6378166, 0.006693422]
|
63
|
+
, [ "Fischer 1968", 6378150, 0.006693422]
|
64
|
+
, [ "GRS 1967", 6378160, 0.006694605]
|
65
|
+
, [ "GRS 1980", 6378137, 0.00669438]
|
66
|
+
, [ "Helmert 1906", 6378200, 0.006693422]
|
67
|
+
, [ "Hough", 6378270, 0.00672267]
|
68
|
+
, [ "International", 6378388, 0.00672267]
|
69
|
+
, [ "Krassovsky", 6378245, 0.006693422]
|
70
|
+
, [ "Modified Airy", 6377340, 0.00667054]
|
71
|
+
, [ "Modified Everest", 6377304, 0.006637847]
|
72
|
+
, [ "Modified Fischer 1960", 6378155, 0.006693422]
|
73
|
+
, [ "South American 1969", 6378160, 0.006694542]
|
74
|
+
, [ "WGS 60", 6378165, 0.006693422]
|
75
|
+
, [ "WGS 66", 6378145, 0.006694542]
|
76
|
+
, [ "WGS-72", 6378135, 0.006694318]
|
77
|
+
, [ "WGS-84", 6378137, 0.00669438 ]
|
78
|
+
, [ "Everest 1830 Malaysia", 6377299, 0.006637847]
|
79
|
+
, [ "Everest 1956 India", 6377301, 0.006637847]
|
80
|
+
, [ "Everest 1964 Malaysia and Singapore", 6377304, 0.006637847]
|
81
|
+
, [ "Everest 1969 Malaysia", 6377296, 0.006637847]
|
82
|
+
, [ "Everest Pakistan", 6377296, 0.006637534]
|
83
|
+
, [ "Indonesian 1974", 6378160, 0.006694609]
|
84
|
+
, [ "Arc 1950", 6378249.145,0.006803481]
|
85
|
+
, [ "NAD 27",6378206.4,0.006768658]
|
86
|
+
, [ "NAD 83",6378137,0.006694384]
|
87
|
+
);
|
88
|
+
|
89
|
+
# calc ecc as
|
90
|
+
# a = semi major axis
|
91
|
+
# b = semi minor axis
|
92
|
+
# e^2 = (a^2-b^2)/a^2
|
93
|
+
# For clarke 1880 (Arc1950) a=6378249.145 b=6356514.966398753
|
94
|
+
# e^2 (40682062155693.23 - 40405282518051.34) / 40682062155693.23
|
95
|
+
# e^2 = 0.0068034810178165
|
96
|
+
|
97
|
+
foreach my $el (@Ellipsoid)
|
98
|
+
{ my ($name, $eqrad, $eccsq) = @$el;
|
99
|
+
$Ellipsoid{$name} = $el;
|
100
|
+
$Ellipsoid{_cleanup_name $name} = $el;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
# Returns "official" name, equator radius and square eccentricity
|
105
|
+
# The specified name can be numeric (for compatibility reasons) or
|
106
|
+
# a more-or-less exact name
|
107
|
+
# Examples: my($name, $r, $sqecc) = ellipsoid_info 'wgs84';
|
108
|
+
# my($name, $r, $sqecc) = ellipsoid_info 'WGS 84';
|
109
|
+
# my($name, $r, $sqecc) = ellipsoid_info 'WGS-84';
|
110
|
+
# my($name, $r, $sqecc) = ellipsoid_info 'WGS-84 (new specs)';
|
111
|
+
# my($name, $r, $sqecc) = ellipsoid_info 22;
|
112
|
+
|
113
|
+
sub ellipsoid_info($)
|
114
|
+
{ my $id = shift;
|
115
|
+
|
116
|
+
my $el = $id !~ m/\D/
|
117
|
+
? $Ellipsoid[$id-1] # old system counted from 1
|
118
|
+
: $Ellipsoid{$id} || $Ellipsoid{_cleanup_name $id};
|
119
|
+
|
120
|
+
defined $el ? @$el : ();
|
121
|
+
}
|
122
|
+
|
123
|
+
# Expects Ellipsoid Number or name, Latitude, Longitude
|
124
|
+
# (Latitude and Longitude in decimal degrees)
|
125
|
+
# Returns UTM Zone, UTM Easting, UTM Northing
|
126
|
+
|
127
|
+
sub latlon_to_utm(@)
|
128
|
+
{ my ($ellips, $latitude, $longitude) = @_;
|
129
|
+
|
130
|
+
die("Longitude value ($longitude) invalid\n")
|
131
|
+
if $longitude < -180 || $longitude > 180;
|
132
|
+
|
133
|
+
my $long2 = $longitude - int(($longitude + 180)/360) * 360;
|
134
|
+
my $zone = _latlon_zone_number($latitude, $long2);
|
135
|
+
|
136
|
+
_latlon_to_utm($ellips || 'WGS84', $zone, $latitude, $long2);
|
137
|
+
}
|
138
|
+
|
139
|
+
sub _latlon_zone_number
|
140
|
+
{ my ($latitude, $long2) = @_;
|
141
|
+
|
142
|
+
my $zone = int( ($long2 + 180)/6) + 1;
|
143
|
+
if($latitude >= 56.0 && $latitude < 64.0 && $long2 >= 3.0 && $long2 < 12.0)
|
144
|
+
{ $zone = 32;
|
145
|
+
}
|
146
|
+
if($latitude >= 72.0 && $latitude < 84.0) {
|
147
|
+
$zone = ($long2 >= 0.0 && $long2 < 9.0) ? 31
|
148
|
+
: ($long2 >= 9.0 && $long2 < 21.0) ? 33
|
149
|
+
: ($long2 >= 21.0 && $long2 < 33.0) ? 35
|
150
|
+
: ($long2 >= 33.0 && $long2 < 42.0) ? 37
|
151
|
+
: $zone;
|
152
|
+
}
|
153
|
+
return $zone;
|
154
|
+
}
|
155
|
+
|
156
|
+
sub _latlon_to_utm
|
157
|
+
{ my ($ellips, $zone, $latitude, $long2) = @_;
|
158
|
+
|
159
|
+
my ($name, $radius, $eccentricity) = ellipsoid_info $ellips
|
160
|
+
or die("Ellipsoid value ($ellips) invalid\n");
|
161
|
+
|
162
|
+
my $lat_radian = $deg2rad * $latitude;
|
163
|
+
my $long_radian = $deg2rad * $long2;
|
164
|
+
|
165
|
+
my $k0 = 0.9996; # scale
|
166
|
+
|
167
|
+
my $longorigin = ($zone - 1)*6 - 180 + 3;
|
168
|
+
my $longoriginradian = $deg2rad * $longorigin;
|
169
|
+
my $eccentprime = $eccentricity/(1-$eccentricity);
|
170
|
+
|
171
|
+
my $N = $radius / sqrt(1-$eccentricity * sin($lat_radian)*sin($lat_radian));
|
172
|
+
my $T = tan($lat_radian) * tan($lat_radian);
|
173
|
+
my $C = $eccentprime * cos($lat_radian)*cos($lat_radian);
|
174
|
+
my $A = cos($lat_radian) * ($long_radian - $longoriginradian);
|
175
|
+
my $M = $radius
|
176
|
+
* ( ( 1 - $eccentricity/4 - 3 * $eccentricity * $eccentricity/64
|
177
|
+
- 5 * $eccentricity * $eccentricity * $eccentricity/256
|
178
|
+
) * $lat_radian
|
179
|
+
- ( 3 * $eccentricity/8 + 3 * $eccentricity * $eccentricity/32
|
180
|
+
+ 45 * $eccentricity * $eccentricity * $eccentricity/1024
|
181
|
+
) * sin(2 * $lat_radian)
|
182
|
+
+ ( 15 * $eccentricity * $eccentricity/256 +
|
183
|
+
45 * $eccentricity * $eccentricity * $eccentricity/1024
|
184
|
+
) * sin(4 * $lat_radian)
|
185
|
+
- ( 35 * $eccentricity * $eccentricity * $eccentricity/3072
|
186
|
+
) * sin(6 * $lat_radian)
|
187
|
+
);
|
188
|
+
|
189
|
+
my $utm_easting = $k0*$N*($A+(1-$T+$C)*$A*$A*$A/6
|
190
|
+
+ (5-18*$T+$T*$T+72*$C-58*$eccentprime)*$A*$A*$A*$A*$A/120)
|
191
|
+
+ 500000.0;
|
192
|
+
|
193
|
+
my $utm_northing= $k0 * ( $M + $N*tan($lat_radian) * ( $A*$A/2+(5-$T+9*$C+4*$C*$C)*$A*$A*$A*$A/24 + (61-58*$T+$T*$T+600*$C-330*$eccentprime) * $A*$A*$A*$A*$A*$A/720));
|
194
|
+
|
195
|
+
$utm_northing += 10000000.0 if $latitude < 0;
|
196
|
+
|
197
|
+
my $utm_letter
|
198
|
+
= ( 84 >= $latitude && $latitude >= 72) ? 'X'
|
199
|
+
: ( 72 > $latitude && $latitude >= 64) ? 'W'
|
200
|
+
: ( 64 > $latitude && $latitude >= 56) ? 'V'
|
201
|
+
: ( 56 > $latitude && $latitude >= 48) ? 'U'
|
202
|
+
: ( 48 > $latitude && $latitude >= 40) ? 'T'
|
203
|
+
: ( 40 > $latitude && $latitude >= 32) ? 'S'
|
204
|
+
: ( 32 > $latitude && $latitude >= 24) ? 'R'
|
205
|
+
: ( 24 > $latitude && $latitude >= 16) ? 'Q'
|
206
|
+
: ( 16 > $latitude && $latitude >= 8) ? 'P'
|
207
|
+
: ( 8 > $latitude && $latitude >= 0) ? 'N'
|
208
|
+
: ( 0 > $latitude && $latitude >= -8) ? 'M'
|
209
|
+
: ( -8 > $latitude && $latitude >= -16) ? 'L'
|
210
|
+
: (-16 > $latitude && $latitude >= -24) ? 'K'
|
211
|
+
: (-24 > $latitude && $latitude >= -32) ? 'J'
|
212
|
+
: (-32 > $latitude && $latitude >= -40) ? 'H'
|
213
|
+
: (-40 > $latitude && $latitude >= -48) ? 'G'
|
214
|
+
: (-48 > $latitude && $latitude >= -56) ? 'F'
|
215
|
+
: (-56 > $latitude && $latitude >= -64) ? 'E'
|
216
|
+
: (-64 > $latitude && $latitude >= -72) ? 'D'
|
217
|
+
: (-72 > $latitude && $latitude >= -80) ? 'C'
|
218
|
+
: die("Latitude ($latitude) out of UTM range\n");
|
219
|
+
|
220
|
+
$zone .= $utm_letter;
|
221
|
+
|
222
|
+
($zone, $utm_easting, $utm_northing);
|
223
|
+
}
|
224
|
+
# End Graham Crookham code
|
225
|
+
#===============================================================================
|
226
|
+
|
227
|
+
%Image::ExifTool::UserDefined = (
|
228
|
+
'Image::ExifTool::Composite' => {
|
229
|
+
UTMCoordinates => {
|
230
|
+
Desire => {
|
231
|
+
0 => 'GPSMapDatum',
|
232
|
+
},
|
233
|
+
Require => {
|
234
|
+
1 => 'GPSLatitude',
|
235
|
+
2 => 'GPSLongitude',
|
236
|
+
},
|
237
|
+
ValueConv => 'join " ", latlon_to_utm(@val)',
|
238
|
+
PrintConv => 'sprintf("%s %.3fm E %.3fm N", split(" ", $val))',
|
239
|
+
},
|
240
|
+
UTMZone => {
|
241
|
+
Require => 'UTMCoordinates',
|
242
|
+
ValueConv => 'my @a=split(" ",$val); $a[0]',
|
243
|
+
},
|
244
|
+
UTMEasting => {
|
245
|
+
Require => 'UTMCoordinates',
|
246
|
+
ValueConv => 'my @a=split(" ",$val); $a[1]',
|
247
|
+
},
|
248
|
+
UTMNorthing => {
|
249
|
+
Require => 'UTMCoordinates',
|
250
|
+
ValueConv => 'my @a=split(" ",$val); $a[2]',
|
251
|
+
},
|
252
|
+
},
|
253
|
+
);
|
254
|
+
|
255
|
+
#------------------------------------------------------------------------------
|
256
|
+
1; #end
|