OSMAttachedSidewalkProcessor.java

  1. package org.heigit.ors.routing.graphhopper.extensions.reader.osmfeatureprocessors;

  2. import com.graphhopper.reader.ReaderWay;

  3. import java.util.HashSet;
  4. import java.util.Set;

  5. public class OSMAttachedSidewalkProcessor {

  6.     public static final String KEY_ORS_SIDEWALK_SIDE = "ors-sidewalk-side";
  7.     public static final String VAL_RIGHT = "right";
  8.     public static final String VAL_LEFT = "left";

  9.     protected enum Side {LEFT, RIGHT, BOTH, NONE}

  10.     public boolean hasSidewalkInfo(ReaderWay way) {
  11.         return identifySidesWhereSidewalkIsPresent(way) != Side.NONE;
  12.     }

  13.     /**
  14.      * Get the keys that represent sidewalk information
  15.      *
  16.      * @param way
  17.      * @return
  18.      */
  19.     protected Set<String> getSidewalkKeys(ReaderWay way) {
  20.         Set<String> sidewalkInfoKeys = new HashSet<>();

  21.         Set<String> keys = way.getTags().keySet();
  22.         for (String k : keys) {
  23.             if (isSidewalkInfoKey(k)) {
  24.                 sidewalkInfoKeys.add(k);
  25.             }
  26.         }

  27.         return sidewalkInfoKeys;
  28.     }

  29.     /**
  30.      * Identify if the specified key could contain sidewalk information
  31.      *
  32.      * @param osmTagKey
  33.      * @return
  34.      */
  35.     private boolean isSidewalkInfoKey(String osmTagKey) {
  36.         return osmTagKey.startsWith("sidewalk:") || osmTagKey.startsWith("footway:");
  37.     }

  38.     /**
  39.      * Add a tag to the way which signifies which side of the road the sidewalk needs to be processed for
  40.      *
  41.      * @param way
  42.      * @param side
  43.      * @return
  44.      */
  45.     public ReaderWay attachSidewalkTag(ReaderWay way, Side side) {
  46.         switch (side) {
  47.             case LEFT:
  48.                 way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_LEFT);
  49.                 break;
  50.             case RIGHT:
  51.                 way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_RIGHT);
  52.                 break;
  53.             case BOTH:
  54.                 if (way.hasTag(KEY_ORS_SIDEWALK_SIDE) && way.getTag(KEY_ORS_SIDEWALK_SIDE).equalsIgnoreCase(VAL_LEFT)) {
  55.                     // The left side has been attached previously, so now attach the right side
  56.                     way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_RIGHT);
  57.                 } else {
  58.                     // start with the left side
  59.                     way.setTag(KEY_ORS_SIDEWALK_SIDE, VAL_LEFT);
  60.                 }
  61.                 break;
  62.             case NONE:
  63.                 if (way.hasTag(KEY_ORS_SIDEWALK_SIDE)) {
  64.                     way.removeTag(KEY_ORS_SIDEWALK_SIDE);
  65.                 }
  66.         }

  67.         return way;
  68.     }

  69.     /**
  70.      * Determine which sidewalk side is to be processed based on the tag that was attached.
  71.      *
  72.      * @param way
  73.      * @return
  74.      */
  75.     public Side getPreparedSide(ReaderWay way) {
  76.         if (way.hasTag(KEY_ORS_SIDEWALK_SIDE)) {
  77.             String preparedSide = way.getTag(KEY_ORS_SIDEWALK_SIDE);
  78.             if (preparedSide.equalsIgnoreCase(VAL_LEFT)) {
  79.                 return Side.LEFT;
  80.             }
  81.             if (preparedSide.equalsIgnoreCase(VAL_RIGHT)) {
  82.                 return Side.RIGHT;
  83.             }
  84.         }

  85.         return Side.NONE;
  86.     }

  87.     /**
  88.      * Identify which side there is a sidealk present on the road based on the tags assigned in OSM
  89.      *
  90.      * @param osmWay
  91.      * @return
  92.      */
  93.     protected Side identifySidesWhereSidewalkIsPresent(ReaderWay osmWay) {
  94.         boolean sidewalkOnLeftSide = false;
  95.         boolean sidewalkOnRightSide = false;
  96.         boolean sidewalkOnBothSides = false;

  97.         if (osmWay.hasTag("sidewalk")) {
  98.             String side = osmWay.getTag("sidewalk");
  99.             switch (side) {
  100.                 case VAL_LEFT -> sidewalkOnLeftSide = true;
  101.                 case VAL_RIGHT -> sidewalkOnRightSide = true;
  102.                 case "both" -> sidewalkOnBothSides = true;
  103.                 default -> {
  104.                 }
  105.             }
  106.         }

  107.         Set<String> sidewalkProperties = getSidewalkKeys(osmWay);

  108.         for (String key : sidewalkProperties) {
  109.             if (key.startsWith("sidewalk:left") || key.startsWith("footway:left")) sidewalkOnLeftSide = true;
  110.             if (key.startsWith("sidewalk:right") || key.startsWith("footway:right")) sidewalkOnRightSide = true;
  111.             if (key.startsWith("sidewalk:both") || key.startsWith("footway:both")) sidewalkOnBothSides = true;
  112.         }

  113.         if (sidewalkOnLeftSide && sidewalkOnRightSide) {
  114.             sidewalkOnBothSides = true;
  115.         }

  116.         if (sidewalkOnBothSides) {
  117.             return Side.BOTH;
  118.         }

  119.         if (sidewalkOnLeftSide) {
  120.             return Side.LEFT;
  121.         }

  122.         if (sidewalkOnRightSide) {
  123.             return Side.RIGHT;
  124.         }

  125.         return Side.NONE;
  126.     }
  127. }