# ------------------------------------------------------------------- # 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 # ------------------------------------------------------------------- # xp_dsfgen.py # This class is coming into play at the very end of the tile # generation process, and builds the DSF (Distributable Scenery # Format) file for X-Plane. # # For this, you will need two tools which I cannot re-distribute: # - DSFTool # - DDSTool # # You can download both of these for free from X-Plane's website. # Place them somewhere convenient, and point to them in the # xp_ variables in defines.py # ------------------------------------------------------------------- import os import glob import math from random import randrange from log import * from tiledb import * class mstr_xp_dsfgen: # Instantiate with Lat/Lng, as usual def __init__(self, lat, lng, amtdg): self._latitude = lat self._longitude = lng self._tiledb = mstr_tiledb(lat, lng) self._tmpdsf = mstr_datafolder + "_cache/tiledsf.txt" self._dsfstring = "" self._amtdg = amtdg mstr_msg("xp_dsfgen", "DSFgen initialized") self.build_header() # Construct header of DSF txt def build_header(self): self._dsfstring = self._dsfstring + "PROPERTY sim/west " + str(int(self._longitude)) + "\n" self._dsfstring = self._dsfstring + "PROPERTY sim/east " + str(int(self._longitude + 1)) + "\n" self._dsfstring = self._dsfstring + "PROPERTY sim/south " + str(int(self._latitude)) + "\n" self._dsfstring = self._dsfstring + "PROPERTY sim/north " + str(int(self._latitude+1)) + "\n" self._dsfstring = self._dsfstring + "PROPERTY sim/planet earth\n" self._dsfstring = self._dsfstring + "PROPERTY sim/creation_agent Orthographic\n" mstr_msg("xp_dsfgen", "Header built") # Let's now walk through the single polygon definitions def build_polygon_defs(self): mstr_msg("xp_dsfgen", "Walking through forest polygons") # Pick the kind of forest we work with for f in range(1, self._amtdg+1): #rws = self._tiledb.perform_query("SELECT * FROM xp_scenery WHERE datagroup="+str(f)+";") frs = self.pick_forest_type() self._dsfstring = self._dsfstring + "POLYGON_DEF lib/g8/"+frs+"\n" # Put in the data curpoly=0 for f in range(1, self._amtdg+1): rws = self._tiledb.perform_query("SELECT * FROM xpscenery WHERE datagroup="+str(f)+";") self._dsfstring = self._dsfstring + "BEGIN_POLYGON "+str(curpoly)+" 255 2\n" self._dsfstring = self._dsfstring + "BEGIN_WINDING\n" for r in rws: self._dsfstring = self._dsfstring + "POLYGON_POINT " + str(r[2]) + " " + str(r[1]) + "\n" self._dsfstring = self._dsfstring + "END_WINDING\n" self._dsfstring = self._dsfstring + "END_POLYGON\n" curpoly = curpoly + 1 mstr_msg("xp_dsfgen", "Forest definitions complete") # Write the text file def write_dsf_txt(self): with open(mstr_datafolder + "_cache/dsf.txt", 'w') as textfile: textfile.write(self._dsfstring) # Convert the DSF into actual, usable data for X-Plane def convert_dsf_text(self): # Find separator sep = "" if os.name == "nt": sep = "\\" if os.name == "posix": sep = "/" datafolder = mstr_datafolder.replace("/", sep) # First, create the Earth nav data folder should it not exist end_base = datafolder + "Tiles" + sep + str(self._latitude) + "_" + str(self._longitude) + sep + "Earth nav data" # Create the appropriate rounded folder end_round = self.xplane_latlng_folder(self.find_earthnavdata_number()) if not os.path.exists(end_base): os.makedirs(end_base) if not os.path.exists(end_base + sep + end_round): os.makedirs(end_base + sep + end_round) # Get the file name for the DSF end_latlng = self.xplane_latlng_folder([self._latitude, self._longitude]) # Perform conversion os.system(mstr_xp_dsftool + " --text2dsf " + datafolder + "_cache" + sep + "dsf.txt \"" + end_base + sep + end_round + sep + end_latlng + ".dsf\"") # Find the next "by-ten" numbers for the current latitude and longitude def find_earthnavdata_number(self): earthnavdata = [] lat = abs(int(self._latitude / 10) * 10) lng = abs(int(self._longitude / 10) * 10) earthnavdata.append(lat) earthnavdata.append(lng) return earthnavdata # Construct an X-Plane compatible folder name for latitude and longitude def xplane_latlng_folder(self, numbers): fstr = "" if numbers[0] >= 0: fstr = "+" if numbers[0] < 0: fstr = "-" if abs(numbers[0]) < 10: fstr = fstr + "0" + str(numbers[0]) if abs(numbers[0]) >= 10 and numbers[0] <= 90: fstr = fstr + str(numbers[0]) if numbers[1] >= 0: fstr = fstr + "+" if numbers[1] < 0: fstr = fstr + "-" if abs(numbers[1]) < 10: fstr = fstr + "00" + str(numbers[1]) if abs(numbers[1]) >= 10 and numbers[0] <= 99: fstr = fstr + "0" + str(numbers[1]) if abs(numbers[1]) >= 100 : fstr = fstr + str(numbers[1]) return fstr # Pick some forest type from X-Plane def pick_forest_type(self): ftype = 0 # Where forests live in X-Plane. rootfolder = mstr_xp_folder + "Resources/default scenery/1000 forests/" forests = glob.glob(rootfolder + "mixed_*.for") ftype = randrange(1, len(forests)-1) fstring = forests[ftype] fstring = fstring.replace(mstr_xp_folder + "Resources/default scenery/1000 forests\\", "") return fstring dsf = mstr_xp_dsfgen(51, 7, 1) dsf.build_polygon_defs() dsf.write_dsf_txt() dsf.convert_dsf_text()