rwcarlsen / goexif

Decode embedded EXIF meta data from image files.
BSD 2-Clause "Simplified" License
627 stars 134 forks source link

Values for GPS are inexact #15

Closed ovidiuvisan closed 10 years ago

ovidiuvisan commented 10 years ago

Given 57 15' 23.31" N as latitude, converted to decimal should output 57.256475 not 57.256474

only when i converted back to GPS coordinates the problem becomes clear: 57.256475 == 57 15' 23.31" 57.256474 == 57 15' 23.3" (converted using http://www.onlineconversion.com/map_decimaldegrees.htm) seems you are taking in account only the first digit after the . Same issue on Longitude. Can you please fix it, to have the same output as exiftool?

rwcarlsen commented 10 years ago

Could you provide a photo (or link to one) that exemplifies the problem?

ovidiuvisan commented 10 years ago

dscn0035 Sure, this picture can be used.

exiftool -c "%.6f degrees" -gps:GPSLatitude DSCN0035.JPG GPS Latitude : 57.242143 degrees

and using goexif: 57.24214

same for Longitude

exiftool -c "%.6f degrees" -gps:GPSLongitude DSCN0035.JPG GPS Longitude : 111.401488 degrees

and using goexif: 111.40149

if you take both values for Latitude for example and convert them back into GPS degrees, minutes, seconds with http://www.onlineconversion.com/map_decimaldegrees.htm, the problem will become clear, goexif takes in account only 1st decimal in seconds, 57 14' 31.7" instead of 57 14' 31.71". It should take all the decimals in account.

rwcarlsen commented 10 years ago

I don't think there is anything wrong with goexif. The exif GPS tag data is returned in Go's big.Rat format. The raw Lat-Long data I get from the sample file is:

GPSLatitude: ["57/1","14/1","31716/1000"]
GPSLongitude: ["111/1","24/1","5358/1000"]

You will want to do sth like this (except handle all the errors):

    fname := "gps.jpg"
    f, _ := os.Open(fname)
    x, _ := exif.Decode(f)

    lat, _ := x.Get(exif.GPSLatitude)
    deg, _ := lat.Rat(0).Float64()
    min, _ := lat.Rat(1).Float64()
    sec, _ := lat.Rat(2).Float64()
    floatLat := deg + min/60 + sec/3600
    fmt.Printf("latitude: %v\n", floatLat)

That gives me this output:

latitude: 57.24214333333333
ovidiuvisan commented 10 years ago

i see, thank you for the example. This will work fine.