首页 > 编程语言 >【Python&RS】基于矢量范围批量下载遥感瓦片高清数据(天地图、高德、谷歌等)

【Python&RS】基于矢量范围批量下载遥感瓦片高清数据(天地图、高德、谷歌等)

时间:2023-12-29 21:33:53浏览次数:38  
标签:RS Python image zoom Windows str 瓦片 tile 高德

        这个是之前写的代码了,正好今天有空所以就和大家分享一下。我们在处理项目时,有时候需要高清底图作为辅助数据源去对比数据,所以可能会需要卫星数据。所以今天就和大家分享一下如何使用Python基于矢量范围批量下载高清遥感瓦片数据。

1 读取矢量边界

        这里我们使用osgeo中的osr、ogr库去读取矢量的地理范围。之前也分享过,感兴趣的可以去Python&GIS专栏里面看一看。

def Open_Vector(path_shp):
    """
    :param path_shp: 输入84坐标矢量
    :return: 返回四至范围
    """
    ds = ogr.Open(path_shp, True)
    # True表示以读写方式打开
    layer = ds.GetLayer(0)
    # 获取图层
    feature = layer.GetFeature(0)
    geom = feature.GetGeometryRef()
    # 获取该要素的地理空间范围
    left, right, down, up = geom.GetEnvelope()
    # 获取图层的地理范围
    return left, right, down, up

2 通过经纬度计算航带数

        这里没什么好说的,就是基础的公式,计算即可。这个函数在整个函数作为辅助函数,主程序会自己调用它。

def calculation_tile(lat, lon, zoom):
    """
    :param lat: 84坐标纬度
    :param lon: 84坐标经度
    :param zoom: 缩放级别
    :return: 瓦片的行列号
    """
    # 将经纬度从WGS84坐标系转换为GCJ02坐标系
    # lon_deg,lat_deg = WGS84_To_GCJ02(lon_deg,lat_deg)
    # 根据缩放级别计算格网数量
    n = 2.0 ** zoom
    # 将纬度从度转换为弧度
    lat_radio = math.radians(lat)
    # 计算瓦片中的x坐标
    tile_x = int((lon + 180.0) / 360.0 * n)
    # 计算瓦片中的y坐标
    tile_y = int((1.0 - math.log(math.tan(lat_radio) + (1 / math.cos(lat_radio))) / math.pi) / 2.0 * n)
    # 返回计算得到的瓦片坐标(行和列)
    return tile_x, tile_y 

3 获取瓦片下载链接

        这里使用了基础的反爬虫方法,随机调用请求头。

def Get_image(url, x, y):
    agents = [
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.24 Safari/535.1',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.27 (KHTML, like Gecko) Chrome/12.0.712.0 Safari/534.27',
        'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari'
        '/537.36',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari'
        '/532.5',
        'Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.310.0 Safari'
        '/532.9',
        'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari'
        '/534.7',
        'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 '
        'Safari/534.14',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 '
        'Safari/534.14',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 '
        'Safari/534.20',
        ]
    try:
        # 打印下载成功的消息,显示瓦片的位置和下载状态
        print("瓦片" + str(x) + '_' + str(y) + '下载成功')
        # 创建一个请求对象,使用指定的URL
        requests = urllib.request.Request(url)
        # 为请求添加一个随机的User-Agent头,以模拟不同的浏览器或客户端
        requests.add_header('User-Agent', random.choice(agents))  # 换用随机请求头
        # 使用指定的请求打开URL,并设置超时时间为60秒
        image = urllib.request.urlopen(requests, timeout=60)
        # 读取返回的图像数据
        image_io = image.read()
        # 使用BytesIO将图像数据转换为可处理的字节流对象
        image_bytes = io.BytesIO(image_io)
        # 使用PIL库打开图像
        image = Image.open(image_bytes)
        # 将图像从RGB格式转换为BGR格式(OpenCV需要的格式)
        image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
    except EOFError:
        # 如果发生EOFError(可能由于网络问题、超时等),打印下载失败的消息并尝试重试
        print("瓦片" + str(x) + '_' + str(y) + '下载失败,正在重试......')
        Get_image(url, x, y)  # 递归调用Get_image函数进行重试
    # 返回处理后的图像数据
    return image

4 主程序

        这里就不过多解释了,我的代码注释非常完善,如果有什么不懂的,直接留言即可。

# -*- coding: utf-8 -*-
"""
@Time : 2023/4/9 14:37
@Auth : RS迷途小书童
@File :Vector Download Remote Sensing Tile Data.py
@IDE :PyCharm
@Purpose:根据矢量范围下载三方地图瓦片
@Web:博客地址:https://blog.csdn.net/m0_56729804
"""
import io
import cv2
import math
import random
import numpy as np
from osgeo import ogr
import urllib.request
from PIL import Image


def Write_image(lat1, lon1, lat2, lon2, out_path):
    """
    :param lat1: 左上角纬度
    :param lon1: 左上角经度
    :param lat2: 右下角纬度
    :param lon2: 右下角经度
    :return: 返回瓦片影像
    """
    zooms = list()
    # 创建一个空列表zooms,用于存储所有的缩放级别
    for i in range(1, 19):
        # 循环缩放级别
        col = calculation_tile(lat1, lon1, i)
        # 将经纬度转换为对应的地图瓦片编号,结果存储在col中
        row = calculation_tile(lat2, lon2, i)
        if col[0] - row[0] == 0 or col[1] - row[1] == 0:
            continue
        else:
            zooms.append(i)
            # 如果差值不为0,将当前的缩放级别i添加到zooms列表中
    zoom = zooms[-1]
    # 获取zooms列表中的最后一个元素,即最大的缩放级别,并存储在zoom变量中
    left_up = calculation_tile(lat1, lon1, zoom)
    # 使用最大的缩放级别和第一个经纬度范围,调用函数获取左上角的地图瓦片编号,存储在left_up中
    right_down = calculation_tile(lat2, lon2, zoom)
    # 使用最大的缩放级别和第二个经纬度范围,调用函数获取右下角的地图瓦片编号,存储在right_down中
    images_columns = list()
    # 创建一个空列表images_columns,用于存储所有的地图瓦片图像列
    print("当前瓦片行数:", right_down[0]-left_up[0])
    print("当前瓦片列数:", right_down[1] - left_up[1])
    print("--------------------------------------数据获取--------------------------------------")
    for x in range(left_up[0], right_down[0]):
        # 循环行
        images_rows = list()
        # 创建一个空列表images_rows,用于存储所有的地图瓦片图像行
        for y in range(left_up[1], right_down[1]):
            # 循环列
            tile_url = 'http://t4.tianditu.com/DataServer?T=img_w&x='+str(x)+'&y='+str(y)+'&l='+str(zoom) + \
                       '&tk=45c78b2bc2ecfa2b35a3e4e454ada5ce'
            image = Get_image(tile_url, x, y)
            cv2.imwrite(out_path + "/%s.jpg" % (str(x)+"_"+str(y)), image)
            images_rows.append(image)
            # 将获取到的瓦片图像添加到images_rows列表中,用于后续的图像合成
        img_column_new = np.vstack(images_rows)
        # 使用NumPy的v stack函数,将images_rows列表中的所有图像竖直堆叠起来,形成一个新的图像列
        images_columns.append(img_column_new)
        # 将这个新的图像列添加到images_columns列表中,用于后续的图像合成
    print("正在拼接瓦片数据......")
    result = np.hstack(images_columns)
    # 使用NumPy的h stack函数,将images_columns列表中的所有图像水平堆叠起来,形成一个最终的大图像
    print("正在保存瓦片数据......")
    cv2.imwrite(out_path + "/result.jpg", result)
    return result

5 总结

""" 
tile_url = 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i'+str(zoom)+'!2i'+str(x)+'!3i'+str(y)+'!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'
# Google地图瓦片
tile_url = 'http://mt3.google.cn/vt/lyrs=s@110&hl=zh-CN&gl=cn&src=app&x='+str(x)+'&y='+str(y)+'&z='+str(zoom)+'&s=G'
# Google影像瓦片
tile_url = 'http://t4.tianditu.com/DataServer?T=img_w&x='+str(x)+'&y='+str(y)+'&l='+str(zoom)+'&tk=45c78b2bc2ecfa2b35a3e4e454ada5ce'
# 天地图卫星数据,vec_w电子地图(2000坐标系)
"http://wprd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scl=1&style=6&x=" + str(x) + "&y=" + str(y) + "&z=" + str(zoom) + "&ltype=3"
# 高德底图,偏移(火星坐标系)
"""

        这里输入的矢量需要是WGS84坐标系的经纬度,不能是投影坐标系哦。此外如果使用高德、百度等底图可能会有一定的偏移,因为我国需要加密成火星坐标系,但是还是可以用的。天地图就无所谓,它的坐标是准的。

标签:RS,Python,image,zoom,Windows,str,瓦片,tile,高德
From: https://www.cnblogs.com/RSran/p/17935717.html

相关文章

  • Microsoft 365开发:如何通过Powershell调整外部用户访问的有效期
    Blog链接:https://blog.51cto.com/13969817用户在分享文档时,应该根据实际情况设置合理的访客访问有效期,从而保护文档的安全性和完整性,具体原因如下:·      保护文档内容:限制访问有效期可以防止文档被无限制地访问和使用,从而保护文档的内容不被泄露或滥用·      保证......
  • 【python爬虫课程设计】从懂球帝爬取中超联赛知名运动员数据+数据可视化
    一、选题背景:中超联赛作为中国顶级足球赛事,吸引了广泛的关注,其球员数据包含了丰富的信息,涵盖球员技术、表现和比赛策略等方面。随着数据科学技术的不断发展,对于足球俱乐部和教练来说,充分利用这些数据进行分析和挖掘,以制定更有效的战术和管理策略变得愈发重要。选题背景重点:1.数......
  • python反编译全流程
    [NISACTF2022]ezpython1、将exe文件转换为pyc文件格式此题附件下载下来后为exe文件格式,我们需要用到pyinstxtractor.py这个工具来将exe文件转成pyc格式在pyinstxtractor.py的文件夹中cmd,输入pythonpyinstxtractor.py文件名2、修改magicnumber经过以上操作后会生成一个......
  • 【Python数据分析课程设计】大数据分析—Pokemon 1996-2022年各世代宝可梦数据集分析
    一、选题背景宝可梦是一种受欢迎的媒体内容和游戏系列,由任天堂、GameFreak和Creatures等公司合作开发。它们是虚构的生物角色,具有各种不同的属性、技能和能力。自1996年首次推出以来,宝可梦已经成为全球范围内的文化现象。宝可梦不仅仅是娱乐产品,它们也在社会中产生了广泛的影响: ......
  • RSA算法学习
    RSA算法学习介绍:RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(RonRivest)、阿迪·萨莫尔(AdiShamir)和伦纳德·阿德曼(LeonardAdleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA......
  • ubuntu16下升级python3的版本--升级到3.8
    ubuntu16下升级python3的版本,这里是升级到3.8。1.首先添加安装源,在命令行输入如下命令:$sudoadd-apt-repositoryppa:jonathonf/python-3.82.更新apt$sudoaptupdate3.更新安装源后,通过apt安装Python3.8$sudoapt-getinstallpython3.84.安装完成之后,设置Python3.8的......
  • Maximum And Queries (hard version)
    题目传送门感觉这题比\(\rmF\)难啊,\(\rmF\)就是个板子,但为啥这题是蓝的,\(\rmF\)是紫的。思路首先考虑\(nq\)怎么做。发现很简单,按位贪心就行了。具体地说,从大到小枚举二进制位,判断答案中能否出现这一位,若\(i\)当前这一位没有值,那么必须被补全到这个值,否则无所谓,然......
  • 30 RS485串口程序收发环路设计
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录米联客(MiLianKe)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!1概述在前面的课程中,我们已经学习了UART串口程序的设计,在工业场合为了提高串口的抗干扰能力,以及传输距离,RS4......
  • 使用Pipenv进行Python虚拟环境管理--conda平替
    Pipenv使用教程Anaconda是一个开箱即用的Python开发环境,同时也包含虚拟环境管理工具conda。但是Anaconda的缺点包括:大型安装包:Anaconda的安装包相对较大,需要消耗较多的磁盘空间。依赖冲突:在使用Anaconda时,若安装包过多可能会出现依赖冲突的情况,需要手动解决。此时则......
  • Python+Selenium+Pytest+Allure+Jenkins实现的Web自动化框架
    目录一、测试的项目二、需求分析三、用例设计-部分用例举例四、框架说明4.1测试框架结构图如下:4.2项目功能五、代码设计与功能说明5.1POM简介:PageObjectModle页面对象模型5.2基础封装层:pages/basePage.py5.3PO页面对象层:pages/userLoginPage.py5.4TestCase测试用例层:testc......