Commit 6e2ce57a authored by Christian Hoesel's avatar Christian Hoesel
Browse files

Erweiterung des NetzCaches um Gesamtstrassen

parent ed579ae4
Loading
Loading
Loading
Loading
+157 −174
Original line number Diff line number Diff line
@@ -9,19 +9,23 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.bitctrl.util.monitor.IMonitor;
import com.bitctrl.util.monitor.SubMonitor;

import de.bsvrz.dav.daf.main.config.DataModel;
import de.bsvrz.dav.daf.main.config.SystemObject;
import de.bsvrz.sys.funclib.bitctrl.modell.ObjektFactory;
import de.bsvrz.sys.funclib.bitctrl.modell.SystemObjekt;
import de.bsvrz.sys.funclib.bitctrl.modell.tmkexlmstglobal.attribute.AttRdsTMCRichtung;
import de.bsvrz.sys.funclib.bitctrl.modell.tmtmcglobal.attribute.AttTmcRichtung;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.konfigurationsdaten.KdAeusseresStrassenSegment;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.konfigurationsdaten.KdGesamtStrasse;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.konfigurationsdaten.KdStrasse.Daten;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.konfigurationsdaten.KdStrassenSegment;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.objekte.AeusseresStrassenSegment;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.objekte.GesamtStrasse;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.objekte.InneresStrassenSegment;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.objekte.Netz;
import de.bsvrz.sys.funclib.bitctrl.modell.tmverkehrglobal.objekte.NetzBestandTeil;
@@ -51,6 +55,8 @@ public class NetzCache extends AbstractCache {
	private Map<Strasse, List<StrassenSegment>> s2ss;
	private Map<StrassenSegment, Strasse> ss2s;

	private Set<GesamtStrasse> gesamtstrassen;

	// StraßenSegment <-> StraßenTeilSegment
	// private Map<StrassenSegment, List<StrassenTeilSegment>> ss2sts;
	// private Map<StrassenTeilSegment, List<StrassenSegment>> sts2ss;
@@ -66,45 +72,38 @@ public class NetzCache extends AbstractCache {
	private HashMap<Strasse, String> strassenNummernMap;

	/**
	 * Map, welche den Namen des Von-Knotens zu einer Straße in positiver
	 * Richtung speichert. Bei negativer Richtung ist dann der Von-Knoten der
	 * Nach-Knoten.
	 * Map, welche den Namen des Von-Knotens zu einer Straße in positiver Richtung
	 * speichert. Bei negativer Richtung ist dann der Von-Knoten der Nach-Knoten.
	 */
	private Map<Strasse, String> vonStrassenKnotenMap;

	/**
	 * Map, welche den Namen des Nach-Knotens zu einer Straße in positiver
	 * Richtung speichert. Bei negativer Richtung ist dann der Nach-Knoten der
	 * Von-Knoten.
	 * Map, welche den Namen des Nach-Knotens zu einer Straße in positiver Richtung
	 * speichert. Bei negativer Richtung ist dann der Nach-Knoten der Von-Knoten.
	 */
	private Map<Strasse, String> nachStrassenKnotenMap;

	/**
	 * Initialisert den Netzcache, in dem alle notwendige Daten aus der
	 * Konfiguration gelesen und zwischengespeichert werden. Insbesondere werden
	 * notwendige Rückwärtreferenzen aufgelöst, die in der Konfiguration so
	 * nicht gesichert werden.
	 * notwendige Rückwärtreferenzen aufgelöst, die in der Konfiguration so nicht
	 * gesichert werden.
	 *
	 * Nach Aufruf der Methode ist der Cache <strong>nicht</strong>
	 * initialisert. Stattdessen wird ein Job angestoßen der diese Aufgabe
	 * übernimmt.
	 * Nach Aufruf der Methode ist der Cache <strong>nicht</strong> initialisert.
	 * Stattdessen wird ein Job angestoßen der diese Aufgabe übernimmt.
	 *
	 * @param moc
	 *            der Cache, von welchem dieser Cache abhängig ist
	 * @param verbindungsCache
	 *            der verwendete Verbindungscache
	 * @param moc              der Cache, von welchem dieser Cache abhängig ist
	 * @param verbindungsCache der verwendete Verbindungscache
	 *
	 * @see AbstractCache#isInitialisiert()
	 * @see #addPropertyChangeListener(PropertyChangeListener)
	 * @see #PROP_STATE
	 */
	public NetzCache(final ModellObjektCache moc,
			final AbstractDavVerbindungsCache verbindungsCache) {
	public NetzCache(final ModellObjektCache moc, final AbstractDavVerbindungsCache verbindungsCache) {
		super(moc, verbindungsCache);
	}

	protected void preInit(final ModellObjektCache moc,
			final AbstractDavVerbindungsCache verbindungsCache) {
	protected void preInit(final ModellObjektCache moc, final AbstractDavVerbindungsCache verbindungsCache) {
		this.moc = moc;
		this.verbindungsCache = verbindungsCache;
	}
@@ -122,6 +121,7 @@ public class NetzCache extends AbstractCache {

		s2ss = new HashMap<>();
		ss2s = new HashMap<>();
		gesamtstrassen = new HashSet<>();

		// ss2sts = new HashMap<StrassenSegment, List<StrassenTeilSegment>>();
		// sts2ss = new HashMap<StrassenTeilSegment, List<StrassenSegment>>();
@@ -145,15 +145,12 @@ public class NetzCache extends AbstractCache {

		// (2) Lade Konfigurationsdaten "AeussereStrassenSegment"
		subMonitor.subTask("Lade StrassenSegment-Daten der Netzbestandteile");
		final DataModel dataModel = verbindungsCache.getObjektFactory().getDav()
				.getDataModel();
		final DataModel dataModel = verbindungsCache.getObjektFactory().getDav().getDataModel();
		if (isBenutzeBlockAbruf()) {
			dataModel.getConfigurationData(aessSO,
					dataModel.getAttributeGroup(KdStrassenSegment.PID));
			dataModel.getConfigurationData(aessSO, dataModel.getAttributeGroup(KdStrassenSegment.PID));
		} else {
			for (final SystemObject so : aessSO) {
				so.getConfigurationData(
						dataModel.getAttributeGroup(KdStrassenSegment.PID));
				so.getConfigurationData(dataModel.getAttributeGroup(KdStrassenSegment.PID));
			}
		}
		subMonitor.worked(250);
@@ -163,15 +160,12 @@ public class NetzCache extends AbstractCache {
		}

		// (3) Lade Daten
		subMonitor.subTask(
				"Lade AeussereStrassenSegment-Daten der Netzbestandteile");
		subMonitor.subTask("Lade AeussereStrassenSegment-Daten der Netzbestandteile");
		if (isBenutzeBlockAbruf()) {
			dataModel.getConfigurationData(aessSO, dataModel
					.getAttributeGroup(KdAeusseresStrassenSegment.PID));
			dataModel.getConfigurationData(aessSO, dataModel.getAttributeGroup(KdAeusseresStrassenSegment.PID));
		} else {
			for (final SystemObject so : aessSO) {
				so.getConfigurationData(dataModel
						.getAttributeGroup(KdAeusseresStrassenSegment.PID));
				so.getConfigurationData(dataModel.getAttributeGroup(KdAeusseresStrassenSegment.PID));
			}

		}
@@ -190,11 +184,8 @@ public class NetzCache extends AbstractCache {
			int i = 1;
			for (final AeusseresStrassenSegment segment : aess) {

				subMonitor2
						.subTask(new StringBuffer("Analysiere Netzbestandteil ")
								.append(i).append(" von ")
								.append(anzahlSegmente).append(": ")
								.append(segment.getName()).toString());
				subMonitor2.subTask(new StringBuffer("Analysiere Netzbestandteil ").append(i).append(" von ")
						.append(anzahlSegmente).append(": ").append(segment.getName()).toString());

				cacheAeusseresStrassenSegment(segment);
				subMonitor2.worked(1);
@@ -206,41 +197,56 @@ public class NetzCache extends AbstractCache {
			}
		}

		ObjektFactory objektFactory = verbindungsCache.getObjektFactory();
		@SuppressWarnings("unchecked")
		List<GesamtStrasse> gesamtStrassen = (List<GesamtStrasse>) objektFactory
				.bestimmeModellobjekte(GesamtStrasse.PID);
		objektFactory.getDaten(gesamtStrassen, KdGesamtStrasse.class);

		Set<Strasse> alleStrassenDesNetzes = getStrassen();

		for (GesamtStrasse g : gesamtStrassen) {
			KdGesamtStrasse.Daten datum = g.getKdGesamtStrasse().getDatum();
			if (datum != null) {
				boolean enthalten = datum.getStrasseFR1().stream().anyMatch(s -> alleStrassenDesNetzes.contains(s));
				if (!enthalten) {
					enthalten = datum.getStrasseFR2().stream().anyMatch(s -> alleStrassenDesNetzes.contains(s));
				}

				if (enthalten) {
					gesamtStrassen.add(g);
				}
			}
		}

		// TODO Straßensegmente der Straßen sortieren
		// TODO Straßenteilsegmente der Straßensegmente sortieren

		Debug.getLogger()
				.info("Benötigte Zeit zum Initialisieren des BitCtrl Netz-Caches: "
		Debug.getLogger().info("Benötigte Zeit zum Initialisieren des BitCtrl Netz-Caches: "
				+ (System.currentTimeMillis() - start) + " ms");

		return true;
	}

	/**
	 * Ermittelt rekursiv sämtliche äußeren Straßensegmente eines Netzes sowie
	 * deren Teilnetze.
	 * Ermittelt rekursiv sämtliche äußeren Straßensegmente eines Netzes sowie deren
	 * Teilnetze.
	 *
	 * @param netz
	 *            das Netz
	 * @param besuchteNetze
	 *            die bereits besuchte Netze, verhindert Endlosschleifen
	 * @param netz          das Netz
	 * @param besuchteNetze die bereits besuchte Netze, verhindert Endlosschleifen
	 */
	private void ermittelAeussereStrassenSegmente(final Netz netz,
			final ArrayList<Netz> besuchteNetze) {
	private void ermittelAeussereStrassenSegmente(final Netz netz, final ArrayList<Netz> besuchteNetze) {

		if (besuchteNetze.contains(netz)) {
			return;
		}
		besuchteNetze.add(netz);

		for (final NetzBestandTeil netzBestandTeil : netz
				.getNetzBestandTeile()) {
			if (netzBestandTeil instanceof AeusseresStrassenSegment
					&& !aess.contains(netzBestandTeil)) {
		for (final NetzBestandTeil netzBestandTeil : netz.getNetzBestandTeile()) {
			if (netzBestandTeil instanceof AeusseresStrassenSegment && !aess.contains(netzBestandTeil)) {
				aess.add((AeusseresStrassenSegment) netzBestandTeil);
			} else if (netzBestandTeil instanceof Netz) {
				ermittelAeussereStrassenSegmente((Netz) netzBestandTeil,
						besuchteNetze);
				ermittelAeussereStrassenSegmente((Netz) netzBestandTeil, besuchteNetze);
			}
		}
	}
@@ -248,16 +254,13 @@ public class NetzCache extends AbstractCache {
	/**
	 * Cacht die Daten des Start- und Endknoten eines äußeren Straßensegments.
	 *
	 * @param segment
	 *            das äußere Straßensegment
	 * @param segment das äußere Straßensegment
	 */
	protected void cacheAeusseresStrassenSegment(
			final AeusseresStrassenSegment segment) {
	protected void cacheAeusseresStrassenSegment(final AeusseresStrassenSegment segment) {
		// cacheStrassenTeilSegmente(aess);
		cacheStrasse(segment);

		StrassenKnoten sk = segment.getKdAeusseresStrassenSegment().getDatum()
				.getVonKnoten();
		StrassenKnoten sk = segment.getKdAeusseresStrassenSegment().getDatum().getVonKnoten();
		if (sk != null) {
			cacheInneresStrasseSegment(sk);
		}
@@ -269,12 +272,10 @@ public class NetzCache extends AbstractCache {
	}

	/**
	 * Erzeugt die Referenzen StraßenKnoten &lt;-&gt; InneresStraßenSegment.
	 * Cacht auch die Straße und die Straßenteilsegmente der inneren
	 * Straßensegmente.
	 * Erzeugt die Referenzen StraßenKnoten &lt;-&gt; InneresStraßenSegment. Cacht
	 * auch die Straße und die Straßenteilsegmente der inneren Straßensegmente.
	 *
	 * @param sk
	 *            der zu cachende Straßenknoten
	 * @param sk der zu cachende Straßenknoten
	 */
	protected void cacheInneresStrasseSegment(final StrassenKnoten sk) {
		if (sk2iss.containsKey(sk)) {
@@ -283,8 +284,7 @@ public class NetzCache extends AbstractCache {
		}

		final Set<InneresStrassenSegment> mengeISS = new HashSet<>();
		for (final InneresStrassenSegment iss : sk
				.getInnereStrassenSegmente()) {
		for (final InneresStrassenSegment iss : sk.getInnereStrassenSegmente()) {
			iss2sk.put(iss, sk);
			mengeISS.add(iss);

@@ -297,8 +297,7 @@ public class NetzCache extends AbstractCache {
	/**
	 * Erzeugt die Referenzen StraßenSegment &lt;-&gt; Straßen.
	 *
	 * @param ss
	 *            das Straßensegment
	 * @param ss das Straßensegment
	 */
	protected void cacheStrasse(final StrassenSegment ss) {
		if (ss2s.containsKey(ss)) {
@@ -322,8 +321,7 @@ public class NetzCache extends AbstractCache {
			s2ss.get(s).add(ss);

			// Parse den Straßennamen und fülle die entsprechenden Maps
			if (s.getKdStrasse() == null
					|| s.getKdStrasse().getDatum() == null) {
			if (s.getKdStrasse() == null || s.getKdStrasse().getDatum() == null) {
				return;
			}
			final Daten datum = s.getKdStrasse().getDatum();
@@ -331,31 +329,28 @@ public class NetzCache extends AbstractCache {
			if (strassenNamenMap.get(name) == null) {
				strassenNamenMap.put(name, s);
			}
			final String nummer = datum.getTyp().toString().substring(0, 1)
					+ datum.getNummer().getValue();
			final String nummer = datum.getTyp().toString().substring(0, 1) + datum.getNummer().getValue();
			if (strassenNummernMap.get(s) == null) {
				strassenNummernMap.put(s, nummer);
			}
			if (name.contains(" von ") && name.contains(" nach ")) {
				if (vonStrassenKnotenMap.get(s) == null) {
					final String vonStrassenKnoten = name.substring(
							name.indexOf(" von ") + 5, name.indexOf(" nach "));
					final String vonStrassenKnoten = name.substring(name.indexOf(" von ") + 5, name.indexOf(" nach "));
					vonStrassenKnotenMap.put(s, vonStrassenKnoten);
				}
				if (nachStrassenKnotenMap.get(s) == null) {
					final String nachStrassenKnoten = name
							.substring(name.indexOf(" nach ") + 6);
					final String nachStrassenKnoten = name.substring(name.indexOf(" nach ") + 6);
					nachStrassenKnotenMap.put(s, nachStrassenKnoten);
				}
			}

		}
	}

	/**
	 * Erzeugt die Referenzen StraßenSegment <-> StraßenTeilSegment.
	 *
	 * @param ss
	 *            das zu cachende Straßensegment
	 * @param ss das zu cachende Straßensegment
	 */
	// protected void cacheStrassenTeilSegmente(final StrassenSegment ss) {
	// if (ss2sts.containsKey(ss)) {
@@ -388,6 +383,35 @@ public class NetzCache extends AbstractCache {
		return verkehrsModellNetz;
	}

	/**
	 * Gibt die {@link GesamtStrasse}s im Netz zurück.
	 *
	 * @return die vorhandenen {@link GesamtStrasse}n.
	 */
	public Set<GesamtStrasse> getGesamtStrassen() {
		ensureInit();
		return Collections.unmodifiableSet(gesamtstrassen);
	}

	/**
	 * Liefert die {@link Strasse}n einer {@link GesamtStrasse} in der gefragten
	 * Richtung. Es werden nur {@link Strasse}n ermittelt, die auch im Netz sind.
	 * 
	 */
	public Set<Strasse> getStrassen(final GesamtStrasse gesamtStraße, final AttTmcRichtung richtung) {

		Set<Strasse> strassen = getStrassen();
		KdGesamtStrasse.Daten datum = gesamtStraße.getKdGesamtStrasse().getDatum();
		if (datum != null) {
			if (AttTmcRichtung.ZUSTAND_1_POSITIV.equals(richtung)) {
				return datum.getStrasseFR1().stream().filter(s -> strassen.contains(s)).collect(Collectors.toSet());
			} else if (AttTmcRichtung.ZUSTAND_1N_NEGATIV.equals(richtung)) {
				return datum.getStrasseFR2().stream().filter(s -> strassen.contains(s)).collect(Collectors.toSet());
			}
		}
		return Collections.unmodifiableSet(Collections.emptySet());
	}

	/**
	 * Gibt die Straßen im Netz zurück.
	 *
@@ -439,11 +463,9 @@ public class NetzCache extends AbstractCache {
	}

	/**
	 * Gibt zu einem inneren Straßensegment den dazugehörigen Straßenknoten
	 * zurück.
	 * Gibt zu einem inneren Straßensegment den dazugehörigen Straßenknoten zurück.
	 *
	 * @param iss
	 *            ein inneres Straßensegment.
	 * @param iss ein inneres Straßensegment.
	 * @return der dazugehörige Straßenknoten oder <code>null</code>, wenn das
	 *         innere Straßensegment unbekannt ist.
	 */
@@ -455,13 +477,11 @@ public class NetzCache extends AbstractCache {
	/**
	 * Gibt die inneren Straßensegmente eines Straßenknotens zurück.
	 *
	 * @param sk
	 *            ein Straßenknoten.
	 * @param sk ein Straßenknoten.
	 * @return die inneren Straßensegmente oder eine leere Liste, wenn der
	 *         Straßenknoten keine Straßensegmente hat oder unbekannt ist.
	 */
	public Set<InneresStrassenSegment> getInneresStrassenSegmente(
			final StrassenKnoten sk) {
	public Set<InneresStrassenSegment> getInneresStrassenSegmente(final StrassenKnoten sk) {
		ensureInit();
		return sk2iss.get(sk);
	}
@@ -469,8 +489,7 @@ public class NetzCache extends AbstractCache {
	/**
	 * Gibt die Straßensegmente einer Straße zurück.
	 *
	 * @param strasse
	 *            eine Straße.
	 * @param strasse eine Straße.
	 * @return die Straßensegmente der Strasse.
	 */
	public List<StrassenSegment> getStrassenSegmente(final Strasse strasse) {
@@ -481,8 +500,7 @@ public class NetzCache extends AbstractCache {
	/**
	 * Gibt die Straße zu einem Straßensegment zurück.
	 *
	 * @param ss
	 *            ein Straßensegment.
	 * @param ss ein Straßensegment.
	 * @return die Straße auf dem das Straßensegment liegt.
	 */
	public Strasse getStrasse(final StrassenSegment ss) {
@@ -491,11 +509,10 @@ public class NetzCache extends AbstractCache {
	}

	/**
	 * Gibt zu einem Straßenteilsegment das Straßensegment (inneres oder
	 * äußeres) zurück.
	 * Gibt zu einem Straßenteilsegment das Straßensegment (inneres oder äußeres)
	 * zurück.
	 *
	 * @param sts
	 *            ein Straßenteilsegment.
	 * @param sts ein Straßenteilsegment.
	 * @return das dazugehörige innere oder äußere Straßensegment.
	 */
	// public List<StrassenSegment> getStrassenSegment(
@@ -508,8 +525,7 @@ public class NetzCache extends AbstractCache {
	 * Gibt zu einem Straßensegment (inneres oder äußeres) die dazugehörigen
	 * Straßenteilsegmente zurück.
	 *
	 * @param ss
	 *            ein inneres oder äußeres Straßensegment.
	 * @param ss ein inneres oder äußeres Straßensegment.
	 * @return die dazugehörigen Straßenteilsegmente.
	 */
	// public List<StrassenTeilSegment> getStrassenTeilSegmente(
@@ -521,8 +537,7 @@ public class NetzCache extends AbstractCache {
	/**
	 * Liefert die zu einem gegebenen Straßennamen gehörige Straße zurück.
	 *
	 * @param strassenName
	 *            der Straßenname, darf nicht <code>null</code> sein
	 * @param strassenName der Straßenname, darf nicht <code>null</code> sein
	 *
	 * @return die zu einem gegebenen Straßennamen gehörige Straße, kann
	 *         <code>null</code> sein
@@ -536,8 +551,7 @@ public class NetzCache extends AbstractCache {
	/**
	 * Liefert die Straßennummer einer gegebenen Straße zurück.
	 *
	 * @param strasse
	 *            die Straße, darf nicht <code>null</code> sein
	 * @param strasse die Straße, darf nicht <code>null</code> sein
	 *
	 * @return die Straßennummer einer gegebenen Straße
	 */
@@ -549,33 +563,28 @@ public class NetzCache extends AbstractCache {

	/**
	 * Liefert den Straßennamen zu einer gegebenen Straßennummer und Richtung
	 * zurück. Sollte kein Straßenname für die gegebene Straßennummer
	 * existieren, wird die Straßennummer zurückgegeben.
	 * zurück. Sollte kein Straßenname für die gegebene Straßennummer existieren,
	 * wird die Straßennummer zurückgegeben.
	 *
	 * @param strasse
	 *            die Straße, darf nicht <code>null</code> sein
	 * @param richtung
	 *            die Richtung, darf nicht <code>null</code> sein
	 * @param strasse  die Straße, darf nicht <code>null</code> sein
	 * @param richtung die Richtung, darf nicht <code>null</code> sein
	 *
	 * @return Straßennamen zu einer gegebenen Straßennummer und Richtungr,
	 *         niemals <code>null</code>
	 * @return Straßennamen zu einer gegebenen Straßennummer und Richtungr, niemals
	 *         <code>null</code>
	 */
	public String getStrassenName(final Strasse strasse,
			final AttRdsTMCRichtung richtung) {
	public String getStrassenName(final Strasse strasse, final AttRdsTMCRichtung richtung) {
		ensureInit();
		assert strasse != null;
		assert richtung != null;
		if (richtung.getValue() == AttRdsTMCRichtung.ZUSTAND_0_POSITIV
				.getValue()) {
		if (richtung.getValue() == AttRdsTMCRichtung.ZUSTAND_0_POSITIV.getValue()) {
			return strasse.getName();
		}
		final String nummer = getStrassenNummer(strasse);
		final String von = getVonStrassenKnoten(strasse, richtung);
		final String nach = getNachStrassenKnoten(strasse, richtung);
		if (nummer != null && !"".equals(nummer) && von != null
				&& !"".equals(von) && nach != null && !"".equals(nach)) {
			return new StringBuffer(nummer).append(" von ").append(von)
					.append(" nach ").append(nach).toString();
		if (nummer != null && !"".equals(nummer) && von != null && !"".equals(von) && nach != null
				&& !"".equals(nach)) {
			return new StringBuffer(nummer).append(" von ").append(von).append(" nach ").append(nach).toString();
		}
		return strasse.getName();
	}
@@ -583,48 +592,38 @@ public class NetzCache extends AbstractCache {
	/**
	 * Liefert den Straßennamen zu einer gegebenen Straße und Richtung zurück.
	 *
	 * @param strasse
	 *            die Straße, darf nicht <code>null</code> sein
	 * @param richtung
	 *            die Richtung, darf auch <code>null</code> sein
	 * @param strasse  die Straße, darf nicht <code>null</code> sein
	 * @param richtung die Richtung, darf auch <code>null</code> sein
	 *
	 * @return Straßennamen zu einer gegebenen Straßennummer und Richtung,
	 *         niemals <code>null</code>
	 * @return Straßennamen zu einer gegebenen Straßennummer und Richtung, niemals
	 *         <code>null</code>
	 */
	public String getStrassenName(final Strasse strasse,
			final AttTmcRichtung richtung) {
	public String getStrassenName(final Strasse strasse, final AttTmcRichtung richtung) {
		ensureInit();
		assert strasse != null;
		if (AttTmcRichtung.ZUSTAND_1N_NEGATIV.equals(richtung)) {
			return getStrassenName(strasse,
					AttRdsTMCRichtung.ZUSTAND_1_NEGATIV);
			return getStrassenName(strasse, AttRdsTMCRichtung.ZUSTAND_1_NEGATIV);
		}
		if (AttTmcRichtung.ZUSTAND_1_POSITIV.equals(richtung)) {
			return getStrassenName(strasse,
					AttRdsTMCRichtung.ZUSTAND_0_POSITIV);
			return getStrassenName(strasse, AttRdsTMCRichtung.ZUSTAND_0_POSITIV);
		}
		return strasse.getName();
	}

	/**
	 * Liefert den Namen des Von-Straßenknotens zu einer gegebenen Straße
	 * zurück.
	 * Liefert den Namen des Von-Straßenknotens zu einer gegebenen Straße zurück.
	 *
	 * @param strasse
	 *            die Straße, darf nicht <code>null</code> sein
	 * @param richtung
	 *            die Straßenrichtung, darf nicht <code>null</code> sein
	 * @param strasse  die Straße, darf nicht <code>null</code> sein
	 * @param richtung die Straßenrichtung, darf nicht <code>null</code> sein
	 *
	 * @return Von-Straßenknoten zu einer gegebenen Straßennummer, kann
	 *         <code>null</code> sein
	 */
	public String getVonStrassenKnoten(final Strasse strasse,
			final AttRdsTMCRichtung richtung) {
	public String getVonStrassenKnoten(final Strasse strasse, final AttRdsTMCRichtung richtung) {
		ensureInit();
		assert strasse != null;
		assert richtung != null;
		final String vonStrassenKnoten = (richtung
				.getValue() == AttRdsTMCRichtung.ZUSTAND_0_POSITIV.getValue())
		final String vonStrassenKnoten = (richtung.getValue() == AttRdsTMCRichtung.ZUSTAND_0_POSITIV.getValue())
				? vonStrassenKnotenMap.get(strasse)
				: nachStrassenKnotenMap.get(strasse);
		if (vonStrassenKnoten != null && !"".equals(vonStrassenKnoten)) {
@@ -634,44 +633,34 @@ public class NetzCache extends AbstractCache {
	}

	/**
	 * Liefert den Namen des Von-Straßenknotens zu einer gegebenen Straße
	 * zurück.
	 * Liefert den Namen des Von-Straßenknotens zu einer gegebenen Straße zurück.
	 *
	 * @param strasse
	 *            die Straße, darf nicht <code>null</code> sein
	 * @param richtung
	 *            die Straßenrichtung, darf nicht <code>null</code> sein
	 * @param strasse  die Straße, darf nicht <code>null</code> sein
	 * @param richtung die Straßenrichtung, darf nicht <code>null</code> sein
	 *
	 * @return Von-Straßenknoten zu einer gegebenen Straßennummer, kann
	 *         <code>null</code> sein
	 */
	public String getVonStrassenKnoten(final Strasse strasse,
			final AttTmcRichtung richtung) {
	public String getVonStrassenKnoten(final Strasse strasse, final AttTmcRichtung richtung) {
		return getVonStrassenKnoten(strasse,
				richtung == AttTmcRichtung.ZUSTAND_1_POSITIV
						? AttRdsTMCRichtung.ZUSTAND_0_POSITIV
				richtung == AttTmcRichtung.ZUSTAND_1_POSITIV ? AttRdsTMCRichtung.ZUSTAND_0_POSITIV
						: AttRdsTMCRichtung.ZUSTAND_1_NEGATIV);
	}

	/**
	 * Liefert den Namen des Nach-Straßenknotens zu einer gegebenen Straße
	 * zurück.
	 * Liefert den Namen des Nach-Straßenknotens zu einer gegebenen Straße zurück.
	 *
	 * @param strasse
	 *            die Straße, darf nicht <code>null</code> sein
	 * @param richtung
	 *            die Straßenrichtung, darf nicht <code>null</code> sein
	 * @param strasse  die Straße, darf nicht <code>null</code> sein
	 * @param richtung die Straßenrichtung, darf nicht <code>null</code> sein
	 *
	 * @return Nach-Straßenknoten zu einer gegebenen Straßennummer, kann
	 *         <code>null</code> sein
	 */
	public String getNachStrassenKnoten(final Strasse strasse,
			final AttRdsTMCRichtung richtung) {
	public String getNachStrassenKnoten(final Strasse strasse, final AttRdsTMCRichtung richtung) {
		ensureInit();
		assert strasse != null;
		assert richtung != null;
		final String nachStrassenKnoten = (richtung
				.getValue() == AttRdsTMCRichtung.ZUSTAND_0_POSITIV.getValue())
		final String nachStrassenKnoten = (richtung.getValue() == AttRdsTMCRichtung.ZUSTAND_0_POSITIV.getValue())
				? nachStrassenKnotenMap.get(strasse)
				: vonStrassenKnotenMap.get(strasse);
		if (nachStrassenKnoten != null && !"".equals(nachStrassenKnoten)) {
@@ -681,27 +670,21 @@ public class NetzCache extends AbstractCache {
	}

	/**
	 * Liefert den Namen des Nach-Straßenknotens zu einer gegebenen Straße
	 * zurück.
	 * Liefert den Namen des Nach-Straßenknotens zu einer gegebenen Straße zurück.
	 *
	 * @param strasse
	 *            die Straße, darf nicht <code>null</code> sein
	 * @param richtung
	 *            die Straßenrichtung, darf nicht <code>null</code> sein
	 * @param strasse  die Straße, darf nicht <code>null</code> sein
	 * @param richtung die Straßenrichtung, darf nicht <code>null</code> sein
	 *
	 * @return Nach-Straßenknoten zu einer gegebenen Straßennummer, kann
	 *         <code>null</code> sein
	 */
	public String getNachStrassenKnoten(final Strasse strasse,
			final AttTmcRichtung richtung) {
	public String getNachStrassenKnoten(final Strasse strasse, final AttTmcRichtung richtung) {
		return getNachStrassenKnoten(strasse,
				richtung == AttTmcRichtung.ZUSTAND_1_POSITIV
						? AttRdsTMCRichtung.ZUSTAND_0_POSITIV
				richtung == AttTmcRichtung.ZUSTAND_1_POSITIV ? AttRdsTMCRichtung.ZUSTAND_0_POSITIV
						: AttRdsTMCRichtung.ZUSTAND_1_NEGATIV);
	}

	private Collection<SystemObject> resolveSystemObjects(
			final Collection<? extends SystemObjekt> objekte) {
	private Collection<SystemObject> resolveSystemObjects(final Collection<? extends SystemObjekt> objekte) {
		final ArrayList<SystemObject> objects = new ArrayList<>(objekte.size());
		for (final SystemObjekt objekt : objekte) {
			objects.add(objekt.getSystemObject());