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