SpeedStorage.java
package org.heigit.ors.routing.graphhopper.extensions.storages;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.storage.DataAccess;
import com.graphhopper.storage.Directory;
import com.graphhopper.storage.Graph;
import com.graphhopper.storage.GraphExtension;
/**
* Simple storage designed to hold edgeID - direction - speed
* Speeds should be in kph
* Indexed by edgeIds
*
* @author Hendrik Leuschner
*/
public class SpeedStorage implements GraphExtension {
private static final long BYTE_COUNT = 2; //One byte for forward speed, one byte for backward speed.
private static final long BYTE_POS_SPEED = 0;
private static final long BYTE_POS_SPEED_REVERSE = 1;
protected DataAccess speedData;
protected int edgeCount;
protected FlagEncoder flagEncoder;
public SpeedStorage(FlagEncoder flagEncoder) {
this.flagEncoder = flagEncoder;
}
@Override
public void init(Graph graph, Directory directory) {
this.speedData = directory.find("ext_speeds_" + this.flagEncoder.toString());
}
@Override
public boolean loadExisting() {
if (!speedData.loadExisting())
return false;
this.edgeCount = speedData.getHeader(0);
return true;
}
/**
* Creates the storage and defaults all values to Byte.MIN_VALUE
*
* @param edgeCount
* @return The storage
*/
@Override
public SpeedStorage create(long edgeCount) {
speedData.create(BYTE_COUNT * edgeCount);
for (int i = 0; i < edgeCount; i++) {
this.setSpeed(i, false, Byte.MIN_VALUE);
this.setSpeed(i, true, Byte.MIN_VALUE);
}
return this;
}
public void setSpeed(int edgeId, boolean reverse, byte speed) {
checkEdgeInBounds(edgeId);
speedData.setBytes(BYTE_COUNT * edgeId + (reverse ? BYTE_POS_SPEED_REVERSE : BYTE_POS_SPEED), new byte[]{speed}, 1);
}
public void setSpeed(int edgeId, boolean reverse, int speed) {
if (speed > Byte.MAX_VALUE || speed < Byte.MIN_VALUE)
throw new IllegalArgumentException("Speed value " + speed + " out of range: " + Byte.MIN_VALUE + " to " + Byte.MAX_VALUE);
this.setSpeed(edgeId, reverse, (byte) speed);
}
public int getSpeed(int edgeId, boolean reverse) {
checkEdgeInBounds(edgeId);
byte[] speedByte = new byte[1];
speedData.getBytes(BYTE_COUNT * edgeId + (reverse ? BYTE_POS_SPEED_REVERSE : BYTE_POS_SPEED), speedByte, 1);
return speedByte[0];
}
public boolean hasSpeed(int edgeId, boolean reverse) {
return this.getSpeed(edgeId, reverse) != Byte.MIN_VALUE;
}
@Override
public long getCapacity() {
return speedData.getCapacity();
}
@Override
public void close() {
speedData.close();
}
@Override
public boolean isClosed() {
return speedData.isClosed();
}
@Override
public void flush() {
speedData.flush();
}
protected void checkEdgeInBounds(int edgeId) {
if (edgeId >= speedData.getCapacity() / BYTE_COUNT) {
speedData.ensureCapacity(edgeId * BYTE_COUNT);
}
}
}