Difference in routing between core and web app---web find the way, code doesn't

Hi.

I need to calculate driving distances between many pairs of locations (lon, lat). Following an example on this web, I made the code included below (I know it’s terrible, I can’t use Java). It reads pairs of GPS locations from a CSV file, makes graphhopper to calculate the distance, and writes it together with the locations into a CSV file.

Now, the code fails for some pairs—graphhopper doesn’t find any route (the error message is “com.graphhopper.util.exceptions.ConnectionNotFoundException: Connection between locations not found”). However, if I start the graphhopper web locally and insert the locations of the failed pairs, it finds a way. Hence my questions:

  1. What’s the difference in routing setting between my code derived from the example and the web setting?
  2. How should I change the code to get the same results as from the web—or at least always find a way?

Many thanks for any help or hint.

Best wishes,
Michal

The simplified version of the code (I removed reading and writing the CSVs):

import com.graphhopper.*;
import com.graphhopper.reader.osm.*;
import com.graphhopper.routing.util.*;
import com.graphhopper.GHRequest.*;
import com.graphhopper.util.*;


public class Distancer {

    // map source: https://download.geofabrik.de/europe/czech-republic.html
    private static final String MAP_FILE = "maps/czech-republic-latest.osm.pbf";


    public static void main(String[] args) throws IOException {

	// create one GraphHopper instance
	GraphHopper hopper = new GraphHopperOSM();
	hopper.setDataReaderFile(MAP_FILE);
	// where to store graphhopper files?
	hopper.setGraphHopperLocation("graphFolder");
	hopper.setEncodingManager(new EncodingManager("car"));
	// now this can take minutes if it imports or a few seconds for loading
	// of course this is dependent on the area you import
	hopper.importOrLoad();

	// process the gps pairs, find the distances, and write it down
    String[] nextLine;
	double distance;
    String distout;
    // nextLine is a list of the GPS locations
        while ((nextLine = reader.readNext()) != null) {
		// calculate the distance
		distance = 0;
		// simple configuration of the request object, see the 
		// GraphHopperServlet classs for more possibilities.
		double latFrom = Double.parseDouble(nextLine[0]);
		double lonFrom = Double.parseDouble(nextLine[1]);
		double latTo = Double.parseDouble(nextLine[2]);
		double lonTo = Double.parseDouble(nextLine[3]);
		GHRequest req = new GHRequest(latFrom, lonFrom, latTo, lonTo).
		    setWeighting("fastest").
		    setVehicle("car");
		GHResponse rsp = hopper.route(req);

   		// use the best path, see the GHResponse class for more possibilities.
    		PathWrapper path = rsp.getBest();
    		// points, distance in meters and time in millis of the full path
    		PointList pointList = path.getPoints();
    		distance = path.getDistance();
            // this is what I care about
            distout = Double.toString(distance);
        }

    }

}
2 Likes

You can try to use the following settings for the import:

prepare.min_network_size=200
prepare.min_one_way_network_size=200

(or higher values) to make GraphHopper less error-prone against OSM problems.

Many thanks. Could you possibly suggest me where should I put these two lines? As I said, I don’t understand neither Java nor graphhopper very well. (I usually code from stratch in R or python.)

Many thanks for any hint.

Usually this goes in the configuration file (config.properties or config.yml in recent master) but in your java code you would do:

hopper = new GraphHopperOSM().init(new CmdArgs().
         put("prepare.min_network_size", "200").
         put("prepare.min_one_way_network_size", "200"));

Make sure you remove the preprocessed data at “graphFolder”. Otherwise this won’t have an effect and just loads the previously generated road network data.

Many thanks. This seems to solve almost all my problems.

May I ask you two more questions:

  1. Where can I find documentation to these two and other similar parameters?
  2. How should I change my code to find the sortest route available? It seems that I have to regenerate the graph folder with some other option? What should I change?

Best wishes,
Michal

Our documentation is here: https://github.com/graphhopper/graphhopper/blob/master/docs/index.md and several parameters are documented in the config.properties (config.yml in latest master)

How should I change my code to find the sortest route available?

weighting=shortest either per request or prepare.ch.weightings=shortest in the config or in your case there where you have the other params now

Many thanks. However, could you possibly hint me more precisely where should I put the weithing parameter? I’m less than novice in both Java and GraphHopper.

My hopper setting is:

    GraphHopper hopper = new GraphHopperOSM();
    hopper.setDataReaderFile(MAP_FILE); //osmFile);
    hopper.init(new CmdArgs().
            put("prepare.min_network_size", "200").
            put("prepare.min_one_way_network_size", "200"));
    hopper.setGraphHopperLocation("graphFolder");
    hopper.setEncodingManager(new EncodingManager("car"));
    hopper.importOrLoad();

My request / response setting is:

    GHRequest req = new GHRequest(latFrom, lonFrom, latTo, lonTo).
            setWeighting(NAVIGATION_TYPE).
            setVehicle("car");
    GHResponse rsp = hopper.route(req);

When I change NAVIGATION_TYPE to “shortest” (from “fastest”), then every request / response fails with the following error message:

[java.lang.IllegalArgumentException: Cannot find CH RoutingAlgorithmFactory for weighting map {weighting=shortest, vehicle=car} in entries fastest|car, ]

Hence I think I have to regenerate the map / hopper with some extra parameter but I don’t know where to put it.

Many thanks for any hint or help.

Best wishes,
Michal