Fix routing
This commit is contained in:
parent
13910d284d
commit
3030c73f8a
3 changed files with 82 additions and 62 deletions
|
@ -28,6 +28,7 @@ import java.util.Comparator;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import gnu.trove.iterator.TLongObjectIterator;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
@ -296,12 +297,14 @@ public class BinaryMapRouteReaderAdapter {
|
|||
public Map<String, Integer> decodingRules = null;
|
||||
List<RouteSubregion> subregions = new ArrayList<RouteSubregion>();
|
||||
List<RouteSubregion> basesubregions = new ArrayList<RouteSubregion>();
|
||||
List<Integer> trafficSignalsTags = new ArrayList<>();
|
||||
|
||||
int directionForward = -1;
|
||||
int directionBackward = -1;
|
||||
int directionTrafficSignalsForward = -1;
|
||||
int directionTrafficSignalsBackward = -1;
|
||||
public int directionForward = -1;
|
||||
public int directionBackward = -1;
|
||||
public int directionTrafficSignalsForward = -1;
|
||||
public int directionTrafficSignalsBackward = -1;
|
||||
public int trafficSignals = -1;
|
||||
public int stopSign = -1;
|
||||
public int giveWaySign = -1;
|
||||
|
||||
int nameTypeRule = -1;
|
||||
int refTypeRule = -1;
|
||||
|
@ -359,8 +362,12 @@ public class BinaryMapRouteReaderAdapter {
|
|||
destinationTypeRule = id;
|
||||
} else if (tags.equals("destination:ref") || tags.equals("destination:ref:forward") || tags.equals("destination:ref:backward")) {
|
||||
destinationRefTypeRule = id;
|
||||
} else if (tags.equals("highway") && (val.equals("traffic_signals") || val.equals("stop") || val.equals("give_way"))){
|
||||
trafficSignalsTags.add(id);
|
||||
} else if (tags.equals("highway") && val.equals("traffic_signals")){
|
||||
trafficSignals = id;
|
||||
} else if (tags.equals("highway") && val.equals("stop")){
|
||||
stopSign = id;
|
||||
} else if (tags.equals("highway") && val.equals("give_way")){
|
||||
giveWaySign = id;
|
||||
} else if (tags.equals("traffic_signals:direction")){
|
||||
if (val.equals("forward")) {
|
||||
directionTrafficSignalsForward = id;
|
||||
|
@ -376,19 +383,6 @@ public class BinaryMapRouteReaderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isTrafficSignalsRule(int ruleId) {
|
||||
return trafficSignalsTags.contains(ruleId);
|
||||
}
|
||||
|
||||
public int getTrafficSignalDirection(int ruleId) {
|
||||
if (ruleId == directionForward || ruleId == directionTrafficSignalsForward) {
|
||||
return 1;
|
||||
} else if (ruleId == directionBackward || ruleId == directionTrafficSignalsBackward) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void completeRouteEncodingRules() {
|
||||
for(int i = 0; i < routeEncodingRules.size(); i++) {
|
||||
|
|
|
@ -357,58 +357,71 @@ public class GeneralRouter implements VehicleRouter {
|
|||
public float defineObstacle(RouteDataObject road, int point, boolean dir) {
|
||||
int[] pointTypes = road.getPointTypes(point);
|
||||
if(pointTypes != null) {
|
||||
Float obst = getCache(RouteDataObjectAttribute.OBSTACLES, road.region, pointTypes);
|
||||
Float obst = getCache(RouteDataObjectAttribute.OBSTACLES, road.region, pointTypes, dir);
|
||||
if(obst == null) {
|
||||
obst = getObjContext(RouteDataObjectAttribute.OBSTACLES).evaluateFloat(road.region, pointTypes, 0);
|
||||
putCache(RouteDataObjectAttribute.OBSTACLES, road.region, pointTypes, obst);
|
||||
int[] filteredPointTypes = filterDirectionTags(road, pointTypes, dir);
|
||||
obst = getObjContext(RouteDataObjectAttribute.OBSTACLES).evaluateFloat(road.region, filteredPointTypes, 0);
|
||||
putCache(RouteDataObjectAttribute.OBSTACLES, road.region, pointTypes, obst, dir);
|
||||
}
|
||||
return obst;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean foundDirRule = false;
|
||||
TIntArrayList filteredRules = new TIntArrayList();
|
||||
|
||||
@Override
|
||||
public float defineRoutingObstacle(RouteDataObject road, int point, boolean dir) {
|
||||
int[] pointTypes = road.getPointTypes(point);
|
||||
if (pointTypes != null) {
|
||||
filteredRules.clear();
|
||||
for (int i = 0; i < pointTypes.length; i++) {
|
||||
foundDirRule = false;
|
||||
if (road.region.isTrafficSignalsRule(pointTypes[i])) {
|
||||
for (int rid : pointTypes) {
|
||||
if (rid != pointTypes[i]) {
|
||||
int trafficSignalDir = road.region.getTrafficSignalDirection(rid);
|
||||
if (trafficSignalDir != 0) {
|
||||
if ((dir && trafficSignalDir > 0) || (!dir && trafficSignalDir < 0)) {
|
||||
filteredRules.add(pointTypes[i]);
|
||||
}
|
||||
foundDirRule = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundDirRule) {
|
||||
filteredRules.add(pointTypes[i]);
|
||||
}
|
||||
} else if (road.region.getTrafficSignalDirection(pointTypes[i]) == 0) {
|
||||
filteredRules.add(pointTypes[i]);
|
||||
}
|
||||
}
|
||||
pointTypes = filteredRules.size() > 0 ? filteredRules.toArray() : null;
|
||||
|
||||
}
|
||||
if(pointTypes != null) {
|
||||
Float obst = getCache(RouteDataObjectAttribute.ROUTING_OBSTACLES, road.region, pointTypes);
|
||||
Float obst = getCache(RouteDataObjectAttribute.ROUTING_OBSTACLES, road.region, pointTypes, dir);
|
||||
if(obst == null) {
|
||||
obst = getObjContext(RouteDataObjectAttribute.ROUTING_OBSTACLES).evaluateFloat(road.region, pointTypes, 0);
|
||||
putCache(RouteDataObjectAttribute.ROUTING_OBSTACLES, road.region, pointTypes, obst);
|
||||
int[] filteredPointTypes = filterDirectionTags(road, pointTypes, dir );
|
||||
obst = getObjContext(RouteDataObjectAttribute.ROUTING_OBSTACLES).evaluateFloat(road.region, filteredPointTypes, 0);
|
||||
putCache(RouteDataObjectAttribute.ROUTING_OBSTACLES, road.region, pointTypes, obst, dir);
|
||||
}
|
||||
return obst;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int[] filterDirectionTags(RouteDataObject road, int[] pointTypes, boolean dir) {
|
||||
int wayOppositeDirection = dir ? -1 : 1;
|
||||
int direction = 0;
|
||||
int tdirection = 0;
|
||||
for (int i = 0; i < pointTypes.length; i++) {
|
||||
if (pointTypes[i] == road.region.directionBackward) {
|
||||
direction = -1;
|
||||
} else if(pointTypes[i] == road.region.directionForward) {
|
||||
direction = 1;
|
||||
} else if (pointTypes[i] == road.region.directionTrafficSignalsBackward) {
|
||||
tdirection = -1;
|
||||
} else if(pointTypes[i] == road.region.directionTrafficSignalsForward) {
|
||||
tdirection = 1;
|
||||
}
|
||||
}
|
||||
if (direction != 0 || tdirection != 0) {
|
||||
TIntArrayList filteredRules = new TIntArrayList();
|
||||
for (int i = 0; i < pointTypes.length; i++) {
|
||||
boolean skip = false;
|
||||
if ((pointTypes[i] == road.region.stopSign || pointTypes[i] == road.region.giveWaySign)
|
||||
&& direction == wayOppositeDirection) {
|
||||
skip = true;
|
||||
} else if (pointTypes[i] == road.region.trafficSignals && direction == wayOppositeDirection) {
|
||||
skip = true;
|
||||
}
|
||||
if (!skip) {
|
||||
filteredRules.add(pointTypes[i]);
|
||||
}
|
||||
}
|
||||
return filteredRules.toArray();
|
||||
}
|
||||
return pointTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double defineHeightObstacle(RouteDataObject road, short startIndex, short endIndex) {
|
||||
if(!heightObstacles) {
|
||||
|
@ -492,16 +505,20 @@ public class GeneralRouter implements VehicleRouter {
|
|||
Float sp = getCache(RouteDataObjectAttribute.ROAD_PRIORITIES, road);
|
||||
if(sp == null) {
|
||||
sp = getObjContext(RouteDataObjectAttribute.ROAD_PRIORITIES).evaluateFloat(road, 1f);
|
||||
putCache(RouteDataObjectAttribute.ROAD_PRIORITIES, road, sp);
|
||||
putCache(RouteDataObjectAttribute.ROAD_PRIORITIES, road, sp, false);
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
private void putCache(RouteDataObjectAttribute attr, RouteDataObject road, Float val) {
|
||||
putCache(attr, road.region, road.types, val);
|
||||
putCache(attr, road.region, road.types, val, false);
|
||||
}
|
||||
|
||||
private void putCache(RouteDataObjectAttribute attr, RouteRegion reg, int[] types, Float val) {
|
||||
private void putCache(RouteDataObjectAttribute attr, RouteDataObject road, Float val, boolean extra) {
|
||||
putCache(attr, road.region, road.types, val, extra);
|
||||
}
|
||||
|
||||
private void putCache(RouteDataObjectAttribute attr, RouteRegion reg, int[] types, Float val, boolean extra) {
|
||||
Map<RouteRegion, Map<IntHolder, Float>> ch = evalCache[attr.ordinal()];
|
||||
if (USE_CACHE) {
|
||||
Map<IntHolder, Float> rM = ch.get(reg);
|
||||
|
@ -509,40 +526,48 @@ public class GeneralRouter implements VehicleRouter {
|
|||
rM = new HashMap<IntHolder, Float>();
|
||||
ch.put(reg, rM);
|
||||
}
|
||||
rM.put(new IntHolder(types), val);
|
||||
rM.put(new IntHolder(types, extra), val);
|
||||
}
|
||||
TIMER += System.nanoTime();
|
||||
}
|
||||
|
||||
class IntHolder {
|
||||
private final int[] array;
|
||||
IntHolder(int[] ts) { array = ts; }
|
||||
@Override public int hashCode() { return Arrays.hashCode(array); }
|
||||
private final boolean extra;
|
||||
|
||||
IntHolder(int[] ts, boolean extra) {
|
||||
array = ts;
|
||||
this.extra = extra;
|
||||
}
|
||||
@Override public int hashCode() { return Arrays.hashCode(array) + (extra ? 1 : 0) ; }
|
||||
@Override public boolean equals(Object other) {
|
||||
if (array == other) { return true; }
|
||||
if (! (other instanceof IntHolder) ) {
|
||||
return false;
|
||||
}
|
||||
if (((IntHolder) other).extra != this.extra) {
|
||||
return false;
|
||||
}
|
||||
//noinspection unchecked
|
||||
return Arrays.equals(array, ((IntHolder) other).array);
|
||||
}
|
||||
}
|
||||
|
||||
private Float getCache(RouteDataObjectAttribute attr, RouteDataObject road) {
|
||||
return getCache(attr, road.region, road.types);
|
||||
return getCache(attr, road.region, road.types, false);
|
||||
}
|
||||
|
||||
private Float getCache(RouteDataObjectAttribute attr, RouteRegion reg, int[] types) {
|
||||
private Float getCache(RouteDataObjectAttribute attr, RouteRegion reg, int[] types, boolean extra) {
|
||||
Map<RouteRegion, Map<IntHolder, Float>> ch = evalCache[attr.ordinal()];
|
||||
TIMER -= System.nanoTime();
|
||||
// TIMER -= System.nanoTime();
|
||||
if (USE_CACHE) {
|
||||
Map<IntHolder, Float> rM = ch.get(reg);
|
||||
if (rM == null) {
|
||||
return null;
|
||||
}
|
||||
Float vl = rM.get(new IntHolder(types));
|
||||
Float vl = rM.get(new IntHolder(types, extra));
|
||||
if(vl != null) {
|
||||
TIMER += System.nanoTime();
|
||||
// TIMER += System.nanoTime();
|
||||
return vl;
|
||||
}
|
||||
}
|
||||
|
|
1
OsmAnd-java/src/test/resources/.gitignore
vendored
1
OsmAnd-java/src/test/resources/.gitignore
vendored
|
@ -3,3 +3,4 @@
|
|||
*.obf
|
||||
*.osm
|
||||
phrases.xml
|
||||
*.obf.gz
|
||||
|
|
Loading…
Reference in a new issue