使用高德或者百度的逆地理编码API将照片根据拍摄地址进行分类
高德和百度地图都提供了逆地理编码的API来方便个人开发者进行开发,百度的API免费使用次数为300/天,高德为15000/月,照片多的话还是使用高德更方便:可以在对应的个人开发平台:高德开放平台、百度开放平台 申请账号并使用API;
本文是在 ZXW_NUDT的相关文章的基础上进行修改的,侵删
以下代码使用python运行:
百度API
# -*- coding: utf-8 -*-
"""
Created on Tue May 27 15:36:57 2025
@author: F1_tsp6
"""
import exifread
import re
import json
import requests
import os
import shutil
# 转换经纬度格式
def latitude_and_longitude_convert_to_decimal_system(deg, min, sec):
"""
经纬度转为小数
:param deg: 度
:param min: 分
:param sec: 秒(可以是分数形式,如"30/1")
:return: 十进制小数
"""
try:
sec = float(sec.split('/')[0]) / float(sec.split('/')[1]) if '/' in sec else float(sec)
return float(deg) + (float(min) / 60.0) + (sec / 3600.0)
except:
return None
# 读取照片的GPS经纬度信息
def find_GPS_image(pic_path):
GPS = {}
date = ''
with open(pic_path, 'rb') as f:
tags = exifread.process_file(f)
for tag, value in tags.items():
# 纬度参考
if tag == 'GPS GPSLatitudeRef':
GPS['GPSLatitudeRef'] = str(value)
# 经度参考
elif tag == 'GPS GPSLongitudeRef':
GPS['GPSLongitudeRef'] = str(value)
# 海拔参考
elif tag == 'GPS GPSAltitudeRef':
GPS['GPSAltitudeRef'] = str(value)
elif tag == 'GPS GPSLatitude':
gps_latitude = value.values
deg, min, sec = [str(x) for x in gps_latitude]
GPS['GPSLatitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec)
elif tag == 'GPS GPSLongitude':
gps_longitude = value.values
deg, min, sec = [str(x) for x in gps_longitude]
GPS['GPSLongitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec)
elif tag == 'GPS GPSAltitude':
GPS['GPSAltitude'] = str(value)
elif 'Date' in tag:
date = str(value)
return {'GPS_information': GPS, 'date_information': date}
# 输出经纬度(度、分、秒)
def Position(x, y):
nsl = x
ewl = y
'''度'''
angle1 = int(nsl)
angle2 = int(ewl)
'''分'''
min1 = int((nsl - angle1) * 60)
min2 = int((ewl - angle2) * 60)
'''秒'''
second1 = round((((nsl - angle1) * 60) - min1) * 60, 2)
second2 = round((((ewl - angle2) * 60) - min2) * 60, 2)
print("北纬:{}度{}分{}秒".format(angle1, min1, second1))
print("东经:{}度{}分{}秒".format(angle2, min2, second2))
# 通过百度地图的API将GPS信息转换成地址
def find_address_from_GPS(GPS):
"""
使用Geocoding API把经纬度坐标转换为结构化地址。
:param GPS:
:return:
"""
secret_key = '使用自己的key'
if not GPS['GPS_information']:
return '该照片无GPS信息'
lat = GPS['GPS_information'].get('GPSLatitude')
lng = GPS['GPS_information'].get('GPSLongitude')
if lat is None or lng is None:
return '无效的GPS坐标'
# 打印十进制度数的经纬度
print("\n照片的经纬度(十进制度数):")
print("纬度:{:.6f}".format(lat))
print("经度:{:.6f}".format(lng))
# 打印度分秒
print("\n照片的经纬度(度分秒):")
Position(lat, lng)
baidu_map_api = f"https://api.map.baidu.com/reverse_geocoding/v3/?ak={secret_key}&location={lat},{lng}&output=json&pois=0"
response = requests.get(baidu_map_api)
try:
content = response.json()
except json.JSONDecodeError:
return '无法解析百度地图API的响应'
if content.get("status") != 0:
return '百度地图API返回错误'
result = content.get("result", {})
formatted_address = result.get("formatted_address", "未知地址")
address_component = result.get("addressComponent", {})
province = address_component.get("province", "")
city = address_component.get("city", "")
district = address_component.get("district", "")
location_desc = result.get("sematic_description", "")
return formatted_address, province, city, district, location_desc
if __name__ == '__main__':
pic_path = '输入自己的路径'#
#image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp']
files = os.listdir(pic_path)
for file in files:
source=pic_path +'/'+ file
GPS_info = find_GPS_image(pic_path=source)
address = find_address_from_GPS(GPS=GPS_info)
#print("\n拍摄时间:" + GPS_info.get("date_information", "未知"))
#print("照片拍摄地址:", end='')
if isinstance(address, tuple) and address[2]!='':
# address 为 (formatted_address, province, city, district, location_desc)
# 打印详细地址信息
print(f"城市:{address[2]}")
folder_name = address[2]
path = '输入自己的路径'+ folder_name
os.makedirs(path, exist_ok=True)
shutil.move(source, path)
#print("\n详细地址信息:")
#print(f"省份:{address[1]}")
#print(f"区县:{address[3]}")
#print(f"位置描述:{address[4]}")
else:
#path=pic_path +'/'+ '无地址'
#shutil.move(source, path)
print('移动失败:'+str(address))
也可以使用高德的API进行编码(两者的编码方式略有差异):
高德API
# -*- coding: utf-8 -*-
"""
Created on Tue May 27 15:36:57 2025
@author: F1_tsp6
"""
import exifread
import re
import json
import requests
import os
import shutil
# 转换经纬度格式
def latitude_and_longitude_convert_to_decimal_system(deg, min, sec):
"""
经纬度转为小数
:param deg: 度
:param min: 分
:param sec: 秒(可以是分数形式,如"30/1")
:return: 十进制小数
"""
try:
sec = float(sec.split('/')[0]) / float(sec.split('/')[1]) if '/' in sec else float(sec)
return float(deg) + (float(min) / 60.0) + (sec / 3600.0)
except:
return None
# 读取照片的GPS经纬度信息
def find_GPS_image(pic_path):
GPS = {}
date = ''
with open(pic_path, 'rb') as f:
tags = exifread.process_file(f)
for tag, value in tags.items():
# 纬度参考
if tag == 'GPS GPSLatitudeRef':
GPS['GPSLatitudeRef'] = str(value)
# 经度参考
elif tag == 'GPS GPSLongitudeRef':
GPS['GPSLongitudeRef'] = str(value)
# 海拔参考
elif tag == 'GPS GPSAltitudeRef':
GPS['GPSAltitudeRef'] = str(value)
elif tag == 'GPS GPSLatitude':
gps_latitude = value.values
deg, min, sec = [str(x) for x in gps_latitude]
GPS['GPSLatitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec)
elif tag == 'GPS GPSLongitude':
gps_longitude = value.values
deg, min, sec = [str(x) for x in gps_longitude]
GPS['GPSLongitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec)
elif tag == 'GPS GPSAltitude':
GPS['GPSAltitude'] = str(value)
elif 'Date' in tag:
date = str(value)
return {'GPS_information': GPS, 'date_information': date}
# 输出经纬度(度、分、秒)
def Position(x, y):
nsl = x
ewl = y
'''度'''
angle1 = int(nsl)
angle2 = int(ewl)
'''分'''
min1 = int((nsl - angle1) * 60)
min2 = int((ewl - angle2) * 60)
'''秒'''
second1 = round((((nsl - angle1) * 60) - min1) * 60, 2)
second2 = round((((ewl - angle2) * 60) - min2) * 60, 2)
print("北纬:{}度{}分{}秒".format(angle1, min1, second1))
print("东经:{}度{}分{}秒".format(angle2, min2, second2))
# 通过百度地图的API将GPS信息转换成地址
def find_address_from_GPS(GPS):
"""
使用Geocoding API把经纬度坐标转换为结构化地址。
:param GPS:
:return:
"""
secret_key = '使用自己的key'
if not GPS['GPS_information']:
return '该照片无GPS信息'
lat = GPS['GPS_information'].get('GPSLatitude')
lng = GPS['GPS_information'].get('GPSLongitude')
if lat is None or lng is None:
return '无效的GPS坐标'
# 打印十进制度数的经纬度
print("\n照片的经纬度(十进制度数):")
print("纬度:{:.6f}".format(lat))
print("经度:{:.6f}".format(lng))
# 打印度分秒
print("\n照片的经纬度(度分秒):")
Position(lat, lng)
gaode_map_api = f"https://restapi.amap.com/v3/geocode/regeo?output=json&location={lng},{lat}&key={secret_key}&extensions=all"
response = requests.get(gaode_map_api)
try:
content = response.json()
except json.JSONDecodeError:
return '无法解析高德地图API的响应'
if content.get("status")!= '1':
return '高德地图API返回错误'
result = content.get("regeocode", {})
formatted_address = result.get("formatted_address", "未知地址")
address_component = result.get("addressComponent", {})
province = address_component.get("province", "")
city = address_component.get("city", "")
district = address_component.get("district", "")
#location_desc = result.get("sematic_description", "")
return formatted_address, province, city, district
if __name__ == '__main__':
pic_path = 'G:/2T内容/20230406备份_待完全恢复/图片/待GPS分地区'
#image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp']
files = os.listdir(pic_path)
for file in files:
source=pic_path +'/'+ file
GPS_info = find_GPS_image(pic_path=source)
address = find_address_from_GPS(GPS=GPS_info)
#print("\n拍摄时间:" + GPS_info.get("date_information", "未知"))
#print("照片拍摄地址:", end='')
if isinstance(address, tuple) and str(address[2])!='[]':
# address 为 (formatted_address, province, city, district)
# 打印详细地址信息
print(f"{file}城市:{address[2]}")
folder_name = address[2]
path = 'G:/2T内容/20230406备份_待完全恢复/图片/'+ folder_name
os.makedirs(path, exist_ok=True)
shutil.move(source, path)
#print("\n详细地址信息:")
#print(f"省份:{address[1]}")
#print(f"区县:{address[3]}")
#print(f"位置描述:{address[4]}")
else:
#path=pic_path +'/'+ '无地址'
#shutil.move(source, path)
print('移动失败:'+str(address))