orthographic/xp_dsfgen.py

158 lines
6.0 KiB
Python

# -------------------------------------------------------------------
# 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()