package pl.edu.agh.logic;
import static com.google.common.collect.Lists.newArrayList;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Date;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import pl.edu.agh.model.Way;
import pl.edu.agh.spatial.WGS84GeometryFactory;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
public class UTurnPathCorrectorTest {
private PathCorrector pathCorrector;
private RoadNetwork roadNetwork;
private GeometryFactory geometryFactory = new WGS84GeometryFactory();
@Before
public void preparePathCorrector() {
LineString line1 = geometryFactory.createLineString(new Coordinate[] { new Coordinate(0, 0),
new Coordinate(1, 0), new Coordinate(2, 0) });
LineString line2 = geometryFactory.createLineString(new Coordinate[] { new Coordinate(2, 0),
new Coordinate(3, 0), new Coordinate(4, 0) });
LineString line3 = geometryFactory.createLineString(new Coordinate[] { new Coordinate(4, 0),
new Coordinate(5, 0), new Coordinate(6, 0) });
List<Way> ways = newArrayList();
ways.add(createWay(1, 1, 2, line1, false));
ways.add(createWay(2, 2, 3, line2, true));
ways.add(createWay(3, 3, 4, line3, false));
roadNetwork = new RoadNetwork(ways, geometryFactory);
pathCorrector = new UTurnPathCorrector(roadNetwork);
}
private Way createWay(int gid, int source, int target, LineString line, boolean isOneWay) {
Way way1 = new Way();
way1.setGid(gid);
way1.setSource(source);
way1.setTarget(target);
way1.setGeometry(geometryFactory.createMultiLineString(new LineString[] { line }));
way1.setLength(2.0);
way1.setReverseCost(isOneWay ? 1.0 : 2.0);
return way1;
}
@Test
public void forPathWithTwoMatchingToCorrectlyDirectedRoadReturnsTheSamePath() {
Road[] roads = roadNetwork.getRoadsById(1).toArray(new Road[0]);
Road directRoad = roads[0].isReversed() ? roads[1] : roads[0];
Path path = Path.createPath(new Coordinate(0.5, 0), directRoad, new Date()).matchPointToLastRoad(
new Coordinate(1.5, 0), new Date());
Path corrected = pathCorrector.correct(path);
assertTrue(PathUtils.pathContainsOneDirectedRoad(corrected));
assertEquals(corrected.getMatchings().get(0).getRoad(), directRoad);
}
@Test
public void forPathWithTwoMatchingToWrongDirectedRoadReturnsThePathWithReversedRoad() {
Road[] roads = roadNetwork.getRoadsById(1).toArray(new Road[0]);
Road directRoad = roads[0].isReversed() ? roads[1] : roads[0];
Road reversedRoad = roads[0].isReversed() ? roads[0] : roads[1];
Path path = Path.createPath(new Coordinate(1.5, 0), directRoad, new Date()).matchPointToLastRoad(
new Coordinate(0.5, 0), new Date());
Path corrected = pathCorrector.correct(path);
assertTrue(PathUtils.pathContainsOneDirectedRoad(corrected));
assertEquals(corrected.getMatchings().get(0).getRoad(), reversedRoad);
}
@Test
public void forPathWithTwoMatchingToOneWayRoadReturnsTheSamePath() {
Road[] roads = roadNetwork.getRoadsById(2).toArray(new Road[0]);
Road directRoad = roads[0].isReversed() ? roads[1] : roads[0];
Path path = Path.createPath(new Coordinate(1.5, 0), directRoad, new Date()).matchPointToLastRoad(
new Coordinate(0.5, 0), new Date());
Path corrected = pathCorrector.correct(path);
assertEquals(path, corrected);
}
@Test
public void forPathWithUTurnReturnsThePathWithOneRoad() {
Road[] roads = roadNetwork.getRoadsById(1).toArray(new Road[0]);
Road directRoad = roads[0].isReversed() ? roads[1] : roads[0];
Road reversedRoad = roads[0].isReversed() ? roads[0] : roads[1];
Path path = Path.createPath(new Coordinate(1.5, 0), directRoad, new Date()).matchPointToRoad(
new Coordinate(0.5, 0), reversedRoad, new Date());
Path corrected = pathCorrector.correct(path);
assertTrue(PathUtils.pathContainsOneDirectedRoad(corrected));
assertEquals(corrected.getMatchings().get(0).getRoad(), reversedRoad);
}
@Test
public void forPathWithUTurnAndDistanceBetweenPointsGreaterThanPathLengthReturnsTheSamePath() {
Road[] roads = roadNetwork.getRoadsById(1).toArray(new Road[0]);
Road directRoad = roads[0].isReversed() ? roads[1] : roads[0];
Road reversedRoad = roads[0].isReversed() ? roads[0] : roads[1];
Path path = Path.createPath(new Coordinate(1.6, 0), directRoad, new Date())
.matchPointToRoad(new Coordinate(0.4, 0), reversedRoad, new Date())
.matchPointToRoad(new Coordinate(1.6, 0), directRoad, new Date());
Path corrected = pathCorrector.correct(path);
assertEquals(path, corrected);
}
@Test
public void forPathWithoutUTurnsReturnsTheSamePath() {
Path path = Path.createPath(new Coordinate(1, 0), getRoad(1, false), new Date())
.matchPointToLastRoad(new Coordinate(1.5, 0), new Date())
.matchPointToRoad(new Coordinate(3, 0), getRoad(2, false), new Date())
.matchPointToRoad(new Coordinate(5.0, 0), getRoad(3, false), new Date())
.matchPointToLastRoad(new Coordinate(5.5, 0), new Date());
Path corrected = pathCorrector.correct(path);
assertEquals(path.getMatchings().size(), corrected.getMatchings().size());
for (int i = 0 ; i < path.getMatchings().size(); i++) {
assertEquals(path.getMatchings().get(i).getRoad(), corrected.getMatchings().get(i).getRoad());
}
}
@Test
public void forPathWithUTurnsAtBeginningAndEndCorrectsThem() {
Path path = Path.createPath(new Coordinate(1, 0), getRoad(1, true), new Date())
.matchPointToRoad(new Coordinate(1.5, 0), getRoad(1, false), new Date())
.matchPointToRoad(new Coordinate(3, 0), getRoad(2, false), new Date())
.matchPointToRoad(new Coordinate(5.0, 0), getRoad(3, false), new Date())
.matchPointToRoad(new Coordinate(5.5, 0), getRoad(3, true), new Date());
Path corrected = pathCorrector.correct(path);
assertEquals(path.getMatchings().size(), corrected.getMatchings().size());
assertEquals(corrected.getMatchings().get(0).getRoad(), corrected.getMatchings().get(1).getRoad());
assertEquals(corrected.getMatchings().get(3).getRoad(), corrected.getMatchings().get(4).getRoad());
for (int i = 1; i < 4; i++) {
assertEquals(path.getMatchings().get(i).getRoad(), corrected.getMatchings().get(i).getRoad());
}
}
@Test
public void forPathWithLongUTurnsAtBeginningAndEndDoesNotCorrectThem() {
Path path = Path.createPath(new Coordinate(0, 0), getRoad(1, true), new Date())
.matchPointToRoad(new Coordinate(1.5, 0), getRoad(1, false), new Date())
.matchPointToLastRoad(new Coordinate(0, 0), new Date())
.matchPointToLastRoad(new Coordinate(1.5, 0), new Date())
.matchPointToRoad(new Coordinate(3, 0), getRoad(2, false), new Date())
.matchPointToRoad(new Coordinate(4.0, 0), getRoad(3, false), new Date())
.matchPointToRoad(new Coordinate(5.5, 0), getRoad(3, true), new Date())
.matchPointToLastRoad(new Coordinate(4.0, 0), new Date())
.matchPointToLastRoad(new Coordinate(5.5, 0), new Date());
Path corrected = pathCorrector.correct(path);
assertEquals(path.getMatchings().size(), corrected.getMatchings().size());
for (int i = 0 ; i < path.getMatchings().size(); i++) {
assertEquals(path.getMatchings().get(i).getRoad(), corrected.getMatchings().get(i).getRoad());
}
}
private Road getRoad(int id, boolean reversed) {
Road[] roads = roadNetwork.getRoadsById(id).toArray(new Road[0]);
if (roads.length == 1) {
return (roads[0].isReversed() == reversed) ? roads[0] : null;
}
return (roads[0].isReversed() == reversed) ? roads[0] : roads[1];
}
}