#!/usr/bin/env python3 """Task 3 (user-confirmed reading): ground-level and design-grade values per 20 m station from sheet 02-002 (당진방향). Confirmed by the user (2026-10-21): decimal texts in CR-TABL-TEX2 are 지반고 (GL), sheet 002 values used; the ruler 740.00..980.00 is chainage 4+740..4+980, and 0.00 is 5+000 (ruler continues in 20 m steps). Method: ruler texts give anchors (chainage = 4000+v for 740..980; 5000+v after 0.00). Each decimal text is projected onto the ruler axis; its station is the nearest anchor. Two decimal series appear at each station (|across| ~ 17-21 and ~ 32-39 m); the series names are NOT assigned here (HITL). Checks are reported, not forced.""" import csv import math import re import sys import ezdxf SRC, OUT = sys.argv[1], sys.argv[2] msp = ezdxf.readfile(SRC).modelspace() texts = [(e.dxf.insert.x, e.dxf.insert.y, e.dxf.text.strip()) for e in msp.query("TEXT") if e.dxf.layer == "CR-TABL-TEX2"] ruler = {} for x, y, s in texts: if re.fullmatch(r"\d{1,3}\.00", s): ruler[int(s.split(".")[0])] = (x, y) anchors = {} for v in range(740, 1000, 20): if v in ruler: anchors[4000 + v] = ruler[v] for v in range(0, 1000, 20): if v in ruler: anchors[5000 + v] = ruler[v] else: break stas = sorted(anchors) print("anchors:", len(stas), "range", stas[0], "..", stas[-1]) gaps = [(stas[i + 1] - stas[i], round(math.dist(anchors[stas[i]], anchors[stas[i + 1]]), 2)) for i in range(len(stas) - 1)] print("consecutive (dSTA, chord m):", gaps) A0, A1 = anchors[stas[0]], anchors[stas[-1]] L = math.dist(A0, A1) u = ((A1[0] - A0[0]) / L, (A1[1] - A0[1]) / L) v_ = (-u[1], u[0]) rows = [] for x, y, s in texts: if not re.fullmatch(r"\d{1,3}\.\d{3}", s): continue dx, dy = x - A0[0], y - A0[1] along = dx * u[0] + dy * u[1] across = dx * v_[0] + dy * v_[1] if not (-5.0 <= along <= L + 5.0 and abs(across) < 60): continue # outside the ruler band (table noise) sta_est = stas[0] + along * (stas[-1] - stas[0]) / L near = min(stas, key=lambda k: abs(k - sta_est)) rows.append((near, round(sta_est, 1), round(across, 2), float(s), round(x, 2), round(y, 2))) with open(OUT, "w", newline="", encoding="utf-8") as fh: w = csv.writer(fh) w.writerow(["station_anchor", "est_station", "across_m", "value", "x", "y"]) w.writerows(sorted(rows)) per = {} for near, est, acr, val, _, _ in rows: per.setdefault(near, []).append((acr, val)) for k in sorted(per): print(f"STA {k}: " + " ".join(f"[{a:+.1f}m {val:.3f}]" for a, val in sorted(per[k])))