// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.JunctionChecker.converting;
import java.util.ArrayList;
import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.LeadsTo;
/**
* löscht Pseudochannels, also 2 Channels, die ein Segment repräsentieren, werden zu einem Channel zusammnegefaßt. Dabei übernimmt der 1. Channel den ToNode des Nachfrolger sowie seine LeadsTo-Relationen. Der 2. CHannel wird anschließend gelöscht. Dies iterativ bis das betrachtete Segment nur noch aus einem Channel besteht
* @author joerg
*/
public class PseudoChannelRemover {
private final ChannelDiGraph digraph;
//private final ArrayList<Channel> pseudochannels = new ArrayList<Channel>();
private Channel succChannel;
private Channel tempToChannel;
private LeadsTo tempLeadsTo;
public PseudoChannelRemover(ChannelDiGraph digraph) {
this.digraph = digraph;
}
private void mergeChannel(Channel tempchannel) {
succChannel = tempchannel.getLeadsTo().get(0).getToChannel();
tempchannel.setToNode(succChannel.getToNode());
//log.trace("---Folgender Channel ist überflüssig: " + succChannel.getNewid() + "---");
//log.trace("... und wird durch diesen ersetzt: " + tempchannel.getNewid());
//VorgängerChannel der nachfolgenden Channels des zu löschenden, überflüssigen Channels neu setzen
for (int i = 0; i < succChannel.getLeadsTo().size(); i++) {
for (int j = 0; j < succChannel.getLeadsTo().get(i).getToChannel().getPredChannels().size(); j++) {
if (succChannel.getLeadsTo().get(i).getToChannel().getPredChannels().get(j).getNewid() == succChannel.getNewid()) {
succChannel.getLeadsTo().get(i).getToChannel().getPredChannels().remove(j);
succChannel.getLeadsTo().get(i).getToChannel().addPredChannel(tempchannel);
}
}
}
//LeadsTo des zu ersetzenden Channels für den neuen Channel neu erzeugen
tempchannel.removeLeadsTo();
for (int i = 0; i < succChannel.getLeadsTo().size(); i++) {
tempToChannel = succChannel.getLeadsTo().get(i).getToChannel();
//log.trace("tempToChannel: " + tempToChannel.toString());
tempLeadsTo = new LeadsTo(tempchannel, tempToChannel);
//log.trace(i + ". Durchlauf: Füge ledasTo hinzu: " + tempLeadsTo.toString());
digraph.addLeadsTo(tempLeadsTo);
}
//TODO: quick'n'dirty
ArrayList<LeadsTo> tls = succChannel.getLeadsTo();
for (int i = 0; i < tls.size(); i++) {
digraph.removeLeadsTo(tls.get(i));
}
digraph.removeChannel(succChannel);
//pseudochannels.add(tempchannel.getSuccChannels().get(0));
}
public void removePseudoChannels() {
Channel tempChannel;
for (int i = 0; i < digraph.getChannels().size(); i++) {
tempChannel = digraph.getChannelAtPosition(i);
while (digraph.isInBBox(tempChannel.getToNode())
&& (tempChannel.getLeadsTo().size() == 1)
&& (tempChannel.getLeadsTo().get(0).getToChannel().getPredChannels().size() <= 1)
&& (tempChannel.getBackChannelID() != tempChannel.getLeadsTo().get(0).getToChannel().getNewid())) {
// dies if-abfrage verhindert eine endlosschleife, wenn der
// channel ein kreisverkehr istjava
if (tempChannel.getLeadsTo().get(0).getToChannel().equals(tempChannel)) {
break;
} else {
mergeChannel(tempChannel);
}
}
}
}
}