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
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.

26 changes: 26 additions & 0 deletions lib/xcsoar/mapgen/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
from xcsoar.mapgen.georect import GeoRect
from xcsoar.mapgen.waypoints.parser import parse_waypoint_file

cherrypy.config.update(
{
"log.screen": True, # Log to stdout
"log.error_file": "error.log", # Log errors to a file
"log.access_file": "access.log", # Log access to a file
}
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally this runs in a container. The Filesystem is usually readonly. Please remove this configuration.


class Server(object):
def __init__(self, dir_jobs):
Expand Down Expand Up @@ -62,6 +70,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 +84,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 +93,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 +102,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 +159,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)
2 changes: 1 addition & 1 deletion lib/xcsoar/mapgen/server/views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<div id="map"/>
<em class="note">Draw the map bounds rectangle by clicking in the map.</em>
<hr/>
<label class="left" for="left">Minimum Longitude:</label><input id="left" type="text" name="left"/><br/>
<label class="left" for="left">Minimum Longitude:</label><input id="left" type="text" name="left" value="43"/><br/>
lordfolken marked this conversation as resolved.
Show resolved Hide resolved
<label class="left" for="right">Maximum Longitude:</label><input id="right" type="text" name="right"/><br/>
<label class="left" for="bottom">Minimum Latitude:</label><input id="bottom" type="text" name="bottom"/><br/>
<label class="left" for="top">Maximum Latitude:</label><input id="top" type="text" name="top"/><br/>
Expand Down
4 changes: 4 additions & 0 deletions lib/xcsoar/mapgen/waypoints/list.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from xcsoar.mapgen.waypoints.waypoint import Waypoint
from xcsoar.mapgen.georect import GeoRect
import cherrypy


class WaypointList:
Expand Down Expand Up @@ -33,10 +34,13 @@ def extend(self, wp_list):
def get_bounds(self, offset_distance=15.0):
rc = GeoRect(180, -180, -90, 90)
for wp in self.__list:
# cherrypy.log(f'In list.py: {wp.name}, lat: {wp.lat:.3f}, lon: {wp.lon:.3f}')
lordfolken marked this conversation as resolved.
Show resolved Hide resolved
rc.left = min(rc.left, wp.lon)
rc.right = max(rc.right, wp.lon)
rc.top = max(rc.top, wp.lat)
rc.bottom = min(rc.bottom, wp.lat)

rc.expand(offset_distance)
# cherrypy.log(f'In list.py - final rc: left {rc.left:.3f}, right: {rc.right:.3f}, top: {rc.top:.3f}, bot {rc.bottom:.3f}')

lordfolken marked this conversation as resolved.
Show resolved Hide resolved
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
26 changes: 15 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 Expand Up @@ -133,3 +135,5 @@ def parse_seeyou_waypoints(lines, bounds=None):
waypoint_list.append(wp)

return waypoint_list

return waypoint_list
lordfolken marked this conversation as resolved.
Show resolved Hide resolved
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