// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.JunctionChecker.connectedness;
import java.util.Vector;
import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.LeadsTo;
/**
* Diese Klasse versiegelt einen Digraphen, also die Enden eines outgoingChannels außerhalb einer Boundingbox werden mit dem Anfang eines bel. incomingChannels außerhalb der Boundigbox verbunden unbd umgekehrt
* @author joerg
*/
public class DiGraphSealer {
// vorsichtshalber auf einen hohen negativen Wert gesetzt. besser
// automatisch setzen!
// TODO: NewID automatisch setzen
private int newID = 1000000;
private ChannelDiGraph digraph;
public DiGraphSealer(ChannelDiGraph digraph) {
this.digraph = digraph;
}
public DiGraphSealer(ChannelDiGraph digraph, int newID) {
this.digraph = digraph;
this.newID = newID;
}
/**
* versiegelt den vorher gesetzten DiGraphen
*/
public void sealingGraph() {
Vector<Integer> outgoingChannelIDs = new Vector<>();
Vector<Integer> incomingChannelIDs = new Vector<>();
for (int i = 0; i < digraph.numberOfChannels(); i++) {
if (digraph.isInBBox(digraph.getChannelAtPosition(i).getFromNode()) == false) {
incomingChannelIDs.add(i);
}
if (digraph.isInBBox(digraph.getChannelAtPosition(i).getToNode()) == false) {
outgoingChannelIDs.add(i);
}
}
Channel tempChannel;
LeadsTo tempLeadsTo;
for (int i = 0; i < outgoingChannelIDs.size(); i++) {
if (digraph.getChannelAtPosition(outgoingChannelIDs.get(i))
.getLeadsTo().size() == 0) {
tempChannel = new Channel(digraph.getChannelAtPosition(
outgoingChannelIDs.get(i)).getToNode(), digraph
.getChannelAtPosition(incomingChannelIDs.get(0))
.getFromNode());
//dem Channel auch den neuen Channel als Nachfolger übergeben!!!
//sonst gibts Probleme beim JunctionCheck
tempLeadsTo = new LeadsTo(digraph
.getChannelAtPosition(outgoingChannelIDs.get(i)),
tempChannel);
digraph.getChannelAtPosition(outgoingChannelIDs.get(i))
.addLeadsTo(tempLeadsTo);
digraph.addLeadsTo(tempLeadsTo);
tempLeadsTo = new LeadsTo(tempChannel, digraph
.getChannelAtPosition(incomingChannelIDs.get(0)));
tempChannel.addLeadsTo(tempLeadsTo);
digraph.addLeadsTo(tempLeadsTo);
tempChannel.addWay(digraph.getChannelAtPosition(
outgoingChannelIDs.get(i)).getWay());
tempChannel.setNewid(newID);
newID++;
digraph.addChannel(tempChannel);
}
}
for (int i = 0; i < incomingChannelIDs.size(); i++) {
if (digraph.getChannelAtPosition(incomingChannelIDs.get(i))
.getPredChannels().size() == 0) {
tempChannel = new Channel(digraph.getChannelAtPosition(
outgoingChannelIDs.get(0)).getToNode(), digraph
.getChannelAtPosition(incomingChannelIDs.get(i))
.getFromNode());
//dem Channel auch den neuen Channel als Nachfolger überegeben
// sonst gibt es Probleme beim JuncitonCheck
digraph
.getChannelAtPosition(incomingChannelIDs.get(i)).addPredChannel(tempChannel);
tempLeadsTo = new LeadsTo(tempChannel, digraph
.getChannelAtPosition(incomingChannelIDs.get(i)));
tempChannel.addLeadsTo(tempLeadsTo);
digraph.addLeadsTo(tempLeadsTo);
tempLeadsTo = new LeadsTo(digraph
.getChannelAtPosition(outgoingChannelIDs.get(0)),
tempChannel);
digraph.getChannelAtPosition(outgoingChannelIDs.get(0))
.addLeadsTo(tempLeadsTo);
digraph.addLeadsTo(tempLeadsTo);
tempChannel.addWay(digraph.getChannelAtPosition(
incomingChannelIDs.get(i)).getWay());
tempChannel.setNewid(newID);
newID++;
digraph.addChannel(tempChannel);
}
}
this.deleteDuplicateChannels();
}
/*
private void showLeadsTo() {
for (int i = 0; i < digraph.getChannels().size(); i++) {
log.debug("Untersuche CHannel: " + digraph.getChannelAtPosition(i).getNewid());
for (int j = 0; j < digraph.getChannelAtPosition(i).getLeadsTo().size(); j++) {
log.debug("LeadsTo: " + digraph.getChannelAtPosition(i).getLeadsTo().get(j).toString());
}
}
}*/
/**
* dirt'n'quick methode zum löschen doppelter channels TODO:
* versiegeln-methode überarbeiten
*TODO: benutze ich die überhaupt noch?
*/
private void deleteDuplicateChannels() {
for (int i = 0; i < digraph.getChannels().size(); i++) {
for (int j = i + 1; j < digraph.getChannels().size(); j++) {
if (digraph.getChannelAtPosition(i).getFromNode() == digraph
.getChannelAtPosition(j).getFromNode()
&& digraph.getChannelAtPosition(i).getToNode() == digraph
.getChannelAtPosition(j).getToNode()) {
digraph.removeChannel(digraph.getChannelAtPosition(j));
}
}
}
}
/**
* setzt Wert für IDs für neu angelegte Ways
*/
public void setNewID(int newID) {
this.newID = newID;
}
/**
* @uml.property name="newID"
*/
public int getNewID() {
return newID;
}
public ChannelDiGraph getDiGraph() {
return digraph;
}
}