【Python入门教程】获取图片可视化精准定位(逆地理编码)

发布时间 2023-06-06 18:33:51作者: RS然
  1. 使用exifread库读取图片的经纬度信息(WGS84坐标)
  2. 使用高德开放API将经纬度转为高德底图经纬度,并输出具体位置
  3. 使用folium库,以高德底图为基准,在网页上可视化显示地图和兴趣点

一、获取图片经纬度

        之前发过类似的文章,这里就不赘述了。下面代码中有相应注释。

def Get_LatLon(path_image):
    """
    :param path_image: 输入图片路径
    :return: 返回纬度、经度
    """
    # 获取图片的经纬度信息
    f = open(path_image, 'rb')
    contents = exifread.process_file(f)
    longitude = contents["GPS GPSLongitude"].values
    longitude_f = longitude[0].num/longitude[0].den + (longitude[1].num/longitude[1].den/60) + (longitude[2].num/longitude[2].den/3600)
    latitude = contents["GPS GPSLatitude"].values
    latitude_f = latitude[0].num/latitude[0].den + (latitude[1].num/latitude[1].den/60) + (latitude[2].num/latitude[2].den/3600)
    # print("经度:", longitude_f)  # contents['GPS GPSLatitudeRef']
    # print("纬度:", latitude_f)  # contents['GPS GPSLongitudeRef']
    f.close()
    return latitude_f, longitude_f

二、高德开放API将经纬度转为高德底图经纬度,并输出具体位置

1.注册账号,获取key

        打开高德开放平台,注册账号后点击控制台。点击我的应用,然后创建应用后就会得到一个key。对于地理编码官方也有说明文档,可以自行参考。

2.使用高德开放API将经纬度转为高德底图经纬度,并输出具体位置

def Get_address(latitude_f2, longitude_f2):
    """
    :param latitude_f2: 输入WGS84纬度
    :param longitude_f2: 输入WGS84经度
    :return: 返回地址、高德经纬度
    """
    key = '**********'
    # 高德地图api
    url_lonlat = f'https://restapi.amap.com/v3/assistant/coordinate/convert?locations=%s,%s&coordsys=gps' \
                 f'&output=json&key={key}' % (longitude_f2, latitude_f2)
    r_lonlat = requests.get(url_lonlat)
    gaode_lonlat = r_lonlat.json()['locations']
    # 获取高德经纬度
    url_address = f'https://restapi.amap.com/v3/geocode/regeo?output=json&location=%s&key={key}' \
                  f'&radius=1000&extensions=all' % gaode_lonlat
    r_address = requests.get(url_address)
    gaode_address = r_address.json()['regeocode']['formatted_address']
    # 获取经纬度对应的详细地址
    return gaode_address, gaode_lonlat

三、folium库以高德底图为基准在网页上可视化显示地图和兴趣点

def Show_map(address1, lonlat):
    """
    :param address1: 高德地址
    :param lonlat: 高德经纬度
    :return: 打开html,可视化地图
    """
    tiles1 = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
    # 高德底图api
    map_url = folium.Map([float(lonlat.split(',')[1]), float(lonlat.split(',')[0])],
                         tiles=tiles1,
                         attr="&copy; <a href=http://ditu.amap.com/>高德地图</a>",
                         zoom_start=15,
                         control_scale=True,
                         )
    # 底图的基本设置
    folium.Marker(
        location=[float(lonlat.split(',')[1]), float(lonlat.split(',')[0])],
        popup=folium.Popup('%s' % address1, max_width=20),
        icon=folium.Icon(color='red', icon='info-sign')  # 标记颜色图标
    ).add_to(map_url)
    # 添加标记点
    folium.Circle(
        radius=3000,
        location=[float(lonlat.split(',')[1]), float(lonlat.split(',')[0])],
        popup=folium.Popup('范围', max_width=20),
        color="crimson",
        fill=False,
    ).add_to(map_url)
    # 添加圆圈
    map_url.add_child(folium.ClickForMarker(popup="新点"))
    # 添加新点
    map_url.add_child(plugins.MeasureControl(position='topleft'))
    # 地图测距离
    map_url.add_child(folium.LatLngPopup())
    # 经纬度查询
    map_url.save('map.html')
    # 保存为html
    webbrowser.open('map.html')

四、完整代码

        记得自己修改key和图片路径!

# -*- coding: utf-8 -*-
"""
@Time : 2023/6/1 15:29
@Auth : RS迷途小书童
@File :Positioning based on images.py
@IDE :PyCharm
@Purpose :通过图片获取其准确位置并在网页上可视化
"""
import exifread
import requests
import folium
# 地图模块
import webbrowser
# 浏览器调用
from folium import plugins


def Get_LatLon(path_image):
    """
    :param path_image: 输入图片路径
    :return: 返回纬度、经度
    """
    # 获取图片的经纬度信息
    f = open(path_image, 'rb')
    contents = exifread.process_file(f)
    longitude = contents["GPS GPSLongitude"].values
    longitude_f = longitude[0].num/longitude[0].den + (longitude[1].num/longitude[1].den/60) + (longitude[2].num/longitude[2].den/3600)
    latitude = contents["GPS GPSLatitude"].values
    latitude_f = latitude[0].num/latitude[0].den + (latitude[1].num/latitude[1].den/60) + (latitude[2].num/latitude[2].den/3600)
    # print("经度:", longitude_f)  # contents['GPS GPSLatitudeRef']
    # print("纬度:", latitude_f)  # contents['GPS GPSLongitudeRef']
    f.close()
    return latitude_f, longitude_f


def Get_address(latitude_f2, longitude_f2):
    """
    :param latitude_f2: 输入WGS84纬度
    :param longitude_f2: 输入WGS84经度
    :return: 返回地址、高德经纬度
    """
    key = '*******'
    # 高德地图api
    url_lonlat = f'https://restapi.amap.com/v3/assistant/coordinate/convert?locations=%s,%s&coordsys=gps' \
                 f'&output=json&key={key}' % (longitude_f2, latitude_f2)
    r_lonlat = requests.get(url_lonlat)
    gaode_lonlat = r_lonlat.json()['locations']
    # 获取高德经纬度
    url_address = f'https://restapi.amap.com/v3/geocode/regeo?output=json&location=%s&key={key}' \
                  f'&radius=1000&extensions=all' % gaode_lonlat
    r_address = requests.get(url_address)
    gaode_address = r_address.json()['regeocode']['formatted_address']
    # 获取经纬度对应的详细地址
    return gaode_address, gaode_lonlat


def Show_map(address1, lonlat):
    """
    :param address1: 高德地址
    :param lonlat: 高德经纬度
    :return: 打开html,可视化地图
    """
    tiles1 = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
    # 高德底图api
    map_url = folium.Map([float(lonlat.split(',')[1]), float(lonlat.split(',')[0])],
                         tiles=tiles1,
                         attr="&copy; <a href=http://ditu.amap.com/>高德地图</a>",
                         zoom_start=15,
                         control_scale=True,
                         )
    # 底图的基本设置
    folium.Marker(
        location=[float(lonlat.split(',')[1]), float(lonlat.split(',')[0])],
        popup=folium.Popup('%s' % address1, max_width=20),
        icon=folium.Icon(color='red', icon='info-sign')  # 标记颜色图标
    ).add_to(map_url)
    # 添加标记点
    folium.Circle(
        radius=3000,
        location=[float(lonlat.split(',')[1]), float(lonlat.split(',')[0])],
        popup=folium.Popup('范围', max_width=20),
        color="crimson",
        fill=False,
    ).add_to(map_url)
    # 添加圆圈
    map_url.add_child(folium.ClickForMarker(popup="新点"))
    # 添加新点
    map_url.add_child(plugins.MeasureControl(position='topleft'))
    # 地图测距离
    map_url.add_child(folium.LatLngPopup())
    # 经纬度查询
    map_url.save('map.html')
    # 保存为html
    webbrowser.open('map.html')


if __name__ == "__main__":
    file_image = "G:/721_0211_W.jpeg"
    latitude_f1, longitude_f1 = Get_LatLon(file_image)
    # 输入图片路径,获取WGS84经纬度
    address, lonlat = Get_address(latitude_f1, longitude_f1)
    # 获取高德地址和经纬度
    Show_map(address, lonlat)
    # 在网页上可视化显示

 

本文章主要是分享个人在学习Python过程中写过的一些代码。有些部分参考了前人以及官网的教程,如有侵权请联系作者删除,大家有问题可以随时留言交流,博主会及时