From: marstr Date: Tue, 27 Aug 2024 19:24:32 +0000 (+0200) Subject: Corrected bug in layergen preventing generation of tile completion layer X-Git-Url: https://marstr.online/code/gitweb.cgi?a=commitdiff_plain;h=f455988334a4062a57231eabda58855a180f9d89;p=orthographic Corrected bug in layergen preventing generation of tile completion layer --- diff --git a/layergen.py b/layergen.py index bc06993..b4da8c8 100644 --- a/layergen.py +++ b/layergen.py @@ -99,341 +99,178 @@ class mstr_layergen: return layer_final - # This generates the layer to be masked + # This generates the layer from the defined mask def genlayer(self): - # Ok so. For speed reasons, we only proceed if there is anything to do. - if os.path.isfile(mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + ".png"): - - mstr_msg("mstr_layergen", "Layer to be generated: " + str(self._latitude) + "-" + str(self._lat_number) + ":" + str(self._longitude) + "-" + str(self._lng_number) + " -- tag: " + self._tag + " - value: " + self._value ) - - # Before we generate the layer, let's check for airports in this chunk - mstr_msg("mstr_layergen", "Checking for airport/s with ICAO code") - osmxml = mstr_osmxml(0,0) - icao = osmxml.find_icao_codes(mstr_datafolder + "_cache\\tile.xml") - mstr_msg("mstr_layergen", "Found " + str(len(icao)) + " airport/s") - # Runway surface, if any other than concrete/asphalt - rw_surface = "" - # If we find an airport, make a note ... - if len(icao) >= 1: - for i in icao: - # ... but only, if this airport is not already noted - iccheck = self._tiledb.perform_query("SELECT * FROM airports WHERE icao='" + i +"';") - if len(iccheck) == 0: - self._tiledb.insert_icao(i, self._lat_number, self._lng_number, self._latitude, self._longitude) - mstr_msg("mstr_layergen", "Airport/s noted in data file") - rw_surface = osmxml.find_runway_surface(mstr_datafolder + "_cache\\tile.xml") - - # The image for the layer itself - layer = Image.new("RGBA", (self._imgsize, self._imgsize)) - layer_pix = layer.load() - - # There are some things we need to use sources for, and some things, we do not. - # We need to differentiate that. - - if (self._isline == False and self._tag != "building") or (self._is_completion == True): - # Determine where we get the our source material from - root_folder = mstr_datafolder + "Textures\\" - for s in mstr_ortho_layers: - if s[0] == self._tag and s[1] == self._value: - fld_main = len(s)-2 - fld_sub = len(s)-1 - root_folder = root_folder + s[fld_main] + "\\" + s[fld_sub] - - # Determine which sources to use. - # First, we need to check for adjacent tile information. We then either - # need to use the source of any adjacent tile, or we can choose freely. - src = -1 - - # Find our adjacent tiles - adjtiles = findAdjacentTilesTo(self._lat_number, self._lng_number) - - mstr_msg("mstr_layergen", "Performing adjacency check") - # Walk through each tile and see what we can find in relation to this - # tile in the center - # Since we already know the order in adjtiles, we can do this real easy - if self._is_completion == False: - at = self._tiledb.get_adjacency_for_source(adjtiles[0][0], adjtiles[0][1], self._tag, self._value) # Top - ar = self._tiledb.get_adjacency_for_source(adjtiles[1][0], adjtiles[1][1], self._tag, self._value) # Right - ab = self._tiledb.get_adjacency_for_source(adjtiles[2][0], adjtiles[2][1], self._tag, self._value) # Bottom - al = self._tiledb.get_adjacency_for_source(adjtiles[3][0], adjtiles[3][1], self._tag, self._value) # Left - if self._is_completion == True: - at = self._tiledb.get_adjacency_for_completion(adjtiles[0][0], adjtiles[0][1], self._tag, self._value) # Top - ar = self._tiledb.get_adjacency_for_completion(adjtiles[1][0], adjtiles[1][1], self._tag, self._value) # Right - ab = self._tiledb.get_adjacency_for_completion(adjtiles[2][0], adjtiles[2][1], self._tag, self._value) # Bottom - al = self._tiledb.get_adjacency_for_completion(adjtiles[3][0], adjtiles[3][1], self._tag, self._value) # Left - - # We are south to the top tile. - if len(at) == 1 and src == -1: - if "b" in at[0][5]: src = int(at[0][4]) - # We are west to the right tile. - if len(ar) == 1 and src == -1: - if "l" in ar[0][5]: src = int(ar[0][4]) - # We are north to the bottom tile. - if len(ab) == 1 and src == -1: - if "t" in ab[0][5]: src = int(ab[0][4]) - # We are east to the left tile. - if len(al) == 1 and src == -1: - if "r" in al[0][5]: src = int(al[0][4]) - - mstr_msg("mstr_layergen", "Adjacency check completed") - - brd = glob.glob(root_folder + "\\brd\\b*.png") - - # If the adjacency check returned nothing (src is still -1), - # then pick something - if src == -1: - if len(brd) == 1: src=1 - if len(brd) >= 2: - src = randrange(1, len(brd)) - - ptc = glob.glob(root_folder + "\\ptc\\b" + str(src) + "_p*.png") - - # Load in the sources to work with - brd_src = Image.open(root_folder + "\\brd\\b" + str(src) + ".png") - ptc_src = [] - for p in ptc: - ptc_src.append(Image.open(p)) - mstr_msg("mstr_layergen", "Layer sources selected") - - # OK! Load the mask - if self._is_completion == False: - osm_mask = Image.open( mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + ".png" ) - if self._is_completion == True: - osm_mask = Image.open( mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_tile-completion.png" ) - - # Generate an edge mask from the original - osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) - osm_edge = osm_edge.filter(ImageFilter.MaxFilter) - mstr_msg("mstr_layergen", "Edge mask generated") - - # We need to change the image in certain conditions - if self._value == "hedge" and self._tag == "barrier": - osm_mask = osm_edge - - # From here on in we will need to perform some adjustments on the masks, depending - # on what they are. - 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 - - # Begin producing a largely random image - samples = 250 # <- We need this in a moment - for i in range(samples): - imgid = 0 - if len(ptc_src) == 1: imgid = 0 - if len(ptc_src) >= 2: - imgid = randrange(1, len(ptc_src)) - 1 - l = 0 - int(ptc_src[imgid].width / 2) - r = layer.width - int(ptc_src[imgid].width / 2) - t = 0 - int(ptc_src[imgid].height / 2) - b = layer.height - int(ptc_src[imgid].height / 2) - layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) ) - mstr_msg("mstr_layergen", "Layer image generated") - - # We now need to add the seamless border - layer.alpha_composite( brd_src ) - mstr_msg("mstr_layergen", "Layer image completed") - - - # And now for the Big Mac. - # Generate the layer from the mask. - layer_comp = Image.new("RGBA", (self._imgsize, self._imgsize)) - layer_pix = layer.load() - mask_pix = osm_mask.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: - rgb=layer_pix[x,y] - a=mask_pix[x,y] - 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 - if self._tag == "landuse": - if self._value == "forest" or self._value == "farmland": - osm_edge = osm_edge.filter(ImageFilter.ModeFilter(size=15)) - osm_edge = osm_edge.filter(ImageFilter.BoxBlur(radius=2)) - layer_border = self.genborder(osm_edge, "landuse", "meadow") - layer_comp.alpha_composite(layer_border) - - # 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" ) - if self._is_completion == True: - layer_comp.save( mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_tile-completion_layer.png" ) - #layer_final.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("mstr_layergen", "Layer image finalized and saved.") - - - # Let's try our hand at pseudo shadows - if mstr_shadow_enabled == True: - shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) - for sh in mstr_shadow_casters: - if self._tag == sh[0] and self._value == sh[1]: - mstr_msg("mstr_layergen", "Generating shadow for layer") - 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 - if shf_x <= self._imgsize-1: - a = mask_pix[x,y][3] - 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("mstr_layergen", "Shadow layer completed") - - - - # Check if pixels touch the borders of the image, and if so - - # make a not of that in the database. - at=False - ar=False - ab=False - al=False - layer_pix = layer_comp.load() # <- Just to be safe - - # Top scan - for i in range(0, self._imgsize-1): - p = layer_pix[i,0] - if p[3] > 0: - at=True - break - - # Right scan - for i in range(0, self._imgsize-1): - p = layer_pix[self._imgsize-1,i] - if p[3] > 0: - ar=True - break - - # Bottom scan - for i in range(0, self._imgsize-1): - p = layer_pix[i,self._imgsize-1] - if p[3] > 0: - ab=True - break - - # Left scan - for i in range(0, self._imgsize-1): - p = layer_pix[1,i] - if p[3] > 0: - al=True - break - - # Construct DB String - adjstr = "" - if at==True: adjstr = adjstr + "t" - if ar==True: adjstr = adjstr + "r" - if ab==True: adjstr = adjstr + "b" - if al==True: adjstr = adjstr + "l" - - # Store into DB - but only if there is something to store - if adjstr != "": - if self._is_completion == False: - self._tiledb.insert_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr) - if self._is_completion == True: - self._tiledb.insert_completion_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr) - self._tiledb.commit_query() - self._tiledb.close_db() - mstr_msg("mstr_layergen", "Adjacency info stored in database") + mstr_msg("mstr_layergen", "Layer to be generated: " + str(self._latitude) + "-" + str(self._lat_number) + ":" + str(self._longitude) + "-" + str(self._lng_number) + " -- tag: " + self._tag + " - value: " + self._value ) + + # Before we generate the layer, let's check for airports in this chunk + mstr_msg("mstr_layergen", "Checking for airport/s with ICAO code") + osmxml = mstr_osmxml(0,0) + icao = osmxml.find_icao_codes(mstr_datafolder + "_cache\\tile.xml") + mstr_msg("mstr_layergen", "Found " + str(len(icao)) + " airport/s") + # Runway surface, if any other than concrete/asphalt + rw_surface = "" + # If we find an airport, make a note ... + if len(icao) >= 1: + for i in icao: + # ... but only, if this airport is not already noted + iccheck = self._tiledb.perform_query("SELECT * FROM airports WHERE icao='" + i +"';") + if len(iccheck) == 0: + self._tiledb.insert_icao(i, self._lat_number, self._lng_number, self._latitude, self._longitude) + mstr_msg("mstr_layergen", "Airport/s noted in data file") + rw_surface = osmxml.find_runway_surface(mstr_datafolder + "_cache\\tile.xml") + + # The image for the layer itself + layer = Image.new("RGBA", (self._imgsize, self._imgsize)) + layer_pix = layer.load() + + # There are some things we need to use sources for, and some things, we do not. + # We need to differentiate that. + + if (self._isline == False and self._tag != "building") or (self._is_completion == True): + # Determine where we get the our source material from + root_folder = mstr_datafolder + "Textures\\" + for s in mstr_ortho_layers: + if s[0] == self._tag and s[1] == self._value: + fld_main = len(s)-2 + fld_sub = len(s)-1 + root_folder = root_folder + s[fld_main] + "\\" + s[fld_sub] + + # Determine which sources to use. + # First, we need to check for adjacent tile information. We then either + # need to use the source of any adjacent tile, or we can choose freely. + src = -1 + # Find our adjacent tiles + adjtiles = findAdjacentTilesTo(self._lat_number, self._lng_number) + + mstr_msg("mstr_layergen", "Performing adjacency check") + # Walk through each tile and see what we can find in relation to this + # tile in the center + # Since we already know the order in adjtiles, we can do this real easy + if self._is_completion == False: + at = self._tiledb.get_adjacency_for_source(adjtiles[0][0], adjtiles[0][1], self._tag, self._value) # Top + ar = self._tiledb.get_adjacency_for_source(adjtiles[1][0], adjtiles[1][1], self._tag, self._value) # Right + ab = self._tiledb.get_adjacency_for_source(adjtiles[2][0], adjtiles[2][1], self._tag, self._value) # Bottom + al = self._tiledb.get_adjacency_for_source(adjtiles[3][0], adjtiles[3][1], self._tag, self._value) # Left + if self._is_completion == True: + at = self._tiledb.get_adjacency_for_completion(adjtiles[0][0], adjtiles[0][1], self._tag, self._value) # Top + ar = self._tiledb.get_adjacency_for_completion(adjtiles[1][0], adjtiles[1][1], self._tag, self._value) # Right + ab = self._tiledb.get_adjacency_for_completion(adjtiles[2][0], adjtiles[2][1], self._tag, self._value) # Bottom + al = self._tiledb.get_adjacency_for_completion(adjtiles[3][0], adjtiles[3][1], self._tag, self._value) # Left + + # We are south to the top tile. + if len(at) == 1 and src == -1: + if "b" in at[0][5]: src = int(at[0][4]) + # We are west to the right tile. + if len(ar) == 1 and src == -1: + if "l" in ar[0][5]: src = int(ar[0][4]) + # We are north to the bottom tile. + if len(ab) == 1 and src == -1: + if "t" in ab[0][5]: src = int(ab[0][4]) + # We are east to the left tile. + if len(al) == 1 and src == -1: + if "r" in al[0][5]: src = int(al[0][4]) + + mstr_msg("mstr_layergen", "Adjacency check completed") - # If we encounter one of these road-specific tags, we need to proceed differently. - - if self._isline == True or self._tag == "building": + brd = glob.glob(root_folder + "\\brd\\b*.png") - # We will need the mask in question + # If the adjacency check returned nothing (src is still -1), + # then pick something + if src == -1: + if len(brd) == 1: src=1 + if len(brd) >= 2: + src = randrange(1, len(brd)) + + ptc = glob.glob(root_folder + "\\ptc\\b" + str(src) + "_p*.png") + + # Load in the sources to work with + brd_src = Image.open(root_folder + "\\brd\\b" + str(src) + ".png") + ptc_src = [] + for p in ptc: + ptc_src.append(Image.open(p)) + mstr_msg("mstr_layergen", "Layer sources selected") + + # OK! Load the mask + if self._is_completion == False: osm_mask = Image.open( mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + ".png" ) + if self._is_completion == True: + osm_mask = Image.open( mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_tile-completion.png" ) + + # Generate an edge mask from the original + osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) + osm_edge = osm_edge.filter(ImageFilter.MaxFilter) + mstr_msg("mstr_layergen", "Edge mask generated") + + # We need to change the image in certain conditions + if self._value == "hedge" and self._tag == "barrier": + osm_mask = osm_edge + + # From here on in we will need to perform some adjustments on the masks, depending + # on what they are. + 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 + + # Begin producing a largely random image + samples = 250 # <- We need this in a moment + for i in range(samples): + imgid = 0 + if len(ptc_src) == 1: imgid = 0 + if len(ptc_src) >= 2: + imgid = randrange(1, len(ptc_src)) - 1 + l = 0 - int(ptc_src[imgid].width / 2) + r = layer.width - int(ptc_src[imgid].width / 2) + t = 0 - int(ptc_src[imgid].height / 2) + b = layer.height - int(ptc_src[imgid].height / 2) + layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) ) + mstr_msg("mstr_layergen", "Layer image generated") + + # We now need to add the seamless border + layer.alpha_composite( brd_src ) + mstr_msg("mstr_layergen", "Layer image completed") + + + # And now for the Big Mac. + # Generate the layer from the mask. + layer_comp = Image.new("RGBA", (self._imgsize, self._imgsize)) + layer_pix = layer.load() + mask_pix = osm_mask.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: + rgb=layer_pix[x,y] + a=mask_pix[x,y] + 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 + if self._tag == "landuse": + if self._value == "forest" or self._value == "farmland": + osm_edge = osm_edge.filter(ImageFilter.ModeFilter(size=15)) + osm_edge = osm_edge.filter(ImageFilter.BoxBlur(radius=2)) + layer_border = self.genborder(osm_edge, "landuse", "meadow") + layer_comp.alpha_composite(layer_border) + + # 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" ) + if self._is_completion == True: + layer_comp.save( mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_tile-completion_layer.png" ) + #layer_final.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("mstr_layergen", "Layer image finalized and saved.") - # Generate an edge mask from the original - osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) - osm_edge = osm_edge.filter(ImageFilter.MaxFilter) - mstr_msg("mstr_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 - osm_edge = osm_edge.filter(ImageFilter.BoxBlur(radius=1)) - - - # And now for the Big Mac. - # Generate the layer from the mask. Same as above - except! - # This time we have no source material - instead we will fill the - # mask with a color that is appropriate for this street type. - layer_comp = Image.new("RGBA", (self._imgsize, self._imgsize)) - mask_pix = osm_mask.load() - edge_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: - a=mask_pix[x,y] - e=edge_pix[x,y] - # Find a suitable color - d = 0 - if self._tag == "aeroway" and self._value == "runway": - # It seems only runways with any other surface than concrete - # are mentioned in OSM. So we need to make sure when to render - # "concrete" and when to leave it. Only sometimes the word - # "asphalt" is mentioned - if rw_surface == "" or rw_surface == "asphalt": - d = randrange(81, 101) - layer_comp_pix[x, y] = ( d,d,d,a[3] ) - if self._tag == "railway": - d = randrange(41, 61) - layer_comp_pix[x, y] = ( d,d,d,a[3] ) - if self._tag == "highway": - d = randrange(81, 101) - layer_comp_pix[x, y] = ( d,d,d,a[3] ) - if self._tag == "waterway" and self._value == "stream": - d = randrange(1, 15) - layer_comp_pix[x, y] = ( 19-d, 62-d, 71-d, a[3] ) - if self._tag == "building": - r = randrange(1, 20) - - if self._value == "yes": - d = (116-r, 117-r,135-r) - layer_comp_pix[x, y] = ( d[0], d[1], d[2], a[3] ) - if e[3] > 0: - b = (96-r, 97-r, 115-r) - layer_comp_pix[x, y] = ( b[0],b[1],b[2],e[3] ) - - if self._value == "office" or self._value == "retail": - d = (100-r, 100-r, 100-r) - layer_comp_pix[x, y] = ( d[0], d[1], d[2], a[3] ) - if e[3] > 0: - b = (80-r, 80-r, 80-r) - layer_comp_pix[x, y] = ( b[0],b[1],b[2],e[3] ) - - if self._value == "industrial": - d = (166-r, 170-r, 175-r) - layer_comp_pix[x, y] = ( d[0], d[1], d[2], a[3] ) - if e[3] > 0: - b = (146-r, 150-r, 155-r) - layer_comp_pix[x, y] = ( b[0],b[1],b[2],e[3] ) - - if self._value == "track" or self._value == "path": - d = randrange(1,20) - r = 164 - d - g = 159 - d - b = 138 - d - layer_comp_pix[x, y] = ( r,g,b,a[3] ) - mstr_msg("mstr_layergen", "Layer image generated") - - # Building shadow - if mstr_shadow_enabled == True: - if self._tag == "building": + + # Let's try our hand at pseudo shadows + if mstr_shadow_enabled == True: + shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) + for sh in mstr_shadow_casters: + if self._tag == sh[0] and self._value == sh[1]: mstr_msg("mstr_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): @@ -448,25 +285,185 @@ class mstr_layergen: 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("mstr_layergen", "Shadow layer completed") - - # Highways and runways of any kind get some special treatment - if (self._tag == "highway" and self._value == "motorway") or (self._tag == "aeroway" and self._value == "runway"): - # We will now add some white lines for coolness - 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(185, 215) - a=mask_pix[x,y] - layer_comp_pix[x, y] = ( w,w,w,a[3] ) - - mstr_msg("mstr_layergen", "Street lines added") - - # 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("mstr_layergen", "Layer image finalized and saved.") + + + + # Check if pixels touch the borders of the image, and if so - + # make a not of that in the database. + at=False + ar=False + ab=False + al=False + layer_pix = layer_comp.load() # <- Just to be safe + + # Top scan + for i in range(0, self._imgsize-1): + p = layer_pix[i,0] + if p[3] > 0: + at=True + break + + # Right scan + for i in range(0, self._imgsize-1): + p = layer_pix[self._imgsize-1,i] + if p[3] > 0: + ar=True + break + + # Bottom scan + for i in range(0, self._imgsize-1): + p = layer_pix[i,self._imgsize-1] + if p[3] > 0: + ab=True + break + + # Left scan + for i in range(0, self._imgsize-1): + p = layer_pix[1,i] + if p[3] > 0: + al=True + break + + # Construct DB String + adjstr = "" + if at==True: adjstr = adjstr + "t" + if ar==True: adjstr = adjstr + "r" + if ab==True: adjstr = adjstr + "b" + if al==True: adjstr = adjstr + "l" + + # Store into DB - but only if there is something to store + if adjstr != "": + if self._is_completion == False: + self._tiledb.insert_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr) + if self._is_completion == True: + self._tiledb.insert_completion_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr) + self._tiledb.commit_query() + self._tiledb.close_db() + mstr_msg("mstr_layergen", "Adjacency info stored in database") + + + # If we encounter one of these road-specific tags, we need to proceed differently. + + if self._isline == True or self._tag == "building": + + # We will need the mask in question + osm_mask = Image.open( mstr_datafolder + "_cache\\" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + ".png" ) + + # Generate an edge mask from the original + osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) + osm_edge = osm_edge.filter(ImageFilter.MaxFilter) + mstr_msg("mstr_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 + osm_edge = osm_edge.filter(ImageFilter.BoxBlur(radius=1)) + + + # And now for the Big Mac. + # Generate the layer from the mask. Same as above - except! + # This time we have no source material - instead we will fill the + # mask with a color that is appropriate for this street type. + layer_comp = Image.new("RGBA", (self._imgsize, self._imgsize)) + mask_pix = osm_mask.load() + edge_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: + a=mask_pix[x,y] + e=edge_pix[x,y] + # Find a suitable color + d = 0 + if self._tag == "aeroway" and self._value == "runway": + # It seems only runways with any other surface than concrete + # are mentioned in OSM. So we need to make sure when to render + # "concrete" and when to leave it. Only sometimes the word + # "asphalt" is mentioned + if rw_surface == "" or rw_surface == "asphalt": + d = randrange(81, 101) + layer_comp_pix[x, y] = ( d,d,d,a[3] ) + if self._tag == "railway": + d = randrange(41, 61) + layer_comp_pix[x, y] = ( d,d,d,a[3] ) + if self._tag == "highway": + d = randrange(81, 101) + layer_comp_pix[x, y] = ( d,d,d,a[3] ) + if self._tag == "waterway" and self._value == "stream": + d = randrange(1, 15) + layer_comp_pix[x, y] = ( 19-d, 62-d, 71-d, a[3] ) + if self._tag == "building": + r = randrange(1, 20) + + if self._value == "yes": + d = (116-r, 117-r,135-r) + layer_comp_pix[x, y] = ( d[0], d[1], d[2], a[3] ) + if e[3] > 0: + b = (96-r, 97-r, 115-r) + layer_comp_pix[x, y] = ( b[0],b[1],b[2],e[3] ) + + if self._value == "office" or self._value == "retail": + d = (100-r, 100-r, 100-r) + layer_comp_pix[x, y] = ( d[0], d[1], d[2], a[3] ) + if e[3] > 0: + b = (80-r, 80-r, 80-r) + layer_comp_pix[x, y] = ( b[0],b[1],b[2],e[3] ) + + if self._value == "industrial": + d = (166-r, 170-r, 175-r) + layer_comp_pix[x, y] = ( d[0], d[1], d[2], a[3] ) + if e[3] > 0: + b = (146-r, 150-r, 155-r) + layer_comp_pix[x, y] = ( b[0],b[1],b[2],e[3] ) + + if self._value == "track" or self._value == "path": + d = randrange(1,20) + r = 164 - d + g = 159 - d + b = 138 - d + layer_comp_pix[x, y] = ( r,g,b,a[3] ) + mstr_msg("mstr_layergen", "Layer image generated") + + # Building shadow + if mstr_shadow_enabled == True: + if self._tag == "building": + mstr_msg("mstr_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 + if shf_x <= self._imgsize-1: + a = mask_pix[x,y][3] + 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("mstr_layergen", "Shadow layer completed") + + # Highways and runways of any kind get some special treatment + if (self._tag == "highway" and self._value == "motorway") or (self._tag == "aeroway" and self._value == "runway"): + # We will now add some white lines for coolness + 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(185, 215) + a=mask_pix[x,y] + layer_comp_pix[x, y] = ( w,w,w,a[3] ) + + mstr_msg("mstr_layergen", "Street lines added") + + # 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("mstr_layergen", "Layer image finalized and saved.") diff --git a/orthographic.py b/orthographic.py index a21bc6e..ba10abe 100644 --- a/orthographic.py +++ b/orthographic.py @@ -122,7 +122,6 @@ class mstr_orthographic: lg.genlayer() mstr_msg("mstr_orthographic", "All layers created") - # We should have all layers now. # Snap a photo with our satellite :) mstr_msg("mstr_orthographic", "Generating ortho photo") diff --git a/photogen.py b/photogen.py index 7d1b5aa..320ca8b 100644 --- a/photogen.py +++ b/photogen.py @@ -42,6 +42,7 @@ class mstr_photogen: # First, we walk through all layers and blend them on top of each other, in order mstr_msg("mstr_photogen", "Merging layers") + 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