Skip to content

Commit

Permalink
Implements tiling of all layers (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
gampleman authored Apr 3, 2019
1 parent 5adc7e0 commit 6e046e1
Show file tree
Hide file tree
Showing 70 changed files with 1,807 additions and 17,065 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
yarn.lock
.DS_Store
node_modules/
dist/
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,6 @@ A `color` value. You can interpolate based on zoom or using data-driven styling

A `color` value. You can interpolate based on zoom. The color of an outline drawn around the arrow. Defaults to transparent.

## Limitations

3. Datasource tiling isn't implemented.

## Data

This visualization is designed to visualize wind speed data based on a regular grid - such that is typically available from forecast models. This data is encoded in a texture in [plate carrée](https://en.wikipedia.org/wiki/Equirectangular_projection) projection where the R channel corresponds to x (or u), and the G channel corresponds to y (or v). However, these encodings are relative to the total observed range which must be encoded in an accompanying JSON file:
Expand Down
69 changes: 18 additions & 51 deletions data/gfswind2png.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ def build_meta_json(data_dir, datetime, width, height, umin, umax, vmin, vmax):
"vMax": round(vmax, 2),
"minzoom": 0,
"maxzoom": 2,
"tiles": [f"{data_dir}/{{z}}/{{x}}/{{y}}.png"],
"tiles": [f"{{z}}/{{x}}/{{y}}.png"],
}


def write_json(data_dir, json_output):
with open(f"{data_dir}tile.json", "w") as f:
f.write(json.dumps(json_output, indent=4, separators=(",", ": ")))
with open(os.path.join(data_dir, "tile.json"), "w") as f:
f.write(json.dumps(json_output))


def write_image(filename, image):
Expand Down Expand Up @@ -153,8 +153,11 @@ def slice_image(image, start_y, end_y, start_x, end_x):

tilejson_variables = {}

tilejson_variables["height"] = 180
tilejson_variables["width"] = 360
height = 180
width = 360

tilejson_variables["height"] = height
tilejson_variables["width"] = width

try:
tilejson_variables["datetime"] = datetime.strptime(
Expand All @@ -163,9 +166,9 @@ def slice_image(image, start_y, end_y, start_x, end_x):
except ValueError as e:
raise ValueError("Invalid timestamp entered.") from e

for product in ("1p00", "0p50", "0p25"):
filename = f"{args.output_dir}{args.timestamp}_{product}.grb"
for product, zoom in [("1p00", 0), ("0p50", 1), ("0p25", 2)]:
filename = os.path.join(args.output_dir, f"{args.timestamp}_{product}.grb")

# TODO: can probably streamline these steps without saving intermediary files
download_data(filename, product, args.timestamp)
bands = import_data(filename)
Expand All @@ -179,51 +182,15 @@ def slice_image(image, start_y, end_y, start_x, end_x):

image = reshape_as_image(bands)

if product == "1p00":
filename = f"{args.timestamp}/0/0/0.png"
write_image(filename, image)

elif product == "0p50":
tiles = [
("0/1", (0, 180, 0, 360)),
("1/1", (0, 180, 360, 720)),
("0/0", (180, 360, 0, 360)),
("1/0", (180, 360, 360, 720)),
]

for path, slices in tiles:
filename = f"{args.timestamp}/1/{path}.png"
image_cut = slice_image(image, *slices)
write_image(filename, image_cut)

elif product == "0p25":
tiles = [
("0/3", (0, 180, 0, 360)),
("1/3", (0, 180, 360, 720)),
("2/3", (0, 180, 720, 1080)),
("3/3", (0, 180, 1080, 1440)),
("0/2", (180, 360, 0, 360)),
("1/2", (180, 360, 360, 720)),
("2/2", (180, 360, 720, 1080)),
("3/2", (180, 360, 1080, 1440)),
("0/1", (360, 540, 0, 360)),
("1/1", (360, 540, 360, 720)),
("2/1", (360, 540, 720, 1080)),
("3/1", (360, 540, 1080, 1440)),
("0/0", (540, 720, 0, 360)),
("1/0", (540, 720, 360, 720)),
("2/0", (540, 720, 720, 1080)),
("3/0", (540, 720, 1080, 1440)),
]

for path, slices in tiles:
filename = f"{args.timestamp}/2/{path}.png"
image_cut = slice_image(image, *slices)
for x in range(2 ** zoom):
for y in range(2 ** zoom):
filename = os.path.join(args.output_dir, args.timestamp, str(zoom), str(x), f"{y}.png")
image_cut = slice_image(image, y * height, (y + 1) * height, x * width, (x + 1) * width)
write_image(filename, image_cut)

json_output = build_meta_json(args.timestamp, **tilejson_variables)
write_json(f"{args.output_dir}/{args.timestamp}/", json_output)
json_output = build_meta_json(args.timestamp, **tilejson_variables)
write_json(os.path.join(args.output_dir, args.timestamp), json_output)

if args.clean:
for f in glob.glob(f"{args.output_dir}*.grb"):
for f in glob.glob(os.path.join(args.output_dir, "*.grb")):
os.remove(f)
2 changes: 1 addition & 1 deletion demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ function initializeConfig(container, { style, layers }) {
style
});
map.on("load", () => {
const source = windGL.source("wind/2016112006.json");
const source = windGL.source("wind/2019031012/tile.json");
layers.forEach(({ type, after, properties }) => {
const layer = windGL[type](
Object.assign(
Expand Down
Loading

0 comments on commit 6e046e1

Please sign in to comment.