[ADD] Nachbau ILS-3.0-Showroom: tests/testdata/showroom_ils.json aus Showroom_ILS_3_0.dxf (6 Kreisel, 11 Gefaellestrecken, Separatoren/Scanner; Hoehen noch Platzhalter), Treiber tests/test_showroom_ils.lsp (TEST_SHOWROOM_ILS, Menue Tests -> ILS 3.0 Showroom), in alltests.json bis zu den Hoehen deaktiviert; [ADD] dxf_scan_components.py: --flach (waagrechte Staustrecken mit AS an genau einem Ende als GF), --kreisel-achse (Kreisel ohne AN8/SP8, z.B. Schleifen mit Weichenboegen), zerstueckelte Staustrecken-Linien werden vereint, ES am unteren Ende wird erkannt und verbraucht, AS/ES-Seite ohne Seitenangabe im Namen aus der Lage zur Fahrtrichtung, Kurznamen AE-*/EE-*; [FIX] Kreisel-Paarung: zwei Kreisel auf derselben Achse wurden ueber die Luecke gepaart (800 + 12832 statt 9033 + 3000) - Tausch-Nachbesserung auf minimale Abstandssumme; [CHANGE] test_dematic_arvato.lsp: Lauf als dematic_arvato:bau-datei herausgeloest (vom Showroom-Treiber mitgenutzt); [ADD] Tests in test_dxf_scan_gf.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+209
-17
@@ -153,6 +153,15 @@ GF_LINIE_MIN_DZ = 100.0
|
||||
# rechts), nicht der kleinste Abstand.
|
||||
GF_AS_MAX_ENTLANG = 2000.0
|
||||
GF_AS_MAX_QUER = 700.0
|
||||
# Wie weit (mm) das AS/ES VOR dem Linienende liegen darf, also schon auf der
|
||||
# Kreisel-Seite. In Dematic_arvato liegt es innerhalb der Linie; im
|
||||
# Showroom_ILS_3_0-Plan endet die Staustrecke 305 mm vor dem Element, das auf
|
||||
# der Kreisel-Kette sitzt. Kleiner als das Linienraster quer zur Kette
|
||||
# (Nachbar-GF der Gegenrichtung lag dort 1200 mm entfernt).
|
||||
GF_AS_MAX_VOR = 800.0
|
||||
# Toleranz (mm) fuer zusammenstossende Linienenden beim Zusammenfassen
|
||||
# zerstueckelter Staustrecken (linien_zusammenfassen).
|
||||
GF_LINIE_STOSS_TOL = 1.0
|
||||
|
||||
# Groesste Luecke (mm) zwischen Linienende und Kreisel-Kette, bis zu der die
|
||||
# Linie an diesen Kreisel angeschlossen wird. Gezeichnet ist nur die
|
||||
@@ -303,8 +312,9 @@ FAMILIEN = [
|
||||
("omniflo_weiche", ["Weiche *", "Weichen-TEF*"]),
|
||||
("bogen", ["3D_ILS_Bogen_*", "3D_FF_Bogen_*", "TEF_Bogen_*",
|
||||
"tef30*", "tef90*"]),
|
||||
# "AE-D"/"EE-R": Kurznamen der aelteren ILS-Plaene (Showroom_ILS_3_0.dxf)
|
||||
("schleuselement", ["Ausschleuselement*", "Einschleuselement*",
|
||||
"EE_Neu*", "AE_Neu*"]),
|
||||
"EE_Neu*", "AE_Neu*", "AE-*", "EE-*"]),
|
||||
("sensor", ["S-LP", "S-SP", "SCAN", "SCAN_*", "Scanner*",
|
||||
"Separator*", "Stopper*", "Stopperschleuse*"]),
|
||||
]
|
||||
@@ -399,12 +409,12 @@ def mappe_block(bname):
|
||||
geraten)
|
||||
|
||||
# Aus-/Einschleuselement -> AS_Element / ES_Element
|
||||
if "ausschleus" in low or low.startswith("ae_"):
|
||||
if "ausschleus" in low or low.startswith(("ae_", "ae-")):
|
||||
winkel, geschaetzt = winkel_aus_name(bname, DEFAULT_SCHLEUS_WINKEL)
|
||||
if geschaetzt:
|
||||
geraten.append("Winkel=%d" % winkel)
|
||||
return "AS_Element_%d_%s" % (winkel, seite_aus()), geraten
|
||||
if "einschleus" in low or low.startswith("ee_"):
|
||||
if "einschleus" in low or low.startswith(("ee_", "ee-")):
|
||||
winkel, geschaetzt = winkel_aus_name(bname, DEFAULT_SCHLEUS_WINKEL)
|
||||
if geschaetzt:
|
||||
geraten.append("Winkel=%d" % winkel)
|
||||
@@ -1047,17 +1057,25 @@ def kreisel_paare_bilden(an_liste, sp_liste):
|
||||
19 m daneben gepaart). Zusaetzlich muessen beide auf einer gemeinsamen
|
||||
Achse liegen (Querversatz <= KREISEL_MAX_QUER).
|
||||
|
||||
Danach Tausch-Nachbesserung auf minimale Abstandssumme (siehe unten).
|
||||
|
||||
Rueckgabe: (paare [(an, sp, abstand)] nach AN-Position sortiert,
|
||||
AN8 ohne Partner, SP8 ohne Partner)
|
||||
"""
|
||||
def abstand(an, sp):
|
||||
"""Mittenabstand, oder None wenn nicht auf gemeinsamer Achse."""
|
||||
dx = abs(sp["x"] - an["x"])
|
||||
dy = abs(sp["y"] - an["y"])
|
||||
if min(dx, dy) > KREISEL_MAX_QUER:
|
||||
return None
|
||||
return math.hypot(dx, dy)
|
||||
|
||||
kandidaten = []
|
||||
for ia, an in enumerate(an_liste):
|
||||
for isp, sp in enumerate(sp_liste):
|
||||
dx = abs(sp["x"] - an["x"])
|
||||
dy = abs(sp["y"] - an["y"])
|
||||
if min(dx, dy) > KREISEL_MAX_QUER:
|
||||
continue
|
||||
kandidaten.append((math.hypot(dx, dy), ia, isp))
|
||||
d = abstand(an, sp)
|
||||
if d is not None:
|
||||
kandidaten.append((d, ia, isp))
|
||||
kandidaten.sort()
|
||||
an_frei = set(range(len(an_liste)))
|
||||
sp_frei = set(range(len(sp_liste)))
|
||||
@@ -1066,7 +1084,29 @@ def kreisel_paare_bilden(an_liste, sp_liste):
|
||||
if ia in an_frei and isp in sp_frei:
|
||||
an_frei.discard(ia)
|
||||
sp_frei.discard(isp)
|
||||
paare.append((an_liste[ia], sp_liste[isp], dist))
|
||||
paare.append([an_liste[ia], sp_liste[isp], dist])
|
||||
|
||||
# Nachbesserung: zwei Paare tauschen ihre SP8, solange die Summe der
|
||||
# Abstaende dadurch kleiner wird. "Kuerzestes Paar zuerst" allein
|
||||
# scheitert an zwei Kreiseln auf DERSELBEN Achse: die Luecke zwischen
|
||||
# SP8 des einen und AN8 des anderen ist kuerzer als beide Kreisel und
|
||||
# wird zuerst gepaart (Showroom_ILS_3_0: 800 + 12832 statt 9033 + 3000).
|
||||
# Die echte Zuordnung hat immer die kleinere Summe - jede vertauschte
|
||||
# Paarung ueberspannt mindestens eine Luecke doppelt.
|
||||
verbessert = True
|
||||
while verbessert:
|
||||
verbessert = False
|
||||
for i in range(len(paare)):
|
||||
for j in range(i + 1, len(paare)):
|
||||
a1, s1, d1 = paare[i]
|
||||
a2, s2, d2 = paare[j]
|
||||
n1, n2 = abstand(a1, s2), abstand(a2, s1)
|
||||
if n1 is None or n2 is None or n1 + n2 >= d1 + d2 - 1e-6:
|
||||
continue
|
||||
paare[i] = [a1, s2, n1]
|
||||
paare[j] = [a2, s1, n2]
|
||||
verbessert = True
|
||||
paare = [tuple(p) for p in paare]
|
||||
paare.sort(key=lambda p: (p[0]["x"], p[0]["y"]))
|
||||
return (paare,
|
||||
[an_liste[i] for i in sorted(an_frei)],
|
||||
@@ -1320,6 +1360,10 @@ def as_am_ende(p, richtung, as_liste, belegt):
|
||||
auf dieser Seite liegen - das trennt ihn vom Nachbar-AS der Linie daneben.
|
||||
Bereits vergebene AS (belegt = Menge von id()) zaehlen nicht.
|
||||
|
||||
Funktioniert genauso fuer Einschleuselemente am unteren Ende (es_liste in
|
||||
gf_eintraege_aus_linien), dann mit der Richtung vom unteren Ende in die
|
||||
Linie hinein.
|
||||
|
||||
Rueckgabe: (treffer, zielblock, geraten) oder None.
|
||||
"""
|
||||
beste = None
|
||||
@@ -1329,7 +1373,8 @@ def as_am_ende(p, richtung, as_liste, belegt):
|
||||
vx, vy = t["x"] - p[0], t["y"] - p[1]
|
||||
entlang = vx * richtung[0] + vy * richtung[1]
|
||||
quer = richtung[0] * vy - richtung[1] * vx
|
||||
if not (0.0 <= entlang <= GF_AS_MAX_ENTLANG and abs(quer) <= GF_AS_MAX_QUER):
|
||||
if not (-GF_AS_MAX_VOR <= entlang <= GF_AS_MAX_ENTLANG
|
||||
and abs(quer) <= GF_AS_MAX_QUER):
|
||||
continue
|
||||
block, geraten = mappe_block(t["block"])
|
||||
if "Seite=%s" % DEFAULT_SEITE not in (geraten or []):
|
||||
@@ -1376,8 +1421,78 @@ def kreisel_anschluss(p, richtung, kreisel):
|
||||
return beste
|
||||
|
||||
|
||||
def linien_zusammenfassen(linien):
|
||||
"""Kollineare, aneinanderstossende Linien desselben Layers vereinen.
|
||||
|
||||
Eine Staustrecke ist im Plan oft in Stuecke zerlegt (Showroom_ILS_3_0:
|
||||
vier LINEs je GF, an den Separatoren getrennt). Als Einzelstuecke fehlte
|
||||
jedem das AS am einen oder das ES am anderen Ende. Vereint wird nur bei
|
||||
gleicher Richtung (in 3D) und Stoss innerhalb GF_LINIE_STOSS_TOL.
|
||||
"""
|
||||
def richtung(ln):
|
||||
d = [ln["b"][i] - ln["a"][i] for i in range(3)]
|
||||
n = math.sqrt(sum(c * c for c in d))
|
||||
return [c / n for c in d] if n else None
|
||||
|
||||
def kollinear(r1, r2):
|
||||
kreuz = (r1[1] * r2[2] - r1[2] * r2[1], r1[2] * r2[0] - r1[0] * r2[2],
|
||||
r1[0] * r2[1] - r1[1] * r2[0])
|
||||
# 1e-3 rad (~0.06 Grad): die Plaene sind nicht exakt gezeichnet -
|
||||
# im Showroom-Plan sitzt das Separatorstueck 0,3 mm neben der Achse,
|
||||
# das verkippt das bis dahin vereinte Stueck um ~2.6e-4.
|
||||
return math.sqrt(sum(c * c for c in kreuz)) < 1e-3
|
||||
|
||||
def gleich(p, q):
|
||||
return math.dist(p, q) <= GF_LINIE_STOSS_TOL
|
||||
|
||||
rest = [{"layer": ln["layer"], "a": list(ln["a"]), "b": list(ln["b"])}
|
||||
for ln in linien]
|
||||
fertig = []
|
||||
while rest:
|
||||
akt = rest.pop(0)
|
||||
gewachsen = True
|
||||
while gewachsen:
|
||||
gewachsen = False
|
||||
ra = richtung(akt)
|
||||
for ln in rest:
|
||||
rb = richtung(ln)
|
||||
if (ln["layer"] != akt["layer"] or ra is None or rb is None
|
||||
or not kollinear(ra, rb)):
|
||||
continue
|
||||
# Die vier moeglichen Stoesse; das Ergebnis behaelt die
|
||||
# beiden aeusseren Enden.
|
||||
for p_akt, q_akt in (("a", "b"), ("b", "a")):
|
||||
for p_ln, q_ln in (("a", "b"), ("b", "a")):
|
||||
if gleich(akt[p_akt], ln[p_ln]):
|
||||
akt = {"layer": akt["layer"], "a": akt[q_akt],
|
||||
"b": ln[q_ln]}
|
||||
gewachsen = True
|
||||
break
|
||||
if gewachsen:
|
||||
break
|
||||
if gewachsen:
|
||||
rest.remove(ln)
|
||||
break
|
||||
fertig.append(akt)
|
||||
return fertig
|
||||
|
||||
|
||||
def seite_aus_lage(t, p, r):
|
||||
"""Seite eines AS/ES aus seiner Lage zur GF-Fahrtrichtung.
|
||||
|
||||
t = Element, p = Punkt auf der Achse, r = Fahrtrichtung der GF (bergab).
|
||||
Links der Fahrtrichtung -> "links", sonst "rechts" - dieselbe Zuordnung
|
||||
wie in Dematic_arvato ("Ausschleuselement links" liegt links der
|
||||
Fahrtrichtung, siehe as_am_ende). Nur fuer Bloecke ohne Seite im Namen
|
||||
("AE-D"/"EE-R"); gespiegelte Inserts landen dadurch automatisch auf der
|
||||
Gegenseite.
|
||||
"""
|
||||
vx, vy = t["x"] - p[0], t["y"] - p[1]
|
||||
return "links" if r[0] * vy - r[1] * vx > 0 else "rechts"
|
||||
|
||||
|
||||
def gf_eintraege_aus_linien(linien, as_liste, kreisel=None, sep_liste=None,
|
||||
winkel_default=3.0):
|
||||
winkel_default=3.0, es_liste=None, flach=False):
|
||||
"""Gefaellestrecken (Modus 1, Schema 2.1) aus Staustrecken-Linien.
|
||||
|
||||
Eine Gefaellestrecke laeuft immer bergab: Start ist das HOEHERE
|
||||
@@ -1407,15 +1522,35 @@ def gf_eintraege_aus_linien(linien, as_liste, kreisel=None, sep_liste=None,
|
||||
die Gefaellestrecke selbst mit, als Einzel-Insert stuenden sie doppelt in
|
||||
der Zeichnung (und im Sivas-Export). Der AS eines uebersprungenen
|
||||
Steigfoerderers bleibt unverbraucht.
|
||||
|
||||
es_liste: Einschleuselemente; eines am unteren Ende liefert es_seite/
|
||||
es_winkel und wird ebenfalls verbraucht. Ohne es_liste bleiben beide
|
||||
Defaults (Dematic_arvato hat kein ES im Plan).
|
||||
|
||||
flach: 2D-Plan ohne Hoehen (alle Linien waagrecht, z.B.
|
||||
Showroom_ILS_3_0). Dann ist eine waagrechte Linie eine GF, wenn genau an
|
||||
EINEM Ende ein Ausschleuselement sitzt - dieses Ende ist oben. Ohne flach
|
||||
werden waagrechte Linien wie bisher uebergangen.
|
||||
"""
|
||||
eintraege, hinweise = [], []
|
||||
belegt = set()
|
||||
waagrecht = 0
|
||||
kandidaten = []
|
||||
for ln in linien:
|
||||
for ln in linien_zusammenfassen(linien):
|
||||
a, b = ln["a"], ln["b"]
|
||||
if abs(a[2] - b[2]) < GF_LINIE_MIN_DZ:
|
||||
waagrecht += 1
|
||||
lxy = math.hypot(b[0] - a[0], b[1] - a[1])
|
||||
if not (flach and lxy > 0.0):
|
||||
waagrecht += 1
|
||||
continue
|
||||
r_ab = ((b[0] - a[0]) / lxy, (b[1] - a[1]) / lxy)
|
||||
as_a = as_am_ende(a, r_ab, as_liste, belegt)
|
||||
as_b = as_am_ende(b, (-r_ab[0], -r_ab[1]), as_liste, belegt)
|
||||
if (as_a is None) == (as_b is None):
|
||||
waagrecht += 1
|
||||
continue
|
||||
hoch, tief = (a, b) if as_a is not None else (b, a)
|
||||
kandidaten.append((hoch, tief, lxy, ln["layer"]))
|
||||
continue
|
||||
hoch, tief = (a, b) if a[2] > b[2] else (b, a)
|
||||
lxy = math.hypot(tief[0] - hoch[0], tief[1] - hoch[1])
|
||||
@@ -1495,6 +1630,13 @@ def gf_eintraege_aus_linien(linien, as_liste, kreisel=None, sep_liste=None,
|
||||
belegt.add(id(t))
|
||||
teile = block.split("_") # AS_Element_<winkel>_<seite>
|
||||
eintrag["as_winkel"], eintrag["as_seite"] = teile[2], teile[3]
|
||||
if "Seite=%s" % DEFAULT_SEITE in geraten:
|
||||
eintrag["as_seite"] = seite_aus_lage(t, hoch, r)
|
||||
geraten = [g for g in geraten if not g.startswith("Seite=")]
|
||||
block = "AS_Element_%s_%s" % (eintrag["as_winkel"],
|
||||
eintrag["as_seite"])
|
||||
kommentar += ("; as_seite %s aus der Lage zur Fahrtrichtung"
|
||||
% eintrag["as_seite"])
|
||||
kommentar += ("; AS aus Block '%s' bei (%.2f, %.2f) -> %s, als "
|
||||
"Einzel-Insert entfernt (baut die GF selbst)"
|
||||
% (t["block"], t["x"], t["y"], block))
|
||||
@@ -1520,7 +1662,28 @@ def gf_eintraege_aus_linien(linien, as_liste, kreisel=None, sep_liste=None,
|
||||
kommentar += ("; Separator auf der Achse entfernt (die GF baut "
|
||||
"ihren eigenen): %s" % ", ".join(weg))
|
||||
|
||||
kommentar += "; es_seite/es_winkel sind Defaults (kein ES im DXF)."
|
||||
unten = (as_am_ende(tief, (-r[0], -r[1]), es_liste, belegt)
|
||||
if es_liste else None)
|
||||
if unten is not None:
|
||||
t, block, geraten = unten
|
||||
belegt.add(id(t))
|
||||
teile = block.split("_") # ES_Element_<winkel>_<seite>
|
||||
eintrag["es_winkel"], eintrag["es_seite"] = teile[2], teile[3]
|
||||
if "Seite=%s" % DEFAULT_SEITE in geraten:
|
||||
eintrag["es_seite"] = seite_aus_lage(t, tief, r)
|
||||
geraten = [g for g in geraten if not g.startswith("Seite=")]
|
||||
block = "ES_Element_%s_%s" % (eintrag["es_winkel"],
|
||||
eintrag["es_seite"])
|
||||
kommentar += ("; es_seite %s aus der Lage zur Fahrtrichtung"
|
||||
% eintrag["es_seite"])
|
||||
kommentar += ("; ES aus Block '%s' bei (%.2f, %.2f) -> %s, als "
|
||||
"Einzel-Insert entfernt (baut die GF selbst)"
|
||||
% (t["block"], t["x"], t["y"], block))
|
||||
if geraten:
|
||||
kommentar += " - geraten: %s" % ", ".join(geraten)
|
||||
kommentar += "."
|
||||
else:
|
||||
kommentar += "; es_seite/es_winkel sind Defaults (kein ES im DXF)."
|
||||
eintrag["comment"] = kommentar
|
||||
eintraege.append(eintrag)
|
||||
|
||||
@@ -1532,12 +1695,20 @@ def gf_eintraege_aus_linien(linien, as_liste, kreisel=None, sep_liste=None,
|
||||
|
||||
|
||||
def baue_eintraege(treffer, defaults, boegen, weichen,
|
||||
bekannte_bloecke=None, linien=None, kreisel_hoehen=None):
|
||||
bekannte_bloecke=None, linien=None, kreisel_hoehen=None,
|
||||
kreisel_achsen=None, flach=False):
|
||||
"""Erkannte Vorkommen auf die Schemata aus object_data.md abbilden.
|
||||
|
||||
kreisel_hoehen: Liste (x, y, z) vom Anwender - z gilt fuer den Kreisel,
|
||||
dessen Einfuegepunkt (Eintrag x/y) hoechstens KREISEL_HOEHE_TOL entfernt
|
||||
liegt, und fuer die Gefaellestrecken, die an ihm anschliessen.
|
||||
|
||||
kreisel_achsen: Liste (x1, y1, x2, y2) vom Anwender - Radmitten eines
|
||||
Kreisels ohne AN8/SP8 im Plan (Showroom_ILS_3_0: Schleifen, die an beiden
|
||||
Enden mit Weichenboegen schliessen). Wird als STANDARD-Kreisel
|
||||
angenaehert, x1/y1 gilt als AN8-Seite.
|
||||
|
||||
flach: siehe gf_eintraege_aus_linien.
|
||||
"""
|
||||
nach_familie = {}
|
||||
for t in treffer:
|
||||
@@ -1555,6 +1726,12 @@ def baue_eintraege(treffer, defaults, boegen, weichen,
|
||||
for an in an_rest:
|
||||
hinweise.append("AN8 bei (%.2f, %.2f) ohne SP8-Partner" % (an["x"], an["y"]))
|
||||
eintraege.append(sensor_eintrag(an, bekannte_bloecke, hinweise, treffer))
|
||||
for x1, y1, x2, y2 in kreisel_achsen or []:
|
||||
an = {"block": "(manuell AN8)", "layer": "--kreisel-achse",
|
||||
"x": x1, "y": y1, "z": 0.0, "darstellung": "2D"}
|
||||
sp = {"block": "(manuell SP8)", "layer": "--kreisel-achse",
|
||||
"x": x2, "y": y2, "z": 0.0, "darstellung": "2D"}
|
||||
kreisel_paare.append((an, sp, math.hypot(x2 - x1, y2 - y1)))
|
||||
for i, (an, sp, dist) in enumerate(kreisel_paare, start=1):
|
||||
rotation = math.degrees(math.atan2(sp["y"] - an["y"], sp["x"] - an["x"])) % 360.0
|
||||
# AN8/SP8 sind flache 2D-Symbole auf Z=0 - die Einbauhoehe steht nicht
|
||||
@@ -1632,9 +1809,12 @@ def baue_eintraege(treffer, defaults, boegen, weichen,
|
||||
if linien:
|
||||
as_liste = [t for t in nach_familie.get("schleuselement", [])
|
||||
if mappe_block(t["block"])[0].startswith("AS_Element")]
|
||||
es_liste = [t for t in nach_familie.get("schleuselement", [])
|
||||
if mappe_block(t["block"])[0].startswith("ES_Element")]
|
||||
gf, belegt, gf_hinweise = gf_eintraege_aus_linien(
|
||||
linien, as_liste, kreisel_geo, nach_familie.get("sensor", []),
|
||||
defaults.get("gefaelle", {}).get("default_winkel", 3.0))
|
||||
defaults.get("gefaelle", {}).get("default_winkel", 3.0),
|
||||
es_liste, flach)
|
||||
eintraege.extend(gf)
|
||||
hinweise.extend(gf_hinweise)
|
||||
for familie in ("schleuselement", "sensor"):
|
||||
@@ -1873,6 +2053,17 @@ def main():
|
||||
"(wie im Ausgabe-JSON); gilt auch fuer Start/Ende "
|
||||
"der daran anschliessenden Gefaellestrecken. "
|
||||
"Mehrfach angebbar")
|
||||
parser.add_argument("--kreisel-achse", nargs=4, type=float,
|
||||
action="append", metavar=("X1", "Y1", "X2", "Y2"),
|
||||
help="Kreisel ohne AN8/SP8 im Plan (z.B. Schleife mit "
|
||||
"Weichenboegen an beiden Enden): Radmitten der "
|
||||
"beiden Enden, X1/Y1 = AN8-Seite. Wird als "
|
||||
"STANDARD-Kreisel angenaehert. Mehrfach angebbar")
|
||||
parser.add_argument("--flach", action="store_true",
|
||||
help="2D-Plan ohne Hoehen: waagrechte Staustrecken-"
|
||||
"Linien mit Ausschleuselement an genau einem "
|
||||
"Ende als Gefaellestrecke ausgeben (Hoehen dann "
|
||||
"ueber --kreisel-hoehe)")
|
||||
parser.add_argument("--projekt",
|
||||
help="Projektkennung in den erzeugten IDs "
|
||||
"(Default: Name der DXF-Datei ohne Endung)")
|
||||
@@ -1937,7 +2128,8 @@ def main():
|
||||
|
||||
eintraege, hinweise = baue_eintraege(treffer, defaults, boegen, weichen,
|
||||
bekannte_bloecke, linien,
|
||||
args.kreisel_hoehe)
|
||||
args.kreisel_hoehe, args.kreisel_achse,
|
||||
args.flach)
|
||||
if args.ohne_hoehen:
|
||||
print("%s --ohne-hoehen: Hoehe in %d Eintraegen auf 0 gesetzt"
|
||||
% (PREFIX, hoehen_entfernen(eintraege)))
|
||||
|
||||
Reference in New Issue
Block a user