package org.opentripplanner.traffic; import com.google.common.collect.Maps; import junit.framework.TestCase; import org.junit.Test; import org.opentripplanner.routing.core.TraverseMode; import org.opentripplanner.routing.edgetype.StreetEdge; import org.opentripplanner.routing.edgetype.StreetTraversalPermission; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.vertextype.OsmVertex; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.Map; /** Test that street speed sources get used */ public class StreetSpeedSourceTest extends TestCase { @Test public void testMatching () { Graph g = new Graph(); OsmVertex v1 = new OsmVertex(g, "v1", 0, 0, 5l); OsmVertex v2 = new OsmVertex(g, "v2", 0, 0.01, 6l); StreetEdge se = new StreetEdge(v1, v2, null, "test", 1000, StreetTraversalPermission.CAR, false); se.wayId = 10; // create a speed sample SegmentSpeedSample s = getSpeedSample(); Map<Segment, SegmentSpeedSample> speeds = Maps.newHashMap(); Segment seg = new Segment(10l, 5l, 6l); speeds.put(seg, s); g.streetSpeedSource = new StreetSpeedSnapshotSource(); g.streetSpeedSource.setSnapshot(new StreetSpeedSnapshot(speeds)); // confirm that we get the correct speeds. // This also implicitly tests encoding/decoding OffsetDateTime odt = OffsetDateTime.of(2015, 6, 1, 8, 5, 0, 0, ZoneOffset.UTC); StreetSpeedSnapshot snap = g.streetSpeedSource.getSnapshot(); double monday8am = snap.getSpeed(se, TraverseMode.CAR, odt.toInstant().toEpochMilli()); // no data: should use average assertEquals(1.33, monday8am, 0.1); odt = odt.plusHours(1); double monday9am = snap.getSpeed(se, TraverseMode.CAR, odt.toInstant().toEpochMilli()); assertEquals(6.1, monday9am, 0.1); odt = odt.plusHours(1); double monday10am = snap.getSpeed(se, TraverseMode.CAR, odt.toInstant().toEpochMilli()); assertEquals(33.3, monday10am, 0.1); se.wayId = 102; double wrongStreet = snap.getSpeed(se, TraverseMode.CAR, odt.toInstant().toEpochMilli()); assertTrue(Double.isNaN(wrongStreet)); } @Test public void testConcurrency () { Graph g = new Graph(); StreetSpeedSnapshotSource ssss = new StreetSpeedSnapshotSource(); OsmVertex v1 = new OsmVertex(g, "v1", 0, 0, 5l); OsmVertex v2 = new OsmVertex(g, "v2", 0, 0.01, 6l); StreetEdge se = new StreetEdge(v1, v2, null, "test", 1000, StreetTraversalPermission.CAR, false); se.wayId = 10; Map<Segment, SegmentSpeedSample> ss2 = Maps.newHashMap(); Segment seg = new Segment(10l, 5l, 6l); ss2.put(seg, getSpeedSample()); StreetSpeedSnapshot ssOrig = new StreetSpeedSnapshot(ss2); ssss.setSnapshot(ssOrig); StreetSpeedSnapshot snap = ssss.getSnapshot(); assertEquals(ssOrig, snap); // should be match assertFalse(Double.isNaN(snap.getSpeed(se, TraverseMode.CAR, System.currentTimeMillis()))); // should not have changed assertEquals(snap, ssss.getSnapshot()); Map<Segment, SegmentSpeedSample> ss1 = Maps.newHashMap(); seg = new Segment(10l, 4l, 6l); ss1.put(seg, getSpeedSample()); StreetSpeedSnapshot ssNew = new StreetSpeedSnapshot(ss1); ssss.setSnapshot(ssNew); snap = ssss.getSnapshot(); assertEquals(ssNew, snap); // should be no match; the segment in the index does not match the street edge assertTrue(Double.isNaN(snap.getSpeed(se, TraverseMode.CAR, System.currentTimeMillis()))); } /** Make a speed sample */ private SegmentSpeedSample getSpeedSample() { double[] hourBins = new double[7 * 24]; for (int i = 0; i < hourBins.length; i++) { if (i == 8) hourBins[i] = Double.NaN; else if (i == 9) // ~20km/h hourBins[i] = 6.1; else // ~120 km/h hourBins[i] = 33.3; } // ~4km/h double avg = 1.33; return new SegmentSpeedSample(avg, hourBins); } }