Edge direction problem

I’m trying to calculate heading of edge, so I need to know start node id and end node id of edges. In the document https://github.com/graphhopper/graphhopper/blob/master/docs/core/technical.md, it said if the edge is like: A→B, then nodeA should be smaller than nodeB. However, in my application, there isn’t such rule to restrict node order, which some edges nodeA is larger than nodeB. I also use flagencoder like this: How to determine allowed directions of travel for an edge?. However, it get both true for an edge, which in my thoughts, it should be one for true and one for false.

I’m not sure if I understand what you are trying to do, but you can get the node IDs of an edge like this:

int base = edgeState.getBaseNode();
int adj = edgeState.getAdjNode();

Then you can get the GPS coordinates of these nodes like this:

double lat = graph.getNodeAccess().getLat(base);
double lon = graph.getNodeAccess().getLon(base);
// ... and the same for adj

Using the GPS coordinates it should be easy to calculate the heading of the edge.
GraphHopper provides some helper methods for this. For example you can do:

double angle = new AngleCalc().calcOrientation(latBase, lonBase, latAdj, lonAdj);

which will give you the angle relative to east.

Thank you easbar. However the problem is that the

getBaseNode(), getAdjNode()

method doesn’t mean the edge is BaseNode→AdjNode, it also could be AdjNode→BaseNode, which in that cases, the calculated angle is opposed to real heading.

Yes, GraphHopper edges are undirected, but they have access flags that indicate whether they are accessible in both directions or not (see the other discussion you linked to). So except for one-way streets every edge basically has two headings, but without further information it is not clear to me which one you are looking for.

If I want to use flags to indicate the edge can only accessible in one directions, what should I change? Basically, I am now using original graphhopper mapmatching, and the config of graphhopper is like this:

GraphHopperConfig graphHopperConfiguration = new GraphHopperConfig();
String ghFolder = “graph-cache”;
graphHopperConfiguration.putObject(“graph.location”, ghFolder);

    String vehicle = args.getString("vehicle");
    if (Helper.isEmpty(vehicle))
        vehicle = EncodingManager.create(new DefaultEncodedValueFactory(), new DefaultFlagEncoderFactory(), ghFolder).fetchEdgeEncoders().get(0).toString();
    // Penalizing inner-link U-turns only works with fastest weighting, since
    // shortest weighting does not apply penalties to unfavored virtual edges.
    String weightingStr = "fastest";
    Profile profile = new Profile(vehicle + "_profile").setVehicle(vehicle).setWeighting(weightingStr).setTurnCosts(false);
    graphHopperConfiguration.setProfiles(Collections.singletonList(profile));
    GraphHopper hopper = new GraphHopperOSM().init(graphHopperConfiguration);
    System.out.println("loading graph from cache");
    hopper.load(graphHopperConfiguration.getString("graph.location", ghFolder));

    PMap hints = new PMap().putObject(MAX_VISITED_NODES, args.get("max_visited_nodes"));
    hints.putObject("profile", profile.getName());
    MapMatching mapMatching = new MapMatching(hopper, hints);
    mapMatching.setTransitionProbabilityBeta(args.getDouble("transition_probability_beta"));
    mapMatching.setMeasurementErrorSigma(args.getDouble("gps_accuracy"));
    mapMatching.setEvaluation(args.getBoolean("evaluation"));

I use

flagencoder = graphHopper.getEncodingManager().getEncoder(“car”);

to get what I want. Thank you for your help.

You should probably take a look at how GraphHopper handles the oneway=yes tag. If there is a oneway tag GraphHopper will use the access encoded value to restrict the access of an edge in one direction only.

Powered by Discourse