From 01e53bdcde8e665b151983bd21b26ef4417155b2 Mon Sep 17 00:00:00 2001 From: "Marcus Str." Date: Fri, 20 Dec 2024 14:05:48 +0100 Subject: [PATCH] Contrast values moved into separate file to make sure values only appear once. Appropriate adjustments toward that in layergen. Made sure trees do not get placed in water in photogen. --- defines.py | 8 ++-- layergen.py | 18 ++++++--- photogen.py | 40 +++++++++++++++---- tileprep.py | 109 ++++++++++++++++++++++++---------------------------- 4 files changed, 98 insertions(+), 77 deletions(-) diff --git a/defines.py b/defines.py index 4aaf21e..4729919 100644 --- a/defines.py +++ b/defines.py @@ -232,10 +232,10 @@ mstr_mask_blur = [ ("landuse", "farmland", 10), ("landuse", "farmyard", 10), # Z-Order 2 - ("landuse", "forest", 10), - ("leisure", "nature_reserve", 10), - ("natural", "wood", 10), - ("natural", "tree_row", 10), + ("landuse", "forest", 12), + ("leisure", "nature_reserve", 12), + ("natural", "wood", 12), + ("natural", "tree_row", 12), ("landuse", "military", 15), # Z-Order 3 ("natural", "bare_rock", 25), diff --git a/layergen.py b/layergen.py index 8ef3208..f9fc702 100644 --- a/layergen.py +++ b/layergen.py @@ -146,20 +146,21 @@ class mstr_layergen: # Find layer contrast to apply, if any - def findLayerContrast(self): + def findLayerContrast(self, res): contrast = 0 # The already existing source data - srcfile = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/" + str(self._lat_number) + "_" + str( - self._lng_number) + srcfile = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/ctrdata" # Let's open the file and find our entry with open(srcfile) as file: for line in file: linedata = line.split(" ") - if linedata[0] == self._tag and linedata[1] == self._value: - contrast = int(linedata[4]) + if len(linedata) > 1: # Make sure we don't break at last line of data file + if linedata[0] == self._tag and linedata[1] == self._value and linedata[2] == ctr: + contrast = int(linedata[3]) + break return contrast @@ -287,13 +288,18 @@ class mstr_layergen: # Determine which sources to use. src = self.findLayerSource() + srcstr = "" + for s in range(len(src)): + srcstr = srcstr + str(src[s]) + if s < len(src)-1: + srcstr = strsrc + "," # Patch and border sources. There can only be one for each. brd_src = None ptc_src = [] # Find this layer's predetermined contrast - lyr_contrast = self.findLayerContrast() + lyr_contrast = self.findLayerContrast(srcstr) if lyr_contrast != 0: mstr_msg("layergen", "Applying contrast value: " + str(lyr_contrast)) diff --git a/photogen.py b/photogen.py index 0dbdb7b..a4e4672 100644 --- a/photogen.py +++ b/photogen.py @@ -52,8 +52,8 @@ class mstr_photogen: #root_filename = mstr_datafolder + "/_cache/" + str(self._lat) + "-" + str(self._ty) + "_" + str(self._lng) + "-" + str(self._tx) + "_" # Correct layers - #mstr_msg("photogen", "Correcting layer order issues") - #layers = self.correctLayerIssues(layers) + mstr_msg("photogen", "Correcting layer order issues") + layers = self.correctLayerIssues(layers) # First, we walk through all layers and blend them on top of each other, in order mstr_msg("photogen", "Merging layers") @@ -202,7 +202,7 @@ class mstr_photogen: # One more thing... mstr_msg("photogen", "Adding features to layers") - self.addTreesToFeatures(layers) + self.addTreesToFeatures(layers, waterlayers) # Throw missing buildings on top lyr = 0 @@ -337,7 +337,15 @@ class mstr_photogen: # This used to be in layergen and solves the problem of roads being rendered above trees. # It is the only solution that worked, after some research. - def addTreesToFeatures(self, layers): + def addTreesToFeatures(self, layers, wtr): + + # Generate a combined water layer. Order and appearance does not matter. + wtrlyr = Image.new("RGBA", (self._imgsize, self._imgsize)) + for l in wtr: + wtrlyr.alpha_composite(l) + + # Preload the water layer for comparison + wtrpix = wtrlyr.load() # Walk through list of layers to decide where to add the trees curlyr = 0 @@ -353,7 +361,8 @@ class mstr_photogen: lx = randrange(0, self._imgsize) ly = randrange(0, self._imgsize) lp = lyrmask[lx,ly] - if lp[3] == 255: + wp = wtrpix[lx,ly] + if lp[3] == 255 and wp[3] == 0: # Exclude water bodies from tree placement tree = self.generate_tree() trees.alpha_composite(tree, (lx, ly)) @@ -401,8 +410,8 @@ class mstr_photogen: def correctLayerIssues(self, layers): # First the residential/forest dilemma - residential = 0 - forest = 0 + residential = -1 + forest = -1 curlyr = 0 for lyr in self._lyrnames: @@ -412,7 +421,22 @@ class mstr_photogen: forest = curlyr curlyr = curlyr+1 - layers[forest].alpha_composite(layers[residential]) + # Make sure we hit the correct layers with correct content! + # Only do something if both are found. + if residential != -1 and forest != -1: + rsd_pix = layers[residential].load() + frs_pix = layers[forest].load() + rsd_adj = Image.new("RGBA", (self._imgsize, self._imgsize)) + adj_pix = rsd_adj.load() + + for y in range(0, self._tile.height): + for x in range(0, self._tile.width): + fp = frs_pix[x,y] + rp = rsd_pix[x,y] + if rp[3] > 0 and fp[3] > 0: + adj_pix[x,y] = (rp[0], rp[1], rp[2], rp[3]) + + layers[forest].alpha_composite(rsd_adj) return layers diff --git a/tileprep.py b/tileprep.py index a43123e..09c5c1c 100644 --- a/tileprep.py +++ b/tileprep.py @@ -132,25 +132,6 @@ class mstr_tileprep: return src - # Get existing contrast value - def _getResourceContrast(self, tv, th): - # This either remains 0 or a string different to "0" in the end - ctr = "0" - df = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/" + str(tv) + "_" + str(th) - fnlines = [] - if os.path.isfile(df) == True: # It is possible that the requested file does not yet exist - with open(df) as textfile: - fnlines = textfile.readlines() - - for ln in fnlines: - l = ln.split(" ") - if l[0] == self._tag and l[1] == self._value: - l[4] = l[4].replace("\n", "") - ctr = l[4] - - return ctr - - # Find the edge touch info def _getResourceTouch(self, tv, th): touch = "" @@ -184,51 +165,69 @@ class mstr_tileprep: # Store the required resource information into the appropriate tile - def _storeResourceInfo(self, tile_v, tile_h, res, ctr): + def _storeResourceInfo(self, tile_v, tile_h, res): + # Separate file for contrast values + ctrdata = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/ctrdata" + df = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/" + str(tile_v) + "_" + str(tile_h) fnlines = [] - contrast = ctr if os.path.isfile(df) == True: # It is possible that the requested file does not yet exist with open(df) as textfile: fnlines = textfile.readlines() curline = 0 + for ln in fnlines: l = ln.split(" ") if len(l) > 1: if l[0] == self._tag and l[1] == self._value: l[2] = res - l[4] = l[4].replace("\n", "") - #contrast = l[4] - # Find contrast values for some tags - if contrast == "0": - if ( - (l[0] == "landuse" and l[1] == "forest") or - (l[0] == "landuse" and l[1] == "meadow") or - (l[0] == "landuse" and l[1] == "grass") or - (l[0] == "leisure" and l[1] == "nature_reserve") or - (l[0] == "natural" and l[1] == "grassland") or - (l[0] == "landuse" and l[1] == "greenfield") or - (l[0] == "natural" and l[1] == "heath") or - (l[0] == "natural" and l[1] == "wetland") or - (l[0] == "leisure" and l[1] == "park") or - (l[0] == "building") - ): - contrast = str(randrange(1, 4)) - - l[4] = l[4].replace("\n", "") - fnlines[curline] = l[0] + " " + l[1] + " " + l[2] + " " + l[3] + " " + contrast + fnlines[curline] = l[0] + " " + l[1] + " " + l[2] + " " + l[3] curline = curline+1 lines = "" for l in range(len(fnlines)): lines = lines + fnlines[l] - if l < len(lines)-1: lines = lines+"\n" with open(df, 'w') as textfile: textfile.write(lines) + # Take care of contrast value + ctrcontent = [] + if os.path.isfile(ctrdata) == True: + with open(ctrdata) as textfile: + ctrcontent = textfile.readlines() + + # Compare if we already have a data string for this particular resource + ctrpresent = False + if len(ctrcontent) > 0: + for ln in range(0, len(ctrcontent)): + cnt = ctrcontent[ln].split(" ") + if cnt[0] == self._tag and cnt[1] == self._value and cnt[2] == res: + ctrpresent = True + break + + # Should there not be a contrast value for this resource, add it + if ctrpresent == False: + if ( + (self._tag == "landuse" and self._value == "forest") or + (self._tag == "landuse" and self._value == "meadow") or + (self._tag == "landuse" and self._value == "grass") or + (self._tag == "leisure" and self._value == "nature_reserve") or + (self._tag == "natural" and self._value == "grassland") or + (self._tag == "landuse" and self._value == "greenfield") or + (self._tag == "natural" and self._value == "heath") or + (self._tag == "natural" and self._value == "wetland") or + (self._tag == "leisure" and self._value == "park") or + (self._tag == "building") + ): + contrast = str(randrange(1, 4)) + newline = self._tag + " " + self._value + " " + res + " " + str(contrast) + "\n" + + with open(ctrdata, 'a') as textfile: + textfile.write(newline) + # Walk through the now existing data files and make sure we always pick the correct # sources for every tile, thus evading previous edge detection errors @@ -238,7 +237,7 @@ class mstr_tileprep: edge_end = [0,0,0,0] # top, right, bottom, left # Array with info we need - resinfo = ["", "", ""] # Touch, Resource numbers, contrast + resinfo = ["", ""] # Touch, Resource numbers, contrast # Go through everything until the end is reached (no more options left) end_reached = False @@ -251,17 +250,15 @@ class mstr_tileprep: while edge_end[0] == 0: resinfo[0] = self._getResourceTouch(tv, th) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if resinfo[1] == "0": - self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2]) + self._storeResourceInfo(tv, th, self._selectResources()) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if "t" in resinfo[0]: tv=tv+1 rinfo = self._getResourceInfo(tv, th) - if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2]) + if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1]) else: edge_end[0] = 1 @@ -272,17 +269,15 @@ class mstr_tileprep: while edge_end[1] == 0: resinfo[0] = self._getResourceTouch(tv, th) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if resinfo[1] == "0": - self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2]) + self._storeResourceInfo(tv, th, self._selectResources()) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if "r" in resinfo[0]: th=th+1 rinfo = self._getResourceInfo(tv, th) - if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2]) + if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1]) else: edge_end[1] = 1 @@ -293,17 +288,15 @@ class mstr_tileprep: while edge_end[2] == 0: resinfo[0] = self._getResourceTouch(tv, th) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if resinfo[1] == "0": - self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2]) + self._storeResourceInfo(tv, th, self._selectResources()) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if "b" in resinfo[0]: tv=tv-1 rinfo = self._getResourceInfo(tv, th) - if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2]) + if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1]) else: edge_end[2] = 1 @@ -314,17 +307,15 @@ class mstr_tileprep: while edge_end[3] == 0: resinfo[0] = self._getResourceTouch(tv, th) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if resinfo[1] == "0": - self._storeResourceInfo(tv, th, self._selectResources(), resinfo[2]) + self._storeResourceInfo(tv, th, self._selectResources()) resinfo[1] = self._getResourceInfo(tv, th) - resinfo[2] = self._getResourceContrast(tv, th) if "l" in resinfo[0]: th=th-1 rinfo = self._getResourceInfo(tv, th) - if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1], resinfo[2]) + if rinfo == "0": self._storeResourceInfo(tv, th, resinfo[1]) else: edge_end[3] = 1