"""One-off (2026-10-19): write the values read from the Ungok P3 drawing (see prompt log Task_도면도형직접판독시험) into data/운곡교P3/params.json. params.json only; expected.json is left alone (independent evidence, P7). Backs up params/expected/confirm first. Prints what changed and what was NOT read. usage: python tools/apply_p3_read_values.py [--dry]""" import copy import json import shutil import sys import time from pathlib import Path APP = Path(__file__).resolve().parents[1] sys.path.insert(0, str(APP / "web")) sys.path.insert(0, str(APP)) import store # noqa: E402 from tools import infer_footing_rebar as inf # noqa: E402 p3 = store.Pier("운곡교P3") P = p3.load("params") Q = copy.deepcopy(P) P1 = json.loads((APP / "data" / "운곡교P1" / "params.json").read_text(encoding="utf-8")) SH = -1909 # coping heights P1 -> P3 (D1 EL labels) changes = [] def put(obj, path, val, why): keys = path.split(".") x = obj for k in keys[:-1]: x = x[int(k)] if isinstance(x, list) else x[k] last = int(keys[-1]) if isinstance(x, list) else keys[-1] old = x[last] if old != val: x[last] = val changes.append((path, old if not isinstance(old, (list, dict)) else f"{type(old).__name__}[{len(old)}]", val if not isinstance(val, (list, dict)) else f"{type(val).__name__}[{len(val)}]", why)) # ---- footing, piles, column (D1 dimension texts, cross-checked by section-view line lengths and the pile layout sums) put(Q, "footing.size_y", 8800.0, "D1 8.800, 800+4@1800+800") put(Q, "footing.z_bottom", 25175, "D1 EL. 25.175") put(Q, "lean_concrete.size_y", 9000.0, "footing + 200 (section lines 9000)") put(Q, "lean_concrete.z_bottom", 25075, "footing bottom - 100") put(Q, "lean_concrete.z_top", 25175, "= footing bottom") put(Q, "piles.pitch_y", 1800.0, "D1 4@1.800=7.200") put(Q, "piles.length", 25300, "D1 L=25.3M") put(Q, "column.height", 11127, "D1 11.127 = 38502 - (25175 + 2200)") # ---- coping (geometry of D1 front view, tools/extract_coping_outline.py) steps = [(-6000, -3764, 41502), (-3764, -1263, 41576), (-1263, 1237, 41650), (1237, 3738, 41724), (3738, 6000, 41798)] for i, (a, b, z) in enumerate(steps): put(Q, f"coping.top_steps.{i}.x0", float(a), "D1 coping top outline") put(Q, f"coping.top_steps.{i}.x1", float(b), "D1 coping top outline") put(Q, f"coping.top_steps.{i}.z", z, "D1 coping top outline + EL. 41.798") put(Q, "coping.z_bottom_flat", 38502, "D1 coping soffit flat") # ---- coping rebar (D1 front view rebar lines) for t, z in (("1", 41402), ("2", 41302), ("3", 41202)): put(Q, f"coping_rebar.top.tiers.{t}.z", z, "D1 rebar lines") put(Q, "coping_rebar.bottom.z_flat", 38602, "soffit flat + 100 (as P1)") put(Q, "coping_rebar.loops.levels", [v + SH for v in P1["coping_rebar"]["loops"]["levels"]], "P1 levels shifted by the coping drop; lines at 40102..40852 seen") put(Q, "coping_rebar.c15.z", 41698, "D1 rebar line") put(Q, "coping_rebar.c15.x0", 3838, "D1 rebar line; schedule C15 a 2.062 = 5900 - 3838") put(Q, "coping_rebar.c16.z", 41550, "D1 rebar line") put(Q, "coping_rebar.c16.x0", -1163, "schedule C16 a 5.251 = 4088 + 1163") put(Q, "coping_rebar.c16.x1", 4088, "D1 rebar line") # ---- bearings (D1 plan view LWPOLYLINEs, datum = coping plan centre as in P1) bs = Q["bearing_seats"] pitch = 2500.5 put(Q, "bearing_seats.pitch_x", pitch, "plan pedestals 2487.4 -> 4987.9; text 3@2.501=7.502") put(Q, "bearing_seats.pedestal_girder5.front_half", [[4369.3, -1280.7], [4408.7, -31.3], [5608.1, -69.1], [5568.7, -1318.5]], "D1 plan outline") put(Q, "bearing_seats.pedestal_girder5.rear_half", [[4408.7, -31.3], [4448.0, 1218.1], [5647.4, 1180.3], [5608.1, -69.1]], "D1 plan outline") put(Q, "bearing_seats.pedestal_girder5.rotation_deg", 1.81, "outline angle 178.19") put(Q, "bearing_seats.pad_rows.front.centre_rel_girder5", [4987.9, -699.9], "D1 plan pad polyline") put(Q, "bearing_seats.pad_rows.front.rotation_deg", 1.81, "pad polyline angle") put(Q, "bearing_seats.pad_rows.rear.centre_rel_girder5", [5014.1, 599.6], "D1 plan pad polyline") put(Q, "bearing_seats.pad_rows.rear.rotation_deg", 0.5, "pad polyline angle") for i, b in enumerate(bs["bearings"]): g = b["girder_line"] front = b["row"] == "front" x = (4987.9 if front else 5014.1) - (5 - g) * pitch put(Q, f"bearing_seats.bearings.{i}.centre", [round(x, 1), -699.9 if front else 599.6], "g4/g5 drawn, g1-g3 by pitch") put(Q, f"bearing_seats.bearings.{i}.rotation_deg", 1.81 if front else 0.5, "pad angle") # ---- footing rebar (rules of tools/infer_footing_rebar.py + D1 rebar points) r = inf.infer(10350, 8800) put(Q, "footing_rebar.a_x", r["a_x"], "footing - 200") put(Q, "footing_rebar.a_y", r["a_y"], "footing - 200") for k in ("bottom_Y1", "bottom_X2", "bottom_Y3", "bottom_X4", "top_Y", "top_X"): put(Q, f"footing_rebar.layers.{k}.pos", [float(v) for v in r[k]], "layer rule; counts equal the schedule") mid_x = {"550.0": [-2750, -1750, -750, 750, 1750, 2750], "950.0": [-3750, -3250, -2250, -1250, -250, 250, 1250, 2250, 3250, 3750]} mid_x["1350.0"], mid_x["1750.0"] = mid_x["550.0"], mid_x["950.0"] mid_y = {"550.0": [-3875, -2875, -1875, 1875, 2875, 3875], "950.0": [-4375, -3375, -2375, -1375, -375, 375, 1375, 2375, 3375, 4375]} mid_y["1350.0"], mid_y["1750.0"] = mid_y["550.0"], mid_y["950.0"] put(Q, "footing_rebar.layers.mid_X.levels", {k: [float(v) for v in vs] for k, vs in mid_x.items()}, "D1 section dots (B11), 32 bars") put(Q, "footing_rebar.layers.mid_Y.levels", {k: [float(v) for v in vs] for k, vs in mid_y.items()}, "D1 front dots (B12), 32 bars (schedule 38, as P1: drawn 28 / schedule 34)") put(Q, "footing_rebar.b9.grid_x", [-4625 + 250 * i for i in range(38)], "38 x 33 grid, checkerboard = 627 = schedule") put(Q, "footing_rebar.b9.grid_y", [-4000 + 250 * i for i in range(33)], "38 x 33 grid") put(Q, "footing_rebar.b9.count", 627, "schedule 627 = 1351.185 / 2.155") put(Q, "footing_rebar.b10.size_y", 8644.0, "schedule B10 b 8.644") # ---- column rebar (schedule + D1 hoop dots) put(Q, "column_rebar.main_bars.p1.hook_leg_z", 25475, "footing bottom + 300 (as P1)") put(Q, "column_rebar.main_bars.p1.straight_from", 25815, "+ bend R340") put(Q, "column_rebar.main_bars.p1.straight_len", 15337, "schedule P1 A 15.337") put(Q, "column_rebar.main_bars.p2.z0", 25475, "as above") put(Q, "column_rebar.main_bars.p2.length", 15677, "schedule P2 15.677") levels = [26355 + 120 * i for i in range(31)] levels += [levels[-1] + 300 * (i + 1) for i in range(33)] put(Q, "column_rebar.hoops.levels", levels, "first level 26355 seen in D1 dots; 31 @120 + 33 @300 (schedule 9+22+33)") put(Q, "column_rebar.hoops.marks", ["P4"] * 9 + ["P5"] * 22 + ["P3"] * 33, "schedule counts") put(Q, "column_rebar.hoops.radius", 902, "schedule P4/P5 R 902 (2*pi*902 = 5667)") put(Q, "column_rebar.ties.levels", [26355 + 1800 * i for i in range(8)], "ASSUMED start; chain 7@1.800 = 8 levels (schedule P6 32 = 8 x 4)") print(f"{len(changes)} changes") for c in changes: print(f" {c[0]:58s} {str(c[1])[:22]:>22} -> {str(c[2])[:28]:<28} | {c[3]}") print("NOT read / not changed: coping_rebar c14 points, stirrups, bottom curve, top_right, x_c9..x_c11; schedule tables; column ties start/end (assumed); main-bar bottom z (assumed)") if "--dry" in sys.argv: sys.exit(0) bk = p3.dir / "backup" / f"before_read_values_{time.strftime('%Y%m%d_%H%M%S')}" bk.mkdir(parents=True) for f in ("params.json", "expected.json", "confirm.json"): if (p3.dir / f).exists(): shutil.copy2(p3.dir / f, bk / f) p3.save("params", Q) print("saved; backup:", bk)