/* * Licensed to GraphHopper GmbH under one or more contributor * license agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. * * GraphHopper GmbH licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.graphhopper; import com.google.transit.realtime.GtfsRealtime; import com.graphhopper.reader.gtfs.GraphHopperGtfs; import com.graphhopper.reader.gtfs.GtfsStorage; import com.graphhopper.reader.gtfs.PtFlagEncoder; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.GHDirectory; import com.graphhopper.storage.GraphHopperStorage; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.util.Helper; import com.graphhopper.util.Parameters; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import java.io.File; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Arrays; import java.util.Collections; import static com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.SKIPPED; import static com.graphhopper.reader.gtfs.GtfsHelper.time; import static org.junit.Assert.assertEquals; public class RealtimeIT { private static final String GRAPH_LOC = "target/RealtimeIT"; private static final ZoneId zoneId = ZoneId.of("America/Los_Angeles"); private static GraphHopperGtfs.Factory graphHopperFactory; private static GraphHopperStorage graphHopperStorage; private static LocationIndex locationIndex; @BeforeClass public static void init() { Helper.removeDir(new File(GRAPH_LOC)); final PtFlagEncoder ptFlagEncoder = new PtFlagEncoder(); EncodingManager encodingManager = new EncodingManager(Arrays.asList(ptFlagEncoder), 8); GHDirectory directory = GraphHopperGtfs.createGHDirectory(GRAPH_LOC); GtfsStorage gtfsStorage = GraphHopperGtfs.createGtfsStorage(); graphHopperStorage = GraphHopperGtfs.createOrLoad(directory, encodingManager, ptFlagEncoder, gtfsStorage, true, Collections.singleton("files/sample-feed.zip"), Collections.emptyList()); locationIndex = GraphHopperGtfs.createOrLoadIndex(directory, graphHopperStorage); graphHopperFactory = GraphHopperGtfs.createFactory(ptFlagEncoder, GraphHopperGtfs.createTranslationMap(), graphHopperStorage, locationIndex, gtfsStorage); } @AfterClass public static void close() { graphHopperStorage.close(); locationIndex.close(); } @Test public void testSkipDepartureStop() { final double FROM_LAT = 36.914893, FROM_LON = -116.76821; // NADAV stop final double TO_LAT = 36.914944, TO_LON = -116.761472; // NANAA stop GHRequest ghRequest = new GHRequest( FROM_LAT, FROM_LON, TO_LAT, TO_LON ); // I want to go at 6:44 ghRequest.getHints().put(Parameters.PT.EARLIEST_DEPARTURE_TIME, LocalDateTime.of(2007,1,1,6,44).atZone(zoneId).toInstant()); ghRequest.getHints().put(Parameters.PT.IGNORE_TRANSFERS, "true"); ghRequest.getHints().put(Parameters.PT.MAX_WALK_DISTANCE_PER_LEG, 30); // But the 6:00 departure of my line is going to skip my departure stop :-( final GtfsRealtime.FeedMessage.Builder feedMessageBuilder = GtfsRealtime.FeedMessage.newBuilder(); feedMessageBuilder.setHeader(GtfsRealtime.FeedHeader.newBuilder().setGtfsRealtimeVersion("wurst")); feedMessageBuilder.addEntityBuilder() .setId("pups") .getTripUpdateBuilder() .setTrip(GtfsRealtime.TripDescriptor.newBuilder().setTripId("CITY2").setStartTime("06:00:00")) .addStopTimeUpdateBuilder() .setStopSequence(3) .setScheduleRelationship(SKIPPED); GHResponse response = graphHopperFactory.createWith(feedMessageBuilder.build()).route(ghRequest); assertEquals(1, response.getAll().size()); assertEquals("I have to wait half an hour for the next one (and ride 5 minutes)", time(0, 35), response.getBest().getTime(), 0.1); } @Test public void testSkipArrivalStop() { final double FROM_LAT = 36.914893, FROM_LON = -116.76821; // NADAV stop final double TO_LAT = 36.914944, TO_LON = -116.761472; // NANAA stop GHRequest ghRequest = new GHRequest( FROM_LAT, FROM_LON, TO_LAT, TO_LON ); // I want to go at 6:44 ghRequest.getHints().put(Parameters.PT.EARLIEST_DEPARTURE_TIME, LocalDateTime.of(2007,1,1,6,44).atZone(zoneId).toInstant()); ghRequest.getHints().put(Parameters.PT.IGNORE_TRANSFERS, "true"); ghRequest.getHints().put(Parameters.PT.MAX_WALK_DISTANCE_PER_LEG, 30); // But the 6:00 departure of my line is going to skip my arrival stop :-( final GtfsRealtime.FeedMessage.Builder feedMessageBuilder = GtfsRealtime.FeedMessage.newBuilder(); feedMessageBuilder.setHeader(GtfsRealtime.FeedHeader.newBuilder().setGtfsRealtimeVersion("wurst")); feedMessageBuilder.addEntityBuilder() .setId("pups") .getTripUpdateBuilder() .setTrip(GtfsRealtime.TripDescriptor.newBuilder().setTripId("CITY2").setStartTime("06:00:00")) .addStopTimeUpdateBuilder() .setStopSequence(4) .setScheduleRelationship(SKIPPED); GHResponse response = graphHopperFactory.createWith(feedMessageBuilder.build()).route(ghRequest); assertEquals(1, response.getAll().size()); assertEquals("I have to continue to STAGECOACH and then go back one stop with the 07:00 bus.", time(0, 21), response.getBest().getTime(), 0.1); } @Test public void testSkipTransferStop() { final double FROM_LAT = 36.914893, FROM_LON = -116.76821; // NADAV stop final double TO_LAT = 36.868446, TO_LON = -116.784582; // BEATTY_AIRPORT stop GHRequest ghRequest = new GHRequest( FROM_LAT, FROM_LON, TO_LAT, TO_LON ); // I want to go at 6:44 ghRequest.getHints().put(Parameters.PT.EARLIEST_DEPARTURE_TIME, LocalDateTime.of(2007,1,1,6,44).atZone(zoneId).toInstant()); ghRequest.getHints().put(Parameters.PT.IGNORE_TRANSFERS, "true"); ghRequest.getHints().put(Parameters.PT.MAX_WALK_DISTANCE_PER_LEG, 30); // But the 6:00 departure of my line is going to skip my transfer stop :-( final GtfsRealtime.FeedMessage.Builder feedMessageBuilder = GtfsRealtime.FeedMessage.newBuilder(); feedMessageBuilder.setHeader(GtfsRealtime.FeedHeader.newBuilder().setGtfsRealtimeVersion("wurst")); feedMessageBuilder.addEntityBuilder() .setId("pups") .getTripUpdateBuilder() .setTrip(GtfsRealtime.TripDescriptor.newBuilder().setTripId("CITY2").setStartTime("06:00:00")) .addStopTimeUpdateBuilder() .setStopSequence(5) .setScheduleRelationship(SKIPPED); GHResponse response = graphHopperFactory.createWith(feedMessageBuilder.build()).route(ghRequest); assertEquals(1, response.getAll().size()); assertEquals("The 6:44 bus will not call at STAGECOACH, so I will be 30 min late at the airport.", time(1, 6), response.getBest().getTime(), 0.1); } @Test public void testBlockTrips() { final double FROM_LAT = 36.868446, FROM_LON = -116.784582; // BEATTY_AIRPORT stop final double TO_LAT = 36.425288, TO_LON = -117.133162; // FUR_CREEK_RES stop GHRequest ghRequest = new GHRequest( FROM_LAT, FROM_LON, TO_LAT, TO_LON ); ghRequest.getHints().put(Parameters.PT.EARLIEST_DEPARTURE_TIME, LocalDateTime.of(2007,1,1,8,0).atZone(zoneId).toInstant()); ghRequest.getHints().put(Parameters.PT.IGNORE_TRANSFERS, "true"); ghRequest.getHints().put(Parameters.PT.MAX_WALK_DISTANCE_PER_LEG, 30); // My line does not stop at Bullfrog today. If this was a real transfer, I would not be // able to change lines there. But it is not a real transfer, so I can go on as planned. final GtfsRealtime.FeedMessage.Builder feedMessageBuilder = GtfsRealtime.FeedMessage.newBuilder(); feedMessageBuilder.setHeader(GtfsRealtime.FeedHeader.newBuilder().setGtfsRealtimeVersion("wurst")); feedMessageBuilder.addEntityBuilder() .setId("pups") .getTripUpdateBuilder() .setTrip(GtfsRealtime.TripDescriptor.newBuilder().setTripId("AB1").setStartTime("00:00:00")) .addStopTimeUpdateBuilder() .setStopSequence(2) .setScheduleRelationship(SKIPPED); GHResponse response = graphHopperFactory.createWith(feedMessageBuilder.build()).route(ghRequest); assertEquals("I can still use the AB1 trip", "AB1", (((Trip.PtLeg) response.getBest().getLegs().get(0)).tripId)); assertEquals("It takes", time(1,20), response.getBest().getTime()); } }