/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.graph.traverse.standard; import java.util.Iterator; import org.geotools.graph.structure.DirectedGraphable; import org.geotools.graph.structure.DirectedNode; import org.geotools.graph.structure.Graph; import org.geotools.graph.structure.GraphVisitor; import org.geotools.graph.structure.Graphable; import org.geotools.graph.traverse.GraphTraversal; import org.geotools.graph.traverse.basic.AbstractGraphIterator; import org.geotools.graph.util.FIFOQueue; import org.geotools.graph.util.Queue; /** * * @source $URL$ */ public class DirectedBreadthFirstTopologicalIterator extends AbstractGraphIterator { private Queue m_queue; public void init(Graph graph, GraphTraversal traversal) { //create queue m_queue = buildQueue(graph); //initialize nodes graph.visitNodes( new GraphVisitor() { public int visit(Graphable component) { DirectedNode node = (DirectedNode)component; node.setVisited(false); node.setCount(0); if (node.getInDegree() == 0) m_queue.enq(node); return(0); } } ); } public Graphable next(GraphTraversal traversal) { return(!m_queue.isEmpty() ? (Graphable)m_queue.deq() : null); } public void cont(Graphable current, GraphTraversal traversal) { //increment the count of all adjacent nodes by one // if the result count equal to the degree, place it into the queue DirectedGraphable directed = (DirectedGraphable)current; for (Iterator itr = directed.getOutRelated(); itr.hasNext();) { DirectedNode related = (DirectedNode)itr.next(); if (!traversal.isVisited(related)) { related.setCount(related.getCount()+1); if (related.getInDegree() == related.getCount()) m_queue.enq(related); } } } public void killBranch(Graphable current, GraphTraversal traversal) { //do nothing } protected Queue buildQueue(Graph graph) { return(new FIFOQueue(graph.getNodes().size())); } }