"""Read footing rebar B1-B12 and append `footing_rebar` to params.json (existing keys unchanged). Sources: D3 schedule (판독/3_survey.json), D1 정면도/단면도 rebar dots and lines (판독/front.json, side.json), D1·D2 dimension chains. Heights are z above footing bottom (EL 26.208). Values tagged [hitl] are pending user approval (설계서 v0.1.05 §6). """ import json from collections import defaultdict from pathlib import Path HERE = Path(__file__).resolve().parent FB = 26208 def dots(name, cx): d = json.loads((HERE / "판독" / f"{name}.json").read_text(encoding="utf-8")) lv = defaultdict(list) for r in d: if r["type"] == "CIRCLE" and r["layer"].startswith("CS-RBAR") and 8115 < r["pts"][0][1] < 10316 \ and abs(r["r"] - 27) < 1: lv[round(r["pts"][0][1] - 8115.6, 1)].append(round(r["pts"][0][0] - cx, 1)) return {z: sorted(v) for z, v in lv.items()} def mirror(xs, edge=None): """Half-view positions (x >= 0) -> full symmetric list; drop column/B10 dots beyond `edge`.""" xs = [x for x in xs if edge is None or x <= edge] return sorted({-x for x in xs} | set(xs)) def main(): sched_rows = {} texts = json.loads((HERE / "판독" / "3_survey.json").read_text(encoding="utf-8"))["texts"] for m in ["B%d" % i for i in range(1, 13)]: for t0 in [t for t in texts if t["text"] == m and t["y"] > 15000]: row = sorted([t for t in texts if abs(t["y"] - t0["y"]) < 40 and t0["x"] - 50 <= t["x"] < t0["x"] + 20000], key=lambda a: a["x"]) sched_rows[m] = [t["text"] for t in row] fd, sd = dots("front", 12159.4), dots("side", 30133.6) # front dots = Y-bars (x), side dots = X-bars (y) edge_x, edge_y = 4575, 3800 layers = { "bottom_Y1": dict(marks="B2/B4 alternate", z=122.0, pos=mirror(fd[122.0], edge_x), axis="Y"), "bottom_X2": dict(marks="B6/B8 alternate", z=178.0, pos=mirror(sd[178.0], edge_y), axis="X"), "bottom_Y3": dict(marks="B3", z=227.5, pos=mirror(fd[227.5], edge_x), axis="Y"), "bottom_X4": dict(marks="B7", z=277.0, pos=mirror(sd[277.0], edge_y), axis="X"), "top_Y": dict(marks="B1", z=2073.0, pos=mirror(fd[2073.0], edge_x), axis="Y"), "top_X": dict(marks="B5", z=2127.0, pos=mirror(sd[2127.0], edge_y), axis="X"), "mid_X": dict(marks="B11", axis="X", levels={z: mirror(sd[z], edge_y - 1) for z in (550.0, 950.0, 1350.0, 1750.0)}), "mid_Y": dict(marks="B12", axis="Y", levels={z: mirror(fd[z], edge_x - 1) for z in (550.0, 950.0, 1350.0, 1750.0)}), } b9_x = [-4125 + 250 * i for i in range(34)] # D1 정면도 '450','33@250=8.250','450' (중앙) b9_y = [-3500 + 250 * j for j in range(29)] # D1 단면도 '300','28@250=7.000','300' (중앙) b9 = [(x, y) for i, x in enumerate(b9_x) for j, y in enumerate(b9_y) if (i + j) % 2 == 0] fr = dict( _note="Footing rebar B1-B12; z above footing bottom EL 26.208; X/Y as model axes", schedule=sched_rows, layers=layers, b9=dict(grid_x=b9_x, grid_y=b9_y, checker_parity=0, count=len(b9), z0=150 - 22.5, a=1995, b=96, c=64, src="D1 EREC vertical lines z 150~2100 @250 both views; count = 1062.415/2.155 = 493 [역산]; " "checkerboard parity [추론, hitl]"), b10=dict(levels=[150 + 200 * k for k in range(1, 10)], size_x=9198, size_y=7644, src="D1 정면도 우측 '150','9@200=1.800'; dots x=4593/y=3818; D3 B10 a 9.198 b 7.644"), legs=dict(B2=dict(leg=1950, dir="up", at="Y ends"), B6=dict(leg=1950, dir="up", at="X ends"), B5=dict(leg=200, dir="down"), B7=dict(leg=200, dir="up"), B1=dict(hook=200, dir="down"), B3=dict(hook=200, dir="up"), B11=dict(leg=100, dir="down [hitl]"), B12=dict(hook=100, dir="down [hitl]")), counts_check={k: (len(v["pos"]) if "pos" in v else sum(len(p) for p in v["levels"].values())) for k, v in layers.items()}, ) pp = HERE / "params.json" params = json.loads(pp.read_text(encoding="utf-8")) params["footing_rebar"] = fr pp.write_text(json.dumps(params, ensure_ascii=False, indent=2), encoding="utf-8") print(json.dumps(dict(counts=fr["counts_check"], b9=len(b9), schedule=sched_rows), ensure_ascii=False)) if __name__ == "__main__": main()