Problem with route building through oneway segment

Hello,

I am having trouble building route through unidirectional segment. For the sake of simplicity, I am trying to build the route through single way, from start to end. When in osm file corresponding way has oneway=no, the route is built normally. However, when I change oneway=yes, the route isn’t built in both directions - forward and backward. Here’s my minimal example:

package testroute;

import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.GraphHopper;
import com.graphhopper.config.CHProfile;
import com.graphhopper.config.Profile;
import com.graphhopper.util.GHUtility;
import com.graphhopper.util.shapes.GHPoint;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class TestOnewayRoute {
    private static final Logger logger = LoggerFactory.getLogger(TestOnewayRoute.class);

    public static void clearCache(String folder) {
        try {
            Process process = new ProcessBuilder("rm", "-rf", folder).start();
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException("Failed to clear cache", e);
        }
    }

    static GraphHopper createHopper(String filename) {
        var cacheFolder = "cache";
        clearCache(cacheFolder);
        GraphHopper hopper = new GraphHopper();
        hopper.setOSMFile(filename);
        hopper.setGraphHopperLocation(cacheFolder);
        hopper.setEncodedValuesString("car_access, car_average_speed, road_access");
        hopper.setProfiles(new Profile("car").setCustomModel(GHUtility.loadCustomModelFromJar("car.json")));
        hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("car"));
        hopper.importOrLoad();
        return hopper;
    }

    private void buildRoute(String filename, GHPoint from, GHPoint to) {
        try {
            var hopper = createHopper(filename);
            var request = new GHRequest().setProfile("car").addPoint(from).addPoint(to);
            GHResponse response = hopper.route(request);
            var route = response.getBest().getPoints();
            assert from.equals(route.get(0)) && to.equals(route.get(route.size() - 1));
            logger.info(String.format("Route built successfully for %s from %s to %s", filename, from, to));
        } catch (Exception e) {
            logger.info(String.format("Failed to build route for %s from %s to %s: %s", filename, from, to, e));
        }
    }

    @Test
    public void test() {
        var from = new GHPoint(55.8009173, 37.7069076);
        var to = new GHPoint(55.8031634, 37.7058660);
        buildRoute("oneway-no.osm", from, to);
        buildRoute("oneway-yes.osm", from, to);
        buildRoute("oneway-yes.osm", to, from);
    }
}

The output:

Route built successfully for data/oneway-no.osm from 55.8009173,37.7069076 to 55.8031634,37.705866
Failed to build route for data/oneway-yes.osm from 55.8009173,37.7069076 to 55.8031634,37.705866: java.lang.RuntimeException: Cannot fetch best response if list is empty
Failed to build route for data/oneway-yes.osm from 55.8031634,37.705866 to 55.8009173,37.7069076: java.lang.RuntimeException: Cannot fetch best response if list is empty

data files to reproduce the test

Any help would be appreciated.

If you set hopper.setMinNetworkSize(0); it works: The route will be found in one direction and there will be a connection-not-found error for the other. This is because without this setting GraphHopper will recognize the two directions of the edge as single edge subnetworks: edges that lead nowhere. Your example is very contrived (only a single road). Did you run into a similar problem on a bigger map?

@easbar thanks for your answer, it helped. Answering your question: yes, I indeed ran into the similar problem on bigger map, but unfortunately I can’t share it, that’s why I made this minimal example.