// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
/**
* @author joerg
*/
public class ChannelDiGraph extends Graph {
private ArrayList<Channel> channels = new ArrayList<>();
private final ArrayList<LeadsTo> leadsTos = new ArrayList<>();
private final HashSet<Channel> selectedChannels = new HashSet<>();
private HashSet<Channel> junctioncandidate = new HashSet<>();
public void setChannels(ArrayList<Channel> channels) {
this.channels = channels;
}
/*
* gibt den Channel mit dem übergebendem OSMNode als FromNode zurück
*/
public Channel getChannelWithFromNode(OSMNode node) {
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).getFromNode() == node) {
return channels.get(i);
}
}
return null;
}
/**
* gibt alle CHannels des Digraphen zurück
* @return Channels des Digraphen
*/
public ArrayList<Channel> getChannels() {
return channels;
}
/**
* löscht den übergebenden Channel im Digraphen
*/
public void removeChannel(Channel channel) {
channels.remove(channel);
}
/**
* fügt einen Channel des ChannelDigraphen hinzu
*
* @param channel
* hinzuzufügender Channel
*/
public void addChannel(Channel channel) {
this.channels.add(channel);
}
/**
* Anzahl der innerhalb des DiGraphen gespeicherten Channels
*
* @return Anzahl der Channels
*/
public int numberOfChannels() {
return channels.size();
}
/**
* gibt Channel i an der Position i in der ArrayList zurück
*
* @param i
* Position innerhalb der ArrayList
* @return gewünschter Channel
*/
public Channel getChannelAtPosition(int i) {
return channels.get(i);
}
/**
* gibt den Channel mit der gesuchten ID zurück
* @param id ID des Channels
* @return der gesuchte Channel, wenn nicht vorhanden null
*/
public Channel getChannelWithID(int id) {
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).getNewid() == id) {
return channels.get(i);
}
}
return null;
}
/**
* gibt alle From und To OSMNodes eines Graphen zurück (nicht die
* ZWischenknoten)
*
* @return alle From und To Nodes aller Channels des Digraphen
*/
public OSMNode[] getAllOSMNodes() {
HashMap<Long, OSMNode> nodes = new HashMap<>();
for (int i = 0; i < channels.size(); i++) {
if (!nodes.containsKey(channels.get(i).getFromNode().getId())) {
nodes.put(channels.get(i).getFromNode().getId(), channels
.get(i).getFromNode());
}
if (!nodes.containsKey(channels.get(i).getToNode().getId())) {
nodes.put(channels.get(i).getToNode().getId(), channels.get(i)
.getToNode());
}
}
OSMNode[] nodearray = new OSMNode[nodes.size()];
return nodes.values().toArray(nodearray);
}
public ArrayList<LeadsTo> getLeadsTo() {
return leadsTos;
}
/*
public void setLeadsTo(ArrayList<LeadsTo> leadsTo) {
this.leadsTos = leadsTo;
}*/
public void setForwardEdge(Channel fromChannel, Channel toChannel) {
for (int i = 0; i < leadsTos.size(); i++) {
if (leadsTos.get(i).getFromChannel() == fromChannel) {
if (leadsTos.get(i).getToChannel() == toChannel)
leadsTos.get(i).setForwardEdge(true);
}
}
}
/**
* fügt eine leadsto-relation dem digraphen und dem entsprechendem Channel hinzu
*/
public void addLeadsTo(LeadsTo leadsTo) {
leadsTos.add(leadsTo);
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).getNewid() == leadsTo.getFromChannel().getNewid()) {
channels.get(i).addLeadsTo(leadsTo);
return;
}
}
}
public void removeLeadsTo(LeadsTo leadsTo) {
leadsTos.remove(leadsTo);
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).equals(leadsTo.getFromChannel())) {
channels.get(i).removeLeadsTo(leadsTo);
return;
}
}
}
/**
* gibt den Channel zurück, der paßt. Sind Channel doppelt vorhanden, wird
* nur der erste passende zurückgegeben!
*/
public LeadsTo getLeadsTo(Channel fromChannel, Channel toChannel) {
for (int i = 0; i < leadsTos.size(); i++) {
if (leadsTos.get(i).getFromChannel().getNewid() == fromChannel.getNewid()) {
//log.trace("FromChannel mit ID gefunden: " + fromChannel.getNewid());
if (leadsTos.get(i).getToChannel().getNewid() == toChannel.getNewid()) {
//log.trace("Leads To gefunden: " + leadsTos.get(i).toString());
return leadsTos.get(i);
}
}
}
return null;
}
/**
* gibt alle Channels zurück, die von diesen OSM-Knoten abgehen/hingehen
*/
public ArrayList<Channel> getChannelsTouchingOSMNodes(ArrayList<OSMNode> nodes) {
ArrayList<Channel> touchingChannel = new ArrayList<>();
for (int i = 0; i < nodes.size(); i++) {
for (int j = 0; j < channels.size(); j++) {
if (channels.get(j).getFromNode().getId() == nodes.get(i).getId()) {
if (!touchingChannel.contains(channels.get(j))) {
touchingChannel.add(channels.get(j));
}
} else if (channels.get(j).getToNode().getId() == nodes.get(i).getId()) {
if (!touchingChannel.contains(channels.get(j))) {
touchingChannel.add(channels.get(j));
}
}
}
}
return touchingChannel;
}
public ArrayList<Channel> getChannelsTouchingOSMNode(long id) {
ArrayList<Channel> returnchannels = new ArrayList<>();
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).getFromNode().getId() == id) {
returnchannels.add(channels.get(i));
}
if (channels.get(i).getToNode().getId() == id) {
returnchannels.add(channels.get(i));
}
}
return returnchannels;
}
/**
* gibt den oder die Channels twischen diesen OSM-Punkten zurück
*/
public ArrayList<Channel> getChannelsBetween(int idfrom, int idto) {
ArrayList<Channel> channelsresult = new ArrayList<>();
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).getFromNode().getId() == idfrom) {
if (channels.get(i).getToNode().getId() == idto) {
channelsresult.add(channels.get(i));
}
} else if (channels.get(i).getFromNode().getId() == idto) {
if (channels.get(i).getToNode().getId() == idfrom) {
channelsresult.add(channels.get(i));
}
}
}
return channelsresult;
}
public ArrayList<Channel> getChannelswithWayID(int id) {
ArrayList<Channel> channelsresult = new ArrayList<>();
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).getWay().getId() == id) {
channelsresult.add(channels.get(i));
}
}
return channelsresult;
}
public void detectSelectedChannels(double left, double top, double right, double bottom) {
for (int i = 0; i < channels.size(); i++) {
//log.trace(channels.get(i).getFromNode().toString());
if ((channels.get(i).getFromNode().getLatitude() <= top) && (channels.get(i).getFromNode().getLatitude() >= bottom)
&& (channels.get(i).getFromNode().getLongitude() >= left) && (channels.get(i).getFromNode().getLongitude() <= right)) {
channels.get(i).setSelected(true);
selectedChannels.add(channels.get(i));
}
if ((channels.get(i).getToNode().getLatitude() <= top) && (channels.get(i).getToNode().getLatitude() >= bottom)
&& (channels.get(i).getToNode().getLongitude() >= left) && (channels.get(i).getToNode().getLongitude() <= right)) {
channels.get(i).setSelected(true);
selectedChannels.add(channels.get(i));
}
}
}
/**
* löscht die markierten Channels aus der Liste der markierten Channels und setzt die
* Eigenschaft isSelected auf false
*/
public void ereaseSelectedChannels() {
for (int i = 0; i < selectedChannels.size(); i++) {
Iterator<Channel> it = selectedChannels.iterator();
while (it.hasNext()) {
it.next().setSelected(false);
}
}
selectedChannels.clear();
}
public HashSet<Channel> getSelectedChannels() {
return selectedChannels;
}
public HashSet<Channel> getJunctionCandidate() {
return junctioncandidate;
}
public void ereaseJunctioncandidate() {
Iterator<Channel> it = junctioncandidate.iterator();
while (it.hasNext()) {
it.next().setPartOfJunction(false);
}
junctioncandidate.clear();
}
/**
* setzt die Channels eines Kreuzungskandidaten
* falls in im Hashset vorher Channels gespeichert waren, werden diese vorher gelöscht!
*/
public void setJunctioncandidate(HashSet<Channel> junctionCandidate) {
this.junctioncandidate.clear();
this.junctioncandidate = junctionCandidate;
Iterator<Channel> it = junctionCandidate.iterator();
while (it.hasNext()) {
it.next().setPartOfJunction(true);
}
}
public void addJunctioncandidateChannel(Channel channel) {
junctioncandidate.add(channel);
channel.setPartOfJunction(true);
}
/*TODO: kann weg oder?
public void ereaseChannelsSubgraph() {
for (int i = 0; i < channels.size(); i++) {
channels.get(i).setSubgraph(false);
}
}
public void ereaseChannelsInDegree() {
for (int i = 0; i < channels.size(); i++) {
channels.get(i).setIndegree(0);
}
}
public void ereaseChannelsOutDegree() {
for (int i = 0; i < channels.size(); i++) {
channels.get(i).setOutdegree(0);
}
}
*/
}