import json,math,pathlib root=pathlib.Path(__file__).resolve().parents[1] model=json.loads((root/'src/model/block7.json').read_text(encoding='utf8')) parts=model['parts']; assert len(parts)==154 assert len({p['id'] for p in parts})==154 results=[] for s,top,el in [('A',-74271.37855593952,106.675),('B',-91211.37855593952,107.307)]: raw=json.loads((root/f'docs/extracted/section-{s}.json').read_text(encoding='utf8')) assert len(raw)==114 assert sum(l['layer']=='CS-CONC-MAJR' for l in raw)==108 assert sum(l['layer']=='CS-CONC-MINR' for l in raw)==6 for original,part in zip(raw,parts[:114]): assert original['handle']==part['handles'][0 if s=='A' else 1] for key,point in zip(['a','b'],part[s.lower()]): expected=[(original[key][0]-1128486.218066491)/1000,el+(original[key][1]-top)/1000] assert all(abs(a-b)<0.000000051 for a,b in zip(point,expected)) results.append(f'{s}: 114개 선 HANDLE·레이어·양 끝점 원본 대조 통과 (좌표 반올림 오차 0.000051mm 이하)') for p in parts: assert len(p['a'])==len(p['b']) assert all(math.isfinite(v) for s in ['a','b'] for point in p[s] for v in point) assert sum(p['kind']=='arc' for p in parts)==4 assert abs(model['longitudinalStations'][1]-model['longitudinalStations'][0]-model['length'])<1e-10 assert model['sectionStations'][1]-model['sectionStations'][0]==20 for i,el in enumerate(model['sectionTops']): assert abs(max(pt[1] for p in parts[:114] for pt in p['a' if i==0 else 'b'])-el)<1e-7 assert abs((parts[1]['a'][1][1]-parts[1]['a'][0][1]))<1e-7 results+=['154개 ID 중복 없음 / 모든 좌표 유한수 / 대응 꼭짓점 수 일치','원호 4개, 좌우 삽입 블록 40쌍 반영','벽체 상단 EL 및 종단 측점 차 19.980m 검산 통과','원본 단면 STA 간격 20.000m 보존; 사용자 허용에 따라 배치 간격만 19.980m로 대응 (verify_geometry.mjs에서 별도 검증)'] print('\n'.join(results)) (root/'docs/좌표검증결과.txt').write_text('\n'.join(results)+'\n',encoding='utf8')