Massive changes to building generation, adjustments to area generation, changes to tile completion. More layers that were previously missing, added. Texture changes. Getting close to public release.

This commit is contained in:
Marcus Str. 2024-10-04 20:41:59 +02:00
parent 5d05f376f6
commit db5fb30787
285 changed files with 476 additions and 155 deletions

View File

@ -53,12 +53,14 @@ mstr_show_log = True
# We will simply things to achieve good-looking results. # We will simply things to achieve good-looking results.
# You can, however, disable the shadow rendering layer here. # You can, however, disable the shadow rendering layer here.
mstr_shadow_enabled = True mstr_shadow_enabled = True
mstr_shadow_strength = 0.85 mstr_shadow_strength = 0.65
mstr_shadow_shift = 24 mstr_shadow_shift = 15
# The tags that cast shadows # The tags that cast shadows
mstr_shadow_casters = [ mstr_shadow_casters = [
("landuse", "forest"), ("landuse", "forest"),
("leisure", "nature_reserve"), ("leisure", "nature_reserve"),
("natural", "wood"),
("natural", "tree_row"),
("building", "semidetached_house"), ("building", "semidetached_house"),
("building", "apartments"), ("building", "apartments"),
("building", "garage"), ("building", "garage"),
@ -138,6 +140,7 @@ mstr_ortho_layers = [
("leisure", "garden", "leisure", "green"), ("leisure", "garden", "leisure", "green"),
("leisure", "sports_centre", "leisure", "green"), ("leisure", "sports_centre", "leisure", "green"),
("leisure", "pitch", "leisure", "green"), ("leisure", "pitch", "leisure", "green"),
("leisure", "playground", "leisure", "green"),
("landuse", "farmland", "landuse", "farmland"), ("landuse", "farmland", "landuse", "farmland"),
("landuse", "farmyard", "landuse", "farmland"), ("landuse", "farmyard", "landuse", "farmland"),
("landuse", "military", "landuse", "residential-boundary"), ("landuse", "military", "landuse", "residential-boundary"),
@ -154,6 +157,8 @@ mstr_ortho_layers = [
("waterway", "stream", 10), ("waterway", "stream", 10),
("leisure", "nature_reserve", "landuse", "forest"), ("leisure", "nature_reserve", "landuse", "forest"),
("landuse", "forest", "landuse", "forest"), ("landuse", "forest", "landuse", "forest"),
("natural", "wood", "natural", "wood"),
("natural", "tree_row", 22),
("natural", "wetland", "natural", "wetland"), ("natural", "wetland", "natural", "wetland"),
("natural", "scrub", "natural", "scrub"), ("natural", "scrub", "natural", "scrub"),
("natural", "heath", "natural", "heath"), ("natural", "heath", "natural", "heath"),
@ -166,7 +171,9 @@ mstr_ortho_layers = [
("water", "lake", "natural", "water"), ("water", "lake", "natural", "water"),
("water", "pond", "natural", "water"), ("water", "pond", "natural", "water"),
("water", "river", "natural", "water"), ("water", "river", "natural", "water"),
("amenity", "parking", "amenities", "parking"), ("leisure", "swimming_pool", "natural", "water"),
("amenity", "parking", "amenity", "parking"),
("amenity", "school", "amenity", "school"),
("highway", "pedestrian", 4), ("highway", "pedestrian", 4),
# Z-Order 4 # Z-Order 4
("highway", "motorway", 32), ("highway", "motorway", 32),
@ -189,6 +196,9 @@ mstr_ortho_layers = [
("building", "terrace", "building", "industrial"), ("building", "terrace", "building", "industrial"),
("building", "hangar", "building", "industrial"), ("building", "hangar", "building", "industrial"),
("building", "school", "building", "common"), ("building", "school", "building", "common"),
("building", "kindergarten", "building", "kindergarten"),
("building", "public", "building", "public"),
("building", "commercial", "building", "commercial"),
("building", "yes", "building", "common"), ("building", "yes", "building", "common"),
("place", "sea", "natural", "sea"), ("place", "sea", "natural", "sea"),
("place", "ocean", "natural", "sea") ("place", "ocean", "natural", "sea")
@ -198,33 +208,36 @@ mstr_ortho_layers = [
# Blur values for the single masks of the ortho layers # Blur values for the single masks of the ortho layers
mstr_mask_blur = [ mstr_mask_blur = [
# Z-Order 0 # Z-Order 0
("landuse", "residential", 30), ("landuse", "residential", 20),
("boundary", "administrative", 30), ("boundary", "administrative", 20),
# Z-Order 1 # Z-Order 1
("landuse", "grass", 30), ("landuse", "grass", 12),
("landuse", "cemetery", 30), ("landuse", "cemetery", 12),
("landuse", "greenfield", 30), ("landuse", "greenfield", 12),
("landuse", "orchard", 30), ("landuse", "orchard", 12),
("landuse", "meadow", 30), ("landuse", "meadow", 12),
("barrier", "hedge", 5), ("barrier", "hedge", 1),
("landuse", "recreation_ground", 20), ("landuse", "recreation_ground", 20),
("landuse", "vineyard", 30), ("landuse", "vineyard", 12),
("natural", "grassland", 30), ("natural", "grassland", 12),
("natural", "wetland", 30), ("natural", "wetland", 30),
("natural", "scrub", 20), ("natural", "scrub", 15),
("natural", "heath", 20), ("natural", "heath", 15),
("leisure", "park", 30), ("leisure", "park", 15),
("leisure", "golf_course", 25), ("leisure", "golf_course", 25),
("leisure", "dog_park", 35), ("leisure", "dog_park", 15),
("leisure", "garden", 20), ("leisure", "garden", 20),
("leisure", "sports_centre", 5), ("leisure", "sports_centre", 5),
("leisure", "pitch", 2), ("leisure", "pitch", 2),
("leisure", "playground", 2),
("landuse", "farmland", 10), ("landuse", "farmland", 10),
("landuse", "farmyard", 10), ("landuse", "farmyard", 10),
# Z-Order 2 # Z-Order 2
("landuse", "forest", 20), ("landuse", "forest", 8),
("leisure", "nature_reserve", 20), ("leisure", "nature_reserve", 8),
("landuse", "military", 30), ("natural", "wood", 8),
("natural", "tree_row", 8),
("landuse", "military", 15),
# Z-Order 3 # Z-Order 3
("natural", "bare_rock", 25), ("natural", "bare_rock", 25),
("natural", "water", 4), ("natural", "water", 4),
@ -233,26 +246,28 @@ mstr_mask_blur = [
("water", "lake", 10), ("water", "lake", 10),
("water", "pond", 10), ("water", "pond", 10),
("water", "river", 10), ("water", "river", 10),
("leisure", "swimming_pool", 10),
("waterway", "river", 10), ("waterway", "river", 10),
("waterway", "stream", 10), ("waterway", "stream", 10),
("amenity", "parking", 3), ("amenity", "parking", 1),
("amenity", "school", 1),
("highway", "pedestrian", 12), ("highway", "pedestrian", 12),
# Z-Order 4 # Z-Order 4
("highway", "motorway", 5), ("highway", "motorway", 2),
("highway", "primary", 5), ("highway", "primary", 2),
("highway", "secondary", 5), ("highway", "secondary", 2),
("highway", "tertiary", 5), ("highway", "tertiary", 2),
("highway", "unclassified", 5), ("highway", "unclassified", 2),
("highway", "living_street", 5), ("highway", "living_street", 2),
("highway", "residential", 5), ("highway", "residential", 2),
("highway", "service", 3), ("highway", "service", 2),
("highway", "footway", 3), ("highway", "footway", 2),
("highway", "track", 3), ("highway", "track", 2),
("highway", "path", 3), ("highway", "path", 2),
("railway", "rail", 4), ("railway", "rail", 2),
# Z-Order 5 # Z-Order 5
("aeroway", "taxiway", 12), ("aeroway", "taxiway", 2),
("aeroway", "runway", 12), ("aeroway", "runway", 2),
("building", "detached", 1), ("building", "detached", 1),
("building", "church", 1), ("building", "church", 1),
("building", "hotel", 1), ("building", "hotel", 1),
@ -268,7 +283,149 @@ mstr_mask_blur = [
("building", "terrace", 1), ("building", "terrace", 1),
("building", "hangar", 1), ("building", "hangar", 1),
("building", "school", 1), ("building", "school", 1),
("building", "yes", 1), ("building", "kindergarten", 1),
("building", "public", 1),
("building", "commercial", 1),
("building", "yes", 0),
("place", "sea", 1), ("place", "sea", 1),
("place", "ocean", 1) ("place", "ocean", 1)
] ]
# Base colors for different building types
mstr_building_base_colors = [
("detached", [
"#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
"#534136", "#4d3424", "#534b45", "#553724", "#574c45",
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("church", [
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("hotel", [
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("farm", [
"#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
"#534136", "#4d3424", "#534b45", "#553724", "#574c45"
]
),
("semidetached_house", [
"#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
"#534136", "#4d3424", "#534b45", "#553724", "#574c45",
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("apartments", [
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("civic", [
"#7b848b", "#5d6d7b", "#5e646a", "#454d53", "#585b5e",
"#877a78", "#797372", "#797372", "#6f5550", "#7c7574"
]
),
("garage", [
"#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
"#523731", "#46484e", "#33353a", "#3a3733", "#5d5a57"
]
),
("office", [
"#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
"#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
"#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
]
),
("retail", [
"#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
"#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
"#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
]
),
("industrial", [
"#939fa2", "#728080", "#9eafaf", "#4f6061", "#96b2b6",
"#b2b398", "#878868", "#989888", "#bdb79c", "#959386"
]
),
("house", [
"#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
"#534136", "#4d3424", "#534b45", "#553724", "#574c45",
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("terrace", [
"#86898c", "#5e656c", "#6d6868", "#6d6c68", "#46443d",
"#3d4546", "#6b7071", "#716b70", "#738684", "#868073"
]
),
("hangar", [
"#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
"#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
"#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
]
),
("school", [
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("kindergarten", [
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("public", [
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
),
("commercial", [
"#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
"#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
"#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
]
),
("yes", [
"#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
"#534136", "#4d3424", "#534b45", "#553724", "#574c45",
"#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
"#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
]
)
]
mstr_completion_colors = [
("+50+000", [
(48,63,34),
(81,95,64),
(105,100,64),
(91,105,72),
(78,69,41),
(116,113,78),
(90,94,69),
(58,68,40),
(57,72,41),
(93,103,76),
(139,142,111),
(92,102,73),
(71,86,55),
(103,105,91),
(96,78,56),
(143,141,113),
(107,108,74),
(41,56,34),
(51,63,41),
(137,137,107)
]
)
]

View File

@ -16,7 +16,7 @@ import glob
import os import os
from random import randrange from random import randrange
import random import random
from PIL import Image, ImageFilter, ImageDraw, ImagePath from PIL import Image, ImageFilter, ImageDraw, ImagePath, ImageEnhance
from defines import * from defines import *
from log import * from log import *
from tileinfo import * from tileinfo import *
@ -399,20 +399,70 @@ class mstr_layergen:
layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) ) layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) )
mstr_msg("layergen", "Layer image generated") mstr_msg("layergen", "Layer image generated")
# Here we need to do some magic to make some features look more natural
if (self._tag == "landuse" and self._value == "meadow") or (self._tag == "natural" and self._value == "grassland") or (self._tag == "natural" and self._value == "heath"):
amt = randrange(1,16)
for i in range(1, amt+1):
ptc = randrange(1, 14)
img = Image.open(mstr_datafolder + "textures/tile/completion/p" + str(ptc)+".png")
lx = randrange( int(layer.width/20), layer.width - (int(layer.width/20)) - img.width )
ly = randrange( int(layer.width/20), layer.width - (int(layer.width/20)) - img.height )
layer.alpha_composite( img, (lx, ly) )
# We now need to add the seamless border # We now need to add the seamless border
layer.alpha_composite( brd_src ) layer.alpha_composite( brd_src )
# Here we need to do some magic to make some features look more natural
if (self._tag == "landuse" and self._value == "meadow") or (self._tag == "natural" and self._value == "grassland") or (self._tag == "natural" and self._value == "heath") or (self._tag == "landuse" and self._value == "cemetery") or (self._tag == "landuse" and self._value == "residential"):
if self._is_completion == False:
amt = randrange(1,251)
for i in range(1, amt+1):
ptc = randrange(1, 14)
img = Image.open(mstr_datafolder + "textures/tile/completion/p" + str(ptc)+".png")
img = img.rotate(randrange(0, 360), expand=True)
a = img.getchannel("A")
bbox = a.getbbox()
img = img.crop(bbox)
lx = randrange( self._imgsize - img.width )
ly = randrange( self._imgsize - img.height )
layer.alpha_composite( img, (lx, ly) )
if self._is_completion == True:
mp = osm_mask.load()
edn = self.xplane_latlng_folder(self.find_earthnavdata_number())
idx = 0
for r in mstr_completion_colors:
if r[0] == edn:
break
else:
idx = idx+1
for y in range(self._imgsize):
for x in range(self._imgsize):
if mp[x,y][3] > 0:
# Pick a color
a = mp[x,y]
cidx = randrange(len(mstr_completion_colors[idx][1]))
clr = mstr_completion_colors[idx][1][cidx]
layer_pix[x,y] = (clr[0], clr[1], clr[2], a[3])
amt = randrange(1,51)
for i in range(1, amt+1):
ptc = randrange(1, 14)
img = Image.open(mstr_datafolder + "textures/tile/completion/p" + str(ptc)+".png")
img = img.rotate(randrange(0, 360), expand=True)
a = img.getchannel("A")
bbox = a.getbbox()
img = img.crop(bbox)
imgp = img.load()
for y in range(img.height):
for x in range(img.width):
c = imgp[x,y]
nc = (c[0], c[1], c[2], int(imgp[x,y][3]*0.25))
imgp[x,y] = nc
lx = randrange( self._imgsize - img.width )
ly = randrange( self._imgsize - img.height )
layer.alpha_composite( img, (lx, ly))
layer = layer.filter(ImageFilter.GaussianBlur(radius=1))
# Add trees only in some features
if (self._tag == "landuse" and self._value == "cemetery") or (self._tag == "landuse" and self._value == "residential") or (self._tag == "leisure" and self._value == "park"):
amt = 3500
for i in range(1, amt+1):
p = randrange(1, 11)
tree = Image.open(mstr_datafolder + "textures/building/area/p" + str(p) + ".png")
lx = randrange( self._imgsize - tree.width )
ly = randrange( self._imgsize - tree.height )
layer.alpha_composite(tree, (lx, ly))
mstr_msg("layergen", "Layer image completed") mstr_msg("layergen", "Layer image completed")
@ -427,10 +477,7 @@ class mstr_layergen:
if mask_pix[x, y][3] > 0: if mask_pix[x, y][3] > 0:
rgb=layer_pix[x,y] rgb=layer_pix[x,y]
a=mask_pix[x,y] a=mask_pix[x,y]
if self._value == "residential": layer_comp_pix[x, y] = ( rgb[0], rgb[1], rgb[2], a[3])
layer_comp_pix[x, y] = ( rgb[0], rgb[1], rgb[2], int(a[3]/2))
if self._value != "residential":
layer_comp_pix[x, y] = ( rgb[0], rgb[1], rgb[2], a[3])
# For some things, we will need to add a border and then add this to the layer. # For some things, we will need to add a border and then add this to the layer.
layer_border = None layer_border = None
@ -464,6 +511,17 @@ class mstr_layergen:
mstr_msg("layergen", "Adjacent fading completed") mstr_msg("layergen", "Adjacent fading completed")
# Add a white-ish border around pitches
if self._tag == "leisure" and self._value == "pitch":
epx = osm_edge.load()
for y in range(self._imgsize):
for x in range(self._imgsize):
ep = epx[x,y]
if ep[3] > 0:
d = randrange(10,101)
nw = (200-d,200-d,200-d,255)
layer_comp_pix[x,y] = nw
# Store layer # Store layer
if self._is_completion == False: if self._is_completion == False:
layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" ) layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" )
@ -500,18 +558,11 @@ class mstr_layergen:
for x in range(self._imgsize-1): for x in range(self._imgsize-1):
m = mask_pix[x,y] m = mask_pix[x,y]
shf_x = 0 shf_x = 0
# Buildings get slightly closer shadows shf_x = x + mstr_shadow_shift
if self._tag == "building":
shf_x = x + int(mstr_shadow_shift/2)
if self._tag != "building":
shf_x = x + mstr_shadow_shift
if shf_x <= self._imgsize-1: if shf_x <= self._imgsize-1:
a = mask_pix[x,y][3] a = mask_pix[x,y][3]
st = 0 st = 0
if self._tag == "building": st = random.uniform(0.45, mstr_shadow_strength)
st = random.uniform(0.25, mstr_shadow_strength/2)
if self._tag != "building":
st = random.uniform(0.45, mstr_shadow_strength)
ca = a * st ca = a * st
aa = int(ca) aa = int(ca)
shadow_pix[shf_x, y] = (0,0,0,aa) shadow_pix[shf_x, y] = (0,0,0,aa)
@ -583,7 +634,7 @@ class mstr_layergen:
#self._tiledb.close_db() #self._tiledb.close_db()
# Create a water mask we need to remove from the DDS later # Create a water mask we need to remove from the DDS later
if (self._tag == "natural" and self._value == "water") or (self._tag == "water" and self._value == "lake") or (self._tag == "water" and self._value == "pond") or (self._tag == "water" and self._value == "river"): if (self._tag == "natural" and self._value == "water") or (self._tag == "water" and self._value == "lake") or (self._tag == "water" and self._value == "pond") or (self._tag == "water" and self._value == "river") or (self._tag == "leisure" and self._value == "swimming_pool"):
mstr_msg("layergen", "Generating inland water mask") mstr_msg("layergen", "Generating inland water mask")
inl_mask = Image.new("RGBA", (self._imgsize, self._imgsize), (0,0,0,0)) inl_mask = Image.new("RGBA", (self._imgsize, self._imgsize), (0,0,0,0))
lyr_pix = layer_comp.load() lyr_pix = layer_comp.load()
@ -615,10 +666,12 @@ class mstr_layergen:
mstr_msg("layergen", "Edge mask generated") mstr_msg("layergen", "Edge mask generated")
# As above, we will apply the blur as noted in the defines # As above, we will apply the blur as noted in the defines
for i in mstr_mask_blur: # Except for buildings
if i[0] == self._tag and i[1] == self._value: if self._tag != "building":
osm_mask = osm_mask.filter(ImageFilter.BoxBlur(radius=i[2])) for i in mstr_mask_blur:
break if i[0] == self._tag and i[1] == self._value:
osm_mask = osm_mask.filter(ImageFilter.BoxBlur(radius=i[2]))
break
osm_edge = osm_edge.filter(ImageFilter.BoxBlur(radius=1)) osm_edge = osm_edge.filter(ImageFilter.BoxBlur(radius=1))
@ -631,34 +684,6 @@ class mstr_layergen:
edge_pix = osm_edge.load() edge_pix = osm_edge.load()
layer_comp_pix = layer_comp.load() layer_comp_pix = layer_comp.load()
# Let's define some base color ranges for different types of buildings
bld_clr = [
("detached", 190, 192, 195),
("church", 134, 134, 136),
("hotel", 153, 147, 138),
("farm", 145, 124, 121),
("semidetached_house", 167, 163, 152),
("apartments", 129, 134, 127),
("civic", 134, 134, 136),
("garage", 101, 109, 111),
("office", 139, 152, 156),
("retail", 121, 122, 108),
("industrial", 191, 192, 187),
("house", 145, 124, 121),
("terrace", 191, 192, 187),
("hangar", 137, 162, 195),
("school", 111, 117, 115),
("yes", 152, 144, 141)
]
# Find the color index to work with
cidx = 0
if self._tag == "building":
for c in bld_clr:
if c[0] == self._value:
break
cidx = cidx+1
for y in range(self._imgsize): for y in range(self._imgsize):
for x in range(self._imgsize): for x in range(self._imgsize):
if mask_pix[x, y][3] > 0: if mask_pix[x, y][3] > 0:
@ -678,7 +703,7 @@ class mstr_layergen:
d = randrange(41, 61) d = randrange(41, 61)
layer_comp_pix[x, y] = ( d,d,d,a[3] ) layer_comp_pix[x, y] = ( d,d,d,a[3] )
if self._tag == "highway" and self._value != "motorway": if self._tag == "highway" and self._value != "motorway":
d = randrange(140,160) d = randrange(85, 101)
layer_comp_pix[x, y] = ( d,d,d,a[3] ) layer_comp_pix[x, y] = ( d,d,d,a[3] )
if self._tag == "highway" and self._value == "motorway": if self._tag == "highway" and self._value == "motorway":
d = randrange(1,20) d = randrange(1,20)
@ -691,24 +716,28 @@ class mstr_layergen:
# Rock, grass, water # Rock, grass, water
mats = [ (48-d, 45-d, 42-d), (58-d, 81-d, 41-d), (129-d, 148-d, 159-d) ] mats = [ (48-d, 45-d, 42-d), (58-d, 81-d, 41-d), (129-d, 148-d, 159-d) ]
# Pick one of those # Pick one of those
pick = randrange(1,4) #pick = randrange(1,4)
pick = 2
t = a[3]-d t = a[3]-d
if t < 0: t = 0 if t < 0: t = 0
layer_comp_pix[x, y] = ( mats[pick-1][0], mats[pick-1][1], mats[pick-1][2], t ) if e[3] > 0:
layer_comp_pix[x, y] = ( mats[pick-1][0], mats[pick-1][1], mats[pick-1][2], t )
# A bit special here # A bit special here
if self._tag == "building": if self._tag == "building":
# Find a color range for the pixel
# Find a color range
d = randrange(1,21) d = randrange(1,21)
# Bring in some variety by making the one or other pixel darker nr = a[0]+40 - d
dp = randrange(1, 3) ng = a[1]+40 - d
if dp == 2: nb = a[2]+40 - d
d = d + 20 if nr < 0: nr = 0
# Adjust this pixel if ng < 0: ng = 0
c = (bld_clr[cidx][1]-d, bld_clr[cidx][2]-d, bld_clr[cidx][3]-d, 255) if nb < 0: nb = 0
# Set pixel if nr > 255: nr = 255
layer_comp_pix[x, y] = c if ng > 255: ng = 255
if nb > 255: nb = 255
nc = (nr, ng, nb, 255)
layer_comp_pix[x,y] = (nr,ng,nb,255)
if self._value == "track" or self._value == "path": if self._value == "track" or self._value == "path":
d = randrange(1,20) d = randrange(1,20)
@ -717,9 +746,21 @@ class mstr_layergen:
b = 138 - d b = 138 - d
layer_comp_pix[x, y] = ( r,g,b,a[3] ) layer_comp_pix[x, y] = ( r,g,b,a[3] )
# A bit different for tree rows
if self._tag == "natural" and self._value == "tree_row":
for t in range(20001):
lx = randrange(self._imgsize)
ly = randrange(self._imgsize)
a = mask_pix[lx,ly]
if a[3] > 0:
if lx < self._imgsize and ly < self._imgsize:
p = randrange(1,11)
tree = Image.open(mstr_datafolder + "textures/building/area/p" + str(p) + ".png")
layer_comp.alpha_composite(tree, (lx, ly))
# We will do some super magic here to let houses look more realistic # We will do some super magic here to let houses look more realistic
if self._tag == "building" or self._value == "cemetery": if self._tag == "building":
vls = [ "detached", "hotel", "farm", "semidetached_house", "apartments", "civic", "office", "retail", "industrial", "house", "school", "yes" ] vls = [ "detached", "hotel", "farm", "semidetached_house", "apartments", "civic", "house", "school", "kindergarten", "yes" ]
if self._value in vls: if self._value in vls:
# Generate a new image # Generate a new image
details = Image.new("RGBA", (self._imgsize, self._imgsize)) details = Image.new("RGBA", (self._imgsize, self._imgsize))
@ -729,11 +770,11 @@ class mstr_layergen:
for x in range(self._imgsize-1): for x in range(self._imgsize-1):
p = layer_pix[x,y] p = layer_pix[x,y]
if p[3] > 0: if p[3] > 0:
shf_x = x+randrange(1, 21) shf_x = x+randrange(1, 16)
shf_y = y+randrange(1, 21) shf_y = y+randrange(1, 16)
shf_x2 = x-randrange(1, 21) shf_x2 = x-randrange(1, 16)
shf_y2 = y-randrange(1, 21) shf_y2 = y-randrange(1, 16)
if shf_x <= self._imgsize-1 and shf_x >= 0 and shf_y <= self._imgsize-1 and shf_y >= 0: if shf_x < self._imgsize and shf_y < self._imgsize and shf_x2 < self._imgsize and shf_y2 < self._imgsize:
st = random.uniform(0.65, 0.85) st = random.uniform(0.65, 0.85)
ca = 255 * st ca = 255 * st
aa = int(ca) aa = int(ca)
@ -741,18 +782,9 @@ class mstr_layergen:
d2 = randrange(1,26) d2 = randrange(1,26)
details_pix[shf_x, shf_y] = (187-d, 179-d, 176-d, aa) details_pix[shf_x, shf_y] = (187-d, 179-d, 176-d, aa)
details_pix[shf_x2, shf_y2] = (187-d2, 179-d2, 176-d2, aa) details_pix[shf_x2, shf_y2] = (187-d2, 179-d2, 176-d2, aa)
# Merge the details BELOW the houses
details.alpha_composite(layer_comp)
layer_comp = details
# New edge
osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES)
osm_edge = osm_edge.filter(ImageFilter.MaxFilter)
osm_edge = osm_edge.filter(ImageFilter.GaussianBlur(radius=2))
# Blur the image
layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=1))
osm_edge.alpha_composite(layer_comp)
layer_comp = osm_edge
# Let's see how it works with this method
details.save(mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer_details.png")
# Add some random trees # Add some random trees
div = int(self._imgsize/200) div = int(self._imgsize/200)
@ -769,7 +801,7 @@ class mstr_layergen:
# Do some random shift away from this location # Do some random shift away from this location
shf_x = randrange(x-11, x+11) shf_x = randrange(x-11, x+11)
shf_y = randrange(y-11, y+11) shf_y = randrange(y-11, y+11)
if shf_x > 0 and shf_x < self._imgsize and shf_y > 0 and shf_y < self._imgsize: if shf_x < self._imgsize and shf_y < self._imgsize:
# Pick a number of trees to place # Pick a number of trees to place
numtrees = randrange(1, 16) numtrees = randrange(1, 16)
for i in range(1, numtrees+1): for i in range(1, numtrees+1):
@ -798,18 +830,54 @@ class mstr_layergen:
for y in range(self._imgsize-1): for y in range(self._imgsize-1):
for x in range(self._imgsize-1): for x in range(self._imgsize-1):
m = mask_pix[x,y] m = mask_pix[x,y]
shf_x = x + randrange(1, mstr_shadow_shift + 1) shf_x = x + mstr_shadow_shift
shf_x2 = x + randrange(1, mstr_shadow_shift + 1) shf_y = y + (mstr_shadow_shift/2)
if shf_x <= self._imgsize-1 and shf_x >= 0 and shf_x2 <= self._imgsize-1 and shf_x2 >= 0: if shf_x < self._imgsize and shf_y < self._imgsize:
a = mask_pix[x,y][3] a = mask_pix[x,y][3]
st = random.uniform(0.6, mstr_shadow_strength) st = random.uniform(0.3, mstr_shadow_strength)
ca = a * st ca = a * st
aa = int(ca) aa = int(ca)
shadow_pix[shf_x, y] = (0,0,0,aa) shadow_pix[shf_x, shf_y] = (0,0,0,aa)
shadow_pix[shf_x2, y] = (0,0,0,aa) shadow = shadow.filter(ImageFilter.GaussianBlur(radius=2))
shadow.save(mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer_shadow.png") shadow.save(mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer_shadow.png")
mstr_msg("layergen", "Shadow layer completed") mstr_msg("layergen", "Shadow layer completed")
# Some funnies with shadows
if self._tag == "building" and (self._value == "detached" or self._value == "semidetached_house" or self._value == "apartments" or self._value == "civic" or self._value == "house" or self._value == "terrace"):
mask_pix = osm_mask.load()
roofshadow = Image.new("RGBA", (self._imgsize, self._imgsize))
roofpix = roofshadow.load()
# Generate a pseudo shifted roof shadow
for y in range(self._imgsize):
for x in range(self._imgsize):
mp = mask_pix[x,y]
if mp[3] == 255:
nx = x+8
ny = y+4
if nx < self._imgsize and ny < self._imgsize:
roofpix[nx,ny] = (0,0,0,255)
# Now apply the shift where necessary
roofpix = roofshadow.load()
mask_pix = osm_mask.load()
layer_comp_pix = layer_comp.load()
for y in range(self._imgsize):
for x in range(self._imgsize):
rp = roofpix[x,y]
mp = mask_pix[x,y]
if rp[3] == 255 and mp[3] == 255:
c = layer_comp_pix[x,y]
dim = randrange(30,61)
nr = c[0] - dim
ng = c[1] - dim
nb = c[2] - dim
if nr < 0: nr = 0
if ng < 0: ng = 0
if nb < 0: nb = 0
layer_comp_pix[x,y] = (nr, ng, nb, c[3])
#layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=1))
# Highways and runways of any kind get some special treatment # Highways and runways of any kind get some special treatment
if (self._tag == "highway" and self._value == "motorway") or (self._tag == "highway" and self._value == "primary") or (self._tag == "highway" and self._value == "secondary") or (self._tag == "highway" and self._value == "tertiary") or (self._tag == "aeroway" and self._value == "runway"): if (self._tag == "highway" and self._value == "motorway") or (self._tag == "highway" and self._value == "primary") or (self._tag == "highway" and self._value == "secondary") or (self._tag == "highway" and self._value == "tertiary") or (self._tag == "aeroway" and self._value == "runway"):
# We will now add some white lines for coolness # We will now add some white lines for coolness
@ -819,16 +887,27 @@ class mstr_layergen:
for x in range(self._imgsize): for x in range(self._imgsize):
if mask_pix[x, y][3] > 0: if mask_pix[x, y][3] > 0:
# Find a suitable color # Find a suitable color
w = randrange(185, 215) w = randrange(125, 156)
a=mask_pix[x,y] a=mask_pix[x,y]
layer_comp_pix[x, y] = ( w,w,w,a[3] ) layer_comp_pix[x, y] = ( w,w,w,a[3] )
if self._tag == "highway" and self._value == "residential":
mask_pix = osm_edge.load()
layer_comp_pix = layer_comp.load()
for y in range(self._imgsize):
for x in range(self._imgsize):
if mask_pix[x, y][3] > 0:
# Find a suitable color
w = randrange(60, 96)
a=mask_pix[x,y]
layer_comp_pix[x, y] = ( w,w,w,a[3] )
mstr_msg("layergen", "Street lines added") mstr_msg("layergen", "Street lines added")
if self._tag == "waterway" and (self._value == "river" or self._value == "stream"): if self._tag == "waterway" and (self._value == "river" or self._value == "stream"):
layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=4)) layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=4))
# Store layer # Store layer
layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" ) layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" )
mstr_msg("layergen", "Layer image finalized and saved.") mstr_msg("layergen", "Layer image finalized and saved.")
@ -990,3 +1069,28 @@ class mstr_layergen:
# Report our findings # Report our findings
return sources return sources
# Find the next "by-ten" numbers for the current latitude and longitude
def find_earthnavdata_number(self):
earthnavdata = []
lat = abs(int(self._latitude / 10) * 10)
lng = abs(int(self._longitude / 10) * 10)
earthnavdata.append(lat)
earthnavdata.append(lng)
return earthnavdata
# Construct an X-Plane compatible folder name for latitude and longitude
def xplane_latlng_folder(self, numbers):
fstr = ""
if numbers[0] >= 0: fstr = "+"
if numbers[0] < 0: fstr = "-"
if abs(numbers[0]) < 10: fstr = fstr + "0" + str(numbers[0])
if abs(numbers[0]) >= 10 and numbers[0] <= 90: fstr = fstr + str(numbers[0])
if numbers[1] >= 0: fstr = fstr + "+"
if numbers[1] < 0: fstr = fstr + "-"
if abs(numbers[1]) < 10: fstr = fstr + "00" + str(numbers[1])
if abs(numbers[1]) >= 10 and numbers[0] <= 99: fstr = fstr + "0" + str(numbers[1])
if abs(numbers[1]) >= 100 : fstr = fstr + str(numbers[1])
return fstr

View File

@ -170,10 +170,26 @@ class mstr_maskgen:
# Corel Draw! # Corel Draw!
imgd = ImageDraw.Draw(mask_img) imgd = ImageDraw.Draw(mask_img)
# Draw polygons for everything except those three tags # Draw polygons
if self._isline == False: if self._isline == False:
if len(pts) >= 3: if len(pts) >= 3:
imgd.polygon(pts, fill="#000000") if self._tag != "building":
imgd.polygon(pts, fill="#000000")
if self._tag == "building":
# Find ID of color index to use
idx = 0
for i in mstr_building_base_colors:
if i[0] == self._value:
break
else:
idx = idx + 1
# Now we have the index.
# Pick some color from it
c = randrange(len( mstr_building_base_colors[idx][1]))
clr = mstr_building_base_colors[idx][1][c]
# And draw the polygon with that -
# this will be the base color for that building in the layer
imgd.polygon(pts, fill=clr)
# For road specific items, draw lines instead # For road specific items, draw lines instead
if self._isline == True: if self._isline == True:

View File

@ -1,6 +1,6 @@
import os import os
from PIL import Image, ImageFilter from PIL import Image, ImageFilter, ImageEnhance
from defines import * from defines import *
from layergen import * from layergen import *
from log import * from log import *
@ -45,20 +45,58 @@ class mstr_photogen:
# First, we walk through all layers and blend them on top of each other, in order # First, we walk through all layers and blend them on top of each other, in order
mstr_msg("photogen", "Merging layers") mstr_msg("photogen", "Merging layers")
# Shadow merging
bldg_shadow = Image.new("RGBA", (self._imgsize, self._imgsize))
if mstr_shadow_enabled == True:
for l in mstr_ortho_layers:
if l[0] == "building":
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer_shadow.png"):
shd = Image.open(root_filename + l[0] + "-" + l[1] + "_layer_shadow.png")
bldg_shadow.alpha_composite(shd)
# Details merging
bldg_details = Image.new("RGBA", (self._imgsize, self._imgsize))
for l in mstr_ortho_layers:
if l[0] == "building":
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer_details.png"):
dtl = Image.open(root_filename + l[0] + "-" + l[1] + "_layer_details.png")
dtl = dtl.filter(ImageFilter.GaussianBlur(radius=1))
bldg_details.alpha_composite(dtl)
# Building merging
bldg_main = Image.new("RGBA", (self._imgsize, self._imgsize))
for l in mstr_ortho_layers:
if l[0] == "building":
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer.png"):
bld = Image.open(root_filename + l[0] + "-" + l[1] + "_layer.png")
bld = bld.filter(ImageFilter.GaussianBlur(radius=0.35))
bldg_main.alpha_composite(bld)
# Merge the building layers
bldg_final = Image.new("RGBA", (self._imgsize, self._imgsize))
bldg_final.alpha_composite(bldg_details)
bldg_final.alpha_composite(bldg_shadow)
bldg_final.alpha_composite(bldg_main)
for l in mstr_ortho_layers: for l in mstr_ortho_layers:
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer.png"): if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer.png"):
# Need to divert in case we have shadows # Need to divert in case we have shadows
if mstr_shadow_enabled == True: if mstr_shadow_enabled == True:
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer_shadow.png"): if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer_shadow.png"):
sn = root_filename + l[0] + "-" + l[1] + "_layer_shadow.png" if l[0] != "building":
s_layer = Image.open(sn) sn = root_filename + l[0] + "-" + l[1] + "_layer_shadow.png"
self._tile.alpha_composite(s_layer) s_layer = Image.open(sn)
# Complete the file name based on the template self._tile.alpha_composite(s_layer)
fn = root_filename + l[0] + "-" + l[1] + "_layer.png" if l[0] != "building":
# Open the layer # Complete the file name based on the template
layer = Image.open(fn) fn = root_filename + l[0] + "-" + l[1] + "_layer.png"
# Converge the layer with this image # Open the layer
self._tile.alpha_composite(layer) layer = Image.open(fn)
if l[0] == "leisure" and l[1] == "pitch":
layer = layer.filter(ImageFilter.GaussianBlur(radius=0.2))
# Converge the layer with this image
self._tile.alpha_composite(layer)
# Drop the buildings on top
self._tile.alpha_composite(bldg_final)
# When we have run through this loop, we will end up with a sandwiched # When we have run through this loop, we will end up with a sandwiched
# image of all the other images, in their correct order. # image of all the other images, in their correct order.
@ -117,7 +155,8 @@ class mstr_photogen:
["natural", "water"], ["natural", "water"],
["water", "lake"], ["water", "lake"],
["water", "pond"], ["water", "pond"],
["water", "river"] ["water", "river"],
["leisure", "swimming_pool"]
) )
for l in water_layers: for l in water_layers:
fn = mstr_datafolder + "_cache/" + str(self._lat) + "-" + str(self._ty) + "_" + str(self._lng) + "-" + str(self._tx) + "_" + l[0] + "-" + l[1] + "_layer_mask.png" fn = mstr_datafolder + "_cache/" + str(self._lat) + "-" + str(self._ty) + "_" + str(self._lng) + "-" + str(self._tx) + "_" + l[0] + "-" + l[1] + "_layer_mask.png"
@ -147,6 +186,9 @@ class mstr_photogen:
# Scale to correct size. # Scale to correct size.
#self._tile = self._tile.resize((mstr_photores, mstr_photores), Image.Resampling.BILINEAR) #self._tile = self._tile.resize((mstr_photores, mstr_photores), Image.Resampling.BILINEAR)
# Contrast
self._tile = ImageEnhance.Contrast(self._tile).enhance(1)
# This we can save accordingly. # This we can save accordingly.
self._tile.save(mstr_datafolder + "z_orthographic/orthos/" + self._latlngfld + "/" + str(self._ty) + "_" + str(self._tx) + ".png") self._tile.save(mstr_datafolder + "z_orthographic/orthos/" + self._latlngfld + "/" + str(self._ty) + "_" + str(self._tx) + ".png")

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Some files were not shown because too many files have changed in this diff Show More