-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathanimated_hillshade.py
136 lines (94 loc) · 3.59 KB
/
animated_hillshade.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from functools import partial
import datashader as ds
import numpy as np
from datashader.colors import Elevation
from datashader.transfer_functions import shade, stack
from xrspatial import bump, generate_terrain, hillshade, mean
W = 600
H = 400
cvs = ds.Canvas(plot_width=W, plot_height=H,
x_range=(-20e6, 20e6),
y_range=(-20e6, 20e6))
terrain = generate_terrain(canvas=cvs)
def heights(locations, src, src_range, height=20):
num_bumps = locations.shape[0]
out = np.zeros(num_bumps, dtype=np.uint16)
for r in range(0, num_bumps):
loc = locations[r]
x = loc[0]
y = loc[1]
val = src[y, x]
if val >= src_range[0] and val < src_range[1]:
out[r] = height
return out
T = 300000 # Number of trees to add per call
src = terrain.data
trees = bump(W, H, count=T, height_func=partial(heights, src=src,
src_range=(1000, 1300), height=5))
trees += bump(W, H, count=T//2, height_func=partial(
heights, src=src, src_range=(1300, 1700), height=20))
trees += bump(W, H, count=T//3, height_func=partial(
heights, src=src, src_range=(1700, 2000), height=5))
tree_colorize = trees.copy()
tree_colorize.data[tree_colorize.data == 0] = np.nan
LAND_CONSTANT = 50.0
water = terrain.copy()
water.data = np.where(water.data > 0, LAND_CONSTANT, 0)
water = mean(water, passes=50, excludes=[LAND_CONSTANT])
water.data[water.data == LAND_CONSTANT] = np.nan
def create_map(azimuth):
global cvs
global terrain
global water
global trees
img = stack(shade(terrain, cmap=Elevation, how='linear'),
shade(water, cmap=['aqua', 'white']),
shade(hillshade(terrain + trees, azimuth=azimuth),
cmap=['black', 'white'], how='linear', alpha=128),
shade(tree_colorize, cmap='limegreen', how='linear')
)
print('image created')
return img.to_pil()
def create_map2():
global cvs
global terrain
global water
global trees
img = stack(shade(terrain, cmap=['black', 'white'], how='linear'))
yield img.to_pil()
img = stack(shade(terrain, cmap=Elevation, how='linear'))
yield img.to_pil()
img = stack(shade(terrain, cmap=Elevation, how='linear'),
shade(hillshade(terrain, azimuth=210),
cmap=['black', 'white'], how='linear', alpha=128),
)
yield img.to_pil()
img = stack(shade(terrain, cmap=Elevation, how='linear'),
shade(water, cmap=['aqua', 'white']),
shade(hillshade(terrain, azimuth=210),
cmap=['black', 'white'], how='linear', alpha=128),
)
yield img.to_pil()
img = stack(shade(terrain, cmap=Elevation, how='linear'),
shade(water, cmap=['aqua', 'white']),
shade(hillshade(terrain + trees, azimuth=210),
cmap=['black', 'white'], how='linear', alpha=128),
shade(tree_colorize, cmap='limegreen', how='linear')
)
yield img.to_pil()
yield img.to_pil()
yield img.to_pil()
yield img.to_pil()
def gif1():
images = []
for i in np.linspace(0, 360, 6):
images.append(create_map(int(i)))
images[0].save('animated_hillshade.gif',
save_all=True, append_images=images[1:],
optimize=False, duration=5000, loop=0)
def gif2():
images = list(create_map2())
images[0].save('composite_map.gif',
save_all=True, append_images=images[1:],
optimize=False, duration=1000, loop=0)
gif2()