Files
fs25-adsmartpickup/tools/ad-smooth/adturns.py
T

37 lines
1.9 KiB
Python

import re,math,collections,sys
def load(path):
s=open(path,encoding="utf-8-sig").read()
w=re.search(r"<waypoints>(.*?)</waypoints>",s,re.S).group(1)
g=lambda t:re.search(rf"<{t}>(.*?)</{t}>",w,re.S).group(1)
ids=[int(v) for v in g("id").split(",")]
X=[float(v) for v in g("x").split(",")]; Z=[float(v) for v in g("z").split(",")]
sp=lambda t:[[int(v) for v in e.split(",") if v not in("","-1")] for e in g(t).split(";")]
out=sp("out"); inc=sp("incoming"); fl=[int(v) for v in g("flags").split(",")]
N={i:dict(x=X[k],z=Z[k],out=out[k],inc=inc[k],fl=fl[k]) for k,i in enumerate(ids)}
mk=[(int(a),b) for a,b in re.findall(r'<mm\d+ id="(\d+)" name="([^"]*)"',s)]
return s,N,mk
def ang(N,a,b,c):
A,B,C=N[a],N[b],N[c]
v1=(B["x"]-A["x"],B["z"]-A["z"]); v2=(C["x"]-B["x"],C["z"]-B["z"])
l1=math.hypot(*v1); l2=math.hypot(*v2)
if l1<1e-3 or l2<1e-3: return 0,l1,l2
d=(v1[0]*v2[0]+v1[1]*v2[1])/(l1*l2)
return math.degrees(math.acos(max(-1,min(1,d)))),l1,l2
if __name__=="__main__":
s,N,mk=load(sys.argv[1])
print("noder",len(N),"markører",len(mk),"flags",collections.Counter(n["fl"] for n in N.values()))
sharp=[];rev=0
for b,n in N.items():
for a in n["inc"]:
for c in n["out"]:
if a==c or a not in N or c not in N: continue
# samme retning som forbindelse? tjek at a->b og b->c er reelle kanter
if b not in N[a]["out"]: continue
t,l1,l2=ang(N,a,b,c)
if t>135: rev+=1; continue # U-vending / bakke-par, ikke et sving
if t>45: sharp.append((round(t),a,b,c,len(n["inc"]),len(n["out"]),round(l1,1),round(l2,1)))
kinds=collections.Counter("kæde" if (x[4]==1 and x[5]==1) else "kryds" for x in sharp)
print("sving >45°:",len(sharp),kinds,"(>135° udeladt:",rev,")")
print("fordeling:",collections.Counter(min(x[0]//15*15,135) for x in sharp))
nodes={x[2] for x in sharp}; print("unikke knæk-noder",len(nodes))