Including offline public transport routing into android app

How do I import and use a GTFS file into my android app to make (offline) public transport routing available? I found the way to do it in the web instance, but haven’t found a quickstart-style guide to do it. Is it even possible? Reading the project on Public Transit (https://github.com/graphhopper/graphhopper/projects/1) makes me think it is, but haven’t found the way to do it…

Hi,

I haven’t tried if this is possible or not. Reading and routing with a GTFS file is definitely possible with the regular web server. Instead of instantiating GraphHopper or GraphHopperOSM, try to instantiate GraphHopperGTFS.

Cheers,
Robin

The quickstart on how to create the necessary files is in the module Readme. Currently we have no official Android support for public transit but you can try. Still import the data on a desktop or server before the mobile usage - similar to what you need to do for road routing.

I get this error when I follow the Readme instructions:

2017-11-01 10:42:34,052 [main] INFO com.graphhopper.http.CmdArgsModule - jsonp disabled
Exception in thread “main” com.google.inject.ProvisionException: Unable to provision, see the following errors:

  1. Error in custom provider, java.lang.IllegalArgumentException: entry in encoder list not supported pt

I don’t seem to find the GraphHopperGTFS class within the com.graphhopper.* packages in android…

GraphHopperGtfs class exists in reader-gtfs module.

Successfully imported. Thank you, @devemux86 !

I still have doubts about the usage of GraphHopperGtfs class, @boldtrn

Also, @karussell , I’m still unabe to execute the quickstart instructions (error in a comment above).

I hope you guys can help me with that.

My best guess is that this error is created because you don’t use the the GraphHopperGtfs class. If you use the regular GraphHopper class, you will use the DefaultFlagEncoderFactory, which does not contain public transport.

How can I use it when I’m executing ./graphhopper.shto generate the files?

It should work exactly as documented in the documentation linked above. Currently, it’s not possible to do it with ./graphhopper.sh import, you have to use ./graphhopper.sh web. Will create a PR that fixes this issue.

Cheers,
Robin

Thanks, @boldtrn, but I’m still unable to find where should I modify the Graphhopper class into GraphhopperGtfs class…

You only need to do this for the Android code. Essentially you would change this everywhere in the Android code where graphhopper = new GraphHopper to graphhopper = new GraphHopperGtfs. Hope this helps.

Cheers,
Robin

trying to do it in this line:

GraphHopperGtfs tmpHopp = new GraphHopperGtfs().forMobile();

There is no parameterless overload for GraphHopperGtfs contructor…

Also, the ./graphhopper.sh script (where the data to import is supposed to be processed) won’t run because of the pt flag error…

Yes, please have a look at the class itself: GraphHopperGtfs(PtFlagEncoder flagEncoder, TranslationMap translationMap, GraphHopperStorage graphHopperStorage, LocationIndex locationIndex, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed). You can also use the factory, as shown here:

      public static void init() {
        Helper.removeDir(new File(GRAPH_LOC));
        final PtFlagEncoder ptFlagEncoder = new PtFlagEncoder();
        EncodingManager encodingManager = new EncodingManager.Builder().addAll(Arrays.asList(ptFlagEncoder), 8).build();
        GHDirectory directory = GraphHopperGtfs.createGHDirectory(GRAPH_LOC);
        GtfsStorage gtfsStorage = GraphHopperGtfs.createGtfsStorage();
        graphHopperStorage = GraphHopperGtfs.createOrLoad(directory, encodingManager, ptFlagEncoder, gtfsStorage, false, Collections.singleton("files/sample-feed.zip"), Collections.emptyList());
        locationIndex = GraphHopperGtfs.createOrLoadIndex(directory, graphHopperStorage, ptFlagEncoder);
        graphHopper = GraphHopperGtfs.createFactory(ptFlagEncoder, GraphHopperGtfs.createTranslationMap(), graphHopperStorage, locationIndex, gtfsStorage)
                .createWithoutRealtimeFeed();
    }

Would you please post a complete example?

Cheers,
Robin

Hello @boldtrn, this is the specific error:

eduardo@walhalla:~/metro/workspace/new_graphhopper/graphhopper$ java -Xmx5g -Xms5g -jar web/target/graphhopper-web-*-with-dep.jar datareader-file=portland_oregon.osm.pbf gtfs-file=gtfs-portland.zip jetty.port=8989 jetty.resourcebase=./web/src/main/webapp graph.flag_encoders=pt prepare.ch.weightings=no graph.location=./graph-cache
2017-11-02 16:05:50,301 [main] INFO  com.graphhopper.http.CmdArgsModule - jsonp disabled
Exception in thread "main" com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error in custom provider, java.lang.IllegalArgumentException: entry in encoder list not supported pt
  at com.graphhopper.http.GraphHopperModule.createGraphHopper(GraphHopperModule.java:71) (via modules: com.graphhopper.http.GHServer$1 -> com.graphhopper.http.GraphHopperModule)
  at com.graphhopper.http.GraphHopperModule.createGraphHopper(GraphHopperModule.java:71) (via modules: com.graphhopper.http.GHServer$1 -> com.graphhopper.http.GraphHopperModule)
  while locating com.graphhopper.GraphHopper
    for the 1st parameter of com.graphhopper.http.GraphHopperModule.getGraphHopperService(GraphHopperModule.java:119)
  while locating com.graphhopper.http.GraphHopperService

1 error
	at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1028)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
	at com.graphhopper.http.GHServer.start(GHServer.java:122)
	at com.graphhopper.http.GHServer.start(GHServer.java:63)
	at com.graphhopper.http.GHServer.main(GHServer.java:58)
Caused by: java.lang.IllegalArgumentException: entry in encoder list not supported pt
	at com.graphhopper.routing.util.DefaultFlagEncoderFactory.createFlagEncoder(DefaultFlagEncoderFactory.java:60)
	at com.graphhopper.routing.util.EncodingManager.parseEncoderString(EncodingManager.java:129)
	at com.graphhopper.routing.util.EncodingManager.<init>(EncodingManager.java:71)
	at com.graphhopper.GraphHopper.init(GraphHopper.java:545)
	at com.graphhopper.http.GraphHopperModule.createGraphHopper(GraphHopperModule.java:76)
	at com.graphhopper.http.GraphHopperModule$$FastClassByGuice$$5270f821.invoke(<generated>)
	at com.google.inject.internal.ProviderMethod$FastClassProviderMethod.doProvision(ProviderMethod.java:264)
	at com.google.inject.internal.ProviderMethod$Factory.provision(ProviderMethod.java:401)
	at com.google.inject.internal.ProviderMethod$Factory.get(ProviderMethod.java:376)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:194)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
	at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
	at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
	at com.google.inject.internal.ProviderMethod$Factory.provision(ProviderMethod.java:402)
	at com.google.inject.internal.ProviderMethod$Factory.get(ProviderMethod.java:376)
	at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1019)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1085)
	at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1015)
	... 4 more

You call looks wrong to me. The parameter should be gtfs.file not gtfs-file. This should be also true for the other parameters, like datareader.file, etc.

Hello! I was able to run the script and start the server, but it is unable to find any route: No route found is always the message. What could be the reason?

Could have different reasons. Did you change anything in the code? Try to see if there is an exception, what are the logs while importing and while routing?

I haven’t modified the code.
This is the log:
2017-11-21 21:21:19,366 [qtp525968792-26] ERROR com.graphhopper.http.GHBaseServlet - point=45.525592%2C-122.686386&point=45.512121%2C-122.68158&type=json&locale=en-US&vehicle=pt&weighting=fastest&elevation=false&key=&pt.earliest_departure_time=2017-11-22T02%3A21%3A00.000Z 0:0:0:0:0:0:0:1 en_US Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36 [45.525592,-122.686386, 45.512121,-122.68158], took:1.4975425, , fastest, pt, errors:[java.lang.RuntimeException: No route found]

I think you want to combine car and pt in the config? This is not yet possible (out of the box):