package btools.mapcreator; import java.io.BufferedWriter; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeSet; import btools.util.CheapAngleMeter; /** * Container for a turn restriction * * @author ab */ public class RestrictionData extends MapCreatorBase { public String restrictionKey; public String restriction; public short exceptions; public long fromWid; public long toWid; public long viaNid; public RestrictionData next; public int viaLon; public int viaLat; public int fromLon; public int fromLat; public int toLon; public int toLat; public boolean badWayMatch; private static Map names = new HashMap<>(); private static Set badTRs = new TreeSet<>(); public RestrictionData() { } public boolean isPositive() { return restriction.startsWith("only_"); } public boolean isValid() { boolean valid = fromLon != 0 && toLon != 0 && (restriction.startsWith("only_") || restriction.startsWith("no_")); valid = valid && restriction.indexOf("on_red") < 0; // filter out on-red restrictions if ((!valid) || badWayMatch || !(checkGeometry())) { synchronized (badTRs) { badTRs.add(((long) viaLon) << 32 | viaLat); } } return valid && "restriction".equals(restrictionKey); } private boolean checkGeometry() { double a = (new CheapAngleMeter()).calcAngle(fromLon, fromLat, viaLon, viaLat, toLon, toLat); String t; if (restriction.startsWith("only_")) { t = restriction.substring("only_".length()); } else if (restriction.startsWith("no_")) { t = restriction.substring("no_".length()); } else throw new RuntimeException("ups"); if (restrictionKey.endsWith(":conditional")) { int idx = t.indexOf('@'); if (idx >= 0) { t = t.substring(0, idx).trim(); } } if ("left_turn".equals(t)) { return a < -5. && a > -175.; } if ("right_turn".equals(t)) { return a > 5. && a < 175.; } if ("straight_on".equals(t)) { return a > -85. && a < 85.; } if ("u_turn".equals(t)) { return a < -95. || a > 95.; } return "entry".equals(t) || "exit".equals(t); } private static String unifyName(String name) { synchronized (names) { String n = names.get(name); if (n == null) { names.put(name, name); n = name; } return n; } } public static void dumpBadTRs() { try (BufferedWriter bw = new BufferedWriter(new FileWriter("badtrs.txt"))) { for (Long id : badTRs) { bw.write("" + id + " 26\n"); } } catch (IOException ioe) { throw new RuntimeException(ioe); } } public RestrictionData(DataInputStream di) throws Exception { restrictionKey = unifyName(di.readUTF()); restriction = unifyName(di.readUTF()); exceptions = di.readShort(); fromWid = readId(di); toWid = readId(di); viaNid = readId(di); } public void writeTo(DataOutputStream dos) throws Exception { dos.writeUTF(restrictionKey); dos.writeUTF(restriction); dos.writeShort(exceptions); writeId(dos, fromWid); writeId(dos, toWid); writeId(dos, viaNid); } }