fix router for some cases
git-svn-id: https://osmand.googlecode.com/svn/trunk@855 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
a60ef26f4d
commit
0b064d51db
5 changed files with 196 additions and 42 deletions
|
@ -73,11 +73,11 @@ public class BinaryRouteDataReader {
|
|||
autoPriorityValues.put("tertiary", 1.0d);
|
||||
autoPriorityValues.put("tertiary_link", 1.0d);
|
||||
autoPriorityValues.put("residential", 0.8d);
|
||||
autoPriorityValues.put("service", 0.5d);
|
||||
autoPriorityValues.put("service", 0.6d);
|
||||
autoPriorityValues.put("unclassified", 0.7d);
|
||||
autoPriorityValues.put("road", 0.7d);
|
||||
autoPriorityValues.put("track", 0.5d);
|
||||
autoPriorityValues.put("path", 0.5d);
|
||||
autoPriorityValues.put("track", 0.2d);
|
||||
autoPriorityValues.put("path", 0.2d);
|
||||
autoPriorityValues.put("living_street", 0.5d);
|
||||
}
|
||||
|
||||
|
@ -216,6 +216,7 @@ public class BinaryRouteDataReader {
|
|||
RouteSegment next = null;
|
||||
|
||||
// search context (needed for searching route)
|
||||
// Initially it should be null (!) because it checks was it segment visited before
|
||||
RouteSegment parentRoute = null;
|
||||
int parentSegmentEnd = 0;
|
||||
|
||||
|
@ -285,7 +286,9 @@ public class BinaryRouteDataReader {
|
|||
for (BinaryMapIndexReader r : map) {
|
||||
r.searchMapIndex(request);
|
||||
for (BinaryMapDataObject o : request.searchResults) {
|
||||
if (ctx.idObjects.containsKey(o.getId())) {
|
||||
BinaryMapDataObject old = ctx.idObjects.get(o.getId());
|
||||
// sometimes way are presented only partially in one index
|
||||
if (old != null && old.getPointsLength() >= o.getPointsLength()) {
|
||||
continue;
|
||||
}
|
||||
ctx.idObjects.put(o.getId(), o);
|
||||
|
@ -338,11 +341,12 @@ public class BinaryRouteDataReader {
|
|||
|
||||
|
||||
// TODO write unit tests
|
||||
// TODO add information about turns
|
||||
// TODO think about u-turn
|
||||
// TODO fix roundabout
|
||||
// TODO access
|
||||
// TODO bicycle router (?)
|
||||
// TODO routing between indexes
|
||||
// TODO fastest/shortest way
|
||||
/**
|
||||
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
||||
* return list of segments
|
||||
|
@ -381,8 +385,9 @@ public class BinaryRouteDataReader {
|
|||
|
||||
// because first point of the start is not visited do the same as in cycle but only for one point
|
||||
long ls = (((long) startX) << 31) + (long) startY;
|
||||
loadRoutes(ctx, (startX >> (31 - ZOOM_LOAD_TILES)), (startY >> (31 - ZOOM_LOAD_TILES)));
|
||||
RouteSegment startNbs = ctx.routes.get(ls);
|
||||
while(startNbs != null) {
|
||||
while(startNbs != null) { // startNbs.road.id >> 3, start.road.id >> 3
|
||||
if(startNbs.road.id != start.road.id){
|
||||
startNbs.parentRoute = start;
|
||||
startNbs.parentSegmentEnd = start.segmentStart;
|
||||
|
@ -453,6 +458,8 @@ public class BinaryRouteDataReader {
|
|||
// 2. calculate point and try to load neighbor ways if they are not loaded
|
||||
long l = (((long) road.getPoint31XTile(j)) << 31) + (long) road.getPoint31YTile(j);
|
||||
loadRoutes(ctx, (road.getPoint31XTile(j) >> (31 - ZOOM_LOAD_TILES)), (road.getPoint31YTile(j) >> (31 - ZOOM_LOAD_TILES)));
|
||||
long nt = (road.id << 8l) + segment.segmentStart;
|
||||
visitedSegments.add(nt);
|
||||
|
||||
// 3. get intersected ways
|
||||
RouteSegment next = ctx.routes.get(l);
|
||||
|
@ -473,9 +480,9 @@ public class BinaryRouteDataReader {
|
|||
|
||||
// 3.2 calculate possible ways to put into priority queue
|
||||
while(next != null){
|
||||
long nt = (next.road.id << 8l) + next.segmentStart;
|
||||
long nts = (next.road.id << 8l) + next.segmentStart;
|
||||
/* next.road.id >> 3 != road.id >> 3 - used that line for debug with osm map */
|
||||
if(next.road.id != road.id && !visitedSegments.contains(nt)){
|
||||
if(next.road.id != road.id && !visitedSegments.contains(nts)){
|
||||
int type = -1;
|
||||
for(int i = 0; i< road.getRestrictionCount(); i++){
|
||||
if(road.getRestriction(i) == next.road.id){
|
||||
|
@ -491,10 +498,7 @@ public class BinaryRouteDataReader {
|
|||
type == MapRenderingTypes.RESTRICTION_NO_U_TURN){
|
||||
// next = next.next; continue;
|
||||
} else {
|
||||
// because no one segment is visited twice (see check before)
|
||||
// put additional information to recover whole route after
|
||||
next.parentRoute = segment;
|
||||
next.parentSegmentEnd = j;
|
||||
|
||||
int x = road.getPoint31XTile(j);
|
||||
int y = road.getPoint31YTile(j);
|
||||
|
||||
|
@ -505,24 +509,38 @@ public class BinaryRouteDataReader {
|
|||
speed = ctx.router.getMinDefaultSpeed();
|
||||
}
|
||||
|
||||
next.distanceFromStart = segment.distanceFromStart + squareRootDist(x, y, middlex, middley) / speed;
|
||||
double distanceFromStart = segment.distanceFromStart + squareRootDist(x, y, middlex, middley) / speed;
|
||||
// calculate turn time
|
||||
next.distanceFromStart += ctx.router.calculateTurnTime(middley, middlex, x, y, segment, next, j);
|
||||
|
||||
distanceFromStart += ctx.router.calculateTurnTime(middley, middlex, x, y, segment, next, j);
|
||||
// add obstacles time
|
||||
next.distanceFromStart += obstaclesTime;
|
||||
distanceFromStart += obstaclesTime;
|
||||
|
||||
|
||||
next.distanceToEnd = squareRootDist(x, y, endX, endY) / ctx.router.getMaxDefaultSpeed();
|
||||
if(type == -1){
|
||||
// case no restriction
|
||||
segmentsToVisitNotForbidden.add(next);
|
||||
} else {
|
||||
// case exclusive restriction (only_right, only_straight, ...)
|
||||
exclusiveRestriction = true;
|
||||
segmentsToVisitNotForbidden.clear();
|
||||
segmentsToVisitPrescricted.add(next);
|
||||
double distanceToEnd = squareRootDist(x, y, endX, endY) / ctx.router.getMaxDefaultSpeed();
|
||||
|
||||
if(next.parentRoute == null || next.distanceFromStart + next.distanceToEnd >
|
||||
distanceFromStart + distanceToEnd){
|
||||
next.distanceFromStart = distanceFromStart;
|
||||
next.distanceToEnd = distanceToEnd;
|
||||
if(next.parentRoute != null){
|
||||
// already in queue remove it
|
||||
graphSegments.remove(next);
|
||||
}
|
||||
// put additional information to recover whole route after
|
||||
next.parentRoute = segment;
|
||||
next.parentSegmentEnd = j;
|
||||
if(type == -1){
|
||||
// case no restriction
|
||||
segmentsToVisitNotForbidden.add(next);
|
||||
} else {
|
||||
// case exclusive restriction (only_right, only_straight, ...)
|
||||
exclusiveRestriction = true;
|
||||
segmentsToVisitNotForbidden.clear();
|
||||
segmentsToVisitPrescricted.add(next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
next = next.next;
|
||||
|
@ -530,13 +548,9 @@ public class BinaryRouteDataReader {
|
|||
|
||||
// add all allowed route segments to priority queue
|
||||
for(RouteSegment s : segmentsToVisitNotForbidden){
|
||||
long nt = (s.road.id << 8l) + s.segmentStart;
|
||||
visitedSegments.add(nt);
|
||||
graphSegments.add(s);
|
||||
}
|
||||
for(RouteSegment s : segmentsToVisitPrescricted){
|
||||
long nt = (s.road.id << 8l) + s.segmentStart;
|
||||
visitedSegments.add(nt);
|
||||
graphSegments.add(s);
|
||||
}
|
||||
}
|
||||
|
@ -551,6 +565,11 @@ public class BinaryRouteDataReader {
|
|||
end.segmentEnd : end.segmentStart;
|
||||
RouteSegment segment = finalRoute;
|
||||
|
||||
System.out.println("ROUTE : ");
|
||||
System.out.println("Start lat=" + MapUtils.get31LatitudeY(start.road.getPoint31YTile(start.segmentEnd)) +
|
||||
" lon=" + MapUtils.get31LongitudeX(start.road.getPoint31XTile(start.segmentEnd)));
|
||||
System.out.println("END lat=" + MapUtils.get31LatitudeY(end.road.getPoint31YTile(end.segmentStart)) +
|
||||
" lon=" + MapUtils.get31LongitudeX(end.road.getPoint31XTile(end.segmentStart)));
|
||||
while(segment != null){
|
||||
RouteSegmentResult res = new RouteSegmentResult();
|
||||
res.object = segment.road;
|
||||
|
@ -567,6 +586,7 @@ public class BinaryRouteDataReader {
|
|||
}
|
||||
// do not add segments consists from 1 poitn
|
||||
if(res.startPointIndex != res.endPointIndex) {
|
||||
System.out.println("id="+(res.object.id >> 3) + " start=" + res.startPointIndex + " end=" + res.endPointIndex);
|
||||
result.add(0, res);
|
||||
}
|
||||
res.startPoint = convertPoint(res.object, res.startPointIndex);
|
||||
|
|
110
DataExtractionOSM/src/net/osmand/binary/RouterTests.java
Normal file
110
DataExtractionOSM/src/net/osmand/binary/RouterTests.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
public class RouterTests {
|
||||
//
|
||||
|
||||
// BELARUS
|
||||
// 1. Correct BREST near to border!
|
||||
// Start lat=52.15449120254751 lon=23.901958465576172
|
||||
// END lat=52.07294489666366 lon=23.656225204467773
|
||||
// id=34001524 start=0 end=2
|
||||
// id=58208937 start=0 end=9
|
||||
// id=58208944 start=0 end=20
|
||||
// id=25297376 start=0 end=1
|
||||
// id=64080970 start=0 end=1
|
||||
// id=58208916 start=0 end=8
|
||||
// id=28510027 start=0 end=2
|
||||
// id=28510029 start=0 end=6
|
||||
// id=25296360 start=0 end=4
|
||||
// id=75839018 start=0 end=33
|
||||
// id=84437417 start=0 end=3
|
||||
// id=84437365 start=0 end=1
|
||||
// id=31775053 start=5 end=22
|
||||
// id=36294997 start=36 end=0
|
||||
|
||||
// MINSK (good known way). The best at 70%
|
||||
// Start lat=53.91088592425074 lon=27.579095363616943
|
||||
// END lat=53.953863330122196 lon=27.68131971359253
|
||||
// id=46724311 start=6 end=2
|
||||
// id=60889993 start=0 end=9
|
||||
// id=25225646 start=0 end=18
|
||||
// id=25225916 start=0 end=22
|
||||
// id=30854239 start=16 end=0
|
||||
// id=30854243 start=1 end=0
|
||||
// id=30854252 start=0 end=8
|
||||
// id=30854254 start=0 end=1
|
||||
// id=33912019 start=0 end=2
|
||||
// id=33912004 start=0 end=5
|
||||
// id=33911980 start=0 end=9
|
||||
// id=33911977 start=0 end=1
|
||||
// id=33911967 start=0 end=3
|
||||
// id=31499010 start=0 end=8
|
||||
// id=35566247 start=0 end=5
|
||||
// id=35566202 start=0 end=2
|
||||
// id=37700614 start=0 end=1
|
||||
// id=33911493 start=0 end=1
|
||||
// id=31279905 start=0 end=3
|
||||
// id=33911472 start=0 end=2
|
||||
// id=33911443 start=1 end=7
|
||||
// id=31691782 start=1 end=0
|
||||
// id=40885457 start=1 end=0
|
||||
// id=40885456 start=1 end=0
|
||||
// id=40885459 start=3 end=2
|
||||
|
||||
// MINSK (restriction + roundabout). The best at 80%
|
||||
// Start lat=53.91104391755144 lon=27.57664918899536
|
||||
// END lat=53.91172012212507 lon=27.57993221282959
|
||||
// id=40885459 start=2 end=3
|
||||
// id=40885456 start=0 end=1
|
||||
// id=40885457 start=0 end=1
|
||||
// id=31691782 start=0 end=1
|
||||
// id=33911443 start=0 end=1
|
||||
// id=25228312 start=0 end=6
|
||||
// id=61594239 start=0 end=1
|
||||
// id=61594235 start=0 end=3
|
||||
// id=25228310 start=0 end=5
|
||||
// id=61594238 start=0 end=2
|
||||
// id=25441562 start=0 end=3
|
||||
// id=33911427 start=0 end=1
|
||||
// id=33911466 start=0 end=4
|
||||
|
||||
// MINSK (restriction + roundabout). The best at 95%
|
||||
// Start lat=53.90940707797713 lon=27.49480962753296
|
||||
// END lat=53.910405620946285 lon=27.49556064605713
|
||||
// id=30821192 start=0 end=3
|
||||
// id=48470183 start=0 end=1
|
||||
// id=48470184 start=0 end=1
|
||||
// id=48470565 start=0 end=1
|
||||
// id=30821117 start=0 end=1
|
||||
// id=30813591 start=7 end=8
|
||||
|
||||
// MINSK. The best at 90%
|
||||
// Start lat=53.92008645787278 lon=27.58763551712036
|
||||
// END lat=53.93877827466741 lon=27.605509757995605
|
||||
// id=25227299 start=0 end=1
|
||||
// id=50727963 start=0 end=2
|
||||
// id=50727962 start=0 end=4
|
||||
// id=50728110 start=0 end=2
|
||||
// id=33911936 start=0 end=12
|
||||
// id=33911931 start=0 end=1
|
||||
// id=33911932 start=0 end=1
|
||||
// id=33911926 start=0 end=4
|
||||
// id=33911764 start=0 end=3
|
||||
// id=38575349 start=0 end=1
|
||||
// id=38575351 start=0 end=2
|
||||
// id=38575346 start=0 end=1
|
||||
// id=33911503 start=0 end=2
|
||||
// id=38571365 start=0 end=5
|
||||
// id=38571368 start=0 end=4
|
||||
// id=38571370 start=1 end=2
|
||||
|
||||
// POLAND/BELARUS (problems with way connection) The best at 100%
|
||||
// Start lat=52.115756035004786 lon=23.56539487838745
|
||||
// END lat=52.03710226357107 lon=23.47106695175171
|
||||
// id=32032589 start=8 end=9
|
||||
// id=32032656 start=0 end=18
|
||||
// id=32031919 start=1 end=0
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -42,14 +42,36 @@ public class DataExtractionSettings {
|
|||
}
|
||||
|
||||
|
||||
public File getDefaultRoutingFile(){
|
||||
public File[] getDefaultRoutingFile(){
|
||||
String routingFile = preferences.get("routing_file", null);
|
||||
if(routingFile == null || !new File(routingFile).exists()){
|
||||
if(routingFile == null){
|
||||
return null;
|
||||
}
|
||||
return new File(routingFile);
|
||||
String[] files = routingFile.split(",");
|
||||
List<File> fs = new ArrayList<File>();
|
||||
for(String f : files){
|
||||
if(new File(f.trim()).exists()){
|
||||
fs.add(new File(f.trim()));
|
||||
}
|
||||
}
|
||||
|
||||
return fs.toArray(new File[fs.size()]);
|
||||
}
|
||||
|
||||
public String getDefaultRoutingFilePath(){
|
||||
File[] file = getDefaultRoutingFile();
|
||||
String path = "";
|
||||
if (file != null) {
|
||||
for (int i = 0; i < file.length; i++) {
|
||||
if (i > 0) {
|
||||
path += ", ";
|
||||
}
|
||||
path += file[i].getAbsolutePath();
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setDefaultRoutingPath(String path){
|
||||
preferences.put("routing_file", path);
|
||||
}
|
||||
|
|
|
@ -305,8 +305,8 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
public List<Way> selfRoute(LatLon start, LatLon end) {
|
||||
List<Way> res = new ArrayList<Way>();
|
||||
long time = System.currentTimeMillis();
|
||||
File file = DataExtractionSettings.getSettings().getDefaultRoutingFile();
|
||||
if(file == null){
|
||||
File[] files = DataExtractionSettings.getSettings().getDefaultRoutingFile();
|
||||
if(files == null){
|
||||
JOptionPane.showMessageDialog(OsmExtractionUI.MAIN_APP.getFrame(), "Please specify obf file in settings", "Obf file not found",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return null;
|
||||
|
@ -314,10 +314,14 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
System.out.println("Self made route from " + start + " to " + end);
|
||||
if (start != null && end != null) {
|
||||
try {
|
||||
BinaryMapIndexReader[] rs = new BinaryMapIndexReader[files.length];
|
||||
for(int i=0; i<files.length; i++){
|
||||
RandomAccessFile raf = new RandomAccessFile(files[i], "r"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
rs[i] = new BinaryMapIndexReader(raf);
|
||||
|
||||
RandomAccessFile raf = new RandomAccessFile(file, "r"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
|
||||
BinaryRouteDataReader router = new BinaryRouteDataReader(reader);
|
||||
}
|
||||
|
||||
BinaryRouteDataReader router = new BinaryRouteDataReader(rs);
|
||||
RoutingContext ctx = new RoutingContext();
|
||||
|
||||
// find closest way
|
||||
|
|
|
@ -108,8 +108,8 @@ public class OsmExtractionPreferencesDialog extends JDialog {
|
|||
l.setConstraints(label, constr);
|
||||
|
||||
pathToObfRoutingFile = new JTextField();
|
||||
File file = DataExtractionSettings.getSettings().getDefaultRoutingFile();
|
||||
pathToObfRoutingFile.setText(file == null ? "" : file.getAbsolutePath());
|
||||
|
||||
pathToObfRoutingFile.setText(DataExtractionSettings.getSettings().getDefaultRoutingFilePath());
|
||||
panel.add(pathToObfRoutingFile);
|
||||
constr = new GridBagConstraints();
|
||||
constr.weightx = 1;
|
||||
|
@ -260,9 +260,7 @@ public class OsmExtractionPreferencesDialog extends JDialog {
|
|||
if(!settings.getMapRenderingTypesFile().equals(renderingTypesFile.getText())){
|
||||
settings.setMapRenderingTypesFile(renderingTypesFile.getText());
|
||||
}
|
||||
File f = settings.getDefaultRoutingFile();
|
||||
String routingFile = f == null ? "" : f.getAbsolutePath();
|
||||
if(!routingFile.equals(pathToObfRoutingFile.getText())){
|
||||
if(!settings.getDefaultRoutingFilePath().equals(pathToObfRoutingFile.getText())){
|
||||
settings.setDefaultRoutingPath(pathToObfRoutingFile.getText());
|
||||
}
|
||||
// if(settings.isSupressWarningsForDuplicatedId() != supressWarning.isSelected()){
|
||||
|
|
Loading…
Reference in a new issue