• Python 获取谷歌切片数据,在cesium上加载


    最近一直在做 “python 从入门到精通” 的学习,经过断断续续的学习,想着如何跟专业范围内的东西结合起来。现在分享一下如何从谷歌地图上下载切片数据,然后在cesium上加载。

    1 切片结构

    首先要搞清楚谷歌地图的切片结构。谷歌地图的整个范围是:南纬85.05到北纬85.05,东经180到西经180。切片的起点是北纬85.05°,东经180°。X轴与北纬85.05°重合,向右为正向。Y轴与东经180°重合,向下为正向。切片级别从0级开始,0级是一张图片,为全球的平面图。1级是有4张图片,也就是将0级的图沿中心“横竖”切一刀。顺着这个分发,每一级都是上一级的每一个图片沿中心“横竖”切一刀。如下图:
    0级
    1级
    2级

    从上图也可以看出,切片的每一级,都是由上一级的每一个切片一分为四形成的。那么就可以知道:
    每一级的切片数量:
    tile_count = 22*level
    其中 level为当前级别
    X方向每一行切片数量:
    tile_count_x = 2level
    Y方向每一列切片数量:
    tile_count_x = 2level

    2 地图地址

    谷歌地图的切片地址一般为:http://www.google.com/maps/vt?lyrs=s@815&gl=cn&x=&y=&z=
    其中x和y分别为切片坐标,z为切片的级别,例如 http://www.google.com/maps/vt?lyrs=s@815&gl=cn&x=0&y=0&z=0 表示0级下的第一张切片

    3 cesium 切片格式

    cesium中有一种自定义的地图provider,UrlTemplateImageryProvider,对应的url格式为url: ‘{z}/{x}/{y}’,其中z是缩放级别,x、y为坐标。那么根据这个结构,就可以在下载切片的时候创建对应的文件夹。

    4 python 下载

    1)循环每一个级别,分别下载

    def run(self, level):
            for i in range(level+1):
                # 创建当前级别的文件夹
                self.createLevelDir(self.level)
                # 下载切片
                self.levelDownPre(i)
                print(self.level)
                self.level+=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2)创建文件夹

    def createLevelDir(self, rpath):
            """
            创建文件夹
            :return: null
            """
            # TODO: 判断文件夹是否存在
            if not os.path.exists(str(rpath)):
                print(f'{str(rpath)} 文件夹不存在')
                os.mkdir(str(rpath))
                print(f'{str(rpath)} 文件夹创建成功')
                return True
            else:
                print(f'{str(rpath)} 文件夹已存在')
                return False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3)准备下载所需地址,文件

    def levelDownPre(self, level):
        """
        当前层级下,下载所有瓦片数据准备
        :param level: 当前层级
        :return
        """
        self.tile_count = 2**(2*level)
        # print(f'当前层级为:{level}, 瓦片总数为:{self.tile_count}')
        self.lines = 2**level
        self.tile_index = 0
        for i in range(self.lines):
            if self.createLevelDir(f'{self.level}/{i}'):
                for j in range(self.lines):
                    url = f'{self.base_url}{i}&y={j}&z={self.level}'
                    # print(f'瓦片坐标:({i},{j}), 瓦片地址:{url}')
                    self.rd.down(f'{self.level}/{i}/{j}.png', i, j, self.level)
                    print(f'第 {self.level} 级,({i},{j})个坐标,第{self.tile_index}/{self.tile_count}个瓦片')
                    self.tile_index+=1
                    time.sleep(0.5)
            else:
                print('当前瓦片已下载')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4)下载切片

    def down(self, path, x, y, z):
        self.url = self.base_url + f'{x}&y={y}&z={z}'
        try:
            urllib.request.urlretrieve(url=self.url, filename=path)
        except:
            print('请求被拒绝。。。重新开始')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5 切片数据

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    6 cesium加载

    下载完数据,就是在cesium中加载。这里做测试,把下载的数据放在项目本地。
    let xyzProvider = new Cesium.UrlTemplateImageryProvider({
    url: ‘data/xyz/{z}/{x}/{y}.png’,
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    maximumLevel: 5
    });
    this.viewer.imageryLayers.addImageryProvider(xyzProvider);
    在这里插入图片描述

    完整加载

  • 相关阅读:
    Jmeter使用
    java的集合
    【C语言】队列的实现
    JAVA:实现MaxHeap最大堆算法(附完整源码)
    Linux 安装apache
    编译器工程师眼中的好代码:Loop Interchange
    G. Path Prefixes 树上二分
    /LatestBuild: Operation not permitted
    java泛型
    sass和 scss的区别?
  • 原文地址:https://blog.csdn.net/u014328243/article/details/126758612