From d93234c9b7b6a52ba3a760989a54731827d0dd03 Mon Sep 17 00:00:00 2001 From: Gael-de-Sailly Date: Sat, 14 Nov 2020 16:10:32 +0100 Subject: [PATCH] Moved Python files inside a folder (package), except the 2 that are directly executable --- terrain_rivers.py => generate.py | 34 +++--- terrainlib/__init__.py | 7 ++ bounds.py => terrainlib/bounds.py | 0 erosion.py => terrainlib/erosion.py | 4 +- rivermapper.py => terrainlib/rivermapper.py | 0 save.py => terrainlib/save.py | 0 settings.py => terrainlib/settings.py | 0 terrainlib/view.py | 91 ++++++++++++++ view_map.py | 124 +++----------------- 9 files changed, 132 insertions(+), 128 deletions(-) rename terrain_rivers.py => generate.py (77%) create mode 100644 terrainlib/__init__.py rename bounds.py => terrainlib/bounds.py (100%) rename erosion.py => terrainlib/erosion.py (97%) rename rivermapper.py => terrainlib/rivermapper.py (100%) rename save.py => terrainlib/save.py (100%) rename settings.py => terrainlib/settings.py (100%) create mode 100644 terrainlib/view.py diff --git a/terrain_rivers.py b/generate.py similarity index 77% rename from terrain_rivers.py rename to generate.py index 893c0a3..802a9f0 100755 --- a/terrain_rivers.py +++ b/generate.py @@ -2,14 +2,10 @@ import numpy as np import noise -from save import save -from erosion import EvolutionModel -import bounds import os import sys -import settings -import view_map +import terrainlib ### READ SETTINGS argc = len(sys.argv) @@ -31,7 +27,7 @@ while i < argc: config_file = arg i += 1 -params = settings.read_config_file(config_file) +params = terrainlib.read_config_file(config_file) params.update(params_from_args) # Params given from args prevail against conf file print(params) @@ -84,8 +80,8 @@ nn = n*vscale + offset ### COMPUTE LANDSCAPE EVOLUTION # Initialize landscape evolution model print('Initializing model') -model = EvolutionModel(nn, K=1, m=0.35, d=1, sea_level=0, flex_radius=flex_radius) -view_map.update(model.dem, model.lakes, t=5, title='Initializing...') +model = terrainlib.EvolutionModel(nn, K=1, m=0.35, d=1, sea_level=0, flex_radius=flex_radius) +terrainlib.update(model.dem, model.lakes, t=5, title='Initializing...') dt = time/niter @@ -95,7 +91,7 @@ model.calculate_flow() for i in range(niter): disp_niter = 'Iteration {:d} of {:d}...'.format(i+1, niter) - view_map.update(model.dem, model.lakes, title=disp_niter) + terrainlib.update(model.dem, model.lakes, title=disp_niter) print(disp_niter) print('Diffusion') model.diffusion(dt) @@ -109,8 +105,8 @@ for i in range(niter): print('Done!') # Twist the grid -bx, by = bounds.make_bounds(model.dirs, model.rivers) -offset_x, offset_y = bounds.twist(bx, by, bounds.get_fixed(model.dirs)) +bx, by = terrainlib.make_bounds(model.dirs, model.rivers) +offset_x, offset_y = terrainlib.twist(bx, by, terrainlib.get_fixed(model.dirs)) # Convert offset in 8-bits offset_x = np.clip(np.floor(offset_x * 256), -128, 127) @@ -121,16 +117,16 @@ if not os.path.isdir('data'): os.mkdir('data') os.chdir('data') # Save the files -save(model.dem, 'dem', dtype='>i2') -save(model.lakes, 'lakes', dtype='>i2') -save(offset_x, 'offset_x', dtype='i1') -save(offset_y, 'offset_y', dtype='i1') +terrainlib.save(model.dem, 'dem', dtype='>i2') +terrainlib.save(model.lakes, 'lakes', dtype='>i2') +terrainlib.save(offset_x, 'offset_x', dtype='i1') +terrainlib.save(offset_y, 'offset_y', dtype='i1') -save(model.dirs, 'dirs', dtype='u1') -save(model.rivers, 'rivers', dtype='>u4') +terrainlib.save(model.dirs, 'dirs', dtype='u1') +terrainlib.save(model.rivers, 'rivers', dtype='>u4') with open('size', 'w') as sfile: sfile.write('{:d}\n{:d}'.format(mapsize+1, mapsize+1)) -view_map.stats(model.dem, model.lakes) -view_map.plot(model.dem, model.lakes, title='Final map') +terrainlib.stats(model.dem, model.lakes) +terrainlib.plot(model.dem, model.lakes, title='Final map') diff --git a/terrainlib/__init__.py b/terrainlib/__init__.py new file mode 100644 index 0000000..8775f17 --- /dev/null +++ b/terrainlib/__init__.py @@ -0,0 +1,7 @@ +# Load packages and provide easy access to important functions + +from .settings import read_config_file +from .erosion import EvolutionModel +from .save import save +from .bounds import make_bounds, twist, get_fixed +from .view import stats, update, plot diff --git a/bounds.py b/terrainlib/bounds.py similarity index 100% rename from bounds.py rename to terrainlib/bounds.py diff --git a/erosion.py b/terrainlib/erosion.py similarity index 97% rename from erosion.py rename to terrainlib/erosion.py index 7f830cf..ca971df 100644 --- a/erosion.py +++ b/terrainlib/erosion.py @@ -1,6 +1,6 @@ import numpy as np import scipy.ndimage as im -import rivermapper as rm +from .rivermapper import flow def advection(dem, dirs, rivers, time, K=1, m=0.5, sea_level=0): """ @@ -76,7 +76,7 @@ class EvolutionModel: self.flow_uptodate = False def calculate_flow(self): - self.dirs, self.lakes, self.rivers = rm.flow(self.dem) + self.dirs, self.lakes, self.rivers = flow(self.dem) self.flow_uptodate = True def advection(self, time): diff --git a/rivermapper.py b/terrainlib/rivermapper.py similarity index 100% rename from rivermapper.py rename to terrainlib/rivermapper.py diff --git a/save.py b/terrainlib/save.py similarity index 100% rename from save.py rename to terrainlib/save.py diff --git a/settings.py b/terrainlib/settings.py similarity index 100% rename from settings.py rename to terrainlib/settings.py diff --git a/terrainlib/view.py b/terrainlib/view.py new file mode 100644 index 0000000..68afde9 --- /dev/null +++ b/terrainlib/view.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + +import numpy as np + +has_matplotlib = True +try: + import matplotlib.colors as mcl + import matplotlib.pyplot as plt + try: + import colorcet as cc + cmap1 = cc.cm.CET_L11 + cmap2 = cc.cm.CET_L12 + except ImportError: # No module colorcet + import matplotlib.cm as cm + cmap1 = cm.summer + cmap2 = cm.Blues +except ImportError: # No module matplotlib + has_matplotlib = False + +if has_matplotlib: + def view_map(dem, lakes, scale=1, title=None): + if not has_matplotlib: + return + lakes_sea = np.maximum(lakes, 0) + water = np.maximum(lakes_sea - dem, 0) + max_elev = lakes_sea.max() + max_depth = water.max() + + ls = mcl.LightSource(azdeg=315, altdeg=45) + rgb = ls.shade(lakes_sea, cmap=cmap1, vert_exag=1/scale, blend_mode='soft', vmin=0, vmax=max_elev) + + (X, Y) = dem.shape + extent = (0, Y*scale, 0, X*scale) + plt.imshow(np.flipud(rgb), extent=extent, interpolation='antialiased') + alpha = (water > 0).astype('u1') + plt.imshow(np.flipud(water), alpha=np.flipud(alpha), cmap=cmap2, extent=extent, vmin=0, vmax=max_depth, interpolation='antialiased') + + sm1 = plt.cm.ScalarMappable(cmap=cmap1, norm=plt.Normalize(vmin=0, vmax=max_elev)) + plt.colorbar(sm1).set_label('Elevation') + + sm2 = plt.cm.ScalarMappable(cmap=cmap2, norm=plt.Normalize(vmin=0, vmax=max_depth)) + plt.colorbar(sm2).set_label('Water depth') + + plt.xlabel('X') + plt.ylabel('Z') + + if title is not None: + plt.title(title, fontweight='bold') + + def update(*args, t=0.01, **kwargs): + plt.clf() + view_map(*args, **kwargs) + plt.pause(t) + + def plot(*args, **kwargs): + plt.clf() + view_map(*args, **kwargs) + plt.show() + +else: + def update(*args, **kwargs): + pass + def plot(*args, **kwargs): + pass + +def stats(dem, lake_dem, scale=1): + surface = dem.size + + continent = lake_dem >= 0 + continent_surface = continent.sum() + + lake = continent & (lake_dem>dem) + lake_surface = lake.sum() + + print('--- General ---') + print('Grid size: {:5d}x{:5d}'.format(dem.shape[0], dem.shape[1])) + if scale > 1: + print('Map size: {:5d}x{:5d}'.format(int(dem.shape[0]*scale), int(dem.shape[1]*scale))) + print() + print('--- Surfaces ---') + print('Continents: {:6.2%}'.format(continent_surface/surface)) + print('-> Ground: {:6.2%}'.format((continent_surface-lake_surface)/surface)) + print('-> Lakes: {:6.2%}'.format(lake_surface/surface)) + print('Oceans: {:6.2%}'.format(1-continent_surface/surface)) + print() + print('--- Elevations ---') + print('Mean elevation: {:4.0f}'.format(dem.mean())) + print('Mean ocean depth: {:4.0f}'.format((dem*~continent).sum()/(surface-continent_surface))) + print('Mean continent elev: {:4.0f}'.format((dem*continent).sum()/continent_surface)) + print('Lowest elevation: {:4.0f}'.format(dem.min())) + print('Highest elevation: {:4.0f}'.format(dem.max())) diff --git a/view_map.py b/view_map.py index 6496125..c3efe6d 100755 --- a/view_map.py +++ b/view_map.py @@ -2,118 +2,28 @@ import numpy as np import zlib -import matplotlib.colors as mcl -import matplotlib.pyplot as plt +import sys +import os -has_matplotlib = True -try: - import matplotlib.colors as mcl - import matplotlib.pyplot as plt - try: - import colorcet as cc - cmap1 = cc.cm.CET_L11 - cmap2 = cc.cm.CET_L12 - except ImportError: # No module colorcet - import matplotlib.cm as cm - cmap1 = cm.summer - cmap2 = cm.Blues -except ImportError: # No module matplotlib - has_matplotlib = False +from terrainlib import stats, plot -if has_matplotlib: - def view_map(dem, lakes, scale=1, title=None): - if not has_matplotlib: - return - lakes_sea = np.maximum(lakes, 0) - water = np.maximum(lakes_sea - dem, 0) - max_elev = lakes_sea.max() - max_depth = water.max() +scale = 1 +if len(sys.argv) > 1: + os.chdir(sys.argv[1]) +if len(sys.argv) > 2: + scale = int(sys.argv[2]) - ls = mcl.LightSource(azdeg=315, altdeg=45) - rgb = ls.shade(lakes_sea, cmap=cmap1, vert_exag=1/scale, blend_mode='soft', vmin=0, vmax=max_elev) - - (X, Y) = dem.shape - extent = (0, Y*scale, 0, X*scale) - plt.imshow(np.flipud(rgb), extent=extent, interpolation='antialiased') - alpha = (water > 0).astype('u1') - plt.imshow(np.flipud(water), alpha=np.flipud(alpha), cmap=cmap2, extent=extent, vmin=0, vmax=max_depth, interpolation='antialiased') - - sm1 = plt.cm.ScalarMappable(cmap=cmap1, norm=plt.Normalize(vmin=0, vmax=max_elev)) - plt.colorbar(sm1).set_label('Elevation') - - sm2 = plt.cm.ScalarMappable(cmap=cmap2, norm=plt.Normalize(vmin=0, vmax=max_depth)) - plt.colorbar(sm2).set_label('Water depth') - - plt.xlabel('X') - plt.ylabel('Z') - - if title is not None: - plt.title(title, fontweight='bold') - - def update(*args, t=0.01, **kwargs): - plt.clf() - view_map(*args, **kwargs) - plt.pause(t) - - def plot(*args, **kwargs): - plt.clf() - view_map(*args, **kwargs) - plt.show() - -else: - def update(*args, **kwargs): - pass - def plot(*args, **kwargs): - pass - -def stats(dem, lake_dem, scale=1): - surface = dem.size - - continent = lake_dem >= 0 - continent_surface = continent.sum() - - lake = continent & (lake_dem>dem) - lake_surface = lake.sum() - - print('--- General ---') - print('Grid size: {:5d}x{:5d}'.format(dem.shape[0], dem.shape[1])) - if scale > 1: - print('Map size: {:5d}x{:5d}'.format(int(dem.shape[0]*scale), int(dem.shape[1]*scale))) - print() - print('--- Surfaces ---') - print('Continents: {:6.2%}'.format(continent_surface/surface)) - print('-> Ground: {:6.2%}'.format((continent_surface-lake_surface)/surface)) - print('-> Lakes: {:6.2%}'.format(lake_surface/surface)) - print('Oceans: {:6.2%}'.format(1-continent_surface/surface)) - print() - print('--- Elevations ---') - print('Mean elevation: {:4.0f}'.format(dem.mean())) - print('Mean ocean depth: {:4.0f}'.format((dem*~continent).sum()/(surface-continent_surface))) - print('Mean continent elev: {:4.0f}'.format((dem*continent).sum()/continent_surface)) - print('Lowest elevation: {:4.0f}'.format(dem.min())) - print('Highest elevation: {:4.0f}'.format(dem.max())) - -if __name__ == "__main__": - import sys - import os - - scale = 1 - if len(sys.argv) > 1: - os.chdir(sys.argv[1]) - if len(sys.argv) > 2: - scale = int(sys.argv[2]) - - def load_map(name, dtype, shape): - dtype = np.dtype(dtype) - with open(name, 'rb') as f: - data = f.read() +def load_map(name, dtype, shape): + dtype = np.dtype(dtype) + with open(name, 'rb') as f: + data = f.read() if len(data) < shape[0]*shape[1]*dtype.itemsize: data = zlib.decompress(data) return np.frombuffer(data, dtype=dtype).reshape(shape) - shape = np.loadtxt('size', dtype='u4') - dem = load_map('dem', '>i2', shape) - lakes = load_map('lakes', '>i2', shape) +shape = np.loadtxt('size', dtype='u4') +dem = load_map('dem', '>i2', shape) +lakes = load_map('lakes', '>i2', shape) - stats(dem, lakes, scale=scale) - plot(dem, lakes, scale) +stats(dem, lakes, scale=scale) +plot(dem, lakes, scale=scale)