【问题标题】:how to normalise latitude into the range of -90 to 90?如何将纬度归一化到-90到90的范围内?
【发布时间】:2018-12-23 09:21:21
【问题描述】:

使用 piexif 我得到了纬度和经度的 DMS,我试图将其转换为十进制度,但对于某些图像,我得到的纬度值是 184.62583333333333,它超出了 [-90,90] 范围。

查看下面的代码,

exif_dict = piexif.load('images/DJI_0026.JPG')
long = 0
latt = 0
value = exif_dict['GPS']
if value:
    lat = value[2]
    lon = value[4]
    for i in range(3):
        if i == 1:
            latt += lat[i][0]/60.0
        elif i == 2:
            latt += lat[i][0]/3600.0
        else:
            latt += lat[i][0]
    for i in range(3):
        if i == 1:
            long += lon[i][0]/60.0
        elif i == 2:
            long += lon[i][0]/3600.0
        else:
            long += lon[i][0]
print(latt, long)

值 = {0: (2, 3, 0, 0), 1: b'N', 2: ((19, 1), (8, 1), (595773, 10000)), 3: b 'E', 4: ((73, 1), (0, 1), (131775, 10000)), 5: 0, 6: (70989, 1000)}

我关心的是纬度和经度,它们存储在键 2 和 4 的值中。

纬度 = 19+8/60.0+595773/3600.0

经度 = 73+0/60.0+131775/3600.0

这就是输出。

输出:184.62583333333333 109.60416666666666

请告诉我如何在 [-90,90] 范围内标准化纬度。

【问题讨论】:

  • 原始EXIF数据是如何编码的?
  • @ThierryLathuille,像这样 {0: (2, 3, 0, 0), 1: b'N', 2: ((19, 1), (8, 1), (595773 , 10000)), 3: b'E', 4: ((73, 1), (0, 1), (131775, 10000)), 5: 0, 6: (70989, 1000)}
  • 当您使用调试器单步执行代码时,值与您预期的不同?将坐标与其他程序显示的坐标进行比较。
  • @RolandIllig,我得到了正确的输出,但我想标准化我得到的纬度经度,cz 当你在地图上搜索时,没有这样的纬度和经度的地方。

标签: python normalize piexif


【解决方案1】:

piexif 返回的 GPS 坐标数据格式如下:

exif_data = {0: (2, 3, 0, 0),
             # Latitude: b'N' or b'S'
             1: b'N', 
             # deg, min, sec as (numerator,denominator) of rationals
             2: ((19, 1), (8, 1), (595773, 10000)),
             # Longitude: b'E' or b'W'
             3: b'E', 
             4: ((73, 1), (0, 1), (131775, 10000)), 
             5: 0, 6: (70989, 1000)}

纬度和经度被给出为正的、合理的值,朝向 N 或 S(分别是 E 或 W)。

我们需要将正值从 DMS 转换为十进制,然后根据方向给它们正确的符号:

def convert_DMS_tuple(tup):
    d, m, s = [t[0]/t[1] for t in tup]
    degrees = d + m/60 + s/3600
    return degrees

def EXIF_to_lat_long(exif_data):
    # Latitude is counted positive towards N
    lat_sign = 1 if exif_data[1] == b'N' else -1
    lat = lat_sign*convert_DMS_tuple(exif_data[2])

    # Longitude is counted positive towards E
    long_sign = 1 if exif_data[3] == b'E' else -1
    long = long_sign*convert_DMS_tuple(exif_data[4])

    return lat, long

EXIF_to_lat_long(exif_data)
# (19.149882583333333, 73.00366041666666)

你可以这样使用:

exif_dict = piexif.load('images/DJI_0026.JPG')
value = exif_dict['GPS']
if value:
   print(EXIF_to_lat_long(value))

【讨论】:

  • 完成了!谢谢。
【解决方案2】:

从您提供的示例值看来,您应该将 val[0] 除以 val[1]。

例如,595773 / 10000 = 59,这对于一秒钟来说非常有意义。

顺便说一句,您不需要for 循环。它们使您的代码比必要的更长。

value[1] == b'N' 可能是有原因的。您当前的代码不会评估它。这意味着您的代码仅适用于地球表面的 1/4。

请参阅https://sno.phy.queensu.ca/~phil/exiftool/TagNames/GPS.html 以获得良好的概述。您的代码也应该能够解释 South 和 West。

【讨论】:

  • 纬度始终为 2,经度始终为 4。
  • 你能帮我怎么做吗?我不明白。
  • @rolandilling 是正确的。根据exif2 specshere GPSLatitude 表示纬度。纬度表示为三个 RATIONAL 值,分别给出度、分和秒。如果纬度用度、分和秒表示,典型的格式是 dd/1,mm/1,ss/1。当使用度数和分钟数时,例如,分钟的分数最多保留两位小数,格式为 dd/1,mmmm/100,0/1。所以,度 = 19/1,分 = 8/1,秒 = 595773/10000
  • 你不应该依赖总是在索引 2 处的经度——你的意思是纬度,这在标准中。在您链接的页面中,您可以看到纬度的标签 ID 为 0x0002。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
相关资源
最近更新 更多