From: Marcus Str. Date: Tue, 8 Oct 2024 19:20:51 +0000 (+0200) Subject: Added textures. Changes to shadow generation. Refinements to layers and blurs. Made... X-Git-Url: https://marstr.online/code/gitweb.cgi?a=commitdiff_plain;h=be750bd53c3fd362a7d59dea6da394f3ea2f2dc9;p=marstr%2Forthographic.git Added textures. Changes to shadow generation. Refinements to layers and blurs. Made sure roads appear correctly. Removed streams for inland cutting as those are barely visible on actual satellite images. Proper testing to be done, close to public release. --- diff --git a/defines.py b/defines.py index b162937..033d61b 100644 --- a/defines.py +++ b/defines.py @@ -22,7 +22,7 @@ mstr_datafolder = "/home/marcus/Data/Developer/Projects/orthographic/" mstr_osm_endpoint = "https://marstr.online/osm/v1/" # Define the texture resolution you want to have your photos at. -mstr_photores = 2048 # <- Change this to 4096 for 16k resolution +mstr_photores = 2048 # Radius of zoom level 18 aerials around airports with ICAO code # Value is in tiles - not in km @@ -54,20 +54,13 @@ mstr_show_log = True # You can, however, disable the shadow rendering layer here. mstr_shadow_enabled = True mstr_shadow_strength = 0.65 -mstr_shadow_shift = 15 +mstr_shadow_shift = 16 +mstr_shadow_floor_h = 2.8 # 2.5m ceiling height + 30cm concrete per floor # 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"), - ("building", "office"), - ("building", "retail"), - ("building", "industrial"), - ("building", "yes") + ("natural", "wood") ] @@ -248,19 +241,19 @@ mstr_mask_blur = [ ("water", "river", 10), ("leisure", "swimming_pool", 10), ("waterway", "river", 10), - ("waterway", "stream", 2), + ("waterway", "stream", 4), ("amenity", "parking", 1), ("amenity", "school", 1), ("highway", "pedestrian", 12), # Z-Order 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", "motorway", 1), + ("highway", "primary", 1), + ("highway", "secondary", 1), + ("highway", "tertiary", 1), + ("highway", "unclassified", 1), + ("highway", "living_street", 1), + ("highway", "residential", 1), + ("highway", "service", 1), ("highway", "footway", 2), ("highway", "track", 2), ("highway", "path", 2), @@ -395,8 +388,6 @@ mstr_building_base_colors = [ ] ), ("yes", [ - "#693333", "#592b2b", "#513434", "#4a1e1e", "#362626", - "#534136", "#4d3424", "#534b45", "#553724", "#574c45", "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651", "#454545", "#39393b", "#4b4b4c", "#363638", "#525252" ] diff --git a/functions.py b/functions.py index 664a875..b424fe2 100644 --- a/functions.py +++ b/functions.py @@ -86,3 +86,8 @@ def in_circle(center_x, center_y, radius, x, y): return square_dist <= radius ** 2 +# Find meters per pixel. Requires width of tile in meters +# Needed for proper approximation of shadow length per building level +def meters_per_pixel(lngwidth): + mpx = lngwidth / mstr_photores + return mpx diff --git a/layergen.py b/layergen.py index 75f1e3a..a2ae152 100644 --- a/layergen.py +++ b/layergen.py @@ -87,11 +87,13 @@ class mstr_layergen: brd_src = Image.open(root_folder + "/brd/b" + str(src) + ".png") ptc_src = [] for p in ptc: - ptc_src.append(Image.open(p)) + pimg = Image.open(p) + pimg = pimg.rotate(randrange(0, 360), expand=True) + ptc_src.append(pimg) mstr_msg("layergen", "Border sources selected") # Begin producing a largely random image - samples = 250 # <- We need this in a moment + samples = 250 # <- We need this in a moment for i in range(samples): imgid = 0 if len(ptc_src) == 1: imgid = 0 @@ -455,13 +457,28 @@ class mstr_layergen: # 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"): + trees = Image.new("RGBA", (self._imgsize, self._imgsize)) amt = 3500 for i in range(1, amt+1): - p = randrange(1, 11) + p = randrange(1, 16) 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)) + trees.alpha_composite(tree, (lx, ly)) + + tree_shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) + tree_pix = trees.load() + shadow_pix = tree_shadow.load() + for y in range(self._imgsize): + for x in range(self._imgsize): + tp = tree_pix[x,y] + if tp[3] > 0: + sc = (0,0,0,180) + if x+8 < self._imgsize and y+5 < self._imgsize: + shadow_pix[x+8,y+5] = sc + tree_shadow = tree_shadow.filter(ImageFilter.GaussianBlur(radius=2)) + tree_shadow.alpha_composite(trees) + layer.alpha_composite(tree_shadow) mstr_msg("layergen", "Layer image completed") @@ -527,9 +544,21 @@ class mstr_layergen: if self._tag == "landuse" and self._value == "forest": # The residential layer MUST exist before we reach the forest part. fn = mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_landuse-residential_layer.png" - if os.path.isfile(fn) == True: + if os.path.isfile(fn): rsd = Image.open(fn) - layer_comp.alpha_composite(rsd) + rsd_pix = rsd.load() + forest_layer = Image.new("RGBA", (self._imgsize, self._imgsize)) + for_pix = forest_layer.load() + for y in range(self._imgsize): + for x in range(self._imgsize): + rpix = rsd_pix[x,y] + lpix = layer_comp_pix[x,y] + if rpix[3] > 0 and lpix[3] > 0: + for_pix[x,y] = (rpix[0], rpix[1], rpix[2], rpix[3]) + layer_comp.alpha_composite(forest_layer) + #if os.path.isfile(fn) == True: + # rsd = Image.open(fn) + # layer_comp.alpha_composite(rsd) # Store layer if self._is_completion == False: @@ -563,18 +592,40 @@ class mstr_layergen: mstr_msg("layergen", "Generating shadow for layer") shadow_pix = shadow.load() mask_pix = osm_mask.load() + shf = 1 + while shf < mstr_shadow_shift: + for y in range(self._imgsize): + for x in range(self._imgsize): + mp = layer_comp_pix[x,y] + if mp[3] == 255: + if x+(shf*2) < self._imgsize and y+shf < self._imgsize: + rndshd = randrange(5, 210) + shadow_pix[x+(shf*2), y+shf] = (0,0,0,rndshd) + shf = shf+1 + + # Tree removal + for y in range(self._imgsize): + for x in range(self._imgsize): + lp = layer_comp_pix[x,y] + if lp[3] >= 250: + shadow_pix[x,y] = (0,0,0,0) + + shadow = shadow.filter(ImageFilter.GaussianBlur(radius=2)) + + """ for y in range(self._imgsize-1): for x in range(self._imgsize-1): m = mask_pix[x,y] shf_x = 0 shf_x = x + mstr_shadow_shift - if shf_x <= self._imgsize-1: + if shf_x < self._imgsize: a = mask_pix[x,y][3] st = 0 st = random.uniform(0.45, mstr_shadow_strength) ca = a * st aa = int(ca) shadow_pix[shf_x, y] = (0,0,0,aa) + """ 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") @@ -643,7 +694,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") or (self._tag == "leisure" and self._value == "swimming_pool") or (self._tag == "waterway" and self._value == "stream"): + 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() @@ -681,7 +732,6 @@ class mstr_layergen: 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)) # And now for the Big Mac. @@ -712,14 +762,15 @@ 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(85, 101) - layer_comp_pix[x, y] = ( d,d,d,a[3] ) + dr = randrange(110,121) + dg = randrange(110,121) + db = randrange(115,130) + layer_comp_pix[x, y] = ( dr,dg,db,a[3] ) if self._tag == "highway" and self._value == "motorway": - d = randrange(1,20) - r = 86-d - g = 97-d - b = 106-d - layer_comp_pix[x, y] = ( r,g,b,a[3] ) + dr = randrange(77,89) + dg = randrange(88,96) + db = randrange(90,101) + layer_comp_pix[x, y] = ( dr,dg,db,a[3] ) if self._tag == "waterway" and (self._value == "stream" or self._value == "river"): d = randrange(1, 15) # Rock, grass, water @@ -730,7 +781,7 @@ class mstr_layergen: t = a[3]-d if t < 0: t = 0 if e[3] > 0: - layer_comp_pix[x, y] = ( mats[pick-1][0], mats[pick-1][1], mats[pick-1][2], t ) + layer_comp_pix[x, y] = ( mats[pick-1][0], mats[pick-1][1], mats[pick-1][2], 35 ) # A bit special here if self._tag == "building": @@ -757,15 +808,31 @@ class mstr_layergen: # A bit different for tree rows if self._tag == "natural" and self._value == "tree_row": + trees = Image.new("RGBA", (self._imgsize, self._imgsize)) 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) + p = randrange(1,16) tree = Image.open(mstr_datafolder + "textures/building/area/p" + str(p) + ".png") - layer_comp.alpha_composite(tree, (lx, ly)) + trees.alpha_composite(tree, (lx, ly)) + if mstr_shadow_enabled == True: + tree_shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) + tree_pix = trees.load() + shadow_pix = tree_shadow.load() + for y in range(self._imgsize): + for x in range(self._imgsize): + tp = tree_pix[x,y] + if tp[3] > 0: + rndshd = randrange(5, 210) + sc = (0,0,0,rndshd) + if x+8 < self._imgsize and y+5 < self._imgsize: + shadow_pix[x+8,y+5] = sc + tree_shadow = tree_shadow.filter(ImageFilter.GaussianBlur(radius=2)) + tree_shadow.alpha_composite(trees) + layer_comp.alpha_composite(tree_shadow) # We will do some super magic here to let houses look more realistic if self._tag == "building": @@ -815,7 +882,7 @@ class mstr_layergen: numtrees = randrange(1, 16) for i in range(1, numtrees+1): # Pick some file - pick = str(randrange(1, 11)) + pick = str(randrange(1, 16)) tree = Image.open(mstr_datafolder + "textures/building/area/p" + pick + ".png") # Do a correction for the location if needed if shf_x < 1: shf_x = 1 @@ -823,33 +890,39 @@ class mstr_layergen: if shf_x > self._imgsize - tree.width: shf_x = self._imgsize - tree.width - 1 if shf_y > self._imgsize - tree.height: shf_y = self._imgsize - tree.height - 1 trees.alpha_composite(tree, (shf_x, shf_y)) - trees.alpha_composite(layer_comp) - layer_comp = trees - + if mstr_shadow_enabled == True: + tree_shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) + tree_pix = trees.load() + shadow_pix = tree_shadow.load() + for y in range(self._imgsize): + for x in range(self._imgsize): + tp = tree_pix[x,y] + if tp[3] > 0: + sc = (0,0,0,180) + if x+8 < self._imgsize and y+5 < self._imgsize: + shadow_pix[x+8,y+5] = sc + tree_shadow = tree_shadow.filter(ImageFilter.GaussianBlur(radius=2)) + tree_shadow.alpha_composite(trees) + + # Save this separately, so that we can blur buildings, but not the trees + fn = mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer_building_trees.png" + + if os.path.isfile(fn) == True: + extrees = Image.open(fn) + extrees.alpha_composite(tree_shadow) + extrees.save(fn) + else: + tree_shadow.save(fn) + + #layer_comp.alpha_composite(tree_shadow) + #tree_shadow.alpha_composite(layer_comp) + #layer_comp = tree_shadow + mstr_msg("layergen", "Layer image generated") # Building shadow if mstr_shadow_enabled == True: - if self._tag == "building": - mstr_msg("layergen", "Generating shadow for layer") - shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) - shadow_pix = shadow.load() - mask_pix = osm_mask.load() - for y in range(self._imgsize-1): - for x in range(self._imgsize-1): - m = mask_pix[x,y] - 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.3, mstr_shadow_strength) - ca = a * st - aa = int(ca) - 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"): @@ -890,6 +963,7 @@ class mstr_layergen: # 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 + osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) mask_pix = osm_edge.load() layer_comp_pix = layer_comp.load() for y in range(self._imgsize): @@ -901,13 +975,14 @@ class mstr_layergen: layer_comp_pix[x, y] = ( w,w,w,a[3] ) if self._tag == "highway" and self._value == "residential": + osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) 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) + w = randrange(150,181) a=mask_pix[x,y] layer_comp_pix[x, y] = ( w,w,w,a[3] ) mstr_msg("layergen", "Street lines added") diff --git a/maskgen.py b/maskgen.py index 04181d1..732d08c 100644 --- a/maskgen.py +++ b/maskgen.py @@ -27,6 +27,7 @@ from defines import * from log import * from PIL import Image, ImageFilter, ImageDraw, ImagePath from random import randrange +from functions import * import random class mstr_maskgen: @@ -65,11 +66,18 @@ class mstr_maskgen: latlng.append(float(i[2])) break return latlng - - # Only needed if X-Plane scenery is built - def _set_xpscenery_datagroup(self, dg): - self._xpdg = dg + + # Set width of tile - for buildings + def set_tile_width(self, tile_width): + self._tile_width = tile_width + + # Numbers needed for the possible building shadow layer + def set_latlng_numbers(self, lat, tv, lng, th): + self._latitude = lat + self._lat_number = tv + self._longitude = lng + self._lng_number = th # Builds the required mask @@ -99,6 +107,9 @@ class mstr_maskgen: # Longitude bbox.append(self._box[2] + ((self._box[3]-1) * mstr_zl_18)) bbox.append(self._box[2] + ((self._box[3]-1) * mstr_zl_18) + mstr_zl_18) + + # Building levels, if this is a building + bld_levels = 0 # Generate mask for ONE tag only if self._subtag == None: @@ -107,6 +118,8 @@ class mstr_maskgen: nd = [] for d in way: if d[0] == w[0]: + if self._tag == "building" and bld_levels == 0: + bld_levels = xml.find_building_levels(tilexml, w[0]) nd.append(d[1]) frs.append(nd) # Scout through relations as these also make up map data @@ -203,5 +216,58 @@ class mstr_maskgen: # Save image mask_img.save(mstr_datafolder + "_cache/" + fstr + "_" + self._tag + "-" + self._value + ".png") + + # If this is a building, we need to render the shadow here, as we only know the height + # of the building in this loop. + if mstr_shadow_enabled == True: + if self._tag == "building": + mpp = meters_per_pixel(self._tile_width) * mstr_zl_18 + pix_per_floor = mstr_shadow_floor_h / mpp + total_pix = pix_per_floor * bld_levels + shift = int(total_pix) + + fn = mstr_datafolder + "_cache/" + fstr + "_" + self._tag + "-" + self._value + "_layer_shadow.png" + + mask_pix = mask_img.load() + + bld_shadow = Image.new("RGBA", (mstr_photores, mstr_photores)) + bld_shadow_pix = bld_shadow.load() + + # Shadow sweep + shf = 1 + while shf <= shift: + for y in range(mstr_photores): + for x in range(mstr_photores): + mp = mask_pix[x,y] + if mp[3] != 0: + if x+(shf*2) < mstr_photores and y+shf < mstr_photores: + bld_shadow_pix[x+(shf*2), y+shf] = (0,0,0,255) + shf = shf+1 + + # Building removal sweep + for y in range(mstr_photores): + for x in range(mstr_photores): + mp = mask_pix[x,y] + if mp[3] != 0: + bld_shadow_pix[x,y] = (0,0,0,0) + + + # Correct alpha + bld_shadow_pix = bld_shadow.load() + for y in range(mstr_photores): + for x in range(mstr_photores): + sp = bld_shadow_pix[x,y] + if sp[3] != 0: + bld_shadow_pix[x,y] = (0,0,0,120) + + # Store + if os.path.isfile(fn) == True: + lyr = Image.open(fn) + lyr.alpha_composite(bld_shadow) + lyr.save(fn) + else: + bld_shadow.save(fn) + + # Inform mstr_msg("maskgen", "Mask built.") diff --git a/orthographic.py b/orthographic.py index 04353f2..a279c4c 100644 --- a/orthographic.py +++ b/orthographic.py @@ -201,8 +201,9 @@ class mstr_orthographic: # Generate the mask mg = mstr_maskgen( [self._lat, cur_tile_y, self._long, cur_tile_x], self._vstep, layer[0], layer[1], layer[2]) - if mstr_xp_genscenery == True: - mg._set_xpscenery_datagroup(xp_datagroup) + if layer[0] == "building": + mg.set_tile_width(self._findWidthOfLongitude(bb_lat)) + mg.set_latlng_numbers(self._lat, lat_grid, self._long, lng_grid) mg._build_mask() # Generate the layer diff --git a/osmxml.py b/osmxml.py index abd8ed5..3f4c931 100644 --- a/osmxml.py +++ b/osmxml.py @@ -149,6 +149,23 @@ class mstr_osmxml: # Return the found surface type return surface + + + # Find the levels of a building (for shadow rendering) + def find_building_levels(self, xmlfile, way_id): + lvl = 3 # Standard if we don't find anything else + xml_doc = xml.dom.minidom.parse(xmlfile) + wpdata = xml_doc.getElementsByTagName("way") + for wp in wpdata: + if wp.getAttribute("id") == way_id: + tags = wp.getElementsByTagName("tag") + for tag in tags: + a = tag.getAttribute("k") + v = tag.getAttribute("v") + if a == "building:levels": + lvl = int(v) + break + return lvl # It turns out that some features hide themselves in the relations section. diff --git a/photogen.py b/photogen.py index df73ee8..d5a581f 100644 --- a/photogen.py +++ b/photogen.py @@ -52,6 +52,7 @@ class mstr_photogen: 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") + shd = shd.filter(ImageFilter.GaussianBlur(radius=2)) bldg_shadow.alpha_composite(shd) # Details merging bldg_details = Image.new("RGBA", (self._imgsize, self._imgsize)) @@ -69,10 +70,18 @@ class mstr_photogen: bld = Image.open(root_filename + l[0] + "-" + l[1] + "_layer.png") bld = bld.filter(ImageFilter.GaussianBlur(radius=1)) bldg_main.alpha_composite(bld) + # Trees merging + tree_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_building_trees.png"): + trs= Image.open(root_filename + l[0] + "-" + l[1] + "_layer_building_trees.png") + tree_main.alpha_composite(trs) # 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(tree_main) bldg_final.alpha_composite(bldg_main) for l in mstr_ortho_layers: @@ -153,8 +162,7 @@ class mstr_photogen: ["water", "lake"], ["water", "pond"], ["water", "river"], - ["leisure", "swimming_pool"], - ["waterway", "stream"] + ["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" diff --git a/textures/amenities/parking/brd/b1.png b/textures/amenities/parking/brd/b1.png deleted file mode 100644 index e9b3ec6..0000000 Binary files a/textures/amenities/parking/brd/b1.png and /dev/null differ diff --git a/textures/amenities/parking/ptc/b1_p1.png b/textures/amenities/parking/ptc/b1_p1.png deleted file mode 100644 index c8b87c6..0000000 Binary files a/textures/amenities/parking/ptc/b1_p1.png and /dev/null differ diff --git a/textures/boundary/administrative/brd/b1.png b/textures/boundary/administrative/brd/b1.png index 921b503..6be9ba8 100644 Binary files a/textures/boundary/administrative/brd/b1.png and b/textures/boundary/administrative/brd/b1.png differ diff --git a/textures/boundary/administrative/brd/b2.png b/textures/boundary/administrative/brd/b2.png index 13f583a..268b38b 100644 Binary files a/textures/boundary/administrative/brd/b2.png and b/textures/boundary/administrative/brd/b2.png differ diff --git a/textures/boundary/administrative/brd/b3.png b/textures/boundary/administrative/brd/b3.png index 099ecfd..cd73d2e 100644 Binary files a/textures/boundary/administrative/brd/b3.png and b/textures/boundary/administrative/brd/b3.png differ diff --git a/textures/boundary/administrative/brd/b4.png b/textures/boundary/administrative/brd/b4.png new file mode 100644 index 0000000..6e53e94 Binary files /dev/null and b/textures/boundary/administrative/brd/b4.png differ diff --git a/textures/boundary/administrative/ptc/b1_p1.png b/textures/boundary/administrative/ptc/b1_p1.png index 954bdf9..c1d1a3a 100644 Binary files a/textures/boundary/administrative/ptc/b1_p1.png and b/textures/boundary/administrative/ptc/b1_p1.png differ diff --git a/textures/boundary/administrative/ptc/b1_p2.png b/textures/boundary/administrative/ptc/b1_p2.png index 61e1afa..708dc34 100644 Binary files a/textures/boundary/administrative/ptc/b1_p2.png and b/textures/boundary/administrative/ptc/b1_p2.png differ diff --git a/textures/boundary/administrative/ptc/b2_p1.png b/textures/boundary/administrative/ptc/b2_p1.png index 347a7ea..057d796 100644 Binary files a/textures/boundary/administrative/ptc/b2_p1.png and b/textures/boundary/administrative/ptc/b2_p1.png differ diff --git a/textures/boundary/administrative/ptc/b2_p2.png b/textures/boundary/administrative/ptc/b2_p2.png index ec82ffa..c9631c3 100644 Binary files a/textures/boundary/administrative/ptc/b2_p2.png and b/textures/boundary/administrative/ptc/b2_p2.png differ diff --git a/textures/boundary/administrative/ptc/b3_p1.png b/textures/boundary/administrative/ptc/b3_p1.png index 86d472c..916014b 100644 Binary files a/textures/boundary/administrative/ptc/b3_p1.png and b/textures/boundary/administrative/ptc/b3_p1.png differ diff --git a/textures/boundary/administrative/ptc/b3_p2.png b/textures/boundary/administrative/ptc/b3_p2.png index c513faa..872f736 100644 Binary files a/textures/boundary/administrative/ptc/b3_p2.png and b/textures/boundary/administrative/ptc/b3_p2.png differ diff --git a/textures/boundary/administrative/ptc/b4_p1.png b/textures/boundary/administrative/ptc/b4_p1.png new file mode 100644 index 0000000..cee27fe Binary files /dev/null and b/textures/boundary/administrative/ptc/b4_p1.png differ diff --git a/textures/boundary/administrative/ptc/b4_p2.png b/textures/boundary/administrative/ptc/b4_p2.png new file mode 100644 index 0000000..547a0fe Binary files /dev/null and b/textures/boundary/administrative/ptc/b4_p2.png differ diff --git a/textures/building/area/p1.png b/textures/building/area/p1.png index 7e7424e..0791426 100644 Binary files a/textures/building/area/p1.png and b/textures/building/area/p1.png differ diff --git a/textures/building/area/p10.png b/textures/building/area/p10.png index cb3f640..94c7db1 100644 Binary files a/textures/building/area/p10.png and b/textures/building/area/p10.png differ diff --git a/textures/building/area/p11.png b/textures/building/area/p11.png new file mode 100644 index 0000000..5fdda5a Binary files /dev/null and b/textures/building/area/p11.png differ diff --git a/textures/building/area/p12.png b/textures/building/area/p12.png new file mode 100644 index 0000000..fbaff7f Binary files /dev/null and b/textures/building/area/p12.png differ diff --git a/textures/building/area/p13.png b/textures/building/area/p13.png new file mode 100644 index 0000000..13becc6 Binary files /dev/null and b/textures/building/area/p13.png differ diff --git a/textures/building/area/p14.png b/textures/building/area/p14.png new file mode 100644 index 0000000..7d0b7f7 Binary files /dev/null and b/textures/building/area/p14.png differ diff --git a/textures/building/area/p15.png b/textures/building/area/p15.png new file mode 100644 index 0000000..9c19a39 Binary files /dev/null and b/textures/building/area/p15.png differ diff --git a/textures/building/area/p2.png b/textures/building/area/p2.png index b06670a..c4bc642 100644 Binary files a/textures/building/area/p2.png and b/textures/building/area/p2.png differ diff --git a/textures/building/area/p3.png b/textures/building/area/p3.png index dbdfb3c..c88a171 100644 Binary files a/textures/building/area/p3.png and b/textures/building/area/p3.png differ diff --git a/textures/building/area/p4.png b/textures/building/area/p4.png index df6254d..cb1962a 100644 Binary files a/textures/building/area/p4.png and b/textures/building/area/p4.png differ diff --git a/textures/building/area/p5.png b/textures/building/area/p5.png index b51df3b..c6d2fa8 100644 Binary files a/textures/building/area/p5.png and b/textures/building/area/p5.png differ diff --git a/textures/building/area/p6.png b/textures/building/area/p6.png index 09e9a11..942bc9e 100644 Binary files a/textures/building/area/p6.png and b/textures/building/area/p6.png differ diff --git a/textures/building/area/p7.png b/textures/building/area/p7.png index 500f61c..f79a29e 100644 Binary files a/textures/building/area/p7.png and b/textures/building/area/p7.png differ diff --git a/textures/building/area/p8.png b/textures/building/area/p8.png index fdd9086..4e21e30 100644 Binary files a/textures/building/area/p8.png and b/textures/building/area/p8.png differ diff --git a/textures/building/area/p9.png b/textures/building/area/p9.png index 8218812..a8680da 100644 Binary files a/textures/building/area/p9.png and b/textures/building/area/p9.png differ diff --git a/textures/landuse/residential-boundary/brd/b1.png b/textures/landuse/residential-boundary/brd/b1.png index 921b503..6be9ba8 100644 Binary files a/textures/landuse/residential-boundary/brd/b1.png and b/textures/landuse/residential-boundary/brd/b1.png differ diff --git a/textures/landuse/residential-boundary/brd/b2.png b/textures/landuse/residential-boundary/brd/b2.png index 13f583a..268b38b 100644 Binary files a/textures/landuse/residential-boundary/brd/b2.png and b/textures/landuse/residential-boundary/brd/b2.png differ diff --git a/textures/landuse/residential-boundary/brd/b3.png b/textures/landuse/residential-boundary/brd/b3.png index 099ecfd..cd73d2e 100644 Binary files a/textures/landuse/residential-boundary/brd/b3.png and b/textures/landuse/residential-boundary/brd/b3.png differ diff --git a/textures/landuse/residential-boundary/brd/b4.png b/textures/landuse/residential-boundary/brd/b4.png new file mode 100644 index 0000000..6e53e94 Binary files /dev/null and b/textures/landuse/residential-boundary/brd/b4.png differ diff --git a/textures/landuse/residential-boundary/ptc/b1_p1.png b/textures/landuse/residential-boundary/ptc/b1_p1.png index 954bdf9..c1d1a3a 100644 Binary files a/textures/landuse/residential-boundary/ptc/b1_p1.png and b/textures/landuse/residential-boundary/ptc/b1_p1.png differ diff --git a/textures/landuse/residential-boundary/ptc/b1_p2.png b/textures/landuse/residential-boundary/ptc/b1_p2.png index 61e1afa..708dc34 100644 Binary files a/textures/landuse/residential-boundary/ptc/b1_p2.png and b/textures/landuse/residential-boundary/ptc/b1_p2.png differ diff --git a/textures/landuse/residential-boundary/ptc/b2_p1.png b/textures/landuse/residential-boundary/ptc/b2_p1.png index 347a7ea..057d796 100644 Binary files a/textures/landuse/residential-boundary/ptc/b2_p1.png and b/textures/landuse/residential-boundary/ptc/b2_p1.png differ diff --git a/textures/landuse/residential-boundary/ptc/b2_p2.png b/textures/landuse/residential-boundary/ptc/b2_p2.png index ec82ffa..c9631c3 100644 Binary files a/textures/landuse/residential-boundary/ptc/b2_p2.png and b/textures/landuse/residential-boundary/ptc/b2_p2.png differ diff --git a/textures/landuse/residential-boundary/ptc/b3_p1.png b/textures/landuse/residential-boundary/ptc/b3_p1.png index 86d472c..916014b 100644 Binary files a/textures/landuse/residential-boundary/ptc/b3_p1.png and b/textures/landuse/residential-boundary/ptc/b3_p1.png differ diff --git a/textures/landuse/residential-boundary/ptc/b3_p2.png b/textures/landuse/residential-boundary/ptc/b3_p2.png index c513faa..872f736 100644 Binary files a/textures/landuse/residential-boundary/ptc/b3_p2.png and b/textures/landuse/residential-boundary/ptc/b3_p2.png differ diff --git a/textures/landuse/residential-boundary/ptc/b4_p1.png b/textures/landuse/residential-boundary/ptc/b4_p1.png new file mode 100644 index 0000000..cee27fe Binary files /dev/null and b/textures/landuse/residential-boundary/ptc/b4_p1.png differ diff --git a/textures/landuse/residential-boundary/ptc/b4_p2.png b/textures/landuse/residential-boundary/ptc/b4_p2.png new file mode 100644 index 0000000..547a0fe Binary files /dev/null and b/textures/landuse/residential-boundary/ptc/b4_p2.png differ diff --git a/textures/landuse/residential/brd/b1.png b/textures/landuse/residential/brd/b1.png index 921b503..6be9ba8 100644 Binary files a/textures/landuse/residential/brd/b1.png and b/textures/landuse/residential/brd/b1.png differ diff --git a/textures/landuse/residential/brd/b2.png b/textures/landuse/residential/brd/b2.png index 13f583a..268b38b 100644 Binary files a/textures/landuse/residential/brd/b2.png and b/textures/landuse/residential/brd/b2.png differ diff --git a/textures/landuse/residential/brd/b3.png b/textures/landuse/residential/brd/b3.png index 099ecfd..cd73d2e 100644 Binary files a/textures/landuse/residential/brd/b3.png and b/textures/landuse/residential/brd/b3.png differ diff --git a/textures/landuse/residential/brd/b4.png b/textures/landuse/residential/brd/b4.png new file mode 100644 index 0000000..6e53e94 Binary files /dev/null and b/textures/landuse/residential/brd/b4.png differ diff --git a/textures/landuse/residential/ptc/b1_p1.png b/textures/landuse/residential/ptc/b1_p1.png index 954bdf9..c1d1a3a 100644 Binary files a/textures/landuse/residential/ptc/b1_p1.png and b/textures/landuse/residential/ptc/b1_p1.png differ diff --git a/textures/landuse/residential/ptc/b1_p2.png b/textures/landuse/residential/ptc/b1_p2.png index 61e1afa..708dc34 100644 Binary files a/textures/landuse/residential/ptc/b1_p2.png and b/textures/landuse/residential/ptc/b1_p2.png differ diff --git a/textures/landuse/residential/ptc/b2_p1.png b/textures/landuse/residential/ptc/b2_p1.png index 347a7ea..057d796 100644 Binary files a/textures/landuse/residential/ptc/b2_p1.png and b/textures/landuse/residential/ptc/b2_p1.png differ diff --git a/textures/landuse/residential/ptc/b2_p2.png b/textures/landuse/residential/ptc/b2_p2.png index ec82ffa..c9631c3 100644 Binary files a/textures/landuse/residential/ptc/b2_p2.png and b/textures/landuse/residential/ptc/b2_p2.png differ diff --git a/textures/landuse/residential/ptc/b3_p1.png b/textures/landuse/residential/ptc/b3_p1.png index 86d472c..916014b 100644 Binary files a/textures/landuse/residential/ptc/b3_p1.png and b/textures/landuse/residential/ptc/b3_p1.png differ diff --git a/textures/landuse/residential/ptc/b3_p2.png b/textures/landuse/residential/ptc/b3_p2.png index c513faa..872f736 100644 Binary files a/textures/landuse/residential/ptc/b3_p2.png and b/textures/landuse/residential/ptc/b3_p2.png differ diff --git a/textures/landuse/residential/ptc/b4_p1.png b/textures/landuse/residential/ptc/b4_p1.png new file mode 100644 index 0000000..cee27fe Binary files /dev/null and b/textures/landuse/residential/ptc/b4_p1.png differ diff --git a/textures/landuse/residential/ptc/b4_p2.png b/textures/landuse/residential/ptc/b4_p2.png new file mode 100644 index 0000000..547a0fe Binary files /dev/null and b/textures/landuse/residential/ptc/b4_p2.png differ