RC4 - Implemented cross-degree adjacency checks, corrected major issue in tile completion adjacency checks
This commit is contained in:
parent
d180f75e07
commit
a4c0291e74
178
layergen.py
178
layergen.py
@ -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.")
|
||||||
|
@ -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.")
|
||||||
|
@ -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))
|
@ -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 = {
|
||||||
|
14
photogen.py
14
photogen.py
@ -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")
|
64
tiledb.py
64
tiledb.py
@ -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()
|
||||||
|
|
||||||
|
32
tilegen.py
32
tilegen.py
@ -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.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user