python图片定位坐标,python获取照片的地点
每张照片的属性里都会有一个经纬度信息。本文将使用Python提取图片的经纬度,锁定照片的低点。有兴趣的朋友可以和边肖一起试试。
00-1010 1.原则1。图像必须有纬度和经度信息2。纬度格式转换3。根据经纬度定位2。python调用高德API进行图像定位1.main.py源代码2.position_utils.py源代码
目录
一、原理
1.图片必须具有经纬度信息
2.1 GPS点坐标的两种表示法(仍有一些误差)
2.1.1十进制度和分钟
例如:纬度和经度。58660 . 68686868686
2.1.2十进制的度、分和秒
2.1.3实际距离转换
地球子午线长度39940.67公里,纬度一秒钟变化110.94公里,1.849公里,30.8米,赤道圈40075.36公里。北京的纬度大概是北纬40度,纬度圈是40075 * sin(90-40)。这里的经度曾经是276公里,还有1.42公里。
赤道上绕地球一圈共有40075.04公里,这个圈分为360,每1度(度)有60。赤道上每一度和秒的长度计算如下:
40075.04公里/360=111.31955公里
111.31955公里/60英尺=1.8553258公里=1855.3米
而每一分钟都有60秒,每一秒都代表1855.3m/60=30.92m
计算任意两点之间距离的公式为:
d=111.12 cos { 1/[sinasinb ten cosacosbcos(b—a)]}
其中包括:
A点的经纬度分别为A和 A,B点的经纬度分别为B和 B,D为距离。结论
1经度差对应的东西方向的距离与其纬度密切相关。
赤道经度差1对应的弧长约为111公里。
具体数据如下:
东西距离对应的经纬度差为1
20 104公里
20 100公里
30 96公里
30 90公里
40 85公里
40 80公里
1 70公里
1.不同地区经纬度不一样,每度的距离差也不一样。如果假设地球是一个完美的球体(这样误差就不大),纬度为B的面积:
纬度一变,球体南北距离变化:R/180 …111.7km,经度一变,球体东西距离变化:R/180cosB …111.7cosB,比如北京B=40,cosB=0.766,经度一变,东西距离变化85.567km2,经度不同,在南极
一旦经度发生变化,球体从东到西的距离发生变化:R/180cosB …111.7cosB (R为地球半径,B为纬度)纬度之间的距离相同;一旦纬度发生变化,球体南北距离发生变化:R/180 …111.7km (R为地球半径)。
2.经纬度格式转换
高德坐标传感器
百度坐标取件
2>二、python调用高德API进行图片定位
1.main.py源码
代码如下(示例):
import osimport exifread
from decimal import Decimal
from position_utils import *
import requests
import json
import datetime
# pip3 install exifread
class Location(object):
def __init__(self, image_path):
self.img_path = image_path
self.api_key = "4e8d619c69859ce0f8962de9297c3764" #申请的高德APP web KEY
#self.api_key = "4f458eaded9bad93b63b8a2c67f5c0e0" #申请的高德APP web KEY
self.url_get_position = https://restapi.amap.com/v3/geocode/regeo?key={}&location={}
def run(self):
coordinate = self.__get_image_ability()
print(f获取到经度、纬度是:{coordinate})
if not coordinate:
return
# 根据经度和纬度,获取到详细地址
address = self.__get_address(coordinate)
# 检验坐标值
# https://lbs.amap.com/console/show/picker
print(f他当前位置在:{address})
def __get_address(self, location):
"""
根据坐标得到详细地址
:param location: 经纬度值
:return:
"""
resp = requests.get(self.url_get_position.format(self.api_key, location))
location_data = json.loads(resp.text)
address = location_data.get(regeocode).get(formatted_address)
return address
def __format_lati_long_data(self, data):
"""
对经度和纬度数据做处理,保留6位小数
:param data: 原始经度和纬度值
:return:
"""
# 删除左右括号和空格
data_list_tmp = str(data).replace([, ).replace(], ).split(,)
data_list = [data.strip() for data in data_list_tmp]
# 替换秒的值
data_tmp = data_list[-1].split(/)
# 秒的值
data_sec = int(data_tmp[0]) / int(data_tmp[1]) / 3600
# 替换分的值
data_tmp = data_list[-2]
# 分的值
data_minute = int(data_tmp) / 60
# 度的值
data_degree = int(data_list[0])
# 由于高德API只能识别到小数点后的6位
# 需要转换为浮点数,并保留为6位小数
result = "%.6f" % (data_degree + data_minute + data_sec)
return float(result)
def __get_image_ability(self):
"""
获取图片的属性值,包含:经纬度、拍摄时间等
:param picture_name:
:return:
"""
# 利用exifread库,读取图片的属性
img_exif = exifread.process_file(open(self.img_path, rb))
# 能够读取到属性
if img_exif:
# 纬度数
latitude_gps = img_exif[GPS GPSLatitude]
# N,S 南北纬方向
latitude_direction = img_exif[GPS GPSLatitudeRef]
# 经度数
longitude_gps = img_exif[GPS GPSLongitude]
# E,W 东西经方向
longitude_direction = img_exif[GPS GPSLongitudeRef]
# 拍摄时间
take_time = img_exif[EXIF DateTimeOriginal]
is_lie = self.judge_time_met(take_time)
if is_lie:
print(很遗憾的通知你,他/她在撒谎!!!照片不是今天拍的)
return
# 纬度、经度、拍摄时间
if latitude_gps and longitude_gps and take_time:
# 对纬度、经度值原始值作进一步的处理
latitude = self.__format_lati_long_data(latitude_gps)
longitude = self.__format_lati_long_data(longitude_gps)
# print(f{longitude},{latitude})
# 注意:由于gps获取的坐标在国内高德等主流地图上逆编码不够精确,这里需要转换为火星坐标系
location = wgs84togcj02(longitude, latitude)
return f{location[0]},{location[1]}
else:
print(f获取的图片数据属性不完整)
return
else:
print(抱歉,图片不是原图,没法获取到图片属性。)
return
def judge_time_met(self, take_time):
"""
通知拍摄时间判断女朋友是否撒谎
:param take_time:
:return:
"""
# 拍摄时间
format_time = str(take_time).split(" ")[0].replace(":", "-")
print(照片拍摄日期是:)
print(format_time)
# 当天日期 验证照片是否是当日拍摄
# today = str(datetime.date.today())
# if format_time == today:
# return False
# else:
# return True
if __name__ == __main__:
# 女朋友发过来的图片【原图】 #图片命名容易冲突,更换开头就可以
location = Location(./aec0cddf45a946dec358301ddf17982.jpg)
# 找到女朋友的地理位置
location.run()
2.position_utils.py源码
代码如下(坐标转换示例):
# -*- coding: utf-8 -*-import json
import math
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626 # π
a = 6378245.0 # 长半轴
ee = 0.00669342162296594323 # 扁率
def wgs84togcj02(lng, lat):
"""
WGS84转GCJ02(火星坐标系)
:param lng:WGS84坐标系的经度
:param lat:WGS84坐标系的纬度
:return:
"""
if out_of_china(lng, lat): # 判断是否在国内
return lng, lat
dlat = transformlat(lng - 105.0, lat - 35.0)
dlng = transformlng(lng - 105.0, lat - 35.0)
radlat = lat / 180.0 * pi
magic = math.sin(radlat)
magic = 1 - ee * magic * magic
sqrtmagic = math.sqrt(magic)
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
mglat = lat + dlat
mglng = lng + dlng
return [mglng, mglat]
def gcj02towgs84(lng, lat):
"""
GCJ02(火星坐标系)转GPS84
:param lng:火星坐标系的经度
:param lat:火星坐标系纬度
:return:
"""
if out_of_china(lng, lat):
return lng, lat
dlat = transformlat(lng - 105.0, lat - 35.0)
dlng = transformlng(lng - 105.0, lat - 35.0)
radlat = lat / 180.0 * pi
magic = math.sin(radlat)
magic = 1 - ee * magic * magic
sqrtmagic = math.sqrt(magic)
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
mglat = lat + dlat
mglng = lng + dlng
return [lng * 2 - mglng, lat * 2 - mglat]
def transformlat(lng, lat):
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
math.sin(2.0 * lng * pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(lat * pi) + 40.0 *
math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
math.sin(lat * pi / 30.0)) * 2.0 / 3.0
return ret
def transformlng(lng, lat):
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
math.sin(2.0 * lng * pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(lng * pi) + 40.0 *
math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
return ret
def out_of_china(lng, lat):
"""
判断是否在国内,不在国内不做偏移
:param lng:
:param lat:
:return:
"""
if lng < 72.004 or lng > 137.8347:
return True
if lat < 0.8293 or lat > 55.8271:
return True
return False
将需要定位的图片放到指定路径下,运行main.py
运行结果:
照片拍摄日期是:
2021-10-22
获取到经度、纬度是:115.46513298108795,38.83474699749353
他当前位置在:河北省保定市莲池区南大园乡朝阳南大街2166号长城家园南区
运行截图展示:
以上就是利用Python提取图片经纬度并锁定拍照地点的详细内容,更多关于Python提取图片经纬度的资料请关注盛行IT软件开发工作室其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。