Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/usr/bin/env python
# Define the background image datasets ...
imgs = {
"cross-blend-hypso" : {
"description" : "Cross-blended Hypsometric Tints with Relief, Water, Drains and Ocean Bottom from Natural Earth",
"rasters" : {
"large" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/HYP_HR_SR_OB_DR.zip",
"medium" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/HYP_LR_SR_OB_DR.zip",
"small" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/raster/HYP_50M_SR_W.zip",
},
"source" : "http://www.naturalearthdata.com/downloads/10m-raster-data/10m-cross-blend-hypso/ and http://www.naturalearthdata.com/downloads/50m-raster-data/50m-cross-blend-hypso/",
},
"gray-earth" : {
"description" : "Gray Earth with Shaded Relief, Hypsography, Ocean Bottom and Drainages from Natural Earth",
"rasters" : {
"large" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/GRAY_HR_SR_OB_DR.zip",
"medium" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/GRAY_LR_SR_OB_DR.zip",
"small" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/raster/GRAY_50M_SR_OB.zip",
},
"source" : "http://www.naturalearthdata.com/downloads/10m-raster-data/10m-gray-earth/ and http://www.naturalearthdata.com/downloads/50m-raster-data/50m-gray-earth/",
},
"natural-earth-1" : {
"description" : "Natural Earth I with Shaded Relief, Water and Drainages from Natural Earth",
"rasters" : {
"large" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/NE1_HR_LC_SR_W_DR.zip",
"medium" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/NE1_LR_LC_SR_W_DR.zip",
"small" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/raster/NE1_50M_SR_W.zip",
},
"source" : "http://www.naturalearthdata.com/downloads/10m-raster-data/10m-natural-earth-1/ and http://www.naturalearthdata.com/downloads/50m-raster-data/50m-natural-earth-1/",
},
"natural-earth-2" : {
"description" : "Natural Earth II with Shaded Relief, Water and Drainages from Natural Earth",
"rasters" : {
"large" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/NE2_HR_LC_SR_W_DR.zip",
"medium" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/NE2_LR_LC_SR_W_DR.zip",
"small" : "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/raster/NE2_50M_SR_W.zip",
},
"source" : "http://www.naturalearthdata.com/downloads/10m-raster-data/10m-natural-earth-2/ and http://www.naturalearthdata.com/downloads/50m-raster-data/50m-natural-earth-2/",
},
"shaded-relief" : {
"description" : "Shaded Relief Basic from Natural Earth",
"rasters" : {
"large" : "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/SR_HR.zip",
"medium" : "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/raster/SR_LR.zip",
"small" : "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/raster/SR_50M.zip",
},
"source" : "https://www.naturalearthdata.com/downloads/10m-raster-data/10m-shaded-relief/ and https://www.naturalearthdata.com/downloads/50m-raster-data/50m-shaded-relief/",
},
}
# Import modules ...
import json
import os
import requests
import subprocess
import zipfile
# Import my module ...
try:
import pyguymer
except:
raise Exception("you need to have the Python module from https://github.com/Guymer/PyGuymer located somewhere in your $PYTHONPATH")
# Create JSON dictionary ...
data = {}
data["__comment__"] = "JSON file specifying the image to use for a given type/name and resolution. Read in by cartopy.mpl.geoaxes.read_user_background_images."
# ******************************************************************************
# * CREATE PNG IMAGES FROM REMOTE SOURCES *
# ******************************************************************************
# Start session ...
sess = requests.Session()
sess.allow_redirects = True
sess.max_redirects = 5
# Loop over background image datasets ...
for img in imgs.iterkeys():
# Add to JSON dictionary ...
data[img] = {}
data[img]["__comment__"] = imgs[img]["description"]
data[img]["__projection__"] = "PlateCarree"
data[img]["__source__"] = imgs[img]["source"]
# Loop over sizes ...
for size in imgs[img]["rasters"].iterkeys():
# Deduce ZIP file name and download it if it is missing ...
zfile = "{0:s}_{1:s}.zip".format(img, size)
if not os.path.exists(zfile):
print "Downloading \"{0:s}\" ...".format(zfile)
if not pyguymer.download_file(sess, imgs[img]["rasters"][size], zfile):
raise Exception("download failed", imgs[img]["rasters"][size])
# Deduce TIF file name and extract it if is missing ...
tfile = "{0:s}_{1:s}.tif".format(img, size)
if not os.path.exists(tfile):
print "Extracting \"{0:s}\" ...".format(tfile)
with zipfile.ZipFile(zfile, "r") as zobj:
for member in zobj.namelist():
if member.lower().endswith(".tif"):
tmp = zobj.extract(member)
os.rename(tmp, tfile)
break
# Deduce PNG file name and convert TIF to PNG if it is missing ...
pfile = "{0:s}_{1:s}.png".format(img, size)
if not os.path.exists(pfile):
print "Creating \"{0:s}\" ...".format(pfile)
subprocess.check_call(
["convert", tfile, pfile],
stderr = open(os.devnull, "wt"),
stdout = open(os.devnull, "wt")
)
subprocess.check_call(
["optipng", pfile],
stderr = open(os.devnull, "wt"),
stdout = open(os.devnull, "wt")
)
# Add to JSON dictionary ...
data[img][size] = pfile
# End session ...
sess.close()
# ******************************************************************************
# * CREATE DOWNSCALED PNG IMAGES FROM LOCAL SOURCES *
# ******************************************************************************
# Loop over background image datasets ...
for img in imgs.iterkeys():
# Loop over sizes ...
for size in imgs[img]["rasters"].iterkeys():
# Deduce PNG file name ...
pfile1 = "{0:s}_{1:s}.png".format(img, size)
# Loop over downscaled sizes ...
for width in [512, 1024, 2048, 4096]:
# Deduce downscaled PNG file name and create it if missing ...
pfile2 = "{0:s}_{1:s}{2:04d}px.png".format(img, size, width)
if not os.path.exists(pfile2):
print "Creating \"{0:s}\" ...".format(pfile2)
subprocess.check_call(
["convert", pfile1, "-resize", "{0:d}x".format(width), pfile2],
stderr = open(os.devnull, "wt"),
stdout = open(os.devnull, "wt")
)
subprocess.check_call(
["optipng", pfile2],
stderr = open(os.devnull, "wt"),
stdout = open(os.devnull, "wt")
)
# Add to JSON dictionary ...
data[img]["{0:s}{1:04d}px".format(size, width)] = pfile2
# Save JSON dictionary ...
open(
"images.json",
"wt",
).write(
json.dumps(
data,
indent = 4,
sort_keys = True
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.