2020-04-09 21:13:38 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
import noise
|
|
|
|
from save import save
|
|
|
|
from erosion import EvolutionModel
|
2020-04-12 09:40:10 +02:00
|
|
|
import bounds
|
2020-04-09 21:13:38 +02:00
|
|
|
import os
|
|
|
|
import sys
|
2020-05-30 12:03:34 +02:00
|
|
|
import settings
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-11-14 12:05:52 +01:00
|
|
|
import view_map
|
|
|
|
|
2020-04-09 21:13:38 +02:00
|
|
|
# Always place in this script's parent directory
|
|
|
|
os.chdir(os.path.dirname(sys.argv[0]))
|
|
|
|
argc = len(sys.argv)
|
|
|
|
|
2020-11-14 12:19:40 +01:00
|
|
|
config_file = 'terrain.conf'
|
2020-05-30 12:03:34 +02:00
|
|
|
|
2020-04-09 21:13:38 +02:00
|
|
|
if argc > 1:
|
2020-11-14 12:19:40 +01:00
|
|
|
config_file = sys.argv[1]
|
|
|
|
|
|
|
|
params = settings.read_config_file(config_file)
|
2020-05-30 12:03:34 +02:00
|
|
|
|
|
|
|
def get_setting(name, default):
|
|
|
|
if name in params:
|
|
|
|
return params[name]
|
|
|
|
return default
|
|
|
|
|
2020-11-14 12:19:40 +01:00
|
|
|
mapsize = int(get_setting('mapsize', 1000))
|
|
|
|
scale = float(get_setting('scale', 400.0))
|
|
|
|
vscale = float(get_setting('vscale', 300.0))
|
2020-05-30 12:03:34 +02:00
|
|
|
offset = float(get_setting('offset', 0.0))
|
2020-11-14 12:19:40 +01:00
|
|
|
persistence = float(get_setting('persistence', 0.6))
|
2020-05-30 12:03:34 +02:00
|
|
|
lacunarity = float(get_setting('lacunarity', 2.0))
|
|
|
|
|
|
|
|
K = float(get_setting('K', 1.0))
|
|
|
|
m = float(get_setting('m', 0.35))
|
2020-11-14 12:19:40 +01:00
|
|
|
d = float(get_setting('d', 0.8))
|
2020-05-30 12:03:34 +02:00
|
|
|
sea_level = float(get_setting('sea_level', 0.0))
|
|
|
|
flex_radius = float(get_setting('flex_radius', 20.0))
|
|
|
|
|
|
|
|
time = float(get_setting('time', 10.0))
|
|
|
|
niter = int(get_setting('niter', 10))
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-04-26 19:51:21 +02:00
|
|
|
n = np.zeros((mapsize+1, mapsize+1))
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-04-26 17:13:38 +02:00
|
|
|
# Set noise parameters
|
2020-04-09 21:13:38 +02:00
|
|
|
params = {
|
2020-04-26 19:51:21 +02:00
|
|
|
"octaves" : int(np.ceil(np.log2(mapsize)))+1,
|
2020-05-30 12:03:34 +02:00
|
|
|
"persistence" : persistence,
|
|
|
|
"lacunarity" : lacunarity,
|
2020-04-09 21:13:38 +02:00
|
|
|
}
|
|
|
|
|
2020-04-26 17:13:38 +02:00
|
|
|
# Determine noise offset randomly
|
2020-04-09 21:13:38 +02:00
|
|
|
xbase = np.random.randint(65536)
|
|
|
|
ybase = np.random.randint(65536)
|
|
|
|
|
2020-04-26 17:13:38 +02:00
|
|
|
# Generate the noise
|
2020-04-26 19:51:21 +02:00
|
|
|
for x in range(mapsize+1):
|
|
|
|
for y in range(mapsize+1):
|
2020-04-09 21:13:38 +02:00
|
|
|
n[x,y] = noise.snoise2(x/scale + xbase, y/scale + ybase, **params)
|
|
|
|
|
2020-05-30 12:03:34 +02:00
|
|
|
nn = n*vscale + offset
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-04-26 17:13:38 +02:00
|
|
|
# Initialize landscape evolution model
|
2020-04-09 21:13:38 +02:00
|
|
|
print('Initializing model')
|
2020-05-30 12:03:34 +02:00
|
|
|
model = EvolutionModel(nn, K=1, m=0.35, d=1, sea_level=0, flex_radius=flex_radius)
|
2020-11-14 12:05:52 +01:00
|
|
|
view_map.update(model.dem, model.lakes, t=5, title='Initializing...')
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-05-30 12:03:34 +02:00
|
|
|
dt = time/niter
|
2020-04-10 19:37:27 +02:00
|
|
|
|
2020-05-30 12:03:34 +02:00
|
|
|
# Run the model's processes: the order in which the processes are run is arbitrary and could be changed.
|
|
|
|
print('Initial flow calculation')
|
2020-04-09 21:13:38 +02:00
|
|
|
model.calculate_flow()
|
|
|
|
|
2020-05-30 12:03:34 +02:00
|
|
|
for i in range(niter):
|
2020-11-14 12:05:52 +01:00
|
|
|
disp_niter = 'Iteration {:d} of {:d}...'.format(i+1, niter)
|
|
|
|
view_map.update(model.dem, model.lakes, title=disp_niter)
|
|
|
|
print(disp_niter)
|
2020-05-30 12:03:34 +02:00
|
|
|
print('Diffusion')
|
|
|
|
model.diffusion(dt)
|
|
|
|
print('Advection')
|
|
|
|
model.advection(dt)
|
|
|
|
print('Isostatic equilibration')
|
|
|
|
model.adjust_isostasy()
|
|
|
|
print('Flow calculation')
|
|
|
|
model.calculate_flow()
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-11-14 12:05:52 +01:00
|
|
|
print('Done!')
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-04-26 17:13:38 +02:00
|
|
|
# Twist the grid
|
2020-04-12 09:40:10 +02:00
|
|
|
bx, by = bounds.make_bounds(model.dirs, model.rivers)
|
2020-04-26 18:10:23 +02:00
|
|
|
offset_x, offset_y = bounds.twist(bx, by, bounds.get_fixed(model.dirs))
|
2020-04-12 09:40:10 +02:00
|
|
|
|
2020-04-26 17:13:38 +02:00
|
|
|
# Convert offset in 8-bits
|
2020-04-26 18:10:23 +02:00
|
|
|
offset_x = np.clip(np.floor(offset_x * 256), -128, 127)
|
|
|
|
offset_y = np.clip(np.floor(offset_y * 256), -128, 127)
|
2020-04-12 09:40:10 +02:00
|
|
|
|
2020-04-26 23:29:36 +02:00
|
|
|
if not os.path.isdir('data'):
|
|
|
|
os.mkdir('data')
|
|
|
|
os.chdir('data')
|
2020-04-26 17:13:38 +02:00
|
|
|
# Save the files
|
2020-04-09 21:13:38 +02:00
|
|
|
save(model.dem, 'dem', dtype='>i2')
|
|
|
|
save(model.lakes, 'lakes', dtype='>i2')
|
2020-04-12 09:40:10 +02:00
|
|
|
save(offset_x, 'offset_x', dtype='i1')
|
|
|
|
save(offset_y, 'offset_y', dtype='i1')
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-04-26 18:10:23 +02:00
|
|
|
save(model.dirs, 'dirs', dtype='u1')
|
2020-04-13 13:45:52 +02:00
|
|
|
save(model.rivers, 'rivers', dtype='>u4')
|
|
|
|
|
2020-04-09 21:13:38 +02:00
|
|
|
with open('size', 'w') as sfile:
|
2020-04-26 19:51:21 +02:00
|
|
|
sfile.write('{:d}\n{:d}'.format(mapsize+1, mapsize+1))
|
2020-04-09 21:13:38 +02:00
|
|
|
|
2020-11-14 12:05:52 +01:00
|
|
|
view_map.stats(model.dem, model.lakes)
|
|
|
|
view_map.plot(model.dem, model.lakes, title='Final map')
|