Search in sources :

Example 1 with TurnCostStorage

use of com.graphhopper.storage.TurnCostStorage in project graphhopper by graphhopper.

the class CHPreparationGraph method buildTurnCostFunctionFromTurnCostStorage.

/**
 * Builds a turn cost function for a given graph('s turn cost storage) and a weighting.
 * The trivial implementation would be simply returning {@link Weighting#calcTurnWeight}. However, it turned out
 * that reading all turn costs for the current encoder and then storing them in separate arrays upfront speeds up
 * edge-based CH preparation by about 25%. See #2084
 */
public static TurnCostFunction buildTurnCostFunctionFromTurnCostStorage(Graph graph, Weighting weighting) {
    FlagEncoder encoder = weighting.getFlagEncoder();
    String key = TurnCost.key(encoder.toString());
    if (!encoder.hasEncodedValue(key))
        return (inEdge, viaNode, outEdge) -> 0;
    DecimalEncodedValue turnCostEnc = encoder.getDecimalEncodedValue(key);
    TurnCostStorage turnCostStorage = graph.getTurnCostStorage();
    // we maintain a list of inEdge/outEdge/turn-cost triples (we use two arrays for this) that is sorted by nodes
    LongArrayList turnCostEdgePairs = new LongArrayList();
    DoubleArrayList turnCosts = new DoubleArrayList();
    // for each node we store the index of the first turn cost entry/triple in the list
    final int[] turnCostNodes = new int[graph.getNodes() + 1];
    TurnCostStorage.TurnRelationIterator tcIter = turnCostStorage.getAllTurnRelations();
    int lastNode = -1;
    while (tcIter.next()) {
        int viaNode = tcIter.getViaNode();
        if (viaNode < lastNode)
            throw new IllegalStateException();
        long edgePair = BitUtil.LITTLE.combineIntsToLong(tcIter.getFromEdge(), tcIter.getToEdge());
        // note that as long as we only use OSM turn restrictions all the turn costs are infinite anyway
        double turnCost = tcIter.getCost(turnCostEnc);
        int index = turnCostEdgePairs.size();
        turnCostEdgePairs.add(edgePair);
        turnCosts.add(turnCost);
        if (viaNode != lastNode) {
            for (int i = lastNode + 1; i <= viaNode; i++) {
                turnCostNodes[i] = index;
            }
        }
        lastNode = viaNode;
    }
    for (int i = lastNode + 1; i <= turnCostNodes.length - 1; i++) {
        turnCostNodes[i] = turnCostEdgePairs.size();
    }
    turnCostNodes[turnCostNodes.length - 1] = turnCostEdgePairs.size();
    // currently the u-turn costs are the same for all junctions, so for now we just get them for one of them
    double uTurnCosts = weighting.calcTurnWeight(1, 0, 1);
    return (inEdge, viaNode, outEdge) -> {
        if (!EdgeIterator.Edge.isValid(inEdge) || !EdgeIterator.Edge.isValid(outEdge))
            return 0;
        else if (inEdge == outEdge)
            return uTurnCosts;
        // traverse all turn cost entries we have for this viaNode and return the turn costs if we find a match
        for (int i = turnCostNodes[viaNode]; i < turnCostNodes[viaNode + 1]; i++) {
            long l = turnCostEdgePairs.get(i);
            if (inEdge == BitUtil.LITTLE.getIntLow(l) && outEdge == BitUtil.LITTLE.getIntHigh(l))
                return turnCosts.get(i);
        }
        return 0;
    };
}
Also used : IndirectSort(com.carrotsearch.hppc.sorting.IndirectSort) com.carrotsearch.hppc(com.carrotsearch.hppc) TurnCost(com.graphhopper.routing.ev.TurnCost) EdgeIterator(com.graphhopper.util.EdgeIterator) GHUtility(com.graphhopper.util.GHUtility) BitUtil(com.graphhopper.util.BitUtil) ArrayUtil.zero(com.graphhopper.util.ArrayUtil.zero) IndirectComparator(com.carrotsearch.hppc.sorting.IndirectComparator) TurnCostStorage(com.graphhopper.storage.TurnCostStorage) Weighting(com.graphhopper.routing.weighting.Weighting) DecimalEncodedValue(com.graphhopper.routing.ev.DecimalEncodedValue) Graph(com.graphhopper.storage.Graph) FlagEncoder(com.graphhopper.routing.util.FlagEncoder) AllEdgesIterator(com.graphhopper.routing.util.AllEdgesIterator) FlagEncoder(com.graphhopper.routing.util.FlagEncoder) DecimalEncodedValue(com.graphhopper.routing.ev.DecimalEncodedValue) TurnCostStorage(com.graphhopper.storage.TurnCostStorage)

Example 2 with TurnCostStorage

use of com.graphhopper.storage.TurnCostStorage in project graphhopper by graphhopper.

the class OSMTurnRelationParserTest method testGetRestrictionAsEntries.

@Test
public void testGetRestrictionAsEntries() {
    CarFlagEncoder encoder = new CarFlagEncoder(5, 5, 1);
    final Map<Long, Integer> osmNodeToInternal = new HashMap<>();
    final Map<Integer, Long> internalToOSMEdge = new HashMap<>();
    osmNodeToInternal.put(3L, 3);
    // edge ids are only stored if they occurred before in an OSMRelation
    internalToOSMEdge.put(3, 3L);
    internalToOSMEdge.put(4, 4L);
    OSMTurnRelationParser parser = new OSMTurnRelationParser(encoder.toString(), 1, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR));
    GraphHopperStorage ghStorage = new GraphBuilder(new EncodingManager.Builder().add(encoder).addTurnCostParser(parser).build()).create();
    EdgeBasedRoutingAlgorithmTest.initGraph(ghStorage, encoder);
    TurnCostParser.ExternalInternalMap map = new TurnCostParser.ExternalInternalMap() {

        @Override
        public int getInternalNodeIdOfOsmNode(long nodeOsmId) {
            return osmNodeToInternal.getOrDefault(nodeOsmId, -1);
        }

        @Override
        public long getOsmIdOfInternalEdge(int edgeId) {
            Long l = internalToOSMEdge.get(edgeId);
            if (l == null)
                return -1;
            return l;
        }
    };
    // TYPE == ONLY
    OSMTurnRelation instance = new OSMTurnRelation(4, 3, 3, OSMTurnRelation.Type.ONLY);
    parser.addRelationToTCStorage(instance, map, ghStorage);
    TurnCostStorage tcs = ghStorage.getTurnCostStorage();
    DecimalEncodedValue tce = parser.getTurnCostEnc();
    assertTrue(Double.isInfinite(tcs.get(tce, 4, 3, 6)));
    assertEquals(0, tcs.get(tce, 4, 3, 3), .1);
    assertTrue(Double.isInfinite(tcs.get(tce, 4, 3, 2)));
    // TYPE == NOT
    instance = new OSMTurnRelation(4, 3, 3, OSMTurnRelation.Type.NOT);
    parser.addRelationToTCStorage(instance, map, ghStorage);
    assertTrue(Double.isInfinite(tcs.get(tce, 4, 3, 3)));
}
Also used : EncodingManager(com.graphhopper.routing.util.EncodingManager) OSMTurnRelation(com.graphhopper.reader.OSMTurnRelation) HashMap(java.util.HashMap) GraphHopperStorage(com.graphhopper.storage.GraphHopperStorage) DecimalEncodedValue(com.graphhopper.routing.ev.DecimalEncodedValue) GraphBuilder(com.graphhopper.storage.GraphBuilder) TurnCostStorage(com.graphhopper.storage.TurnCostStorage) CarFlagEncoder(com.graphhopper.routing.util.CarFlagEncoder) EdgeBasedRoutingAlgorithmTest(com.graphhopper.routing.EdgeBasedRoutingAlgorithmTest) Test(org.junit.jupiter.api.Test)

Example 3 with TurnCostStorage

use of com.graphhopper.storage.TurnCostStorage in project graphhopper by graphhopper.

the class OSMTurnRelationParser method addRelationToTCStorage.

/**
 * Add the specified relation to the TurnCostStorage
 */
void addRelationToTCStorage(OSMTurnRelation osmTurnRelation, ExternalInternalMap map, Graph graph) {
    TurnCostStorage tcs = graph.getTurnCostStorage();
    int viaNode = map.getInternalNodeIdOfOsmNode(osmTurnRelation.getViaOsmNodeId());
    EdgeExplorer edgeOutExplorer = getOutExplorer(graph), edgeInExplorer = getInExplorer(graph);
    try {
        int edgeIdFrom = EdgeIterator.NO_EDGE;
        // get all incoming edges and receive the edge which is defined by fromOsm
        EdgeIterator iter = edgeInExplorer.setBaseNode(viaNode);
        while (iter.next()) {
            if (map.getOsmIdOfInternalEdge(iter.getEdge()) == osmTurnRelation.getOsmIdFrom()) {
                edgeIdFrom = iter.getEdge();
                break;
            }
        }
        if (!EdgeIterator.Edge.isValid(edgeIdFrom))
            return;
        // get all outgoing edges of the via node
        iter = edgeOutExplorer.setBaseNode(viaNode);
        // for TYPE_NOT_*  we add ONE restriction  (from, via, to)
        while (iter.next()) {
            int edgeId = iter.getEdge();
            long wayId = map.getOsmIdOfInternalEdge(edgeId);
            if (edgeId != edgeIdFrom && osmTurnRelation.getRestriction() == OSMTurnRelation.Type.ONLY && wayId != osmTurnRelation.getOsmIdTo() || osmTurnRelation.getRestriction() == OSMTurnRelation.Type.NOT && wayId == osmTurnRelation.getOsmIdTo() && wayId >= 0) {
                tcs.set(turnCostEnc, edgeIdFrom, viaNode, iter.getEdge(), Double.POSITIVE_INFINITY);
                if (osmTurnRelation.getRestriction() == OSMTurnRelation.Type.NOT)
                    break;
            }
        }
    } catch (Exception e) {
        throw new IllegalStateException("Could not built turn table entry for relation of node with osmId:" + osmTurnRelation.getViaOsmNodeId(), e);
    }
}
Also used : EdgeIterator(com.graphhopper.util.EdgeIterator) EdgeExplorer(com.graphhopper.util.EdgeExplorer) TurnCostStorage(com.graphhopper.storage.TurnCostStorage)

Example 4 with TurnCostStorage

use of com.graphhopper.storage.TurnCostStorage in project graphhopper by graphhopper.

the class DefaultBidirPathExtractorTest method testExtract2.

@Test
public void testExtract2() {
    // 1->2->3
    Graph graph = createGraph();
    GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(1, 2).setDistance(10));
    GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(2, 3).setDistance(20));
    // add some turn costs at node 2 where fwd&bwd searches meet. these costs have to be included in the
    // weight and the time of the path
    TurnCostStorage turnCostStorage = graph.getTurnCostStorage();
    DecimalEncodedValue turnCostEnc = encodingManager.getDecimalEncodedValue(TurnCost.key(carEncoder.toString()));
    turnCostStorage.set(turnCostEnc, 0, 2, 1, 5);
    SPTEntry fwdEntry = new SPTEntry(0, 2, 0.6);
    fwdEntry.parent = new SPTEntry(EdgeIterator.NO_EDGE, 1, 0);
    SPTEntry bwdEntry = new SPTEntry(1, 2, 1.2);
    bwdEntry.parent = new SPTEntry(EdgeIterator.NO_EDGE, 3, 0);
    Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(carEncoder, new DefaultTurnCostProvider(carEncoder, turnCostStorage)), fwdEntry, bwdEntry, 0);
    p.setWeight(5 + 1.8);
    assertEquals(IntArrayList.from(1, 2, 3), p.calcNodes());
    assertEquals(30, p.getDistance(), 1e-4);
    assertEquals(5 + 1.8, p.getWeight(), 1e-4);
    assertEquals(5000 + 1800, p.getTime(), 1.e-6);
}
Also used : Graph(com.graphhopper.storage.Graph) DecimalEncodedValue(com.graphhopper.routing.ev.DecimalEncodedValue) TurnCostStorage(com.graphhopper.storage.TurnCostStorage) FastestWeighting(com.graphhopper.routing.weighting.FastestWeighting) DefaultTurnCostProvider(com.graphhopper.routing.weighting.DefaultTurnCostProvider) Test(org.junit.jupiter.api.Test)

Aggregations

TurnCostStorage (com.graphhopper.storage.TurnCostStorage)4 DecimalEncodedValue (com.graphhopper.routing.ev.DecimalEncodedValue)3 Graph (com.graphhopper.storage.Graph)2 EdgeIterator (com.graphhopper.util.EdgeIterator)2 Test (org.junit.jupiter.api.Test)2 com.carrotsearch.hppc (com.carrotsearch.hppc)1 IndirectComparator (com.carrotsearch.hppc.sorting.IndirectComparator)1 IndirectSort (com.carrotsearch.hppc.sorting.IndirectSort)1 OSMTurnRelation (com.graphhopper.reader.OSMTurnRelation)1 EdgeBasedRoutingAlgorithmTest (com.graphhopper.routing.EdgeBasedRoutingAlgorithmTest)1 TurnCost (com.graphhopper.routing.ev.TurnCost)1 AllEdgesIterator (com.graphhopper.routing.util.AllEdgesIterator)1 CarFlagEncoder (com.graphhopper.routing.util.CarFlagEncoder)1 EncodingManager (com.graphhopper.routing.util.EncodingManager)1 FlagEncoder (com.graphhopper.routing.util.FlagEncoder)1 DefaultTurnCostProvider (com.graphhopper.routing.weighting.DefaultTurnCostProvider)1 FastestWeighting (com.graphhopper.routing.weighting.FastestWeighting)1 Weighting (com.graphhopper.routing.weighting.Weighting)1 GraphBuilder (com.graphhopper.storage.GraphBuilder)1 GraphHopperStorage (com.graphhopper.storage.GraphHopperStorage)1