Merge branch 'preciseRouting'

This commit is contained in:
Victor Shcherb 2012-09-29 14:26:12 +02:00
commit 6a38053226
33 changed files with 1196 additions and 918 deletions

View file

@ -23,7 +23,7 @@ import org.xml.sax.SAXException;
public class JUnitRouteTest { public class JUnitRouteTest {
static BinaryMapIndexReader[] rs; static BinaryMapIndexReader[] rs;
private NativeSwingRendering lib; static NativeSwingRendering lib;
@Before @Before
public void setupFiles() throws IOException { public void setupFiles() throws IOException {
if(rs != null){ if(rs != null){
@ -51,27 +51,27 @@ public class JUnitRouteTest {
} }
@Test @Test
public void runCZ() throws SAXException, IOException, ParserConfigurationException { public void runCZ() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("cz.test.xml"), rs, RoutingConfiguration.getDefault()); RouterTestsSuite.test(lib, getClass().getResourceAsStream("cz.test.xml"), rs, RoutingConfiguration.getDefault());
} }
@Test @Test
public void runNL() throws SAXException, IOException, ParserConfigurationException { public void runNL() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl.test.xml"), rs, RoutingConfiguration.getDefault()); RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl.test.xml"), rs, RoutingConfiguration.getDefault());
} }
@Test @Test
public void runNL2() throws SAXException, IOException, ParserConfigurationException { public void runNL2() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl2.test.xml"), rs, RoutingConfiguration.getDefault()); RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl2.test.xml"), rs, RoutingConfiguration.getDefault());
} }
@Test @Test
public void runNLLeid() throws SAXException, IOException, ParserConfigurationException { public void runNLLeid() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl_leid.test.xml"), rs, RoutingConfiguration.getDefault()); RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl_leid.test.xml"), rs, RoutingConfiguration.getDefault());
} }
@Test @Test
public void runBLR() throws SAXException, IOException, ParserConfigurationException { public void runBLR() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("blr.test.xml"), rs, RoutingConfiguration.getDefault()); RouterTestsSuite.test(lib, getClass().getResourceAsStream("blr.test.xml"), rs, RoutingConfiguration.getDefault());
} }

View file

@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.osmand.NativeLibrary; import net.osmand.NativeLibrary;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
@ -17,6 +16,7 @@ import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.BinaryRoutePlanner.RouteSegment; import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration; import net.osmand.router.RoutingConfiguration;
import net.osmand.router.RoutingConfiguration.Builder;
import net.osmand.router.RoutingContext; import net.osmand.router.RoutingContext;
import net.osmand.swing.DataExtractionSettings; import net.osmand.swing.DataExtractionSettings;
@ -77,7 +77,7 @@ public class RouterTestsSuite {
} }
} }
public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException { public static void main(String[] args) throws Exception {
Parameters params = Parameters.init(args); Parameters params = Parameters.init(args);
if(params.tests.isEmpty() || params.obfDir == null) { if(params.tests.isEmpty() || params.obfDir == null) {
println("Run router tests is console utility to test route calculation for osmand."); println("Run router tests is console utility to test route calculation for osmand.");
@ -116,15 +116,13 @@ public class RouterTestsSuite {
} }
public static boolean test(NativeLibrary lib, InputStream resource, BinaryMapIndexReader[] rs, RoutingConfiguration.Builder config) throws SAXException, IOException, ParserConfigurationException { public static boolean test(NativeLibrary lib, InputStream resource, BinaryMapIndexReader[] rs, RoutingConfiguration.Builder config) throws Exception {
Document testSuite = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(resource)); Document testSuite = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(resource));
NodeList tests = testSuite.getElementsByTagName("test"); NodeList tests = testSuite.getElementsByTagName("test");
for (int i = 0; i < tests.getLength(); i++) { for (int i = 0; i < tests.getLength(); i++) {
Element e = (Element) tests.item(i); Element e = (Element) tests.item(i);
BinaryRoutePlanner router = new BinaryRoutePlanner(lib, rs); testRoute(e, config, lib, rs);
RoutingConfiguration.DEFAULT_DESIRABLE_TILES_IN_MEMORY = 100;
testRoute(e, router, config);
} }
return true; return true;
@ -147,7 +145,7 @@ public class RouterTestsSuite {
return false; return false;
} }
private static void testRoute(Element testCase, BinaryRoutePlanner planner, RoutingConfiguration.Builder config) throws IOException, SAXException { private static void testRoute(Element testCase, Builder config, NativeLibrary lib, BinaryMapIndexReader[] rs) throws IOException, SAXException, InterruptedException {
String vehicle = testCase.getAttribute("vehicle"); String vehicle = testCase.getAttribute("vehicle");
int loadedTiles = (int) parseFloat(testCase, "loadedTiles"); int loadedTiles = (int) parseFloat(testCase, "loadedTiles");
int visitedSegments = (int) parseFloat(testCase, "visitedSegments"); int visitedSegments = (int) parseFloat(testCase, "visitedSegments");
@ -159,7 +157,9 @@ public class RouterTestsSuite {
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because 'best_percent' attribute is not specified \n\n" ); System.err.println("\n\n!! Skipped test case '" + testDescription + "' because 'best_percent' attribute is not specified \n\n" );
return; return;
} }
RoutingContext ctx = new RoutingContext(config.build(vehicle)); BinaryRoutePlanner router = new BinaryRoutePlanner();
RoutingContext ctx = new RoutingContext(config.build(vehicle, RoutingConfiguration.DEFAULT_MEMORY_LIMIT),
lib, rs);
String skip = testCase.getAttribute("skip_comment"); String skip = testCase.getAttribute("skip_comment");
if (skip != null && skip.length() > 0) { if (skip != null && skip.length() > 0) {
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because '" + skip + "'\n\n" ); System.err.println("\n\n!! Skipped test case '" + testDescription + "' because '" + skip + "'\n\n" );
@ -169,17 +169,17 @@ public class RouterTestsSuite {
double startLat = Double.parseDouble(testCase.getAttribute("start_lat")); double startLat = Double.parseDouble(testCase.getAttribute("start_lat"));
double startLon = Double.parseDouble(testCase.getAttribute("start_lon")); double startLon = Double.parseDouble(testCase.getAttribute("start_lon"));
RouteSegment startSegment = planner.findRouteSegment(startLat, startLon, ctx); RouteSegment startSegment = router.findRouteSegment(startLat, startLon, ctx);
double endLat = Double.parseDouble(testCase.getAttribute("target_lat")); double endLat = Double.parseDouble(testCase.getAttribute("target_lat"));
double endLon = Double.parseDouble(testCase.getAttribute("target_lon")); double endLon = Double.parseDouble(testCase.getAttribute("target_lon"));
RouteSegment endSegment = planner.findRouteSegment(endLat, endLon, ctx); RouteSegment endSegment = router.findRouteSegment(endLat, endLon, ctx);
if(startSegment == null){ if(startSegment == null){
throw new IllegalArgumentException("Start segment is not found for test : " + testDescription); throw new IllegalArgumentException("Start segment is not found for test : " + testDescription);
} }
if(endSegment == null){ if(endSegment == null){
throw new IllegalArgumentException("End segment is not found for test : " + testDescription); throw new IllegalArgumentException("End segment is not found for test : " + testDescription);
} }
List<RouteSegmentResult> route = planner.searchRoute(ctx, startSegment, endSegment, false); List<RouteSegmentResult> route = router.searchRoute(ctx, startSegment, endSegment, false);
float completeTime = 0; float completeTime = 0;
float completeDistance = 0; float completeDistance = 0;
for (int i = 0; i < route.size(); i++) { for (int i = 0; i < route.size(); i++) {

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<router_tests> <router_tests>
<test regions="" description="Belarus" best_percent="5" vehicle="car" <test regions="" description="Belarus" best_percent="5" vehicle="car"
start_lat="53.91102495838691" start_lon="27.579245567321777" target_lat="53.908383230651346" target_lon="27.48626947402954" complete_time="1093.2324" loadedTiles = "10" visitedSegments = "832" complete_distance = "9285.089" > start_lat="53.91102495838691" start_lon="27.579245567321777" target_lat="53.908383230651346" target_lon="27.48626947402954" complete_time="1093.2324" loadedTiles = "220" visitedSegments = "832" complete_distance = "9285.089" >
<segment id="40885459" start="3" end="2" time = "10.731602" name = "" distance = "89.43001" turn = "Go ahead" start_bearing = "30.2094" end_bearing = "30.2094" description = "Go ahead and go 89.43 meters" /> <segment id="40885459" start="3" end="2" time = "10.731602" name = "" distance = "89.43001" turn = "Go ahead" start_bearing = "30.2094" end_bearing = "30.2094" description = "Go ahead and go 89.43 meters" />
<segment id="40885456" start="1" end="0" time = "0.7542267" name = "" distance = "6.2852225" turn = "Turn left" start_bearing = "-57.804268" end_bearing = "-57.804268" description = "Turn left and go 47.32 meters" /> <segment id="40885456" start="1" end="0" time = "0.7542267" name = "" distance = "6.2852225" turn = "Turn left" start_bearing = "-57.804268" end_bearing = "-57.804268" description = "Turn left and go 47.32 meters" />
<segment id="40885457" start="1" end="0" time = "1.6372955" name = "" distance = "13.64413" start_bearing = "-57.47511" end_bearing = "-57.47511" description = "" /> <segment id="40885457" start="1" end="0" time = "1.6372955" name = "" distance = "13.64413" start_bearing = "-57.47511" end_bearing = "-57.47511" description = "" />

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<router_tests> <router_tests>
<test regions="" description="Czech" best_percent="10" vehicle="car" <test regions="" description="Czech" best_percent="10" vehicle="car"
start_lat="50.07577452522076" start_lon="14.45427417755127" target_lat="49.120547036367746" target_lon="16.335017681121826" complete_time="7241.0713" loadedTiles = "250" visitedSegments = "2598" complete_distance = "204110.28" > start_lat="50.07577452522076" start_lon="14.45427417755127" target_lat="49.120547036367746" target_lon="16.335017681121826" complete_time="7241.0713" loadedTiles = "580" visitedSegments = "2598" complete_distance = "204110.28" >
<segment id="148483636" start="1" end="3" time = "7.144318" name = "" distance = "69.45865" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-13.969152" end_bearing = "-15.124007" description = "Go ahead and go 184.99 meters" /> <segment id="148483636" start="1" end="3" time = "7.144318" name = "" distance = "69.45865" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-13.969152" end_bearing = "-15.124007" description = "Go ahead and go 184.99 meters" />
<segment id="38611055" start="0" end="3" time = "11.883394" name = "Perunova" distance = "115.533" start_bearing = "-13.348727" end_bearing = "-14.32272" description = "" /> <segment id="38611055" start="0" end="3" time = "11.883394" name = "Perunova" distance = "115.533" start_bearing = "-13.348727" end_bearing = "-14.32272" description = "" />
<segment id="128493079" start="0" end="10" time = "27.32003" name = "Vinohradská" distance = "341.5004" turn = "Turn right" turn_angle = "99.87288" start_bearing = "85.550156" end_bearing = "84.289406" description = "Turn right and go 341.50 meters" /> <segment id="128493079" start="0" end="10" time = "27.32003" name = "Vinohradská" distance = "341.5004" turn = "Turn right" turn_angle = "99.87288" start_bearing = "85.550156" end_bearing = "84.289406" description = "Turn right and go 341.50 meters" />

View file

@ -1,21 +1,28 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<router_tests> <router_tests>
<test regions="" description="Long route to Maastricht" best_percent="5" vehicle="car" <test regions="" description="Long route to Maastricht" best_percent="5" vehicle="car"
start_lat="52.290868841722975" start_lon="4.831130504608154" target_lat="50.85492897352447" target_lon="5.701689720153809" complete_time="6897.156" loadedTiles = "185" visitedSegments = "3542" complete_distance = "208149.2" > start_lat="52.290868841722975" start_lon="4.831130504608154" target_lat="50.85492897352447" target_lon="5.701689720153809" complete_time="7043.331" loadedTiles = "1785" visitedSegments = "4456" complete_distance = "208488.69" >
<segment id="7366509" start="9" end="11" time = "9.088743" name = "" distance = "75.739525" turn = "Go ahead" turn_angle = "0.0" start_bearing = "115.31378" end_bearing = "115.46335" description = "Go ahead and go 75.74 meters" /> <segment id="7366509" start="9" end="11" time = "9.088743" name = "" distance = "75.739525" turn = "Go ahead" turn_angle = "0.0" start_bearing = "115.31378" end_bearing = "115.46335" description = "Go ahead and go 75.74 meters" />
<segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" turn = "Turn right" turn_angle = "89.33931" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "Turn right and go 26.76 meters" /> <segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" turn = "Turn right" turn_angle = "89.33931" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "Turn right and go 26.76 meters" />
<segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 774.68 meters" /> <segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 761.63 meters" />
<segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" /> <segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" />
<segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" /> <segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" />
<segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" /> <segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" />
<segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" /> <segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" />
<segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" /> <segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" />
<segment id="7365071" start="0" end="1" time = "0.9398953" name = "Zetterij" distance = "13.054101" start_bearing = "117.97948" end_bearing = "117.97948" description = "" /> <segment id="7365070" start="0" end="1" time = "1.0716465" name = "Bovenkerkerweg (N521) " distance = "14.883979" turn = "Turn right" turn_angle = "94.95008" start_bearing = "-170.42577" end_bearing = "-170.42577" description = "Turn right and go 58.89 meters" />
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" turn = "Turn left" turn_angle = "-105.37932" start_bearing = "12.60016" end_bearing = "12.60016" description = "Turn left and go 968.58 meters" /> <segment id="7365086" start="0" end="1" time = "3.1682494" name = "Bovenkerkerweg (N521) " distance = "44.003468" start_bearing = "-172.57889" end_bearing = "-172.57889" description = "" />
<segment id="7365086" start="1" end="3" time = "30.227621" name = "Bovenkerkerweg (N521) " distance = "72.60584" turn = "Keep right" turn_angle = "1.9589691" start_bearing = "-170.61992" end_bearing = "-173.29016" description = "Keep right and go 110.76 meters" />
<segment id="7365099" start="0" end="3" time = "2.747028" name = "Bovenkerkerweg (N521) " distance = "38.15317" start_bearing = "-173.21103" end_bearing = "-177.61406" description = "" />
<segment id="7365062" start="6" end="7" time = "0.84723866" name = "Beneluxbaan" distance = "11.767203" turn = "Make uturn" turn_angle = "0.0" start_bearing = "97.0165" end_bearing = "97.0165" description = "Make uturn and go 1105.87 meters" />
<segment id="7365101" start="0" end="3" time = "2.8561046" name = "Bovenkerkerweg (N521) " distance = "39.66812" start_bearing = "10.885527" end_bearing = "11.458753" description = "" />
<segment id="7365085" start="0" end="1" time = "8.459829" name = "Bovenkerkerweg (N521) " distance = "117.49763" start_bearing = "6.4971123" end_bearing = "6.4971123" description = "" />
<segment id="7365069" start="0" end="1" time = "0.57796" name = "Bovenkerkerweg (N521) " distance = "8.027223" start_bearing = "5.3145456" end_bearing = "5.3145456" description = "" />
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" start_bearing = "12.60016" end_bearing = "12.60016" description = "" />
<segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" /> <segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" />
<segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" /> <segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" />
<segment id="7364781" start="0" end="6" time = "54.49686" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" /> <segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" />
<segment id="7364782" start="1" end="0" time = "16.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" /> <segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
<segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" /> <segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" />
<segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" /> <segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" />
<segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" /> <segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" />
@ -32,10 +39,10 @@
<segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" /> <segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" />
<segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" /> <segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" />
<segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" /> <segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" />
<segment id="58384522" start="0" end="4" time = "20.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" /> <segment id="58384522" start="0" end="4" time = "30.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" />
<segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" /> <segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" />
<segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" /> <segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" />
<segment id="49900222" start="0" end="1" time = "16.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" /> <segment id="49900222" start="0" end="1" time = "26.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" />
<segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" /> <segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" />
<segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" /> <segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" />
<segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" /> <segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" />
@ -85,7 +92,7 @@
<segment id="80761369" start="0" end="1" time = "1.9537628" name = " (A2) " distance = "54.27119" start_bearing = "-178.45705" end_bearing = "-178.45705" description = "" /> <segment id="80761369" start="0" end="1" time = "1.9537628" name = " (A2) " distance = "54.27119" start_bearing = "-178.45705" end_bearing = "-178.45705" description = "" />
<segment id="80761365" start="0" end="6" time = "11.0511" name = " (A2) " distance = "306.975" start_bearing = "-176.12459" end_bearing = "-171.34746" description = "" /> <segment id="80761365" start="0" end="6" time = "11.0511" name = " (A2) " distance = "306.975" start_bearing = "-176.12459" end_bearing = "-171.34746" description = "" />
<segment id="152126643" start="0" end="2" time = "16.587639" name = " (A2) " distance = "460.76776" start_bearing = "-168.47627" end_bearing = "-165.6754" description = "" /> <segment id="152126643" start="0" end="2" time = "16.587639" name = " (A2) " distance = "460.76776" start_bearing = "-168.47627" end_bearing = "-165.6754" description = "" />
<segment id="93810171" start="0" end="1" time = "8.644352" name = " (A2) " distance = "240.1209" turn = "Keep left" turn_angle = "-1.1266632" lanes = "[1, 1, 0, 0]" start_bearing = "-166.80206" end_bearing = "-166.80206" description = "Keep left[1, 1, 0, 0] and go 4539.38 meters (*)" /> <segment id="93810171" start="0" end="1" time = "8.644352" name = " (A2) " distance = "240.1209" turn = "Keep left" turn_angle = "-1.1266632" lanes = "[1, 1, 0, 0]" start_bearing = "-166.80206" end_bearing = "-166.80206" description = "Keep left[1, 1, 0, 0] and go 4539.38 meters" />
<segment id="7054468" start="0" end="2" time = "29.638718" name = " (A2) " distance = "823.2977" start_bearing = "-167.47635" end_bearing = "-165.95709" description = "" /> <segment id="7054468" start="0" end="2" time = "29.638718" name = " (A2) " distance = "823.2977" start_bearing = "-167.47635" end_bearing = "-165.95709" description = "" />
<segment id="7054457" start="0" end="1" time = "3.6500416" name = " (A2) " distance = "101.390045" start_bearing = "-166.36688" end_bearing = "-166.36688" description = "" /> <segment id="7054457" start="0" end="1" time = "3.6500416" name = " (A2) " distance = "101.390045" start_bearing = "-166.36688" end_bearing = "-166.36688" description = "" />
<segment id="7054352" start="0" end="3" time = "24.02921" name = " (A2) " distance = "667.478" start_bearing = "-165.3489" end_bearing = "-165.1765" description = "" /> <segment id="7054352" start="0" end="3" time = "24.02921" name = " (A2) " distance = "667.478" start_bearing = "-165.3489" end_bearing = "-165.1765" description = "" />
@ -144,18 +151,18 @@
<segment id="7083242" start="0" end="8" time = "23.373617" name = " (A2) " distance = "779.12054" start_bearing = "-177.66797" end_bearing = "-177.48619" description = "" /> <segment id="7083242" start="0" end="8" time = "23.373617" name = " (A2) " distance = "779.12054" start_bearing = "-177.66797" end_bearing = "-177.48619" description = "" />
<segment id="7083262" start="0" end="1" time = "1.0658783" name = " (A2) " distance = "35.529278" start_bearing = "-176.44215" end_bearing = "-176.44215" description = "" /> <segment id="7083262" start="0" end="1" time = "1.0658783" name = " (A2) " distance = "35.529278" start_bearing = "-176.44215" end_bearing = "-176.44215" description = "" />
<segment id="60928833" start="0" end="1" time = "25.311256" name = " (A2) " distance = "843.7085" start_bearing = "-177.94655" end_bearing = "-177.94655" description = "" /> <segment id="60928833" start="0" end="1" time = "25.311256" name = " (A2) " distance = "843.7085" start_bearing = "-177.94655" end_bearing = "-177.94655" description = "" />
<segment id="7082839" start="0" end="10" time = "58.871197" name = " (A2) " distance = "1962.3732" turn = "Keep left" turn_angle = "0.121292114" lanes = "[1, 1, 1, 0]" start_bearing = "-177.82526" end_bearing = "176.08842" description = "Keep left[1, 1, 1, 0] and go 2067.44 meters (*)" /> <segment id="7082839" start="0" end="10" time = "58.871197" name = " (A2) " distance = "1962.3732" turn = "Keep left" turn_angle = "0.121292114" lanes = "[1, 1, 1, 0]" start_bearing = "-177.82526" end_bearing = "176.08842" description = "Keep left[1, 1, 1, 0] and go 4778.54 meters (*)" />
<segment id="87195824" start="0" end="1" time = "3.1519196" name = " (A2) " distance = "105.06398" start_bearing = "175.76361" end_bearing = "175.76361" description = "" /> <segment id="87195824" start="0" end="1" time = "3.1519196" name = " (A2) " distance = "105.06398" start_bearing = "175.76361" end_bearing = "175.76361" description = "" />
<segment id="87195824" start="1" end="9" time = "24.882273" name = " (A2) " distance = "829.40906" turn = "Keep left" turn_angle = "0.11303711" lanes = "[1, 1, 1, 0]" start_bearing = "175.87665" end_bearing = "158.7495" description = "Keep left[1, 1, 1, 0] and go 2711.10 meters (*)" /> <segment id="87195824" start="1" end="9" time = "24.882273" name = " (A2) " distance = "829.40906" start_bearing = "175.87665" end_bearing = "158.7495" description = "" />
<segment id="87195830" start="0" end="7" time = "19.536932" name = " (A2) " distance = "651.231" start_bearing = "157.98872" end_bearing = "135.32278" description = "" /> <segment id="87195830" start="0" end="7" time = "19.536932" name = " (A2) " distance = "651.231" start_bearing = "157.98872" end_bearing = "135.32278" description = "" />
<segment id="7082846" start="0" end="1" time = "1.332016" name = " (A2) " distance = "44.40053" start_bearing = "132.66948" end_bearing = "132.66948" description = "" /> <segment id="7082846" start="0" end="1" time = "1.332016" name = " (A2) " distance = "44.40053" start_bearing = "132.66948" end_bearing = "132.66948" description = "" />
<segment id="7082849" start="0" end="3" time = "12.256795" name = " (A2) " distance = "408.5598" start_bearing = "129.9005" end_bearing = "123.859245" description = "" /> <segment id="7082849" start="0" end="3" time = "12.256795" name = " (A2) " distance = "408.5598" start_bearing = "129.9005" end_bearing = "123.859245" description = "" />
<segment id="7082851" start="0" end="1" time = "1.7693062" name = " (A2) " distance = "58.976868" start_bearing = "124.133446" end_bearing = "124.133446" description = "" /> <segment id="7082851" start="0" end="1" time = "1.7693062" name = " (A2) " distance = "58.976868" start_bearing = "124.133446" end_bearing = "124.133446" description = "" />
<segment id="7081833" start="0" end="9" time = "21.555794" name = " (A2) " distance = "718.5264" start_bearing = "125.44192" end_bearing = "141.00053" description = "" /> <segment id="7081833" start="0" end="9" time = "21.555794" name = " (A2) " distance = "718.5264" start_bearing = "125.44192" end_bearing = "141.00053" description = "" />
<segment id="7081833" start="9" end="11" time = "18.920055" name = " (A2) " distance = "630.6685" turn = "Keep left" turn_angle = "1.3838348" lanes = "[1, 1, 1, 0]" start_bearing = "142.38437" end_bearing = "143.98479" description = "Keep left[1, 1, 1, 0] and go 1705.73 meters (*)" /> <segment id="7081833" start="9" end="11" time = "18.920055" name = " (A2) " distance = "630.6685" turn = "Keep left" turn_angle = "1.3838348" lanes = "[1, 1, 1, 0]" start_bearing = "142.38437" end_bearing = "143.98479" description = "Keep left[1, 1, 1, 0] and go 4214.98 meters (*)" />
<segment id="7081844" start="0" end="1" time = "0.74438155" name = " (A2) " distance = "24.812717" start_bearing = "144.41263" end_bearing = "144.41263" description = "" /> <segment id="7081844" start="0" end="1" time = "0.74438155" name = " (A2) " distance = "24.812717" start_bearing = "144.41263" end_bearing = "144.41263" description = "" />
<segment id="7081846" start="0" end="2" time = "31.507397" name = " (A2) " distance = "1050.2466" start_bearing = "144.40886" end_bearing = "145.51918" description = "" /> <segment id="7081846" start="0" end="2" time = "31.507397" name = " (A2) " distance = "1050.2466" start_bearing = "144.40886" end_bearing = "145.51918" description = "" />
<segment id="7081846" start="2" end="3" time = "0.46107167" name = " (A2) " distance = "15.369055" turn = "Keep left" turn_angle = "0.04182434" lanes = "[1, 1, 1, 0]" start_bearing = "145.561" end_bearing = "145.561" description = "Keep left[1, 1, 1, 0] and go 2509.26 meters (*)" /> <segment id="7081846" start="2" end="3" time = "0.46107167" name = " (A2) " distance = "15.369055" start_bearing = "145.561" end_bearing = "145.561" description = "" />
<segment id="7081825" start="0" end="1" time = "1.5179313" name = " (A2) " distance = "50.59771" start_bearing = "145.9634" end_bearing = "145.9634" description = "" /> <segment id="7081825" start="0" end="1" time = "1.5179313" name = " (A2) " distance = "50.59771" start_bearing = "145.9634" end_bearing = "145.9634" description = "" />
<segment id="7081704" start="0" end="3" time = "36.545654" name = " (A2) " distance = "1218.1884" start_bearing = "145.98322" end_bearing = "145.91476" description = "" /> <segment id="7081704" start="0" end="3" time = "36.545654" name = " (A2) " distance = "1218.1884" start_bearing = "145.98322" end_bearing = "145.91476" description = "" />
<segment id="7081701" start="0" end="1" time = "3.0920525" name = " (A2) " distance = "103.068405" start_bearing = "146.47978" end_bearing = "146.47978" description = "" /> <segment id="7081701" start="0" end="1" time = "3.0920525" name = " (A2) " distance = "103.068405" start_bearing = "146.47978" end_bearing = "146.47978" description = "" />
@ -163,7 +170,7 @@
<segment id="7081386" start="0" end="1" time = "6.63905" name = " (A2) " distance = "221.30167" start_bearing = "145.88553" end_bearing = "145.88553" description = "" /> <segment id="7081386" start="0" end="1" time = "6.63905" name = " (A2) " distance = "221.30167" start_bearing = "145.88553" end_bearing = "145.88553" description = "" />
<segment id="7081384" start="0" end="1" time = "1.1803325" name = " (A2) " distance = "39.344418" start_bearing = "145.42284" end_bearing = "145.42284" description = "" /> <segment id="7081384" start="0" end="1" time = "1.1803325" name = " (A2) " distance = "39.344418" start_bearing = "145.42284" end_bearing = "145.42284" description = "" />
<segment id="7081015" start="0" end="3" time = "21.335112" name = " (A2) " distance = "711.17035" start_bearing = "145.26582" end_bearing = "140.59818" description = "" /> <segment id="7081015" start="0" end="3" time = "21.335112" name = " (A2) " distance = "711.17035" start_bearing = "145.26582" end_bearing = "140.59818" description = "" />
<segment id="54318418" start="0" end="27" time = "123.92231" name = " (A2) " distance = "4130.7437" turn = "Keep left" turn_angle = "-2.0806732" lanes = "[1, 1, 0, 0]" start_bearing = "138.5175" end_bearing = "164.93518" description = "Keep left[1, 1, 0, 0] and go 7595.80 meters (*)" /> <segment id="54318418" start="0" end="27" time = "123.92231" name = " (A2) " distance = "4130.7437" turn = "Keep left" turn_angle = "-2.0806732" lanes = "[1, 1, 0, 0]" start_bearing = "138.5175" end_bearing = "164.93518" description = "Keep left[1, 1, 0, 0] and go 7595.80 meters" />
<segment id="6950203" start="0" end="1" time = "1.0974485" name = " (A2) " distance = "36.581615" start_bearing = "166.4589" end_bearing = "166.4589" description = "" /> <segment id="6950203" start="0" end="1" time = "1.0974485" name = " (A2) " distance = "36.581615" start_bearing = "166.4589" end_bearing = "166.4589" description = "" />
<segment id="35286295" start="0" end="4" time = "8.819818" name = " (A2) " distance = "293.9939" start_bearing = "167.24911" end_bearing = "172.56018" description = "" /> <segment id="35286295" start="0" end="4" time = "8.819818" name = " (A2) " distance = "293.9939" start_bearing = "167.24911" end_bearing = "172.56018" description = "" />
<segment id="35266566" start="0" end="2" time = "3.0470872" name = " (A2) " distance = "101.56957" start_bearing = "174.98376" end_bearing = "177.47758" description = "" /> <segment id="35266566" start="0" end="2" time = "3.0470872" name = " (A2) " distance = "101.56957" start_bearing = "174.98376" end_bearing = "177.47758" description = "" />
@ -195,10 +202,10 @@
<segment id="7173912" start="0" end="8" time = "12.146003" name = " (A2) " distance = "404.86673" start_bearing = "164.6402" end_bearing = "175.66768" description = "" /> <segment id="7173912" start="0" end="8" time = "12.146003" name = " (A2) " distance = "404.86673" start_bearing = "164.6402" end_bearing = "175.66768" description = "" />
<segment id="7173915" start="0" end="1" time = "1.8925273" name = " (A2) " distance = "63.084244" start_bearing = "177.30571" end_bearing = "177.30571" description = "" /> <segment id="7173915" start="0" end="1" time = "1.8925273" name = " (A2) " distance = "63.084244" start_bearing = "177.30571" end_bearing = "177.30571" description = "" />
<segment id="7173917" start="0" end="1" time = "1.7798107" name = " (A2) " distance = "59.32702" start_bearing = "178.19316" end_bearing = "178.19316" description = "" /> <segment id="7173917" start="0" end="1" time = "1.7798107" name = " (A2) " distance = "59.32702" start_bearing = "178.19316" end_bearing = "178.19316" description = "" />
<segment id="7173917" start="1" end="2" time = "4.5603037" name = " (A2) " distance = "152.01012" turn = "Keep left" turn_angle = "0.6930847" lanes = "[1, 1, 0]" start_bearing = "178.88625" end_bearing = "178.88625" description = "Keep left[1, 1, 0] and go 1775.60 meters (*)" /> <segment id="7173917" start="1" end="2" time = "4.5603037" name = " (A2) " distance = "152.01012" turn = "Keep left" turn_angle = "0.6930847" lanes = "[1, 1, 0]" start_bearing = "178.88625" end_bearing = "178.88625" description = "Keep left[1, 1, 0] and go 6521.90 meters (*)" />
<segment id="7173905" start="0" end="1" time = "1.4901867" name = " (A2) " distance = "49.67289" start_bearing = "-180.0" end_bearing = "180.0" description = "" /> <segment id="7173905" start="0" end="1" time = "1.4901867" name = " (A2) " distance = "49.67289" start_bearing = "-180.0" end_bearing = "180.0" description = "" />
<segment id="7173935" start="0" end="5" time = "47.21756" name = " (A2) " distance = "1573.9186" start_bearing = "178.95203" end_bearing = "176.12459" description = "" /> <segment id="7173935" start="0" end="5" time = "47.21756" name = " (A2) " distance = "1573.9186" start_bearing = "178.95203" end_bearing = "176.12459" description = "" />
<segment id="7173935" start="5" end="21" time = "142.38881" name = " (A2) " distance = "4746.2935" turn = "Keep left" turn_angle = "-1.4848022" lanes = "[1, 1, 0]" start_bearing = "174.63979" end_bearing = "145.51537" description = "Keep left[1, 1, 0] and go 4746.29 meters (*)" /> <segment id="7173935" start="5" end="21" time = "142.38881" name = " (A2) " distance = "4746.2935" start_bearing = "174.63979" end_bearing = "145.51537" description = "" />
<segment id="7173935" start="21" end="29" time = "67.018425" name = " (A2) " distance = "2233.9475" turn = "Keep left" turn_angle = "-0.6148071" lanes = "[1, 1, 0]" start_bearing = "144.90056" end_bearing = "141.10718" description = "Keep left[1, 1, 0] and go 2233.95 meters (*)" /> <segment id="7173935" start="21" end="29" time = "67.018425" name = " (A2) " distance = "2233.9475" turn = "Keep left" turn_angle = "-0.6148071" lanes = "[1, 1, 0]" start_bearing = "144.90056" end_bearing = "141.10718" description = "Keep left[1, 1, 0] and go 2233.95 meters (*)" />
<segment id="7173935" start="29" end="32" time = "14.9291725" name = " (A2) " distance = "497.63907" turn = "Keep left" turn_angle = "-1.8707886" lanes = "[1, 1, 0]" start_bearing = "139.23639" end_bearing = "138.31236" description = "Keep left[1, 1, 0] and go 1980.99 meters (*)" /> <segment id="7173935" start="29" end="32" time = "14.9291725" name = " (A2) " distance = "497.63907" turn = "Keep left" turn_angle = "-1.8707886" lanes = "[1, 1, 0]" start_bearing = "139.23639" end_bearing = "138.31236" description = "Keep left[1, 1, 0] and go 1980.99 meters (*)" />
<segment id="7179075" start="0" end="1" time = "1.5465801" name = " (A2) " distance = "51.55267" start_bearing = "138.19594" end_bearing = "138.19594" description = "" /> <segment id="7179075" start="0" end="1" time = "1.5465801" name = " (A2) " distance = "51.55267" start_bearing = "138.19594" end_bearing = "138.19594" description = "" />
@ -250,14 +257,14 @@
<segment id="34601788" start="0" end="2" time = "17.838524" name = " (A2;A67) " distance = "594.61743" start_bearing = "92.92696" end_bearing = "92.76961" description = "" /> <segment id="34601788" start="0" end="2" time = "17.838524" name = " (A2;A67) " distance = "594.61743" start_bearing = "92.92696" end_bearing = "92.76961" description = "" />
<segment id="129359000" start="0" end="1" time = "0.8941588" name = " (A2;A67) " distance = "29.80529" start_bearing = "92.80981" end_bearing = "92.80981" description = "" /> <segment id="129359000" start="0" end="1" time = "0.8941588" name = " (A2;A67) " distance = "29.80529" start_bearing = "92.80981" end_bearing = "92.80981" description = "" />
<segment id="129359001" start="0" end="1" time = "0.17860866" name = " (A2;A67) " distance = "5.953622" start_bearing = "91.7357" end_bearing = "91.7357" description = "" /> <segment id="129359001" start="0" end="1" time = "0.17860866" name = " (A2;A67) " distance = "5.953622" start_bearing = "91.7357" end_bearing = "91.7357" description = "" />
<segment id="41960113" start="0" end="9" time = "12.305996" name = " (A2) " distance = "410.19983" turn = "Keep left" turn_angle = "0.41725922" lanes = "[1, 1, 0, 0]" start_bearing = "92.15296" end_bearing = "107.69364" description = "Keep left[1, 1, 0, 0] and go 6969.30 meters (*)" /> <segment id="41960113" start="0" end="9" time = "12.305996" name = " (A2) " distance = "410.19983" turn = "Keep left" turn_angle = "0.41725922" lanes = "[1, 1, 0, 0]" start_bearing = "92.15296" end_bearing = "107.69364" description = "Keep left[1, 1, 0, 0] and go 6969.30 meters" />
<segment id="46177355" start="0" end="3" time = "2.9886634" name = " (A2) " distance = "99.62211" start_bearing = "107.61258" end_bearing = "111.48204" description = "" /> <segment id="46177355" start="0" end="3" time = "2.9886634" name = " (A2) " distance = "99.62211" start_bearing = "107.61258" end_bearing = "111.48204" description = "" />
<segment id="7181608" start="0" end="13" time = "14.447598" name = " (A2) " distance = "481.5866" start_bearing = "112.94894" end_bearing = "141.93434" description = "" /> <segment id="7181608" start="0" end="13" time = "14.447598" name = " (A2) " distance = "481.5866" start_bearing = "112.94894" end_bearing = "141.93434" description = "" />
<segment id="129358985" start="0" end="2" time = "2.1925447" name = " (A2) " distance = "73.08482" start_bearing = "146.47247" end_bearing = "146.47247" description = "" /> <segment id="129358985" start="0" end="2" time = "2.1925447" name = " (A2) " distance = "73.08482" start_bearing = "146.47247" end_bearing = "146.47247" description = "" />
<segment id="129358986" start="0" end="10" time = "15.391882" name = " (A2) " distance = "513.0627" start_bearing = "148.48593" end_bearing = "174.4588" description = "" /> <segment id="129358986" start="0" end="10" time = "15.391882" name = " (A2) " distance = "513.0627" start_bearing = "148.48593" end_bearing = "174.4588" description = "" />
<segment id="57124219" start="0" end="1" time = "3.6961312" name = " (A2) " distance = "123.20437" start_bearing = "163.70851" end_bearing = "163.70851" description = "" /> <segment id="57124219" start="0" end="1" time = "3.6961312" name = " (A2) " distance = "123.20437" start_bearing = "163.70851" end_bearing = "163.70851" description = "" />
<segment id="7138181" start="0" end="11" time = "158.05623" name = " (A2) " distance = "5268.541" start_bearing = "164.86745" end_bearing = "150.9332" description = "" /> <segment id="7138181" start="0" end="11" time = "158.05623" name = " (A2) " distance = "5268.541" start_bearing = "164.86745" end_bearing = "150.9332" description = "" />
<segment id="7138582" start="0" end="1" time = "12.939249" name = " (A2) " distance = "431.3083" turn = "Keep left" turn_angle = "1.0292664" lanes = "[1, 1, 0]" start_bearing = "151.96246" end_bearing = "151.96246" description = "Keep left[1, 1, 0] and go 4949.16 meters (*)" /> <segment id="7138582" start="0" end="1" time = "12.939249" name = " (A2) " distance = "431.3083" turn = "Keep left" turn_angle = "1.0292664" lanes = "[1, 1, 0]" start_bearing = "151.96246" end_bearing = "151.96246" description = "Keep left[1, 1, 0] and go 6302.33 meters (*)" />
<segment id="7138584" start="0" end="1" time = "1.9605826" name = " (A2) " distance = "65.35275" start_bearing = "151.7652" end_bearing = "151.7652" description = "" /> <segment id="7138584" start="0" end="1" time = "1.9605826" name = " (A2) " distance = "65.35275" start_bearing = "151.7652" end_bearing = "151.7652" description = "" />
<segment id="7138593" start="0" end="8" time = "22.77318" name = " (A2) " distance = "759.106" start_bearing = "149.63991" end_bearing = "122.376434" description = "" /> <segment id="7138593" start="0" end="8" time = "22.77318" name = " (A2) " distance = "759.106" start_bearing = "149.63991" end_bearing = "122.376434" description = "" />
<segment id="7138594" start="0" end="1" time = "1.104279" name = " (A2) " distance = "36.809303" start_bearing = "122.19573" end_bearing = "122.19573" description = "" /> <segment id="7138594" start="0" end="1" time = "1.104279" name = " (A2) " distance = "36.809303" start_bearing = "122.19573" end_bearing = "122.19573" description = "" />
@ -267,7 +274,7 @@
<segment id="7138608" start="0" end="1" time = "0.5713057" name = " (A2) " distance = "19.043524" start_bearing = "121.53479" end_bearing = "121.53479" description = "" /> <segment id="7138608" start="0" end="1" time = "0.5713057" name = " (A2) " distance = "19.043524" start_bearing = "121.53479" end_bearing = "121.53479" description = "" />
<segment id="7138570" start="0" end="4" time = "30.841974" name = " (A2) " distance = "1028.0658" start_bearing = "122.167595" end_bearing = "120.012825" description = "" /> <segment id="7138570" start="0" end="4" time = "30.841974" name = " (A2) " distance = "1028.0658" start_bearing = "122.167595" end_bearing = "120.012825" description = "" />
<segment id="7137120" start="0" end="9" time = "60.733063" name = " (A2) " distance = "2024.4354" start_bearing = "119.456055" end_bearing = "142.62645" description = "" /> <segment id="7137120" start="0" end="9" time = "60.733063" name = " (A2) " distance = "2024.4354" start_bearing = "119.456055" end_bearing = "142.62645" description = "" />
<segment id="7137120" start="9" end="12" time = "19.791756" name = " (A2) " distance = "659.72516" turn = "Keep left" turn_angle = "-0.8337555" lanes = "[1, 1, 0]" start_bearing = "141.7927" end_bearing = "142.10811" description = "Keep left[1, 1, 0] and go 1353.16 meters (*)" /> <segment id="7137120" start="9" end="12" time = "19.791756" name = " (A2) " distance = "659.72516" start_bearing = "141.7927" end_bearing = "142.10811" description = "" />
<segment id="7137076" start="0" end="1" time = "1.9422636" name = " (A2) " distance = "64.74212" start_bearing = "142.06673" end_bearing = "142.06673" description = "" /> <segment id="7137076" start="0" end="1" time = "1.9422636" name = " (A2) " distance = "64.74212" start_bearing = "142.06673" end_bearing = "142.06673" description = "" />
<segment id="7137093" start="0" end="2" time = "18.860876" name = " (A2) " distance = "628.6958" start_bearing = "143.43219" end_bearing = "148.48138" description = "" /> <segment id="7137093" start="0" end="2" time = "18.860876" name = " (A2) " distance = "628.6958" start_bearing = "143.43219" end_bearing = "148.48138" description = "" />
<segment id="7137085" start="0" end="2" time = "8.986393" name = " (A2) " distance = "299.54642" turn = "Keep left" turn_angle = "-1.9695587" lanes = "[1, 1, 0]" start_bearing = "146.51183" end_bearing = "144.0556" description = "Keep left[1, 1, 0] and go 2280.14 meters (*)" /> <segment id="7137085" start="0" end="2" time = "8.986393" name = " (A2) " distance = "299.54642" turn = "Keep left" turn_angle = "-1.9695587" lanes = "[1, 1, 0]" start_bearing = "146.51183" end_bearing = "144.0556" description = "Keep left[1, 1, 0] and go 2280.14 meters (*)" />
@ -282,17 +289,17 @@
<segment id="7134786" start="0" end="4" time = "6.239682" name = " (A2) " distance = "207.9894" start_bearing = "132.66269" end_bearing = "143.909" description = "" /> <segment id="7134786" start="0" end="4" time = "6.239682" name = " (A2) " distance = "207.9894" start_bearing = "132.66269" end_bearing = "143.909" description = "" />
<segment id="7134786" start="4" end="18" time = "46.656086" name = " (A2) " distance = "1555.2029" turn = "Keep left" turn_angle = "3.9660034" lanes = "[1, 1, 0]" start_bearing = "147.875" end_bearing = "129.92787" description = "Keep left[1, 1, 0] and go 1555.20 meters (*)" /> <segment id="7134786" start="4" end="18" time = "46.656086" name = " (A2) " distance = "1555.2029" turn = "Keep left" turn_angle = "3.9660034" lanes = "[1, 1, 0]" start_bearing = "147.875" end_bearing = "129.92787" description = "Keep left[1, 1, 0] and go 1555.20 meters (*)" />
<segment id="7133368" start="0" end="45" time = "161.42354" name = " (A2) " distance = "5380.784" turn = "Keep left" turn_angle = "-7.772148" lanes = "[1, 1, 0]" start_bearing = "122.15572" end_bearing = "127.22508" description = "Keep left[1, 1, 0] and go 5380.78 meters (*)" /> <segment id="7133368" start="0" end="45" time = "161.42354" name = " (A2) " distance = "5380.784" turn = "Keep left" turn_angle = "-7.772148" lanes = "[1, 1, 0]" start_bearing = "122.15572" end_bearing = "127.22508" description = "Keep left[1, 1, 0] and go 5380.78 meters (*)" />
<segment id="6735354" start="0" end="1" time = "3.023609" name = " (A2) " distance = "100.78696" turn = "Keep left" turn_angle = "7.550812" lanes = "[1, 1, 0]" start_bearing = "134.7759" end_bearing = "134.7759" description = "Keep left[1, 1, 0] and go 3543.38 meters (*)" /> <segment id="6735354" start="0" end="1" time = "3.023609" name = " (A2) " distance = "100.78696" turn = "Keep left" turn_angle = "7.550812" lanes = "[1, 1, 0]" start_bearing = "134.7759" end_bearing = "134.7759" description = "Keep left[1, 1, 0] and go 6298.18 meters (*)" />
<segment id="57123265" start="0" end="4" time = "11.997399" name = " (A2) " distance = "399.9133" start_bearing = "139.2456" end_bearing = "150.65193" description = "" /> <segment id="57123265" start="0" end="4" time = "11.997399" name = " (A2) " distance = "399.9133" start_bearing = "139.2456" end_bearing = "150.65193" description = "" />
<segment id="6735330" start="0" end="1" time = "1.8624623" name = " (A2) " distance = "62.082073" start_bearing = "152.81473" end_bearing = "152.81473" description = "" /> <segment id="6735330" start="0" end="1" time = "1.8624623" name = " (A2) " distance = "62.082073" start_bearing = "152.81473" end_bearing = "152.81473" description = "" />
<segment id="6735347" start="0" end="3" time = "19.002733" name = " (A2) " distance = "633.4244" start_bearing = "153.98177" end_bearing = "158.04019" description = "" /> <segment id="6735347" start="0" end="3" time = "19.002733" name = " (A2) " distance = "633.4244" start_bearing = "153.98177" end_bearing = "158.04019" description = "" />
<segment id="6735335" start="0" end="1" time = "2.4163463" name = " (A2) " distance = "80.54487" start_bearing = "159.67686" end_bearing = "159.67686" description = "" /> <segment id="6735335" start="0" end="1" time = "2.4163463" name = " (A2) " distance = "80.54487" start_bearing = "159.67686" end_bearing = "159.67686" description = "" />
<segment id="6733875" start="0" end="12" time = "67.998856" name = " (A2) " distance = "2266.6284" start_bearing = "158.63722" end_bearing = "121.59014" description = "" /> <segment id="6733875" start="0" end="12" time = "67.998856" name = " (A2) " distance = "2266.6284" start_bearing = "158.63722" end_bearing = "121.59014" description = "" />
<segment id="6733875" start="12" end="30" time = "82.64402" name = " (A2) " distance = "2754.8008" turn = "Keep left" turn_angle = "-0.029792786" lanes = "[1, 1, 0]" start_bearing = "121.56035" end_bearing = "146.53694" description = "Keep left[1, 1, 0] and go 2754.80 meters (*)" /> <segment id="6733875" start="12" end="30" time = "82.64402" name = " (A2) " distance = "2754.8008" start_bearing = "121.56035" end_bearing = "146.53694" description = "" />
<segment id="6733875" start="30" end="31" time = "5.352952" name = " (A2) " distance = "178.43173" turn = "Keep left" turn_angle = "-1.6221619" lanes = "[1, 1, 0]" start_bearing = "144.91478" end_bearing = "144.91478" description = "Keep left[1, 1, 0] and go 2295.99 meters (*)" /> <segment id="6733875" start="30" end="31" time = "5.352952" name = " (A2) " distance = "178.43173" turn = "Keep left" turn_angle = "-1.6221619" lanes = "[1, 1, 0]" start_bearing = "144.91478" end_bearing = "144.91478" description = "Keep left[1, 1, 0] and go 7194.36 meters (*)" />
<segment id="6733858" start="0" end="1" time = "1.2741007" name = " (A2) " distance = "42.47002" start_bearing = "144.78241" end_bearing = "144.78241" description = "" /> <segment id="6733858" start="0" end="1" time = "1.2741007" name = " (A2) " distance = "42.47002" start_bearing = "144.78241" end_bearing = "144.78241" description = "" />
<segment id="6761009" start="0" end="8" time = "62.252544" name = " (A2) " distance = "2075.0847" start_bearing = "142.9811" end_bearing = "149.37885" description = "" /> <segment id="6761009" start="0" end="8" time = "62.252544" name = " (A2) " distance = "2075.0847" start_bearing = "142.9811" end_bearing = "149.37885" description = "" />
<segment id="6761009" start="8" end="19" time = "146.95122" name = " (A2) " distance = "4898.3735" turn = "Keep left" turn_angle = "0.2501831" lanes = "[1, 1, 0]" start_bearing = "149.62903" end_bearing = "157.77496" description = "Keep left[1, 1, 0] and go 4898.37 meters (*)" /> <segment id="6761009" start="8" end="19" time = "146.95122" name = " (A2) " distance = "4898.3735" start_bearing = "149.62903" end_bearing = "157.77496" description = "" />
<segment id="6761009" start="19" end="27" time = "28.343882" name = " (A2) " distance = "944.796" turn = "Keep left" turn_angle = "1.53656" lanes = "[1, 1, 0]" start_bearing = "159.31152" end_bearing = "138.09918" description = "Keep left[1, 1, 0] and go 4997.55 meters (*)" /> <segment id="6761009" start="19" end="27" time = "28.343882" name = " (A2) " distance = "944.796" turn = "Keep left" turn_angle = "1.53656" lanes = "[1, 1, 0]" start_bearing = "159.31152" end_bearing = "138.09918" description = "Keep left[1, 1, 0] and go 4997.55 meters (*)" />
<segment id="6760794" start="0" end="11" time = "48.690052" name = " (A2) " distance = "1623.0017" start_bearing = "137.40173" end_bearing = "113.73268" description = "" /> <segment id="6760794" start="0" end="11" time = "48.690052" name = " (A2) " distance = "1623.0017" start_bearing = "137.40173" end_bearing = "113.73268" description = "" />
<segment id="37874907" start="0" end="1" time = "1.0846229" name = " (A2) " distance = "36.154095" start_bearing = "114.14554" end_bearing = "114.14554" description = "" /> <segment id="37874907" start="0" end="1" time = "1.0846229" name = " (A2) " distance = "36.154095" start_bearing = "114.14554" end_bearing = "114.14554" description = "" />
@ -318,8 +325,8 @@
<segment id="6756968" start="0" end="12" time = "51.92214" name = " (A2) " distance = "1730.7379" start_bearing = "-131.39786" end_bearing = "-151.28493" description = "" /> <segment id="6756968" start="0" end="12" time = "51.92214" name = " (A2) " distance = "1730.7379" start_bearing = "-131.39786" end_bearing = "-151.28493" description = "" />
<segment id="6756967" start="0" end="1" time = "0.86474246" name = " (A2) " distance = "28.824747" start_bearing = "-151.12456" end_bearing = "-151.12456" description = "" /> <segment id="6756967" start="0" end="1" time = "0.86474246" name = " (A2) " distance = "28.824747" start_bearing = "-151.12456" end_bearing = "-151.12456" description = "" />
<segment id="6764626" start="0" end="13" time = "76.00803" name = " (A2) " distance = "2533.601" start_bearing = "-151.3797" end_bearing = "-170.0643" description = "" /> <segment id="6764626" start="0" end="13" time = "76.00803" name = " (A2) " distance = "2533.601" start_bearing = "-151.3797" end_bearing = "-170.0643" description = "" />
<segment id="6764626" start="13" end="22" time = "39.152573" name = " (A2) " distance = "1305.0857" turn = "Keep left" turn_angle = "-3.17984" lanes = "[1, 1, 0]" start_bearing = "-173.24414" end_bearing = "171.15948" description = "Keep left[1, 1, 0] and go 1305.09 meters (*)" /> <segment id="6764626" start="13" end="22" time = "39.152573" name = " (A2) " distance = "1305.0857" turn = "Keep left" turn_angle = "-3.17984" lanes = "[1, 1, 0]" start_bearing = "-173.24414" end_bearing = "171.15948" description = "Keep left[1, 1, 0] and go 3249.24 meters (*)" />
<segment id="6764626" start="22" end="28" time = "34.96675" name = " (A2) " distance = "1165.5583" turn = "Keep left" turn_angle = "0.58154297" lanes = "[1, 1, 0]" start_bearing = "171.74103" end_bearing = "-178.93416" description = "Keep left[1, 1, 0] and go 1944.16 meters (*)" /> <segment id="6764626" start="22" end="28" time = "34.96675" name = " (A2) " distance = "1165.5583" start_bearing = "171.74103" end_bearing = "-178.93416" description = "" />
<segment id="6764627" start="0" end="1" time = "1.2607403" name = " (A2) " distance = "42.024677" start_bearing = "-176.93352" end_bearing = "-176.93352" description = "" /> <segment id="6764627" start="0" end="1" time = "1.2607403" name = " (A2) " distance = "42.024677" start_bearing = "-176.93352" end_bearing = "-176.93352" description = "" />
<segment id="6764640" start="0" end="2" time = "6.8866363" name = " (A2) " distance = "229.55453" start_bearing = "-177.31622" end_bearing = "-173.53018" description = "" /> <segment id="6764640" start="0" end="2" time = "6.8866363" name = " (A2) " distance = "229.55453" start_bearing = "-177.31622" end_bearing = "-173.53018" description = "" />
<segment id="6764637" start="0" end="1" time = "1.7470565" name = " (A2) " distance = "58.235214" start_bearing = "-173.29016" end_bearing = "-173.29016" description = "" /> <segment id="6764637" start="0" end="1" time = "1.7470565" name = " (A2) " distance = "58.235214" start_bearing = "-173.29016" end_bearing = "-173.29016" description = "" />
@ -334,19 +341,24 @@
<segment id="6776798" start="0" end="3" time = "13.407926" name = " (A2) " distance = "446.93085" start_bearing = "-163.23038" end_bearing = "-167.19052" description = "" /> <segment id="6776798" start="0" end="3" time = "13.407926" name = " (A2) " distance = "446.93085" start_bearing = "-163.23038" end_bearing = "-167.19052" description = "" />
<segment id="6776788" start="0" end="1" time = "1.570805" name = " (A2) " distance = "52.36016" start_bearing = "-171.61038" end_bearing = "-171.61038" description = "" /> <segment id="6776788" start="0" end="1" time = "1.570805" name = " (A2) " distance = "52.36016" start_bearing = "-171.61038" end_bearing = "-171.61038" description = "" />
<segment id="6774982" start="0" end="11" time = "31.075895" name = " (A2) " distance = "1035.8632" start_bearing = "-174.4368" end_bearing = "155.75833" description = "" /> <segment id="6774982" start="0" end="11" time = "31.075895" name = " (A2) " distance = "1035.8632" start_bearing = "-174.4368" end_bearing = "155.75833" description = "" />
<segment id="6774982" start="11" end="16" time = "8.318511" name = " (A2) " distance = "277.2837" turn = "Keep left" turn_angle = "1.7171173" lanes = "[1, 1, 0]" start_bearing = "157.47545" end_bearing = "165.72327" description = "Keep left[1, 1, 0] and go 2484.68 meters (*)" /> <segment id="6774984" start="0" end="3" time = "8.277423" name = " (A2) " distance = "275.9141" turn = "Keep right" turn_angle = "8.29628" lanes = "[0, 0, 1]" start_bearing = "164.05461" end_bearing = "164.55247" description = "Keep right[0, 0, 1] and go 675.00 meters" />
<segment id="6774986" start="0" end="1" time = "1.193324" name = " (A2) " distance = "39.777462" start_bearing = "167.14766" end_bearing = "167.14766" description = "" /> <segment id="6774985" start="0" end="1" time = "1.1368768" name = " (A2) " distance = "37.895893" start_bearing = "166.94069" end_bearing = "166.94069" description = "" />
<segment id="6774822" start="0" end="7" time = "22.103643" name = " (A2) " distance = "736.7881" start_bearing = "168.73532" end_bearing = "-175.156" description = "" /> <segment id="6774979" start="0" end="1" time = "0.96351945" name = " (A2) " distance = "32.117313" start_bearing = "168.36636" end_bearing = "168.36636" description = "" />
<segment id="6775285" start="0" end="1" time = "2.0140622" name = " (A2) " distance = "67.1354" start_bearing = "-175.16959" end_bearing = "-175.16959" description = "" /> <segment id="6774821" start="0" end="5" time = "9.872207" name = " (A2) " distance = "329.07355" start_bearing = "170.36246" end_bearing = "176.13081" description = "" />
<segment id="6775316" start="0" end="3" time = "31.417942" name = " (A2) " distance = "1047.2646" start_bearing = "-175.58209" end_bearing = "-177.13759" description = "" /> <segment id="6774821" start="5" end="8" time = "10.706974" name = " (A2) " distance = "356.8991" turn = "Keep left" turn_angle = "5.017029" lanes = "[1, 0]" start_bearing = "-178.85216" end_bearing = "-174.92787" description = "Keep left[1, 0] and go 478.32 meters" />
<segment id="6775289" start="0" end="1" time = "0.4754576" name = " (A2) " distance = "15.848586" start_bearing = "-175.12073" end_bearing = "-175.12073" description = "" />
<segment id="6775286" start="0" end="1" time = "1.9916139" name = " (A2) " distance = "66.38713" start_bearing = "-174.54448" end_bearing = "-174.54448" description = "" />
<segment id="6775315" start="0" end="1" time = "1.175504" name = " (A2) " distance = "39.183464" start_bearing = "-176.40643" end_bearing = "-176.40643" description = "" />
<segment id="6775263" start="0" end="1" time = "14.832899" name = " (A2) " distance = "494.42993" turn = "Keep left" turn_angle = "0.9855652" lanes = "[1, 0]" start_bearing = "-175.42087" end_bearing = "-175.42087" description = "Keep left[1, 0] and go 1326.35 meters" />
<segment id="6775253" start="0" end="4" time = "15.464679" name = " (A2) " distance = "515.48926" start_bearing = "-175.13548" end_bearing = "179.25352" description = "" />
<segment id="6775293" start="0" end="3" time = "8.217698" name = " (A2) " distance = "273.92325" start_bearing = "178.83086" end_bearing = "173.03853" description = "" /> <segment id="6775293" start="0" end="3" time = "8.217698" name = " (A2) " distance = "273.92325" start_bearing = "178.83086" end_bearing = "173.03853" description = "" />
<segment id="80503748" start="0" end="1" time = "1.2753391" name = " (A2) " distance = "42.511303" start_bearing = "172.01514" end_bearing = "172.01514" description = "" /> <segment id="80503748" start="0" end="1" time = "1.2753391" name = " (A2) " distance = "42.511303" start_bearing = "172.01514" end_bearing = "172.01514" description = "" />
<segment id="80503746" start="0" end="5" time = "20.195436" name = " (A2) " distance = "673.1812" turn = "Keep left" turn_angle = "-3.4476776" lanes = "[1, 1, 0]" start_bearing = "168.56746" end_bearing = "174.3032" description = "Keep left[1, 1, 0] and go 1875.95 meters (*)" /> <segment id="80503746" start="0" end="5" time = "20.195436" name = " (A2) " distance = "673.1812" turn = "Keep left" turn_angle = "-3.4476776" lanes = "[1, 1, 0]" start_bearing = "168.56746" end_bearing = "174.3032" description = "Keep left[1, 1, 0] and go 2945.10 meters (*)" />
<segment id="6775303" start="0" end="1" time = "2.5965672" name = " (A2) " distance = "86.55224" start_bearing = "177.13136" end_bearing = "177.13136" description = "" /> <segment id="6775303" start="0" end="1" time = "2.5965672" name = " (A2) " distance = "86.55224" start_bearing = "177.13136" end_bearing = "177.13136" description = "" />
<segment id="6773089" start="0" end="5" time = "14.480419" name = " (A2) " distance = "482.68063" start_bearing = "177.7094" end_bearing = "-171.79578" description = "" /> <segment id="6773089" start="0" end="5" time = "14.480419" name = " (A2) " distance = "482.68063" start_bearing = "177.7094" end_bearing = "-171.79578" description = "" />
<segment id="6773086" start="0" end="1" time = "0.97906727" name = " (A2) " distance = "32.635574" start_bearing = "-170.75389" end_bearing = "-170.75389" description = "" /> <segment id="6773086" start="0" end="1" time = "0.97906727" name = " (A2) " distance = "32.635574" start_bearing = "-170.75389" end_bearing = "-170.75389" description = "" />
<segment id="6777666" start="0" end="7" time = "18.026918" name = " (A2) " distance = "600.8972" start_bearing = "-169.69516" end_bearing = "-160.51387" description = "" /> <segment id="6777666" start="0" end="7" time = "18.026918" name = " (A2) " distance = "600.8972" start_bearing = "-169.69516" end_bearing = "-160.51387" description = "" />
<segment id="6777666" start="7" end="8" time = "2.2491179" name = " (A2) " distance = "74.9706" turn = "Keep left" turn_angle = "1.9710846" lanes = "[1, 1, 0]" start_bearing = "-158.54279" end_bearing = "-158.54279" description = "Keep left[1, 1, 0] and go 1069.15 meters (*)" /> <segment id="6777666" start="7" end="8" time = "2.2491179" name = " (A2) " distance = "74.9706" start_bearing = "-158.54279" end_bearing = "-158.54279" description = "" />
<segment id="163556624" start="0" end="1" time = "0.64583343" name = " (A2) " distance = "21.527779" start_bearing = "-157.61986" end_bearing = "-157.61986" description = "" /> <segment id="163556624" start="0" end="1" time = "0.64583343" name = " (A2) " distance = "21.527779" start_bearing = "-157.61986" end_bearing = "-157.61986" description = "" />
<segment id="163556988" start="0" end="5" time = "18.745827" name = " (A2) " distance = "624.86084" start_bearing = "-155.4445" end_bearing = "-149.23146" description = "" /> <segment id="163556988" start="0" end="5" time = "18.745827" name = " (A2) " distance = "624.86084" start_bearing = "-155.4445" end_bearing = "-149.23146" description = "" />
<segment id="6777681" start="0" end="1" time = "1.31523" name = " (A2) " distance = "43.841" start_bearing = "-148.86969" end_bearing = "-148.86969" description = "" /> <segment id="6777681" start="0" end="1" time = "1.31523" name = " (A2) " distance = "43.841" start_bearing = "-148.86969" end_bearing = "-148.86969" description = "" />
@ -371,20 +383,21 @@
<segment id="7125104" start="0" end="1" time = "0.87968373" name = " (A2) " distance = "21.992092" start_bearing = "-140.5722" end_bearing = "-140.5722" description = "" /> <segment id="7125104" start="0" end="1" time = "0.87968373" name = " (A2) " distance = "21.992092" start_bearing = "-140.5722" end_bearing = "-140.5722" description = "" />
<segment id="132365571" start="0" end="5" time = "26.710241" name = " (A2) " distance = "519.3658" start_bearing = "-141.59787" end_bearing = "-145.58632" description = "" /> <segment id="132365571" start="0" end="5" time = "26.710241" name = " (A2) " distance = "519.3658" start_bearing = "-141.59787" end_bearing = "-145.58632" description = "" />
<segment id="7125108" start="0" end="1" time = "3.795417" name = " (A2) " distance = "52.714127" start_bearing = "-143.29416" end_bearing = "-143.29416" description = "" /> <segment id="7125108" start="0" end="1" time = "3.795417" name = " (A2) " distance = "52.714127" start_bearing = "-143.29416" end_bearing = "-143.29416" description = "" />
<segment id="74176013" start="0" end="5" time = "48.209896" name = "Viaductweg" distance = "252.9152" turn = "Turn right" turn_angle = "82.28676" start_bearing = "-61.007404" end_bearing = "-68.404686" description = "Turn right and go 557.98 meters" /> <segment id="74176013" start="0" end="5" time = "68.20989" name = "Viaductweg" distance = "252.9152" turn = "Turn right" turn_angle = "82.28676" start_bearing = "-61.007404" end_bearing = "-68.404686" description = "Turn right and go 724.83 meters" />
<segment id="7125080" start="0" end="3" time = "22.315641" name = "Viaductweg" distance = "132.08797" start_bearing = "-69.443954" end_bearing = "-67.22757" description = "" /> <segment id="7125080" start="0" end="3" time = "32.31564" name = "Viaductweg" distance = "132.08797" start_bearing = "-69.443954" end_bearing = "-67.22757" description = "" />
<segment id="7126430" start="0" end="1" time = "1.6430479" name = "Viaductweg" distance = "29.666143" start_bearing = "-65.46227" end_bearing = "-65.46227" description = "" /> <segment id="7126430" start="0" end="1" time = "1.6430479" name = "Viaductweg" distance = "29.666143" start_bearing = "-65.46227" end_bearing = "-65.46227" description = "" />
<segment id="7126427" start="0" end="6" time = "10.318509" name = "Viaductweg" distance = "143.31262" start_bearing = "-65.64201" end_bearing = "-83.198685" description = "" /> <segment id="7126427" start="0" end="6" time = "10.318509" name = "Viaductweg" distance = "143.31262" start_bearing = "-65.64201" end_bearing = "-83.198685" description = "" />
<segment id="7126427" start="6" end="13" time = "12.012888" name = "Viaductweg" distance = "166.84567" turn = "Keep left" turn_angle = "-1.0907211" start_bearing = "-84.289406" end_bearing = "-97.0165" description = "Keep left and go 166.85 meters (*)" /> <segment id="7126427" start="6" end="13" time = "12.012888" name = "Viaductweg" distance = "166.84567" start_bearing = "-84.289406" end_bearing = "-97.0165" description = "" />
<segment id="7126424" start="0" end="1" time = "16.031185" name = "" distance = "12.889814" turn = "Turn left" turn_angle = "-91.472435" start_bearing = "171.51106" end_bearing = "171.51106" description = "Turn left and go 561.36 meters" /> <segment id="7126424" start="0" end="1" time = "26.031185" name = "" distance = "12.889814" turn = "Turn left" turn_angle = "-91.472435" start_bearing = "171.51106" end_bearing = "171.51106" description = "Turn left and go 872.82 meters" />
<segment id="102699301" start="0" end="5" time = "18.381628" name = "Franciscus Romanusweg" distance = "46.967056" start_bearing = "171.8699" end_bearing = "-159.22775" description = "" /> <segment id="102699301" start="0" end="5" time = "28.381628" name = "Franciscus Romanusweg" distance = "46.967056" start_bearing = "171.8699" end_bearing = "-159.22775" description = "" />
<segment id="144552858" start="10" end="0" time = "14.33854" name = "Franciscus Romanusweg" distance = "199.1464" start_bearing = "-123.69007" end_bearing = "-95.59934" description = "" /> <segment id="144552858" start="10" end="0" time = "14.33854" name = "Franciscus Romanusweg" distance = "199.1464" start_bearing = "-123.69007" end_bearing = "-95.59934" description = "" />
<segment id="32102945" start="7" end="0" time = "22.397062" name = "Franciscus Romanusweg" distance = "102.73698" start_bearing = "-94.76364" end_bearing = "-134.44374" description = "" /> <segment id="32102945" start="7" end="0" time = "32.39706" name = "Franciscus Romanusweg" distance = "102.73698" start_bearing = "-94.76364" end_bearing = "-134.44374" description = "" />
<segment id="7126419" start="18" end="4" time = "14.372538" name = "Franciscus Romanusweg" distance = "199.61858" start_bearing = "-135.0" end_bearing = "171.8699" description = "" /> <segment id="7126419" start="18" end="4" time = "14.372538" name = "Franciscus Romanusweg" distance = "199.61858" start_bearing = "-135.0" end_bearing = "171.8699" description = "" />
<segment id="7126419" start="4" end="0" time = "14.157407" name = "Franciscus Romanusweg" distance = "196.63066" turn = "Keep left" turn_angle = "-0.07077026" start_bearing = "171.79913" end_bearing = "171.17232" description = "Keep left and go 196.63 meters (*)" /> <segment id="7126419" start="4" end="0" time = "14.157407" name = "Franciscus Romanusweg" distance = "196.63066" start_bearing = "171.79913" end_bearing = "171.17232" description = "" />
<segment id="7126340" start="3" end="0" time = "11.169105" name = "Antonius Bieleveltstraat" distance = "108.58852" turn = "Turn left" turn_angle = "-97.285736" start_bearing = "73.88658" end_bearing = "136.25446" description = "Turn left and go 108.59 meters" /> <segment id="7126414" start="1" end="0" time = "1.3585912" name = "Franciscus Romanusweg" distance = "22.643187" start_bearing = "175.156" end_bearing = "175.156" description = "" />
<segment id="7126350" start="6" end="0" time = "11.346093" name = "Schildersplein" distance = "110.30924" turn = "Turn right" turn_angle = "90.667496" start_bearing = "-133.07805" end_bearing = "135.0" description = "Turn right and go 157.22 meters" /> <segment id="7126200" start="0" end="4" time = "6.637338" name = "Franciscus Romanusweg" distance = "92.18526" start_bearing = "178.2643" end_bearing = "-169.38034" description = "" />
<segment id="7126313" start="1" end="0" time = "4.8251657" name = "Valentijn Clotsstraat" distance = "46.91133" start_bearing = "132.89091" end_bearing = "132.89091" description = "" /> <segment id="7126312" start="0" end="4" time = "11.829202" name = "Karel de Vogelstraat" distance = "115.00613" turn = "Turn left" turn_angle = "-90.10545" start_bearing = "100.514206" end_bearing = "35.387886" description = "Turn left and go 115.01 meters" />
<segment id="7126313" start="1" end="0" time = "4.8251657" name = "Valentijn Clotsstraat" distance = "46.91133" turn = "Turn right" turn_angle = "97.50303" start_bearing = "132.89091" end_bearing = "132.89091" description = "Turn right and go 46.91 meters" />
<segment id="7126355" start="4" end="0" time = "5.2888374" name = "Gebroeders Hermansstraat" distance = "51.419254" turn = "Turn left" turn_angle = "-81.665085" start_bearing = "51.22583" end_bearing = "136.49434" description = "Turn left and go 51.42 meters" /> <segment id="7126355" start="4" end="0" time = "5.2888374" name = "Gebroeders Hermansstraat" distance = "51.419254" turn = "Turn left" turn_angle = "-81.665085" start_bearing = "51.22583" end_bearing = "136.49434" description = "Turn left and go 51.42 meters" />
<segment id="7126356" start="3" end="2" time = "0.0" name = "" distance = "0.0" turn = "Turn right" turn_angle = "81.091034" start_bearing = "-142.41463" end_bearing = "-140.19443" description = "Turn right and go 0.00 meters" /> <segment id="7126356" start="3" end="2" time = "0.0" name = "" distance = "0.0" turn = "Turn right" turn_angle = "81.091034" start_bearing = "-142.41463" end_bearing = "-140.19443" description = "Turn right and go 0.00 meters" />
</test> </test>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<router_tests> <router_tests>
<test regions="" description="Route to Antwerpen" best_percent="10" vehicle="car" <test regions="" description="Route to Antwerpen" best_percent="10" vehicle="car"
start_lat="52.29344776082418" start_lon="4.834756851196289" target_lat="51.21717320613008" target_lon="4.402492046356201" complete_time="5541.6855" loadedTiles = "438" visitedSegments = "9031" complete_distance = "155763.8" > start_lat="52.29344776082418" start_lon="4.834756851196289" target_lat="51.21717320613008" target_lon="4.402492046356201" complete_time="5953.306" loadedTiles = "3120" visitedSegments = "11834" complete_distance = "159654.98" >
<segment id="7367192" start="1" end="0" time = "1.9570006" name = "" distance = "24.462507" turn = "Go ahead" turn_angle = "0.0" start_bearing = "108.39158" end_bearing = "108.39158" description = "Go ahead and go 24.46 meters" /> <segment id="7367192" start="1" end="0" time = "1.9570006" name = "" distance = "24.462507" turn = "Go ahead" turn_angle = "0.0" start_bearing = "108.39158" end_bearing = "108.39158" description = "Go ahead and go 24.46 meters" />
<segment id="7366497" start="4" end="0" time = "8.245201" name = "Noorddammerweg" distance = "103.06502" turn = "Turn right" turn_angle = "96.414085" start_bearing = "-155.19434" end_bearing = "-129.80557" description = "Turn right and go 127.54 meters" /> <segment id="7366497" start="4" end="0" time = "8.245201" name = "Noorddammerweg" distance = "103.06502" turn = "Turn right" turn_angle = "96.414085" start_bearing = "-155.19434" end_bearing = "-129.80557" description = "Turn right and go 127.54 meters" />
<segment id="7366502" start="1" end="0" time = "2.9368546" name = "Urbanusparkstraat" distance = "24.473787" start_bearing = "-116.56505" end_bearing = "-116.56505" description = "" /> <segment id="7366502" start="1" end="0" time = "2.9368546" name = "Urbanusparkstraat" distance = "24.473787" start_bearing = "-116.56505" end_bearing = "-116.56505" description = "" />
@ -10,18 +10,25 @@
<segment id="7366534" start="1" end="0" time = "4.5096536" name = "Sint Urbanuspark" distance = "56.37067" start_bearing = "-158.61427" end_bearing = "-158.61427" description = "" /> <segment id="7366534" start="1" end="0" time = "4.5096536" name = "Sint Urbanuspark" distance = "56.37067" start_bearing = "-158.61427" end_bearing = "-158.61427" description = "" />
<segment id="7366606" start="1" end="0" time = "4.542828" name = "Sint Urbanuspark" distance = "56.785347" start_bearing = "-153.1908" end_bearing = "-153.1908" description = "" /> <segment id="7366606" start="1" end="0" time = "4.542828" name = "Sint Urbanuspark" distance = "56.785347" start_bearing = "-153.1908" end_bearing = "-153.1908" description = "" />
<segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "" /> <segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "" />
<segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 774.68 meters" /> <segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 761.63 meters" />
<segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" /> <segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" />
<segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" /> <segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" />
<segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" /> <segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" />
<segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" /> <segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" />
<segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" /> <segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" />
<segment id="7365071" start="0" end="1" time = "0.9398953" name = "Zetterij" distance = "13.054101" start_bearing = "117.97948" end_bearing = "117.97948" description = "" /> <segment id="7365070" start="0" end="1" time = "1.0716465" name = "Bovenkerkerweg (N521) " distance = "14.883979" turn = "Turn right" turn_angle = "94.95008" start_bearing = "-170.42577" end_bearing = "-170.42577" description = "Turn right and go 58.89 meters" />
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" turn = "Turn left" turn_angle = "-105.37932" start_bearing = "12.60016" end_bearing = "12.60016" description = "Turn left and go 968.58 meters" /> <segment id="7365086" start="0" end="1" time = "3.1682494" name = "Bovenkerkerweg (N521) " distance = "44.003468" start_bearing = "-172.57889" end_bearing = "-172.57889" description = "" />
<segment id="7365086" start="1" end="3" time = "30.227621" name = "Bovenkerkerweg (N521) " distance = "72.60584" turn = "Keep right" turn_angle = "1.9589691" start_bearing = "-170.61992" end_bearing = "-173.29016" description = "Keep right and go 110.76 meters" />
<segment id="7365099" start="0" end="3" time = "2.747028" name = "Bovenkerkerweg (N521) " distance = "38.15317" start_bearing = "-173.21103" end_bearing = "-177.61406" description = "" />
<segment id="7365062" start="6" end="7" time = "0.84723866" name = "Beneluxbaan" distance = "11.767203" turn = "Make uturn" turn_angle = "0.0" start_bearing = "97.0165" end_bearing = "97.0165" description = "Make uturn and go 1105.87 meters" />
<segment id="7365101" start="0" end="3" time = "2.8561046" name = "Bovenkerkerweg (N521) " distance = "39.66812" start_bearing = "10.885527" end_bearing = "11.458753" description = "" />
<segment id="7365085" start="0" end="1" time = "8.459829" name = "Bovenkerkerweg (N521) " distance = "117.49763" start_bearing = "6.4971123" end_bearing = "6.4971123" description = "" />
<segment id="7365069" start="0" end="1" time = "0.57796" name = "Bovenkerkerweg (N521) " distance = "8.027223" start_bearing = "5.3145456" end_bearing = "5.3145456" description = "" />
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" start_bearing = "12.60016" end_bearing = "12.60016" description = "" />
<segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" /> <segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" />
<segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" /> <segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" />
<segment id="7364781" start="0" end="6" time = "54.49686" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" /> <segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" />
<segment id="7364782" start="1" end="0" time = "16.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" /> <segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
<segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" /> <segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" />
<segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" /> <segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" />
<segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" /> <segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" />
@ -38,10 +45,10 @@
<segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" /> <segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" />
<segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" /> <segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" />
<segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" /> <segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" />
<segment id="58384522" start="0" end="4" time = "20.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" /> <segment id="58384522" start="0" end="4" time = "30.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" />
<segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" /> <segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" />
<segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" /> <segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" />
<segment id="49900222" start="0" end="1" time = "16.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" /> <segment id="49900222" start="0" end="1" time = "26.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" />
<segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" /> <segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" />
<segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" /> <segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" />
<segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" /> <segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" />
@ -82,26 +89,21 @@
<segment id="127580802" start="3" end="5" time = "23.851204" name = " (A2) " distance = "662.53345" turn = "Keep left" turn_angle = "-0.8713379" lanes = "[1, 1, 1, 1, 1, 0]" start_bearing = "156.3491" end_bearing = "157.03491" description = "Keep left[1, 1, 1, 1, 1, 0] and go 3086.16 meters (*)" /> <segment id="127580802" start="3" end="5" time = "23.851204" name = " (A2) " distance = "662.53345" turn = "Keep left" turn_angle = "-0.8713379" lanes = "[1, 1, 1, 1, 1, 0]" start_bearing = "156.3491" end_bearing = "157.03491" description = "Keep left[1, 1, 1, 1, 1, 0] and go 3086.16 meters (*)" />
<segment id="76140687" start="0" end="1" time = "1.273901" name = " (A2) " distance = "35.38614" start_bearing = "157.15196" end_bearing = "157.15196" description = "" /> <segment id="76140687" start="0" end="1" time = "1.273901" name = " (A2) " distance = "35.38614" start_bearing = "157.15196" end_bearing = "157.15196" description = "" />
<segment id="76140684" start="0" end="12" time = "85.97655" name = " (A2) " distance = "2388.2375" start_bearing = "158.17053" end_bearing = "133.95096" description = "" /> <segment id="76140684" start="0" end="12" time = "85.97655" name = " (A2) " distance = "2388.2375" start_bearing = "158.17053" end_bearing = "133.95096" description = "" />
<segment id="7063640" start="0" end="4" time = "22.955816" name = " (A2) " distance = "637.66156" turn = "Keep right" turn_angle = "5.8865967" lanes = "[0, 0, 0, 0, 1, 1]" start_bearing = "139.83755" end_bearing = "133.75592" description = "Keep right[0, 0, 0, 0, 1, 1] and go 637.66 meters" /> <segment id="79262900" start="0" end="8" time = "33.028996" name = " (A2) " distance = "917.4721" turn = "Keep left" turn_angle = "-1.6629486" lanes = "[1, 1, 1, 1, 0, 0]" start_bearing = "132.28801" end_bearing = "124.28688" description = "Keep left[1, 1, 1, 1, 0, 0] and go 6977.00 meters" />
<segment id="80749050" start="0" end="8" time = "29.595013" name = " (A2) " distance = "822.08374" turn = "Keep left" turn_angle = "-6.2392197" lanes = "[1, 0, 0]" start_bearing = "127.5167" end_bearing = "124.00188" description = "Keep left[1, 0, 0] and go 1675.15 meters (*)" /> <segment id="79262901" start="0" end="11" time = "83.45524" name = " (A2) " distance = "2318.2012" start_bearing = "123.34157" end_bearing = "138.1617" description = "" />
<segment id="80749051" start="0" end="1" time = "5.690788" name = " (A2) " distance = "158.07745" start_bearing = "123.72714" end_bearing = "123.72714" description = "" /> <segment id="7061299" start="0" end="4" time = "12.982101" name = " (A2) " distance = "360.61395" start_bearing = "137.78456" end_bearing = "139.08562" description = "" />
<segment id="114712634" start="0" end="5" time = "25.019554" name = " (A2) " distance = "694.9876" start_bearing = "123.795296" end_bearing = "122.66091" description = "" /> <segment id="151258641" start="0" end="6" time = "22.246897" name = " (A2) " distance = "617.96936" start_bearing = "143.19708" end_bearing = "150.50703" description = "" />
<segment id="80749052" start="0" end="7" time = "27.790503" name = " (A2) " distance = "771.95844" turn = "Keep left" turn_angle = "1.7918243" start_bearing = "124.452736" end_bearing = "135.1993" description = "Keep left and go 3777.28 meters (*)" /> <segment id="80761370" start="0" end="9" time = "58.68163" name = "Leidsche Rijntunnel (A2) " distance = "1630.0453" start_bearing = "153.77612" end_bearing = "172.87498" description = "" />
<segment id="99998240" start="0" end="10" time = "39.82047" name = " (A2) " distance = "1106.1241" start_bearing = "137.54857" end_bearing = "150.25511" description = "" /> <segment id="80761383" start="0" end="2" time = "11.184597" name = " (A2) " distance = "310.68326" start_bearing = "174.99852" end_bearing = "179.38173" description = "" />
<segment id="32512734" start="0" end="9" time = "59.071857" name = "Leidsche Rijntunnel (A2) " distance = "1640.885" start_bearing = "153.49524" end_bearing = "174.09386" description = "" /> <segment id="80761369" start="0" end="1" time = "1.9537628" name = " (A2) " distance = "54.27119" start_bearing = "-178.45705" end_bearing = "-178.45705" description = "" />
<segment id="51795374" start="0" end="2" time = "9.2991705" name = " (A2) " distance = "258.3103" start_bearing = "176.55423" end_bearing = "179.28766" description = "" /> <segment id="80761365" start="0" end="6" time = "11.0511" name = " (A2) " distance = "306.975" start_bearing = "-176.12459" end_bearing = "-171.34746" description = "" />
<segment id="51795374" start="2" end="3" time = "1.7690709" name = " (A2) " distance = "49.14086" turn = "Keep left" turn_angle = "-0.5798187" lanes = "[1, 1, 0, 0]" start_bearing = "178.70784" end_bearing = "178.70784" description = "Keep left[1, 1, 0, 0] and go 1041.26 meters (*)" /> <segment id="152126643" start="0" end="2" time = "16.587639" name = " (A2) " distance = "460.76776" start_bearing = "-168.47627" end_bearing = "-165.6754" description = "" />
<segment id="51763743" start="0" end="1" time = "1.9273798" name = " (A2) " distance = "53.53833" start_bearing = "-178.62674" end_bearing = "-178.62674" description = "" /> <segment id="93810171" start="0" end="1" time = "8.644352" name = " (A2) " distance = "240.1209" turn = "Keep left" turn_angle = "-1.1266632" lanes = "[1, 1, 0, 0]" start_bearing = "-166.80206" end_bearing = "-166.80206" description = "Keep left[1, 1, 0, 0] and go 4539.38 meters" />
<segment id="51764573" start="0" end="6" time = "12.954628" name = " (A2) " distance = "359.8508" start_bearing = "-175.96658" end_bearing = "-171.84186" description = "" /> <segment id="7054468" start="0" end="2" time = "29.638718" name = " (A2) " distance = "823.2977" start_bearing = "-167.47635" end_bearing = "-165.95709" description = "" />
<segment id="114712628" start="0" end="2" time = "7.6056266" name = " (A2) " distance = "211.26741" start_bearing = "-170.33298" end_bearing = "-165.04005" description = "" /> <segment id="7054457" start="0" end="1" time = "3.6500416" name = " (A2) " distance = "101.390045" start_bearing = "-166.36688" end_bearing = "-166.36688" description = "" />
<segment id="45356321" start="0" end="1" time = "13.2288" name = " (A2) " distance = "367.46667" start_bearing = "-164.98569" end_bearing = "-164.98569" description = "" /> <segment id="7054352" start="0" end="3" time = "24.02921" name = " (A2) " distance = "667.478" start_bearing = "-165.3489" end_bearing = "-165.1765" description = "" />
<segment id="93810170" start="0" end="18" time = "32.24873" name = " (A2) " distance = "895.7981" turn = "Keep right" turn_angle = "1.6514435" lanes = "[0, 0, 1]" start_bearing = "-163.33424" end_bearing = "-165.01373" description = "Keep right[0, 0, 1] and go 4389.06 meters (*)" /> <segment id="78380419" start="0" end="1" time = "1.7932974" name = " (A2) " distance = "49.81382" start_bearing = "-165.75967" end_bearing = "-165.75967" description = "" />
<segment id="7054459" start="0" end="1" time = "0.5385003" name = " (A2) " distance = "14.958343" start_bearing = "-165.11374" end_bearing = "-165.11374" description = "" /> <segment id="78380416" start="0" end="1" time = "6.098158" name = " (A2) " distance = "169.39328" start_bearing = "-164.95683" end_bearing = "-164.95683" description = "" />
<segment id="7054436" start="0" end="1" time = "3.7654755" name = " (A2) " distance = "104.59655" start_bearing = "-165.37912" end_bearing = "-165.37912" description = "" />
<segment id="7065542" start="0" end="2" time = "16.98387" name = " (A2) " distance = "471.77417" start_bearing = "-166.1587" end_bearing = "-165.21095" description = "" />
<segment id="7065536" start="0" end="1" time = "7.173017" name = " (A2) " distance = "199.25047" start_bearing = "-166.11705" end_bearing = "-166.11705" description = "" />
<segment id="78380417" start="0" end="1" time = "1.6784111" name = " (A2) " distance = "46.62253" start_bearing = "-167.54431" end_bearing = "-167.54431" description = "" />
<segment id="78380413" start="0" end="1" time = "6.054087" name = " (A2) " distance = "168.1691" start_bearing = "-168.89789" end_bearing = "-168.89789" description = "" />
<segment id="7064773" start="0" end="10" time = "66.43809" name = " (A2) " distance = "1845.5026" start_bearing = "-165.6186" end_bearing = "-178.60915" description = "" /> <segment id="7064773" start="0" end="10" time = "66.43809" name = " (A2) " distance = "1845.5026" start_bearing = "-165.6186" end_bearing = "-178.60915" description = "" />
<segment id="48836778" start="0" end="1" time = "1.2691222" name = " (A2) " distance = "35.2534" start_bearing = "-177.61406" end_bearing = "-177.61406" description = "" /> <segment id="48836778" start="0" end="1" time = "1.2691222" name = " (A2) " distance = "35.2534" start_bearing = "-177.61406" end_bearing = "-177.61406" description = "" />
<segment id="48836779" start="0" end="3" time = "21.856815" name = " (A2) " distance = "607.1338" start_bearing = "-179.3338" end_bearing = "-178.12825" description = "" /> <segment id="48836779" start="0" end="3" time = "21.856815" name = " (A2) " distance = "607.1338" start_bearing = "-179.3338" end_bearing = "-178.12825" description = "" />
@ -146,15 +148,15 @@
<segment id="7105838" start="0" end="4" time = "12.845104" name = " (A27) " distance = "428.17014" start_bearing = "-147.84592" end_bearing = "-151.59348" description = "" /> <segment id="7105838" start="0" end="4" time = "12.845104" name = " (A27) " distance = "428.17014" start_bearing = "-147.84592" end_bearing = "-151.59348" description = "" />
<segment id="7105835" start="0" end="1" time = "1.1449802" name = " (A27) " distance = "38.166004" start_bearing = "-152.30673" end_bearing = "-152.30673" description = "" /> <segment id="7105835" start="0" end="1" time = "1.1449802" name = " (A27) " distance = "38.166004" start_bearing = "-152.30673" end_bearing = "-152.30673" description = "" />
<segment id="7105842" start="0" end="11" time = "107.7067" name = " (A27) " distance = "3590.2234" start_bearing = "-155.1287" end_bearing = "-166.30568" description = "" /> <segment id="7105842" start="0" end="11" time = "107.7067" name = " (A27) " distance = "3590.2234" start_bearing = "-155.1287" end_bearing = "-166.30568" description = "" />
<segment id="7109387" start="0" end="1" time = "9.073263" name = " (A27) " distance = "302.44208" turn = "Keep left" turn_angle = "0.164505" lanes = "[1, 1, 0]" start_bearing = "-166.14117" end_bearing = "-166.14117" description = "Keep left[1, 1, 0] and go 3105.36 meters (*)" /> <segment id="7109387" start="0" end="1" time = "9.073263" name = " (A27) " distance = "302.44208" turn = "Keep left" turn_angle = "0.164505" lanes = "[1, 1, 0]" start_bearing = "-166.14117" end_bearing = "-166.14117" description = "Keep left[1, 1, 0] and go 5594.20 meters (*)" />
<segment id="7109392" start="0" end="1" time = "2.1320362" name = " (A27) " distance = "71.06787" start_bearing = "-166.68306" end_bearing = "-166.68306" description = "" /> <segment id="7109392" start="0" end="1" time = "2.1320362" name = " (A27) " distance = "71.06787" start_bearing = "-166.68306" end_bearing = "-166.68306" description = "" />
<segment id="7109396" start="0" end="1" time = "9.105985" name = " (A27) " distance = "303.5328" start_bearing = "-166.04816" end_bearing = "-166.04816" description = "" /> <segment id="7109396" start="0" end="1" time = "9.105985" name = " (A27) " distance = "303.5328" start_bearing = "-166.04816" end_bearing = "-166.04816" description = "" />
<segment id="7109400" start="0" end="6" time = "30.953196" name = " (A27) " distance = "1031.7732" start_bearing = "-167.03697" end_bearing = "-158.87846" description = "" /> <segment id="7109400" start="0" end="6" time = "30.953196" name = " (A27) " distance = "1031.7732" start_bearing = "-167.03697" end_bearing = "-158.87846" description = "" />
<segment id="7109402" start="0" end="1" time = "2.1459546" name = " (A27) " distance = "71.53182" start_bearing = "-159.66669" end_bearing = "-159.66669" description = "" /> <segment id="7109402" start="0" end="1" time = "2.1459546" name = " (A27) " distance = "71.53182" start_bearing = "-159.66669" end_bearing = "-159.66669" description = "" />
<segment id="7109403" start="0" end="2" time = "39.75041" name = " (A27) " distance = "1325.0135" start_bearing = "-158.95221" end_bearing = "-159.1193" description = "" /> <segment id="7109403" start="0" end="2" time = "39.75041" name = " (A27) " distance = "1325.0135" start_bearing = "-158.95221" end_bearing = "-159.1193" description = "" />
<segment id="7109403" start="2" end="7" time = "69.964554" name = " (A27) " distance = "2332.1519" turn = "Keep left" turn_angle = "-0.13427734" lanes = "[1, 1, 0]" start_bearing = "-159.25357" end_bearing = "-163.85815" description = "Keep left[1, 1, 0] and go 2488.84 meters (*)" /> <segment id="7109403" start="2" end="7" time = "69.964554" name = " (A27) " distance = "2332.1519" start_bearing = "-159.25357" end_bearing = "-163.85815" description = "" />
<segment id="28196316" start="0" end="1" time = "5.6407747" name = " (A27) " distance = "156.6882" start_bearing = "-163.61809" end_bearing = "-163.61809" description = "" /> <segment id="28196316" start="0" end="1" time = "5.6407747" name = " (A27) " distance = "156.6882" start_bearing = "-163.61809" end_bearing = "-163.61809" description = "" />
<segment id="10196765" start="0" end="1" time = "22.247164" name = " (A27) " distance = "617.9768" turn = "Keep left" turn_angle = "-0.49978638" lanes = "[1, 1, 0, 0]" start_bearing = "-164.11787" end_bearing = "-164.11787" description = "Keep left[1, 1, 0, 0] and go 2155.25 meters (*)" /> <segment id="10196765" start="0" end="1" time = "22.247164" name = " (A27) " distance = "617.9768" turn = "Keep left" turn_angle = "-0.49978638" lanes = "[1, 1, 0, 0]" start_bearing = "-164.11787" end_bearing = "-164.11787" description = "Keep left[1, 1, 0, 0] and go 2155.25 meters" />
<segment id="43545572" start="0" end="1" time = "1.1079632" name = " (A27) " distance = "30.776758" start_bearing = "-163.86441" end_bearing = "-163.86441" description = "" /> <segment id="43545572" start="0" end="1" time = "1.1079632" name = " (A27) " distance = "30.776758" start_bearing = "-163.86441" end_bearing = "-163.86441" description = "" />
<segment id="43545571" start="0" end="1" time = "6.129849" name = " (A27) " distance = "170.27359" start_bearing = "-164.27641" end_bearing = "-164.27641" description = "" /> <segment id="43545571" start="0" end="1" time = "6.129849" name = " (A27) " distance = "170.27359" start_bearing = "-164.27641" end_bearing = "-164.27641" description = "" />
<segment id="7111062" start="0" end="1" time = "3.681373" name = " (A27) " distance = "102.26036" start_bearing = "-164.53667" end_bearing = "-164.53667" description = "" /> <segment id="7111062" start="0" end="1" time = "3.681373" name = " (A27) " distance = "102.26036" start_bearing = "-164.53667" end_bearing = "-164.53667" description = "" />
@ -173,10 +175,10 @@
<segment id="85076242" start="0" end="1" time = "1.6107373" name = " (A27) " distance = "53.691242" start_bearing = "-167.06454" end_bearing = "-167.06454" description = "" /> <segment id="85076242" start="0" end="1" time = "1.6107373" name = " (A27) " distance = "53.691242" start_bearing = "-167.06454" end_bearing = "-167.06454" description = "" />
<segment id="7118606" start="0" end="2" time = "5.0012426" name = " (A27) " distance = "166.70808" turn = "Keep left" turn_angle = "-1.3887634" lanes = "[1, 1, 0]" start_bearing = "-168.45331" end_bearing = "-170.20853" description = "Keep left[1, 1, 0] and go 2906.29 meters (*)" /> <segment id="7118606" start="0" end="2" time = "5.0012426" name = " (A27) " distance = "166.70808" turn = "Keep left" turn_angle = "-1.3887634" lanes = "[1, 1, 0]" start_bearing = "-168.45331" end_bearing = "-170.20853" description = "Keep left[1, 1, 0] and go 2906.29 meters (*)" />
<segment id="7118631" start="0" end="5" time = "82.18753" name = " (A27) " distance = "2739.5842" start_bearing = "-173.15642" end_bearing = "178.0464" description = "" /> <segment id="7118631" start="0" end="5" time = "82.18753" name = " (A27) " distance = "2739.5842" start_bearing = "-173.15642" end_bearing = "178.0464" description = "" />
<segment id="7118631" start="5" end="17" time = "67.97151" name = " (A27) " distance = "2265.7168" turn = "Keep left" turn_angle = "-0.51820374" lanes = "[1, 1, 0]" start_bearing = "177.5282" end_bearing = "-163.64418" description = "Keep left[1, 1, 0] and go 3546.68 meters (*)" /> <segment id="7118631" start="5" end="17" time = "67.97151" name = " (A27) " distance = "2265.7168" turn = "Keep left" turn_angle = "-0.51820374" lanes = "[1, 1, 0]" start_bearing = "177.5282" end_bearing = "-163.64418" description = "Keep left[1, 1, 0] and go 4487.76 meters (*)" />
<segment id="7118867" start="0" end="1" time = "3.947046" name = " (A27) " distance = "131.5682" start_bearing = "-163.6786" end_bearing = "-163.6786" description = "" /> <segment id="7118867" start="0" end="1" time = "3.947046" name = " (A27) " distance = "131.5682" start_bearing = "-163.6786" end_bearing = "-163.6786" description = "" />
<segment id="7118635" start="0" end="8" time = "34.481792" name = " (A27) " distance = "1149.3931" start_bearing = "-163.27983" end_bearing = "-152.46683" description = "" /> <segment id="7118635" start="0" end="8" time = "34.481792" name = " (A27) " distance = "1149.3931" start_bearing = "-163.27983" end_bearing = "-152.46683" description = "" />
<segment id="7118635" start="8" end="14" time = "28.23234" name = " (A27) " distance = "941.07794" turn = "Keep left" turn_angle = "1.8730164" lanes = "[1, 1, 0]" start_bearing = "-150.59381" end_bearing = "-143.1301" description = "Keep left[1, 1, 0] and go 941.08 meters (*)" /> <segment id="7118635" start="8" end="14" time = "28.23234" name = " (A27) " distance = "941.07794" start_bearing = "-150.59381" end_bearing = "-143.1301" description = "" />
<segment id="7269367" start="0" end="5" time = "11.039033" name = " (A27) " distance = "367.96774" turn = "Keep left" turn_angle = "1.8817291" lanes = "[1, 1, 0]" start_bearing = "-141.24837" end_bearing = "-134.22127" description = "Keep left[1, 1, 0] and go 3099.88 meters (*)" /> <segment id="7269367" start="0" end="5" time = "11.039033" name = " (A27) " distance = "367.96774" turn = "Keep left" turn_angle = "1.8817291" lanes = "[1, 1, 0]" start_bearing = "-141.24837" end_bearing = "-134.22127" description = "Keep left[1, 1, 0] and go 3099.88 meters (*)" />
<segment id="7269370" start="0" end="1" time = "1.28553" name = " (A27) " distance = "42.850998" start_bearing = "-132.92996" end_bearing = "-132.92996" description = "" /> <segment id="7269370" start="0" end="1" time = "1.28553" name = " (A27) " distance = "42.850998" start_bearing = "-132.92996" end_bearing = "-132.92996" description = "" />
<segment id="7269381" start="0" end="1" time = "13.34158" name = " (A27) " distance = "444.71933" start_bearing = "-132.06519" end_bearing = "-132.06519" description = "" /> <segment id="7269381" start="0" end="1" time = "13.34158" name = " (A27) " distance = "444.71933" start_bearing = "-132.06519" end_bearing = "-132.06519" description = "" />
@ -200,11 +202,11 @@
<segment id="7263539" start="0" end="1" time = "13.529672" name = " (A27) " distance = "450.989" turn = "Keep left" turn_angle = "0.5317688" lanes = "[1, 1, 0]" start_bearing = "-144.64249" end_bearing = "-144.64249" description = "Keep left[1, 1, 0] and go 573.67 meters (*)" /> <segment id="7263539" start="0" end="1" time = "13.529672" name = " (A27) " distance = "450.989" turn = "Keep left" turn_angle = "0.5317688" lanes = "[1, 1, 0]" start_bearing = "-144.64249" end_bearing = "-144.64249" description = "Keep left[1, 1, 0] and go 573.67 meters (*)" />
<segment id="7263540" start="0" end="1" time = "2.1952474" name = " (A27) " distance = "73.17491" start_bearing = "-144.76836" end_bearing = "-144.76836" description = "" /> <segment id="7263540" start="0" end="1" time = "2.1952474" name = " (A27) " distance = "73.17491" start_bearing = "-144.76836" end_bearing = "-144.76836" description = "" />
<segment id="7263534" start="0" end="1" time = "1.48518" name = " (A27) " distance = "49.505997" start_bearing = "-145.16777" end_bearing = "-145.16777" description = "" /> <segment id="7263534" start="0" end="1" time = "1.48518" name = " (A27) " distance = "49.505997" start_bearing = "-145.16777" end_bearing = "-145.16777" description = "" />
<segment id="7263551" start="0" end="1" time = "8.081274" name = " (A27) " distance = "269.3758" turn = "Keep left" turn_angle = "0.65522766" lanes = "[1, 1, 0]" start_bearing = "-144.51254" end_bearing = "-144.51254" description = "Keep left[1, 1, 0] and go 3445.65 meters (*)" /> <segment id="7263551" start="0" end="1" time = "8.081274" name = " (A27) " distance = "269.3758" turn = "Keep left" turn_angle = "0.65522766" lanes = "[1, 1, 0]" start_bearing = "-144.51254" end_bearing = "-144.51254" description = "Keep left[1, 1, 0] and go 4618.85 meters (*)" />
<segment id="7263543" start="0" end="1" time = "1.4930464" name = " (A27) " distance = "49.76821" start_bearing = "-144.33705" end_bearing = "-144.33705" description = "" /> <segment id="7263543" start="0" end="1" time = "1.4930464" name = " (A27) " distance = "49.76821" start_bearing = "-144.33705" end_bearing = "-144.33705" description = "" />
<segment id="7263541" start="0" end="2" time = "11.839014" name = " (A27) " distance = "394.6338" start_bearing = "-145.24902" end_bearing = "-145.88075" description = "" /> <segment id="7263541" start="0" end="2" time = "11.839014" name = " (A27) " distance = "394.6338" start_bearing = "-145.24902" end_bearing = "-145.88075" description = "" />
<segment id="7263262" start="0" end="11" time = "81.95613" name = " (A27) " distance = "2731.8708" start_bearing = "-147.21733" end_bearing = "-132.22498" description = "" /> <segment id="7263262" start="0" end="11" time = "81.95613" name = " (A27) " distance = "2731.8708" start_bearing = "-147.21733" end_bearing = "-132.22498" description = "" />
<segment id="7263262" start="11" end="18" time = "29.815554" name = " (A27) " distance = "993.85175" turn = "Keep left" turn_angle = "0.36386108" lanes = "[1, 1, 0]" start_bearing = "-131.86111" end_bearing = "-143.02669" description = "Keep left[1, 1, 0] and go 1173.20 meters (*)" /> <segment id="7263262" start="11" end="18" time = "29.815554" name = " (A27) " distance = "993.85175" start_bearing = "-131.86111" end_bearing = "-143.02669" description = "" />
<segment id="7219085" start="0" end="1" time = "2.0454745" name = " (A27) " distance = "68.18248" start_bearing = "-143.31764" end_bearing = "-143.31764" description = "" /> <segment id="7219085" start="0" end="1" time = "2.0454745" name = " (A27) " distance = "68.18248" start_bearing = "-143.31764" end_bearing = "-143.31764" description = "" />
<segment id="7219039" start="0" end="1" time = "3.334863" name = " (A27) " distance = "111.162094" start_bearing = "-142.7682" end_bearing = "-142.7682" description = "" /> <segment id="7219039" start="0" end="1" time = "3.334863" name = " (A27) " distance = "111.162094" start_bearing = "-142.7682" end_bearing = "-142.7682" description = "" />
<segment id="7219034" start="0" end="2" time = "12.746751" name = " (A27) " distance = "424.89166" turn = "Keep left" turn_angle = "-0.589859" lanes = "[1, 1, 0]" start_bearing = "-143.35806" end_bearing = "-145.30484" description = "Keep left[1, 1, 0] and go 1365.41 meters (*)" /> <segment id="7219034" start="0" end="2" time = "12.746751" name = " (A27) " distance = "424.89166" turn = "Keep left" turn_angle = "-0.589859" lanes = "[1, 1, 0]" start_bearing = "-143.35806" end_bearing = "-145.30484" description = "Keep left[1, 1, 0] and go 1365.41 meters (*)" />
@ -219,7 +221,7 @@
<segment id="7220805" start="6" end="10" time = "51.539986" name = " (A58) " distance = "1717.9994" turn = "Keep left" turn_angle = "2.5764084" lanes = "[1, 1, 0]" start_bearing = "-122.23798" end_bearing = "-117.04074" description = "Keep left[1, 1, 0] and go 3497.83 meters (*)" /> <segment id="7220805" start="6" end="10" time = "51.539986" name = " (A58) " distance = "1717.9994" turn = "Keep left" turn_angle = "2.5764084" lanes = "[1, 1, 0]" start_bearing = "-122.23798" end_bearing = "-117.04074" description = "Keep left[1, 1, 0] and go 3497.83 meters (*)" />
<segment id="7221420" start="0" end="1" time = "1.9121938" name = " (A58) " distance = "63.73979" start_bearing = "-117.30431" end_bearing = "-117.30431" description = "" /> <segment id="7221420" start="0" end="1" time = "1.9121938" name = " (A58) " distance = "63.73979" start_bearing = "-117.30431" end_bearing = "-117.30431" description = "" />
<segment id="7221419" start="0" end="19" time = "51.48283" name = " (A58) " distance = "1716.0944" start_bearing = "-115.9752" end_bearing = "-88.17446" description = "" /> <segment id="7221419" start="0" end="19" time = "51.48283" name = " (A58) " distance = "1716.0944" start_bearing = "-115.9752" end_bearing = "-88.17446" description = "" />
<segment id="56501888" start="0" end="1" time = "3.3406813" name = " (A16) " distance = "111.35604" turn = "Keep left" turn_angle = "-0.870697" lanes = "[1, 0, 0]" start_bearing = "-89.04516" end_bearing = "-89.04516" description = "Keep left[1, 0, 0] and go 3625.03 meters" /> <segment id="56501888" start="0" end="1" time = "3.3406813" name = " (A16) " distance = "111.35604" turn = "Keep left" turn_angle = "-0.870697" lanes = "[1, 0, 0]" start_bearing = "-89.04516" end_bearing = "-89.04516" description = "Keep left[1, 0, 0] and go 4532.32 meters" />
<segment id="7230700" start="0" end="2" time = "15.107924" name = " (A16) " distance = "503.59747" start_bearing = "-87.86395" end_bearing = "-87.70623" description = "" /> <segment id="7230700" start="0" end="2" time = "15.107924" name = " (A16) " distance = "503.59747" start_bearing = "-87.86395" end_bearing = "-87.70623" description = "" />
<segment id="7230677" start="0" end="1" time = "1.2922341" name = " (A16) " distance = "43.074467" start_bearing = "-87.55295" end_bearing = "-87.55295" description = "" /> <segment id="7230677" start="0" end="1" time = "1.2922341" name = " (A16) " distance = "43.074467" start_bearing = "-87.55295" end_bearing = "-87.55295" description = "" />
<segment id="7230685" start="0" end="1" time = "1.2477278" name = " (A16) " distance = "41.590923" start_bearing = "-87.97268" end_bearing = "-87.97268" description = "" /> <segment id="7230685" start="0" end="1" time = "1.2477278" name = " (A16) " distance = "41.590923" start_bearing = "-87.97268" end_bearing = "-87.97268" description = "" />
@ -228,7 +230,7 @@
<segment id="92292395" start="0" end="2" time = "0.8898133" name = " (A16) " distance = "29.660442" start_bearing = "119.577835" end_bearing = "123.27489" description = "" /> <segment id="92292395" start="0" end="2" time = "0.8898133" name = " (A16) " distance = "29.660442" start_bearing = "119.577835" end_bearing = "123.27489" description = "" />
<segment id="92292384" start="0" end="4" time = "3.73704" name = " (A16) " distance = "124.568" start_bearing = "138.65222" end_bearing = "158.76529" description = "" /> <segment id="92292384" start="0" end="4" time = "3.73704" name = " (A16) " distance = "124.568" start_bearing = "138.65222" end_bearing = "158.76529" description = "" />
<segment id="7230924" start="1" end="10" time = "72.10512" name = " (A16) " distance = "2403.504" start_bearing = "169.56697" end_bearing = "-174.40125" description = "" /> <segment id="7230924" start="1" end="10" time = "72.10512" name = " (A16) " distance = "2403.504" start_bearing = "169.56697" end_bearing = "-174.40125" description = "" />
<segment id="7230924" start="10" end="14" time = "27.218878" name = " (A16) " distance = "907.2959" turn = "Keep left" turn_angle = "0.2219696" lanes = "[1, 1, 0]" start_bearing = "-174.17928" end_bearing = "-166.34499" description = "Keep left[1, 1, 0] and go 907.30 meters (*)" /> <segment id="7230924" start="10" end="14" time = "27.218878" name = " (A16) " distance = "907.2959" start_bearing = "-174.17928" end_bearing = "-166.34499" description = "" />
<segment id="7230924" start="14" end="19" time = "40.624348" name = " (A16) " distance = "1354.1449" turn = "Keep left" turn_angle = "2.1087189" lanes = "[1, 1, 0]" start_bearing = "-164.23627" end_bearing = "-160.95901" description = "Keep left[1, 1, 0] and go 4952.99 meters (*)" /> <segment id="7230924" start="14" end="19" time = "40.624348" name = " (A16) " distance = "1354.1449" turn = "Keep left" turn_angle = "2.1087189" lanes = "[1, 1, 0]" start_bearing = "-164.23627" end_bearing = "-160.95901" description = "Keep left[1, 1, 0] and go 4952.99 meters (*)" />
<segment id="5094229" start="0" end="10" time = "107.96547" name = " (E19) " distance = "3598.8489" start_bearing = "-160.84958" end_bearing = "-166.38635" description = "" /> <segment id="5094229" start="0" end="10" time = "107.96547" name = " (E19) " distance = "3598.8489" start_bearing = "-160.84958" end_bearing = "-166.38635" description = "" />
<segment id="5094229" start="10" end="18" time = "95.98541" name = " (E19) " distance = "3199.5134" turn = "Keep left" turn_angle = "-0.7148895" lanes = "[1, 1, 0]" start_bearing = "-167.10124" end_bearing = "-163.62823" description = "Keep left[1, 1, 0] and go 3199.51 meters (*)" /> <segment id="5094229" start="10" end="18" time = "95.98541" name = " (E19) " distance = "3199.5134" turn = "Keep left" turn_angle = "-0.7148895" lanes = "[1, 1, 0]" start_bearing = "-167.10124" end_bearing = "-163.62823" description = "Keep left[1, 1, 0] and go 3199.51 meters (*)" />
@ -247,59 +249,53 @@
<segment id="146511986" start="0" end="12" time = "40.64995" name = " (E19) " distance = "1354.9982" start_bearing = "-96.938385" end_bearing = "-115.788925" description = "" /> <segment id="146511986" start="0" end="12" time = "40.64995" name = " (E19) " distance = "1354.9982" start_bearing = "-96.938385" end_bearing = "-115.788925" description = "" />
<segment id="146511986" start="12" end="66" time = "42.2464" name = " (E19) " distance = "1408.2133" turn = "Keep left" turn_angle = "-0.77612305" start_bearing = "-116.56505" end_bearing = "-146.92932" description = "Keep left and go 2377.37 meters (*)" /> <segment id="146511986" start="12" end="66" time = "42.2464" name = " (E19) " distance = "1408.2133" turn = "Keep left" turn_angle = "-0.77612305" start_bearing = "-116.56505" end_bearing = "-146.92932" description = "Keep left and go 2377.37 meters (*)" />
<segment id="4322956" start="0" end="10" time = "29.07467" name = " (R1) " distance = "969.15564" start_bearing = "-158.4047" end_bearing = "-179.59422" description = "" /> <segment id="4322956" start="0" end="10" time = "29.07467" name = " (R1) " distance = "969.15564" start_bearing = "-158.4047" end_bearing = "-179.59422" description = "" />
<segment id="4322894" start="0" end="4" time = "15.602006" name = "" distance = "346.71124" turn = "Keep right" turn_angle = "5.7493896" start_bearing = "-173.84483" end_bearing = "180.0" description = "Keep right and go 346.71 meters" /> <segment id="48525690" start="0" end="2" time = "11.406443" name = " (R1) " distance = "380.21475" turn = "Keep left" turn_angle = "-1.7390594" start_bearing = "178.66672" end_bearing = "178.84267" description = "Keep left and go 3762.28 meters (*)" />
<segment id="4322895" start="0" end="2" time = "3.3338234" name = "" distance = "74.08497" turn = "Keep right" turn_angle = "15.811371" start_bearing = "-164.18863" end_bearing = "-143.55556" description = "Keep right and go 74.08 meters" /> <segment id="4322890" start="0" end="1" time = "3.0917888" name = " (R1) " distance = "103.05962" start_bearing = "-180.0" end_bearing = "180.0" description = "" />
<segment id="8052353" start="0" end="1" time = "6.27333" name = "Groenendaallaan (N129) " distance = "104.555504" turn = "Turn slightly right" turn_angle = "54.170517" start_bearing = "-89.38504" end_bearing = "-89.38504" description = "Turn slightly right and go 312.18 meters" /> <segment id="4322864" start="0" end="3" time = "15.195565" name = " (R1) " distance = "506.5188" start_bearing = "179.7205" end_bearing = "176.42366" description = "" />
<segment id="23386081" start="0" end="3" time = "29.949045" name = "Groenendaallaan (N129) " distance = "207.62564" start_bearing = "-91.04479" end_bearing = "-90.47351" description = "" /> <segment id="4322584" start="0" end="18" time = "62.07714" name = " (R1) " distance = "1724.3651" start_bearing = "173.4802" end_bearing = "137.81555" description = "" />
<segment id="23385761" start="0" end="1" time = "2.3713744" name = "Groenendaallaan (N129) " distance = "32.935757" turn = "Keep left" turn_angle = "4.8982925" start_bearing = "-85.57522" end_bearing = "-85.57522" description = "Keep left and go 128.72 meters" /> <segment id="4322569" start="0" end="11" time = "37.73253" name = " (R1) " distance = "1048.1259" start_bearing = "136.1935" end_bearing = "167.69199" description = "" />
<segment id="23385640" start="0" end="1" time = "17.049618" name = "Groenendaallaan" distance = "28.466919" start_bearing = "-86.28471" end_bearing = "-86.28471" description = "" /> <segment id="4322548" start="0" end="9" time = "37.797874" name = " (R1) " distance = "1049.941" turn = "Keep left" turn_angle = "4.876602" start_bearing = "172.56859" end_bearing = "-148.27234" description = "Keep left and go 1049.94 meters (*)" />
<segment id="12985644" start="0" end="2" time = "17.797262" name = "Groenendaallaan (N101) " distance = "38.85086" start_bearing = "-91.33222" end_bearing = "-90.45114" description = "" /> <segment id="4312411" start="0" end="4" time = "12.700957" name = "" distance = "282.2435" turn = "Keep right" turn_angle = "8.655991" start_bearing = "-139.61635" end_bearing = "-135.0" description = "Keep right and go 466.72 meters" />
<segment id="23385755" start="0" end="1" time = "2.0496185" name = "Groenendaallaan (N101) " distance = "28.466923" start_bearing = "-94.604485" end_bearing = "-94.604485" description = "" /> <segment id="4312416" start="0" end="1" time = "3.1672919" name = "" distance = "70.38426" start_bearing = "-131.5834" end_bearing = "-131.5834" description = "" />
<segment id="23385755" start="1" end="4" time = "24.253155" name = "Groenendaallaan (N101) " distance = "128.51604" turn = "Keep left" turn_angle = "3.736435" start_bearing = "-90.86805" end_bearing = "-92.97373" description = "Keep left and go 315.10 meters (*)" /> <segment id="4312424" start="0" end="2" time = "5.134262" name = "" distance = "114.09471" start_bearing = "-135.54565" end_bearing = "-142.83553" description = "" />
<segment id="83289991" start="0" end="5" time = "9.595843" name = "Groenendaallaan (N101) " distance = "186.58585" start_bearing = "-96.77957" end_bearing = "-85.083435" description = "" /> <segment id="4312429" start="0" end="2" time = "3.6745079" name = "" distance = "81.65573" turn = "Keep right" turn_angle = "2.3079834" start_bearing = "-140.52754" end_bearing = "-132.18445" description = "Keep right and go 81.66 meters" />
<segment id="83289991" start="5" end="6" time = "1.7055488" name = "Groenendaallaan (N101) " distance = "33.16345" turn = "Keep left" turn_angle = "-12.361893" start_bearing = "-97.44533" end_bearing = "-97.44533" description = "Keep left and go 76.67 meters" /> <segment id="146171826" start="0" end="2" time = "3.7306597" name = "Luitenant Lippenslaan (N184) " distance = "62.17766" turn = "Turn slightly right" turn_angle = "51.157074" start_bearing = "-81.027374" end_bearing = "-80.01059" description = "Turn slightly right and go 1112.29 meters" />
<segment id="23135820" start="0" end="2" time = "17.237564" name = "Straatsburgbrug (N101) " distance = "43.508186" start_bearing = "-109.30867" end_bearing = "-127.25529" description = "" /> <segment id="4395067" start="0" end="1" time = "26.002739" name = " (N184) " distance = "16.712315" start_bearing = "-79.69515" end_bearing = "-79.69515" description = "" />
<segment id="23135820" start="2" end="7" time = "13.779428" name = "Straatsburgbrug (N101) " distance = "267.93332" turn = "Keep left" turn_angle = "-17.293846" start_bearing = "-144.54913" end_bearing = "-165.66893" description = "Keep left and go 1050.13 meters" /> <segment id="4453106" start="0" end="6" time = "42.581" name = "Plantin en Moretuslei (N184) " distance = "293.01666" start_bearing = "-84.33272" end_bearing = "-84.770546" description = "" />
<segment id="23135823" start="0" end="5" time = "12.410626" name = "Straatsburgbrug (N101) " distance = "241.31773" start_bearing = "-161.98022" end_bearing = "-135.0" description = "" /> <segment id="35006131" start="0" end="4" time = "16.293785" name = "Plantin en Moretuslei (N184) " distance = "271.56308" start_bearing = "-81.809135" end_bearing = "-79.597755" description = "" />
<segment id="23135833" start="0" end="8" time = "11.765425" name = "Straatsburgbrug (N101) " distance = "228.77214" start_bearing = "-131.33221" end_bearing = "-28.096178" description = "" /> <segment id="29218710" start="0" end="8" time = "28.1292" name = "Plantin en Moretuslei (N184) " distance = "468.82" start_bearing = "-75.28796" end_bearing = "-101.04094" description = "" />
<segment id="23362097" start="0" end="6" time = "25.592014" name = "Siberiastraat (N101) " distance = "176.53357" start_bearing = "-35.202183" end_bearing = "-90.0" description = "" /> <segment id="34785645" start="0" end="2" time = "34.048256" name = "Plantin en Moretuslei (N184) " distance = "150.80424" turn = "Keep right" turn_angle = "30.52707" start_bearing = "-70.51387" end_bearing = "-84.97339" description = "Keep right and go 530.39 meters" />
<segment id="23362104" start="0" end="1" time = "2.7786715" name = "Siberiabrug (N101) " distance = "46.31119" start_bearing = "-89.06844" end_bearing = "-89.06844" description = "" /> <segment id="50897387" start="0" end="1" time = "1.1658815" name = "Plantin en Moretuslei (N184) " distance = "19.43136" start_bearing = "-90.0" end_bearing = "-90.0" description = "" />
<segment id="23362109" start="0" end="5" time = "5.355517" name = "Siberiastraat (N101) " distance = "89.25862" start_bearing = "-90.0" end_bearing = "-122.330185" description = "" /> <segment id="34785644" start="0" end="4" time = "6.0505266" name = "Plantin en Moretuslei (N184) " distance = "100.84211" start_bearing = "-91.39718" end_bearing = "-96.84277" description = "" />
<segment id="83290899" start="0" end="2" time = "1.2550789" name = "Siberiastraat (N101) " distance = "20.917982" turn = "Keep left" turn_angle = "-32.84047" start_bearing = "-155.17065" end_bearing = "-167.125" description = "Keep left and go 200.86 meters" /> <segment id="43287076" start="1" end="0" time = "25.86766" name = "Plantin en Moretuslei" distance = "12.050846" start_bearing = "-96.05419" end_bearing = "-96.05419" description = "" />
<segment id="15555547" start="1" end="0" time = "1.1728384" name = "Siberiastraat (N101) " distance = "19.547306" start_bearing = "-137.72632" end_bearing = "-137.72632" description = "" /> <segment id="50897385" start="0" end="1" time = "39.183067" name = "Plantin en Moretuslei (N184) " distance = "236.38448" start_bearing = "-96.983826" end_bearing = "-96.983826" description = "" />
<segment id="23008534" start="0" end="4" time = "9.623776" name = "Siberiastraat (N101) " distance = "160.39627" start_bearing = "-137.96486" end_bearing = "-139.27477" description = "" /> <segment id="21080483" start="0" end="1" time = "0.7834903" name = "Plantin en Moretuslei (N184) " distance = "10.881809" start_bearing = "-74.42746" end_bearing = "-74.42746" description = "" />
<segment id="23008534" start="4" end="6" time = "3.1598182" name = "Siberiastraat (N101) " distance = "52.663635" turn = "Keep left" turn_angle = "-2.25737" start_bearing = "-141.53214" end_bearing = "-145.89354" description = "Keep left and go 348.54 meters" /> <segment id="29239262" start="0" end="1" time = "1.9438865" name = "Plantin en Moretuslei (N184) " distance = "26.998425" turn = "Keep left" turn_angle = "-20.766968" start_bearing = "-95.19443" end_bearing = "-95.19443" description = "Keep left and go 1284.23 meters" />
<segment id="23541825" start="0" end="3" time = "17.776953" name = "Oosterweelsteenweg" distance = "222.2119" start_bearing = "-176.3396" end_bearing = "-161.56505" description = "" /> <segment id="4394995" start="0" end="1" time = "25.981947" name = "Plantin en Moretuslei (N184) " distance = "13.63815" start_bearing = "-98.130104" end_bearing = "-98.130104" description = "" />
<segment id="23361097" start="0" end="5" time = "5.8934116" name = "Mosselstraat" distance = "73.66764" start_bearing = "-130.85538" end_bearing = "-104.38139" description = "" /> <segment id="4394994" start="0" end="1" time = "26.742825" name = "Van Eycklei (N184) " distance = "24.205906" start_bearing = "-99.6052" end_bearing = "-99.6052" description = "" />
<segment id="46420908" start="0" end="8" time = "16.047739" name = "Sloepenweg" distance = "222.88528" turn = "Turn slightly left" turn_angle = "-46.26085" start_bearing = "-150.64224" end_bearing = "150.64224" description = "Turn slightly left and go 308.08 meters" /> <segment id="34855821" start="0" end="1" time = "2.282983" name = "Van Eycklei (N184) " distance = "31.7081" start_bearing = "-97.16724" end_bearing = "-97.16724" description = "" />
<segment id="33886773" start="0" end="3" time = "6.1337266" name = "Sloepenweg" distance = "85.19065" start_bearing = "106.03994" end_bearing = "131.39153" description = "" /> <segment id="34855824" start="0" end="8" time = "32.686893" name = "Van Eycklei (N184) " distance = "453.98465" start_bearing = "-84.99417" end_bearing = "-56.309933" description = "" />
<segment id="117440382" start="0" end="1" time = "2.4762578" name = "Rijnkaai" distance = "34.39247" turn = "Turn slightly right" turn_angle = "47.369843" start_bearing = "178.76137" end_bearing = "178.76137" description = "Turn slightly right and go 1717.08 meters" /> <segment id="4394980" start="0" end="1" time = "25.729961" name = "Maria-Henriëttalei (N184) " distance = "12.16601" start_bearing = "-46.301952" end_bearing = "-46.301952" description = "" />
<segment id="117440385" start="0" end="1" time = "3.4957857" name = "Kattendijkbrug" distance = "48.55258" start_bearing = "179.77878" end_bearing = "179.77878" description = "" /> <segment id="4430256" start="0" end="2" time = "31.529934" name = "Maria-Henriëttalei (N184) " distance = "108.83224" start_bearing = "-50.833004" end_bearing = "-47.683777" description = "" />
<segment id="133648996" start="0" end="2" time = "5.0220265" name = "Rijnkaai" distance = "69.75037" start_bearing = "179.80174" end_bearing = "-171.8699" description = "" /> <segment id="133434343" start="0" end="1" time = "0.48502362" name = "Maria-Henriëttalei (N184) " distance = "8.083727" start_bearing = "-31.429565" end_bearing = "-31.429565" description = "" />
<segment id="120143807" start="0" end="3" time = "3.6428173" name = "Rijnkaai" distance = "45.535217" start_bearing = "-145.49147" end_bearing = "-111.54098" description = "" /> <segment id="8052374" start="0" end="3" time = "27.157873" name = "Frankrijklei" distance = "35.96455" start_bearing = "-35.90972" end_bearing = "-44.464542" description = "" />
<segment id="120143808" start="0" end="4" time = "8.720661" name = "Rijnkaai" distance = "121.1203" start_bearing = "-137.04541" end_bearing = "179.19307" description = "" /> <segment id="4446690" start="0" end="4" time = "32.2554" name = "Bourlastraat" distance = "90.6925" start_bearing = "-47.935673" end_bearing = "-71.87814" description = "" />
<segment id="83349187" start="0" end="2" time = "3.610016" name = "Rijnkaai" distance = "50.139114" start_bearing = "178.03859" end_bearing = "176.24828" description = "" /> <segment id="4446716" start="0" end="7" time = "3.168966" name = "Leopoldplaats" distance = "39.612076" start_bearing = "-59.743565" end_bearing = "-8.972627" description = "" />
<segment id="50883861" start="0" end="2" time = "4.1431518" name = "Rijnkaai" distance = "57.543777" start_bearing = "158.1986" end_bearing = "169.57928" description = "" /> <segment id="7940942" start="0" end="8" time = "28.65889" name = "Leopoldstraat" distance = "358.2361" start_bearing = "-4.969741" end_bearing = "-23.498566" description = "" />
<segment id="23361255" start="0" end="2" time = "4.742435" name = "Rijnkaai" distance = "65.86715" start_bearing = "-175.4139" end_bearing = "179.32198" description = "" /> <segment id="7940955" start="0" end="2" time = "6.4086165" name = "Komedieplaats" distance = "80.107704" start_bearing = "-46.684685" end_bearing = "-51.608463" description = "" />
<segment id="133656814" start="0" end="2" time = "3.3451478" name = "Rijnkaai" distance = "46.46039" start_bearing = "-169.33022" end_bearing = "-167.41231" description = "" /> <segment id="4446795" start="0" end="2" time = "1.3632743" name = "Komedieplaats" distance = "17.04093" turn = "Keep right" turn_angle = "11.372105" start_bearing = "-40.23636" end_bearing = "-27.645975" description = "Keep right and go 226.12 meters" />
<segment id="19584404" start="0" end="1" time = "17.841076" name = "Rijnkaai" distance = "35.51344" start_bearing = "-164.95361" end_bearing = "-164.95361" description = "" /> <segment id="4446775" start="0" end="16" time = "15.203991" name = "Huidevettersstraat" distance = "190.0499" start_bearing = "-8.746162" end_bearing = "-1.1457628" description = "" />
<segment id="133656813" start="0" end="1" time = "3.7797394" name = "Rijnkaai" distance = "47.246742" start_bearing = "-160.92291" end_bearing = "-160.92291" description = "" /> <segment id="4446826" start="0" end="3" time = "1.5223826" name = "Meir" distance = "19.029783" start_bearing = "-7.6960516" end_bearing = "-30.963757" description = "" />
<segment id="82652955" start="0" end="3" time = "7.2567635" name = "Rijnkaai" distance = "90.70954" start_bearing = "-158.13142" end_bearing = "-164.4072" description = "" /> <segment id="25150191" start="0" end="5" time = "27.61911" name = "Meir" distance = "32.738888" turn = "Keep left" turn_angle = "-32.47119" start_bearing = "-63.434948" end_bearing = "-69.14554" description = "Keep left and go 439.14 meters" />
<segment id="32874073" start="0" end="7" time = "16.602541" name = "Tavernierkaai" distance = "207.53177" start_bearing = "-169.77783" end_bearing = "-160.34618" description = "" /> <segment id="19752616" start="0" end="1" time = "27.84184" name = "Meirbrug" distance = "35.52302" start_bearing = "-75.08797" end_bearing = "-75.08797" description = "" />
<segment id="22957749" start="0" end="3" time = "5.8082724" name = "Tavernierkaai" distance = "72.60341" start_bearing = "-151.02586" end_bearing = "-145.00798" description = "" /> <segment id="33682293" start="0" end="1" time = "0.71734244" name = "Meirbrug" distance = "8.966781" start_bearing = "-86.00909" end_bearing = "-86.00909" description = "" />
<segment id="82651772" start="0" end="2" time = "2.1968422" name = "Tavernierkaai" distance = "27.460526" start_bearing = "-149.96672" end_bearing = "-147.17146" description = "" /> <segment id="7940939" start="0" end="6" time = "5.6946187" name = "Schoenmarkt" distance = "71.18273" start_bearing = "-103.392494" end_bearing = "-96.94099" description = "" />
<segment id="22957750" start="0" end="5" time = "21.785543" name = "Van Meterenkaai" distance = "94.243675" start_bearing = "-146.92932" end_bearing = "-150.41223" description = "" /> <segment id="76441128" start="0" end="5" time = "5.179564" name = "Schoenmarkt" distance = "64.74455" start_bearing = "-94.159645" end_bearing = "-80.37184" description = "" />
<segment id="22957751" start="0" end="1" time = "2.317422" name = "Orteliuskaai" distance = "32.186417" start_bearing = "-158.25922" end_bearing = "-158.25922" description = "" /> <segment id="76441130" start="0" end="3" time = "27.35271" name = "Schoenmarkt" distance = "29.40888" start_bearing = "-82.874985" end_bearing = "-69.04422" description = "" />
<segment id="22957752" start="0" end="2" time = "8.450739" name = "Jordaenskaai" distance = "117.37138" start_bearing = "-158.61746" end_bearing = "-155.77225" description = "" /> <segment id="19752819" start="0" end="5" time = "5.676056" name = "Groenplaats" distance = "70.9507" start_bearing = "-73.73979" end_bearing = "-68.06462" description = "" />
<segment id="25788113" start="0" end="6" time = "17.696148" name = "Jordaenskaai" distance = "245.77983" start_bearing = "-157.96378" end_bearing = "-158.80594" description = "" /> <segment id="19882382" start="0" end="3" time = "1.5475764" name = "" distance = "19.344706" start_bearing = "-90.0" end_bearing = "-147.65256" description = "" />
<segment id="82652959" start="0" end="2" time = "4.6872363" name = "Jordaenskaai" distance = "65.1005" start_bearing = "-158.1986" end_bearing = "-158.65422" description = "" /> <segment id="7940936" start="15" end="14" time = "37.753136" name = "Nationalestraat" distance = "106.27612" start_bearing = "-154.78815" end_bearing = "-154.78815" description = "" />
<segment id="22957753" start="0" end="2" time = "10.221777" name = "Ernest Van Dijckkaai" distance = "141.96913" start_bearing = "-157.03622" end_bearing = "-156.81464" description = "" /> <segment id="22092951" start="0" end="3" time = "40.335327" name = "Lombardenvest" distance = "149.09346" turn = "Turn left" turn_angle = "-106.25054" start_bearing = "98.96131" end_bearing = "112.306206" description = "Turn left and go 149.09 meters" />
<segment id="18954370" start="0" end="3" time = "30.17769" name = "Suikerrui" distance = "147.56088" turn = "Turn left" turn_angle = "-84.42139" start_bearing = "118.76398" end_bearing = "114.26589" description = "Turn left and go 512.98 meters" />
<segment id="23220777" start="0" end="1" time = "1.0868886" name = "Suikerrui" distance = "10.566973" start_bearing = "132.76883" end_bearing = "132.76883" description = "" />
<segment id="19078058" start="0" end="5" time = "12.994094" name = "Oude Koornmarkt" distance = "126.331474" start_bearing = "132.8142" end_bearing = "150.21947" description = "" />
<segment id="82654432" start="0" end="3" time = "11.758362" name = "Oude Koornmarkt" distance = "114.31741" start_bearing = "162.62924" end_bearing = "-169.24203" description = "" />
<segment id="19078060" start="0" end="4" time = "11.74693" name = "Kammenstraat" distance = "114.20627" start_bearing = "-175.45801" end_bearing = "167.90524" description = "" />
<segment id="22092951" start="0" end="3" time = "30.335327" name = "Lombardenvest" distance = "149.09346" turn = "Turn left" turn_angle = "-68.94393" start_bearing = "98.96131" end_bearing = "112.306206" description = "Turn left and go 149.09 meters" />
<segment id="22093399" start="0" end="1" time = "3.7942796" name = "" distance = "36.88883" turn = "Turn right" turn_angle = "60.98716" start_bearing = "173.29337" end_bearing = "173.29337" description = "Turn right and go 36.89 meters" /> <segment id="22093399" start="0" end="1" time = "3.7942796" name = "" distance = "36.88883" turn = "Turn right" turn_angle = "60.98716" start_bearing = "173.29337" end_bearing = "173.29337" description = "Turn right and go 36.89 meters" />
</test> </test>
</router_tests> </router_tests>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<router_tests> <router_tests>
<test regions="" description="Amstelveen-Leiden" best_percent="5" vehicle="car" <test regions="" description="Amstelveen-Leiden" best_percent="5" vehicle="car"
start_lat="52.291026337270445" start_lon="4.848833084106445" target_lat="52.16400849542039" target_lon="4.478881359100342" complete_time="1810.644" loadedTiles = "45" visitedSegments = "2512" complete_distance = "41994.66" > start_lat="52.291026337270445" start_lon="4.848833084106445" target_lat="52.16400849542039" target_lon="4.478881359100342" complete_time="1810.644" loadedTiles = "650" visitedSegments = "2512" complete_distance = "41994.66" >
<segment id="48102635" start="9" end="17" time = "26.337616" name = "" distance = "365.80023" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-80.22256" end_bearing = "-79.69515" description = "Go ahead and go 365.80 meters" /> <segment id="48102635" start="9" end="17" time = "26.337616" name = "" distance = "365.80023" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-80.22256" end_bearing = "-79.69515" description = "Go ahead and go 365.80 meters" />
<segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" turn = "Turn right" turn_angle = "87.82526" start_bearing = "8.130102" end_bearing = "9.901572" description = "Turn right and go 548.57 meters" /> <segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" turn = "Turn right" turn_angle = "87.82526" start_bearing = "8.130102" end_bearing = "9.901572" description = "Turn right and go 548.57 meters" />
<segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" /> <segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />

View file

@ -3,6 +3,7 @@ package net.osmand;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
import net.osmand.binary.RouteDataObject; import net.osmand.binary.RouteDataObject;
import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage; import net.osmand.render.RenderingRulesStorage;
@ -42,7 +43,7 @@ public class NativeLibrary {
public long nativeHandler; public long nativeHandler;
public RouteDataObject[] objects; public RouteDataObject[] objects;
public RouteRegion region; public RouteSubregion region;
public NativeRouteSearchResult(long nativeHandler, RouteDataObject[] objects) { public NativeRouteSearchResult(long nativeHandler, RouteDataObject[] objects) {
this.nativeHandler = nativeHandler; this.nativeHandler = nativeHandler;
this.objects = objects; this.objects = objects;
@ -76,7 +77,7 @@ public class NativeLibrary {
if(rs.nativeHandler == 0) { if(rs.nativeHandler == 0) {
throw new IllegalStateException("Native route handler is 0"); throw new IllegalStateException("Native route handler is 0");
} }
return getRouteDataObjects(rs.region, rs.nativeHandler, x31, y31); return getRouteDataObjects(rs.region.routeReg, rs.nativeHandler, x31, y31);
} }
@ -94,16 +95,17 @@ public class NativeLibrary {
public NativeRouteSearchResult loadRouteRegion(RouteRegion reg, int left, int right, int top, int bottom, boolean loadObjects) { public NativeRouteSearchResult loadRouteRegion(RouteSubregion sub, boolean loadObjects) {
NativeRouteSearchResult lr = loadRoutingData(reg, reg.getName(), reg.getFilePointer(), left, right, top, bottom, loadObjects); NativeRouteSearchResult lr = loadRoutingData(sub.routeReg, sub.routeReg.getName(), sub.routeReg.getFilePointer(),
sub, loadObjects);
if(lr != null && lr.nativeHandler != 0){ if(lr != null && lr.nativeHandler != 0){
lr.region = reg; lr.region = sub;
} }
return lr; return lr;
} }
protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int fpointer, int left, int right, int top, int bottom, protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int regfp,RouteSubregion subreg,
boolean loadObjects); boolean loadObjects);
protected static native void deleteRouteSearchResult(long searchResultHandle); protected static native void deleteRouteSearchResult(long searchResultHandle);

View file

@ -49,7 +49,7 @@ public class BinaryInspector {
// test cases show info // test cases show info
//inspector(new String[]{"-vaddress",/* "-bbox=-121.785,37.35,-121.744,37.33", */"/home/victor/projects/OsmAnd/data/osm-gen/Map.obf"}); inspector(new String[]{/*"-vaddress", "-bbox=-121.785,37.35,-121.744,37.33", */"/home/victor/projects/OsmAnd/data/osm-gen/Netherlands_europe.obf"});
// test case extract parts // test case extract parts
// test case // test case
} }

View file

@ -1962,16 +1962,30 @@ public class BinaryMapIndexReader {
public void initRouteRegionsIfNeeded(SearchRequest<RouteDataObject> req) throws IOException { public void initRouteRegionsIfNeeded(SearchRequest<RouteDataObject> req) throws IOException {
routeAdapter.initRouteTypesIfNeeded(req); routeAdapter.initRouteTypesIfNeeded(req);
} }
public void searchRouteIndex(SearchRequest<RouteDataObject> req, List<RouteSubregion> list) throws IOException { public List<RouteSubregion> searchRouteIndexTree(SearchRequest<RouteDataObject> req, List<RouteSubregion> list) throws IOException {
req.numberOfVisitedObjects = 0; req.numberOfVisitedObjects = 0;
req.numberOfAcceptedObjects = 0; req.numberOfAcceptedObjects = 0;
req.numberOfAcceptedSubtrees = 0; req.numberOfAcceptedSubtrees = 0;
req.numberOfReadSubtrees = 0; req.numberOfReadSubtrees = 0;
if(routeAdapter != null){ if(routeAdapter != null){
initRouteRegionsIfNeeded(req); initRouteRegionsIfNeeded(req);
routeAdapter.searchRouteRegion(req, list); return routeAdapter.searchRouteRegionTree(req, list, new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>());
}
return Collections.emptyList();
}
public void loadRouteIndexData(List<RouteSubregion> toLoad, ResultMatcher<RouteDataObject> matcher) throws IOException {
if(routeAdapter != null){
routeAdapter.loadRouteRegionData(toLoad, matcher);
} }
} }
public List<RouteDataObject> loadRouteIndexData(RouteSubregion rs) throws IOException {
if(routeAdapter != null){
return routeAdapter.loadRouteRegionData(rs);
}
return Collections.emptyList();
}
} }

View file

@ -13,6 +13,7 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import net.osmand.LogUtil; import net.osmand.LogUtil;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.binary.OsmandOdb.IdTable; import net.osmand.binary.OsmandOdb.IdTable;
import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteDataBlock; import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteDataBlock;
@ -154,7 +155,7 @@ public class BinaryMapRouteReaderAdapter {
} }
public static class RouteRegion extends BinaryIndexPart { public static class RouteRegion extends BinaryIndexPart {
int regionsRead; public int regionsRead;
List<RouteSubregion> subregions = new ArrayList<RouteSubregion>(); List<RouteSubregion> subregions = new ArrayList<RouteSubregion>();
List<RouteTypeRule> routeEncodingRules = new ArrayList<BinaryMapRouteReaderAdapter.RouteTypeRule>(); List<RouteTypeRule> routeEncodingRules = new ArrayList<BinaryMapRouteReaderAdapter.RouteTypeRule>();
@ -214,6 +215,7 @@ public class BinaryMapRouteReaderAdapter {
} }
} }
// Used in C++
public static class RouteSubregion { public static class RouteSubregion {
private final static int INT_SIZE = 4; private final static int INT_SIZE = 4;
public final RouteRegion routeReg; public final RouteRegion routeReg;
@ -250,6 +252,16 @@ public class BinaryMapRouteReaderAdapter {
} }
return shallow; return shallow;
} }
public int countSubregions(){
int cnt = 1;
if (subregions != null) {
for (RouteSubregion s : subregions) {
cnt += s.countSubregions();
}
}
return cnt;
}
} }
private CodedInputStreamRAF codedIS; private CodedInputStreamRAF codedIS;
@ -576,6 +588,11 @@ public class BinaryMapRouteReaderAdapter {
break; break;
case RouteDataBox.SHIFTTODATA_FIELD_NUMBER : case RouteDataBox.SHIFTTODATA_FIELD_NUMBER :
thisTree.shiftToData = readInt(); thisTree.shiftToData = readInt();
if(!readChildren) {
// usually 0
thisTree.subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
readChildren = true;
}
break; break;
case RouteDataBox.BOXES_FIELD_NUMBER : case RouteDataBox.BOXES_FIELD_NUMBER :
if(readChildren){ if(readChildren){
@ -617,12 +634,25 @@ public class BinaryMapRouteReaderAdapter {
} }
} }
} }
}
public List<RouteDataObject> loadRouteRegionData(RouteSubregion rs) throws IOException {
TLongArrayList idMap = new TLongArrayList();
TLongObjectHashMap<TLongArrayList> restrictionMap = new TLongObjectHashMap<TLongArrayList>();
if (rs.dataObjects == null) {
codedIS.seek(rs.filePointer + rs.shiftToData);
int limit = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(limit);
readRouteTreeData(rs, idMap, restrictionMap);
codedIS.popLimit(oldLimit);
}
List<RouteDataObject> res = rs.dataObjects;
rs.dataObjects = null;
return res;
} }
public void searchRouteRegion(SearchRequest<RouteDataObject> req, List<RouteSubregion> list) throws IOException { public void loadRouteRegionData(List<RouteSubregion> toLoad, ResultMatcher<RouteDataObject> matcher) throws IOException {
List<RouteSubregion> toLoad = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
searchRouteRegion(req, list, toLoad);
Collections.sort(toLoad, new Comparator<RouteSubregion>() { Collections.sort(toLoad, new Comparator<RouteSubregion>() {
@Override @Override
public int compare(RouteSubregion o1, RouteSubregion o2) { public int compare(RouteSubregion o1, RouteSubregion o2) {
@ -643,7 +673,7 @@ public class BinaryMapRouteReaderAdapter {
} }
for (RouteDataObject ro : rs.dataObjects) { for (RouteDataObject ro : rs.dataObjects) {
if (ro != null) { if (ro != null) {
req.publish(ro); matcher.publish(ro);
} }
} }
// free objects // free objects
@ -651,8 +681,9 @@ public class BinaryMapRouteReaderAdapter {
} }
} }
private void searchRouteRegion(SearchRequest<RouteDataObject> req, List<RouteSubregion> list, List<RouteSubregion> toLoad) throws IOException { public List<RouteSubregion> searchRouteRegionTree(SearchRequest<RouteDataObject> req, List<RouteSubregion> list,
for(RouteSubregion rs : list){ List<RouteSubregion> toLoad) throws IOException {
for (RouteSubregion rs : list) {
if (req.intersects(rs.left, rs.top, rs.right, rs.bottom)) { if (req.intersects(rs.left, rs.top, rs.right, rs.bottom)) {
if (rs.subregions == null) { if (rs.subregions == null) {
codedIS.seek(rs.filePointer); codedIS.seek(rs.filePointer);
@ -660,13 +691,14 @@ public class BinaryMapRouteReaderAdapter {
readRouteTree(rs, null, req.contains(rs.left, rs.top, rs.right, rs.bottom) ? -1 : 1, false); readRouteTree(rs, null, req.contains(rs.left, rs.top, rs.right, rs.bottom) ? -1 : 1, false);
codedIS.popLimit(old); codedIS.popLimit(old);
} }
searchRouteRegion(req, rs.subregions, toLoad); searchRouteRegionTree(req, rs.subregions, toLoad);
if (rs.shiftToData != 0) { if (rs.shiftToData != 0) {
toLoad.add(rs); toLoad.add(rs);
} }
} }
} }
return toLoad;
} }
} }

View file

@ -1,5 +1,6 @@
package net.osmand.binary; package net.osmand.binary;
import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TIntObjectHashMap;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;

View file

@ -1,7 +1,5 @@
package net.osmand.router; package net.osmand.router;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TLongObjectHashMap; import gnu.trove.map.hash.TLongObjectHashMap;
import java.io.IOException; import java.io.IOException;
@ -11,23 +9,13 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import java.util.Set;
import java.util.TreeSet;
import net.osmand.LogUtil; import net.osmand.LogUtil;
import net.osmand.NativeLibrary;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapRouteReaderAdapter;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
import net.osmand.binary.RouteDataObject; import net.osmand.binary.RouteDataObject;
import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MapRenderingTypes;
import net.osmand.osm.MapUtils; import net.osmand.osm.MapUtils;
import net.osmand.router.RoutingContext.RoutingTile;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -35,8 +23,7 @@ public class BinaryRoutePlanner {
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true; public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
private final int REVERSE_WAY_RESTRICTION_ONLY = 1024; private final int REVERSE_WAY_RESTRICTION_ONLY = 1024;
private final NativeLibrary nativeLib; private final int STANDARD_ROAD_IN_QUEUE_OVERHEAD = 900;
private final Map<BinaryMapIndexReader, List<RouteSubregion>> map = new LinkedHashMap<BinaryMapIndexReader, List<RouteSubregion>>();
protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class); protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
@ -44,24 +31,6 @@ public class BinaryRoutePlanner {
private static final float TURN_DEGREE_MIN = 45; private static final float TURN_DEGREE_MIN = 45;
public BinaryRoutePlanner(NativeLibrary nativeLib, BinaryMapIndexReader... map) {
this.nativeLib = nativeLib;
if(nativeLib != null) {
RoutingConfiguration.DEFAULT_DESIRABLE_TILES_IN_MEMORY = 100;
}
for (BinaryMapIndexReader mr : map) {
List<RouteRegion> rr = mr.getRoutingIndexes();
List<RouteSubregion> subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
for (RouteRegion r : rr) {
for (RouteSubregion rs : r.getSubregions()) {
subregions.add(new RouteSubregion(rs));
}
}
this.map.put(mr, subregions);
}
}
private static double squareRootDist(int x1, int y1, int x2, int y2) { private static double squareRootDist(int x1, int y1, int x2, int y2) {
// translate into meters // translate into meters
double dy = convert31YToMeters(y1, y2); double dy = convert31YToMeters(y1, y2);
@ -102,49 +71,38 @@ public class BinaryRoutePlanner {
public RouteSegment findRouteSegment(double lat, double lon, RoutingContext ctx) throws IOException { public RouteSegment findRouteSegment(double lat, double lon, RoutingContext ctx) throws IOException {
int zoomAround = 15;
int coordinatesShift = (1 << (31 - zoomAround));
int px = MapUtils.get31TileNumberX(lon); int px = MapUtils.get31TileNumberX(lon);
int py = MapUtils.get31TileNumberY(lat); int py = MapUtils.get31TileNumberY(lat);
// put in map to avoid duplicate map loading ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
TIntObjectHashMap<RoutingTile> ts = new TIntObjectHashMap<RoutingContext.RoutingTile>(); ctx.loadTileData(px, py, 16, dataObjects);
// calculate box to load neighbor tiles if (dataObjects.isEmpty()) {
RoutingTile rt = ctx.getRoutingTile(px - coordinatesShift, py - coordinatesShift); ctx.loadTileData(px, py, 14, dataObjects);
ts.put(rt.getId(), rt);
rt = ctx.getRoutingTile(px + coordinatesShift, py - coordinatesShift);
ts.put(rt.getId(), rt);
rt = ctx.getRoutingTile(px - coordinatesShift, py + coordinatesShift);
ts.put(rt.getId(), rt);
rt = ctx.getRoutingTile(px + coordinatesShift, py + coordinatesShift);
ts.put(rt.getId(), rt);
List<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
Iterator<RoutingTile> it = ts.valueCollection().iterator();
while(it.hasNext()){
ctx.loadTileData(it.next(), dataObjects, nativeLib, map);
} }
RouteSegment road = null; RouteSegment road = null;
double sdist = 0; double sdist = 0;
int foundProjX = 0; int foundProjX = 0;
int foundProjY = 0; int foundProjY = 0;
for(RouteDataObject r : dataObjects){ for (RouteDataObject r : dataObjects) {
if(r.getPointsLength() > 1){ if (r.getPointsLength() > 1) {
for (int j = 1; j < r.getPointsLength(); j++) { for (int j = 1; j < r.getPointsLength(); j++) {
double mDist = squareRootDist(r.getPoint31XTile(j), r.getPoint31YTile(j), r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1)); double mDist = squareRootDist(r.getPoint31XTile(j), r.getPoint31YTile(j), r.getPoint31XTile(j - 1),
r.getPoint31YTile(j - 1));
int prx = r.getPoint31XTile(j); int prx = r.getPoint31XTile(j);
int pry = r.getPoint31YTile(j); int pry = r.getPoint31YTile(j);
double projection = calculateProjection(r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1), r.getPoint31XTile(j), r.getPoint31YTile(j), double projection = calculateProjection(r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1), r.getPoint31XTile(j),
px, py); r.getPoint31YTile(j), px, py);
if(projection < 0){ if (projection < 0) {
prx = r.getPoint31XTile(j - 1); prx = r.getPoint31XTile(j - 1);
pry = r.getPoint31YTile(j - 1); pry = r.getPoint31YTile(j - 1);
} else if(projection >= mDist * mDist){ } else if (projection >= mDist * mDist) {
prx = r.getPoint31XTile(j); prx = r.getPoint31XTile(j);
pry = r.getPoint31YTile(j); pry = r.getPoint31YTile(j);
} else { } else {
prx = (int) (r.getPoint31XTile(j - 1) + (r.getPoint31XTile(j) - r.getPoint31XTile(j - 1))* (projection / (mDist *mDist))); prx = (int) (r.getPoint31XTile(j - 1) + (r.getPoint31XTile(j) - r.getPoint31XTile(j - 1))
pry = (int) (r.getPoint31YTile(j - 1) + (r.getPoint31YTile(j) - r.getPoint31YTile(j - 1)) * (projection / (mDist *mDist))); * (projection / (mDist * mDist)));
pry = (int) (r.getPoint31YTile(j - 1) + (r.getPoint31YTile(j) - r.getPoint31YTile(j - 1))
* (projection / (mDist * mDist)));
} }
double currentsDist = squareDist(prx, pry, px, py); double currentsDist = squareDist(prx, pry, px, py);
if (road == null || currentsDist < sdist) { if (road == null || currentsDist < sdist) {
@ -158,14 +116,14 @@ public class BinaryRoutePlanner {
} }
} }
} }
if(road != null) { if (road != null) {
// re-register the best road because one more point was inserted // re-register the best road because one more point was inserted
ctx.registerRouteDataObject(road.getRoad(), ctx.getRoutingTile(foundProjX, foundProjY)); ctx.registerRouteDataObject(foundProjX, foundProjY, road.getRoad());
} }
return road; return road;
} }
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, List<RouteSegment> intermediate, boolean leftSideNavigation) throws IOException { public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, List<RouteSegment> intermediate, boolean leftSideNavigation) throws IOException, InterruptedException {
if(intermediate != null && intermediate.size() > 0) { if(intermediate != null && intermediate.size() > 0) {
ArrayList<RouteSegment> ps = new ArrayList<RouteSegment>(intermediate); ArrayList<RouteSegment> ps = new ArrayList<RouteSegment>(intermediate);
ArrayList<RouteSegmentResult> firstPartRecalculatedRoute = null; ArrayList<RouteSegmentResult> firstPartRecalculatedRoute = null;
@ -187,68 +145,74 @@ public class BinaryRoutePlanner {
ps.add(0, start); ps.add(0, start);
List<RouteSegmentResult> results = new ArrayList<RouteSegmentResult>(); List<RouteSegmentResult> results = new ArrayList<RouteSegmentResult>();
for (int i = 0; i < ps.size() - 1; i++) { for (int i = 0; i < ps.size() - 1; i++) {
RoutingContext local = new RoutingContext(ctx.config); RoutingContext local = new RoutingContext(ctx);
local.copyLoadedDataAndClearCaches(ctx);
if(i == 0) { if(i == 0) {
local.previouslyCalculatedRoute = firstPartRecalculatedRoute; local.previouslyCalculatedRoute = firstPartRecalculatedRoute;
} }
local.visitor = ctx.visitor; local.visitor = ctx.visitor;
List<RouteSegmentResult> res = searchRouteInternal(local, ps.get(i), ps.get(i + 1), leftSideNavigation); List<RouteSegmentResult> res = searchRouteInternalPrepare(local, ps.get(i), ps.get(i + 1), leftSideNavigation);
results.addAll(res); results.addAll(res);
ctx.distinctLoadedTiles += local.distinctLoadedTiles; ctx.distinctLoadedTiles += local.distinctLoadedTiles;
ctx.distinctUnloadedTiles.addAll(local.distinctUnloadedTiles);
ctx.loadedTiles += local.loadedTiles; ctx.loadedTiles += local.loadedTiles;
ctx.visitedSegments += local.visitedSegments; ctx.visitedSegments += local.visitedSegments;
ctx.loadedPrevUnloadedTiles += local.loadedPrevUnloadedTiles; ctx.loadedPrevUnloadedTiles += local.loadedPrevUnloadedTiles;
ctx.timeToCalculate += local.timeToCalculate; ctx.timeToCalculate += local.timeToCalculate;
ctx.timeToLoad += local.timeToLoad; ctx.timeToLoad += local.timeToLoad;
ctx.timeToLoadHeaders += local.timeToLoadHeaders;
ctx.relaxedSegments += local.relaxedSegments; ctx.relaxedSegments += local.relaxedSegments;
List<RoutingTile> toUnload = new ArrayList<RoutingContext.RoutingTile>(); local.unloadAllData(ctx);
for(RoutingTile t : local.tiles.valueCollection()){
if(!ctx.tiles.contains(t.getId())) {
toUnload.add(t);
}
}
for(RoutingTile tl : toUnload) {
local.unloadTile(tl, false);
}
if(restPartRecalculatedRoute != null) { if(restPartRecalculatedRoute != null) {
results.addAll(restPartRecalculatedRoute); results.addAll(restPartRecalculatedRoute);
break; break;
} }
} }
Object[] vls = ctx.tiles.values(); ctx.unloadAllData();
for (Object tl : vls) {
if (((RoutingTile) tl).isLoaded()) {
ctx.unloadTile((RoutingTile) tl, false);
}
}
printResults(ctx, start, end, results); printResults(ctx, start, end, results);
return results; return results;
} }
return searchRoute(ctx, start, end, leftSideNavigation); return searchRoute(ctx, start, end, leftSideNavigation);
} }
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException { @SuppressWarnings("static-access")
List<RouteSegmentResult> result = searchRouteInternal(ctx, start, end, leftSideNavigation); public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
if(ctx.SHOW_GC_SIZE){
long h1 = ctx.runGCUsedMemory();
float mb = (1 << 20);
log.warn("Used before routing " + h1 / mb+ " actual");
}
List<RouteSegmentResult> result = searchRouteInternalPrepare(ctx, start, end, leftSideNavigation);
if(result != null) { if(result != null) {
printResults(ctx, start, end, result); printResults(ctx, start, end, result);
} }
Object[] vls = ctx.tiles.values(); if (RoutingContext.SHOW_GC_SIZE) {
for(Object tl : vls) { int sz = ctx.global.size;
ctx.unloadTile((RoutingTile) tl, false); log.warn("Subregion size " + ctx.subregionTiles.size() + " " + " tiles " + ctx.indexedSubregions.size());
ctx.runGCUsedMemory();
long h1 = ctx.runGCUsedMemory();
ctx.unloadAllData();
ctx.runGCUsedMemory();
long h2 = ctx.runGCUsedMemory();
float mb = (1 << 20);
log.warn("Unload context : estimated " + sz / mb + " ?= " + (h1 - h2) / mb + " actual");
} }
return result; return result;
} }
private List<RouteSegmentResult> searchRouteInternalPrepare(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
// Split into 2 methods to let GC work in between
searchRouteInternal(ctx, start, end, leftSideNavigation);
// 4. Route is found : collect all segments and prepare result
return prepareResult(ctx, start, end, leftSideNavigation);
}
/** /**
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm) * Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
* return list of segments * return list of segments
*/ */
public List<RouteSegmentResult> searchRouteInternal(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException { private void searchRouteInternal(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
// measure time // measure time
ctx.timeToLoad = 0; ctx.timeToLoad = 0;
ctx.visitedSegments = 0; ctx.visitedSegments = 0;
@ -378,66 +342,19 @@ public class BinaryRoutePlanner {
graphSegments = graphDirectSegments; graphSegments = graphDirectSegments;
} }
if(ctx.runTilesGC()) {
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
}
if(ctx.runRelaxingStrategy() ) { if(ctx.runRelaxingStrategy() ) {
relaxNotNeededSegments(ctx, graphDirectSegments, true); relaxNotNeededSegments(ctx, graphDirectSegments, true);
relaxNotNeededSegments(ctx, graphReverseSegments, false); relaxNotNeededSegments(ctx, graphReverseSegments, false);
} }
// check if interrupted // check if interrupted
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) { if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
return new ArrayList<RouteSegmentResult>(); throw new InterruptedException("Route calculation interrupted");
} }
} }
println("Result is found"); println("Result is found");
printDebugMemoryInformation(ctx, graphDirectSegments, graphReverseSegments, visitedDirectSegments, visitedOppositeSegments); printDebugMemoryInformation(ctx, graphDirectSegments, graphReverseSegments, visitedDirectSegments, visitedOppositeSegments);
// 4. Route is found : collect all segments and prepare result
List<RouteSegmentResult> resultPrepared = prepareResult(ctx, start, end, leftSideNavigation);
return resultPrepared;
} }
private void unloadUnusedTiles(RoutingContext ctx, int desirableSize) {
// now delete all
List<RoutingTile> list = new ArrayList<RoutingContext.RoutingTile>();
TIntObjectIterator<RoutingTile> it = ctx.tiles.iterator();
int loaded = 0;
while(it.hasNext()) {
it.advance();
RoutingTile t = it.value();
if(t.isLoaded()) {
list.add(t);
loaded++;
}
}
ctx.maxLoadedTiles = Math.max(ctx.maxLoadedTiles, ctx.getCurrentlyLoadedTiles());
Collections.sort(list, new Comparator<RoutingTile>() {
private int pow(int base, int pw) {
int r = 1;
for (int i = 0; i < pw; i++) {
r *= base;
}
return r;
}
@Override
public int compare(RoutingTile o1, RoutingTile o2) {
int v1 = (o1.access + 1) * pow(10, o1.getUnloadCont() -1);
int v2 = (o2.access + 1) * pow(10, o2.getUnloadCont() -1);
return v1 < v2 ? -1 : (v1 == v2 ? 0 : 1);
}
});
if (loaded >= 0.9f * desirableSize) {
int toUnload = Math.max(loaded / 5, loaded - desirableSize);
for (int i = 0; i < loaded; i++) {
list.get(i).access = 0;
if (i < toUnload) {
ctx.unloadTile(list.get(i), true);
}
}
}
}
private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, boolean inverse) { private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, boolean inverse) {
@ -498,34 +415,28 @@ public class BinaryRoutePlanner {
System.out.println(logMsg); System.out.println(logMsg);
} }
private static void printInfo(String logMsg) {
log.warn(logMsg);
}
public void printDebugMemoryInformation(RoutingContext ctx, PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments, public void printDebugMemoryInformation(RoutingContext ctx, PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments,
TLongObjectHashMap<RouteSegment> visitedDirectSegments,TLongObjectHashMap<RouteSegment> visitedOppositeSegments) { TLongObjectHashMap<RouteSegment> visitedDirectSegments,TLongObjectHashMap<RouteSegment> visitedOppositeSegments) {
println("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6); printInfo("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6 + ", time to load headers : " + ctx.timeToLoadHeaders / 1e6);
println("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + ctx.maxLoadedTiles); int maxLoadedTiles = Math.max(ctx.maxLoadedTiles, ctx.getCurrentlyLoadedTiles());
println("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles + printInfo("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + maxLoadedTiles);
" (distinct " + ctx.distinctUnloadedTiles.size()+") "+ ", loaded more than once same tiles " printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
", loaded more than once same tiles "
+ ctx.loadedPrevUnloadedTiles ); + ctx.loadedPrevUnloadedTiles );
println("Visited roads, " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments); printInfo("Visited roads, " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments);
if (graphDirectSegments != null && graphReverseSegments != null) { if (graphDirectSegments != null && graphReverseSegments != null) {
println("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size()); printInfo("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
} }
if (visitedDirectSegments != null && visitedOppositeSegments != null) { if (visitedDirectSegments != null && visitedOppositeSegments != null) {
println("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size()); printInfo("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
} }
} }
public RoutingTile loadRoutes(final RoutingContext ctx, int tile31X, int tile31Y) {
final RoutingTile tile = ctx.getRoutingTile(tile31X, tile31Y);
if (tile.isLoaded()) {
tile.access++;
return tile;
}
ctx.loadTileData(tile, null, nativeLib, map);
return tile;
}
private boolean processRouteSegment(final RoutingContext ctx, boolean reverseWaySearch, private boolean processRouteSegment(final RoutingContext ctx, boolean reverseWaySearch,
PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int targetEndX, int targetEndY, PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int targetEndX, int targetEndY,
@ -620,7 +531,6 @@ public class BinaryRoutePlanner {
// 2. calculate point and try to load neighbor ways if they are not loaded // 2. calculate point and try to load neighbor ways if they are not loaded
int x = road.getPoint31XTile(segmentEnd); int x = road.getPoint31XTile(segmentEnd);
int y = road.getPoint31YTile(segmentEnd); int y = road.getPoint31YTile(segmentEnd);
RoutingTile tile = loadRoutes(ctx, x, y);
if(positive) { if(positive) {
posSegmentDist += squareRootDist(x, y, posSegmentDist += squareRootDist(x, y,
road.getPoint31XTile(segmentEnd - 1), road.getPoint31YTile(segmentEnd - 1)); road.getPoint31XTile(segmentEnd - 1), road.getPoint31YTile(segmentEnd - 1));
@ -645,9 +555,14 @@ public class BinaryRoutePlanner {
} }
obstacleMinusTime += obstacle; obstacleMinusTime += obstacle;
} }
// int overhead = 0;
long l = (((long) x) << 31) + (long) y; // could be expensive calculation
RouteSegment next = tile.getSegment(l, ctx); int overhead = (ctx.visitedSegments - ctx.relaxedSegments ) *
STANDARD_ROAD_IN_QUEUE_OVERHEAD;
if(overhead > ctx.config.memoryLimitation * 0.95){
throw new OutOfMemoryError("There is no enough memory " + ctx.config.memoryLimitation/(1<<20) + " Mb");
}
RouteSegment next = ctx.loadRouteSegment(x, y, ctx.config.memoryLimitation - overhead);
// 3. get intersected ways // 3. get intersected ways
if (next != null) { if (next != null) {
// TO-DO U-Turn // TO-DO U-Turn
@ -886,8 +801,8 @@ public class BinaryRoutePlanner {
// calculate time // calculate time
for (int i = 0; i < result.size(); i++) { for (int i = 0; i < result.size(); i++) {
if(ctx.runTilesGC()) { if(ctx.checkIfMemoryLimitCritical(ctx.config.memoryLimitation)) {
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY); ctx.unloadUnusedTiles(ctx.config.memoryLimitation);
} }
RouteSegmentResult rr = result.get(i); RouteSegmentResult rr = result.get(i);
RouteDataObject road = rr.getObject(); RouteDataObject road = rr.getObject();
@ -1240,8 +1155,6 @@ public class BinaryRoutePlanner {
private void attachRoadSegments(RoutingContext ctx, List<RouteSegmentResult> result, int routeInd, int pointInd, boolean plus) { private void attachRoadSegments(RoutingContext ctx, List<RouteSegmentResult> result, int routeInd, int pointInd, boolean plus) {
RouteSegmentResult rr = result.get(routeInd); RouteSegmentResult rr = result.get(routeInd);
RouteDataObject road = rr.getObject(); RouteDataObject road = rr.getObject();
RoutingTile tl = loadRoutes(ctx, road.getPoint31XTile(pointInd), road.getPoint31YTile(pointInd));
long l = getPoint(road, pointInd);
long nextL = pointInd < road.getPointsLength() - 1 ? getPoint(road, pointInd + 1) : 0; long nextL = pointInd < road.getPointsLength() - 1 ? getPoint(road, pointInd + 1) : 0;
long prevL = pointInd > 0 ? getPoint(road, pointInd - 1) : 0; long prevL = pointInd > 0 ? getPoint(road, pointInd - 1) : 0;
@ -1264,7 +1177,7 @@ public class BinaryRoutePlanner {
} }
} }
} }
RouteSegment routeSegment = tl.getSegment(l, ctx); RouteSegment routeSegment = ctx.loadRouteSegment(road.getPoint31XTile(pointInd), road.getPoint31YTile(pointInd), ctx.config.memoryLimitation);
// try to attach all segments except with current id // try to attach all segments except with current id
while (routeSegment != null) { while (routeSegment != null) {
if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) { if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) {
@ -1343,45 +1256,4 @@ public class BinaryRoutePlanner {
} }
public static class SegmentStat {
String name;
Set<Float> set = new TreeSet<Float>();
public SegmentStat(String name) {
this.name = name;
}
void addNumber(float v) {
set.add(v);
}
@Override
public String toString() {
int segmentation = 7;
StringBuilder sb = new StringBuilder();
sb.append(name).append(" (").append(set.size()).append(") : ");
float s = set.size() / ((float) segmentation);
int k = 0, number = 0;
float limit = 0, value = 0;
Iterator<Float> it = set.iterator();
while (it.hasNext()) {
k++;
number++;
value += it.next();
if (k >= limit) {
limit += s;
sb.append(value / number).append(" ");
number = 0;
value = 0;
}
}
if(number > 0) {
sb.append(value / number).append(" ");
}
return sb.toString();
}
}
} }

View file

@ -19,12 +19,13 @@ public class RoutingConfiguration {
// 1. parameters of routing and different tweaks // 1. parameters of routing and different tweaks
// Influence on A* : f(x) + heuristicCoefficient*g(X) // Influence on A* : f(x) + heuristicCoefficient*g(X)
public double heuristicCoefficient = 1; public double heuristicCoefficient = 1;
public static final int DEFAULT_MEMORY_LIMIT = 30;
// 1.1 tile load parameters (should not affect routing) // 1.1 tile load parameters (should not affect routing)
public int ZOOM_TO_LOAD_TILES = 13; // 12?, 14? public int ZOOM_TO_LOAD_TILES = 16;
public int ITERATIONS_TO_RUN_GC = 100; public int memoryLimitation;
public static int DEFAULT_DESIRABLE_TILES_IN_MEMORY = 30;
public int NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = DEFAULT_DESIRABLE_TILES_IN_MEMORY;
// 1.2 Dynamic road prioritizing (heuristic) // 1.2 Dynamic road prioritizing (heuristic)
public boolean useDynamicRoadPrioritising = true; public boolean useDynamicRoadPrioritising = true;
@ -53,10 +54,10 @@ public class RoutingConfiguration {
private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>(); private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>();
private Map<String, String> attributes = new LinkedHashMap<String, String>(); private Map<String, String> attributes = new LinkedHashMap<String, String>();
public RoutingConfiguration build(String router, String... specialization) { public RoutingConfiguration build(String router, int memoryLimitMB, String... specialization) {
return build(router, null, specialization); return build(router, null, memoryLimitMB, specialization);
} }
public RoutingConfiguration build(String router, Double direction, String... specialization) { public RoutingConfiguration build(String router, Double direction, int memoryLimitMB, String... specialization) {
if (!routers.containsKey(router)) { if (!routers.containsKey(router)) {
router = defaultRouter; router = defaultRouter;
} }
@ -64,10 +65,15 @@ public class RoutingConfiguration {
i.initialDirection = direction; i.initialDirection = direction;
i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient); i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES); i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
i.ITERATIONS_TO_RUN_GC = parseSilentInt(getAttribute(router, "iterationsToRunGC"), i.ITERATIONS_TO_RUN_GC); int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = parseSilentInt(getAttribute(router, "desirableTilesInMemory"), if(desirable != 0) {
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY); i.memoryLimitation = desirable * (1 << 20);
} else {
if(memoryLimitMB == 0) {
memoryLimitMB = DEFAULT_MEMORY_LIMIT;
}
i.memoryLimitation = memoryLimitMB * (1 << 20);
}
i.useDynamicRoadPrioritising = parseSilentBoolean(getAttribute(router, "useDynamicRoadPrioritising"), i.useDynamicRoadPrioritising); i.useDynamicRoadPrioritising = parseSilentBoolean(getAttribute(router, "useDynamicRoadPrioritising"), i.useDynamicRoadPrioritising);
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy); i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance); i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);

File diff suppressed because it is too large Load diff

View file

@ -2,13 +2,15 @@
<osmand_routing_config defaultProfile="car"> <osmand_routing_config defaultProfile="car">
<!-- 1. parameters of routing and different tweaks Influence on A* : --> <!-- 1. parameters of routing and different tweaks Influence on A* : -->
<!-- f(x) + heuristicCoefficient*g(X) --> <!-- f(x) + heuristicCoefficient*g(X) -->
<attribute name="heuristicCoefficient" value="1.0" /> <!-- TEMPORARY needs to be reverted to 1 -->
<attribute name="heuristicCoefficient" value="" />
<!-- 1.1 tile load parameters (should not affect routing) --> <!-- 1.1 tile load parameters (should not affect routing) -->
<attribute name="zoomToLoadTiles" value="13" /> <!-- by default 16 -->
<attribute name="iterationsToRunGC" value="125" /> <attribute name="zoomToLoadTiles" value="16" />
<!-- by default it is 25 --> <!-- by default it is 30. Value specified here overwrites all others
<attribute name="desirableTilesInMemory" value="" /> (don't specify here ! it is device dependent) -->
<attribute name="memoryLimitInMB" value="" />
<!-- 1.2 Dynamic road prioritizing (heuristic) --> <!-- 1.2 Dynamic road prioritizing (heuristic) -->
<attribute name="useDynamicRoadPrioritising" value="true" /> <attribute name="useDynamicRoadPrioritising" value="true" />
@ -129,7 +131,6 @@
</avoid> </avoid>
</routingProfile> </routingProfile>
<routingProfile name="bicycle" baseProfile="bicycle" restrictionsAware="true" minDefaultSpeed="7" maxDefaultSpeed="16" <routingProfile name="bicycle" baseProfile="bicycle" restrictionsAware="true" minDefaultSpeed="7" maxDefaultSpeed="16"
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true"> leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
<!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> --> <!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> -->

View file

@ -119,12 +119,11 @@ public class MapClusterLayer implements MapPanelLayer {
rs.add(new BinaryMapIndexReader(raf)); rs.add(new BinaryMapIndexReader(raf));
} }
} }
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), BinaryRoutePlanner router = new BinaryRoutePlanner();
rs.toArray(new BinaryMapIndexReader[rs.size()]));
Builder builder = RoutingConfiguration.getDefault(); Builder builder = RoutingConfiguration.getDefault();
RoutingConfiguration config = builder.build("car"); RoutingConfiguration config = builder.build("car", RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3);
config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300; RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(),
RoutingContext ctx = new RoutingContext(config); rs.toArray(new BinaryMapIndexReader[rs.size()]));
// find closest way // find closest way
RouteSegment st = router.findRouteSegment(lat, lon, ctx); RouteSegment st = router.findRouteSegment(lat, lon, ctx);
if (st != null) { if (st != null) {
@ -174,7 +173,7 @@ public class MapClusterLayer implements MapPanelLayer {
} }
}); });
List<RouteSegment> results = searchCluster(ctx, st, router); List<RouteSegment> results = searchCluster(ctx, st);
return results; return results;
} }
@ -187,7 +186,7 @@ public class MapClusterLayer implements MapPanelLayer {
} }
private List<RouteSegment> searchCluster(RoutingContext ctx, RouteSegment st, BinaryRoutePlanner router) throws IOException { private List<RouteSegment> searchCluster(RoutingContext ctx, RouteSegment st) throws IOException {
Queue<List<RouteSegment>> queue = new LinkedList<List<RouteSegment>>(); Queue<List<RouteSegment>> queue = new LinkedList<List<RouteSegment>>();
List<RouteSegment> result = new ArrayList<BinaryRoutePlanner.RouteSegment>(); List<RouteSegment> result = new ArrayList<BinaryRoutePlanner.RouteSegment>();
TLongHashSet visitedIds = new TLongHashSet(); TLongHashSet visitedIds = new TLongHashSet();
@ -265,9 +264,7 @@ public class MapClusterLayer implements MapPanelLayer {
int x = road.getPoint31XTile(segmentEnd); int x = road.getPoint31XTile(segmentEnd);
int y = road.getPoint31YTile(segmentEnd); int y = road.getPoint31YTile(segmentEnd);
router.loadRoutes(ctx, x, y); RouteSegment next = ctx.loadRouteSegment(x, y, 0);
long l = (((long) x) << 31) + (long) y;
RouteSegment next = ctx.getRoutingTile(x, y).getSegment(l, ctx);
RouteSegment toAdd = segment; RouteSegment toAdd = segment;
if (!onTheMap.contains(toAdd.getRoad().getId())) { if (!onTheMap.contains(toAdd.getRoad().getId())) {
onTheMap.add(toAdd.getRoad().getId()); onTheMap.add(toAdd.getRoad().getId());

View file

@ -35,16 +35,20 @@ import net.osmand.data.DataTileManager;
import net.osmand.osm.Entity; import net.osmand.osm.Entity;
import net.osmand.osm.LatLon; import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils; import net.osmand.osm.MapUtils;
import net.osmand.osm.Way;
import net.osmand.osm.OSMSettings.OSMTagKey; import net.osmand.osm.OSMSettings.OSMTagKey;
import net.osmand.osm.Way;
import net.osmand.router.BinaryRoutePlanner; import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration; import net.osmand.router.RoutingConfiguration;
import net.osmand.router.RoutingConfiguration.Builder; import net.osmand.router.RoutingConfiguration.Builder;
import net.osmand.router.RoutingContext; import net.osmand.router.RoutingContext;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
import org.apache.commons.logging.Log;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
@ -52,11 +56,6 @@ import org.w3c.dom.NodeList;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.apache.commons.logging.Log;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class MapRouterLayer implements MapPanelLayer { public class MapRouterLayer implements MapPanelLayer {
@ -305,20 +304,6 @@ public class MapRouterLayer implements MapPanelLayer {
} }
// for vector rendering we should extract from osm
// 1. Ways (different kinds) with tag highway= ?,highway=stop ...
// 2. Junction = roundabout
// 3. barrier, traffic_calming=bump
// 4. Save {name, ref} of way to unify it
// + for future routing we should extract from osm
// 1. oneway
// 2. max_speed
// 3. toll
// 4. traffic_signals
// 5. max_heigtht, max_width, min_speed, ...
// 6. incline ?
public static List<Way> route_YOURS(LatLon start, LatLon end){ public static List<Way> route_YOURS(LatLon start, LatLon end){
List<Way> res = new ArrayList<Way>(); List<Way> res = new ArrayList<Way>();
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
@ -625,11 +610,11 @@ public class MapRouterLayer implements MapPanelLayer {
} }
String m = DataExtractionSettings.getSettings().getRouteMode(); String m = DataExtractionSettings.getSettings().getRouteMode();
String[] props = m.split("\\,"); String[] props = m.split("\\,");
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs); BinaryRoutePlanner router = new BinaryRoutePlanner();
RoutingConfiguration config = builder.build(props[0], props); RoutingConfiguration config = builder.build(props[0], RoutingConfiguration.DEFAULT_MEMORY_LIMIT / 2, props);
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300; // config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
// config.ZOOM_TO_LOAD_TILES = 14; // config.ZOOM_TO_LOAD_TILES = 14;
RoutingContext ctx = new RoutingContext(config); RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(), rs);
ctx.previouslyCalculatedRoute = previousRoute; ctx.previouslyCalculatedRoute = previousRoute;
log.info("Use " + config.routerName + "mode for routing"); log.info("Use " + config.routerName + "mode for routing");
@ -638,13 +623,13 @@ public class MapRouterLayer implements MapPanelLayer {
if (st == null) { if (st == null) {
throw new RuntimeException("Starting point for route not found"); throw new RuntimeException("Starting point for route not found");
} }
System.out.println("ROAD TO START " + st.getRoad().getHighway() + " " + st.getRoad().id); log.info("Start road " + st.getRoad().getHighway() + " " + st.getRoad().id);
RouteSegment e = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx); RouteSegment e = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx);
if (e == null) { if (e == null) {
throw new RuntimeException("End point to calculate route was not found"); throw new RuntimeException("End point to calculate route was not found");
} }
System.out.println("ROAD TO END " + e.getRoad().getHighway() + " " + e.getRoad().id); log.info("End road " + e.getRoad().getHighway() + " " + e.getRoad().id);
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>(); List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
if (intermediates != null) { if (intermediates != null) {
@ -763,6 +748,8 @@ public class MapRouterLayer implements MapPanelLayer {
} }
} catch (IOException e) { } catch (IOException e) {
ExceptionHandler.handle(e); ExceptionHandler.handle(e);
} catch (InterruptedException e) {
ExceptionHandler.handle(e);
} finally { } finally {
playPauseButton.setVisible(false); playPauseButton.setVisible(false);
nextTurn.setVisible(false); nextTurn.setVisible(false);

View file

@ -11,6 +11,8 @@
<ToggleButton android:contentDescription="@string/app_mode_pedestrian" android:textOn="" android:textOff="" android:id="@+id/PedestrianButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:background="@drawable/pedestrian_icon"/> <ToggleButton android:contentDescription="@string/app_mode_pedestrian" android:textOn="" android:textOff="" android:id="@+id/PedestrianButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:background="@drawable/pedestrian_icon"/>
</LinearLayout> </LinearLayout>
<CheckBox android:id="@+id/OptimalCheckox" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/non_optimal_route_calculation"/>
</LinearLayout> </LinearLayout>

View file

@ -1,5 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<resources><string name="download_link_and_local_description">Загрузите или обновите локальные данные. <resources>
<string name="non_optimal_route_calculation">Рассчитать неоптимальный (возможно) маршрут на длинные дистанции</string>
<string name="download_link_and_local_description">Загрузите или обновите локальные данные.
\nЧтобы получить дополнительную информацию о карте, выделите её в списке. Удерживайте карту, если вы хотите удалить или деактивировать. \nЧтобы получить дополнительную информацию о карте, выделите её в списке. Удерживайте карту, если вы хотите удалить или деактивировать.
\nДанные на устройстве (%1$s свободно):</string> \nДанные на устройстве (%1$s свободно):</string>
<string name="tip_recent_changes_0_8_3_t">"Изменения в 0.8.3: <string name="tip_recent_changes_0_8_3_t">"Изменения в 0.8.3:
@ -735,7 +737,7 @@
<string name="navigate_point_format_D">ГГГ.ГГГГ</string> <string name="navigate_point_format_D">ГГГ.ГГГГ</string>
<string name="navigate_point_format_DM">ГГГ ММ.МММММ</string> <string name="navigate_point_format_DM">ГГГ ММ.МММММ</string>
<string name="navigate_point_format_DMS">ГГГ ММ СС.ССССС</string> <string name="navigate_point_format_DMS">ГГГ ММ СС.ССССС</string>
<string name="search_shown_on_map">Отобразить на карте</string> <string name="search_shown_on_map">Показать</string>
<string name="navigate_point_cancel">Отмена</string> <string name="navigate_point_cancel">Отмена</string>
<string name="search_address_top_text">Выберите адрес</string> <string name="search_address_top_text">Выберите адрес</string>
<string name="search_address_region">Регион</string> <string name="search_address_region">Регион</string>

View file

@ -9,7 +9,10 @@
1. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 1. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="enable_plugin_monitoring_services">Enable monitoring plugins (tracking, live tracking) to use monitoring services </string>
<string name="non_optimal_route_calculation">Calculate possibly non-optimal route over long distances</string>
<string name="tip_recent_changes_0_8_4_t">Changes in 0.8.4 : <string name="tip_recent_changes_0_8_4_t">Changes in 0.8.4 :
Updated
</string> </string>
<string name="gps_not_available">Please enable GPS in the settings</string> <string name="gps_not_available">Please enable GPS in the settings</string>
<string name="tip_recent_changes_0_8_3_t">Changes in 0.8.3 : <string name="tip_recent_changes_0_8_3_t">Changes in 0.8.3 :

View file

@ -59,6 +59,8 @@ public class OsmandSettings {
boolean set(T obj); boolean set(T obj);
boolean setModeValue(ApplicationMode m, T obj);
T getModeValue(ApplicationMode m); T getModeValue(ApplicationMode m);
String getId(); String getId();
@ -144,6 +146,11 @@ public class OsmandSettings {
public ApplicationMode getModeValue(ApplicationMode m) { public ApplicationMode getModeValue(ApplicationMode m) {
return m; return m;
} }
@Override
public boolean setModeValue(ApplicationMode m, ApplicationMode obj) {
throw new UnsupportedOperationException();
}
}; };
public ApplicationMode getApplicationMode(){ public ApplicationMode getApplicationMode(){
@ -241,6 +248,14 @@ public class OsmandSettings {
defaultValues.put(mode, defValue); defaultValues.put(mode, defValue);
} }
@Override
public boolean setModeValue(ApplicationMode mode, T obj){
if(global) {
return set(obj);
}
return setValue(getProfilePreferences(mode), obj);
}
public T getProfileDefaultValue(){ public T getProfileDefaultValue(){
if(global){ if(global){
return defaultValue; return defaultValue;
@ -596,6 +611,10 @@ public class OsmandSettings {
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<Boolean> FAST_ROUTE_MODE = new BooleanPreference("fast_route_mode", true).makeProfile(); public final OsmandPreference<Boolean> FAST_ROUTE_MODE = new BooleanPreference("fast_route_mode", true).makeProfile();
public final CommonPreference<Boolean> OPTIMAL_ROUTE_MODE = new BooleanPreference("optimal_route_mode", true).makeProfile();
{
OPTIMAL_ROUTE_MODE.setModeDefaultValue(ApplicationMode.PEDESTRIAN, false);
}
public final OsmandPreference<Boolean> SHOW_SPEED_LIMITS = new BooleanPreference("show_speed_limits", true).makeGlobal().cache(); public final OsmandPreference<Boolean> SHOW_SPEED_LIMITS = new BooleanPreference("show_speed_limits", true).makeGlobal().cache();
public final OsmandPreference<Boolean> SHOW_CAMERAS = new BooleanPreference("show_cameras", true).makeGlobal().cache(); public final OsmandPreference<Boolean> SHOW_CAMERAS = new BooleanPreference("show_cameras", true).makeGlobal().cache();

View file

@ -134,7 +134,7 @@ public class MainMenuActivity extends Activity {
SharedPreferences prefs = activity.getApplicationContext().getSharedPreferences("net.osmand.settings", MODE_WORLD_READABLE); SharedPreferences prefs = activity.getApplicationContext().getSharedPreferences("net.osmand.settings", MODE_WORLD_READABLE);
// only one commit should be with contribution version flag // only one commit should be with contribution version flag
// prefs.edit().putBoolean(CONTRIBUTION_VERSION_FLAG, true).commit(); prefs.edit().putBoolean(CONTRIBUTION_VERSION_FLAG, true).commit();
if (prefs.contains(CONTRIBUTION_VERSION_FLAG)) { if (prefs.contains(CONTRIBUTION_VERSION_FLAG)) {
SpannableString content = new SpannableString(textVersion); SpannableString content = new SpannableString(textVersion);
content.setSpan(new ClickableSpan() { content.setSpan(new ClickableSpan() {

View file

@ -292,7 +292,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
Object toShow = settings.getAndClearObjectToShow(); Object toShow = settings.getAndClearObjectToShow();
if(settings.isRouteToPointNavigateAndClear()){ if(settings.isRouteToPointNavigateAndClear()){
// always enable and follow and let calculate it (GPS is not accessible in garage) // always enable and follow and let calculate it (GPS is not accessible in garage)
mapActions.getDirections(getLastKnownLocation(), false); mapActions.getDirections(null, null, false);
} }
if(mapLabelToShow != null && latLonToShow != null){ if(mapLabelToShow != null && latLonToShow != null){
mapLayers.getContextMenuLayer().setSelectedObject(toShow); mapLayers.getContextMenuLayer().setSelectedObject(toShow);

View file

@ -407,13 +407,14 @@ public class MapActivityActions implements DialogProvider {
} }
public void getDirections(final Location from, boolean gpxRouteEnabled) { public void getDirections(final Location fromOrCurrent, final LatLon to, boolean gpxRouteEnabled) {
final RoutingHelper routingHelper = mapActivity.getRoutingHelper(); final RoutingHelper routingHelper = mapActivity.getRoutingHelper();
Builder builder = new AlertDialog.Builder(mapActivity); Builder builder = new AlertDialog.Builder(mapActivity);
View view = mapActivity.getLayoutInflater().inflate(R.layout.calculate_route, null); View view = mapActivity.getLayoutInflater().inflate(R.layout.calculate_route, null);
final CheckBox nonoptimal = (CheckBox) view.findViewById(R.id.OptimalCheckox);
final ToggleButton[] buttons = new ToggleButton[ApplicationMode.values().length]; final ToggleButton[] buttons = new ToggleButton[ApplicationMode.values().length];
buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton); buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton);
buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton); buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton);
@ -426,11 +427,16 @@ public class MapActivityActions implements DialogProvider {
if (buttons[i] != null) { if (buttons[i] != null) {
final int ind = i; final int ind = i;
ToggleButton b = buttons[i]; ToggleButton b = buttons[i];
b.setChecked(appMode == ApplicationMode.values()[i]); final ApplicationMode buttonAppMode = ApplicationMode.values()[i];
b.setChecked(appMode == buttonAppMode);
if(b.isChecked()) {
nonoptimal.setChecked(!settings.OPTIMAL_ROUTE_MODE.getModeValue(buttonAppMode));
}
b.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { b.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) { if (isChecked) {
nonoptimal.setChecked(!settings.OPTIMAL_ROUTE_MODE.getModeValue(buttonAppMode));
for (int j = 0; j < buttons.length; j++) { for (int j = 0; j < buttons.length; j++) {
if (buttons[j] != null) { if (buttons[j] != null) {
if (buttons[j].isChecked() != (ind == j)) { if (buttons[j].isChecked() != (ind == j)) {
@ -461,15 +467,23 @@ public class MapActivityActions implements DialogProvider {
DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener() { DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if(to != null) {
mapActivity.navigateToPoint(to, false, -1);
}
if (!checkPointToNavigate()) { if (!checkPointToNavigate()) {
return; return;
} }
Location from = fromOrCurrent;
if(from == null) {
from = mapActivity.getLastKnownLocation();
}
if (from == null) { if (from == null) {
AccessibleToast.makeText(mapActivity, R.string.unknown_from_location, Toast.LENGTH_LONG).show(); AccessibleToast.makeText(mapActivity, R.string.unknown_from_location, Toast.LENGTH_LONG).show();
return; return;
} }
ApplicationMode mode = getAppMode(buttons, settings); ApplicationMode mode = getAppMode(buttons, settings);
routingHelper.setAppMode(mode); routingHelper.setAppMode(mode);
settings.OPTIMAL_ROUTE_MODE.setModeValue(mode, !nonoptimal.isChecked());
settings.FOLLOW_THE_ROUTE.set(false); settings.FOLLOW_THE_ROUTE.set(false);
settings.FOLLOW_THE_GPX_ROUTE.set(null); settings.FOLLOW_THE_GPX_ROUTE.set(null);
routingHelper.setFollowingMode(false); routingHelper.setFollowingMode(false);
@ -481,12 +495,19 @@ public class MapActivityActions implements DialogProvider {
DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener() { DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if(to != null) {
mapActivity.navigateToPoint(to, false, -1);
}
if (!checkPointToNavigate()) { if (!checkPointToNavigate()) {
return; return;
} }
boolean msg = true; boolean msg = true;
Location current = from; Location current = fromOrCurrent;
if (!mapActivity.isPointAccurateForRouting(from)) { if(current == null) {
current = mapActivity.getLastKnownLocation();
}
if (!mapActivity.isPointAccurateForRouting(current)) {
current = null; current = null;
} }
Location lastKnownLocation = mapActivity.getLastKnownLocation(); Location lastKnownLocation = mapActivity.getLastKnownLocation();
@ -507,6 +528,9 @@ public class MapActivityActions implements DialogProvider {
DialogInterface.OnClickListener useGpxNavigation = new DialogInterface.OnClickListener() { DialogInterface.OnClickListener useGpxNavigation = new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if(to != null) {
mapActivity.navigateToPoint(to, false, -1);
}
ApplicationMode mode = getAppMode(buttons, settings); ApplicationMode mode = getAppMode(buttons, settings);
navigateUsingGPX(mode); navigateUsingGPX(mode);
} }
@ -734,16 +758,14 @@ public class MapActivityActions implements DialogProvider {
} else if (standardId == R.string.context_menu_item_navigate_point) { } else if (standardId == R.string.context_menu_item_navigate_point) {
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, -1); mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, -1);
} else if (standardId == R.string.context_menu_item_directions) { } else if (standardId == R.string.context_menu_item_directions) {
Location loc = mapActivity.getLastKnownLocation();
mapActivity.navigateToPoint(new LatLon(latitude, longitude), false, -1);
// always enable and follow and let calculate it (GPS is not accessible in garage) // always enable and follow and let calculate it (GPS is not accessible in garage)
getDirections(loc, true); getDirections(null, new LatLon(latitude, longitude), true);
} else if (standardId == R.string.context_menu_item_show_route) { } else if (standardId == R.string.context_menu_item_show_route) {
if (checkPointToNavigate()) { if (checkPointToNavigate()) {
Location loc = new Location("map"); Location loc = new Location("map");
loc.setLatitude(latitude); loc.setLatitude(latitude);
loc.setLongitude(longitude); loc.setLongitude(longitude);
getDirections(loc, true); getDirections(loc, null, true);
} }
} else if (standardId == R.string.context_menu_item_intermediate_point) { } else if (standardId == R.string.context_menu_item_intermediate_point) {
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, mapActivity.getIntermediatePoints().size()); mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, mapActivity.getIntermediatePoints().size());
@ -957,8 +979,7 @@ public class MapActivityActions implements DialogProvider {
if (routingHelper.isRouteCalculated()) { if (routingHelper.isRouteCalculated()) {
aboutRoute(); aboutRoute();
} else { } else {
Location loc = mapActivity.getLastKnownLocation(); getDirections(null, null, true);
getDirections(loc, true);
} }
return true; return true;
} }

View file

@ -11,10 +11,8 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams; import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.location.Location; import android.location.Location;
import android.location.LocationManager;
import android.view.View; import android.view.View;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;

View file

@ -0,0 +1,28 @@
package net.osmand.plus.routing;
import java.util.List;
import net.osmand.osm.LatLon;
import net.osmand.plus.activities.ApplicationMode;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.router.Interruptable;
import android.content.Context;
import android.location.Location;
public class RouteCalcuationParams {
public Location start;
public LatLon end;
public List<LatLon> intermediates;
public Context ctx;
public ApplicationMode mode;
public RouteService type;
public GPXRouteParams gpxRoute;
public RouteCalculationResult previousToRecalculate;
public boolean fast;
public boolean optimal;
public boolean leftSide;
public Interruptable interruptable;
}

View file

@ -39,7 +39,6 @@ import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.BinaryRoutePlanner.RouteSegment; import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
import net.osmand.router.GeneralRouter.GeneralRouterProfile; import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.Interruptable;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration; import net.osmand.router.RoutingConfiguration;
import net.osmand.router.RoutingContext; import net.osmand.router.RoutingContext;
@ -147,29 +146,25 @@ public class RouteProvider {
public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, List<LatLon> intermediates, ApplicationMode mode, RouteService type, Context ctx, public RouteCalculationResult calculateRouteImpl(RouteCalcuationParams params){
GPXRouteParams gpxRoute, RouteCalculationResult previousToRecalculate, boolean fast, boolean leftSide, Interruptable interruptable){
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
if (start != null && end != null) { if (params.start != null && params.end != null) {
if(log.isInfoEnabled()){ if(log.isInfoEnabled()){
log.info("Start finding route from " + start + " to " + end +" using " + type.getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ log.info("Start finding route from " + params.start + " to " + params.end +" using " +
params.type.getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} }
try { try {
RouteCalculationResult res; RouteCalculationResult res;
if(gpxRoute != null && !gpxRoute.points.isEmpty()){ if(params.gpxRoute != null && !params.gpxRoute.points.isEmpty()){
res = calculateGpxRoute(start, end, gpxRoute, ctx, leftSide); res = calculateGpxRoute(params);
} else if (type == RouteService.YOURS) { } else if (params.type == RouteService.YOURS) {
res = findYOURSRoute(start, end, mode, fast, ctx, leftSide); res = findYOURSRoute(params);
} else if (type == RouteService.ORS) { } else if (params.type == RouteService.ORS) {
res = findORSRoute(start, end, mode, fast, ctx, leftSide); res = findORSRoute(params);
} else if (type == RouteService.OSMAND) { } else if (params.type == RouteService.OSMAND) {
List<RouteSegmentResult> originalRoute = null; res = findVectorMapsRoute(params);
if(previousToRecalculate != null) {
originalRoute = previousToRecalculate.getOriginalRoute();
}
res = findVectorMapsRoute(start, end, intermediates, mode, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide, interruptable);
} else { } else {
res = findCloudMadeRoute(start, end, intermediates, mode, ctx, fast, leftSide); res = findCloudMadeRoute(params);
} }
if(log.isInfoEnabled() ){ if(log.isInfoEnabled() ){
log.info("Finding route contained " + res.getImmutableLocations().size() + " points for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ log.info("Finding route contained " + res.getImmutableLocations().size() + " points for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@ -186,27 +181,29 @@ public class RouteProvider {
return new RouteCalculationResult(null); return new RouteCalculationResult(null);
} }
private RouteCalculationResult calculateGpxRoute(Location start, LatLon end, GPXRouteParams params, Context ctx, boolean leftSide) {
private RouteCalculationResult calculateGpxRoute(RouteCalcuationParams pars) {
RouteCalculationResult res; RouteCalculationResult res;
// get the closest point to start and to end // get the closest point to start and to end
float minDist = Integer.MAX_VALUE; float minDist = Integer.MAX_VALUE;
int startI = 0; int startI = 0;
GPXRouteParams params = pars.gpxRoute;
List<Location> gpxRoute = params.points; List<Location> gpxRoute = params.points;
int endI = gpxRoute.size(); int endI = gpxRoute.size();
if (start != null) { if (pars.start != null) {
for (int i = 0; i < gpxRoute.size(); i++) { for (int i = 0; i < gpxRoute.size(); i++) {
float d = gpxRoute.get(i).distanceTo(start); float d = gpxRoute.get(i).distanceTo(pars.start);
if (d < minDist) { if (d < minDist) {
startI = i; startI = i;
minDist = d; minDist = d;
} }
} }
} else { } else {
start = gpxRoute.get(0); pars.start = gpxRoute.get(0);
} }
Location l = new Location("temp"); //$NON-NLS-1$ Location l = new Location("temp"); //$NON-NLS-1$
l.setLatitude(end.getLatitude()); l.setLatitude(pars.end.getLatitude());
l.setLongitude(end.getLongitude()); l.setLongitude(pars.end.getLongitude());
minDist = Integer.MAX_VALUE; minDist = Integer.MAX_VALUE;
// get in reverse order taking into account ways with cycle // get in reverse order taking into account ways with cycle
for (int i = gpxRoute.size() - 1; i >= startI; i--) { for (int i = gpxRoute.size() - 1; i >= startI; i--) {
@ -219,7 +216,8 @@ public class RouteProvider {
} }
ArrayList<Location> sublist = new ArrayList<Location>(gpxRoute.subList(startI, endI)); ArrayList<Location> sublist = new ArrayList<Location>(gpxRoute.subList(startI, endI));
if(params.directions == null){ if(params.directions == null){
res = new RouteCalculationResult(sublist, params.directions, start, end, null, null, ctx, leftSide, true); res = new RouteCalculationResult(sublist, params.directions, pars.start, pars.end, null, null,
pars.ctx, pars.leftSide, true);
} else { } else {
List<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>(); List<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>();
for (RouteDirectionInfo info : params.directions) { for (RouteDirectionInfo info : params.directions) {
@ -234,7 +232,8 @@ public class RouteProvider {
subdirections.add(ch); subdirections.add(ch);
} }
} }
res = new RouteCalculationResult(sublist, subdirections, start, end, null, null, ctx, leftSide, true); res = new RouteCalculationResult(sublist, subdirections, pars.start, pars.end, null, null,
pars.ctx, pars.leftSide, true);
} }
return res; return res;
} }
@ -249,23 +248,23 @@ public class RouteProvider {
protected RouteCalculationResult findYOURSRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, Context ctx, boolean leftSide) throws MalformedURLException, IOException, protected RouteCalculationResult findYOURSRoute(RouteCalcuationParams params) throws MalformedURLException, IOException,
ParserConfigurationException, FactoryConfigurationError, SAXException { ParserConfigurationException, FactoryConfigurationError, SAXException {
List<Location> res = new ArrayList<Location>(); List<Location> res = new ArrayList<Location>();
StringBuilder uri = new StringBuilder(); StringBuilder uri = new StringBuilder();
uri.append("http://www.yournavigation.org/api/1.0/gosmore.php?format=kml"); //$NON-NLS-1$ uri.append("http://www.yournavigation.org/api/1.0/gosmore.php?format=kml"); //$NON-NLS-1$
uri.append("&flat=").append(start.getLatitude()); //$NON-NLS-1$ uri.append("&flat=").append(params.start.getLatitude()); //$NON-NLS-1$
uri.append("&flon=").append(start.getLongitude()); //$NON-NLS-1$ uri.append("&flon=").append(params.start.getLongitude()); //$NON-NLS-1$
uri.append("&tlat=").append(end.getLatitude()); //$NON-NLS-1$ uri.append("&tlat=").append(params.end.getLatitude()); //$NON-NLS-1$
uri.append("&tlon=").append(end.getLongitude()); //$NON-NLS-1$ uri.append("&tlon=").append(params.end.getLongitude()); //$NON-NLS-1$
if(ApplicationMode.PEDESTRIAN == mode){ if(ApplicationMode.PEDESTRIAN == params.mode){
uri.append("&v=foot") ; //$NON-NLS-1$ uri.append("&v=foot") ; //$NON-NLS-1$
} else if(ApplicationMode.BICYCLE == mode){ } else if(ApplicationMode.BICYCLE == params.mode){
uri.append("&v=bicycle") ; //$NON-NLS-1$ uri.append("&v=bicycle") ; //$NON-NLS-1$
} else { } else {
uri.append("&v=motorcar"); //$NON-NLS-1$ uri.append("&v=motorcar"); //$NON-NLS-1$
} }
uri.append("&fast=").append(fast ? "1" : "0").append("&layer=mapnik"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ uri.append("&fast=").append(params.fast ? "1" : "0").append("&layer=mapnik"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
log.info("URL route " + uri); log.info("URL route " + uri);
URL url = new URL(uri.toString()); URL url = new URL(uri.toString());
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
@ -304,14 +303,14 @@ public class RouteProvider {
} }
} }
return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true); return new RouteCalculationResult(res, null, params.start, params.end, null, null,
params.ctx, params.leftSide, true);
} }
protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, List<LatLon> intermediates, ApplicationMode mode, OsmandApplication app, protected RouteCalculationResult findVectorMapsRoute(RouteCalcuationParams params) throws IOException {
List<RouteSegmentResult> previousRoute, OsmandApplication app = (OsmandApplication) params.ctx.getApplicationContext();
boolean leftSide, Interruptable interruptable) throws IOException {
BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles(); BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles();
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeOsmandLibrary.getLoadedLibrary(), files); BinaryRoutePlanner router = new BinaryRoutePlanner();
File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML); File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML);
RoutingConfiguration.Builder config ; RoutingConfiguration.Builder config ;
if (routingXml.exists() && routingXml.canRead()) { if (routingXml.exists() && routingXml.canRead()) {
@ -325,9 +324,9 @@ public class RouteProvider {
} }
GeneralRouterProfile p ; GeneralRouterProfile p ;
if (mode == ApplicationMode.BICYCLE) { if (params.mode == ApplicationMode.BICYCLE) {
p = GeneralRouterProfile.BICYCLE; p = GeneralRouterProfile.BICYCLE;
} else if (mode == ApplicationMode.PEDESTRIAN) { } else if (params.mode == ApplicationMode.PEDESTRIAN) {
p = GeneralRouterProfile.PEDESTRIAN; p = GeneralRouterProfile.PEDESTRIAN;
} else { } else {
p = GeneralRouterProfile.CAR; p = GeneralRouterProfile.CAR;
@ -349,21 +348,36 @@ public class RouteProvider {
specs.add(GeneralRouter.AVOID_UNPAVED); specs.add(GeneralRouter.AVOID_UNPAVED);
} }
String[] specialization = specs.toArray(new String[specs.size()]); String[] specialization = specs.toArray(new String[specs.size()]);
RoutingContext ctx = new RoutingContext(config.build(p.name().toLowerCase(), start.hasBearing() ? start.getBearing() / 180d * Math.PI : null, specialization)); float mb = (1 << 20);
ctx.interruptable = interruptable; Runtime rt = Runtime.getRuntime();
ctx.previouslyCalculatedRoute = previousRoute; // make visible
RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx); int memoryLimit = (int) (0.95 * ((rt.maxMemory() - rt.totalMemory()) + rt.freeMemory()) / mb);
log.warn("Use " + memoryLimit + " MB Free " + rt.freeMemory() / mb + " of " + rt.totalMemory() / mb + " max " + rt.maxMemory() / mb);
RoutingConfiguration cf = config.build(p.name().toLowerCase(), params.start.hasBearing() ?
params.start.getBearing() / 180d * Math.PI : null,
memoryLimit, specialization);
if(!params.optimal){
cf.heuristicCoefficient *= 1.5;
}
RoutingContext ctx = new RoutingContext(cf, NativeOsmandLibrary.getLoadedLibrary(), files);
ctx.interruptable = params.interruptable;
if(params.previousToRecalculate != null) {
ctx.previouslyCalculatedRoute = params.previousToRecalculate.getOriginalRoute();
}
RouteSegment st= router.findRouteSegment(params.start.getLatitude(), params.start.getLongitude(), ctx);
if (st == null) { if (st == null) {
return new RouteCalculationResult(app.getString(R.string.starting_point_too_far)); return new RouteCalculationResult(app.getString(R.string.starting_point_too_far));
} }
RouteSegment en = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx); RouteSegment en = router.findRouteSegment(params.end.getLatitude(),
params.end.getLongitude(), ctx);
if (en == null) { if (en == null) {
return new RouteCalculationResult(app.getString(R.string.ending_point_too_far)); return new RouteCalculationResult(app.getString(R.string.ending_point_too_far));
} }
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>(); List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
if (intermediates != null) { if (params.intermediates != null) {
int ind = 1; int ind = 1;
for (LatLon il : intermediates) { for (LatLon il : params.intermediates) {
RouteSegment is = router.findRouteSegment(il.getLatitude(), il.getLongitude(), ctx); RouteSegment is = router.findRouteSegment(il.getLatitude(), il.getLongitude(), ctx);
if (is == null) { if (is == null) {
return new RouteCalculationResult(app.getString(R.string.intermediate_point_too_far, "'" + ind + "'")); return new RouteCalculationResult(app.getString(R.string.intermediate_point_too_far, "'" + ind + "'"));
@ -375,16 +389,19 @@ public class RouteProvider {
try { try {
List<RouteSegmentResult> result; List<RouteSegmentResult> result;
if(inters.size() > 0){ if(inters.size() > 0){
result = router.searchRoute(ctx, st, en, inters, leftSide); result = router.searchRoute(ctx, st, en, inters, params.leftSide);
} else { } else {
result = router.searchRoute(ctx, st, en, leftSide); result = router.searchRoute(ctx, st, en, params.leftSide);
} }
if(result == null || result.isEmpty()) { if(result == null || result.isEmpty()) {
// something really strange better to see that message on the scren // something really strange better to see that message on the scren
return new RouteCalculationResult("Empty result"); return new RouteCalculationResult("Empty result");
} else { } else {
return new RouteCalculationResult(result, start, end, intermediates, app, leftSide); return new RouteCalculationResult(result, params.start, params.end,
params.intermediates, app, params.leftSide);
} }
} catch (InterruptedException e) {
return new RouteCalculationResult("Route calculation was interrupted");
} catch (OutOfMemoryError e) { } catch (OutOfMemoryError e) {
// ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE); // ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE);
// ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); // ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
@ -398,19 +415,19 @@ public class RouteProvider {
} }
protected RouteCalculationResult findCloudMadeRoute(Location start, LatLon end, List<LatLon> intermediates, ApplicationMode mode, Context ctx, boolean fast, boolean leftSide) protected RouteCalculationResult findCloudMadeRoute(RouteCalcuationParams params)
throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException {
List<Location> res = new ArrayList<Location>(); List<Location> res = new ArrayList<Location>();
List<RouteDirectionInfo> directions = null; List<RouteDirectionInfo> directions = null;
StringBuilder uri = new StringBuilder(); StringBuilder uri = new StringBuilder();
// possibly hide that API key because it is privacy of osmand // possibly hide that API key because it is privacy of osmand
uri.append("http://routes.cloudmade.com/A6421860EBB04234AB5EF2D049F2CD8F/api/0.3/"); //$NON-NLS-1$ uri.append("http://routes.cloudmade.com/A6421860EBB04234AB5EF2D049F2CD8F/api/0.3/"); //$NON-NLS-1$
uri.append(start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ uri.append(params.start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
uri.append(start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ uri.append(params.start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
if(intermediates != null && intermediates.size() > 0) { if(params.intermediates != null && params.intermediates.size() > 0) {
uri.append("["); uri.append("[");
boolean first = true; boolean first = true;
for(LatLon il : intermediates) { for(LatLon il : params.intermediates) {
if(!first){ if(!first){
uri.append(","); uri.append(",");
} else { } else {
@ -421,18 +438,18 @@ public class RouteProvider {
} }
uri.append("],"); uri.append("],");
} }
uri.append(end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$ uri.append(params.end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$
uri.append(end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$ uri.append(params.end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$
float speed = 1.5f; float speed = 1.5f;
if (ApplicationMode.PEDESTRIAN == mode) { if (ApplicationMode.PEDESTRIAN == params.mode) {
uri.append("foot.gpx"); //$NON-NLS-1$ uri.append("foot.gpx"); //$NON-NLS-1$
} else if (ApplicationMode.BICYCLE == mode) { } else if (ApplicationMode.BICYCLE == params.mode) {
speed = 5.5f; speed = 5.5f;
uri.append("bicycle.gpx"); //$NON-NLS-1$ uri.append("bicycle.gpx"); //$NON-NLS-1$
} else { } else {
speed = 15.3f; speed = 15.3f;
if (fast) { if (params.fast) {
uri.append("car.gpx"); //$NON-NLS-1$ uri.append("car.gpx"); //$NON-NLS-1$
} else { } else {
uri.append("car/shortest.gpx"); //$NON-NLS-1$ uri.append("car/shortest.gpx"); //$NON-NLS-1$
@ -442,10 +459,11 @@ public class RouteProvider {
log.info("URL route " + uri); log.info("URL route " + uri);
URL url = new URL(uri.toString()); URL url = new URL(uri.toString());
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
GPXFile gpxFile = GPXUtilities.loadGPXFile(ctx, connection.getInputStream(), false); GPXFile gpxFile = GPXUtilities.loadGPXFile(params.ctx, connection.getInputStream(), false);
directions = parseCloudmadeRoute(res, gpxFile, false, leftSide, speed); directions = parseCloudmadeRoute(res, gpxFile, false, params.leftSide, speed);
return new RouteCalculationResult(res, directions, start, end, intermediates, null, ctx, leftSide, true); return new RouteCalculationResult(res, directions, params.start, params.end, params.intermediates,
null, params.ctx, params.leftSide, true);
} }
private static List<RouteDirectionInfo> parseCloudmadeRoute(List<Location> res, GPXFile gpxFile, boolean osmandRouter, private static List<RouteDirectionInfo> parseCloudmadeRoute(List<Location> res, GPXFile gpxFile, boolean osmandRouter,
@ -564,15 +582,14 @@ public class RouteProvider {
return directions; return directions;
} }
protected RouteCalculationResult findORSRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, Context ctx, protected RouteCalculationResult findORSRoute(RouteCalcuationParams params) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError,
boolean leftSide) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError,
SAXException { SAXException {
List<Location> res = new ArrayList<Location>(); List<Location> res = new ArrayList<Location>();
String rpref = "Fastest"; String rpref = "Fastest";
if (ApplicationMode.PEDESTRIAN == mode) { if (ApplicationMode.PEDESTRIAN == params.mode) {
rpref = "Pedestrian"; rpref = "Pedestrian";
} else if (ApplicationMode.BICYCLE == mode) { } else if (ApplicationMode.BICYCLE == params.mode) {
rpref = "Bicycle"; rpref = "Bicycle";
// } else if (ApplicationMode.LOWTRAFFIC == mode) { // } else if (ApplicationMode.LOWTRAFFIC == mode) {
// rpref = "BicycleSafety"; // rpref = "BicycleSafety";
@ -582,13 +599,13 @@ public class RouteProvider {
// rpref = "BicycleRoute"; // rpref = "BicycleRoute";
// } else if (ApplicationMode.MTBIKE == mode) { // } else if (ApplicationMode.MTBIKE == mode) {
// rpref = "BicycleMTB"; // rpref = "BicycleMTB";
} else if (!fast) { } else if (!params.fast) {
rpref = "Shortest"; rpref = "Shortest";
} }
StringBuilder request = new StringBuilder(); StringBuilder request = new StringBuilder();
request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(start.getLongitude()).append(',') request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(params.start.getLongitude()).append(',')
.append(start.getLatitude()).append("&end=").append(end.getLongitude()).append(',').append(end.getLatitude()) .append(params.start.getLatitude()).append("&end=").append(params.end.getLongitude()).append(',').append(params.end.getLatitude())
.append("&preference=").append(rpref); .append("&preference=").append(rpref);
// TODO if we would get instructions from the service, we could use this language setting // TODO if we would get instructions from the service, we could use this language setting
// .append("&language=").append(Locale.getDefault().getLanguage()); // .append("&language=").append(Locale.getDefault().getLanguage());
@ -624,7 +641,7 @@ public class RouteProvider {
} }
} }
return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true); return new RouteCalculationResult(res, null, params.start, params.end, null, null, params.ctx, params.leftSide, true);
} }
public GPXFile createOsmandRouterGPX(RouteCalculationResult srcRoute){ public GPXFile createOsmandRouterGPX(RouteCalculationResult srcRoute){

View file

@ -254,8 +254,8 @@ public class RoutingHelper {
} }
if (calculateRoute) { if (calculateRoute) {
recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, route.isCalculated() ? route
route.isCalculated()? route : null); : null);
} }
double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2; double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2;
if(returnUpdatedLocation && locationProjection != null && currentLocation.distanceTo(locationProjection) < projectDist) { if(returnUpdatedLocation && locationProjection != null && currentLocation.distanceTo(locationProjection) < projectDist) {
@ -569,26 +569,15 @@ public class RoutingHelper {
private class RouteRecalculationThread extends Thread implements Interruptable { private class RouteRecalculationThread extends Thread implements Interruptable {
private final Location start;
private final LatLon end;
private final GPXRouteParams gpxRoute;
private final RouteCalculationResult previousRoute;
private RouteService service;
private boolean interrupted = false; private boolean interrupted = false;
private final List<LatLon> intermediates; private final RouteCalcuationParams params;
public RouteRecalculationThread(String name, public RouteRecalculationThread(String name, RouteCalcuationParams params) {
Location start, LatLon end, List<LatLon> intermediates, GPXRouteParams gpxRoute, RouteCalculationResult previousRoute){
super(name); super(name);
this.start = start; this.params = params;
this.end = end; params.interruptable = this;
this.intermediates = intermediates;
this.gpxRoute = gpxRoute;
this.previousRoute = previousRoute;
service = settings.ROUTER_SERVICE.getModeValue(mode);
} }
public void stopCalculation(){ public void stopCalculation(){
interrupted = true; interrupted = true;
} }
@ -600,10 +589,8 @@ public class RoutingHelper {
@Override @Override
public void run() { public void run() {
boolean leftSide = settings.LEFT_SIDE_NAVIGATION.get();
boolean fastRoute = settings.FAST_ROUTE_MODE.get(); RouteCalculationResult res = provider.calculateRouteImpl(params);
RouteCalculationResult res = provider.calculateRouteImpl(start, end, intermediates, mode, service, app, gpxRoute, previousRoute, fastRoute,
leftSide, this);
if (interrupted) { if (interrupted) {
currentRunningJob = null; currentRunningJob = null;
return; return;
@ -611,7 +598,7 @@ public class RoutingHelper {
synchronized (RoutingHelper.this) { synchronized (RoutingHelper.this) {
if (res.isCalculated()) { if (res.isCalculated()) {
setNewRoute(res, start); setNewRoute(res, params.start);
} else { } else {
evalWaitInterval = evalWaitInterval * 3 / 2; evalWaitInterval = evalWaitInterval * 3 / 2;
evalWaitInterval = Math.min(evalWaitInterval, 120000); evalWaitInterval = Math.min(evalWaitInterval, 120000);
@ -622,7 +609,7 @@ public class RoutingHelper {
if (res.isCalculated()) { if (res.isCalculated()) {
showMessage(app.getString(R.string.new_route_calculated_dist) showMessage(app.getString(R.string.new_route_calculated_dist)
+ ": " + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), app)); //$NON-NLS-1$ + ": " + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), app)); //$NON-NLS-1$
} else if (service != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) { } else if (params.type != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) {
showMessage(app.getString(R.string.error_calculating_route) showMessage(app.getString(R.string.error_calculating_route)
+ ":\n" + app.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG); //$NON-NLS-1$ + ":\n" + app.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG); //$NON-NLS-1$
} else { } else {
@ -644,8 +631,20 @@ public class RoutingHelper {
if(currentRunningJob == null){ if(currentRunningJob == null){
// do not evaluate very often // do not evaluate very often
if (System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval) { if (System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval) {
RouteCalcuationParams params = new RouteCalcuationParams();
params.start = start;
params.end = end;
params.intermediates = intermediates;
params.gpxRoute = gpxRoute;
params.previousToRecalculate = previousRoute;
params.leftSide = settings.LEFT_SIDE_NAVIGATION.get();
params.optimal = settings.OPTIMAL_ROUTE_MODE.get();
params.fast = settings.FAST_ROUTE_MODE.get();
params.type = settings.ROUTER_SERVICE.getModeValue(mode);
params.mode = mode;
params.ctx = app;
synchronized (this) { synchronized (this) {
currentRunningJob = new RouteRecalculationThread("Calculating route", start, end, intermediates, gpxRoute, previousRoute); //$NON-NLS-1$ currentRunningJob = new RouteRecalculationThread("Calculating route", params); //$NON-NLS-1$
currentRunningJob.start(); currentRunningJob.start();
} }
} }

View file

@ -14,6 +14,7 @@ import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView; import android.widget.TextView;
@ -42,7 +43,11 @@ public class MonitoringInfoControl {
monitoringServices.setOnClickListener(new View.OnClickListener() { monitoringServices.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
showBgServiceQAction(monitoringServices, view, map); if(MonitoringInfoControl.this.monitoringServices.isEmpty()) {
Toast.makeText(view.getContext(), R.string.enable_plugin_monitoring_services, Toast.LENGTH_LONG).show();
} else {
showBgServiceQAction(monitoringServices, view, map);
}
} }
}); });
return monitoringServices; return monitoringServices;

View file

@ -281,14 +281,20 @@ bool readRouteTree(CodedInputStream* input, RouteSubregion* thisTree, RouteSubre
break; break;
} }
case OsmAndRoutingIndex_RouteDataBox::kBoxesFieldNumber: { case OsmAndRoutingIndex_RouteDataBox::kBoxesFieldNumber: {
RouteSubregion subregion; if (readChildren) {
readInt(input, &subregion.length); RouteSubregion subregion;
subregion.filePointer = input->getTotalBytesRead(); readInt(input, &subregion.length);
int oldLimit = input->PushLimit(subregion.length); subregion.filePointer = input->getTotalBytesRead();
readRouteTree(input, &subregion, thisTree, depth - 1, true); int oldLimit = input->PushLimit(subregion.length);
input->PopLimit(oldLimit); readRouteTree(input, &subregion, thisTree, depth - 1, true);
input->Seek(subregion.filePointer + subregion.length); input->PopLimit(oldLimit);
thisTree->subregions.push_back(subregion); input->Seek(subregion.filePointer + subregion.length);
thisTree->subregions.push_back(subregion);
} else {
if (!skipUnknownFields(input, tag)) {
return false;
}
}
break; break;
} }
default: { default: {
@ -1310,11 +1316,10 @@ bool readRouteTreeData(CodedInputStream* input, RouteSubregion* s, std::vector<R
bool sortRouteRegions (const RouteSubregion& i,const RouteSubregion& j) { return (i.mapDataBlock<j.mapDataBlock); } bool sortRouteRegions (const RouteSubregion& i,const RouteSubregion& j) { return (i.mapDataBlock<j.mapDataBlock); }
void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs){ void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub){
map<std::string, BinaryMapFile*>::iterator i = openFiles.begin(); map<std::string, BinaryMapFile*>::iterator i = openFiles.begin();
UNORDERED(set)<long long> ids; UNORDERED(set)<long long> ids;
int count = 0; int count = 0;
bool basemapExists = false; bool basemapExists = false;
for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) { for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) {
BinaryMapFile* file = i->second; BinaryMapFile* file = i->second;
@ -1326,33 +1331,22 @@ void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, Rout
if(rs != NULL && (rs->name != routingIndex->name || rs->filePointer != routingIndex->filePointer)){ if(rs != NULL && (rs->name != routingIndex->name || rs->filePointer != routingIndex->filePointer)){
continue; continue;
} }
// check boundaries and init
if (routingIndex->decodingRules.size() == 0) {
bool contain = false;
for (std::vector<RouteSubregion>::iterator subreg = routingIndex->subregions.begin(); subreg != routingIndex->subregions.end();
subreg++) {
if (subreg->right >= q->left && q->right >= subreg->left && subreg->bottom >= q->top
&& q->bottom >= subreg->top) {
contain = true;
}
}
if (contain) {
routingIndex->subregions.clear();
osmand_log_print(LOG_INFO, "Init native index %s", routingIndex->name.c_str());
lseek(file->routefd, 0, SEEK_SET);
FileInputStream input(file->routefd);
input.SetCloseOnDelete(false);
CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2);
cis.Seek(routingIndex->filePointer); // init decoding rules
uint32_t old = cis.PushLimit(routingIndex->length); if (routingIndex->decodingRules.size() == 0) {
readRoutingIndex(&cis, &(*routingIndex)); routingIndex->subregions.clear();
cis.PopLimit(old); lseek(file->routefd, 0, SEEK_SET);
} else { FileInputStream input(file->routefd);
continue; input.SetCloseOnDelete(false);
} CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2);
cis.Seek(routingIndex->filePointer);
uint32_t old = cis.PushLimit(routingIndex->length);
readRoutingIndex(&cis, &(*routingIndex));
cis.PopLimit(old);
} }
// could be simplified but it will be concurrency with init block // could be simplified but it will be concurrency with init block
lseek(file->routefd, 0, SEEK_SET); lseek(file->routefd, 0, SEEK_SET);
FileInputStream input(file->routefd); FileInputStream input(file->routefd);
@ -1360,23 +1354,17 @@ void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, Rout
CodedInputStream cis(&input); CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2); cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2);
std::vector<RouteSubregion> toLoad;
searchRouteRegion(&cis, q, &(*routingIndex), routingIndex->subregions, toLoad, file);
sort(toLoad.begin(), toLoad.end(), sortRouteRegions);
std::vector<RouteDataObject*> iteration; // cis.Seek(sub->filePointer);
int cnt = 0; // uint32_t old = cis.PushLimit(sub->length);
for (std::vector<RouteSubregion>::iterator subreg = toLoad.begin(); subreg != toLoad.end(); subreg++) { // readRouteTree(&cis, &(*sub), NULL, 0, true);
cis.Seek(subreg->filePointer + subreg->mapDataBlock); // cis.PopLimit(old);
uint32_t length; cis.Seek(sub->filePointer + sub->mapDataBlock);
cis.ReadVarint32(&length); uint32_t length;
uint32_t old = cis.PushLimit(length); cis.ReadVarint32(&length);
readRouteTreeData(&cis, &(*subreg), iteration); uint32_t old = cis.PushLimit(length);
list.insert(list.end(), iteration.begin(), iteration.end()); readRouteTreeData(&cis, &(*sub), list);
iteration.clear(); cis.PopLimit(old);
cis.PopLimit(old);
}
std::vector<RouteDataObject*>::iterator rs = list.begin();
} }
} }

View file

@ -235,7 +235,11 @@ struct SearchQuery {
ocean = mixed = false; ocean = mixed = false;
} }
SearchQuery(int l, int r, int t, int b) : SearchQuery(int l, int r, int t, int b) :
req(req), left(l), right(r), top(t), bottom(b) { left(l), right(r), top(t), bottom(b) {
}
SearchQuery(){
} }
bool publish(MapDataObject* obj) { bool publish(MapDataObject* obj) {
@ -243,7 +247,7 @@ struct SearchQuery {
} }
}; };
void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs = NULL); void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub);
ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, std::string msgNothingFound); ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, std::string msgNothingFound);

View file

@ -398,6 +398,16 @@ jclass jclass_NativeRouteSearchResult = NULL;
jmethodID jmethod_NativeRouteSearchResult_init = NULL; jmethodID jmethod_NativeRouteSearchResult_init = NULL;
jclass jclass_RouteSubregion = NULL;
jfieldID jfield_RouteSubregion_length = NULL;
jfieldID jfield_RouteSubregion_filePointer= NULL;
jfieldID jfield_RouteSubregion_left = NULL;
jfieldID jfield_RouteSubregion_right = NULL;
jfieldID jfield_RouteSubregion_top = NULL;
jfieldID jfield_RouteSubregion_bottom = NULL;
jfieldID jfield_RouteSubregion_shiftToData = NULL;
void loadJniRenderingContext(JNIEnv* env) void loadJniRenderingContext(JNIEnv* env)
{ {
jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext"); jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext");
@ -444,6 +454,17 @@ void loadJniRenderingContext(JNIEnv* env)
jfield_RouteDataObject_id = getFid(env, jclass_RouteDataObject, "id", "J" ); jfield_RouteDataObject_id = getFid(env, jclass_RouteDataObject, "id", "J" );
jmethod_RouteDataObject_init = env->GetMethodID(jclass_RouteDataObject, "<init>", "(Lnet/osmand/binary/BinaryMapRouteReaderAdapter$RouteRegion;[I[Ljava/lang/String;)V"); jmethod_RouteDataObject_init = env->GetMethodID(jclass_RouteDataObject, "<init>", "(Lnet/osmand/binary/BinaryMapRouteReaderAdapter$RouteRegion;[I[Ljava/lang/String;)V");
jclass_RouteSubregion = findClass(env, "net/osmand/binary/BinaryMapRouteReaderAdapter$RouteSubregion");
jfield_RouteSubregion_length= getFid(env, jclass_RouteSubregion, "length", "I" );
jfield_RouteSubregion_filePointer= getFid(env, jclass_RouteSubregion, "filePointer", "I" );
jfield_RouteSubregion_left= getFid(env, jclass_RouteSubregion, "left", "I" );
jfield_RouteSubregion_right= getFid(env, jclass_RouteSubregion, "right", "I" );
jfield_RouteSubregion_top= getFid(env, jclass_RouteSubregion, "top", "I" );
jfield_RouteSubregion_bottom= getFid(env, jclass_RouteSubregion, "bottom", "I" );
jfield_RouteSubregion_shiftToData= getFid(env, jclass_RouteSubregion, "shiftToData", "I" );
// public final RouteRegion routeReg;
} }
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc) void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc)
@ -565,17 +586,25 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_getRoute
return res; return res;
} }
//protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int fpointer, int left, int right, int top, int bottom, //protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int regfp, RouteSubregion subreg,
// boolean loadObjects!); // boolean loadObjects);
extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_NativeLibrary_loadRoutingData(JNIEnv* ienv, extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_NativeLibrary_loadRoutingData(JNIEnv* ienv,
jobject obj, jobject reg, jstring regName, jint filepointer, jint left, jint right, jint top, jint bottom, jboolean loadObjects) { jobject obj, jobject reg, jstring regName, jint regFilePointer,
jobject subreg, jboolean loadObjects) {
RoutingIndex ind; RoutingIndex ind;
ind.filePointer = filepointer; ind.filePointer = regFilePointer;
ind.name = getString(ienv, regName); ind.name = getString(ienv, regName);
RouteSubregion sub;
sub.filePointer = ienv->GetIntField(subreg, jfield_RouteSubregion_filePointer);
sub.length = ienv->GetIntField(subreg, jfield_RouteSubregion_length);
sub.left = ienv->GetIntField(subreg, jfield_RouteSubregion_left);
sub.right = ienv->GetIntField(subreg, jfield_RouteSubregion_right);
sub.top = ienv->GetIntField(subreg, jfield_RouteSubregion_top);
sub.bottom = ienv->GetIntField(subreg, jfield_RouteSubregion_bottom);
sub.mapDataBlock= ienv->GetIntField(subreg, jfield_RouteSubregion_shiftToData);
std::vector<RouteDataObject*> result; std::vector<RouteDataObject*> result;
SearchQuery q(left, right, top, bottom); SearchQuery q;
searchRouteRegion(&q, result, &ind); searchRouteRegion(&q, result, &ind, &sub);
if (loadObjects) { if (loadObjects) {