Skip to content

Commit

Permalink
fix #165
Browse files Browse the repository at this point in the history
  • Loading branch information
mceachen committed Jan 1, 2024
1 parent 397db76 commit 1a5063b
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 24 deletions.
40 changes: 31 additions & 9 deletions src/ReadTask.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,28 +71,50 @@ describe("ReadTask", () => {
})
it("S lat is negative", () => {
expect(
parse({ tags: { GPSLatitude: 33.84842123, GPSLatitudeRef: "S" } })
parse({ tags: { GPSLatitude: -33.84842123, GPSLatitudeRef: "S" } })
.GPSLatitude
).to.be.closeTo(-33.84842123, 0.00001)
})
it("E lon is positive", () => {
it("positive E lon is positive", () => {
expect(
parse({
tags: { GPSLongitude: 114.16401667, GPSLongitudeRef: "E" },
}).GPSLongitude
parse({ tags: { GPSLongitude: 114.16401667, GPSLongitudeRef: "E" } })
.GPSLongitude
).to.be.closeTo(114.16401667, 0.00001)
})
it("W lon is negative", () => {
// See https://github.com/photostructure/exiftool-vendored.js/issues/165
it("negative E lon is negative", () => {
expect(
parse({ tags: { GPSLongitude: -114, GPSLongitudeRef: "E" } })
).to.containSubset({
GPSLongitude: -114,
GPSLongitudeRef: "E",
warnings: [
"Invalid GPSLongitude or GPSLongitudeRef: expected E GPSLongitude > 0 but got -114",
],
})
})
it("positive W lon is negative", () => {
expect(
parse({ tags: { GPSLongitude: 122, GPSLongitudeRef: "W" } })
).to.containSubset({
GPSLongitude: 122,
GPSLongitudeRef: "W",
warnings: [
"Invalid GPSLongitude or GPSLongitudeRef: expected W GPSLongitude < 0 but got 122",
],
})
})
it("negative W lon is positive", () => {
expect(
parse({ tags: { GPSLongitude: 122.4406148, GPSLongitudeRef: "W" } })
parse({ tags: { GPSLongitude: -122.4406148, GPSLongitudeRef: "W" } })
.GPSLongitude
).to.be.closeTo(-122.4406148, 0.00001)
})
it("parses lat lon even if timezone is given", () => {
expect(
parse({
tags: {
GPSLongitude: 122.4406148,
GPSLongitude: -122.4406148,
GPSLongitudeRef: "West",
OffsetTime: "+02:00",
},
Expand Down Expand Up @@ -357,7 +379,7 @@ describe("ReadTask", () => {
tags: {
GPSLatitude: 38.791121,
GPSLatitudeRef: "North",
GPSLongitude: 109.606407,
GPSLongitude: -109.606407,
GPSLongitudeRef: "West",
DateTimeOriginal: "2016:08:12 13:28:50",
},
Expand Down
57 changes: 42 additions & 15 deletions src/ReadTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import { ExifToolTask } from "./ExifToolTask"
import { Utf8FilenameCharsetArgs } from "./FilenameCharsetArgs"
import { lazy } from "./Lazy"
import { firstDefinedThunk, map } from "./Maybe"
import { toFloat } from "./Number"
import { isNumber, toFloat } from "./Number"
import { OnlyZerosRE } from "./OnlyZerosRE"
import { pick } from "./Pick"
import { blank, isString, toS } from "./String"
import { blank, isString } from "./String"
import { Tags } from "./Tags"
import {
extractTzOffsetFromDatestamps,
Expand Down Expand Up @@ -193,8 +193,18 @@ export class ReadTask extends ExifToolTask<Tags> {
}

#extractLatLon = lazy(() => {
this.lat ??= this.#latlon("GPSLatitude", "S", 90)
this.lon ??= this.#latlon("GPSLongitude", "W", 180)
this.lat ??= this.#latlon({
tagName: "GPSLatitude",
positiveRef: "N",
negativeRef: "S",
maxValid: 90,
})
this.lon ??= this.#latlon({
tagName: "GPSLongitude",
positiveRef: "E",
negativeRef: "W",
maxValid: 180,
})
if (this.options.ignoreZeroZeroLatLon && this.lat === 0 && this.lon === 0) {
this.invalidLatLon = true
}
Expand All @@ -203,13 +213,20 @@ export class ReadTask extends ExifToolTask<Tags> {
}
})

#latlon(
tagName: "GPSLatitude" | "GPSLongitude",
negateRef: "S" | "W",
#latlon({
tagName,
positiveRef,
negativeRef,
maxValid,
}: {
tagName: "GPSLatitude" | "GPSLongitude"
positiveRef: "N" | "E"
negativeRef: "S" | "W"
maxValid: 90 | 180
): number | undefined {
}): number | undefined {
const tagValue = this._rawDegrouped[tagName]
const ref = this._rawDegrouped[tagName + "Ref"]
const refKey = tagName + "Ref"
const ref = this._rawDegrouped[refKey]
const result = toFloat(tagValue)
if (result == null) {
return
Expand All @@ -221,12 +238,22 @@ export class ReadTask extends ExifToolTask<Tags> {
// Videos may not have a GPSLatitudeRef or GPSLongitudeRef: if this is the case, assume the given sign is correct.
return result
} else {
// Versions of ExifTool pre-12 returned properly-negated lat/lon. ExifTool
// 12+ always returns positive values (!!). Also: if '-GPS*#' is set,
// we'll see "S" instead of "South", hence the .startsWith() instead of
// ===:
const negative = toS(ref).toUpperCase().startsWith(negateRef)
return (negative ? -1 : 1) * Math.abs(result)
// See https://github.com/photostructure/exiftool-vendored.js/issues/165
// and https://www.exiftool.org/TagNames/GPS.html
const expectedPositive =
ref.toUpperCase().startsWith(positiveRef) || (isNumber(ref) && ref >= 0)
const expectedNegative =
ref.toUpperCase().startsWith(negativeRef) || (isNumber(ref) && ref < 0)
if (expectedPositive && result < 0) {
this.warnings.push(
`Invalid ${tagName} or ${refKey}: expected ${ref} ${tagName} > 0 but got ${result}`
)
} else if (expectedNegative && result > 0) {
this.warnings.push(
`Invalid ${tagName} or ${refKey}: expected ${ref} ${tagName} < 0 but got ${result}`
)
}
return result
}
}

Expand Down

0 comments on commit 1a5063b

Please sign in to comment.