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.
229
defines.py
@ -53,12 +53,14 @@ mstr_show_log = True
|
||||
# We will simply things to achieve good-looking results.
|
||||
# You can, however, disable the shadow rendering layer here.
|
||||
mstr_shadow_enabled = True
|
||||
mstr_shadow_strength = 0.85
|
||||
mstr_shadow_shift = 24
|
||||
mstr_shadow_strength = 0.65
|
||||
mstr_shadow_shift = 15
|
||||
# The tags that cast shadows
|
||||
mstr_shadow_casters = [
|
||||
("landuse", "forest"),
|
||||
("leisure", "nature_reserve"),
|
||||
("natural", "wood"),
|
||||
("natural", "tree_row"),
|
||||
("building", "semidetached_house"),
|
||||
("building", "apartments"),
|
||||
("building", "garage"),
|
||||
@ -138,6 +140,7 @@ mstr_ortho_layers = [
|
||||
("leisure", "garden", "leisure", "green"),
|
||||
("leisure", "sports_centre", "leisure", "green"),
|
||||
("leisure", "pitch", "leisure", "green"),
|
||||
("leisure", "playground", "leisure", "green"),
|
||||
("landuse", "farmland", "landuse", "farmland"),
|
||||
("landuse", "farmyard", "landuse", "farmland"),
|
||||
("landuse", "military", "landuse", "residential-boundary"),
|
||||
@ -154,6 +157,8 @@ mstr_ortho_layers = [
|
||||
("waterway", "stream", 10),
|
||||
("leisure", "nature_reserve", "landuse", "forest"),
|
||||
("landuse", "forest", "landuse", "forest"),
|
||||
("natural", "wood", "natural", "wood"),
|
||||
("natural", "tree_row", 22),
|
||||
("natural", "wetland", "natural", "wetland"),
|
||||
("natural", "scrub", "natural", "scrub"),
|
||||
("natural", "heath", "natural", "heath"),
|
||||
@ -166,7 +171,9 @@ mstr_ortho_layers = [
|
||||
("water", "lake", "natural", "water"),
|
||||
("water", "pond", "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),
|
||||
# Z-Order 4
|
||||
("highway", "motorway", 32),
|
||||
@ -189,6 +196,9 @@ mstr_ortho_layers = [
|
||||
("building", "terrace", "building", "industrial"),
|
||||
("building", "hangar", "building", "industrial"),
|
||||
("building", "school", "building", "common"),
|
||||
("building", "kindergarten", "building", "kindergarten"),
|
||||
("building", "public", "building", "public"),
|
||||
("building", "commercial", "building", "commercial"),
|
||||
("building", "yes", "building", "common"),
|
||||
("place", "sea", "natural", "sea"),
|
||||
("place", "ocean", "natural", "sea")
|
||||
@ -198,33 +208,36 @@ mstr_ortho_layers = [
|
||||
# Blur values for the single masks of the ortho layers
|
||||
mstr_mask_blur = [
|
||||
# Z-Order 0
|
||||
("landuse", "residential", 30),
|
||||
("boundary", "administrative", 30),
|
||||
("landuse", "residential", 20),
|
||||
("boundary", "administrative", 20),
|
||||
# Z-Order 1
|
||||
("landuse", "grass", 30),
|
||||
("landuse", "cemetery", 30),
|
||||
("landuse", "greenfield", 30),
|
||||
("landuse", "orchard", 30),
|
||||
("landuse", "meadow", 30),
|
||||
("barrier", "hedge", 5),
|
||||
("landuse", "grass", 12),
|
||||
("landuse", "cemetery", 12),
|
||||
("landuse", "greenfield", 12),
|
||||
("landuse", "orchard", 12),
|
||||
("landuse", "meadow", 12),
|
||||
("barrier", "hedge", 1),
|
||||
("landuse", "recreation_ground", 20),
|
||||
("landuse", "vineyard", 30),
|
||||
("natural", "grassland", 30),
|
||||
("landuse", "vineyard", 12),
|
||||
("natural", "grassland", 12),
|
||||
("natural", "wetland", 30),
|
||||
("natural", "scrub", 20),
|
||||
("natural", "heath", 20),
|
||||
("leisure", "park", 30),
|
||||
("natural", "scrub", 15),
|
||||
("natural", "heath", 15),
|
||||
("leisure", "park", 15),
|
||||
("leisure", "golf_course", 25),
|
||||
("leisure", "dog_park", 35),
|
||||
("leisure", "dog_park", 15),
|
||||
("leisure", "garden", 20),
|
||||
("leisure", "sports_centre", 5),
|
||||
("leisure", "pitch", 2),
|
||||
("leisure", "playground", 2),
|
||||
("landuse", "farmland", 10),
|
||||
("landuse", "farmyard", 10),
|
||||
# Z-Order 2
|
||||
("landuse", "forest", 20),
|
||||
("leisure", "nature_reserve", 20),
|
||||
("landuse", "military", 30),
|
||||
("landuse", "forest", 8),
|
||||
("leisure", "nature_reserve", 8),
|
||||
("natural", "wood", 8),
|
||||
("natural", "tree_row", 8),
|
||||
("landuse", "military", 15),
|
||||
# Z-Order 3
|
||||
("natural", "bare_rock", 25),
|
||||
("natural", "water", 4),
|
||||
@ -233,26 +246,28 @@ mstr_mask_blur = [
|
||||
("water", "lake", 10),
|
||||
("water", "pond", 10),
|
||||
("water", "river", 10),
|
||||
("leisure", "swimming_pool", 10),
|
||||
("waterway", "river", 10),
|
||||
("waterway", "stream", 10),
|
||||
("amenity", "parking", 3),
|
||||
("amenity", "parking", 1),
|
||||
("amenity", "school", 1),
|
||||
("highway", "pedestrian", 12),
|
||||
# Z-Order 4
|
||||
("highway", "motorway", 5),
|
||||
("highway", "primary", 5),
|
||||
("highway", "secondary", 5),
|
||||
("highway", "tertiary", 5),
|
||||
("highway", "unclassified", 5),
|
||||
("highway", "living_street", 5),
|
||||
("highway", "residential", 5),
|
||||
("highway", "service", 3),
|
||||
("highway", "footway", 3),
|
||||
("highway", "track", 3),
|
||||
("highway", "path", 3),
|
||||
("railway", "rail", 4),
|
||||
("highway", "motorway", 2),
|
||||
("highway", "primary", 2),
|
||||
("highway", "secondary", 2),
|
||||
("highway", "tertiary", 2),
|
||||
("highway", "unclassified", 2),
|
||||
("highway", "living_street", 2),
|
||||
("highway", "residential", 2),
|
||||
("highway", "service", 2),
|
||||
("highway", "footway", 2),
|
||||
("highway", "track", 2),
|
||||
("highway", "path", 2),
|
||||
("railway", "rail", 2),
|
||||
# Z-Order 5
|
||||
("aeroway", "taxiway", 12),
|
||||
("aeroway", "runway", 12),
|
||||
("aeroway", "taxiway", 2),
|
||||
("aeroway", "runway", 2),
|
||||
("building", "detached", 1),
|
||||
("building", "church", 1),
|
||||
("building", "hotel", 1),
|
||||
@ -268,7 +283,149 @@ mstr_mask_blur = [
|
||||
("building", "terrace", 1),
|
||||
("building", "hangar", 1),
|
||||
("building", "school", 1),
|
||||
("building", "yes", 1),
|
||||
("building", "kindergarten", 1),
|
||||
("building", "public", 1),
|
||||
("building", "commercial", 1),
|
||||
("building", "yes", 0),
|
||||
("place", "sea", 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)
|
||||
]
|
||||
)
|
||||
]
|
302
layergen.py
@ -16,7 +16,7 @@ import glob
|
||||
import os
|
||||
from random import randrange
|
||||
import random
|
||||
from PIL import Image, ImageFilter, ImageDraw, ImagePath
|
||||
from PIL import Image, ImageFilter, ImageDraw, ImagePath, ImageEnhance
|
||||
from defines import *
|
||||
from log import *
|
||||
from tileinfo import *
|
||||
@ -399,20 +399,70 @@ class mstr_layergen:
|
||||
layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) )
|
||||
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
|
||||
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")
|
||||
|
||||
|
||||
@ -427,10 +477,7 @@ class mstr_layergen:
|
||||
if mask_pix[x, y][3] > 0:
|
||||
rgb=layer_pix[x,y]
|
||||
a=mask_pix[x,y]
|
||||
if self._value == "residential":
|
||||
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])
|
||||
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.
|
||||
layer_border = None
|
||||
@ -464,6 +511,17 @@ class mstr_layergen:
|
||||
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
|
||||
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" )
|
||||
@ -500,18 +558,11 @@ class mstr_layergen:
|
||||
for x in range(self._imgsize-1):
|
||||
m = mask_pix[x,y]
|
||||
shf_x = 0
|
||||
# Buildings get slightly closer shadows
|
||||
if self._tag == "building":
|
||||
shf_x = x + int(mstr_shadow_shift/2)
|
||||
if self._tag != "building":
|
||||
shf_x = x + mstr_shadow_shift
|
||||
shf_x = x + mstr_shadow_shift
|
||||
if shf_x <= self._imgsize-1:
|
||||
a = mask_pix[x,y][3]
|
||||
st = 0
|
||||
if self._tag == "building":
|
||||
st = random.uniform(0.25, mstr_shadow_strength/2)
|
||||
if self._tag != "building":
|
||||
st = random.uniform(0.45, mstr_shadow_strength)
|
||||
st = random.uniform(0.45, mstr_shadow_strength)
|
||||
ca = a * st
|
||||
aa = int(ca)
|
||||
shadow_pix[shf_x, y] = (0,0,0,aa)
|
||||
@ -583,7 +634,7 @@ class mstr_layergen:
|
||||
#self._tiledb.close_db()
|
||||
|
||||
# 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")
|
||||
inl_mask = Image.new("RGBA", (self._imgsize, self._imgsize), (0,0,0,0))
|
||||
lyr_pix = layer_comp.load()
|
||||
@ -615,10 +666,12 @@ class mstr_layergen:
|
||||
mstr_msg("layergen", "Edge mask generated")
|
||||
|
||||
# As above, we will apply the blur as noted in the defines
|
||||
for i in mstr_mask_blur:
|
||||
if i[0] == self._tag and i[1] == self._value:
|
||||
osm_mask = osm_mask.filter(ImageFilter.BoxBlur(radius=i[2]))
|
||||
break
|
||||
# Except for buildings
|
||||
if self._tag != "building":
|
||||
for i in mstr_mask_blur:
|
||||
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))
|
||||
|
||||
|
||||
@ -631,34 +684,6 @@ class mstr_layergen:
|
||||
edge_pix = osm_edge.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 x in range(self._imgsize):
|
||||
if mask_pix[x, y][3] > 0:
|
||||
@ -678,7 +703,7 @@ class mstr_layergen:
|
||||
d = randrange(41, 61)
|
||||
layer_comp_pix[x, y] = ( d,d,d,a[3] )
|
||||
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] )
|
||||
if self._tag == "highway" and self._value == "motorway":
|
||||
d = randrange(1,20)
|
||||
@ -691,24 +716,28 @@ class mstr_layergen:
|
||||
# Rock, grass, water
|
||||
mats = [ (48-d, 45-d, 42-d), (58-d, 81-d, 41-d), (129-d, 148-d, 159-d) ]
|
||||
# Pick one of those
|
||||
pick = randrange(1,4)
|
||||
#pick = randrange(1,4)
|
||||
pick = 2
|
||||
t = a[3]-d
|
||||
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
|
||||
if self._tag == "building":
|
||||
|
||||
# Find a color range
|
||||
# Find a color range for the pixel
|
||||
d = randrange(1,21)
|
||||
# Bring in some variety by making the one or other pixel darker
|
||||
dp = randrange(1, 3)
|
||||
if dp == 2:
|
||||
d = d + 20
|
||||
# Adjust this pixel
|
||||
c = (bld_clr[cidx][1]-d, bld_clr[cidx][2]-d, bld_clr[cidx][3]-d, 255)
|
||||
# Set pixel
|
||||
layer_comp_pix[x, y] = c
|
||||
nr = a[0]+40 - d
|
||||
ng = a[1]+40 - d
|
||||
nb = a[2]+40 - d
|
||||
if nr < 0: nr = 0
|
||||
if ng < 0: ng = 0
|
||||
if nb < 0: nb = 0
|
||||
if nr > 255: nr = 255
|
||||
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":
|
||||
d = randrange(1,20)
|
||||
@ -717,9 +746,21 @@ class mstr_layergen:
|
||||
b = 138 - d
|
||||
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
|
||||
if self._tag == "building" or self._value == "cemetery":
|
||||
vls = [ "detached", "hotel", "farm", "semidetached_house", "apartments", "civic", "office", "retail", "industrial", "house", "school", "yes" ]
|
||||
if self._tag == "building":
|
||||
vls = [ "detached", "hotel", "farm", "semidetached_house", "apartments", "civic", "house", "school", "kindergarten", "yes" ]
|
||||
if self._value in vls:
|
||||
# Generate a new image
|
||||
details = Image.new("RGBA", (self._imgsize, self._imgsize))
|
||||
@ -729,11 +770,11 @@ class mstr_layergen:
|
||||
for x in range(self._imgsize-1):
|
||||
p = layer_pix[x,y]
|
||||
if p[3] > 0:
|
||||
shf_x = x+randrange(1, 21)
|
||||
shf_y = y+randrange(1, 21)
|
||||
shf_x2 = x-randrange(1, 21)
|
||||
shf_y2 = y-randrange(1, 21)
|
||||
if shf_x <= self._imgsize-1 and shf_x >= 0 and shf_y <= self._imgsize-1 and shf_y >= 0:
|
||||
shf_x = x+randrange(1, 16)
|
||||
shf_y = y+randrange(1, 16)
|
||||
shf_x2 = x-randrange(1, 16)
|
||||
shf_y2 = y-randrange(1, 16)
|
||||
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)
|
||||
ca = 255 * st
|
||||
aa = int(ca)
|
||||
@ -741,18 +782,9 @@ class mstr_layergen:
|
||||
d2 = randrange(1,26)
|
||||
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)
|
||||
# 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
|
||||
div = int(self._imgsize/200)
|
||||
@ -769,7 +801,7 @@ class mstr_layergen:
|
||||
# Do some random shift away from this location
|
||||
shf_x = randrange(x-11, x+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
|
||||
numtrees = randrange(1, 16)
|
||||
for i in range(1, numtrees+1):
|
||||
@ -798,18 +830,54 @@ class mstr_layergen:
|
||||
for y in range(self._imgsize-1):
|
||||
for x in range(self._imgsize-1):
|
||||
m = mask_pix[x,y]
|
||||
shf_x = x + randrange(1, mstr_shadow_shift + 1)
|
||||
shf_x2 = x + randrange(1, mstr_shadow_shift + 1)
|
||||
if shf_x <= self._imgsize-1 and shf_x >= 0 and shf_x2 <= self._imgsize-1 and shf_x2 >= 0:
|
||||
shf_x = x + mstr_shadow_shift
|
||||
shf_y = y + (mstr_shadow_shift/2)
|
||||
if shf_x < self._imgsize and shf_y < self._imgsize:
|
||||
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
|
||||
aa = int(ca)
|
||||
shadow_pix[shf_x, y] = (0,0,0,aa)
|
||||
shadow_pix[shf_x2, y] = (0,0,0,aa)
|
||||
shadow_pix[shf_x, shf_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")
|
||||
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
|
||||
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
|
||||
@ -819,16 +887,27 @@ class mstr_layergen:
|
||||
for x in range(self._imgsize):
|
||||
if mask_pix[x, y][3] > 0:
|
||||
# Find a suitable color
|
||||
w = randrange(185, 215)
|
||||
w = randrange(125, 156)
|
||||
a=mask_pix[x,y]
|
||||
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")
|
||||
|
||||
if self._tag == "waterway" and (self._value == "river" or self._value == "stream"):
|
||||
layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=4))
|
||||
|
||||
|
||||
# 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" )
|
||||
mstr_msg("layergen", "Layer image finalized and saved.")
|
||||
@ -990,3 +1069,28 @@ class mstr_layergen:
|
||||
|
||||
# Report our findings
|
||||
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
|
||||
|
20
maskgen.py
@ -170,10 +170,26 @@ class mstr_maskgen:
|
||||
# Corel Draw!
|
||||
imgd = ImageDraw.Draw(mask_img)
|
||||
|
||||
# Draw polygons for everything except those three tags
|
||||
# Draw polygons
|
||||
if self._isline == False:
|
||||
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
|
||||
if self._isline == True:
|
||||
|
64
photogen.py
@ -1,6 +1,6 @@
|
||||
|
||||
import os
|
||||
from PIL import Image, ImageFilter
|
||||
from PIL import Image, ImageFilter, ImageEnhance
|
||||
from defines import *
|
||||
from layergen 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
|
||||
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:
|
||||
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer.png"):
|
||||
# Need to divert in case we have shadows
|
||||
if mstr_shadow_enabled == True:
|
||||
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer_shadow.png"):
|
||||
sn = root_filename + l[0] + "-" + l[1] + "_layer_shadow.png"
|
||||
s_layer = Image.open(sn)
|
||||
self._tile.alpha_composite(s_layer)
|
||||
# Complete the file name based on the template
|
||||
fn = root_filename + l[0] + "-" + l[1] + "_layer.png"
|
||||
# Open the layer
|
||||
layer = Image.open(fn)
|
||||
# Converge the layer with this image
|
||||
self._tile.alpha_composite(layer)
|
||||
if l[0] != "building":
|
||||
sn = root_filename + l[0] + "-" + l[1] + "_layer_shadow.png"
|
||||
s_layer = Image.open(sn)
|
||||
self._tile.alpha_composite(s_layer)
|
||||
if l[0] != "building":
|
||||
# Complete the file name based on the template
|
||||
fn = root_filename + l[0] + "-" + l[1] + "_layer.png"
|
||||
# Open the 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
|
||||
# image of all the other images, in their correct order.
|
||||
@ -117,7 +155,8 @@ class mstr_photogen:
|
||||
["natural", "water"],
|
||||
["water", "lake"],
|
||||
["water", "pond"],
|
||||
["water", "river"]
|
||||
["water", "river"],
|
||||
["leisure", "swimming_pool"]
|
||||
)
|
||||
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"
|
||||
@ -147,6 +186,9 @@ class mstr_photogen:
|
||||
# Scale to correct size.
|
||||
#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.
|
||||
self._tile.save(mstr_datafolder + "z_orthographic/orthos/" + self._latlngfld + "/" + str(self._ty) + "_" + str(self._tx) + ".png")
|
||||
|
||||
|
BIN
textures/amenity/parking/brd/b1.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
textures/amenity/parking/ptc/b1_p1.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
textures/amenity/school/brd/b1.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
textures/amenity/school/ptc/b1_p1.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
textures/barrier/hedge/brd/b1.png
Normal file
After Width: | Height: | Size: 2.9 MiB |
BIN
textures/barrier/hedge/brd/b2.png
Normal file
After Width: | Height: | Size: 2.7 MiB |
BIN
textures/barrier/hedge/brd/b3.png
Normal file
After Width: | Height: | Size: 2.8 MiB |
BIN
textures/barrier/hedge/ptc/b1_p1.png
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
textures/barrier/hedge/ptc/b1_p2.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
textures/barrier/hedge/ptc/b2_p1.png
Normal file
After Width: | Height: | Size: 557 KiB |
BIN
textures/barrier/hedge/ptc/b2_p2.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
textures/barrier/hedge/ptc/b3_p1.png
Normal file
After Width: | Height: | Size: 486 KiB |
BIN
textures/barrier/hedge/ptc/b3_p2.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 6.8 KiB |
BIN
textures/landuse/farmyard/brd/b1.png
Normal file
After Width: | Height: | Size: 2.7 MiB |
BIN
textures/landuse/farmyard/brd/b10.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
textures/landuse/farmyard/brd/b11.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
BIN
textures/landuse/farmyard/brd/b12.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
textures/landuse/farmyard/brd/b13.png
Normal file
After Width: | Height: | Size: 3.4 MiB |
BIN
textures/landuse/farmyard/brd/b14.png
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
textures/landuse/farmyard/brd/b15.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
textures/landuse/farmyard/brd/b16.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
textures/landuse/farmyard/brd/b2.png
Normal file
After Width: | Height: | Size: 3.1 MiB |
BIN
textures/landuse/farmyard/brd/b3.png
Normal file
After Width: | Height: | Size: 2.8 MiB |
BIN
textures/landuse/farmyard/brd/b4.png
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
textures/landuse/farmyard/brd/b5.png
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
textures/landuse/farmyard/brd/b6.png
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
textures/landuse/farmyard/brd/b7.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
textures/landuse/farmyard/brd/b8.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
BIN
textures/landuse/farmyard/brd/b9.png
Normal file
After Width: | Height: | Size: 2.7 MiB |
BIN
textures/landuse/farmyard/ptc/b10_p1.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
textures/landuse/farmyard/ptc/b10_p2.png
Normal file
After Width: | Height: | Size: 828 KiB |
BIN
textures/landuse/farmyard/ptc/b11_p1.png
Normal file
After Width: | Height: | Size: 978 KiB |
BIN
textures/landuse/farmyard/ptc/b11_p2.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
textures/landuse/farmyard/ptc/b12_p1.png
Normal file
After Width: | Height: | Size: 922 KiB |
BIN
textures/landuse/farmyard/ptc/b12_p2.png
Normal file
After Width: | Height: | Size: 877 KiB |
BIN
textures/landuse/farmyard/ptc/b13_p1.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
textures/landuse/farmyard/ptc/b13_p2.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
textures/landuse/farmyard/ptc/b14_p1.png
Normal file
After Width: | Height: | Size: 859 KiB |
BIN
textures/landuse/farmyard/ptc/b14_p2.png
Normal file
After Width: | Height: | Size: 911 KiB |
BIN
textures/landuse/farmyard/ptc/b15_p1.png
Normal file
After Width: | Height: | Size: 668 KiB |
BIN
textures/landuse/farmyard/ptc/b15_p2.png
Normal file
After Width: | Height: | Size: 718 KiB |
BIN
textures/landuse/farmyard/ptc/b16_p1.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
textures/landuse/farmyard/ptc/b16_p2.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
textures/landuse/farmyard/ptc/b1_p1.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
textures/landuse/farmyard/ptc/b1_p2.png
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
textures/landuse/farmyard/ptc/b2_p1.png
Normal file
After Width: | Height: | Size: 2.7 MiB |
BIN
textures/landuse/farmyard/ptc/b2_p2.png
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
textures/landuse/farmyard/ptc/b3_p1.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
textures/landuse/farmyard/ptc/b3_p2.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
textures/landuse/farmyard/ptc/b4_p1.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
textures/landuse/farmyard/ptc/b4_p2.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
textures/landuse/farmyard/ptc/b5_p1.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
textures/landuse/farmyard/ptc/b5_p2.png
Normal file
After Width: | Height: | Size: 2.0 MiB |
BIN
textures/landuse/farmyard/ptc/b6_p1.png
Normal file
After Width: | Height: | Size: 999 KiB |
BIN
textures/landuse/farmyard/ptc/b6_p2.png
Normal file
After Width: | Height: | Size: 866 KiB |
BIN
textures/landuse/farmyard/ptc/b7_p1.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
textures/landuse/farmyard/ptc/b7_p2.png
Normal file
After Width: | Height: | Size: 969 KiB |
BIN
textures/landuse/farmyard/ptc/b8_p1.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
textures/landuse/farmyard/ptc/b8_p2.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
textures/landuse/farmyard/ptc/b9_p1.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
textures/landuse/farmyard/ptc/b9_p2.png
Normal file
After Width: | Height: | Size: 978 KiB |
BIN
textures/landuse/orchard/brd/b1.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
textures/landuse/orchard/brd/b2.png
Normal file
After Width: | Height: | Size: 2.5 MiB |
BIN
textures/landuse/orchard/brd/b3.png
Normal file
After Width: | Height: | Size: 2.6 MiB |
BIN
textures/landuse/orchard/brd/b4.png
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
textures/landuse/orchard/ptc/b1_p1.png
Normal file
After Width: | Height: | Size: 800 KiB |
BIN
textures/landuse/orchard/ptc/b1_p2.png
Normal file
After Width: | Height: | Size: 794 KiB |
BIN
textures/landuse/orchard/ptc/b2_p1.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
textures/landuse/orchard/ptc/b2_p2.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
textures/landuse/orchard/ptc/b3_p1.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
textures/landuse/orchard/ptc/b3_p2.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
textures/landuse/orchard/ptc/b4_p1.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
textures/landuse/orchard/ptc/b4_p2.png
Normal file
After Width: | Height: | Size: 994 KiB |
BIN
textures/landuse/residential/brd/b1.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
textures/landuse/residential/brd/b2.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
textures/landuse/residential/brd/b3.png
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
textures/landuse/residential/ptc/b1_p1.png
Normal file
After Width: | Height: | Size: 958 KiB |
BIN
textures/landuse/residential/ptc/b1_p2.png
Normal file
After Width: | Height: | Size: 578 KiB |
BIN
textures/landuse/residential/ptc/b2_p1.png
Normal file
After Width: | Height: | Size: 871 KiB |
BIN
textures/landuse/residential/ptc/b2_p2.png
Normal file
After Width: | Height: | Size: 716 KiB |
BIN
textures/landuse/residential/ptc/b3_p1.png
Normal file
After Width: | Height: | Size: 899 KiB |
BIN
textures/landuse/residential/ptc/b3_p2.png
Normal file
After Width: | Height: | Size: 904 KiB |
BIN
textures/leisure/nature_reserve/_backup/p1.png
Normal file
After Width: | Height: | Size: 220 KiB |
BIN
textures/leisure/nature_reserve/_backup/p10.png
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
textures/leisure/nature_reserve/_backup/p11.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
textures/leisure/nature_reserve/_backup/p12.png
Normal file
After Width: | Height: | Size: 496 KiB |