158 lines
6.0 KiB
Python
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() |