brouter/brouter-map-creator/src/main/java/btools/mapcreator/RestrictionData.java
2022-11-14 22:06:18 +01:00

129 lines
3.2 KiB
Java

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<String, String> names = new HashMap<>();
private static Set<Long> 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_"));
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);
}
}