misc/persolijn

osm-protobuf/src/main/java/osm/message/Way.java in master
Repositories | Summary | Log | Files

Way.java (4005B) download


  1package osm.message;
  2
  3import java.util.ArrayList;
  4import java.util.Iterator;
  5import java.util.List;
  6import java.util.Map;
  7import java.util.Set;
  8
  9import protobuf.ProtobufReader;
 10
 11// required int64 id = 1;
 12// repeated uint32 keys = 2 [packed = true];
 13// repeated uint32 vals = 3 [packed = true];
 14// optional Info info = 4;
 15// repeated sint64 refs = 8 [packed = true]; // DELTA coded
 16public class Way extends AbstractEntity<Way> {
 17    public enum Direction {
 18        FORWARDS(1), BACKWARDS(-1);
 19
 20        public final int increment;
 21
 22        private Direction(int increment) {
 23            this.increment = increment;
 24        }
 25
 26        public int getStartPoint(int size) {
 27            return switch (increment) {
 28                case 1 -> 0;
 29                case -1 -> size - 1;
 30                default -> throw new RuntimeException("increment must be -1 or 1");
 31            };
 32        }
 33    }
 34
 35    public static final Set<String> WAY_NO_ALLOWED = Set.of(
 36            "pedestrian",
 37            "path",
 38            "bridleway",
 39            "cycleway",
 40            "footway",
 41            "steps");
 42
 43    public static final Map<String, String> WAY_DEFAULT_SPEED = Map.of(
 44            "motorway", "120",
 45            "trunk", "100",
 46            "primary", "80",
 47            "secondary", "80",
 48            "tertiary", "60",
 49            "unclassified", "60",
 50            "residential", "50");
 51
 52    public static final String WAY_UNLIMITED_SPEED = "100";
 53
 54    public final List<Long> children = new ArrayList<>();
 55    public double speedForwards = 0;
 56    public double speedBackwards = 0;
 57
 58    public Way(PrimitiveBlock block) {
 59        super(block);
 60    }
 61
 62    protected boolean isAllowed(Direction direction) {
 63        if (!tags.containsKey("highway"))
 64            return false;
 65
 66        boolean allowed = !WAY_NO_ALLOWED.contains(tags.get("highway"))
 67                || tags.getBoolean("access", v -> false)
 68                || tags.getBoolean("motor_vehicle", v -> false)
 69                || tags.getBoolean("taxi", v -> false)
 70                || tags.getBoolean("psv", v -> false);
 71
 72        if (direction == Direction.BACKWARDS) {
 73            if (tags.getBoolean("oneway"))
 74                allowed = false;
 75
 76            allowed = allowed
 77                    || tags.getBoolean("access:backwards", v -> false)
 78                    || tags.getBoolean("motor_vehicle:backwards", v -> false)
 79                    || tags.getBoolean("psv:backwards", v -> false)
 80                    || tags.getBoolean("taxi:backwards", v -> false);
 81        }
 82
 83        return allowed;
 84    }
 85
 86    protected double getSpeed(Direction direction) {
 87        String speed = "60";
 88        String defaultSpeed;
 89
 90        defaultSpeed = speed = WAY_DEFAULT_SPEED.getOrDefault(tags.get("highway"), speed);
 91        speed = tags.getOrDefault("maxspeed", speed);
 92
 93        if (direction == Direction.BACKWARDS)
 94            speed = tags.getOrDefault("maxspeed:backwards", speed);
 95
 96        if (speed.equals("none"))
 97            speed = WAY_UNLIMITED_SPEED;
 98
 99        try {
100            return Double.parseDouble(speed) / 3.6;
101        } catch (NumberFormatException exc) {
102            return Double.parseDouble(defaultSpeed) / 3.6;
103        }
104    }
105
106    @Override
107    public Way parseRemaining(Iterator<ProtobufReader> tags) {
108        while (tags.hasNext()) {
109            ProtobufReader message = tags.next();
110            switch (message.tag()) {
111                case 4 -> message.skip();
112                case 8 -> message.packed(message::svarint64, 0l, Long::sum)
113                        .forEachRemaining(children::add);
114                default -> message.throwUnexpected();
115            }
116        }
117
118        if (isAllowed(Direction.FORWARDS))
119            speedForwards = getSpeed(Direction.FORWARDS);
120
121        if (isAllowed(Direction.BACKWARDS))
122            speedBackwards = getSpeed(Direction.BACKWARDS);
123
124        return this;
125    }
126
127    @Override
128    public String toString() {
129        return String.format("Way#%d[%dnodes]", id, children.size());
130    }
131}