import sys, json, math sys.path += ['/root/.local/lib/python3.13/site-packages','/usr/local/lib/python3.13/dist-packages','/usr/lib/python3/dist-packages'] import numpy as np from scipy.spatial import cKDTree from scipy.optimize import least_squares import matplotlib; matplotlib.use('Agg'); import matplotlib.pyplot as plt SEC = json.load(open('/tmp/verify_daesan2_run/sections_final.json')) def pts_of(st, pred): out=[]; ids=[] for sid,v in SEC[st]['solids'].items(): if pred(v['group'], v['id']): for poly in v['polys']: out.append(np.array(poly)[:, :2]); ids.append(v['id']) return (np.vstack(out) if out else np.zeros((0,2))), ids def fit_circle(P): x,y=P[:,0],P[:,1] A=np.c_[2*x,2*y,np.ones(len(x))]; b=x*x+y*y c,_,_,_=np.linalg.lstsq(A,b,rcond=None) xc,yc=c[0],c[1]; r=math.sqrt(c[2]+xc*xc+yc*yc) return xc,yc,r # ---- lining crown fit per station fits={} for st in SEC: P,_=pts_of(st, lambda g,i: g=='라이닝') u0=(P[:,0].min()+P[:,0].max())/2; v0=P[:,1].max()-7.282 d=np.hypot(P[:,0]-u0,P[:,1]-v0) sel_o=P[(np.abs(d-7.282)<0.03)&(P[:,1]-v0>4.0)] sel_i=P[(np.abs(d-6.982)<0.03)&(P[:,1]-v0>4.0)] co=fit_circle(sel_o); ci=fit_circle(sel_i) fits[st]={'outer':co,'inner':ci,'n_o':len(sel_o),'n_i':len(sel_i)} print(f"st {st}: outer n={len(sel_o)} centre=({co[0]:.4f},{co[1]:.4f}) R={co[2]:.4f} | inner n={len(sel_i)} centre=({ci[0]:.4f},{ci[1]:.4f}) R={ci[2]:.4f}") # ---- pavement slope (top/bottom envelopes) per station for st in SEC: P,_=pts_of(st, lambda g,i: g=='노면(계획고)') bins=np.arange(P[:,0].min(),P[:,0].max()+0.25,0.25) tops=[];bots=[] for a,b in zip(bins[:-1],bins[1:]): m=(P[:,0]>=a)&(P[:,0]0: tops.append((P[m,0].mean(),P[m,1].max())); bots.append((P[m,0].mean(),P[m,1].min())) tops=np.array(tops); bots=np.array(bots) mt=np.polyfit(tops[:,0],tops[:,1],1); mb=np.polyfit(bots[:,0],bots[:,1],1) fits[st]['slope_top']=mt[0]; fits[st]['slope_bot']=mb[0] print(f"st {st}: PAV top slope dv/du={mt[0]:.5f} (S={mt[0]*100:.3f}%), bottom slope={mb[0]:.5f}; top@u=0 {mt[1]:.4f}, bottom@u=0 {mb[1]:.4f}; u-range [{P[:,0].min():.3f},{P[:,0].max():.3f}]") json.dump(fits, open('/tmp/verify_daesan2_run/fits.json','w'))