Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 209: Add layers accessors #214

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tests/draw_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ def test_draw_river_map(self):

def test_draw_grayscale_heightmap(self):
w = World.open_protobuf("%s/seed_28070.world" % self.tests_data_dir)
target = PNGWriter.grayscale_from_array(w.layers['elevation'].data, scale_to_range=True)
target = PNGWriter.grayscale_from_array(w.elevation.data, scale_to_range=True)
self._assert_img_equal("grayscale_heightmap_28070", target)

def test_draw_ocean(self):
w = World.open_protobuf("%s/seed_28070.world" % self.tests_data_dir)
target = PNGWriter.rgba_from_dimensions(w.width, w.height)
draw_ocean(w.layers['ocean'].data, target)
draw_ocean(w.ocean.data, target)
self._assert_img_equal("ocean_28070", target)

def test_draw_precipitation(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/serialization_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_hdf5_serialize_unserialize(self):
serialized = save_world_to_hdf5(w, filename)
unserialized = load_world_to_hdf5(filename)
self.assertEqual(Set(w.layers.keys()), Set(unserialized.layers.keys()))
self.assertEqual(w.layers['humidity'].quantiles, unserialized.layers['humidity'].quantiles)
self.assertEqual(w.humidity.quantiles, unserialized.humidity.quantiles)
for l in w.layers.keys():
self.assertEqual(w.layers[l], unserialized.layers[l], "Comparing %s" % l)
self.assertTrue(_equal(w.ocean_level, unserialized.ocean_level))
Expand Down
2 changes: 1 addition & 1 deletion worldengine/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def generate_world(world_name, width, height, seed, num_plates, output_dir,

# Generate images
filename = '%s/%s_ocean.png' % (output_dir, world_name)
draw_ocean_on_file(w.layers['ocean'].data, filename)
draw_ocean_on_file(w.ocean.data, filename)
print("* ocean image generated in '%s'" % filename)

if step.include_precipitations:
Expand Down
50 changes: 25 additions & 25 deletions worldengine/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ def get_normalized_elevation_array(world):
''' Convert raw elevation into normalized values between 0 and 255,
and return a numpy array of these values '''

e = world.layers['elevation'].data
ocean = world.layers['ocean'].data
e = world.elevation.data
ocean = world.ocean.data

mask = numpy.ma.array(e, mask=ocean) # only land
min_elev_land = mask.min()
Expand Down Expand Up @@ -324,24 +324,24 @@ def draw_simple_elevation(world, sea_level, target):
""" This function can be used on a generic canvas (either an image to save
on disk or a canvas part of a GUI)
"""
e = world.layers['elevation'].data
e = world.elevation.data
c = numpy.empty(e.shape, dtype=numpy.float)

has_ocean = not (sea_level is None or world.layers['ocean'].data is None or not world.layers['ocean'].data.any()) # or 'not any ocean'
mask_land = numpy.ma.array(e, mask=world.layers['ocean'].data if has_ocean else False) # only land
has_ocean = not (sea_level is None or world.ocean.data is None or not world.ocean.data.any()) # or 'not any ocean'
mask_land = numpy.ma.array(e, mask=world.ocean.data if has_ocean else False) # only land

min_elev_land = mask_land.min()
max_elev_land = mask_land.max()
elev_delta_land = (max_elev_land - min_elev_land) / 11.0

if has_ocean:
land = numpy.logical_not(world.layers['ocean'].data)
land = numpy.logical_not(world.ocean.data)
mask_ocean = numpy.ma.array(e, mask=land) # only ocean
min_elev_sea = mask_ocean.min()
max_elev_sea = mask_ocean.max()
elev_delta_sea = max_elev_sea - min_elev_sea

c[world.layers['ocean'].data] = ((e[world.layers['ocean'].data] - min_elev_sea) / elev_delta_sea)
c[world.ocean.data] = ((e[world.ocean.data] - min_elev_sea) / elev_delta_sea)
c[land] = ((e[land] - min_elev_land) / elev_delta_land) + 1
else:
c = ((e - min_elev_land) / elev_delta_land) + 1
Expand Down Expand Up @@ -377,7 +377,7 @@ def draw_satellite(world, target):

# Get an elevation mask where heights are normalized between 0 and 255
elevation_mask = get_normalized_elevation_array(world)
smooth_mask = numpy.invert(world.layers['ocean'].data) # all land shall be smoothed (other tiles can be included by setting them to True)
smooth_mask = numpy.invert(world.ocean.data) # all land shall be smoothed (other tiles can be included by setting them to True)

rng = numpy.random.RandomState(world.seed) # create our own random generator; necessary for now to make the tests reproducible, even though it is a bit ugly

Expand All @@ -399,7 +399,7 @@ def draw_satellite(world, target):
ice_color_variation = int(30) # 0 means perfectly white ice; must be in [0, 255]; only affects R- and G-channel
for y in range(world.height):
for x in range(world.width):
if world.layers['icecap'].data[y, x] > 0.0:
if world.icecap.data[y, x] > 0.0:
smooth_mask[y, x] = True # smooth the frozen areas, too
variation = rng.randint(0, ice_color_variation)
target.set_pixel(x, y, (255 - ice_color_variation + variation, 255 - ice_color_variation + variation, 255, 255))
Expand Down Expand Up @@ -438,14 +438,14 @@ def draw_satellite(world, target):
for y in range(world.height):
for x in range(world.width):
## Color rivers
if world.is_land((x, y)) and (world.layers['river_map'].data[y, x] > 0.0):
if world.is_land((x, y)) and (world.river_map.data[y, x] > 0.0):
base_color = target[y, x]

r, g, b = add_colors(base_color, RIVER_COLOR_CHANGE)
target.set_pixel(x, y, (r, g, b, 255))

## Color lakes
if world.is_land((x, y)) and (world.layers['lake_map'].data[y, x] != 0):
if world.is_land((x, y)) and (world.lake_map.data[y, x] != 0):
base_color = target[y, x]

r, g, b = add_colors(base_color, LAKE_COLOR_CHANGE)
Expand All @@ -459,13 +459,13 @@ def draw_satellite(world, target):

# Build up list of elevations in the previous n tiles, where n is the shadow size.
# This goes northwest to southeast
prev_elevs = [ world.layers['elevation'].data[y-n, x-n] for n in range(1, SAT_SHADOW_SIZE+1) ]
prev_elevs = [ world.elevation.data[y-n, x-n] for n in range(1, SAT_SHADOW_SIZE+1) ]

# Take the average of the height of the previous n tiles
avg_prev_elev = int( sum(prev_elevs) / len(prev_elevs) )

# Find the difference between this tile's elevation, and the average of the previous elevations
difference = int(world.layers['elevation'].data[y, x] - avg_prev_elev)
difference = int(world.elevation.data[y, x] - avg_prev_elev)

# Amplify the difference
adjusted_difference = difference * SAT_SHADOW_DISTANCE_MULTIPLIER
Expand All @@ -485,8 +485,8 @@ def draw_elevation(world, shadow, target):
width = world.width
height = world.height

data = world.layers['elevation'].data
ocean = world.layers['ocean'].data
data = world.elevation.data
ocean = world.ocean.data

mask = numpy.ma.array(data, mask=ocean)

Expand Down Expand Up @@ -574,7 +574,7 @@ def draw_world(world, target):
biome = world.biome_at((x, y))
target.set_pixel(x, y, _biome_colors[biome.name()])
else:
c = int(world.layers['sea_depth'].data[y, x] * 200 + 50)
c = int(world.sea_depth.data[y, x] * 200 + 50)
target.set_pixel(x, y, (0, 0, 255 - c, 255))


Expand Down Expand Up @@ -617,7 +617,7 @@ def draw_biome(world, target):
width = world.width
height = world.height

biome = world.layers['biome'].data
biome = world.biome.data

for y in range(height):
for x in range(width):
Expand All @@ -632,8 +632,8 @@ def draw_scatter_plot(world, size, target):

#Find min and max values of humidity and temperature on land so we can
#normalize temperature and humidity to the chart
humid = numpy.ma.masked_array(world.layers['humidity'].data, mask=world.layers['ocean'].data)
temp = numpy.ma.masked_array(world.layers['temperature'].data, mask=world.layers['ocean'].data)
humid = numpy.ma.masked_array(world.humidity.data, mask=world.ocean.data)
temp = numpy.ma.masked_array(world.temperature.data, mask=world.ocean.data)
min_humidity = humid.min()
max_humidity = humid.max()
min_temperature = temp.min()
Expand All @@ -650,12 +650,12 @@ def draw_scatter_plot(world, size, target):
h_values = ['62', '50', '37', '25', '12']
t_values = [ 0, 1, 2, 3, 5 ]
for loop in range(0, 5):
h_min = (size - 1) * ((world.layers['humidity'].quantiles[h_values[loop]] - min_humidity) / humidity_delta)
h_min = (size - 1) * ((world.humidity.quantiles[h_values[loop]] - min_humidity) / humidity_delta)
if loop != 4:
h_max = (size - 1) * ((world.layers['humidity'].quantiles[h_values[loop + 1]] - min_humidity) / humidity_delta)
h_max = (size - 1) * ((world.humidity.quantiles[h_values[loop + 1]] - min_humidity) / humidity_delta)
else:
h_max = size
v_max = (size - 1) * ((world.layers['temperature'].thresholds[t_values[loop]][1] - min_temperature) / temperature_delta)
v_max = (size - 1) * ((world.temperature.thresholds[t_values[loop]][1] - min_temperature) / temperature_delta)
if h_min < 0:
h_min = 0
if h_max > size:
Expand All @@ -672,13 +672,13 @@ def draw_scatter_plot(world, size, target):

#draw lines based on thresholds
for t in range(0, 6):
v = (size - 1) * ((world.layers['temperature'].thresholds[t][1] - min_temperature) / temperature_delta)
v = (size - 1) * ((world.temperature.thresholds[t][1] - min_temperature) / temperature_delta)
if 0 < v < size:
for y in range(0, size):
target.set_pixel(int(v), (size - 1) - y, (0, 0, 0, 255))
ranges = ['87', '75', '62', '50', '37', '25', '12']
for p in ranges:
h = (size - 1) * ((world.layers['humidity'].quantiles[p] - min_humidity) / humidity_delta)
h = (size - 1) * ((world.humidity.quantiles[p] - min_humidity) / humidity_delta)
if 0 < h < size:
for x in range(0, size):
target.set_pixel(x, (size - 1) - int(h), (0, 0, 0, 255))
Expand Down Expand Up @@ -756,7 +756,7 @@ def draw_riversmap_on_file(world, filename):


def draw_grayscale_heightmap_on_file(world, filename):
img = PNGWriter.grayscale_from_array(world.layers['elevation'].data, filename, scale_to_range=True)
img = PNGWriter.grayscale_from_array(world.elevation.data, filename, scale_to_range=True)
img.complete()


Expand Down
4 changes: 2 additions & 2 deletions worldengine/drawing_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ def draw_rivers_on_image(world, target, factor=1):

for y in range(world.height):
for x in range(world.width):
if world.is_land((x, y)) and (world.layers['river_map'].data[y, x] > 0.0):
if world.is_land((x, y)) and (world.river_map.data[y, x] > 0.0):
for dx in range(factor):
for dy in range(factor):
target.set_pixel(x * factor + dx, y * factor + dy, (0, 0, 128, 255))
if world.is_land((x, y)) and (world.layers['lake_map'].data[y, x] != 0):
if world.is_land((x, y)) and (world.lake_map.data[y, x] != 0):
for dx in range(factor):
for dy in range(factor):
target.set_pixel(x * factor + dx, y * factor + dy, (0, 100, 128, 255))
Expand Down
18 changes: 9 additions & 9 deletions worldengine/generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ def center_land(world):
"""Translate the map horizontally and vertically to put as much ocean as
possible at the borders. It operates on elevation and plates map"""

y_sums = world.layers['elevation'].data.sum(1) # 1 == sum along x-axis
y_sums = world.elevation.data.sum(1) # 1 == sum along x-axis
y_with_min_sum = y_sums.argmin()
if get_verbose():
print("geo.center_land: height complete")

x_sums = world.layers['elevation'].data.sum(0) # 0 == sum along y-axis
x_sums = world.elevation.data.sum(0) # 0 == sum along y-axis
x_with_min_sum = x_sums.argmin()
if get_verbose():
print("geo.center_land: width complete")

latshift = 0
world.layers['elevation'].data = numpy.roll(numpy.roll(world.layers['elevation'].data, -y_with_min_sum + latshift, axis=0), - x_with_min_sum, axis=1)
world.layers['plates'].data = numpy.roll(numpy.roll(world.layers['plates'].data, -y_with_min_sum + latshift, axis=0), - x_with_min_sum, axis=1)
world.elevation.data = numpy.roll(numpy.roll(world.elevation.data, -y_with_min_sum + latshift, axis=0), - x_with_min_sum, axis=1)
world.plates.data = numpy.roll(numpy.roll(world.plates.data, -y_with_min_sum + latshift, axis=0), - x_with_min_sum, axis=1)
if get_verbose():
print("geo.center_land: width complete")

Expand All @@ -49,8 +49,8 @@ def place_oceans_at_map_borders(world):
ocean_border = int(min(30, max(world.width / 5, world.height / 5)))

def place_ocean(x, y, i):
world.layers['elevation'].data[y, x] = \
(world.layers['elevation'].data[y, x] * i) / ocean_border
world.elevation.data[y, x] = \
(world.elevation.data[y, x] * i) / ocean_border

for x in range(world.width):
for i in range(ocean_border):
Expand All @@ -69,7 +69,7 @@ def add_noise_to_elevation(world, seed):
for y in range(world.height):
for x in range(world.width):
n = snoise2(x / freq * 2, y / freq * 2, octaves, base=seed)
world.layers['elevation'].data[y, x] += n
world.elevation.data[y, x] += n


def fill_ocean(elevation, sea_level):#TODO: Make more use of numpy?
Expand Down Expand Up @@ -105,7 +105,7 @@ def initialize_ocean_and_thresholds(world, ocean_level=1.0):
:param ocean_level: the elevation representing the ocean level
:return: nothing, the world will be changed
"""
e = world.layers['elevation'].data
e = world.elevation.data
ocean = fill_ocean(e, ocean_level)
hl = find_threshold_f(e, 0.10) # the highest 10% of all (!) land are declared hills
ml = find_threshold_f(e, 0.03) # the highest 3% are declared mountains
Expand Down Expand Up @@ -141,7 +141,7 @@ def harmonize_ocean(ocean, elevation, ocean_level):
# ----

def sea_depth(world, sea_level):
sea_depth = sea_level - world.layers['elevation'].data
sea_depth = sea_level - world.elevation.data
for y in range(world.height):
for x in range(world.width):
if world.tiles_around((x, y), radius=1, predicate=world.is_land):
Expand Down
Loading