Way.java (4005B)
1 package osm.message; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; 5 import java.util.List; 6 import java.util.Map; 7 import java.util.Set; 8 9 import 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 16 public 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 }