RangeDijkstra.java

  1. /*
  2.  *  Licensed to GraphHopper GmbH under one or more contributor
  3.  *  license agreements. See the NOTICE file distributed with this work for
  4.  *  additional information regarding copyright ownership.
  5.  *
  6.  *  GraphHopper GmbH licenses this file to you under the Apache License,
  7.  *  Version 2.0 (the "License"); you may not use this file except in
  8.  *  compliance with the License. You may obtain a copy of the License at
  9.  *
  10.  *       http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  *  Unless required by applicable law or agreed to in writing, software
  13.  *  distributed under the License is distributed on an "AS IS" BASIS,
  14.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  *  See the License for the specific language governing permissions and
  16.  *  limitations under the License.
  17.  */
  18. package org.heigit.ors.fastisochrones;

  19. import com.carrotsearch.hppc.IntHashSet;
  20. import com.carrotsearch.hppc.cursors.IntObjectCursor;
  21. import com.graphhopper.routing.SPTEntry;
  22. import com.graphhopper.routing.weighting.Weighting;
  23. import com.graphhopper.storage.Graph;
  24. import com.graphhopper.util.EdgeExplorer;
  25. import com.graphhopper.util.EdgeIterator;

  26. import java.util.HashSet;
  27. import java.util.Set;

  28. import static org.heigit.ors.fastisochrones.partitioning.FastIsochroneParameters.RANGEDIJKSTRA;

  29. /**
  30.  * calculates maximum range (eccentricity) within a cell.
  31.  * <p>
  32.  *
  33.  * @author Hendrik Leuschner
  34.  */
  35. public class RangeDijkstra extends AbstractIsochroneDijkstra {
  36.     private static final boolean USERELEVANTONLY = true;
  37.     private double maximumWeight = 0;
  38.     private IntHashSet cellNodes;
  39.     private final Set<Integer> visitedIds = new HashSet<>();
  40.     private IntHashSet relevantNodes = new IntHashSet();

  41.     public RangeDijkstra(Graph graph, Weighting weighting) {
  42.         super(graph, weighting);
  43.     }

  44.     public double calcMaxWeight(int from, IntHashSet relevantNodes) {
  45.         checkAlreadyRun();
  46.         currEdge = new SPTEntry(EdgeIterator.NO_EDGE, from, 0);
  47.         this.relevantNodes = relevantNodes;
  48.         if (!traversalMode.isEdgeBased()) {
  49.             fromMap.put(from, currEdge);
  50.         }
  51.         if (cellNodes.contains(from))
  52.             visitedIds.add(from);
  53.         else
  54.             throw new IllegalArgumentException("Start node does not belong to cell?");
  55.         runAlgo();
  56.         getMaxWeight();
  57.         return maximumWeight;
  58.     }

  59.     private void getMaxWeight() {
  60.         for (IntObjectCursor<SPTEntry> entry : fromMap) {
  61.             if (USERELEVANTONLY && !relevantNodes.contains(entry.key))
  62.                 continue;

  63.             if (maximumWeight < entry.value.weight)
  64.                 maximumWeight = entry.value.weight;
  65.         }
  66.     }

  67.     protected void runAlgo() {
  68.         EdgeExplorer explorer = graph.createEdgeExplorer();
  69.         while (true) {
  70.             visitedNodes++;
  71.             if (isMaxVisitedNodesExceeded() || finished())
  72.                 break;

  73.             int startNode = currEdge.adjNode;
  74.             EdgeIterator iter = explorer.setBaseNode(startNode);
  75.             while (iter.next()) {
  76.                 if (!accept(iter, currEdge.edge))
  77.                     continue;
  78.                 int traversalId = traversalMode.createTraversalId(iter, false);

  79.                 if (cellNodes.contains(traversalId))
  80.                     visitedIds.add(traversalId);

  81.                 double tmpWeight = weighting.calcEdgeWeight(iter, reverseDirection, currEdge.originalEdge) + currEdge.weight;
  82.                 if (Double.isInfinite(tmpWeight))
  83.                     continue;

  84.                 SPTEntry nEdge = fromMap.get(traversalId);
  85.                 if (nEdge == null) {
  86.                     createEntry(iter, traversalId, tmpWeight);
  87.                 } else if (nEdge.weight > tmpWeight) {
  88.                     updateEntry(nEdge, iter, tmpWeight);
  89.                 }
  90.             }

  91.             if (fromHeap.isEmpty())
  92.                 break;

  93.             currEdge = fromHeap.poll();
  94.             if (currEdge == null)
  95.                 throw new AssertionError("Empty edge cannot happen");
  96.         }
  97.     }

  98.     @Override
  99.     protected boolean finished() {
  100.         return false;
  101.     }

  102.     public void setCellNodes(IntHashSet cellNodes) {
  103.         this.cellNodes = cellNodes;
  104.     }

  105.     public int getFoundCellNodeSize() {
  106.         return visitedIds.size();
  107.     }

  108.     @Override
  109.     public String getName() {
  110.         return RANGEDIJKSTRA;
  111.     }
  112. }