from log import *\r
\r
class mstr_osmxml:\r
- def __init__(self, lat, lng):\r
- self._latv = lat\r
- self._lngv = lng\r
- self._lat = lat\r
- self._lng = lng\r
- self._curB_lat = lat + mstr_zl_18\r
- self._curB_lng = lng + mstr_zl_18\r
+ def __init__(self):\r
+ #self._xmlfn = mstr_datafolder + "_cache/tile_" + str(lat) + "-" + str(v) + "_" + str(lng) + "-" + str(h) + ".xml"\r
+ self._xmldata = None\r
+ self._xmlcontent = ""\r
\r
\r
# Adjust bbox for when this class should persost, but acquire data for a different bbox\r
mstr_msg("osmxml", "Acquiring OSM data for " + str(self._lat)+","+str(self._lng)+" - "+str(self._curB_lat)+","+str(self._curB_lng))\r
\r
# We will use our self-hosted API for this.\r
- while os.path.isfile(mstr_datafolder + "_cache/tile.xml") == False:\r
+ while os.path.isfile(self._xmlfn) == False:\r
data = { \r
"bbox": { \r
"lat": str(self._lat),\r
}\r
r = requests.post(mstr_osm_endpoint, json=data)\r
\r
- xmlf = mstr_datafolder + "_cache/tile.xml"\r
- if os.path.isfile(xmlf):\r
- os.remove(xmlf)\r
- with open(xmlf, 'wb') as textfile:\r
- textfile.write(r.content)\r
+ self._xmlcontent = r.content\r
+\r
+ #if os.path.isfile(self._xmlfn):\r
+ # os.remove(self._xmlfn)\r
+ #with open(self._xmlfn, 'wb') as textfile:\r
+ # textfile.write(r.content)\r
\r
# 1 second delay in case the request fails\r
- if os.path.isfile(mstr_datafolder + "_cache/tile.xml") == False:\r
+ if self._xmlcontent == "":\r
+ #if os.path.isfile(self._xmlfn) == False:\r
sleep(1)\r
- \r
- # Provide the object directly\r
- if asobject == True:\r
- xml_doc = xml.dom.minidom.parse("_cache/tile.xml")\r
- return xml_doc\r
+ \r
+ # Store the content in memory\r
+ self._xmldata = xml.dom.minidom.parse(self._xmlcontent)\r
+ self._xmlcontent = "" # Clear\r
\r
\r
# Get all nodes from the specified OSM file\r
- def acquire_nodes(self, xmlfile):\r
- xml_doc = xml.dom.minidom.parse(xmlfile)\r
- nodedata = xml_doc.getElementsByTagName("node")\r
+ def acquire_nodes(self):\r
+ #xml_doc = xml.dom.minidom.parse(xmlfile)\r
+ nodedata = self._xmldata.getElementsByTagName("node")\r
nodes = []\r
for node in nodedata:\r
p = (node.getAttribute("id"), node.getAttribute("lat"), node.getAttribute("lon"))\r
\r
\r
# Get all waypoint data\r
- def acquire_waypoint_data(self, xmlfile):\r
- xml_doc = xml.dom.minidom.parse(xmlfile)\r
- wpdata = xml_doc.getElementsByTagName("way")\r
+ def acquire_waypoint_data(self):\r
+ #xml_doc = xml.dom.minidom.parse(xmlfile)\r
+ wpdata = self._xmldata.getElementsByTagName("way")\r
wps = []\r
for wp in wpdata:\r
nddata = wp.getElementsByTagName("nd")\r
\r
# Checks if there is an airport or many airports with an ICAO code in the\r
# supplied XML data chunk\r
- def find_icao_codes(self, xmlfile):\r
+ def find_icao_codes(self):\r
icao = []\r
- xml_doc = xml.dom.minidom.parse(xmlfile)\r
- wpdata = xml_doc.getElementsByTagName("way")\r
+ #xml_doc = xml.dom.minidom.parse(xmlfile)\r
+ wpdata = self._xmldata.getElementsByTagName("way")\r
for wp in wpdata:\r
tags = wp.getElementsByTagName("tag")\r
for tag in tags:\r
# If no surface type is specified, the runway will be rendered similar\r
# to how motorways are rendered.\r
# This gets called only if some ICAO code was found\r
- def find_runway_surface(self, xmlfile):\r
+ def find_runway_surface(self):\r
surface = ""\r
wpid = ""\r
- xml_doc = xml.dom.minidom.parse(xmlfile)\r
- wpdata = xml_doc.getElementsByTagName("way")\r
+ #xml_doc = xml.dom.minidom.parse(xmlfile)\r
+ wpdata = self._xmldata.getElementsByTagName("way")\r
for wp in wpdata:\r
tags = wp.getElementsByTagName("tag")\r
for tag in tags:\r
# Find the levels of a building (for shadow rendering)\r
def find_building_levels(self, way_id):\r
lvl = 2 # Standard if we don't find anything else\r
- xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
- wpdata = xml_doc.getElementsByTagName("way")\r
+ #xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
+ wpdata = self._xmldata.getElementsByTagName("way")\r
for wp in wpdata:\r
if wp.getAttribute("id") == way_id:\r
tags = wp.getElementsByTagName("tag")\r
# Find minimum level of a building\r
def find_building_minlevel(self, way_id):\r
lvl = 0 # Standard if we don't find anything else\r
- xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
- wpdata = xml_doc.getElementsByTagName("way")\r
+ #xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
+ wpdata = self._xmldata.getElementsByTagName("way")\r
for wp in wpdata:\r
if wp.getAttribute("id") == way_id:\r
tags = wp.getElementsByTagName("tag")\r
# Find the roof shape\r
def find_building_roof_shape(self, way_id):\r
rs = "flat" # Standard if we don't find anything else\r
- xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
- wpdata = xml_doc.getElementsByTagName("way")\r
+ #xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
+ wpdata = self._xmldata.getElementsByTagName("way")\r
for wp in wpdata:\r
if wp.getAttribute("id") == way_id:\r
tags = wp.getElementsByTagName("tag")\r
# Find the roof levels\r
def find_building_roof_levels(self, way_id):\r
lvl = 0 # Standard if we don't find anything else\r
- xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
- wpdata = xml_doc.getElementsByTagName("way")\r
+ #xml_doc = xml.dom.minidom.parse(mstr_datafolder + "_cache/tile.xml")\r
+ wpdata = self._xmldata.getElementsByTagName("way")\r
for wp in wpdata:\r
if wp.getAttribute("id") == way_id:\r
tags = wp.getElementsByTagName("tag")\r
# the relations and then scan through the outer and inner way IDs.\r
#\r
# Get all relation entries of importance.\r
- def acquire_relations(self, xmlfile):\r
- xml_doc = xml.dom.minidom.parse(xmlfile)\r
- rlxml = xml_doc.getElementsByTagName("relation")\r
+ def acquire_relations(self):\r
+ #xml_doc = xml.dom.minidom.parse(xmlfile)\r
+ rlxml = self._xmldata.getElementsByTagName("relation")\r
rls = []\r
for rl in rlxml:\r
rldata = rl.getElementsByTagName("member")\r
--- /dev/null
+
+# -------------------------------------------------------------------
+# ORTHOGRAPHIC
+# Your personal aerial satellite. Always on. At any altitude.*
+# Developed by MarStrMind
+# License: Open Software License 3.0
+# Up to date version always on marstr.online
+# -------------------------------------------------------------------
+# tileprep.py
+# This prepares a zoom level 18 tile for ortho generation. This class
+# performs the edge detection, selects the required sources for each
+# layer, and stores this information into files which are then used
+# by layergen.
+# -------------------------------------------------------------------
+
+import glob
+from random import randrange
+from PIL import Image
+from osmxml import *
+from maskgen import *
+from defines import *
+from functions import *
+from log import *
+from tileinfo import *
+
+class mstr_tileprep:
+
+ # For this to work we need some fundamentals.
+ def __init__(self, lat, lng, v, h, tag, value, mask, is_completion):
+ self._lat = lat
+ self._lng = lng
+ self._tile_h = h
+ self._tile_v = v
+ self._tag = tag
+ self._value = value
+ self._edges = "" # To be filled by _edgeDetect call
+ self._source = -1
+ self._mask = mask
+ latlngfld = xplane_latlng_folder([lat, lng])
+ self._tileinfo = mstr_tileinfo(lat, lng, v, h, latlngfld)
+
+ # Special case for the final step of an ortho
+ self._is_completion = is_completion
+
+
+ # Prepare the tile accordingly
+ def _prepareTile(self):
+ # Load the mask pixels
+ mp = self._mask.load()
+ imgsize = self._mask.width
+
+ # Run scan
+
+ # Check if pixels touch the borders of the image, and if so -
+ # make a not of that in the database.
+ at=False
+ ar=False
+ ab=False
+ al=False
+
+ # Top scan
+ for i in range(0, imgsize-1):
+ p = mp[i,0]
+ if p[3] > 0:
+ at=True
+ break
+
+ # Right scan
+ for i in range(0, imgsize-1):
+ p = mp[imgsize-1,i]
+ if p[3] > 0:
+ ar=True
+ break
+
+ # Bottom scan
+ for i in range(0, imgsize-1):
+ p = mp[i,imgsize-1]
+ if p[3] > 0:
+ ab=True
+ break
+
+ # Left scan
+ for i in range(0, imgsize-1):
+ p = mp[1,i]
+ if p[3] > 0:
+ al=True
+ break
+
+ # Construct adjacency string
+ adjstr = ""
+ if at==True: adjstr = adjstr + "t"
+ if ar==True: adjstr = adjstr + "r"
+ if ab==True: adjstr = adjstr + "b"
+ if al==True: adjstr = adjstr + "l"
+
+ # Now find out of there is a source from any adjacent tile
+ adjtiles = findAdjacentTilesTo(self._tile_v, self._tile_h)
+ sat = []
+ sar = []
+ sab = []
+ sal = []
+ if self._is_completion == False:
+ if at == True: sat = self._tileinfo.get_adjacency_for_tag_and_value(adjtiles[0][0], adjtiles[0][1], self._tag, self._value) # Top
+ if ar == True: sar = self._tileinfo.get_adjacency_for_tag_and_value(adjtiles[1][0], adjtiles[1][1], self._tag, self._value) # Right
+ if ab == True: sab = self._tileinfo.get_adjacency_for_tag_and_value(adjtiles[2][0], adjtiles[2][1], self._tag, self._value) # Bottom
+ if al == True: sal = self._tileinfo.get_adjacency_for_tag_and_value(adjtiles[3][0], adjtiles[3][1], self._tag, self._value) # Left
+ if self._is_completion == True:
+ if at == True: sat = self._tileinfo.get_adjacency_for_completion(adjtiles[0][0], adjtiles[0][1]) # Top
+ if ar == True: sar = self._tileinfo.get_adjacency_for_completion(adjtiles[1][0], adjtiles[1][1]) # Right
+ if ab == True: sab = self._tileinfo.get_adjacency_for_completion(adjtiles[2][0], adjtiles[2][1]) # Bottom
+ if al == True: sal = self._tileinfo.get_adjacency_for_completion(adjtiles[3][0], adjtiles[3][1]) # Left
+
+ if self._source == -1 and len(sat) == 2: self._source = sat[0]
+ if self._source == -1 and len(sar) == 2: self._source = sar[0]
+ if self._source == -1 and len(sab) == 2: self._source = sab[0]
+ if self._source == -1 and len(sal) == 2: self._source = sal[0]
+
+ # If there was nothing in the info still, we need to select some source
+ if self._source == -1:
+ tx = mstr_datafolder + "textures/" + self._tag + "/" + self._value + "/brd/b*.png"
+ lst = glob.glob(tx)
+ if len(lst) == 1: self._source = 1
+ if len(lst) >= 2: self._source = randrange(1, len(lst)+1)
+
+
+ # Store into DB - but only if there is something to store
+ if adjstr != "":
+ if self._is_completion == False:
+ r = self._tileinfo.get_adjacency_for_tag_and_value(self._tile_v, self._tile_h, self._tag, self._value)
+ if len(r) == 0:
+ self._tileinfo.add_adjacency_data(self._tile_v, self._tile_h, self._tag, self._value, self._source, adjstr)
+ mstr_msg("tileprep", "Adjacency info stored in database")
+
+ if self._is_completion == True:
+ r = self._tileinfo.get_adjacency_for_completion(self._tile_v, self._tile_h)
+ if len(r) == 0:
+ self._tileinfo.add_completion_data(self._tile_v, self._tile_h, self._tag, self._value, self._source, adjstr)
+ mstr_msg("tileprep", "Adjacency info for completion stored in database")
+