# ------------------------------------------------------------------- # ORTHOGRAPHIC # Your personal aerial satellite. Always on. At any altitude.* # Developed by MarStrMind # License: Open Software License 3.0 # Up to date version always on marstr.online # ------------------------------------------------------------------- # tileprep.py # This prepares a zoom level 18 tile for ortho generation. This class # performs the edge detection, selects the required sources for each # layer, and stores this information into files which are then used # by layergen. # ------------------------------------------------------------------- import glob from os import MFD_ALLOW_SEALING from random import randrange from PIL import Image from osmxml import * from maskgen import * from defines import * from functions import * from log import * from tileinfo import * class mstr_tileprep: # For this to work we need some fundamentals. def __init__(self, lat, lng, v, h, tag, value, mask, is_completion): self._lat = lat self._lng = lng self._tile_h = h self._tile_v = v self._tag = tag self._value = value self._edges = "" # To be filled by _edgeDetect call self._source = "" self._mask = mask latlngfld = xplane_latlng_folder([lat, lng]) self._tileinfo = mstr_tileinfo(lat, lng, v, h, latlngfld) # Special case for the final step of an ortho self._is_completion = is_completion def _findCorrectTextureFolder(self): srcfld = [] for lyr in mstr_ortho_layers: if lyr[0] == self._tag and lyr[1] == self._value: srcfld.append(lyr[2]) srcfld.append(lyr[3]) break return srcfld # Use the mask to determine the edges def _determineEdges(self): # Load the mask pixels mp = self._mask.load() imgsize = self._mask.width # Run scan # 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 # Top scan for i in range(0, imgsize): p = mp[i,0] if p[3] > 0: at=True break # Right scan for i in range(0, imgsize): p = mp[imgsize-1,i] if p[3] > 0: ar=True break # Bottom scan for i in range(0, imgsize): p = mp[i,imgsize-1] if p[3] > 0: ab=True break # Left scan for i in range(0, imgsize): p = mp[0,i] if p[3] > 0: al=True break # Construct adjacency 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" # We will now write this down first, without a source being selected if adjstr != "": self._tileinfo.add_adjacency_data(self._tag, self._value, "0", adjstr) # Set the latlng folder def _setLatLngFold(self, latlngfld): self._latlngfld = latlngfld # Find out if there is already something in place for this tag of this tile def _getResourceInfo(self, tv, th): # This either remains 0 or a string different to "0" in the end src = "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[3] = l[3].replace("\n", "") src = l[2] return src # Find the edge touch info def _getResourceTouch(self, tv, th): touch = "" 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[3] = l[3].replace("\n", "") touch = l[3] return touch # Select a combination of resources def _selectResources(self): numbers = list(range(1, 16)) res = random.sample(numbers, 5) # Construct a string of the array resstr = "" for r in range(len(res)): resstr = resstr + str(res[r]) if r < len(res)-1: resstr = resstr + "," return resstr # Store the required resource information into the appropriate tile def _storeResourceInfo(self, tile_v, tile_h, res): df = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/" + str(tile_v) + "_" + str(tile_h) fnlines = [] contrast = 0 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 l[0] == self._tag and l[1] == self._value: l[2] = res contrast = int(l[4]) # Find contrast values for some tags 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") ): if int(l[4]) == 0: contrast = randrange(1, 4) l[3] = l[3].replace("\n", "") fnlines[curline] = l[0] + " " + l[1] + " " + l[2] + " " + l[3] + " " + str(contrast) + "\n" curline = curline+1 lines = "" for l in range(len(fnlines)): lines = lines + fnlines[l] with open(df, 'w') as textfile: textfile.write(lines) # 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 def _placeTileSources(self, mlat, mlng): # The first tile gets to choose something for itself if self._tile_v == 1 and self._tile_h == 1: resstr = self._selectResources() self._storeResourceInfo(1, 1, resstr) # Start "raytracing" # Initial reset tv = self._tile_v th = self._tile_h # Start marching north while tv < mlat+1: restch = self._getResourceTouch(tv, th) if "t" in restch: resstr = self._getResourceInfo(tv, th) if resstr == "0": resstr = self._selectResources() self._storeResourceInfo(tv, th, resstr) resd = self._getResourceInfo(tv+1, th) if resd=="0": self._storeResourceInfo(tv + 1, th, resstr) else: break tv = tv + 1 # Start marching east tv = self._tile_v th = self._tile_h while th < mlng + 1: restch = self._getResourceTouch(tv, th) if "r" in restch: resstr = self._getResourceInfo(tv, th) if resstr == "0": resstr = self._selectResources() self._storeResourceInfo(tv, th, resstr) resd = self._getResourceInfo(tv, th+1) if resd == "0": self._storeResourceInfo(tv, th + 1, resstr) else: break th = th + 1 # Start marching south tv = self._tile_v th = self._tile_h while tv > 0: restch = self._getResourceTouch(tv, th) if "b" in restch: resstr = self._getResourceInfo(tv, th) if resstr == "0": resstr = self._selectResources() self._storeResourceInfo(tv, th, resstr) resd = self._getResourceInfo(tv - 1, th) if resd == "0": self._storeResourceInfo(tv - 1, th, resstr) else: break tv = tv - 1 # Start marching west tv = self._tile_v th = self._tile_h while th > 0: restch = self._getResourceTouch(tv, th) if "l" in restch: resstr = self._getResourceInfo(tv, th) if resstr == "0": resstr = self._selectResources() self._storeResourceInfo(tv, th, resstr) resd = self._getResourceInfo(tv, th-1) if resd == "0": self._storeResourceInfo(tv, th - 1, resstr) else: break th = th - 1