# !/usr/bin/python3
# coding: utf-8
import json
import os
import traceback
import exifread
import requests
def parse_gps_express(gps_express):
'''
GPS坐标表达式转数值
:param gps_express: GPS坐标表达式 [1,2,3/4]
:return: GPS坐标数值 1.033542
'''
try:
express = str(gps_express).replace(" ", "").replace("[", "").replace("]", "")
parts = express.split(",")
subpart = parts[2].split("/")
degrees = float(parts[0])
minutes = float(parts[1])
seconds = float(subpart[0]) / float(subpart[1])
return degrees + minutes / 60 + seconds / 3600
except:
raise Exception("Error information for the picture")
def photo_gps(photo_path):
'''
照片拍摄地GPS坐标
:param photo_path: 照片的磁盘路径
:return: 照片的 (GPS经度,GPS纬度)
'''
if not os.path.isfile(photo_path):
raise Exception("File is not exist")
with open(photo_path, 'rb') as f:
exif_dict = exifread.process_file(f)
longitude_ref = str(exif_dict["GPS GPSLongitudeRef"]).strip()
longitude = parse_gps_express(str(exif_dict["GPS GPSLongitude"]))
latitude_ref = str(exif_dict["GPS GPSLatitudeRef"]).strip()
latitude = parse_gps_express(str(exif_dict["GPS GPSLatitude"]))
lng = longitude if "E" == longitude_ref else 0 - longitude
lat = latitude if "N" == latitude_ref else 0 - latitude
return lng, lat
def convert_gps(gps_coordinates):
'''
坐标转换:GPS转高德
:param gps_coordinates: 多个位置(GPS经度,GPS纬度)的集合
:return: 多个位置(高德经度,高德纬度)的集合
'''
try:
coordinates = "|".join(gps_coordinates) # 最多批量查询40个
token = "cb1c527f67df87bdc3a72f8a75987e62" # 自行申请,免费
url = "https://restapi.amap.com/v3/assistant/coordinate/convert" \
"?locations={0}&key={1}&coordsys=gps&output=json".format(coordinates, token)
response = requests.get(url) # 个人开发者访问限流:100000次/日
result = json.loads(response.text)
if "1" == result["status"]:
return result["locations"].split(";")
else:
raise Exception(result["info"])
except Exception as e:
raise e
def map_address(gd_coordinates):
'''
逆地理编码(高德坐标转地址)
:param gd_coordinates:多个位置(高德经度,高德纬度)的集合
:return:多个位置地址信息的集合
'''
try:
coordinates = "|".join(gd_coordinates) # 最多批量查询20个
token = "cb1c527f67df87bdc3a72f8a75987e62" # 自行申请,免费
batch = "true" if len(gd_coordinates) > 1 else "false"
url = "https://restapi.amap.com/v3/geocode/regeo" \
"?location={0}&key={1}&batch={2}&radius=500&extensions=base&output=json".format(coordinates, token, batch)
response = requests.get(url) # 个人开发者访问限流:6000次/日
result = json.loads(response.text)
if "1" == result["status"]:
address = []
if "true" == batch:
add_lst = list(result["regeocodes"])
for add in add_lst:
address.append(add["formatted_address"])
else:
fmt_add = result["regeocode"]["formatted_address"]
address.append(fmt_add)
return address
else:
raise Exception(result["info"])
except Exception as e:
raise e
if __name__ == '__main__':
try:
lng1, lat1 = photo_gps("3.jpg")
lng2, lat2 = photo_gps("3.jpg")
lng3, lat3 = photo_gps("3.jpg")
gps_coordinates = list()
gps_coordinates.append("%s,%s" % (lng1, lat1))
gps_coordinates.append("%s,%s" % (lng2, lat2))
gps_coordinates.append("%s,%s" % (lng3, lat3))
gd_coordinates = convert_gps(gps_coordinates)
addresses = map_address(gd_coordinates)
for add in addresses:
print(add)
except:
traceback.print_exc()
# -*- coding: utf-8 -*-
# @Date : 2020/02/22 13:59
import requests
import exifread
class GetPhotoInfo:
def __init__(self, photo):
self.photo = photo
# 百度地图ak
self.ak = '3iVKI77ap5Tb2M2FIGS1gvEtcSzD3yWZ'
self.location = self.get_photo_info()
def get_photo_info(self, ):
with open(self.photo, 'rb') as f:
tags = exifread.process_file(f)
try:
# 打印照片其中一些信息
print('拍摄时间:', tags['EXIF DateTimeOriginal'])
print('照相机制造商:', tags['Image Make'])
print('照相机型号:', tags['Image Model'])
print('照片尺寸:', tags['EXIF ExifImageWidth'], tags['EXIF ExifImageLength'])
# 拿到的是度分秒的经纬度,需要转化为十进制的经纬度
# 转换公式为 度 + 分 / 60 + 秒 / 3600
# 纬度
lat_ref = tags["GPS GPSLatitudeRef"].printable
lat = tags["GPS GPSLatitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600
if lat_ref != "N":
lat = lat * (-1)
# 经度
lon_ref = tags["GPS GPSLongitudeRef"].printable
lon = tags["GPS GPSLongitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
lon = float(lon[0]) + float(lon[1]) / 60 + float(lon[2]) / float(lon[3]) / 3600
if lon_ref != "E":
lon = lon * (-1)
except KeyError:
return "ERROR:请确保照片包含经纬度等EXIF信息。"
else:
print("经纬度:", lat, lon)
return lat, lon
def get_location(self):
url = 'http://api.map.baidu.com/reverse_geocoding/v3/?ak={}&output=json' \
'&coordtype=wgs84ll&location={},{}'.format(self.ak, *self.location)
response = requests.get(url).json()
status = response['status']
if status == 0:
address = response['result']['formatted_address']
print('详细地址:', address)
else:
print('baidu_map error')
if __name__ == '__main__':
Main = GetPhotoInfo('F:\\python练习\\41EC18077B90402F1BF6702448D40197.jpg')
Main.get_location()