Python获取 bing 地图发布自己的 TMS 服务(二)解决海量瓦片存取问题
金字塔结构的瓦片数量有多大
以目前互联网常用的WebMecator为例
- 第一层:4幅256*256影像瓦片(JPG或PNG等)
- 第二层:42
- 第三层:43
- 依次类推
比如计算第1层至第18层的瓦片总数目(等比数列求和)91625968980个,大约916亿。存储空间估算在近百T。
瓦片直接存储在文件系统中的缺点
- 文件系统对文件数量、大小的限制
- 不易迁移、备份
- 等等
解决方案
这个问题本质上是对海量小数据的管理,很多互联网大厂都有比较成熟的方案,只需要根据具体情况进行选择调整即可。
单机存储
采用sqlite
存储在多个sqlite中,sqlite文件名保证了唯一性,与(row,column, level)一一对应。
- (row,column, level)可以转为唯一数字,比如QuadKey,或者其他编码方式
- sqlite移动与管理就比较方便。
注意sqlite单文件的大小不要太大。
集群存储
使用HDFS等网络化存储方案。
一个试验
# -*- coding: utf-8 -*-
"""下载区域影像
从第一层到指定层 多线程版 存储到sqlite中 """ import requests
# python3的thread模块
import _thread
import random
import time
from random import random
import os.path
import QuadKey.quadkey as quadkey
import shutil
import secrets as secrets import sqlite_util as dbutil # 下载的最细层
tileZoom = 10
rootTileDir = "tiles_db" # 分的db数量,采用质数 db_num = 1511
lat_min = -90
lat_max = 90
lon_min = -180
lon_max = 180
# MS doesn't want you hardcoding the URLs to the tile server. This request asks for the Aerial
# url template. Replace {quadkey}
response = requests.get("https://dev.virtualearth.net/REST/V1/Imagery/Metadata/Aerial?key=%s" % (secrets.bingKey)) # 返回结果
data = response.json()
print(data) # grabs the data we need from the response.
# 例如:http://ecn.{subdomain}.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=7786
tileUrlTemplate = data['resourceSets'][0]['resources'][0]['imageUrl']
# 例如:['t0', 't1', 't2', 't3']
imageDomains = data['resourceSets'][0]['resources'][0]['imageUrlSubdomains'] if (os.path.exists(rootTileDir) == False):
os.mkdir(rootTileDir) bingTilesDir = os.path.join(rootTileDir, "bing") if (os.path.exists(bingTilesDir) == False):
os.mkdir(bingTilesDir) def get_tiles_by_pixel(tilePixel):
"""
下载该点之上的瓦片 :param lat:
:param lon:
:return:
""" """get pixel coordinates"""
# tilePixel = quadkey.TileSystem.geo_to_pixel((lat, lon), tileZoom) # print(tilePixel) pixel = tilePixel
geo = quadkey.TileSystem.pixel_to_geo(pixel, tileZoom)
# 计算四键
qk = quadkey.from_geo(geo, tileZoom) # 四键
qkStr = str(qk) #
qkArray = []
for index in range(tileZoom):
qkArray.append(qkStr[0:index + 1]) print(qkArray)
# 存放路径
for qk in qkArray:
# db位置
dbPath = "%s/%s.db" % (bingTilesDir, int(qk) % db_num )
print(dbPath) if (os.path.exists(dbPath) == False):
# os.mkdir(dbPath)
dbutil.create_db(dbPath) # 下载影像 if (dbutil.is_exists(dbPath, qk)):
# already downloaded
dbutil.save_images(dbPath, qk)
ok = 1
else:
print("下载中", end='') url = tileUrlTemplate.replace("{subdomain}", imageDomains[0])
url = url.replace("{quadkey}", qk)
url = "%s&key=%s" % (url, secrets.bingKey) response = requests.get(url, stream=True)
print(response)
dbutil.insert(dbPath, qk, response.content) del response
# 强制睡一会,防止bing服务器限制
sleepTime = random() * 3
time.sleep(sleepTime) # 左上为原点
tilePixelMax = quadkey.TileSystem.geo_to_pixel((lat_max, lon_max), tileZoom)
tilePixelMin = quadkey.TileSystem.geo_to_pixel((lat_min, lon_min), tileZoom)
print(tilePixelMax)
print(tilePixelMin) tile_pixel_list = [] for x in range(tilePixelMin[0], tilePixelMax[0], 256):
for y in range(tilePixelMax[1], tilePixelMin[1], 246):
tile_pixel_list.append((x, y)) # 取决与服务器的硬件性能
thread_pause = 30
for i in range(len(tile_pixel_list)):
print("处理"+str(i))
_thread.start_new_thread(get_tiles_by_pixel,(tile_pixel_list[i],) ) if(i % thread_pause == (thread_pause-1)):
print("让正常运行的线程执行完,睡眠开始")
time.sleep(5)
print("睡眠结束") # _thread.start_new_thread( get_tiles_by_pixel, ( ) ) print('下载完毕')
可以优化的点很多
- 修改线程使用方式
- 提高查询影像是否存在的效率
- 减少建立sqlite连接的次数
源码
更多的详情见小专栏文章:GIS之家小专栏
文章尾部提供源代码下载,对本专栏感兴趣的话,可以关注一波
Python获取 bing 地图发布自己的 TMS 服务(二)解决海量瓦片存取问题的更多相关文章
- python获取bing地图发布自己的TMS服务(一)下载瓦片
部分结果 bing地图瓦片使用QuadKey作为命名方式. QuadKey简介 如何计算quadkey 在给定level下,把行号tileY和列号tileX转换为2进制,然后行列交叉存储,再转换为4进 ...
- geotrellis使用(三十一)使用geotrellis直接将GeoTiff发布为TMS服务
前言 传统上我们需要先将Tiff中存储的影像等数据先切割成瓦片,而后再对外提供服务.这样的好处是服务器响应快,典型的用空间来换时间的操作.然而这样造成的问题是空间的巨大浪费,一般情况下均需要存储1-1 ...
- geotrellis使用(三十二)大量GeoTiff文件实时发布TMS服务
前言 在上一篇文章中我讲了如何直接将Geotiff文件发布为TMS服务,在其中只讲了单幅Geotiff的操作,其实单幅这种量级的数据对Geotrellis来说就是杀鸡焉用牛刀,Geotrellis针对 ...
- 获取bing每日图片
http://global.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US 其中idx表示倒数第几张图片 ...
- 使用Python获取Linux系统的各种信息
哪个Python版本? 当我提及Python,所指的就是CPython 2(准确的是2.7).我会显式提醒那些相同的代码在CPython 3 (3.3)上是不工作的,以及提供一份解释不同之处的备选代码 ...
- 获取bing图片并自动设置为电脑桌面背景(C++完整开源程序)
众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸. 我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是: 上网,搜索bing 找 ...
- Python爬取地图瓦片
由于要在内网开发地图项目,不能访问在线的地图服务了,就想把地图瓦片下载下来,网上找了一些下载器都是需要注册及收费的,否则下载到的图都是打水印的,如下: 因为地图瓦片就是按照层级.行.列规则组织的一张张 ...
- 【开源程序(C++)】获取bing图片并自动设置为电脑桌面背景
众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸. 我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是: 上网,搜索bing 找 ...
- python提取百度经验<标题,发布时间,平均流量,总流量,具体的链接>
之前想研究下怎么抓网页数据.然后就有了下面的练习了. 如有BUG.也纯属正常. 只是练习.请勿投入产品使用. #!/usr/bin/python # -*- coding: utf-8 -*- #Fi ...
随机推荐
- python模块——socket
实例一. server: #socket套接字(IP + 端口号)(qq,wechat 发送接收消息依靠socket模块),cs架构import socketserver = socket.socke ...
- Linux命令实战(五)
1.显示/etc目录下,以非字母开头,后面跟了一个字母以及其他任意长度字符的文件或目录. [qiuhom@test ~]$ls -d /etc/[^[:alpha:]][[:alpha:]]* ls: ...
- linux系统LNMP环境部署
源码安装 nginx# yum -y install gcc openssl-devel# useradd -s /sbin/nologin nginx# tar xf nginx-1.14.0.ta ...
- Windows下Apache与PHP的安装与配置
下载Apache Apache的官网(http://httpd.apache.org) 1.把解压后的Apache拷贝到要安装的目标位置.建议拷贝到C盘根目录下,因为这是其默认设置. 2.我选择的是拷 ...
- C++中对C的扩展学习新增语法——强制类型转换
类型转换:主要进行指针类型转换,因为在C++中,不同类型指针不允许隐式转换,任何一个程序中如果出现了大量的类型转换,说明该程序不是太好的程序. 注意事项: 不同类型指针不允许隐式转换: void* 类 ...
- C语言1博客作业06
这个作业属于哪个课程 C语言程序设计II 这个作业的要求在哪里 https://www.cnblogs.com/sanying/p/11771502.html 我在这个课程的目标是 端正态度,认真对待 ...
- js数组之sort()函数
一般我们使用sort函数进行数组的排序,sort()方法有一个可选参数,是用来确定元素顺序的函数.如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序.如: var arr = [&q ...
- centos7 设置连接无线wifi
安装系统后,首先要联网. 1.首先使用网线连接,之后尝试ping www.baidu.com我的是自动通的 2.需要查看网卡型号,先安装工具 yum -y install pciutils* 3.查看 ...
- 【python测试开发栈】python内存管理机制(一)—引用计数
什么是内存 在开始进入正题之前,我们先来回忆下,计算机基础原理的知识,为什么需要内存.我们都知道计算机的CPU相当于人类的大脑,其运算速度非常的快,而我们平时写的数据,比如:文档.代码等都是存储在磁盘 ...
- Java流程控制之(四)中断
目录 break continue return 标签 在程序设计时,循环直接的跳转显得十分重要,虽然Java没有提供goto语句去控制程序的跳转,但为了控制循环,Java提供了continue,br ...