OSMAttachedSidewalkProcessor.java
package org.heigit.ors.routing.graphhopper.extensions.reader.osmfeatureprocessors;
import com.graphhopper.reader.ReaderWay;
import java.util.HashSet;
import java.util.Set;
public class OSMAttachedSidewalkProcessor {
public static final String KEY_ORS_SIDEWALK_SIDE = "ors-sidewalk-side";
public static final String VAL_RIGHT = "right";
public static final String VAL_LEFT = "left";
protected enum Side {LEFT, RIGHT, BOTH, NONE}
public boolean hasSidewalkInfo(ReaderWay way) {
return identifySidesWhereSidewalkIsPresent(way) != Side.NONE;
}
/**
* Get the keys that represent sidewalk information
*
* @param way
* @return
*/
protected Set<String> getSidewalkKeys(ReaderWay way) {
Set<String> sidewalkInfoKeys = new HashSet<>();
Set<String> keys = way.getTags().keySet();
for (String k : keys) {
if (isSidewalkInfoKey(k)) {
sidewalkInfoKeys.add(k);
}
}
return sidewalkInfoKeys;
}
/**
* Identify if the specified key could contain sidewalk information
*
* @param osmTagKey
* @return
*/
private boolean isSidewalkInfoKey(String osmTagKey) {
return osmTagKey.startsWith("sidewalk:") || osmTagKey.startsWith("footway:");
}
/**
* Add a tag to the way which signifies which side of the road the sidewalk needs to be processed for
*
* @param way
* @param side
* @return
*/
public ReaderWay attachSidewalkTag(ReaderWay way, Side side) {
switch (side) {
case LEFT:
way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_LEFT);
break;
case RIGHT:
way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_RIGHT);
break;
case BOTH:
if (way.hasTag(KEY_ORS_SIDEWALK_SIDE) && way.getTag(KEY_ORS_SIDEWALK_SIDE).equalsIgnoreCase(VAL_LEFT)) {
// The left side has been attached previously, so now attach the right side
way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_RIGHT);
} else {
// start with the left side
way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_LEFT);
}
break;
case NONE:
if (way.hasTag(KEY_ORS_SIDEWALK_SIDE)) {
way.removeTag(KEY_ORS_SIDEWALK_SIDE);
}
}
return way;
}
/**
* Determine which sidewalk side is to be processed based on the tag that was attached.
*
* @param way
* @return
*/
public Side getPreparedSide(ReaderWay way) {
if (way.hasTag(KEY_ORS_SIDEWALK_SIDE)) {
String preparedSide = way.getTag(KEY_ORS_SIDEWALK_SIDE);
if (preparedSide.equalsIgnoreCase(VAL_LEFT)) {
return Side.LEFT;
}
if (preparedSide.equalsIgnoreCase(VAL_RIGHT)) {
return Side.RIGHT;
}
}
return Side.NONE;
}
/**
* Identify which side there is a sidealk present on the road based on the tags assigned in OSM
*
* @param osmWay
* @return
*/
protected Side identifySidesWhereSidewalkIsPresent(ReaderWay osmWay) {
boolean sidewalkOnLeftSide = false;
boolean sidewalkOnRightSide = false;
boolean sidewalkOnBothSides = false;
if (osmWay.hasTag("sidewalk")) {
String side = osmWay.getTag("sidewalk");
switch (side) {
case VAL_LEFT -> sidewalkOnLeftSide = true;
case VAL_RIGHT -> sidewalkOnRightSide = true;
case "both" -> sidewalkOnBothSides = true;
default -> {
}
}
}
Set<String> sidewalkProperties = getSidewalkKeys(osmWay);
for (String key : sidewalkProperties) {
if (key.startsWith("sidewalk:left") || key.startsWith("footway:left")) sidewalkOnLeftSide = true;
if (key.startsWith("sidewalk:right") || key.startsWith("footway:right")) sidewalkOnRightSide = true;
if (key.startsWith("sidewalk:both") || key.startsWith("footway:both")) sidewalkOnBothSides = true;
}
if (sidewalkOnLeftSide && sidewalkOnRightSide) {
sidewalkOnBothSides = true;
}
if (sidewalkOnBothSides) {
return Side.BOTH;
}
if (sidewalkOnLeftSide) {
return Side.LEFT;
}
if (sidewalkOnRightSide) {
return Side.RIGHT;
}
return Side.NONE;
}
}