python图片定位坐标,python获取照片的地点

  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 os

  import 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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: