HillIndexGraphStorage.java

  1. /*  This file is part of Openrouteservice.
  2.  *
  3.  *  Openrouteservice is free software; you can redistribute it and/or modify it under the terms of the
  4.  *  GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1
  5.  *  of the License, or (at your option) any later version.

  6.  *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  7.  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8.  *  See the GNU Lesser General Public License for more details.

  9.  *  You should have received a copy of the GNU Lesser General Public License along with this library;
  10.  *  if not, see <https://www.gnu.org/licenses/>.
  11.  */
  12. package org.heigit.ors.routing.graphhopper.extensions.storages;

  13. import com.graphhopper.storage.DataAccess;
  14. import com.graphhopper.storage.Directory;
  15. import com.graphhopper.storage.Graph;
  16. import com.graphhopper.storage.GraphExtension;

  17. import java.util.Map;

  18. public class HillIndexGraphStorage implements GraphExtension {
  19.     private final int efHillIndex;

  20.     private DataAccess orsEdges;
  21.     protected int edgeEntryIndex = 0;
  22.     protected int edgeEntryBytes;
  23.     protected int edgesCount; // number of edges with custom values

  24.     private int maxHillIndex = 15;

  25.     private final byte[] byteValues;

  26.     public HillIndexGraphStorage(Map<String, String> parameters) {
  27.         efHillIndex = 0;

  28.         if (parameters.containsKey("maximum_slope"))
  29.             maxHillIndex = (int) Double.parseDouble(parameters.get("maximum_slope"));

  30.         edgeEntryBytes = edgeEntryIndex + (maxHillIndex > 15 ? 2 : 1);
  31.         edgesCount = 0;
  32.         byteValues = new byte[2];
  33.     }

  34.     public void init(Graph graph, Directory dir) {
  35.         if (edgesCount > 0)
  36.             throw new AssertionError("The ORS storage must be initialized only once.");

  37.         this.orsEdges = dir.find("ext_hillindex");
  38.     }

  39.     public HillIndexGraphStorage create(long initBytes) {
  40.         orsEdges.create(initBytes * edgeEntryBytes);
  41.         return this;
  42.     }

  43.     public void flush() {
  44.         orsEdges.setHeader(0, edgeEntryBytes);
  45.         orsEdges.setHeader(4, edgesCount);
  46.         orsEdges.flush();
  47.     }

  48.     @Override
  49.     public long getCapacity() {
  50.         return orsEdges.getCapacity();
  51.     }

  52.     public void close() {
  53.         orsEdges.close();
  54.     }

  55.     public int entries() {
  56.         return edgesCount;
  57.     }

  58.     public boolean loadExisting() {
  59.         if (!orsEdges.loadExisting())
  60.             throw new IllegalStateException("Unable to load storage 'ext_hillindex'. corrupt file or directory?");

  61.         edgeEntryBytes = orsEdges.getHeader(0);
  62.         edgesCount = orsEdges.getHeader(4);
  63.         return true;
  64.     }

  65.     private void ensureEdgesIndex(int edgeIndex) {
  66.         orsEdges.ensureCapacity(((long) edgeIndex + 1) * edgeEntryBytes);
  67.     }

  68.     private int getHillIndex(int value) {
  69.         return Math.min(value, maxHillIndex);
  70.     }

  71.     public void setEdgeValue(int edgeId, int hillIndex, int reverseHillIndex) {
  72.         edgesCount++;
  73.         ensureEdgesIndex(edgeId);

  74.         if (hillIndex != 0 || reverseHillIndex != 0) {
  75.             // add entry
  76.             long edgePointer = (long) edgeId * edgeEntryBytes;
  77.             if (maxHillIndex <= 15) {
  78.                 byteValues[0] = (byte) (getHillIndex(hillIndex) << 4 | (0x0F & getHillIndex(reverseHillIndex))); //hillIndex | (reverseHillIndex << 4))
  79.                 orsEdges.setBytes(edgePointer + efHillIndex, byteValues, 1);
  80.             } else {
  81.                 byteValues[0] = (byte) getHillIndex(hillIndex);
  82.                 byteValues[1] = (byte) getHillIndex(reverseHillIndex);
  83.                 orsEdges.setBytes(edgePointer + efHillIndex, byteValues, 2);
  84.             }
  85.         }
  86.     }

  87.     public int getEdgeValue(int edgeId, boolean reverse, byte[] buffer) {
  88.         long edgePointer = (long) edgeId * edgeEntryBytes;

  89.         if (maxHillIndex <= 15) {
  90.             orsEdges.getBytes(edgePointer + efHillIndex, buffer, 1);

  91.             int value = buffer[0];
  92.             if (value < 0)
  93.                 value = 256 + value;

  94.             if (reverse)
  95.                 return (value >> 4) & 0xF;
  96.             else
  97.                 return value & 0xF;
  98.         } else {
  99.             orsEdges.getBytes(edgePointer + efHillIndex, buffer, 2);

  100.             return reverse ? buffer[1] : buffer[0];
  101.         }
  102.     }

  103.     @Override
  104.     public boolean isClosed() {
  105.         return false;
  106.     }
  107. }