Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XCSoar (.CUP) and Winpilot (.DAT) file processing now works #90

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ jobs
bin/shptree
bin/gdalwarp
bin/ogr2ogr
Slovenia3.cup
Slovenia3.dat
825 changes: 825 additions & 0 deletions Slovenia3.cup
lordfolken marked this conversation as resolved.
Show resolved Hide resolved

Large diffs are not rendered by default.

824 changes: 824 additions & 0 deletions Slovenia3.dat

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions lib/xcsoar/mapgen/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def index(self, **params):
return view.render()

name = params["name"].strip()

if name == "":
return view.render(error="No map name given!") | HTMLFormFiller(data=params)

Expand All @@ -75,6 +76,7 @@ def index(self, **params):

selection = params["selection"]
waypoint_file = params["waypoint_file"]

if selection in ["waypoint", "waypoint_bounds"]:
if not waypoint_file.file or not waypoint_file.filename:
return view.render(error="No waypoint file uploaded.") | HTMLFormFiller(
Expand All @@ -83,6 +85,7 @@ def index(self, **params):

try:
filename = waypoint_file.filename.lower()

if not filename.endswith(".dat") and (
filename.endswith(".dat") or not filename.endswith(".cup")
):
Expand All @@ -91,12 +94,26 @@ def index(self, **params):
waypoint_file.filename
)
)

# 241212 better way to write this boolean expression (filename already forced to lowercase)
if not filename.endswith(".dat") and not filename.endswith(".cup"):
raise RuntimeError(
"Waypoint file {} has an unsupported format.".format(
waypoint_file.filename
)
)

desc.bounds = parse_waypoint_file(
waypoint_file.filename, waypoint_file.file
).get_bounds()
desc.waypoint_file = (
"waypoints.cup" if filename.endswith(".cup") else "waypoints.dat"
)

return view.render(
error=f"left: {desc.bounds.left:.3f}, right: {desc.bounds.right:.3f}, top: {desc.bounds.top:.3f}, bot {desc.bounds.bottom:.3f}"
) | HTMLFormFiller(data=params)

except:
return view.render(
error="Unsupported waypoint file " + waypoint_file.filename
Expand Down Expand Up @@ -134,6 +151,7 @@ def index(self, **params):

if desc.waypoint_file:
waypoint_file.file.seek(0)

f = open(job.file_path(desc.waypoint_file), "w")
try:
shutil.copyfileobj(fsrc=waypoint_file.file, fdst=f, length=1024 * 64)
Expand Down
1 change: 1 addition & 0 deletions lib/xcsoar/mapgen/server/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def render(*args, **kwargs):
template = loader.load(args[0])
else:
template = cherrypy.thread_data.template

ctxt = Context(url=cherrypy.url)
ctxt.push(kwargs)
return template.generate(ctxt)
1 change: 1 addition & 0 deletions lib/xcsoar/mapgen/waypoints/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ def get_bounds(self, offset_distance=15.0):
rc.bottom = min(rc.bottom, wp.lat)

rc.expand(offset_distance)

return rc
7 changes: 3 additions & 4 deletions lib/xcsoar/mapgen/waypoints/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@


def parse_waypoint_file(filename, file=None):
if not file:
file = open(filename, "r")
lines = file.readlines()

if filename.lower().endswith(".xcw") or filename.lower().endswith(".dat"):
return parse_winpilot_waypoints(file)
return parse_winpilot_waypoints(lines)
elif filename.lower().endswith(".cup"):
return parse_seeyou_waypoints(file)
return parse_seeyou_waypoints(lines) # 241207 gfp bugfix:
else:
raise RuntimeError(
"Waypoint file {} has an unsupported format.".format(filename)
Expand Down
24 changes: 13 additions & 11 deletions lib/xcsoar/mapgen/waypoints/seeyou_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,26 +76,28 @@ def __parse_length(str):
def parse_seeyou_waypoints(lines, bounds=None):
waypoint_list = WaypointList()

first = True
for line in lines:
if first:
first = False
continue
header = "name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc"
lordfolken marked this conversation as resolved.
Show resolved Hide resolved

line = line.strip()
if line == "name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc":
continue
wpnum = 0
for byteline in lines:
wpnum = wpnum + 1
line = byteline.decode("UTF-8")

# check for blank lines or comments
if line == "" or line.startswith("*"):
continue

if header in line:
continue # skip to next line (first waypoint line)

if line == "-----Related Tasks-----":
break

fields = []
line = __CSVLine(line)
while line.has_next():
fields.append(next(line))
CSVline = __CSVLine(line)

while CSVline.has_next():
fields.append(next(CSVline))

if len(fields) < 6:
continue
Expand Down
29 changes: 22 additions & 7 deletions lib/xcsoar/mapgen/waypoints/winpilot_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,50 @@ def __parse_altitude(str):
return int(str) * 0.3048
else:
str = str.rstrip("m")
return int(str)
float_alt = float(str)
int_alt = int(float_alt)

return int(int_alt)


# Winpilot .DAT file lat/lon formats
# Latitude, Longitude: in one of the following formats (ss=seconds, dd = decimals):
# dd:mm:ss (for example: 36:15:20N)
# dd:mm.d (for example: 36:15.3N)
# dd:mm.dd (for example: 36:15.33N)
# dd:mm.ddd (for example: 36:15.333N)
def __parse_coordinate(str):

str = str.lower()
negative = str.endswith("s") or str.endswith("w")
str = str.rstrip("sw") if negative else str.rstrip("ne")

str = str.split(":")
if len(str) < 2:
strsplit = str.split(":")
if len(strsplit) < 2:
return None

if len(str) == 2:
if len(strsplit) == 2:
# degrees + minutes / 60
a = int(str[0]) + float(str[1]) / 60
a = int(strsplit[0]) + float(strsplit[1]) / 60

if len(str) == 3:
if len(strsplit) == 3:
# degrees + minutes / 60 + seconds / 3600
a = int(str[0]) + float(str[1]) / 60 + float(str[2]) / 3600

if negative:
a *= -1

return a


def parse_winpilot_waypoints(lines):

waypoint_list = WaypointList()
wpnum = 0
for byteline in lines:
wpnum += 1

for line in lines:
line = byteline.decode("UTF-8")
line = line.strip()
if line == "" or line.startswith("*"):
continue
Expand Down