RC4 - Implemented cross-degree adjacency checks, corrected major issue in tile completion adjacency checks

This commit is contained in:
marstr 2024-09-02 08:03:45 +02:00
parent d180f75e07
commit a4c0291e74
7 changed files with 285 additions and 93 deletions

View File

@ -45,8 +45,13 @@ class mstr_layergen:
self._isline = is_line self._isline = is_line
if mstr_photores == 2048: self._imgsize = 3000 if mstr_photores == 2048: self._imgsize = 3000
if mstr_photores == 4096: self._imgsize = 6000 if mstr_photores == 4096: self._imgsize = 6000
#mstr_msg("mstr_layergen", "Layer gen initialized") #mstr_msg("layergen", "Layer gen initialized")
# Define maximum latitude and longitude tile numbers
def set_max_latlng_tile(self, maxlatlng):
self._maxlat = maxlatlng[0]
self._maxlng = maxlatlng[1]
mstr_msg("layergen", "Maximum latitude and longitude tile numbers received")
# This generates a "border" image, for example farmland usually has a small space of grass # This generates a "border" image, for example farmland usually has a small space of grass
# before the actual crop of farm field itself. This generates this "border" layer, # before the actual crop of farm field itself. This generates this "border" layer,
@ -71,7 +76,7 @@ class mstr_layergen:
ptc_src = [] ptc_src = []
for p in ptc: for p in ptc:
ptc_src.append(Image.open(p)) ptc_src.append(Image.open(p))
mstr_msg("mstr_layergen", "Border sources selected") mstr_msg("layergen", "Border sources selected")
# Begin producing a largely random image # Begin producing a largely random image
samples = 250 # <- We need this in a moment samples = 250 # <- We need this in a moment
@ -85,11 +90,11 @@ class mstr_layergen:
t = 0 - int(ptc_src[imgid].height / 2) t = 0 - int(ptc_src[imgid].height / 2)
b = layer.height - 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) ) ) layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) )
mstr_msg("mstr_layergen", "Border image generated") mstr_msg("layergen", "Border image generated")
# We now need to add the seamless border # We now need to add the seamless border
layer.alpha_composite( brd_src ) layer.alpha_composite( brd_src )
mstr_msg("mstr_layergen", "Layer image completed") mstr_msg("layergen", "Layer image completed")
# And now for the Big Mac. # And now for the Big Mac.
# Generate the layer from the mask. # Generate the layer from the mask.
@ -103,13 +108,13 @@ class mstr_layergen:
# This generates the layer from the defined mask # This generates the layer from the defined mask
def genlayer(self): def genlayer(self):
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 ) mstr_msg("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 # Before we generate the layer, let's check for airports in this chunk
mstr_msg("mstr_layergen", "Checking for airport/s with ICAO code") mstr_msg("layergen", "Checking for airport/s with ICAO code")
osmxml = mstr_osmxml(0,0) osmxml = mstr_osmxml(0,0)
icao = osmxml.find_icao_codes(mstr_datafolder + "_cache\\tile.xml") icao = osmxml.find_icao_codes(mstr_datafolder + "_cache\\tile.xml")
mstr_msg("mstr_layergen", "Found " + str(len(icao)) + " airport/s") mstr_msg("layergen", "Found " + str(len(icao)) + " airport/s")
# Runway surface, if any other than concrete/asphalt # Runway surface, if any other than concrete/asphalt
rw_surface = "" rw_surface = ""
# If we find an airport, make a note ... # If we find an airport, make a note ...
@ -119,7 +124,7 @@ class mstr_layergen:
iccheck = self._tiledb.perform_query("SELECT * FROM airports WHERE icao='" + i +"';") iccheck = self._tiledb.perform_query("SELECT * FROM airports WHERE icao='" + i +"';")
if len(iccheck) == 0: if len(iccheck) == 0:
self._tiledb.insert_icao(i, self._lat_number, self._lng_number, self._latitude, self._longitude) 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") mstr_msg("layergen", "Airport/s noted in data file")
rw_surface = osmxml.find_runway_surface(mstr_datafolder + "_cache\\tile.xml") rw_surface = osmxml.find_runway_surface(mstr_datafolder + "_cache\\tile.xml")
# The image for the layer itself # The image for the layer itself
@ -146,7 +151,7 @@ class mstr_layergen:
# Find our adjacent tiles # Find our adjacent tiles
adjtiles = findAdjacentTilesTo(self._lat_number, self._lng_number) adjtiles = findAdjacentTilesTo(self._lat_number, self._lng_number)
mstr_msg("mstr_layergen", "Performing adjacency check") mstr_msg("layergen", "Performing adjacency check")
# Walk through each tile and see what we can find in relation to this # Walk through each tile and see what we can find in relation to this
# tile in the center # tile in the center
# Since we already know the order in adjtiles, we can do this real easy # Since we already know the order in adjtiles, we can do this real easy
@ -156,10 +161,30 @@ class mstr_layergen:
ab = self._tiledb.get_adjacency_for_source(adjtiles[2][0], adjtiles[2][1], self._tag, self._value) # Bottom 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 al = self._tiledb.get_adjacency_for_source(adjtiles[3][0], adjtiles[3][1], self._tag, self._value) # Left
if self._is_completion == True: if self._is_completion == True:
at = self._tiledb.get_adjacency_for_completion(adjtiles[0][0], adjtiles[0][1], self._tag, self._value) # Top at = self._tiledb.get_adjacency_for_completion(adjtiles[0][0], adjtiles[0][1]) # Top
ar = self._tiledb.get_adjacency_for_completion(adjtiles[1][0], adjtiles[1][1], self._tag, self._value) # Right ar = self._tiledb.get_adjacency_for_completion(adjtiles[1][0], adjtiles[1][1]) # Right
ab = self._tiledb.get_adjacency_for_completion(adjtiles[2][0], adjtiles[2][1], self._tag, self._value) # Bottom ab = self._tiledb.get_adjacency_for_completion(adjtiles[2][0], adjtiles[2][1]) # Bottom
al = self._tiledb.get_adjacency_for_completion(adjtiles[3][0], adjtiles[3][1], self._tag, self._value) # Left al = self._tiledb.get_adjacency_for_completion(adjtiles[3][0], adjtiles[3][1]) # Left
if len(at) == 1:
self._tag = at[0][2]
self._value = at[0][3]
if len(ar) == 1:
self._tag = ar[0][2]
self._value = ar[0][3]
if len(ab) == 1:
self._tag = ab[0][2]
self._value = ab[0][3]
if len(al) == 1:
self._tag = al[0][2]
self._value = al[0][3]
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]
# We are south to the top tile. # We are south to the top tile.
if len(at) == 1 and src == -1: if len(at) == 1 and src == -1:
@ -174,7 +199,93 @@ class mstr_layergen:
if len(al) == 1 and src == -1: if len(al) == 1 and src == -1:
if "r" in al[0][5]: src = int(al[0][4]) if "r" in al[0][5]: src = int(al[0][4])
mstr_msg("mstr_layergen", "Adjacency check completed") # Should we be at the border of the degree for latitude and longitude, we need to perform
# additional checks
is_deg_brd_t = False
is_deg_brd_r = False
is_deg_brd_b = False
is_deg_brd_l = False
if self._lat_number == 1: is_deg_brd_b = True
if self._lat_number == self._maxlat: is_deg_brd_t = True
if self._lng_number == 1: is_deg_brd_l = True
if self._lng_number == self._maxlng: is_deg_brd_r = True
# Adjacent latitude and longitude tiles
deg_tiles = []
deg_tiles.append( ( self._latitude+1, self._longitude ) ) # Top
deg_tiles.append( ( self._latitude, self._longitude+1 ) ) # Right
deg_tiles.append( ( self._latitude-1, self._longitude ) ) # Bottom
deg_tiles.append( ( self._latitude, self._longitude-1 ) ) # Left
# Perform degree border checks
# - and make sure we do not run into errors - this drove me crazy in testing
atd = []
ard = []
abd = []
ald = []
if is_deg_brd_t == True:
if self._is_completion == False:
atd = self._tiledb.get_adjacency_for_source_in_lat_lng(deg_tiles[0][0], deg_tiles[0][1], 1, self._lng_number, self._tag, self._value) # Top
if self._is_completion == True:
atd = self._tiledb.get_adjacency_for_completion_in_lat_lng(deg_tiles[0][0], deg_tiles[0][1], 1, self._lng_number) # Top
if is_deg_brd_r == True:
if self._is_completion == False:
ard = self._tiledb.get_adjacency_for_source_in_lat_lng(deg_tiles[1][0], deg_tiles[1][1], self._lat_number, 1, self._tag, self._value) # Right
if self._is_completion == True:
ard = self._tiledb.get_adjacency_for_completion_in_lat_lng(deg_tiles[1][0], deg_tiles[1][1], self._lat_number, 1) # Right
if is_deg_brd_b == True:
maxlatlng = self._tiledb.get_highest_latlong_from_tile(self._latitude-1, self._longitude)
if self._is_completion == False:
abd = self._tiledb.get_adjacency_for_source_in_lat_lng(deg_tiles[2][0], deg_tiles[2][1], maxlatlng[0], self._lng_number, self._tag, self._value) # Bottom
if self._is_completion == True:
abd = self._tiledb.get_adjacency_for_completion_in_lat_lng(deg_tiles[2][0], deg_tiles[2][1], maxlatlng[0], self._lng_number) # Bottom
if is_deg_brd_l == True:
maxlatlng = self._tiledb.get_highest_latlong_from_tile(self._latitude, self._longitude-1)
if self._is_completion == False:
ald = self._tiledb.get_adjacency_for_source_in_lat_lng(deg_tiles[2][0], deg_tiles[2][1], self._lat_number, maxlatlng[1], self._tag, self._value) # Left
if self._is_completion == True:
ald = self._tiledb.get_adjacency_for_completion_in_lat_lng(deg_tiles[2][0], deg_tiles[2][1], self._lat_number, maxlatlng[1]) # Left
if (is_deg_brd_t == True or is_deg_brd_r == True or is_deg_brd_b == True or is_deg_brd_l == True):
if src == -1 and self._is_completion == True:
if len(atd) == 1:
self._tag = atd[0][2]
self._value = atd[0][3]
if len(ard) == 1:
self._tag = ard[0][2]
self._value = ard[0][3]
if len(abd) == 1:
self._tag = abd[0][2]
self._value = abd[0][3]
if len(ald) == 1:
self._tag = ald[0][2]
self._value = ald[0][3]
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]
# Should we get here and one of the degree border checks turns out true,
# we need to make sure that we select the source we found. This should
# enable seamless tiling... around the entire planet
if is_deg_brd_t == True and len(at) == 0 and src == -1:
if len(atd) == 1:
if "b" in atd[0][5]: src = int(atd[0][4])
if is_deg_brd_r == True and len(ar) == 0 and src == -1:
if len(ard) == 1:
if "l" in ard[0][5]: src = int(ard[0][4])
if is_deg_brd_b == True and len(ab) == 0 and src == -1:
if len(abd) == 1:
if "t" in abd[0][5]: src = int(abd[0][4])
if is_deg_brd_l == True and len(al) == 0 and src == -1:
if len(ald) == 1:
if "r" in ald[0][5]: src = int(ald[0][4])
mstr_msg("layergen", "Adjacency check completed")
brd = glob.glob(root_folder + "\\brd\\b*.png") brd = glob.glob(root_folder + "\\brd\\b*.png")
@ -192,7 +303,7 @@ class mstr_layergen:
ptc_src = [] ptc_src = []
for p in ptc: for p in ptc:
ptc_src.append(Image.open(p)) ptc_src.append(Image.open(p))
mstr_msg("mstr_layergen", "Layer sources selected") mstr_msg("layergen", "Layer sources selected")
# OK! Load the mask # OK! Load the mask
if self._is_completion == False: if self._is_completion == False:
@ -203,7 +314,7 @@ class mstr_layergen:
# Generate an edge mask from the original # Generate an edge mask from the original
osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES)
osm_edge = osm_edge.filter(ImageFilter.MaxFilter) osm_edge = osm_edge.filter(ImageFilter.MaxFilter)
mstr_msg("mstr_layergen", "Edge mask generated") mstr_msg("layergen", "Edge mask generated")
# This adds some natural looking shapes to these types of features # This adds some natural looking shapes to these types of features
if self._value == "forest" or self._value == "nature_reserve": if self._value == "forest" or self._value == "nature_reserve":
@ -250,7 +361,7 @@ class mstr_layergen:
t = 0 - int(ptc_src[imgid].height / 2) t = 0 - int(ptc_src[imgid].height / 2)
b = layer.height - 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) ) ) layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) )
mstr_msg("mstr_layergen", "Layer image generated") mstr_msg("layergen", "Layer image generated")
# Here we need to do some magic to make some features look more natural # Here we need to do some magic to make some features look more natural
@ -266,7 +377,7 @@ class mstr_layergen:
# We now need to add the seamless border # We now need to add the seamless border
layer.alpha_composite( brd_src ) layer.alpha_composite( brd_src )
mstr_msg("mstr_layergen", "Layer image completed") mstr_msg("layergen", "Layer image completed")
# And now for the Big Mac. # And now for the Big Mac.
@ -301,7 +412,7 @@ class mstr_layergen:
if self._is_completion == True: 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_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" ) #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.") mstr_msg("layergen", "Layer image finalized and saved.")
# Let's try our hand at pseudo shadows # Let's try our hand at pseudo shadows
@ -310,7 +421,7 @@ class mstr_layergen:
shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) shadow = Image.new("RGBA", (self._imgsize, self._imgsize))
for sh in mstr_shadow_casters: for sh in mstr_shadow_casters:
if self._tag == sh[0] and self._value == sh[1]: if self._tag == sh[0] and self._value == sh[1]:
mstr_msg("mstr_layergen", "Generating shadow for layer") mstr_msg("layergen", "Generating shadow for layer")
shadow_pix = shadow.load() shadow_pix = shadow.load()
mask_pix = osm_mask.load() mask_pix = osm_mask.load()
for y in range(self._imgsize-1): for y in range(self._imgsize-1):
@ -333,7 +444,7 @@ class mstr_layergen:
aa = int(ca) aa = int(ca)
shadow_pix[shf_x, y] = (0,0,0,aa) 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") 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") mstr_msg("layergen", "Shadow layer completed")
@ -383,12 +494,19 @@ class mstr_layergen:
# Store into DB - but only if there is something to store # Store into DB - but only if there is something to store
if adjstr != "": if adjstr != "":
if self._is_completion == False: if self._is_completion == False:
self._tiledb.insert_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr) r = self._tiledb.get_adjacency_for_source(self._lat_number, self._lng_number, self._tag, self._value)
if len(r) == 0:
self._tiledb.insert_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr)
mstr_msg("layergen", "Adjacency info stored in database")
if self._is_completion == True: if self._is_completion == True:
self._tiledb.insert_completion_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr) r = self._tiledb.get_adjacency_for_completion(self._lat_number, self._lng_number)
if len(r) == 0:
self._tiledb.insert_completion_info(self._lat_number, self._lng_number, self._tag, self._value, src, adjstr)
mstr_msg("layergen", "Adjacency info for completion stored in database")
self._tiledb.commit_query() self._tiledb.commit_query()
self._tiledb.close_db() 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 we encounter one of these road-specific tags, we need to proceed differently.
@ -401,7 +519,7 @@ class mstr_layergen:
# Generate an edge mask from the original # Generate an edge mask from the original
osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES) osm_edge = osm_mask.filter(ImageFilter.FIND_EDGES)
osm_edge = osm_edge.filter(ImageFilter.MaxFilter) osm_edge = osm_edge.filter(ImageFilter.MaxFilter)
mstr_msg("mstr_layergen", "Edge mask generated") mstr_msg("layergen", "Edge mask generated")
# As above, we will apply the blur as noted in the defines # As above, we will apply the blur as noted in the defines
for i in mstr_mask_blur: for i in mstr_mask_blur:
@ -486,12 +604,12 @@ class mstr_layergen:
b = 138 - d b = 138 - d
layer_comp_pix[x, y] = ( r,g,b,a[3] ) layer_comp_pix[x, y] = ( r,g,b,a[3] )
mstr_msg("mstr_layergen", "Layer image generated") mstr_msg("layergen", "Layer image generated")
# Building shadow # Building shadow
if mstr_shadow_enabled == True: if mstr_shadow_enabled == True:
if self._tag == "building": if self._tag == "building":
mstr_msg("mstr_layergen", "Generating shadow for layer") mstr_msg("layergen", "Generating shadow for layer")
shadow = Image.new("RGBA", (self._imgsize, self._imgsize)) shadow = Image.new("RGBA", (self._imgsize, self._imgsize))
shadow_pix = shadow.load() shadow_pix = shadow.load()
mask_pix = osm_mask.load() mask_pix = osm_mask.load()
@ -506,7 +624,7 @@ class mstr_layergen:
aa = int(ca) aa = int(ca)
shadow_pix[shf_x, y] = (0,0,0,aa) 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") 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") mstr_msg("layergen", "Shadow layer completed")
# Highways and runways of any kind get some special treatment # 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"): 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"):
@ -521,11 +639,11 @@ class mstr_layergen:
a=mask_pix[x,y] a=mask_pix[x,y]
layer_comp_pix[x, y] = ( w,w,w,a[3] ) layer_comp_pix[x, y] = ( w,w,w,a[3] )
mstr_msg("mstr_layergen", "Street lines added") mstr_msg("layergen", "Street lines added")
if self._tag == "waterway" and (self._value == "river" or self._value == "stream"): if self._tag == "waterway" and (self._value == "river" or self._value == "stream"):
layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=4)) layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=4))
# Store layer # 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" ) 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.") mstr_msg("layergen", "Layer image finalized and saved.")

View File

@ -42,7 +42,7 @@ class mstr_maskgen:
self._vstep = vstep self._vstep = vstep
self._scale = 1 / math.cos(math.radians(self._box[0])) self._scale = 1 / math.cos(math.radians(self._box[0]))
self._isline = isline self._isline = isline
#mstr_msg("mstr_maskgen", "Intialized mask gen.") #mstr_msg("maskgen", "Intialized mask gen.")
# Projects a point into the canvas of the mask. # Projects a point into the canvas of the mask.
@ -81,7 +81,7 @@ class mstr_maskgen:
way = xml.acquire_waypoint_data(tilexml) way = xml.acquire_waypoint_data(tilexml)
rls = xml.acquire_relations(tilexml) rls = xml.acquire_relations(tilexml)
mstr_msg("mstr_maskgen", "Building mask for " + str(self._box[0]) + "-" + str(self._box[1]) + ", " + str(self._box[2]) + "-" + str(self._box[3]) + ", for " + self._tag + ": " + self._value ) mstr_msg("maskgen", "Building mask for " + str(self._box[0]) + "-" + str(self._box[1]) + ", " + str(self._box[2]) + "-" + str(self._box[3]) + ", for " + self._tag + ": " + self._value )
frs = [] frs = []
@ -181,4 +181,4 @@ class mstr_maskgen:
# Save image # Save image
mask_img.save(mstr_datafolder + "_cache\\" + fstr + "_" + self._tag + "-" + self._value + ".png") mask_img.save(mstr_datafolder + "_cache\\" + fstr + "_" + self._tag + "-" + self._value + ".png")
# Inform # Inform
mstr_msg("mstr_maskgen", "Mask built.") mstr_msg("maskgen", "Mask built.")

View File

@ -77,7 +77,7 @@ class mstr_orthographic:
# Builds and processes the tile with everything required, in one call. # Builds and processes the tile with everything required, in one call.
def _buildTile(self): def _buildTile(self):
mstr_msg("mstr_orthographic", "Beginning construction of tile") mstr_msg("orthographic", "Beginning construction of tile")
# We need to know which platform we are on # We need to know which platform we are on
os_platform = os.name os_platform = os.name
@ -86,23 +86,23 @@ class mstr_orthographic:
# Temporary images for the ortho tile generation go here # Temporary images for the ortho tile generation go here
if not os.path.exists(self._output + "/_cache"): if not os.path.exists(self._output + "/_cache"):
os.makedirs(self._output + "/_cache") os.makedirs(self._output + "/_cache")
mstr_msg("mstr_orthographic", "Created _cache folder.") mstr_msg("orthographic", "Created _cache folder.")
# Generate the Tiles folder for the finished products # Generate the Tiles folder for the finished products
if not os.path.exists(self._output + "/Tiles"): if not os.path.exists(self._output + "/Tiles"):
os.makedirs(self._output + "/Tiles") os.makedirs(self._output + "/Tiles")
mstr_msg("mstr_orthographic", "Created Tiles folder.") mstr_msg("orthographic", "Created Tiles folder.")
# Generate the Tiles/lat-lng folder for the finished tile # Generate the Tiles/lat-lng folder for the finished tile
if not os.path.exists(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long)): if not os.path.exists(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long)):
os.makedirs(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long)) os.makedirs(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long))
mstr_msg("mstr_orthographic", "Created Tiles sub folder: " +str(self._lat)+"_"+str(self._long)) mstr_msg("orthographic", "Created Tiles sub folder: " +str(self._lat)+"_"+str(self._long))
# Note down diameter of entire tile # Note down diameter of entire tile
#tile_dm = round(self._findWidthOfLongitude(), 3) #tile_dm = round(self._findWidthOfLongitude(), 3)
#mstr_msg("mstr_orthographic", "Tile diameter: " + str(tile_dm) + "m") #mstr_msg("orthographic", "Tile diameter: " + str(tile_dm) + "m")
#dm_of_18 = round(tile_dm * mstr_zl_18, 3) #dm_of_18 = round(tile_dm * mstr_zl_18, 3)
#mstr_msg("mstr_orthographic", "Diameter of ZL 18 tile: " + str(dm_of_18) + "m") #mstr_msg("orthographic", "Diameter of ZL 18 tile: " + str(dm_of_18) + "m")
# The tile is constructed of many smaller parts. We walk through the # The tile is constructed of many smaller parts. We walk through the
# smallest possible, from which the bigger ones are later built. # smallest possible, from which the bigger ones are later built.
@ -113,13 +113,30 @@ class mstr_orthographic:
cur_tile_x = 1 cur_tile_x = 1
cur_tile_y = 1 cur_tile_y = 1
osmxml = mstr_osmxml(0,0) osmxml = mstr_osmxml(0,0)
mstr_msg("mstr_orthographic", "Set initial coordinates and bounding box for OSM acquisition") mstr_msg("orthographic", "Set initial coordinates and bounding box for OSM acquisition")
# The highest encountered tile numbers # The highest encountered tile numbers
# This is needed to produce the zoom level 16 images # This is needed to produce the zoom level 16 images
top_lat = 1 top_lat = 1
top_lng = 1 top_lng = 1
# We need to know the highest possible latitude and longitude tile numbers,
# in case we render at the edge
mlat = 1
mlng = 1
while bb_lat < self._lat + 1:
bb_lat = bb_lat + self._vstep
mlat = mlat+1
while bb_lng < self._long + 1:
bb_lng = bb_lng + mstr_zl_18
mlng = mlng+1
mstr_msg("orthographic", "Max lat tile: " + str(mlat) + " - max lng tile: " + str(mlng))
maxlatlng = [ mlat, mlng ]
# Reset these two
bb_lat = self._lat
bb_lng = self._long
# Previously, I downloaded all XML files in one go - but to ease the # Previously, I downloaded all XML files in one go - but to ease the
# stress on OSM servers and my server, we will do acquire the data # stress on OSM servers and my server, we will do acquire the data
# only for the current processed part of the tile. # only for the current processed part of the tile.
@ -127,17 +144,17 @@ class mstr_orthographic:
while bb_lng < self._long + 1: while bb_lng < self._long + 1:
# Adjust bounding box # Adjust bounding box
osmxml.adjust_bbox(bb_lat, bb_lng, bb_lat_edge, bb_lng_edge) osmxml.adjust_bbox(bb_lat, bb_lng, bb_lat_edge, bb_lng_edge)
mstr_msg("mstr_orthographic", "Adjusted bounding box for XML object") mstr_msg("orthographic", "Adjusted bounding box for XML object")
# Determine what to do... maybe work was interrupted # Determine what to do... maybe work was interrupted
if os.path.isfile(mstr_datafolder + "Tiles\\" + str(self._lat) + "_" + str(self._long) + "\\Textures\\" + str(cur_tile_y) + "_" + str(cur_tile_x) + ".jpg") == False: if os.path.isfile(mstr_datafolder + "Tiles\\" + str(self._lat) + "_" + str(self._long) + "\\Textures\\" + str(cur_tile_y) + "_" + str(cur_tile_x) + ".jpg") == False:
# Let the user know # Let the user know
mstr_msg("mstr_orthographic", "Generating missing orthophoto " + str(cur_tile_y) + "-" + str(cur_tile_x)) mstr_msg("orthographic", "Generating missing orthophoto " + str(cur_tile_y) + "-" + str(cur_tile_x))
# Get the data # Get the data
osmxml.acquire_osm(cur_tile_y, cur_tile_x) # <- This acquires current OSM info osmxml.acquire_osm(cur_tile_y, cur_tile_x) # <- This acquires current OSM info
mstr_msg("mstr_orthographic", "Acquired current OSM info from marstr.online repository") mstr_msg("orthographic", "Acquired current OSM info from marstr.online repository")
# Check for work to be done # Check for work to be done
layers = self.determineLayerWork() layers = self.determineLayerWork()
@ -146,22 +163,22 @@ class mstr_orthographic:
# in their z-order. # in their z-order.
# For each layer, we will generate the mask, the layer image # For each layer, we will generate the mask, the layer image
# itself, and finally, compose the ortho photo. # itself, and finally, compose the ortho photo.
mstr_msg("mstr_orthographic", "Beginning generation of layers") mstr_msg("orthographic", "Beginning generation of layers")
# Generate the Tiles/lat-lng folder for the finished tile # Generate the Tiles/lat-lng folder for the finished tile
if not os.path.exists(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long) + "\\Textures"): if not os.path.exists(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long) + "\\Textures"):
os.makedirs(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long)+"\\Textures") os.makedirs(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long)+"\\Textures")
mstr_msg("mstr_orthographic", "Created tile textures folder") mstr_msg("orthographic", "Created tile textures folder")
# Generate the Tiles/terrain folder for the finished tile # Generate the Tiles/terrain folder for the finished tile
if not os.path.exists(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long) + "\\terrain"): if not os.path.exists(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long) + "\\terrain"):
os.makedirs(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long)+"\\terrain") os.makedirs(self._output + "/Tiles/"+str(self._lat)+"_"+str(self._long)+"\\terrain")
mstr_msg("mstr_orthographic", "Created tile terrain folder") mstr_msg("orthographic", "Created tile terrain folder")
curlyr = 1 curlyr = 1
for layer in layers: for layer in layers:
# Let the user know # Let the user know
mstr_msg("mstr_orthographic", "Processing layer " + str(curlyr) + " of " + str(len(layers))) mstr_msg("orthographic", "Processing layer " + str(curlyr) + " of " + str(len(layers)))
# Generate the mask # Generate the mask
mg = mstr_maskgen( [self._lat, cur_tile_y, self._long, cur_tile_x], self._vstep, layer[0], layer[1], layer[2] ) mg = mstr_maskgen( [self._lat, cur_tile_y, self._long, cur_tile_x], self._vstep, layer[0], layer[1], layer[2] )
@ -169,16 +186,17 @@ class mstr_orthographic:
# Generate the layer # Generate the layer
lg = mstr_layergen(layer[0], layer[1], self._lat, cur_tile_y, self._long, cur_tile_x, layer[2]) lg = mstr_layergen(layer[0], layer[1], self._lat, cur_tile_y, self._long, cur_tile_x, layer[2])
lg.set_max_latlng_tile(maxlatlng)
lg.genlayer() lg.genlayer()
curlyr = curlyr+1 curlyr = curlyr+1
mstr_msg("mstr_orthographic", "All layers created") mstr_msg("orthographic", "All layers created")
# We should have all layers now. # We should have all layers now.
# Snap a photo with our satellite :) # Snap a photo with our satellite :)
mstr_msg("mstr_orthographic", "Generating ortho photo") mstr_msg("orthographic", "Generating ortho photo")
pg = mstr_photogen(self._lat, self._long, cur_tile_y, cur_tile_x) pg = mstr_photogen(self._lat, self._long, cur_tile_y, cur_tile_x, maxlatlng[0], maxlatlng[1])
pg.genphoto() pg.genphoto()
mstr_msg("mstr_orthographic", "Ortho photo generated") mstr_msg("orthographic", " -- Ortho photo generated -- ")
print("") print("")
print("") print("")
@ -186,7 +204,7 @@ class mstr_orthographic:
cur_tile_x = cur_tile_x+1 cur_tile_x = cur_tile_x+1
bb_lng = bb_lng + mstr_zl_18 bb_lng = bb_lng + mstr_zl_18
bb_lng_edge = bb_lng_edge + mstr_zl_18 bb_lng_edge = bb_lng_edge + mstr_zl_18
mstr_msg("mstr_orthographic", "Adjustment of longitude performed") mstr_msg("orthographic", "Adjustment of longitude performed")
# Adjust peak longitude tile number # Adjust peak longitude tile number
if cur_tile_x > top_lng: if cur_tile_x > top_lng:
top_lng = cur_tile_x top_lng = cur_tile_x
@ -201,7 +219,7 @@ class mstr_orthographic:
if os_platform == "posix": if os_platform == "posix":
if self._isFileAccessiblePosix(f) == True: if self._isFileAccessiblePosix(f) == True:
os.remove(f) os.remove(f)
mstr_msg("mstr_orthographic", "Cleared cache") mstr_msg("orthographic", "Cleared cache")
# Adjust latitude and all other values when we get here # Adjust latitude and all other values when we get here
@ -211,25 +229,25 @@ class mstr_orthographic:
bb_lng_edge = self._long + mstr_zl_18 bb_lng_edge = self._long + mstr_zl_18
bb_lat = bb_lat + self._vstep bb_lat = bb_lat + self._vstep
bb_lat_edge = bb_lat_edge + self._vstep bb_lat_edge = bb_lat_edge + self._vstep
mstr_msg("mstr_orthographic", "Adjustment of latitude performed") mstr_msg("orthographic", "Adjustment of latitude performed")
# Adjust peak latitude number # Adjust peak latitude number
if cur_tile_y > top_lat: if cur_tile_y > top_lat:
top_lat = cur_tile_y top_lat = cur_tile_y
mstr_msg("mstr_orthographic", "Generation of all tiles completed!") mstr_msg("orthographic", "Generation of all tiles completed!")
mstr_msg("mstr_orthographic", "Generating ZL16 tiles and keeping airport tiles") mstr_msg("orthographic", "Generating ZL16 tiles and keeping airport tiles")
tg = mstr_tilegen(self._lat, self._lng, self._vstep, top_lat, top_lng) tg = mstr_tilegen(self._lat, self._lng, self._vstep, top_lat, top_lng)
tg.genTiles() tg.genTiles()
mstr_msg("mstr_orthographic", "Final step completed.") mstr_msg("orthographic", "Final step completed.")
print("") print("")
print("") print("")
mstr_msg("mstr_orthographic", "Tile data in: " + mstr_datafolder + "\\Tiles\\" + str(self._lat) + "_" + self._lng) mstr_msg("orthographic", "Tile data in: " + mstr_datafolder + "\\Tiles\\" + str(self._lat) + "_" + self._lng)
mstr_msg("mstr_orthographic", "Orthos are in the Textures subfolder") mstr_msg("orthographic", "Orthos are in the Textures subfolder")
mstr_msg("mstr_orthographic", "X-Plane .ter's are in the terrain subfolder") mstr_msg("orthographic", "X-Plane .ter's are in the terrain subfolder")
print("") print("")
print("") print("")
mstr_msg("mstr_orthographic", "Thanks for using Orthographic! -- Best, Marcus") mstr_msg("orthographic", "Thanks for using Orthographic! -- Best, Marcus")
print("") print("")
@ -239,7 +257,7 @@ class mstr_orthographic:
# Checks which layers need to be generated, and what kind of layer it is # Checks which layers need to be generated, and what kind of layer it is
def determineLayerWork(self): def determineLayerWork(self):
mstr_msg("mstr_orthographic", "Checking for work to be performed") mstr_msg("orthographic", "Checking for work to be performed")
layers = [] layers = []
@ -262,7 +280,7 @@ class mstr_orthographic:
break break
if has_way == True or has_rls == True: if has_way == True or has_rls == True:
mstr_msg("mstr_orthographic", "Adding: " + l[0]+":"+l[1]) mstr_msg("orthographic", "Adding: " + l[0]+":"+l[1])
is_line = False is_line = False
for s in mstr_ortho_layers: for s in mstr_ortho_layers:
if s[0] == l[0] and s[1] == l[1]: if s[0] == l[0] and s[1] == l[1]:
@ -275,7 +293,7 @@ class mstr_orthographic:
ly = (l[0], l[1], is_line) ly = (l[0], l[1], is_line)
layers.append(ly) layers.append(ly)
mstr_msg("mstr_orthographic", "A total of " + str(len(layers)) + " layers were found") mstr_msg("orthographic", "A total of " + str(len(layers)) + " layers were found")
return layers return layers
@ -287,4 +305,4 @@ class mstr_orthographic:
self._output = outfolder self._output = outfolder
self._pwd = pwd self._pwd = pwd
self._vstep = self._findVerticalStepping() self._vstep = self._findVerticalStepping()
mstr_msg("mstr_orthographic", "Initiated with LAT: " + str(lat) + ", LNG: " + str(lng)) mstr_msg("orthographic", "Initiated with LAT: " + str(lat) + ", LNG: " + str(lng))

View File

@ -38,7 +38,7 @@ class mstr_osmxml:
# Acquire XMLs in chunks, then store them # Acquire XMLs in chunks, then store them
def acquire_osm(self, v, h): def acquire_osm(self, v, h):
mstr_msg("mstr_osmxml", "Acquiring OSM data for " + str(self._lat)+","+str(self._lng)+" - "+str(self._curB_lat)+","+str(self._curB_lng)) mstr_msg("osmxml", "Acquiring OSM data for " + str(self._lat)+","+str(self._lng)+" - "+str(self._curB_lat)+","+str(self._curB_lng))
# We will use our self-hosted API for this. # We will use our self-hosted API for this.
data = { data = {

View File

@ -21,18 +21,19 @@ from log import *
class mstr_photogen: class mstr_photogen:
# Initializer doesn't need much # Initializer doesn't need much
def __init__ (self, lat, lng, ty, tx): def __init__ (self, lat, lng, ty, tx, maxlat, maxlng):
self._lat = lat self._lat = lat
self._lng = lng self._lng = lng
self._ty = ty self._ty = ty
self._tx = tx self._tx = tx
self._maxlatlng = [ maxlat, maxlng ]
# Define layer size depending on what is wanted # Define layer size depending on what is wanted
self._imgsize = 0 self._imgsize = 0
if mstr_photores == 2048: self._imgsize = 3000 if mstr_photores == 2048: self._imgsize = 3000
if mstr_photores == 4096: self._imgsize = 6000 if mstr_photores == 4096: self._imgsize = 6000
# Empty image where everything goes into # Empty image where everything goes into
self._tile = Image.new("RGBA", (self._imgsize, self._imgsize)) self._tile = Image.new("RGBA", (self._imgsize, self._imgsize))
mstr_msg("mstr_photogen", "Photogen initialized") mstr_msg("photogen", "Photogen initialized")
# This puts it all together. Bonus: AND saves it. # This puts it all together. Bonus: AND saves it.
@ -41,7 +42,7 @@ class mstr_photogen:
root_filename = mstr_datafolder + "\\_cache\\" + str(self._lat) + "-" + str(self._ty) + "_" + str(self._lng) + "-" + str(self._tx) + "_" root_filename = mstr_datafolder + "\\_cache\\" + str(self._lat) + "-" + str(self._ty) + "_" + str(self._lng) + "-" + str(self._tx) + "_"
# First, we walk through all layers and blend them on top of each other, in order # First, we walk through all layers and blend them on top of each other, in order
mstr_msg("mstr_photogen", "Merging layers") mstr_msg("photogen", "Merging layers")
for l in mstr_ortho_layers: for l in mstr_ortho_layers:
if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer.png"): if os.path.isfile(root_filename + l[0] + "-" + l[1] + "_layer.png"):
@ -67,7 +68,7 @@ class mstr_photogen:
# First, we will check if there is something to fix: # First, we will check if there is something to fix:
emptyspace = self.checkForEmptySpace() emptyspace = self.checkForEmptySpace()
mstr_msg("mstr_photogen", "Checked for empty patches") mstr_msg("photogen", "Checked for empty patches")
# If this check comes back as true, we need to perform # If this check comes back as true, we need to perform
# aforementioned fix: # aforementioned fix:
@ -79,11 +80,12 @@ class mstr_photogen:
tag = mstr_ortho_layers[ltp][0] tag = mstr_ortho_layers[ltp][0]
value = mstr_ortho_layers[ltp][1] value = mstr_ortho_layers[ltp][1]
mstr_msg("mstr_photogen", "Patching empty space") mstr_msg("photogen", "Patching empty space")
self.buildCompletionMask() self.buildCompletionMask()
# Generate the layer as if it were part of the OSM data # Generate the layer as if it were part of the OSM data
lg = mstr_layergen(tag, value, self._lat, self._ty, self._lng, self._tx, False, is_completion=True) lg = mstr_layergen(tag, value, self._lat, self._ty, self._lng, self._tx, False, is_completion=True)
lg.set_max_latlng_tile(self._maxlatlng)
lg.genlayer() lg.genlayer()
# Load the image # Load the image
@ -146,4 +148,4 @@ class mstr_photogen:
# exact pixel positions. # exact pixel positions.
mask.save( mstr_datafolder + "_cache\\" + str(self._lat) + "-" + str(self._ty) + "_" + str(self._lng) + "-" + str(self._tx) + "_tile-completion.png" ) mask.save( mstr_datafolder + "_cache\\" + str(self._lat) + "-" + str(self._ty) + "_" + str(self._lng) + "-" + str(self._tx) + "_tile-completion.png" )
mstr_msg("mstr_photogen", "Generated and saved empty space mask") mstr_msg("photogen", "Generated and saved empty space mask")

View File

@ -26,7 +26,7 @@ class mstr_tiledb:
# The db file will be created, should it not exist # The db file will be created, should it not exist
self._conn = sqlite3.connect(mstr_datafolder + "Tiles\\" + str(self._latitude) + "_" + str(self._longitude) + "\\data.db") self._conn = sqlite3.connect(mstr_datafolder + "Tiles\\" + str(self._latitude) + "_" + str(self._longitude) + "\\data.db")
self._crs = self._conn.cursor() self._crs = self._conn.cursor()
#mstr_msg("mstr_tiledb", "Database object initiated") #mstr_msg("tiledb", "Database object initiated")
# Opens a database file - used by maskgen # Opens a database file - used by maskgen
@ -40,7 +40,7 @@ class mstr_tiledb:
self._conn.execute("CREATE TABLE IF NOT EXISTS tiledata (tile_v INTEGER, tile_h INTEGER, tag TEXT, value TEXT, source INTEGER, adjacent TEXT);") self._conn.execute("CREATE TABLE IF NOT EXISTS tiledata (tile_v INTEGER, tile_h INTEGER, tag TEXT, value TEXT, source INTEGER, adjacent TEXT);")
self._conn.execute("CREATE TABLE IF NOT EXISTS airports (icao TEXT, tile_v INTEGER, tile_h INTEGER, latitude REAL, longitude REAL);") self._conn.execute("CREATE TABLE IF NOT EXISTS airports (icao TEXT, tile_v INTEGER, tile_h INTEGER, latitude REAL, longitude REAL);")
self._conn.execute("CREATE TABLE IF NOT EXISTS completion (tile_v INTEGER, tile_h INTEGER, tag TEXT, value TEXT, source INTEGER, adjacent TEXT);") self._conn.execute("CREATE TABLE IF NOT EXISTS completion (tile_v INTEGER, tile_h INTEGER, tag TEXT, value TEXT, source INTEGER, adjacent TEXT);")
#mstr_msg("mstr_tiledb", "Tables created") #mstr_msg("tiledb", "Tables created")
# Insert data into their segments # Insert data into their segments
@ -68,11 +68,65 @@ class mstr_tiledb:
return rws return rws
# Retrieve the adjacency info for completion of a tile # Retrieve the adjacency info for completion of a tile
def get_adjacency_for_completion(self, v, h, tag, value): def get_adjacency_for_completion(self, v, h):
r = self._crs.execute("SELECT * FROM completion where tile_v="+str(v)+" and tile_h="+str(h)+" and tag='"+tag+"' and value='"+value+"';") r = self._crs.execute("SELECT * FROM completion where tile_v="+str(v)+" and tile_h="+str(h)+";")
rws = r.fetchall() rws = r.fetchall()
return rws return rws
# These calls are a bit more complex. We also need to know adjacency info when we are directly
# next to another latitude or longitude. We want seamless generation in those situations too.
def get_adjacency_for_source_in_lat_lng(self, lat, lng, v, h, tag, value):
# The rows to return
rws = []
# For this we need to tap into the database of the tile, should there be one.
dbn = mstr_datafolder + "Tiles\\" + str(lat) + "_" + str(lng) + "\\data.db"
if os.path.isfile(dbn):
tileconn = sqlite3.connect(dbn)
tilecrsr = tileconn.cursor()
r = tilecrsr.execute("SELECT * from tiledata WHERE tile_v="+str(v)+" AND tile_h="+str(h)+" AND tag='"+tag+"' AND value='"+value+"';")
rws = r.fetchall()
tileconn.close()
return rws
# These calls are a bit more complex. We also need to know adjacency info when we are directly
# next to another latitude or longitude. We want seamless generation in those situations too.
def get_adjacency_for_completion_in_lat_lng(self, lat, lng, v, h):
# The rows to return
rws = []
# For this we need to tap into the database of the tile, should there be one.
dbn = mstr_datafolder + "Tiles\\" + str(lat) + "_" + str(lng) + "\\data.db"
if os.path.isfile(dbn):
tileconn = sqlite3.connect(dbn)
tilecrsr = tileconn.cursor()
r = tilecrsr.execute("SELECT * from completion WHERE tile_v="+str(v)+" AND tile_h="+str(h)+";")
rws = r.fetchall()
tileconn.close()
return rws
# Acquire the highest latitude and longitude tile number of a neighbouring tile
def get_highest_latlong_from_tile(self, lat, lng):
latlng = [-1, -1]
# For this we need to tap into the database of the tile, should there be one.
dbn = mstr_datafolder + "Tiles\\" + str(lat) + "_" + str(lng) + "\\data.db"
if os.path.isfile(dbn):
tileconn = sqlite3.connect(dbn)
tilecrsr = tileconn.cursor()
lt = tilecrsr.execute("SELECT * FROM tiledata ORDER BY tile_v DESC")
rws = lt.fetchall()
lat = rws[0][0]
ln = tilecrsr.execute("SELECT * FROM tiledata ORDER BY tile_h DESC")
rws = ln.fetchall()
lng = rws[0][1]
latlng[0] = lat
latlng[1] = lng
tileconn.close()
return latlng
# Get all tiles with detected airports (ICAO codes) # Get all tiles with detected airports (ICAO codes)
def get_tiles_with_airports(self): def get_tiles_with_airports(self):
r = self._crs.execute("SELECT * FROM airports") r = self._crs.execute("SELECT * FROM airports")
@ -89,6 +143,6 @@ class mstr_tiledb:
# Close DB # Close DB
def close_db(self): def close_db(self):
mstr_msg("mstr_tiledb", "Closing database connection") mstr_msg("tiledb", "Closing database connection")
self._conn.close() self._conn.close()

View File

@ -32,7 +32,7 @@ class mstr_tilegen:
self._maxlng = max_lng self._maxlng = max_lng
# Connection to DB # Connection to DB
self._tiledb = mstr_tiledb(lat, lng) self._tiledb = mstr_tiledb(lat, lng)
mstr_msg("mstr_tilegen", "Tilegen initialized") mstr_msg("tilegen", "Tilegen initialized")
# To write down X-Plane .ter files, we will need to know the exact size # To write down X-Plane .ter files, we will need to know the exact size
@ -62,7 +62,7 @@ class mstr_tilegen:
# Find out how many steps we can walk in every direction # Find out how many steps we can walk in every direction
steps_lat = int(math.ceil(self._maxlat/4)) steps_lat = int(math.ceil(self._maxlat/4))
steps_lng = int(math.ceil(self._maxlng/4)) steps_lng = int(math.ceil(self._maxlng/4))
mstr_msg("mstr_tilegen", "Latitude and longitude steps determined") mstr_msg("tilegen", "Latitude and longitude steps determined")
# OK... so. Let's finish this. # OK... so. Let's finish this.
for lt in range(1, steps_lat): for lt in range(1, steps_lat):
@ -70,7 +70,7 @@ class mstr_tilegen:
# Check if we need to do something # Check if we need to do something
if os.path.isfile(mstr_datafolder + "Tiles\\" + str(self._lat) + "_" + str(self._lng) + "\\Textures\\" + str(self._lat) + "-" + str(ln) + "_" + str(self._lng) + "-" + str(lt) + "_OG16.jpg") == False: if os.path.isfile(mstr_datafolder + "Tiles\\" + str(self._lat) + "_" + str(self._lng) + "\\Textures\\" + str(self._lat) + "-" + str(ln) + "_" + str(self._lng) + "-" + str(lt) + "_OG16.jpg") == False:
mstr_msg("mstr_tilegen", "Generating missing zoom level 16 ortho " + str(self._lat) + "-" + str(ln) + "_" + str(self._lng) + "-" + str(lt) + "_OG16.jpg") mstr_msg("tilegen", "Generating missing zoom level 16 ortho " + str(self._lat) + "-" + str(ln) + "_" + str(self._lng) + "-" + str(lt) + "_OG16.jpg")
# Find out which tiles to process # Find out which tiles to process
tiles = findZL16tiles(cur_lat, cur_lng) tiles = findZL16tiles(cur_lat, cur_lng)
@ -107,45 +107,45 @@ LOAD_CENTER """ + str(a_lat) + " " + str(a_lng) + " " + str(dmt) + " " + "../Tex
NO_ALPHA""" NO_ALPHA"""
with open(mstr_datafolder + "\\Tiles\\"+str(self._lat)+"_"+str(self._lng)+"\\terrain\\"+str(self._lat)+"_"+str(lt)+"-"+str(self._lng)+"-"+str(ln)+"_OG16.ter", 'w') as textfile: with open(mstr_datafolder + "\\Tiles\\"+str(self._lat)+"_"+str(self._lng)+"\\terrain\\"+str(self._lat)+"_"+str(lt)+"-"+str(self._lng)+"-"+str(ln)+"_OG16.ter", 'w') as textfile:
textfile.write(ter_content) textfile.write(ter_content)
mstr_msg("mstr_tilegen", "Wrote .ter file") mstr_msg("tilegen", "Wrote .ter file")
# Adjust # Adjust
a_lng = a_lng + (mstr_zl_16 * 4) a_lng = a_lng + (mstr_zl_16 * 4)
cur_lng = cur_lng + 4 cur_lng = cur_lng + 4
mstr_msg("mstr_tilegen", "Adjusted coordinate values") mstr_msg("tilegen", "Adjusted coordinate values")
# Adjust # Adjust
a_lng = self._lat + (mstr_zl_16 * 2) a_lng = self._lat + (mstr_zl_16 * 2)
a_lat = a_lat + (self._vstep * 4) a_lat = a_lat + (self._vstep * 4)
cur_lat = cur_lat + 4 cur_lat = cur_lat + 4
cur_lng = self._lng cur_lng = self._lng
mstr_msg("mstr_tilegen", "Adjusted coordinate values for next tile loop") mstr_msg("tilegen", "Adjusted coordinate values for next tile loop")
mstr_msg("mstr_tilegen", "Tile generation... completed (wow.jpg)") mstr_msg("tilegen", "Tile generation... completed (wow.jpg)")
# BUT! This is not the end. Yet. # BUT! This is not the end. Yet.
# Make sure we keep tiles around airports. # Make sure we keep tiles around airports.
airports = self._tiledb.get_tiles_with_airports() airports = self._tiledb.get_tiles_with_airports()
mstr_msg("mstr_tilegen", "Filtering ZL18 tiles for airports") mstr_msg("tilegen", "Filtering ZL18 tiles for airports")
# The ZL 18 tiles to keep in the end # The ZL 18 tiles to keep in the end
tiles = [] tiles = []
mstr_msg("mstr_tilegen", "Finding ZL18 tiles to keep") mstr_msg("tilegen", "Finding ZL18 tiles to keep")
for a in airports: for a in airports:
tiles.append(findAirportTiles(int(a[1]), int(a[2]))) tiles.append(findAirportTiles(int(a[1]), int(a[2])))
mstr_msg("mstr_tilegen", "Determined ZL18 tiles") mstr_msg("tilegen", "Determined ZL18 tiles")
# Create a final array to make life easier # Create a final array to make life easier
mstr_msg("mstr_tilegen", "Generating arrays for tiles to keep") mstr_msg("tilegen", "Generating arrays for tiles to keep")
keeping = [] keeping = []
for t in tiles: for t in tiles:
for i in t: for i in t:
keeping.append(i) keeping.append(i)
# Perform the cleanup # Perform the cleanup
mstr_msg("mstr_tilegen", "Cleaning up non-needed tiles") mstr_msg("tilegen", "Cleaning up non-needed tiles")
for y in range(1, self._maxlat): for y in range(1, self._maxlat):
for x in range(1, self._maxlng): for x in range(1, self._maxlng):
fn = str(y) + "_" + str(x) + ".jpg" fn = str(y) + "_" + str(x) + ".jpg"
@ -157,11 +157,11 @@ NO_ALPHA"""
break break
if found == False: if found == False:
os.remove(mstr_datafolder + "\\Tiles\\" + str(self._lat) + "_" + str(self._lng) + "\\Textures\\" + fn) os.remove(mstr_datafolder + "\\Tiles\\" + str(self._lat) + "_" + str(self._lng) + "\\Textures\\" + fn)
mstr_msg("mstr_tilegen", "Cleanup completed") mstr_msg("tilegen", "Cleanup completed")
# And now for the final act of tonight's entertainment # And now for the final act of tonight's entertainment
mstr_msg("mstr_tilegen", "Writing .ter files for ZL18 tiles") mstr_msg("tilegen", "Writing .ter files for ZL18 tiles")
for k in keeping: for k in keeping:
k_lat = self._lat + (k[0] * self._vstep) + (self._vstep * 0.5) k_lat = self._lat + (k[0] * self._vstep) + (self._vstep * 0.5)
@ -176,9 +176,9 @@ LOAD_CENTER """ + str(k_lat) + " " + str(k_lng) + " " + str(k_dmt) + " " + "../T
NO_ALPHA""" NO_ALPHA"""
with open(k_fln, 'w') as textfile: with open(k_fln, 'w') as textfile:
textfile.write(ter_content) textfile.write(ter_content)
mstr_msg("mstr_tilegen", "Wrote all .ter files for ZL18 tiles.") mstr_msg("tilegen", "Wrote all .ter files for ZL18 tiles.")
mstr_msg("mstr_tilegen", "Work complete.") mstr_msg("tilegen", "Work complete.")