Index: src/test/java/org/geotools/graph/util/DijkstraShortestPathFinderWithTurnCostsTest.java =================================================================== --- src/test/java/org/geotools/graph/util/DijkstraShortestPathFinderWithTurnCostsTest.java (revision 0) +++ src/test/java/org/geotools/graph/util/DijkstraShortestPathFinderWithTurnCostsTest.java (revision 0) @@ -0,0 +1,124 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2009, 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.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.geotools.graph.build.GraphBuilder; +import org.geotools.graph.build.basic.BasicGraphBuilder; +import org.geotools.graph.build.line.BasicLineGraphGenerator; +import org.geotools.graph.path.DijkstraShortestPathFinder; +import org.geotools.graph.path.Path; +import org.geotools.graph.structure.Edge; +import org.geotools.graph.structure.Graph; +import org.geotools.graph.structure.Graphable; +import org.geotools.graph.structure.Node; +import org.geotools.graph.traverse.standard.DijkstraIterator; +import org.junit.Assert; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.LineSegment; + +public class DijkstraShortestPathFinderWithTurnCostsTest extends TestCase { + + private Graph graph; + + public DijkstraShortestPathFinderWithTurnCostsTest(String name) { + super(name); + } + + protected void setUp() throws Exception { + super.setUp(); + + LineSegment ld1 = new LineSegment(); + ld1.setCoordinates(new Coordinate(0, 0), new Coordinate(1, 1)); + + LineSegment ld2 = new LineSegment(); + ld2.setCoordinates(new Coordinate(1, 1), new Coordinate(0, 2)); + + LineSegment ld3 = new LineSegment(); + ld3.setCoordinates(new Coordinate(1, 1), new Coordinate(1, 0)); + + // we have some line segments + LineSegment[] lines = { ld1, ld2, ld3 }; + + // create the graph generator + BasicLineGraphGenerator graphGen = new BasicLineGraphGenerator(); + + // add the lines to the graph + for (int i = 0; i < lines.length; i++) { + graphGen.add(lines[i]); + } + + this.graph = graphGen.getGraph(); + + System.out.println(graph); + + } + + public void test1() { + + double[] expected = { 0.0, 1.0, 3.0, 3.0 }; + + ArrayList gotArray = new ArrayList(4); + + Iterator it = graph.getNodes().iterator(); + + Node source = (Node) it.next(); + + // create the path finder + DijkstraShortestPathFinder pf = new DijkstraShortestPathFinder( + graph, (Graphable) source, costFunction(), tcostFunction()); + + pf.calculate(); + + Iterator it1 = graph.getNodes().iterator(); + + while (it1.hasNext()) { + Node d = (Node) it1.next(); + + Path path = pf.getPath((Graphable) d); + + gotArray.add(pf.getCost(d)); + + } + + } + + protected DijkstraIterator.EdgeWeighter costFunction() { + return (new DijkstraIterator.EdgeWeighter() { + public double getWeight(Edge e) { + return 1; + } + }); + } + + protected DijkstraIterator.NodeWeighter tcostFunction() { + return (new DijkstraIterator.NodeWeighter() { + public double getWeight(Node n, Edge e1, Edge e2) { + return 1.0; + } + }); + } + +} Property changes on: src/test/java/org/geotools/graph/util/DijkstraShortestPathFinderWithTurnCostsTest.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id URL Added: svn:eol-style + native Index: src/main/java/org/geotools/graph/traverse/standard/DijkstraIterator.java =================================================================== --- src/main/java/org/geotools/graph/traverse/standard/DijkstraIterator.java (revision 33484) +++ src/main/java/org/geotools/graph/traverse/standard/DijkstraIterator.java (working copy) @@ -89,6 +89,9 @@ /** provides weights for edges in the graph **/ protected EdgeWeighter weighter; + /** provides weights for nodes in the graph **/ + protected NodeWeighter nweighter; + /** priority queue to manage active nodes **/ protected PriorityQueue queue; @@ -102,7 +105,21 @@ * over. */ public DijkstraIterator(EdgeWeighter weighter) { + this(weighter,null); + } + + /** + * Constructs a new Dijkstra iterator which uses the specided EdgeWeighter and + * NodeWeighter + * + * @param weighter Calculates weights for edges in the graph being iterated + * over. + * @param nweighter Calculates weights for nodes in the graph being iterated + * over. + */ + public DijkstraIterator(EdgeWeighter weighter, NodeWeighter nweighter) { this.weighter = weighter; + this.nweighter = nweighter; } /** @@ -180,6 +197,15 @@ double cost = weighter.getWeight(currdn.node.getEdge(related)) + currdn.cost; + //calculate the cost of going through the node + if ( nweighter != null ) { + double ncost = 0d; + if(currdn.parent != null) { + Edge e1 = currdn.parent.node.getEdge(currdn.node); + Edge e2 = currdn.node.getEdge(related); + ncost = nweighter.getWeight(currdn.node,e1,e2); + } + } //if cost less than current cost of related node, update if (cost < reldn.cost) { reldn.cost = cost; @@ -261,6 +287,27 @@ } /** + * Supplies a weight for each pair of adjacent edges. + * + * @author Sandeep Kumar Jakkaraju sandeepkumar@iitbombay.org + * + */ + public static interface NodeWeighter { + + /** + * Returns the weight for a node, with respect to two adjecent edges. + * + * @param n The node. + * @param e1 First edge. + * @param e2 Second edge. + * + * @return The weight associated with traversing through the node from + * the first edge to the second. + */ + public double getWeight(Node n, Edge e1, Edge e2); + } + + /** * Internal data structure used to track node costs, and parent nodes. * * @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net Index: src/main/java/org/geotools/graph/path/DijkstraShortestPathFinder.java =================================================================== --- src/main/java/org/geotools/graph/path/DijkstraShortestPathFinder.java (revision 33484) +++ src/main/java/org/geotools/graph/path/DijkstraShortestPathFinder.java (working copy) @@ -23,6 +23,7 @@ import org.geotools.graph.traverse.basic.BasicGraphTraversal; import org.geotools.graph.traverse.standard.DijkstraIterator; import org.geotools.graph.traverse.standard.DijkstraIterator.EdgeWeighter; +import org.geotools.graph.traverse.standard.DijkstraIterator.NodeWeighter; /** * Calculates node paths in a graph using Dijkstra's Shortest Path Algorithm. @@ -68,8 +69,22 @@ public DijkstraShortestPathFinder( Graph graph, Graphable source, EdgeWeighter weighter ) { + this(graph,source,weighter,null); + } + + /** + * Constructs a new path finder. + * + * @param graph Graph to calculate paths for. + * @param source Node to calculate paths from. + * @param weighter Associates weights with edges in the graph. + * @param nweighter Associates weights with nodes in the graph. + */ + public DijkstraShortestPathFinder( + Graph graph, Graphable source, EdgeWeighter weighter, NodeWeighter nweighter + ) { m_graph = graph; - m_iterator = new DijkstraIterator(weighter); + m_iterator = new DijkstraIterator(weighter,nweighter); m_iterator.setSource(source); m_traversal = new BasicGraphTraversal(graph, this, m_iterator); }