Skip to content

Commit

Permalink
sync with asperge repo
Browse files Browse the repository at this point in the history
  • Loading branch information
speleo3 committed Jun 2, 2024
1 parent bfbf178 commit 7c5ee1b
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 58 deletions.
102 changes: 67 additions & 35 deletions extensions/sexytopo2svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,41 +121,65 @@ def write_shots(parent: etree.Element, data: dict, bbox: BBox, is_ext: bool):
station["name"]: station["eeDirection"]
for station in data["stations"]
}
for station in data["stations"]:
for leg in station["legs"]:
if not name2pos:
pos = name2pos.setdefault(station["name"], (0, 0, 0))
else:
pos = name2pos[station["name"]]
distxy = leg["distance"] * cos(radians(leg["inclination"]))
distz = leg["distance"] * sin(radians(leg["inclination"]))
distx = distxy * sin(radians(leg["azimuth"]))
disty = distxy * cos(radians(leg["azimuth"]))

if leg["destination"] == STATION_NAME_SPLAY:
ee_dir = station["eeDirection"]
else:
ee_dir = ee_directions[leg["destination"]]

if not is_ext:
posdest = (pos[0] + distx, pos[1] - disty, pos[2] + distz)
elif ee_dir == EE_DIRECTION_RIGHT:
posdest = (pos[0] + distxy, pos[1] - distz, 0)
else:
assert ee_dir == EE_DIRECTION_LEFT
posdest = (pos[0] - distxy, pos[1] - distz, 0)
d_frag = f"M {pos[0]} {pos[1]} L {posdest[0]} {posdest[1]}"
if leg["destination"] != STATION_NAME_SPLAY:
assert leg["destination"] not in name2pos
name2pos[leg["destination"]] = posdest
d_legs.append(d_frag)
elif abs(distz) < distxy:
d_splays.append(d_frag)
else:
d_splays_vertical.append(d_frag)

bbox.add_point(pos[0], pos[1])
bbox.add_point(posdest[0], posdest[1])

postpone = [(station, leg) for station in data["stations"]
for leg in station["legs"]]

def process_leg(station, leg):
pos_is_dest = False
if not name2pos:
pos = name2pos.setdefault(station["name"], (0, 0, 0))
elif station["name"] in name2pos:
pos = name2pos[station["name"]]
elif leg["destination"] in name2pos:
pos = name2pos[leg["destination"]]
pos_is_dest = True
else:
postpone.append((station, leg))
return

distxy = leg["distance"] * cos(radians(leg["inclination"]))
distz = leg["distance"] * sin(radians(leg["inclination"]))
distx = distxy * sin(radians(leg["azimuth"]))
disty = distxy * cos(radians(leg["azimuth"]))

if leg["destination"] == STATION_NAME_SPLAY:
ee_dir = station["eeDirection"]
else:
ee_dir = ee_directions[leg["destination"]]

if not is_ext:
posdest = (pos[0] + distx, pos[1] - disty, pos[2] + distz)
elif ee_dir == EE_DIRECTION_RIGHT:
posdest = (pos[0] + distxy, pos[1] - distz, 0)
else:
assert ee_dir == EE_DIRECTION_LEFT
posdest = (pos[0] - distxy, pos[1] - distz, 0)

if pos_is_dest:
pos, posdest = (
tuple((2 * a - b) for (a, b) in zip(pos, posdest)),
pos,
)

d_frag = f"M {pos[0]} {pos[1]} L {posdest[0]} {posdest[1]}"
if leg["destination"] != STATION_NAME_SPLAY:
assert leg["destination"] not in name2pos
name2pos[leg["destination"]] = posdest
d_legs.append(d_frag)
elif abs(distz) < distxy:
d_splays.append(d_frag)
else:
d_splays_vertical.append(d_frag)

bbox.add_point(pos[0], pos[1])
bbox.add_point(posdest[0], posdest[1])

while postpone:
postpone, postpone_prev = [], postpone

for station, leg in postpone_prev:
process_leg(station, leg)

d = " ".join(d_splays_vertical)
etree.SubElement(
Expand All @@ -179,6 +203,14 @@ def write_shots(parent: etree.Element, data: dict, bbox: BBox, is_ext: bool):
CLARK_INKSCAPE_LABEL: "survey",
})

for name, pos in name2pos.items():
elem_text = etree.SubElement(parent, "text", {
"x": str(pos[0]),
"y": str(pos[1]),
"style": f"font-size:0.5;fill:#933",
})
elem_text.text = name


def main(args=None):
argparser = argparse.ArgumentParser(description=__doc__)
Expand Down
92 changes: 69 additions & 23 deletions extensions/topreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import io
import os
import re
import sys
import struct
import time
Expand Down Expand Up @@ -579,6 +580,17 @@ def dump_svx(top,

skip_trip_date = False

# Grotte Asperge convention: Date in file name
if 'filename' in top:
m = re.search(r"[-_.](23-0\d-\d\d|2[3-5][01]\d\d\d)[-_.]", top['filename'])
if m is None:
m = re.search(r"_(23\.0\d\.\d\d)_", top['filename'])
if m is not None:
yymmdd = m.group(1).replace("-", "").replace(".", "")
file.write(P + f'date 20{yymmdd[0:2]}.{yymmdd[2:4]}.{yymmdd[4:6]}')
file.write(end * 2)
skip_trip_date = True

file.write(P + 'data normal from to tape compass clino')
file.write(end)

Expand Down Expand Up @@ -802,7 +814,7 @@ def process_shot(s, do_splays):
defer.remove(s)
break
else:
print('{} unconnected subsurveys'.format(len(defer)))
print('{} unconnected subsurveys'.format(len(defer)), file=sys.stderr)
break

for s in top['shots']:
Expand Down Expand Up @@ -986,15 +998,18 @@ def write_layer(parent: EtreeElement,
file.write(etree.tostring(root).decode("utf-8"))


# Factor for xvi and th2 scaling
# Scales observed in the wild:
# FACTOR = 1 / 0.0254 # ~39.37 # 1.0 world-inch per px
# FACTOR = 2 / 0.0254 # ~78.74 # 0.5 world-inch per px
# Scales that I prefer (metric):
FACTOR = 100 # 1.0 world-cm per px
FACTOR = 50 # 2.0 world-cm per px


def dump_xvi(top, *, file=sys.stdout):
'''Dump drawing as XVI.
'''
# Default XTherion PocketTopo Import Settings
SCALE = 200
RESOLUTION_DPI = 200
METER_PER_INCH = 0.0254
FACTOR = RESOLUTION_DPI / METER_PER_INCH / SCALE

def pnt2xvi(pnt):
return FACTOR * pnt[KEY_X], -FACTOR * pnt[KEY_Y]

Expand Down Expand Up @@ -1052,7 +1067,7 @@ def process_shot(s, do_splays):
defer.remove(s)
break
else:
print('{} unconnected subsurveys'.format(len(defer)))
print('{} unconnected subsurveys'.format(len(defer)), file=sys.stderr)
break

for s in top['shots']:
Expand All @@ -1078,8 +1093,9 @@ def write_shots_and_stations(top, view="outline"):
stations = write_shots(top, view == 'sideview')

write_stationlabels(stations)
return stations

def write_sketchlines(top, view="outline"):
def write_sketchlines(top, view="outline", frompoints=None):
file.write('set XVIsketchlines {\n')

for poly in top[view]['polys']:
Expand All @@ -1092,8 +1108,17 @@ def write_sketchlines(top, view="outline"):

file.write('}\n')

if frompoints:
write_xsections(frompoints, top[view])

file.write('}\n')

def write_xsections(frompoints, drawing):
for xsec in drawing['xsec']:
pnt = pnt2xvi(xsec[KEY_XSEC_POS])
pnt_stn = pnt2xvi(frompoints[xsec[KEY_XSEC_STN]])
file.write(" {yellow " + f"{pnt_stn[0]} {pnt_stn[1]} {pnt[0]} {pnt[1]}" + "}\n")

def write_grid(top, view="outline"):
min_x, min_y, max_x, max_y = get_bbox(top[view]['polys'])
min_x, min_y = pnt2xvi([min_x, min_y])
Expand All @@ -1111,19 +1136,14 @@ def write_grid_spacing():
file.write('set XVIgrids {1.0 m}\n')

write_grid_spacing()
write_shots_and_stations(top)
write_sketchlines(top)
frompoints = write_shots_and_stations(top)
write_sketchlines(top, frompoints=frompoints)
write_grid(top)


def dump_th2(top, *, file=sys.stdout):
def dump_th2(top, *, file=sys.stdout, with_xvi: bool = False):
'''Dump drawing as TH2.
'''
SCALE = 200
RESOLUTION_DPI = 200
METER_PER_INCH = 0.0254
FACTOR = RESOLUTION_DPI / METER_PER_INCH / SCALE

from th2_output import fstr2 as fstr

def to_th2_space(pnt: tuple[float, float]) -> tuple[float, float]:
Expand Down Expand Up @@ -1179,7 +1199,7 @@ def process_shot(s: dict) -> bool:
defer.remove(s)
break
else:
print('{} unconnected subsurveys'.format(len(defer)))
print('{} unconnected subsurveys'.format(len(defer)), file=sys.stderr)
break

return frompoints
Expand All @@ -1189,13 +1209,34 @@ def write_stationlabels(frompoints):
x, y = to_th2_space(pnt)
out.append(f'point {fstr(x)} {fstr(y)} station -name {key}')

def write_background_xvi(frompoints):
if not with_xvi:
return

if not top.get("filename"):
return

try:
station = next(station for (station, pos) in frompoints.items()
if pos == (0, 0))
except StopIteration:
return

out.insert(1, (
'##XTHERION## xth_me_image_insert {0 1 1.0} {0 %s} "../../data/%s.top.xvi" 0 {}'
% (station, stem)))

def write_shots_and_stations(view="outline"):
stations = write_shots(view == 'sideview')
write_background_xvi(stations)
write_stationlabels(stations)

def write_sketchlines(view="outline"):
if with_xvi:
return

for poly in top[view]['polys']:
out.append(f"line u:{poly[KEY_COLOR]}")
out.append(f"line u:{poly[KEY_COLOR]} -clip off")
for pnt in poly['coord']:
x, y = to_th2_space(pnt)
out.append(f' {fstr(x)} {fstr(y)}')
Expand All @@ -1206,7 +1247,7 @@ def write_grid(view="outline"):
min_x, min_y = to_th2_space((min_x, min_y))
max_x, max_y = to_th2_space((max_x, max_y))
min_y, max_y = sorted([min_y, max_y])
BBOX_PADDING_PX = 10
BBOX_PADDING_PX = FACTOR * 2
out.insert(1, (f"##XTHERION## xth_me_area_adjust"
f" {fstr(min_x - BBOX_PADDING_PX)}"
f" {fstr(min_y - BBOX_PADDING_PX)}"
Expand All @@ -1218,8 +1259,8 @@ def write_grid(view="outline"):

out = [
"encoding utf-8",
"##XTHERION## xth_me_area_zoom_to 50",
f"scrap s_{projection}_{stem} -projection {projection}",
"##XTHERION## xth_me_area_zoom_to 25",
f"scrap s_{projection}_{stem} -projection {projection} -scale [{FACTOR} 1 m]",
]

write_shots_and_stations()
Expand Down Expand Up @@ -1279,7 +1320,7 @@ def main(argv=None):
argparser.add_argument(
"--dump",
help="dump file to stdout",
choices=('json', 'svg', 'svx', 'th', 'th2', 'tro', 'xvi'),
choices=('json', 'svg', 'svx', 'th', 'th2', 'tro', 'xvi', 'th2-xvi'),
)
argparser.add_argument("--view", help="open viewer application", choices=('aven', 'inkscape'))
argparser.add_argument("--surveyname", help="survey name for survex dump", default="")
Expand Down Expand Up @@ -1315,6 +1356,11 @@ def main(argv=None):
dump_xvi(top)
elif args.dump == 'th2':
dump_th2(top)
elif args.dump == 'th2-xvi':
with open(f"{filename}.xvi", "w") as handle:
dump_xvi(top, file=handle)
with open(f"{filename}.th2", "w") as handle:
dump_th2(top, file=handle, with_xvi=True)
elif args.dump == 'tro':
dump_tro(top)
elif not args.view:
Expand Down

0 comments on commit 7c5ee1b

Please sign in to comment.