orthographic/perlin.py

144 lines
7.9 KiB
Python

# -------------------------------------------------------------------
# ORTHOGRAPHIC
# Your personal aerial satellite. Always on. At any altitude.*
# Developed by MarStrMind
# License: Open Software License 3.0
# Up to date version always on marstr.online
# -------------------------------------------------------------------
# perlin.py
# Generates a perlin noise image which is used to determine how which
# resource looks.
# -------------------------------------------------------------------
from PIL import Image # Depends on the Pillow lib
from random import randrange
import random
import numpy as np
from perlin_numpy import (
generate_perlin_noise_2d, generate_fractal_noise_2d
)
class mstr_perlin:
def __init__(self, tag, value, mlat, mlng, zl):
self._tag = tag
self._value = value
self._mlat = mlat
self._mlng = mlng
self._zl = zl
self._mapscale = 0
if zl == 16: self._mapscale = 80
if zl == 18: self._mapscale = 20
# Define some base colors
# tag, value, base color, perlin noise color palette
self._bc = [
# Amenity
["amenity", "parking", (31,32,34,255), [ (31,32,34), (74,74,73), (56,55,55), (34,40,44) ]],
["amenity", "school", (26,26,26,255), [ (26,26,26), (78,78,78), (28,29,25), (86,74,64) ]],
# Barrier
["barrier", "hedge", (27,37,25,255), [ (27,37,25), (8,14,13), (15,20,23), (40,40,38) ]],
# Boundary
["boundary", "administrative", (50,49,46,255), [ (50,49,46), (32,38,34), (9,14,18), (82,80,76) ]],
# Landuse
["landuse", "cemetery", (22,22,20,255), [ (22,22,20), (44,43,40), (31,33,29), (39,37,34) ]],
["landuse", "construction", (65,51,32,255), [ (65,51,32), (77,73,67), (45,49,43), (74,63,48) ]],
["landuse", "farmland", (66,60,49,255), [ (66,60,49), (23,32,27), (14,18,20), (45,43,39) ]],
["landuse", "farmyard", (66,60,49,255), [ (66,60,49), (23,32,27), (14,18,20), (45,43,39) ]],
["landuse", "forest", (0,30,10,255), [ (0,30,10), (18,23,16), (15,23,24), (24,29,27) ]],
["landuse", "grass", (23,24,22,255), [ (23,24,22), (40,27,35), (32,34,30), (54,53,51) ]],
["landuse", "greenfield", (23,24,22,255), [ (23,24,22), (40,27,35), (32,34,30), (54,53,51) ]],
["landuse", "meadow", (28,29,27,255), [ (28,29,27), (36,42,40), (45,44,41), (21,22,20) ]],
["landuse", "military", (23,24,22,255), [ (23,24,22), (40,27,35), (32,34,30), (54,53,51) ]],
["landuse", "orchard", (27,38,27,255), [ (27,38,27), (19,22,16), (40,42,33), (40,50,45) ]],
["landuse", "recreation_ground", (27,38,27,255), [ (27,38,27), (19,22,16), (40,42,33), (40,50,45) ]],
["landuse", "residential", (50,49,46,255), [ (50,49,46), (32,38,34), (9,14,18), (82,80,76) ]],
["landuse", "residential-boundary", (50,49,46,255), [ (50,49,46), (32,38,34), (9,14,18), (82,80,76) ]],
["landuse", "vineyard", (66,60,49,255), [ (66,60,49), (23,32,27), (14,18,20), (45,43,39) ]],
# Leisure
["leisure", "dog_park", (66,60,49,255), [ (66,60,49), (23,32,27), (14,18,20), (45,43,39) ]],
["leisure", "garden", (39,39,32,255), [ (39,39,32), (38,47,43), (35,41,31), (21,25,18) ]],
["leisure", "golf_course", (29,39,28,255), [ (29,39,28), (86,81,76), (60,55,45), (13,18,14) ]],
["leisure", "green", (66,60,49,255), [ (66,60,49), (23,32,27), (14,18,20), (45,43,39) ]],
["leisure", "nature_reserve", (0,30,10,255), [ (0,30,10), (18,23,16), (15,23,24), (24,29,27) ]],
["leisure", "park", (23,24,22,255), [ (23,24,22), (40,27,35), (32,34,30), (54,53,51) ]],
["leisure", "pitch", (66,60,49,255), [ (66,60,49), (23,32,27), (14,18,20), (45,43,39) ]],
["leisure", "playground", (65,51,32,255), [ (65,51,32), (77,73,67), (45,49,43), (74,63,48) ]],
["leisure", "sports_centre", (66,60,49,255), [ (66,60,49), (23,32,27), (14,18,20), (45,43,39) ]],
["leisure", "swimming_pool", (9,13,18,255), [ (9,13,18), (9,15,21), (11,12,12), (22,28,31) ]],
# Natural
["natural", "bare_rock", (47,54,56,255), [ (47,54,56), (79,75,71), (84,51,43), (26,33,45) ]],
["natural", "beach", (79,76,69,255), [ (79,76,69), (82,83,80), (71,61,48), (69,68,66) ]],
["natural", "desert", (79,64,42,255), [ (79,64,42), (79,47,24), (37,41,27), (51,39,23) ]],
["natural", "grassland", (23,24,22,255), [ (23,24,22), (40,27,35), (32,34,30), (54,53,51) ]],
["natural", "heath", (26,28,23,255), [ (26,28,23), (45,44,42), (30,34,29), (45,45,42) ]],
["natural", "sand", (79,76,69,255), [ (79,76,69), (82,83,80), (71,61,48), (69,68,66) ]],
["natural", "scree", (38,36,33,255), [ (38,36,33), (81,80,76), (43,42,31), (37,34,27) ]],
["natural", "scrub", (41,39,35,255), [ (41,39,35), (44,38,34), (30,32,39), (20,27,22) ]],
["natural", "water", (9,13,18,255), [ (9,13,18), (9,15,21), (11,12,12), (22,28,31) ]],
["natural", "wetland", (32,34,33,255), [ (32,34,33), (5, 8, 8), (35,36,35), (17,19,17) ]],
["natural", "wood", (0,30,10,255), [ (0,30,10), (18,23,16), (15,23,24), (24,29,27) ]],
# Water
["water", "lake", (9,13,18,255), [ (9,13,18), (9,15,21), (11,12,12), (22,28,31) ]],
["water", "pond", (9,13,18,255), [ (9,13,18), (9,15,21), (11,12,12), (22,28,31) ]],
["water", "river", (9,13,18,255), [ (9,13,18), (9,15,21), (11,12,12), (22,28,31) ]]
]
# Find base color depending on tag/value
def _findBaseColor(self):
idx = -1
for b in range(len(self._bc)):
if self._bc[b][0] == self._tag and self._bc[b][1] == self._value:
idx = b
break
return idx
# Generates a Perlin map depending on what we need
def _generatePerlinMap(self):
idx = self._findBaseColor()
bw = self._mlng * self._mapscale
bh = self._mlat * self._mapscale
wh = 2048
base = Image.new("RGBA", (bw,bh), self._bc[idx][2])
for c in range(len(self._bc[idx][3])):
np.random.seed(randrange(10000000, 100000000))
noise1 = generate_fractal_noise_2d((wh,wh), (16,16), 5)
np.random.seed(randrange(10000000, 100000000))
noise2 = generate_fractal_noise_2d((wh,wh), (8,8), 4)
im1 = Image.new("RGBA", (wh,wh))
im2 = Image.new("RGBA", (wh,wh))
for y in range(0, wh):
for x in range(0, wh):
n = (noise1[y][x] + 1) / 2
v = (
self._bc[idx][3][c][0],
self._bc[idx][3][c][1],
self._bc[idx][3][c][2],
int(n*255)
)
im1.putpixel((x,y), v)
for y in range(0, wh):
for x in range(0, wh):
n = (noise2[y][x] + 1) / 2
v = (
self._bc[idx][3][c][0],
self._bc[idx][3][c][1],
self._bc[idx][3][c][2],
int(n*255)
)
im2.putpixel((x,y), v)
im = Image.blend(im1,im2, alpha=0.5)
base.alpha_composite(im)
# Provide the perlin map
return base