All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.osm.wayproperty.specifier.Condition Maven / Gradle / Ivy

The newest version!
package org.opentripplanner.osm.wayproperty.specifier;

import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.EXACT;
import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.NONE;
import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.WILDCARD;

import java.util.Arrays;
import org.opentripplanner.osm.model.OsmEntity;

public sealed interface Condition {
  String key();

  default MatchResult matchType() {
    return EXACT;
  }

  boolean isExtendedKeyMatch(OsmEntity way, String exKey);

  /**
   * Test to what degree the OSM entity matches with this operation when taking the regular tag keys
   * into account.
   */
  default boolean isMatch(OsmEntity way) {
    return isExtendedKeyMatch(way, this.key());
  }

  default MatchResult match(OsmEntity way) {
    return isMatch(way) ? matchType() : NONE;
  }

  /**
   * Test to what degree the OSM entity matches with this operation when taking the ':left' key
   * suffixes into account.
   * 

* For example, it should not match a way with `cycleway:right=lane` when the `cycleway=lane` was * required but `cycleway:left=lane` should match. */ default boolean isLeftMatch(OsmEntity way) { var leftKey = this.key() + ":left"; if (way.hasTag(leftKey)) { return isExtendedKeyMatch(way, leftKey); } else { return isExplicitBothMatch(way); } } /** * Test to what degree the OSM entity matches with this operation when taking the ':right' key * suffixes into account. *

* For example, it should not match a way with `cycleway:left=lane` when the `cycleway=lane` was * required but `cycleway:right=lane` should match. */ default boolean isRightMatch(OsmEntity way) { var rightKey = this.key() + ":right"; if (way.hasTag(rightKey)) { return isExtendedKeyMatch(way, rightKey); } else { return isExplicitBothMatch(way); } } /** * Test to what degree the OSM entity matches with this operation when taking the ':both' key * suffixes into account. */ default boolean isExplicitBothMatch(OsmEntity way) { var bothKey = this.key() + ":both"; if (way.hasTag(bothKey)) { return isExtendedKeyMatch(way, bothKey); } else { return isMatch(way); } } default boolean isForwardMatch(OsmEntity way) { var forwardKey = this.key() + ":forward"; if (way.hasTag(forwardKey)) { return isExtendedKeyMatch(way, forwardKey); } else { /* Assumes right hand traffic */ return isRightMatch(way); } } default MatchResult matchForward(OsmEntity way) { return isForwardMatch(way) ? matchType() : NONE; } default boolean isBackwardMatch(OsmEntity way) { var backwardKey = this.key() + ":backward"; if (way.hasTag(backwardKey)) { return isExtendedKeyMatch(way, backwardKey); } else { /* Assumes right hand traffic */ return isLeftMatch(way); } } default MatchResult matchBackward(OsmEntity way) { return isBackwardMatch(way) ? matchType() : NONE; } enum MatchResult { EXACT, WILDCARD, NONE, } /** * Selects tags where a given key/value matches. */ record Equals(String key, String value) implements Condition { @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { return way.hasTag(exKey) && way.isTag(exKey, value); } @Override public String toString() { return "%s=%s".formatted(key, value); } } /** * Selects tags with a given key. */ record Present(String key) implements Condition { @Override public MatchResult matchType() { return WILDCARD; } @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { return way.hasTag(exKey); } @Override public String toString() { return "present(%s)".formatted(key); } } /** * Selects tags where a given tag is absent. */ record Absent(String key) implements Condition { @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { return !way.hasTag(exKey); } @Override public String toString() { return "!%s".formatted(key); } } /** * Selects tags where the integer value is greater than a given number. */ record GreaterThan(String key, int value) implements Condition { @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { var maybeInt = way.getTagAsInt(exKey, ignored -> {}); return maybeInt.isPresent() && maybeInt.getAsInt() > value; } @Override public String toString() { return "%s > %s".formatted(key, value); } } /** * Selects tags where the integer value is less than a given number. */ record LessThan(String key, int value) implements Condition { @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { var maybeInt = way.getTagAsInt(exKey, ignored -> {}); return maybeInt.isPresent() && maybeInt.getAsInt() < value; } @Override public String toString() { return "%s < %s".formatted(key, value); } } /** * Selects integer tag values and checks if they are in between a lower and an upper bound. */ record InclusiveRange(String key, int upper, int lower) implements Condition { public InclusiveRange { if (upper < lower) { throw new IllegalArgumentException("Upper bound is lower than lower bound"); } } @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { var maybeInt = way.getTagAsInt(exKey, ignored -> {}); return maybeInt.isPresent() && maybeInt.getAsInt() >= lower && maybeInt.getAsInt() <= upper; } @Override public String toString() { return "%s > %s < %s".formatted(lower, key, upper); } } /** * Selects a tag which has one of a set of given values. */ record OneOf(String key, String... values) implements Condition { @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { return Arrays.stream(values).anyMatch(value -> way.isTag(exKey, value)); } @Override public String toString() { return "%s one of [%s]".formatted(key, String.join(", ", values)); } } /** * Selects a tag where one of the following conditions is true: * - one of a set of given values matches * - the tag is absent */ record OneOfOrAbsent(String key, String... values) implements Condition { /* A use case for this is to detect the absence of a sidewalk, cycle lane or verge*/ public OneOfOrAbsent(String key) { this(key, "no", "none"); } @Override public boolean isExtendedKeyMatch(OsmEntity way, String exKey) { return ( !way.hasTag(exKey) || Arrays.stream(values).anyMatch(value -> way.isTag(exKey, value)) ); } @Override public String toString() { return "%s not one of [%s] or absent".formatted(key, String.join(", ", values)); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy