Skip to content

Commit e0bb35b

Browse files
Frank Paynterlordfolken
authored andcommitted
Changes to allow *.CUP file parsing for geobounding
1 parent cc7b6cd commit e0bb35b

File tree

6 files changed

+61
-25
lines changed

6 files changed

+61
-25
lines changed

lib/xcsoar/mapgen/server/server.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,25 @@ def index(self, **params):
9191
waypoint_file.filename
9292
)
9393
)
94+
95+
if not filename.endswith(".dat") and not filename.endswith(".cup"):
96+
raise RuntimeError(
97+
"Waypoint file {} has an unsupported format.".format(
98+
waypoint_file.filename
99+
)
100+
)
101+
94102
desc.bounds = parse_waypoint_file(
95103
waypoint_file.filename, waypoint_file.file
96104
).get_bounds()
97105
desc.waypoint_file = (
98106
"waypoints.cup" if filename.endswith(".cup") else "waypoints.dat"
99107
)
108+
109+
return view.render(
110+
error=f"left: {desc.bounds.left:.3f}, right: {desc.bounds.right:.3f}, top: {desc.bounds.top:.3f}, bot {desc.bounds.bottom:.3f}"
111+
) | HTMLFormFiller(data=params)
112+
100113
except:
101114
return view.render(
102115
error="Unsupported waypoint file " + waypoint_file.filename
@@ -134,6 +147,7 @@ def index(self, **params):
134147

135148
if desc.waypoint_file:
136149
waypoint_file.file.seek(0)
150+
137151
f = open(job.file_path(desc.waypoint_file), "w")
138152
try:
139153
shutil.copyfileobj(fsrc=waypoint_file.file, fdst=f, length=1024 * 64)

lib/xcsoar/mapgen/server/view.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def render(*args, **kwargs):
4141
template = loader.load(args[0])
4242
else:
4343
template = cherrypy.thread_data.template
44+
4445
ctxt = Context(url=cherrypy.url)
4546
ctxt.push(kwargs)
4647
return template.generate(ctxt)

lib/xcsoar/mapgen/waypoints/list.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ def get_bounds(self, offset_distance=15.0):
3939
rc.bottom = min(rc.bottom, wp.lat)
4040

4141
rc.expand(offset_distance)
42+
4243
return rc

lib/xcsoar/mapgen/waypoints/parser.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@
33
from xcsoar.mapgen.waypoints.winpilot_reader import parse_winpilot_waypoints
44

55

6-
def parse_waypoint_file(filename, file=None):
7-
if not file:
8-
file = open(filename, "r")
6+
def parse_waypoint_file(filename, file):
7+
lines = file.readlines()
98

109
if filename.lower().endswith(".xcw") or filename.lower().endswith(".dat"):
11-
return parse_winpilot_waypoints(file)
10+
return parse_winpilot_waypoints(lines)
1211
elif filename.lower().endswith(".cup"):
13-
return parse_seeyou_waypoints(file)
12+
return parse_seeyou_waypoints(lines) # 241207 gfp bugfix:
1413
else:
1514
raise RuntimeError(
1615
"Waypoint file {} has an unsupported format.".format(filename)

lib/xcsoar/mapgen/waypoints/seeyou_reader.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,34 @@ def __parse_length(str):
7676
def parse_seeyou_waypoints(lines, bounds=None):
7777
waypoint_list = WaypointList()
7878

79-
first = True
80-
for line in lines:
81-
if first:
82-
first = False
83-
continue
84-
85-
line = line.strip()
86-
if line == "name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc":
87-
continue
88-
79+
header = "name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc"
80+
81+
wpnum = 0
82+
for byteline in lines:
83+
wpnum = wpnum + 1
84+
try:
85+
line = byteline.decode("UTF-8")
86+
except UnicodeDecodeError as e:
87+
raise RuntimeError(
88+
f"Failed to decode line {wpnum} as UTF-8: {e}. "
89+
f"Please check the waypoint file encoding and fix any corrupted data."
90+
)
91+
92+
# check for blank lines or comments
8993
if line == "" or line.startswith("*"):
9094
continue
9195

96+
if header in line:
97+
continue # skip to next line (first waypoint line)
98+
9299
if line == "-----Related Tasks-----":
93100
break
94101

95102
fields = []
96-
line = __CSVLine(line)
97-
while line.has_next():
98-
fields.append(next(line))
103+
CSVline = __CSVLine(line)
104+
105+
while CSVline.has_next():
106+
fields.append(next(CSVline))
99107

100108
if len(fields) < 6:
101109
continue

lib/xcsoar/mapgen/waypoints/winpilot_reader.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,33 @@ def __parse_altitude(str):
1010
return int(str) * 0.3048
1111
else:
1212
str = str.rstrip("m")
13-
return int(str)
13+
float_alt = float(str)
14+
int_alt = int(float_alt)
1415

16+
return int(int_alt)
1517

18+
19+
# Winpilot .DAT file lat/lon formats
20+
# Latitude, Longitude: in one of the following formats (ss=seconds, dd = decimals):
21+
# dd:mm:ss (for example: 36:15:20N)
22+
# dd:mm.d (for example: 36:15.3N)
23+
# dd:mm.dd (for example: 36:15.33N)
24+
# dd:mm.ddd (for example: 36:15.333N)
1625
def __parse_coordinate(str):
26+
1727
str = str.lower()
1828
negative = str.endswith("s") or str.endswith("w")
1929
str = str.rstrip("sw") if negative else str.rstrip("ne")
2030

21-
str = str.split(":")
22-
if len(str) < 2:
31+
strsplit = str.split(":")
32+
if len(strsplit) < 2:
2333
return None
2434

25-
if len(str) == 2:
35+
if len(strsplit) == 2:
2636
# degrees + minutes / 60
27-
a = int(str[0]) + float(str[1]) / 60
37+
a = int(strsplit[0]) + float(strsplit[1]) / 60
2838

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

@@ -37,8 +47,11 @@ def __parse_coordinate(str):
3747

3848
def parse_winpilot_waypoints(lines):
3949
waypoint_list = WaypointList()
50+
wpnum = 0
51+
for byteline in lines:
52+
wpnum += 1
4053

41-
for line in lines:
54+
line = byteline.decode("UTF-8")
4255
line = line.strip()
4356
if line == "" or line.startswith("*"):
4457
continue

0 commit comments

Comments
 (0)