package edu.kit.pse.ws2013.routekit.precalculation;
import java.io.File;
import java.util.Arrays;
import java.util.Set;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXParseException;
import edu.kit.pse.ws2013.routekit.map.EdgeBasedGraph;
import edu.kit.pse.ws2013.routekit.map.EdgeProperties;
import edu.kit.pse.ws2013.routekit.map.Graph;
import edu.kit.pse.ws2013.routekit.map.HighwayType;
import edu.kit.pse.ws2013.routekit.map.NodeProperties;
import edu.kit.pse.ws2013.routekit.map.StreetMap;
import edu.kit.pse.ws2013.routekit.map.TurnType;
import edu.kit.pse.ws2013.routekit.models.ProgressReporter;
import edu.kit.pse.ws2013.routekit.profiles.Profile;
public class OSMParserTest {
private static final float EPSILON = 1E-6F;
private ProgressReporter reporter;
private OSMParser parser;
@Before
public void setUp() {
reporter = new ProgressReporter();
reporter.pushTask("Dummy");
parser = new OSMParser();
}
private static File getTestFile(String name) {
return new File(OSMParserTest.class.getResource(name).getFile());
}
@Test(expected = IllegalArgumentException.class)
public void testFileNull() throws Exception {
parser.parseOSM(null, reporter);
}
@Test(expected = SAXParseException.class)
public void testNoOSMFile() throws Exception {
parser.parseOSM(getTestFile("testNoOSM.xml"), reporter);
}
@Test(expected = SAXParseException.class)
public void testMissingTagName() throws Exception {
parser.parseOSM(getTestFile("testMissingTagName.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testMissingTagValue() throws Exception {
parser.parseOSM(getTestFile("testMissingTagValue.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testMissingTagNameNode() throws Exception {
parser.parseOSM(getTestFile("testMissingTagNameNode.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testMissingTagValueNode() throws Exception {
parser.parseOSM(getTestFile("testMissingTagValueNode.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testMissingCoordinates() throws Exception {
parser.parseOSM(getTestFile("testMissingCoordinates.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testInvalidCoordinates() throws Exception {
parser.parseOSM(getTestFile("testInvalidCoordinates.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testInvalidNodeReference() throws Exception {
parser.parseOSM(getTestFile("testInvalidNodeReference.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testMissingNodeId() throws Exception {
parser.parseOSM(getTestFile("testMissingNodeID.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testInvalidWayId() throws Exception {
parser.parseOSM(getTestFile("testInvalidWayID.osm"), reporter);
}
@Test(expected = SAXParseException.class)
public void testInvalidWayMemberReference() throws Exception {
parser.parseOSM(getTestFile("testInvalidWayMemberReference.osm"),
reporter);
}
@Test(expected = SAXParseException.class)
public void testMissingNodeMemberReference() throws Exception {
parser.parseOSM(getTestFile("testMissingNodeMemberReference.osm"),
reporter);
}
@Test
public void testWay() throws Exception {
StreetMap map = parser.parseOSM(getTestFile("testWay.osm"), reporter);
Graph graph = map.getGraph();
EdgeBasedGraph ebg = map.getEdgeBasedGraph();
assertEquals(4, graph.getNumberOfEdges());
assertEquals(3, graph.getNumberOfNodes());
EdgeProperties edgeProps = graph.getEdgeProperties(0);
assertEquals("Hauptstraße", edgeProps.getName());
assertEquals("B 42", edgeProps.getRoadRef());
assertEquals(HighwayType.Primary, edgeProps.getType());
for (int i = 1; i < graph.getNumberOfEdges(); i++) {
assertSame(edgeProps, graph.getEdgeProperties(i));
}
float[] lat = { 48.910534999324206F, 48.910534999324206F,
48.91543512675681F };
float[] lon = { 8.547609656760535F, 8.557401293357438F,
8.561803038249623F };
int[] nodes = new int[3];
Arrays.fill(nodes, -1);
for (int i = 0; i < lat.length; i++) {
for (int j = 0; j < nodes.length; j++) {
if (Math.abs(lat[i] - graph.getCoordinates(j).getLatitude()) < EPSILON
&& Math.abs(lon[i]
- graph.getCoordinates(j).getLongitude()) < EPSILON) {
nodes[i] = j;
}
}
if (nodes[i] == -1) {
fail();
}
}
assertEquals(1, graph.getOutgoingEdges(nodes[0]).size());
assertEquals(2, graph.getOutgoingEdges(nodes[1]).size());
assertEquals(1, graph.getOutgoingEdges(nodes[2]).size());
int[] edges = new int[4];
edges[0] = graph.getOutgoingEdges(nodes[0]).iterator().next();
edges[2] = graph.getOutgoingEdges(nodes[2]).iterator().next();
for (int edge : graph.getOutgoingEdges(nodes[1])) {
if (graph.getTargetNode(edge) == nodes[0]) {
edges[3] = edge;
} else if (graph.getTargetNode(edge) == nodes[2]) {
edges[1] = edge;
} else {
fail();
}
}
assertFalse(edges[1] == edges[3]);
assertEquals(nodes[0], graph.getTargetNode(edges[3]));
assertEquals(nodes[1], graph.getTargetNode(edges[2]));
assertEquals(nodes[2], graph.getTargetNode(edges[1]));
assertEquals(nodes[1], graph.getTargetNode(edges[0]));
assertEquals(2, ebg.getNumberOfTurns());
assertTrue(ebg.getIncomingTurns(edges[0]).isEmpty());
assertTrue(ebg.getOutgoingTurns(edges[1]).isEmpty());
assertTrue(ebg.getIncomingTurns(edges[2]).isEmpty());
assertTrue(ebg.getOutgoingTurns(edges[3]).isEmpty());
assertEquals(1, ebg.getIncomingTurns(edges[1]).size());
assertEquals(1, ebg.getIncomingTurns(edges[3]).size());
assertEquals(ebg.getIncomingTurns(edges[1]),
ebg.getOutgoingTurns(edges[0]));
assertEquals(ebg.getIncomingTurns(edges[3]),
ebg.getOutgoingTurns(edges[2]));
int turn = ebg.getOutgoingTurns(edges[0]).iterator().next();
assertEquals(TurnType.NoTurn, ebg.getTurnType(turn));
assertEquals(edges[1], ebg.getTargetEdge(turn));
turn = ebg.getOutgoingTurns(edges[2]).iterator().next();
assertEquals(TurnType.NoTurn, ebg.getTurnType(turn));
assertEquals(edges[3], ebg.getTargetEdge(turn));
}
@Test
public void testOneway() throws Exception {
StreetMap map = parser
.parseOSM(getTestFile("testOneway.osm"), reporter);
Graph graph = map.getGraph();
assertEquals(1, graph.getNumberOfEdges());
assertEquals(8.547609656760535,
graph.getCoordinates(graph.getStartNode(0)).getLongitude(),
EPSILON);
assertEquals(8.557401293357438,
graph.getCoordinates(graph.getTargetNode(0)).getLongitude(),
EPSILON);
}
@Test
public void testOnewayBackwards() throws Exception {
StreetMap map = parser.parseOSM(getTestFile("testOnewayBackwards.osm"),
reporter);
Graph graph = map.getGraph();
assertEquals(1, graph.getNumberOfEdges());
assertEquals(8.557401293357438,
graph.getCoordinates(graph.getStartNode(0)).getLongitude(),
EPSILON);
assertEquals(8.547609656760535,
graph.getCoordinates(graph.getTargetNode(0)).getLongitude(),
EPSILON);
}
@Test
public void testMaxweightRestriction() throws Exception {
StreetMap map = parser.parseOSM(
getTestFile("testMaxweightRestriction.osm"), reporter);
EdgeBasedGraph ebg = map.getEdgeBasedGraph();
assertEquals(1, ebg.getNumberOfTurns());
assertTrue(ebg.allowsTurn(0, Profile.defaultCar));
assertFalse(ebg.allowsTurn(0, Profile.defaultTruck));
}
@Test
public void testTrafficSignals() throws Exception {
Graph graph = parser.parseOSM(getTestFile("testTrafficSignals.osm"),
reporter).getGraph();
assertTrue(graph.getNodeProperties(graph.getStartNode(0))
.isTrafficLights());
}
private void testTurn(String file, TurnType type) throws Exception {
StreetMap map = parser.parseOSM(getTestFile(file), reporter);
Graph graph = map.getGraph();
EdgeBasedGraph ebg = map.getEdgeBasedGraph();
assertEquals(2, ebg.getNumberOfTurns());
boolean found = false;
for (int turn = 0; turn < ebg.getNumberOfTurns(); turn++) {
if (graph.getEdgeProperties(ebg.getTargetEdge(turn)).getType() == HighwayType.Secondary) {
assertEquals(type, ebg.getTurnType(turn));
found = true;
}
}
assertTrue(found);
}
@Test
public void testRightTurn() throws Exception {
testTurn("testRightTurn.osm", TurnType.RightTurn);
}
@Test
public void testHalfRightTurn() throws Exception {
testTurn("testHalfRightTurn.osm", TurnType.HalfRightTurn);
}
@Test
public void testLeftTurn() throws Exception {
testTurn("testLeftTurn.osm", TurnType.LeftTurn);
}
@Test
public void testHalfLeftTurn() throws Exception {
testTurn("testHalfLeftTurn.osm", TurnType.HalfLeftTurn);
}
@Test
public void testStraightOn() throws Exception {
testTurn("testStraightOn.osm", TurnType.StraightOn);
}
@Test
public void testMotorwayJunction() throws Exception {
StreetMap map = parser.parseOSM(
getTestFile("testMotorwayJunction.osm"), reporter);
Graph graph = map.getGraph();
EdgeBasedGraph ebg = map.getEdgeBasedGraph();
assertEquals(2, ebg.getNumberOfTurns());
NodeProperties nodeProps = graph.getNodeProperties(graph
.getStartNode(ebg.getTargetEdge(0)));
assertTrue(nodeProps.isMotorwayJunction());
assertEquals("Buxtehude West", nodeProps.getJunctionName());
assertEquals("42", nodeProps.getJunctionRef());
boolean found = false;
for (int turn = 0; turn < ebg.getNumberOfTurns(); turn++) {
if (graph.getEdgeProperties(ebg.getTargetEdge(turn)).getRoadRef() == null) {
assertEquals(TurnType.MotorwayJunction, ebg.getTurnType(turn));
found = true;
} else {
assertEquals(TurnType.StraightOn, ebg.getTurnType(turn));
}
}
assertTrue(found);
}
@Test
public void testRoundabout() throws Exception {
StreetMap map = parser.parseOSM(getTestFile("testRoundabout.osm"),
reporter);
Graph graph = map.getGraph();
EdgeBasedGraph ebg = map.getEdgeBasedGraph();
assertEquals(5, graph.getNumberOfEdges());
assertEquals(5, ebg.getNumberOfTurns());
int exitNode = -1;
for (int node = 0; node < graph.getNumberOfNodes(); node++) {
if (graph.getOutgoingEdges(node).size() == 2) {
exitNode = node;
break;
}
}
assertFalse(exitNode < 0);
for (int edge : graph.getOutgoingEdges(exitNode)) {
Set<Integer> turns = ebg.getIncomingTurns(edge);
switch (turns.size()) {
case 1:
assertEquals(TurnType.RoundaboutExit,
ebg.getTurnType(turns.iterator().next()));
break;
case 2:
for (int turn : turns) {
TurnType type = ebg.getTurnType(turn);
if (graph.getEdgeProperties(ebg.getStartEdge(turn))
.getName() != null) {
assertEquals(TurnType.RoundaboutNoExit, type);
} else {
assertEquals(TurnType.RoundaboutEntry, type);
}
}
break;
default:
fail();
}
}
int noTurns = 0;
for (int turn = 0; turn < ebg.getNumberOfTurns(); turn++) {
if (ebg.getTurnType(turn) == TurnType.NoTurn) {
noTurns++;
}
}
assertEquals(2, noTurns);
}
@Test
public void testRestrictionNo() throws Exception {
StreetMap map = parser.parseOSM(getTestFile("testRestrictionNo.osm"),
reporter);
Graph graph = map.getGraph();
EdgeBasedGraph ebg = map.getEdgeBasedGraph();
assertEquals(2, ebg.getNumberOfTurns());
for (int edge = 0; edge < graph.getNumberOfEdges(); edge++) {
if (graph.getEdgeProperties(edge).getType() == HighwayType.Secondary) {
assertEquals(1, ebg.getIncomingTurns(edge).size());
}
}
}
@Test
public void testRestrictionOnly() throws Exception {
StreetMap map = parser.parseOSM(getTestFile("testRestrictionOnly.osm"),
reporter);
Graph graph = map.getGraph();
EdgeBasedGraph ebg = map.getEdgeBasedGraph();
assertEquals(2, ebg.getNumberOfTurns());
for (int turn = 0; turn < ebg.getNumberOfTurns(); turn++) {
assertFalse(graph.getEdgeProperties(ebg.getTargetEdge(turn))
.getType() == HighwayType.Primary);
}
}
@Test
public void testNdTagOutsideWay() throws Exception {
Graph graph = parser.parseOSM(getTestFile("testNdTagOutsideWay.osm"),
reporter).getGraph();
assertEquals(4, graph.getNumberOfEdges());
assertEquals(3, graph.getNumberOfNodes());
}
@Test
public void testMemberTagOutsideRelation() throws Exception {
Graph graph = parser.parseOSM(
getTestFile("testMemberTagOutsideRelation.osm"), reporter)
.getGraph();
assertEquals(4, graph.getNumberOfEdges());
assertEquals(3, graph.getNumberOfNodes());
}
@Test
public void testOtherHighway() throws Exception {
Graph graph = parser.parseOSM(getTestFile("testOtherHighway.osm"),
reporter).getGraph();
assertEquals(0, graph.getNumberOfEdges());
}
}