Skip to content

Commit 75c890f

Browse files
author
Peter
committed
fixed another problem in astar; added integration tests to avoid that in the future
1 parent 948906e commit 75c890f

File tree

13 files changed

+335
-119
lines changed

13 files changed

+335
-119
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ docs/
77
osm.lucene.test*
88
mmap-graph*
99
neo4j*.db
10-
*.osm
10+
core/*.osm
1111
tinker*db

core/files/andorra.osm.gz

778 KB
Binary file not shown.

core/files/monaco.osm.gz

326 KB
Binary file not shown.

core/nbactions.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</goals>
1919
<properties>
2020
<exec.classpathScope>runtime</exec.classpathScope>
21-
<exec.args>-Xms1000m -Xmx1000m -XX:PermSize=20m -XX:MaxPermSize=20m -classpath %classpath de.jetsli.graph.ui.MiniGraphUI debug=true dijkstra=true graph=graph-unterfranken.osm osm=/media/SAMSUNG/unterfranken.osm /media/SAMSUNG/germany.osm</exec.args>
21+
<exec.args>-Xms1000m -Xmx1000m -XX:PermSize=20m -XX:MaxPermSize=20m -classpath %classpath de.jetsli.graph.reader.OSMReader test=true debug=true dijkstra=true graph=graph-unterfranken.osm osm=/media/SAMSUNG/unterfranken.osm</exec.args>
2222
<exec.executable>java</exec.executable>
2323
</properties>
2424
</action>
@@ -30,7 +30,7 @@
3030
</goals>
3131
<properties>
3232
<exec.classpathScope>runtime</exec.classpathScope>
33-
<exec.args>-Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -Xms1000m -Xmx1000m -XX:PermSize=20m -XX:MaxPermSize=20m -classpath %classpath de.jetsli.graph.ui.MiniGraphUI debug=true dijkstra=true graph=graph-unterfranken.osm osm=/media/SAMSUNG/unterfranken.osm /media/SAMSUNG/germany.osm</exec.args>
33+
<exec.args>-Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -Xms1000m -Xmx1000m -XX:PermSize=20m -XX:MaxPermSize=20m -classpath %classpath de.jetsli.graph.reader.OSMReader test=true debug=true dijkstra=true graph=graph-unterfranken.osm osm=/media/SAMSUNG/unterfranken.osm</exec.args>
3434
<jpda.listen>true</jpda.listen>
3535
<exec.executable>java</exec.executable>
3636
</properties>
@@ -42,7 +42,7 @@
4242
<goal>org.codehaus.mojo:exec-maven-plugin:1.1.1:exec</goal>
4343
</goals>
4444
<properties>
45-
<exec.args>${profiler.args} -Xms1000m -Xmx1000m -XX:PermSize=20m -XX:MaxPermSize=20m -classpath %classpath de.jetsli.graph.ui.MiniGraphUI debug=true dijkstra=true graph=graph-unterfranken.osm osm=/media/SAMSUNG/unterfranken.osm /media/SAMSUNG/germany.osm</exec.args>
45+
<exec.args>${profiler.args} -Xms1000m -Xmx1000m -XX:PermSize=20m -XX:MaxPermSize=20m -classpath %classpath de.jetsli.graph.reader.OSMReader test=true debug=true dijkstra=true graph=graph-unterfranken.osm osm=/media/SAMSUNG/unterfranken.osm</exec.args>
4646
<profiler.action>profile</profiler.action>
4747
<exec.executable>${profiler.java}</exec.executable>
4848
</properties>

core/src/main/java/de/jetsli/graph/reader/OSMReader.java

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
*/
1616
package de.jetsli.graph.reader;
1717

18-
import de.jetsli.graph.routing.AStar;
19-
import de.jetsli.graph.routing.DijkstraBidirection;
2018
import de.jetsli.graph.routing.DijkstraBidirectionRef;
21-
import de.jetsli.graph.routing.DijkstraSimple;
2219
import de.jetsli.graph.storage.Storage;
2320
import de.jetsli.graph.util.CalcDistance;
2421
import de.jetsli.graph.routing.Path;
@@ -33,6 +30,8 @@
3330
import java.util.*;
3431
import java.util.List;
3532
import java.util.Map.Entry;
33+
import java.util.zip.GZIPInputStream;
34+
import java.util.zip.ZipInputStream;
3635
import javax.xml.stream.XMLInputFactory;
3736
import javax.xml.stream.XMLStreamConstants;
3837
import javax.xml.stream.XMLStreamException;
@@ -69,10 +68,13 @@ public static void main(String[] strs) throws Exception {
6968
}
7069
};
7170
osm2Graph(osmReader, args);
72-
if (args.getBool("dijkstra", false)) {
71+
if (args.getBool("test", false)) {
72+
new RoutingAlgorithmIntegrationTests(osmReader.getGraph()).start();
73+
} else if (args.getBool("dijkstra", false)) {
74+
// TODO move dijkstra runner into test class too!
7375
//warmup
7476
osmReader.doDijkstra(50);
75-
77+
7678
osmReader.doDijkstra(500);
7779
}
7880
}
@@ -92,7 +94,7 @@ public static void main(String[] strs) throws Exception {
9294
* property 'size' is used to preinstantiate a datastructure/graph to avoid over-memory
9395
* allocation or reallocation (default is 5mio)
9496
*/
95-
public static Graph osm2Graph(CmdArgs args) throws FileNotFoundException {
97+
public static Graph osm2Graph(CmdArgs args) throws IOException {
9698
String storageFolder = args.get("graph", "graph-storage");
9799
if (Helper.isEmpty(storageFolder))
98100
throw new IllegalArgumentException("Please specify a folder where to store the graph");
@@ -101,7 +103,7 @@ public static Graph osm2Graph(CmdArgs args) throws FileNotFoundException {
101103
return osm2Graph(new OSMReader(storageFolder, size), args);
102104
}
103105

104-
public static Graph osm2Graph(OSMReader osmReader, CmdArgs args) throws FileNotFoundException {
106+
public static Graph osm2Graph(OSMReader osmReader, CmdArgs args) throws IOException {
105107
if (!osmReader.loadExisting()) {
106108
String strOsm = args.get("osm", "");
107109
if (Helper.isEmpty(strOsm))
@@ -126,11 +128,11 @@ public void doDijkstra(int runs) throws Exception {
126128
Location2IDIndex index = new Location2IDQuadtree(g).prepareIndex(20000);
127129
double minLat = 49.484186, minLon = 8.974228;
128130
double maxLat = 50.541363, maxLon = 10.880356;
129-
// RoutingAlgorithm algo = new DijkstraBidirectionRef(g);
131+
RoutingAlgorithm algo = new DijkstraBidirectionRef(g);
130132
// RoutingAlgorithm algo = new DijkstraBidirection(g);
131133
// RoutingAlgorithm algo = new DijkstraSimple(g);
132-
RoutingAlgorithm algo = new AStar(g);
133-
134+
// RoutingAlgorithm algo = new AStar(g);
135+
134136
logger.info("running dijkstra with " + algo.getClass().getSimpleName());
135137
Random rand = new Random(123);
136138
StopWatch sw = new StopWatch();
@@ -156,8 +158,8 @@ public void doDijkstra(int runs) throws Exception {
156158
continue;
157159
}
158160
if (i % 20 == 0)
159-
logger.info(i + " " + sw.getSeconds() / (i + 1) + " secs/run (path length:" + p.locations() + ")");
160-
// + " " + p.toString());
161+
logger.info(i + " " + sw.getSeconds() / (i + 1) + " secs/run (distance:"
162+
+ p.distance() + ",length:" + p.locations() + ")");
161163
}
162164
}
163165

@@ -177,12 +179,22 @@ public boolean loadExisting() {
177179
return storage.loadExisting();
178180
}
179181

180-
public void osm2Graph(File osmXmlFile) throws FileNotFoundException {
182+
private InputStream createInputStream(File file) throws IOException {
183+
FileInputStream fi = new FileInputStream(file);
184+
if (file.getAbsolutePath().endsWith(".gz"))
185+
return new GZIPInputStream(fi);
186+
else if (file.getAbsolutePath().endsWith(".zip"))
187+
return new ZipInputStream(fi);
188+
189+
return fi;
190+
}
191+
192+
public void osm2Graph(File osmXmlFile) throws IOException {
181193
// TODO instead of creating two separate input streams,
182194
// could we use PushbackInputStream(new FileInputStream(osmFile)); ???
183-
preprocessAcceptHighwaysOnly(new FileInputStream(osmXmlFile));
184-
writeOsm2Graph(new FileInputStream(osmXmlFile));
185-
storage.flush();
195+
196+
preprocessAcceptHighwaysOnly(createInputStream(osmXmlFile));
197+
writeOsm2Graph(createInputStream(osmXmlFile));
186198

187199
Map subnetworks = new PrepareRouting(storage.getGraph()).findSubnetworks();
188200
logger.info("subnetworks:" + subnetworks.size() + " content:" + subnetworks);
@@ -275,6 +287,7 @@ public void writeOsm2Graph(InputStream is) {
275287
break;
276288
}
277289
}
290+
logger.info(storage.getNodes() + " vs. " + storage.getGraph().getNodes());
278291
storage.flush();
279292
} catch (XMLStreamException ex) {
280293
throw new RuntimeException("Couldn't process file", ex);
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Copyright 2012 Peter Karich [email protected]
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package de.jetsli.graph.reader;
17+
18+
import de.jetsli.graph.routing.AStar;
19+
import de.jetsli.graph.routing.DijkstraBidirection;
20+
import de.jetsli.graph.routing.DijkstraBidirectionRef;
21+
import de.jetsli.graph.routing.DijkstraSimple;
22+
import de.jetsli.graph.routing.Path;
23+
import de.jetsli.graph.routing.RoutingAlgorithm;
24+
import de.jetsli.graph.storage.Graph;
25+
import de.jetsli.graph.storage.Location2IDIndex;
26+
import de.jetsli.graph.storage.Location2IDQuadtree;
27+
import de.jetsli.graph.util.CmdArgs;
28+
import de.jetsli.graph.util.CoordTrig;
29+
import de.jetsli.graph.util.Helper;
30+
import java.io.File;
31+
import java.util.ArrayList;
32+
import java.util.List;
33+
34+
/**
35+
* @author Peter Karich
36+
*/
37+
public class RoutingAlgorithmIntegrationTests {
38+
39+
private final Graph unterfrankenGraph;
40+
41+
public RoutingAlgorithmIntegrationTests(Graph graph) {
42+
this.unterfrankenGraph = graph;
43+
}
44+
45+
public void start() {
46+
Collector testCollector = new Collector();
47+
48+
//
49+
List<OneRun> list = new ArrayList<OneRun>();
50+
list.add(new OneRun(43.727687, 7.418737, 43.730729, 7.421288, 1.532, 88));
51+
list.add(new OneRun(43.727687, 7.418737, 43.74958, 7.436566, 3.448, 136));
52+
runAlgo(testCollector, "files/monaco.osm.gz", "target/graph-monaco", list);
53+
54+
//
55+
list = new ArrayList<OneRun>();
56+
list.add(new OneRun(42.56819, 1.603231, 42.571034, 1.520662, 16.3845, 636));
57+
list.add(new OneRun(42.529176, 1.571302, 42.571034, 1.520662, 12.4408, 397));
58+
runAlgo(testCollector, "files/andorra.osm.gz", "target/graph-andorra", list);
59+
60+
//
61+
testUnterfranken(testCollector);
62+
63+
if (testCollector.list.size() > 0) {
64+
System.out.println("\n-------------------------------\n");
65+
System.out.println("FOUND " + testCollector.list.size() + " ERRORS");
66+
for (String s : testCollector.list) {
67+
System.out.println(s);
68+
}
69+
} else
70+
System.out.println("SUCCESS!");
71+
}
72+
73+
private void testUnterfranken(Collector testCollector) {
74+
RoutingAlgorithm[] algos = createAlgos(unterfrankenGraph);
75+
for (RoutingAlgorithm algo : algos) {
76+
int failed = testCollector.list.size();
77+
testCollector.assertNull(algo, 773352, 858026);
78+
testCollector.assertNull(algo, 696295, 773352);
79+
80+
testCollector.assertDistance(algo, 424236, 794975, 115.4, 2094);
81+
testCollector.assertDistance(algo, 331738, 111807, 121.4, 2328);
82+
testCollector.assertDistance(algo, 501620, 155552, 78.0, 1126);
83+
testCollector.assertDistance(algo, 399826, 269920, 53.1, 1041);
84+
testCollector.assertDistance(algo, 665211, 246823, 35.4, 710);
85+
testCollector.assertDistance(algo, 783718, 696695, 66.3, 1283);
86+
testCollector.assertDistance(algo, 811865, 641256, 113.3, 1729);
87+
testCollector.assertDistance(algo, 513676, 22669, 168.4, 2817);
88+
testCollector.assertDistance(algo, 896965, 769132, 6.0, 131);
89+
testCollector.assertDistance(algo, 115253, 430074, 56.6, 967);
90+
System.out.println("unterfranken " + algo.getClass().getSimpleName()
91+
+ ": " + (testCollector.list.size() - failed) + " failed");
92+
}
93+
}
94+
95+
RoutingAlgorithm[] createAlgos(Graph g) {
96+
return new RoutingAlgorithm[]{new AStar(g), new DijkstraBidirectionRef(g),
97+
new DijkstraBidirection(g), new DijkstraSimple(g)};
98+
}
99+
100+
public static class Collector {
101+
102+
List<String> list = new ArrayList<String>();
103+
104+
public Collector assertNull(RoutingAlgorithm algo, int from, int to) {
105+
Path p = algo.clear().calcShortestPath(from, to);
106+
if (p != null)
107+
list.add(algo.getClass().getSimpleName() + " returns value where null is expected. "
108+
+ "from:" + from + ", to:" + to);
109+
return this;
110+
}
111+
112+
public Collector assertDistance(RoutingAlgorithm algo, int from, int to, double distance, int locations) {
113+
Path p = algo.clear().calcShortestPath(from, to);
114+
if (p == null)
115+
list.add(algo.getClass().getSimpleName() + " returns no path for "
116+
+ "from:" + from + ", to:" + to);
117+
else if (Math.abs(p.distance() - distance) > 1e-1)
118+
list.add(algo.getClass().getSimpleName() + " returns path not matching the expected "
119+
+ "distance of " + distance + "\t Returned was " + p.distance()
120+
+ "\t (expected locations " + locations + ", was " + p.locations() + ") "
121+
+ "from:" + from + ", to:" + to);
122+
else if (p.locations() != locations)
123+
list.add(algo.getClass().getSimpleName() + " returns path not matching the expected "
124+
+ "locations of " + locations + "\t Returned was " + p.locations()
125+
+ "\t (expected distance " + distance + ", was " + p.distance() + ") "
126+
+ "from:" + from + ", to:" + to);
127+
return this;
128+
}
129+
}
130+
131+
class OneRun {
132+
133+
double fromLat, fromLon;
134+
double toLat, toLon;
135+
double dist;
136+
int locs;
137+
138+
public OneRun(double fromLat, double fromLon, double toLat, double toLon, double dist, int locs) {
139+
this.fromLat = fromLat;
140+
this.fromLon = fromLon;
141+
this.toLat = toLat;
142+
this.toLon = toLon;
143+
this.dist = dist;
144+
this.locs = locs;
145+
}
146+
}
147+
148+
void runAlgo(Collector testCollector, String osmFile, String graphFile, List<OneRun> forEveryAlgo) {
149+
try {
150+
// make sure we are using the latest file format
151+
Helper.deleteDir(new File(graphFile));
152+
Graph g = OSMReader.osm2Graph(new CmdArgs().put("osm", osmFile).put("graph", graphFile));
153+
System.out.println(osmFile + " - all locations " + g.getNodes());
154+
Location2IDIndex idx = new Location2IDQuadtree(g).prepareIndex(2000);
155+
RoutingAlgorithm[] algos = createAlgos(g);
156+
for (RoutingAlgorithm algo : algos) {
157+
int failed = testCollector.list.size();
158+
159+
for (OneRun or : forEveryAlgo) {
160+
int from = idx.findID(or.fromLat, or.fromLon);
161+
int to = idx.findID(or.toLat, or.toLon);
162+
testCollector.assertDistance(algo, from, to, or.dist, or.locs);
163+
}
164+
165+
System.out.println(osmFile + " " + algo.getClass().getSimpleName()
166+
+ ": " + (testCollector.list.size() - failed) + " failed");
167+
}
168+
} catch (Exception ex) {
169+
throw new RuntimeException("cannot handle osm file " + osmFile, ex);
170+
} finally {
171+
Helper.deleteDir(new File(graphFile));
172+
}
173+
}
174+
}

0 commit comments

Comments
 (0)