Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
script to process the Miniscale dataset from the Ordnance Survey
#!/usr/bin/env python3
# NOTE: I downloaded the "MiniScale" dataset from the Ordnance Survey, see:
# * https://www.ordnancesurvey.co.uk/business-government/products/miniscale
# This gave me the "minisc_gb.zip" file that is used here.
# Import standard modules ...
import io
import json
import os
import zipfile
# Import special modules ...
try:
import PIL
import PIL.Image
import PIL.TiffTags
except:
raise Exception("run \"pip install --user Pillow\"")
# Import my modules ...
try:
import pyguymer3
except:
raise Exception("you need to have the Python module from https://github.com/Guymer/PyGuymer3 located somewhere in your $PYTHONPATH")
# Configure PIL to open images up to 1 GiP ...
PIL.Image.MAX_IMAGE_PIXELS = 1024 * 1024 * 1024 # [px]
# Initialize dictionary ...
meta = {}
# Make folders if they are missing ...
for dname in ["miniscale/colour", "miniscale/greyscale"]:
if not os.path.exists(dname):
os.makedirs(dname)
# Load dataset ...
with zipfile.ZipFile("minisc_gb.zip", "r") as zObj:
# Loop over members ...
for tif in zObj.namelist():
# Skip this member if it is not a data TIF ...
if "/RGB_TIF_compressed/" not in tif or not tif.lower().endswith(".tif"):
continue
# Extract view name ...
view = os.path.basename(tif)[:-4]
# Deduce colour and greyscale PNG names and skip this member if they
# both exist ...
png1 = os.path.join("miniscale/colour", view + ".png")
png2 = os.path.join("miniscale/greyscale", view + ".png")
if os.path.exists(png1) and os.path.exists(png2):
continue
print("Making \"{:s}\" ...".format(view))
# Read data TIF into RAM so that it becomes seekable ...
# NOTE: https://stackoverflow.com/a/12025492
tObj = io.BytesIO(zObj.read(tif))
# Load data TIF as RGB image ...
with PIL.Image.open(tObj) as img:
# Loop over data TIF metadata and populate the dictionary with the
# data TIF's extent ...
# NOTE: The tie point is the upper-left corner of the data TIF and
# Cartopy wants the lower-left corner.
dx, dy = None, None # [m/px], [m/px]
xmin, xmax, ymin, ymax = None, None, None, None # [m], [m], [m], [m]
for key, val in img.tag.items():
if PIL.TiffTags.TAGS[key] == "ModelPixelScaleTag":
dx, dy = val[0], val[1] # [m/px], [m/px]
if PIL.TiffTags.TAGS[key] == "ModelTiepointTag":
xmin, ymax = val[3], val[4] # [m], [m]
if dx is None or dy is None:
raise Exception("failed to extract \"ModelPixelScaleTag\"")
if xmin is None or ymax is None:
raise Exception("failed to extract \"ModelTiepointTag\"")
xmax = xmin + img.size[0] * dx # [m]
ymin = ymax - img.size[1] * dy # [m]
meta[view] = {
"colour" : png1,
"greyscale" : png2,
"extent" : [xmin, xmax, ymin, ymax]
}
# Save PNGs ...
img.convert("RGB").save(png1, optimize = True)
img.convert("L").save(png2, optimize = True)
pyguymer3.optimize_image(png1, strip = True)
pyguymer3.optimize_image(png2, strip = True)
# Save JSON ...
json.dump(
meta,
open("miniscale.json", "wt"),
ensure_ascii = False,
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.