diff --git a/java/bundles/org.eclipse.set.feature.table.pt1/src/org/eclipse/set/feature/table/pt1/ssld/SsldTransformator.xtend b/java/bundles/org.eclipse.set.feature.table.pt1/src/org/eclipse/set/feature/table/pt1/ssld/SsldTransformator.xtend index 5371a397d..e3cad22b8 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1/src/org/eclipse/set/feature/table/pt1/ssld/SsldTransformator.xtend +++ b/java/bundles/org.eclipse.set.feature.table.pt1/src/org/eclipse/set/feature/table/pt1/ssld/SsldTransformator.xtend @@ -38,6 +38,8 @@ import static extension org.eclipse.set.ppmodel.extensions.PunktObjektExtensions import static extension org.eclipse.set.ppmodel.extensions.SignalExtensions.* import static extension org.eclipse.set.ppmodel.extensions.UrObjectExtensions.* import static extension org.eclipse.set.utils.math.BigDecimalExtensions.* +import org.eclipse.set.ppmodel.extensions.utils.TopGraph +import java.math.BigDecimal /** * Table transformation for a Durchrutschwegtabelle (SSLD). @@ -55,7 +57,7 @@ class SsldTransformator extends AbstractPlanPro2TableModelTransformator { this.topGraphService = topGraphService } - def double getShortestPathLength(Signal signal, Punkt_Objekt p) { + def BigDecimal getShortestPathLength(Signal signal, Punkt_Objekt p) { val points1 = signal.singlePoints.map[new TopPoint(it)] val points2 = p.singlePoints.map[new TopPoint(it)] @@ -63,20 +65,31 @@ class SsldTransformator extends AbstractPlanPro2TableModelTransformator { points2.map [ pb | topGraphService.findShortestDistance(pa, pb) ] - ].filter[present].map[get.doubleValue].min + ].filter[present].map[get].min } - def String getFreigemeldetLaenge(Fstr_DWeg dweg) { - val fmas = dweg?.FMAs + def String getFreigemeldetLaenge(Fstr_DWeg dweg, TopGraph topGraph, + BigDecimal maxLength) { + val startSignal = dweg?.fstrFahrweg?.start + val fmas = dweg?.FMAs.toList.filter [ + topGraph.isInWirkrichtungOfSignal(startSignal, it) + ] if (fmas.empty) { return "" } - val distance = fmas?.fold( - Double.valueOf(0.0), [ Double current, Punkt_Objekt grenze | - Math.max(current, - getShortestPathLength(dweg?.fstrFahrweg?.start, grenze)) - ]) - val roundedDistance = AgateRounding.roundDown(distance) + + val relevantDistances = fmas?.map [ + getShortestPathLength(dweg?.fstrFahrweg?.start, it) + ].filter [ + maxLength.compareTo(it) >= 0 && + dweg?.fstrDWegAllg?.laengeSoll?.wert.compareTo(it) <= 0 + ] + if (relevantDistances.nullOrEmpty) { + return AgateRounding.roundDown(maxLength.doubleValue).toString + } + + val roundedDistance = AgateRounding.roundDown( + relevantDistances.max.doubleValue) if (roundedDistance == 0.0) throw new IllegalArgumentException("no path found") else @@ -88,9 +101,9 @@ class SsldTransformator extends AbstractPlanPro2TableModelTransformator { TMFactory factory, Stell_Bereich controlArea ) { - val fstDwegList = container.fstrDWeg - .filter[isPlanningObject] - .filterObjectsInControlArea(controlArea) + val topGraph = new TopGraph(container.TOPKante) + val fstDwegList = container.fstrDWeg.filter[isPlanningObject]. + filterObjectsInControlArea(controlArea) // var footnoteNumber = 1; for (dweg : fstDwegList) { @@ -170,11 +183,12 @@ class SsldTransformator extends AbstractPlanPro2TableModelTransformator { ) // H: Ssld.Eigenschaften.Laenge.Ist + val fstrFahrWegLength = dweg.fstrFahrweg.length fill( instance, cols.getColumn(Laenge_Ist), dweg, - [fstrFahrweg.length.toTableIntegerAgateDown] + [fstrFahrWegLength.toTableIntegerAgateDown] ) // I: Ssld.Eigenschaften.Laenge.Freigemeldet @@ -182,7 +196,7 @@ class SsldTransformator extends AbstractPlanPro2TableModelTransformator { instance, cols.getColumn(Freigemeldet), dweg, - [dweg.freigemeldetLaenge] + [getFreigemeldetLaenge(topGraph, fstrFahrWegLength)] ) // J: Ssld.Eigenschaften.massgebende_Neigung diff --git a/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/DwegExtensions.xtend b/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/DwegExtensions.xtend index a4e11fc28..8927551af 100644 --- a/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/DwegExtensions.xtend +++ b/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/DwegExtensions.xtend @@ -39,7 +39,9 @@ class DwegExtensions extends BasisObjektExtensions { * @returns the Zug-/Rangierstraßen for this Durchrutschweg */ def static List fstrZugRangier(Fstr_DWeg dweg) { - return dweg?.container?.fstrZugRangier?.filter[fstrZug?.fstrZugDWeg?.IDFstrDWeg?.value === dweg]?.toList + return dweg?.container?.fstrZugRangier?.filter [ + fstrZug?.fstrZugDWeg?.IDFstrDWeg?.value === dweg + ]?.toList } /** @@ -80,7 +82,8 @@ class DwegExtensions extends BasisObjektExtensions { * @returns the Weichen/Kreuzungen-Zuordnungen */ def static List zuordnungen(Fstr_DWeg dweg) { - return dweg?.container?.fstrDWegWKr?.filter[IDFstrDWeg?.value === dweg]?.toList + return dweg?.container?.fstrDWegWKr?. + filter[IDFstrDWeg?.value === dweg]?.toList } /** @@ -89,7 +92,7 @@ class DwegExtensions extends BasisObjektExtensions { * @return the fma on this durchrutschweg, without fma on start signal */ def static Iterable getFMAs(Fstr_DWeg dweg) { - val fmaAnlagen = dweg?.fmaAnlageFreimeldung + val fmaAnlagen = dweg?.fmaAnlageFreimeldung.toList if (fmaAnlagen.empty || fmaAnlagen === null) { return emptySet } @@ -97,36 +100,29 @@ class DwegExtensions extends BasisObjektExtensions { if (fmaAnlagen.contains(null)) { throw new IllegalArgumentException('''«dweg?.bezeichnung?.bezeichnungFstrDWeg?.wert» contains non-FMA-Anlagen within ID_FMA_Anlage''') } - + val topFahrWeg = dweg?.fstrFahrweg?.topKanten val fmaGrenzens = fmaAnlagen.map[fmaGrenzen].flatten.toSet val startSignal = dweg.fstrFahrweg?.start - // 1. Fall: start signal and end fma stay on same TOP_Kante - val fmaOnFahrweg = fmaGrenzens?.filter [ - topKanten.exists[topFahrWeg.contains(it)] - ].filter [ fma | - // Filter fma at start signal - fma.singlePoints.exists [ - !startSignal.singlePoints.map[abstand.wert].contains( - abstand.wert) + return fmaGrenzens.filter [ fma | + val isFmaAtStartSignal = fma.singlePoints.exists [ fmaPotk | + startSignal.singlePoints.map[abstand.wert].exists [ signalDistance | + signalDistance.compareTo(fmaPotk.abstand.wert) == 0 + ] ] - ] - if (!fmaOnFahrweg.empty) { - return fmaOnFahrweg - } - // 2. Fall: start signal and end fma stay on two different TOP_Kante - return dweg.fmaOnAnotherTOPKante(fmaGrenzens) + return fma.topKanten.exists[topFahrWeg.contains(it)] && + !isFmaAtStartSignal || dweg.isRelevantFma(fma) + ].toSet } - def private static Iterable fmaOnAnotherTOPKante(Fstr_DWeg dweg, - Set fmaGrenzens) { + // Fall start signal and the target fma stay on two different TOP_Kante + def private static boolean isRelevantFma(Fstr_DWeg dweg, Punkt_Objekt fma) { val fahrweg = dweg?.fstrFahrweg val topFahrWeg = fahrweg?.topKanten val startSignal = fahrweg?.start val topEndFahrweg = fahrweg?.zielPunktObjekt?.topKanten - // When slip way run over a track switch val dwegGspElement = dweg?.zuordnungen?.map[WKrGspElement] if (!dwegGspElement.empty) { @@ -134,11 +130,9 @@ class DwegExtensions extends BasisObjektExtensions { if (startSignal.topKanten.exists [ dwegGspElement.map[#[topKanteL, topKanteR]].flatten.contains(it) ]) { - return fmaGrenzens.filter [ - topKanten.exists [ - topEndFahrweg.contains(it) - ] - ].filterNull.toSet + return fma.topKanten.exists [ + topEndFahrweg.contains(it) + ] } // 2. Fall: start from top of track switch and this switch is a combined switch @@ -151,15 +145,13 @@ class DwegExtensions extends BasisObjektExtensions { return gzR } return null - ].filterNull + ].filterNull if (!connectionGsp.empty) { - return fmaGrenzens.filter [ - topKanten.exists [ topGrenze | - connectionGsp.exists [ - gzFreimeldungTOPKante.contains(topGrenze) - ] + return fma.topKanten.exists [ topGrenze | + connectionGsp.exists [ + gzFreimeldungTOPKante.contains(topGrenze) ] - ].toSet + ] } } @@ -168,9 +160,9 @@ class DwegExtensions extends BasisObjektExtensions { topEndFahrweg.contains(it) ] && !dweg.fmaAnlageFreimeldung.contains(it) ].toSet - return fmaAnlageOnZiel.map[fmaGrenzen].flatten.filter [ - fmaGrenzens.contains(it) - ].toSet + return fmaAnlageOnZiel.map[fmaGrenzen].flatten.exists [ + it === fma + ] } private static def dispatch Set gzFreimeldungTOPKante( diff --git a/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/SignalExtensions.xtend b/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/SignalExtensions.xtend index fadddf683..986bad395 100644 --- a/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/SignalExtensions.xtend +++ b/java/bundles/org.eclipse.set.ppmodel.extensions/src/org/eclipse/set/ppmodel/extensions/SignalExtensions.xtend @@ -18,9 +18,11 @@ import org.eclipse.set.model.planpro.Ansteuerung_Element.Stell_Bereich import org.eclipse.set.model.planpro.Ansteuerung_Element.Stellelement import org.eclipse.set.model.planpro.Ansteuerung_Element.Unterbringung import org.eclipse.set.model.planpro.Basisobjekte.Punkt_Objekt +import org.eclipse.set.model.planpro.Basisobjekte.Punkt_Objekt_Strecke_AttributeGroup import org.eclipse.set.model.planpro.Basisobjekte.Punkt_Objekt_TOP_Kante_AttributeGroup import org.eclipse.set.model.planpro.Fahrstrasse.Fstr_Zug_Rangier import org.eclipse.set.model.planpro.Flankenschutz.Fla_Schutz +import org.eclipse.set.model.planpro.Geodaten.Strecke import org.eclipse.set.model.planpro.Geodaten.TOP_Kante import org.eclipse.set.model.planpro.Gleis.Gleis_Bezeichnung import org.eclipse.set.model.planpro.Ortung.FMA_Komponente @@ -57,8 +59,6 @@ import static extension org.eclipse.set.ppmodel.extensions.StellelementExtension import static extension org.eclipse.set.ppmodel.extensions.TopKanteExtensions.* import static extension org.eclipse.set.ppmodel.extensions.utils.CollectionExtensions.* import static extension org.eclipse.set.ppmodel.extensions.utils.Debug.* -import org.eclipse.set.model.planpro.Geodaten.Strecke -import org.eclipse.set.model.planpro.Basisobjekte.Punkt_Objekt_Strecke_AttributeGroup /** * This class extends {@link Signal}. @@ -184,9 +184,30 @@ class SignalExtensions extends PunktObjektExtensions { def static boolean isInWirkrichtungOfSignal(TopGraph topGraph, Signal signal, List potks) { - return topGraph.getPaths(signal.singlePoints, potks).flatMap [ - edges - ].forall[isForwards == true] + // Find path from the signal to point object + val relevantPaths = topGraph.getPaths(signal.singlePoints, potks). + flatMap[edges] + if (relevantPaths.isNullOrEmpty) { + return false + } + + // The path must start the TOP_Kante of the signal and have same direction like the signal + return relevantPaths.filter[signal.topKanten.contains(element)].forall [ + val wirkrichtung = signal.getWirkrichtung(element) + if (wirkrichtung === null) { + return isForwards + } + switch (wirkrichtung) { + case ENUM_WIRKRICHTUNG_IN: + return isForwards == true + case ENUM_WIRKRICHTUNG_BEIDE_VALUE: + return true + case ENUM_WIRKRICHTUNG_GEGEN: + return isForwards == false + default: + throw new IllegalArgumentException() + } + ] } /** @@ -470,7 +491,6 @@ class SignalExtensions extends PunktObjektExtensions { return false } - def static List getFmaKomponenten(Signal signal) { val fstrFahrwegs = signal.container.fstrFahrweg.filter [ start === signal || zielSignal === signal @@ -482,17 +502,18 @@ class SignalExtensions extends PunktObjektExtensions { fmaAnlages.exists[fmaKomponent.belongsTo(it)] ].toList } - + def static List> getRouteAndKm(Signal signal) { - val result = [Punkt_Objekt_Strecke_AttributeGroup point| + val result = [ Punkt_Objekt_Strecke_AttributeGroup point | return point?.IDStrecke?.value -> point?.streckeKm?.wert ] val pointRoutes = signal.punktObjektStrecke - val decisivePoint = pointRoutes.filter[kmMassgebend?.wert !== null].toList + val decisivePoint = pointRoutes.filter[kmMassgebend?.wert !== null]. + toList if (decisivePoint.isNullOrEmpty) { return pointRoutes.map[result.apply(it)] } - + return decisivePoint.map[result.apply(it)] } }