45 lines
2.2 KiB
Python
45 lines
2.2 KiB
Python
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]<b)
|
|
if m.sum()>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'))
|