Pythonはbing地図を取得して自分のTMSサービスを発表する(二)大量の瓦のアクセス問題を解決する
5433 ワード
ピラミッド構造の瓦の数はどのくらいですか
現在インターネットでよく使われているWebMecatorを例に挙げると第1層:256*256映像タイル4枚(JPGやPNGなど) 第2層:42 第3層:43 は、例えば、第1層から第18層までの瓦の総数(等比数列加算)91625968980個、約916億個を順次類推する.記憶空間推定は100 T近くである.
瓦がファイルシステムに直接格納される欠点ファイルシステムファイル数、サイズの制限 容易な移行、バックアップ 等 ソリューション
この問題は本質的に大量の小データの管理であり、多くのインターネット大手工場には比較的成熟した方案があり、具体的な状況に応じて選択調整すればよい.
スタンドアロンストレージ
sqliteを使用して複数のsqliteに格納され、sqliteファイル名は一意性を保証し、(row,column,level)に1つ1つ対応します.(row,column,level)は、QuadKey、または他の符号化方式 のような一意の数字に変換することができる. sqliteの移動と管理が便利です.
sqliteシングルファイルのサイズが大きすぎないように注意してください.
クラスタストレージ
HDFSなどのネットワーク化ストレージ方式を使用する.
一つの試験
最適化できる点が多いスレッドの使用方法を変更する .クエリー映像が存在するか否かの効率を向上させる . sqlite接続を確立する回数を減らす ソースコード
詳細は小欄記事:GISの家小欄を参照
記事の末尾にソースコードのダウンロードがあり、このコラムに興味があれば、注目してみてください.
現在インターネットでよく使われているWebMecatorを例に挙げると
瓦がファイルシステムに直接格納される欠点
この問題は本質的に大量の小データの管理であり、多くのインターネット大手工場には比較的成熟した方案があり、具体的な状況に応じて選択調整すればよい.
スタンドアロンストレージ
sqliteを使用して複数のsqliteに格納され、sqliteファイル名は一意性を保証し、(row,column,level)に1つ1つ対応します.
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(' ')
最適化できる点が多い
詳細は小欄記事:GISの家小欄を参照
記事の末尾にソースコードのダウンロードがあり、このコラムに興味があれば、注目してみてください.