import requests as req | |
import sys | |
from dateutil.parser import parse | |
from PIL import Image | |
from StringIO import StringIO | |
# hi8-fetch.py <date> <zoom level> <output> | |
# E.g.: hi8-fetch.py 2016-01-13T22:10:00 8 2016-01-13T221000-z8.png | |
# Fetch Himawari-8 full disks at a given zoom level. | |
# Valid zoom levels seem to be powers of 2, 1..16, and 20. | |
# | |
# To do: | |
# - Better errors (e.g., catch the "No Image" image). | |
# - Don't ignore seconds, and/or: | |
# - option to snap to nearest valid time. | |
# - Librarify. | |
# Tile size for this dataset: | |
width = 550 | |
height = 550 | |
time = parse(sys.argv[1]) | |
scale = int(sys.argv[2]) | |
out = sys.argv[3] | |
base = 'http://himawari8.nict.go.jp/img/D531106/%sd/550' % (scale) | |
tiles = [[None] * scale] * scale | |
def pathfor(t, x, y): | |
return "%s/%s/%02d/%02d/%02d%02d00_%s_%s.png" \ | |
% (base, t.year, t.month, t.day, t.hour, t.minute, x, y) | |
def fetch(session, path, retries=1, verbose=False, failure='error'): | |
# FIXME: this is kinda messy: | |
if retries < 0: | |
if failure == 'warning': | |
raise Warning('Could not download %s (filling with black)') | |
return np.zeros((width, height, 3)) | |
elif failure == 'silent': | |
return np.zeros((width, height, 3)) | |
else: # presumed failure == 'error': | |
raise IOError('Could not download %s') | |
try: | |
tiledata = session.get(path).content | |
tile = Image.open(StringIO(tiledata)) | |
return tile | |
except: | |
if verbose: | |
print('Retrying %s (%s retries left)' % (path, retries)) | |
return fetch( | |
session, | |
path, | |
retries=(retries - 1), | |
verbose=verbose, | |
failure=failure | |
) | |
sess = req.Session() # so requests will reuse the connection | |
png = Image.new('RGB', (width*scale, height*scale)) | |
for x in range(scale): | |
for y in range(scale): | |
path = pathfor(time, x, y) | |
tile = fetch(sess, path, retries=4, verbose=True, failure='error') | |
png.paste(tile, (width*x, height*y, width*(x+1), height*(y+1))) | |
png.save(out, 'PNG') |
This comment has been minimized.
This comment has been minimized.
@joe32097 check out the io library https://docs.python.org/3/library/io.html |
This comment has been minimized.
This comment has been minimized.
Any idea how to avoid or catch the "No Image" images? I've got this running every ten minutes and setting my desktop background. |
This comment has been minimized.
This comment has been minimized.
@willwhitney tiles in the "No Image" frames all have the same prev_tiledata = ""
for x in range(scale):
for y in range(scale):
# ...
if tiledata == prev_tiledata:
sys.exit(0)
prev_tiledata = tiledata
# ... I think I also read somewhere that the "No Image" frames happen at specific times, but this works for me. |
This comment has been minimized.
This comment has been minimized.
Nice, that's a solid answer. |
This comment has been minimized.
This comment has been minimized.
They happen at 02:40 and at 14:40 virtually every day, but they can also happen at other times because of maintenance or random errors, so it’s not enough to hard-code those times. |
This comment has been minimized.
If I am using py 3.5, how can I get StringIO. Are there any up-to-date-versions?