// 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); } } */ }