// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking; import java.util.ArrayList; import java.util.HashSet; import org.openstreetmap.josm.gui.progress.ProgressMonitor; import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel; import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph; /** * JunctionChecker startet das Überprüfen eines Subgraphen auf eine existierende * Kreuzung * * @author joerg * */ public class JunctionChecker { private ArrayList<Channel> subgraph; private ArrayList<Channel> entries; private ArrayList<Channel> exits; private ArrayList<Channel> cycleedges; private ArrayList<Channel> subjunction; private int n; private final JPrepare jPrepare; private JProcess jProcess; private final ChannelDiGraph channeldigraph; private final JCheck jCheck; private ArrayList<Channel> E; private int[][] Grid; private boolean Check; private boolean smallerJunction; private JMinimality m; // Variable wird beim KreuzungsSuchen benutzt, sonst ist sie leer! private ArrayList<HashSet<Channel>> junctions = new ArrayList<>(); //dient zur Zeitmessung private long startIterate = 0; private long stopIterate = 0; private long startGenerate = 0; public JunctionChecker(ChannelDiGraph channeldigraph, int n) { this.jPrepare = new JPrepare(channeldigraph); this.channeldigraph = channeldigraph; this.n = n; this.jCheck = new JCheck(); this.subjunction = new ArrayList<>(); smallerJunction = false; } /** * startet das Überprüfen einer Teilmenge auf die Kreuzungskriterien */ public void checkjunctions(ArrayList<Channel> subgraph, ProgressMonitor pm) { jPrepare.jPrepare(subgraph); entries = jPrepare.getEntries(); exits = jPrepare.getExits(); jProcess = new JProcess(subgraph, channeldigraph); jProcess.jProcess(jPrepare.getEntries()); boolean result = jCheck.jCheck(entries, exits, n); //jPrepare.resetSubgraph(); if (result == true) { this.collectECandidates(subgraph); this.ConstructGrid(); m = new JMinimality(Grid, n, E, entries, exits, channeldigraph, pm, true); m.GenerateSubcolumns(); Check = m.IterateThroughKn(); if (!Check) { smallerJunction = true; } subjunction = m.getSubJunctionCandidate(); } else { Check = false; } } /** * Diese Methode wird aufgerufen, wenn nach Kreuzungen in einer Teilmenge * gesucht werden soll * * @param firstjunction soll nur die erste mögliche Kreuzung ausgegeben werden oder alle */ public void junctionSearch(ArrayList<Channel> subgraph, ProgressMonitor pm) { jPrepare.jPrepare(subgraph); entries = jPrepare.getEntries(); exits = jPrepare.getExits(); jProcess = new JProcess(subgraph, channeldigraph); jProcess.jProcess(jPrepare.getEntries()); this.collectECandidates(subgraph); this.ConstructGrid(); jPrepare.resetSubgraph(); m = new JMinimality(Grid, n, E, new ArrayList<Channel>(), new ArrayList<Channel>(), channeldigraph, pm, false); m.GenerateSubcolumns(); Check = m.IterateThroughKn(); junctions = checkJunctionCandidates(m.getJunctionCandidates()); } public void junctionSearch(ArrayList<Channel> subgraph) { jPrepare.jPrepare(subgraph); entries = jPrepare.getEntries(); exits = jPrepare.getExits(); jProcess = new JProcess(subgraph, channeldigraph); jProcess.jProcess(jPrepare.getEntries()); this.collectECandidates(subgraph); this.ConstructGrid(); jPrepare.resetSubgraph(); m = new JMinimality(Grid, n, E, new ArrayList<Channel>(), new ArrayList<Channel>(), channeldigraph, false); startGenerate = System.currentTimeMillis(); m.GenerateSubcolumns(); startIterate = System.currentTimeMillis(); Check = m.IterateThroughKn(); stopIterate = System.currentTimeMillis(); junctions = checkJunctionCandidates(m.getJunctionCandidates()); } /** * Überprüft die Kreuzunskandidaten, die JMinimality gefunden hat, welche davon eine Kreuzung darstellen (eine Kreuzung * darf keine weiteren Kreuzungen enthalten) */ private ArrayList<HashSet<Channel>> checkJunctionCandidates(ArrayList<HashSet<Channel>> junctioncandidates) { @SuppressWarnings("unchecked") ArrayList<HashSet<Channel>> junctions = (ArrayList<HashSet<Channel>>) junctioncandidates.clone(); for (int i = 0; i < junctioncandidates.size(); i++) { for (int j = 0; j < junctioncandidates.size(); j++) { if (junctioncandidates.get(i).containsAll(junctioncandidates.get(j))) { junctions.remove(junctioncandidates.get(i)); } } } return junctions; } private void collectECandidates(ArrayList<Channel> subgraph) { E = new ArrayList<>(); for (int i = 0; i < subgraph.size(); i++) { if ((subgraph.get(i).getIndegree() + subgraph.get(i).getOutdegree() >= 3) || entries.contains(subgraph.get(i)) || exits.contains(subgraph.get(i))) { E.add(subgraph.get(i)); } } } private void ConstructGrid() { Grid = new int[E.size()][E.size()]; for (int y = 0; y < E.size(); y++) { for (int x = 0; x < E.size(); x++) { if (x != y && !(entries.contains(E.get(x))) && !(exits.contains(E.get(y))) && E.get(y).getReachableNodes().contains(E.get(x))) { Grid[y][x] = 1; //log.trace("Grid-Position auf 1 gesetzT (y/x): " + y + ":" // + x + "(Entry/exit):" + E.get(y).getNewid() + ":" + // E.get(x).getNewid()); } else { Grid[y][x] = 0; } } } } public long getMeasuredIterateTime() { return (stopIterate - startIterate); } public long getMeasuredGenerateTime() { return (startIterate - startGenerate); } public ArrayList<Channel> getSubgraph() { return subgraph; } public void setSubgraph(ArrayList<Channel> subgraph) { this.subgraph = subgraph; } public ArrayList<Channel> getEntries() { return entries; } public void setEntries(ArrayList<Channel> entries) { this.entries = entries; } public ArrayList<Channel> getExits() { return exits; } public void setExits(ArrayList<Channel> exits) { this.exits = exits; } public ArrayList<Channel> getCycleedges() { return cycleedges; } public void setCycleedges(ArrayList<Channel> cycleedges) { this.cycleedges = cycleedges; } public int getN() { return n; } public void setN(int n) { this.n = n; } /** * gibt die kleinere, gefundene Kreuzung zurück (wenn es sie gibt) */ public ArrayList<Channel> getSubJunction() { return subjunction; } /** * gibt das Ergebnis des JCheck zurück (bei false keine generelle Aussage * möglich) * * @return false = keine Kreuzung ODER enthält kleinere Kreuzung true = * Kreuzung * */ public boolean getCheck() { return Check; } /** * gibt den Wert des JMinimality zurück (wenn er ausgeführt wurde) * * @return true = keine kleinere kreuzung, false = kleinere kreuzung * enthalten */ public boolean isSmallerJunction() { return smallerJunction; } /** * das Ergebnis des JCheck als String */ public String getJCheckResult() { return jCheck.getResult(); } /** * gitb die bei der Kruezungssuche gefundenen Kreuzungen zurück, sonst * nichts */ public ArrayList<HashSet<Channel>> getJunctions() { return junctions; } }