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 {
static BinaryMapIndexReader[] rs;
private NativeSwingRendering lib;
static NativeSwingRendering lib;
@Before
public void setupFiles() throws IOException {
if(rs != null){
@ -51,27 +51,27 @@ public class JUnitRouteTest {
}
@Test
public void runCZ() throws SAXException, IOException, ParserConfigurationException {
public void runCZ() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("cz.test.xml"), rs, RoutingConfiguration.getDefault());
}
@Test
public void runNL() throws SAXException, IOException, ParserConfigurationException {
public void runNL() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl.test.xml"), rs, RoutingConfiguration.getDefault());
}
@Test
public void runNL2() throws SAXException, IOException, ParserConfigurationException {
public void runNL2() throws Exception {
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl2.test.xml"), rs, RoutingConfiguration.getDefault());
}
@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());
}
@Test
public void runBLR() throws SAXException, IOException, ParserConfigurationException {
public void runBLR() throws Exception {
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 javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.osmand.NativeLibrary;
import net.osmand.binary.BinaryMapIndexReader;
@ -17,6 +16,7 @@ import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration;
import net.osmand.router.RoutingConfiguration.Builder;
import net.osmand.router.RoutingContext;
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);
if(params.tests.isEmpty() || params.obfDir == null) {
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));
NodeList tests = testSuite.getElementsByTagName("test");
for (int i = 0; i < tests.getLength(); i++) {
Element e = (Element) tests.item(i);
BinaryRoutePlanner router = new BinaryRoutePlanner(lib, rs);
RoutingConfiguration.DEFAULT_DESIRABLE_TILES_IN_MEMORY = 100;
testRoute(e, router, config);
testRoute(e, config, lib, rs);
}
return true;
@ -147,7 +145,7 @@ public class RouterTestsSuite {
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");
int loadedTiles = (int) parseFloat(testCase, "loadedTiles");
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" );
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");
if (skip != null && skip.length() > 0) {
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 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 endLon = Double.parseDouble(testCase.getAttribute("target_lon"));
RouteSegment endSegment = planner.findRouteSegment(endLat, endLon, ctx);
RouteSegment endSegment = router.findRouteSegment(endLat, endLon, ctx);
if(startSegment == null){
throw new IllegalArgumentException("Start segment is not found for test : " + testDescription);
}
if(endSegment == null){
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 completeDistance = 0;
for (int i = 0; i < route.size(); i++) {

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<router_tests>
<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="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 = "" />

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<router_tests>
<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="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" />

View file

@ -1,21 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<router_tests>
<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="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="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="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="7365071" start="0" end="1" time = "0.9398953" name = "Zetterij" distance = "13.054101" start_bearing = "117.97948" end_bearing = "117.97948" description = "" />
<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="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="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="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="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="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 = "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="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 = "" />
@ -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="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="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="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="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 (*)" />
@ -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="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="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="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 = "" />
@ -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="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="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="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="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="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="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="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="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 = "" />
@ -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="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="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="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 = "" />
@ -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="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="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="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="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 = "" />
@ -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="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="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="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="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="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="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 = "" />
@ -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="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="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="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 (*)" />
@ -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="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="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="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="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="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="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="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 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="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="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 = "" />
@ -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="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="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="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="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" 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="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 = "" />
@ -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="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="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="6774986" start="0" end="1" time = "1.193324" name = " (A2) " distance = "39.777462" start_bearing = "167.14766" end_bearing = "167.14766" 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="6775285" start="0" end="1" time = "2.0140622" name = " (A2) " distance = "67.1354" start_bearing = "-175.16959" end_bearing = "-175.16959" 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="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="6774985" start="0" end="1" time = "1.1368768" name = " (A2) " distance = "37.895893" start_bearing = "166.94069" end_bearing = "166.94069" 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="6774821" start="0" end="5" time = "9.872207" name = " (A2) " distance = "329.07355" start_bearing = "170.36246" end_bearing = "176.13081" 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="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="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="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="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 = "" />
@ -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="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="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="7125080" start="0" end="3" time = "22.315641" name = "Viaductweg" distance = "132.08797" start_bearing = "-69.443954" end_bearing = "-67.22757" description = "" />
<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 = "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="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="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="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="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 = "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 = "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="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="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="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="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="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="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="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="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="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="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>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<router_tests>
<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="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 = "" />
@ -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="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="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="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="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="7365071" start="0" end="1" time = "0.9398953" name = "Zetterij" distance = "13.054101" start_bearing = "117.97948" end_bearing = "117.97948" description = "" />
<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="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="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="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="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="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 = "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="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 = "" />
@ -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="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="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="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="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 (*)" />
@ -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="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="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="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="80749051" start="0" end="1" time = "5.690788" name = " (A2) " distance = "158.07745" start_bearing = "123.72714" end_bearing = "123.72714" 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="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="99998240" start="0" end="10" time = "39.82047" name = " (A2) " distance = "1106.1241" start_bearing = "137.54857" end_bearing = "150.25511" 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="51795374" start="0" end="2" time = "9.2991705" name = " (A2) " distance = "258.3103" start_bearing = "176.55423" end_bearing = "179.28766" 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="51763743" start="0" end="1" time = "1.9273798" name = " (A2) " distance = "53.53833" start_bearing = "-178.62674" end_bearing = "-178.62674" description = "" />
<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="114712628" start="0" end="2" time = "7.6056266" name = " (A2) " distance = "211.26741" start_bearing = "-170.33298" end_bearing = "-165.04005" 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="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="7054459" start="0" end="1" time = "0.5385003" name = " (A2) " distance = "14.958343" start_bearing = "-165.11374" end_bearing = "-165.11374" 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="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="79262901" start="0" end="11" time = "83.45524" name = " (A2) " distance = "2318.2012" start_bearing = "123.34157" end_bearing = "138.1617" 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="151258641" start="0" end="6" time = "22.246897" name = " (A2) " distance = "617.96936" start_bearing = "143.19708" end_bearing = "150.50703" description = "" />
<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="80761383" start="0" end="2" time = "11.184597" name = " (A2) " distance = "310.68326" start_bearing = "174.99852" end_bearing = "179.38173" 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="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="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="7054352" start="0" end="3" time = "24.02921" name = " (A2) " distance = "667.478" start_bearing = "-165.3489" end_bearing = "-165.1765" description = "" />
<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="78380416" start="0" end="1" time = "6.098158" name = " (A2) " distance = "169.39328" start_bearing = "-164.95683" end_bearing = "-164.95683" 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="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="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="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="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="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="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="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="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 = "" />
@ -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="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="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="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="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 = "" />
@ -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="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="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="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="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="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 (*)" />
@ -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="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="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="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 = "" />
@ -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="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="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="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 (*)" />
@ -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="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="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="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="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="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="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="23385640" start="0" end="1" time = "17.049618" name = "Groenendaallaan" distance = "28.466919" start_bearing = "-86.28471" end_bearing = "-86.28471" description = "" />
<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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="23541825" start="0" end="3" time = "17.776953" name = "Oosterweelsteenweg" distance = "222.2119" start_bearing = "-176.3396" end_bearing = "-161.56505" 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="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="33886773" start="0" end="3" time = "6.1337266" name = "Sloepenweg" distance = "85.19065" start_bearing = "106.03994" end_bearing = "131.39153" 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="117440385" start="0" end="1" time = "3.4957857" name = "Kattendijkbrug" distance = "48.55258" start_bearing = "179.77878" end_bearing = "179.77878" 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="120143807" start="0" end="3" time = "3.6428173" name = "Rijnkaai" distance = "45.535217" start_bearing = "-145.49147" end_bearing = "-111.54098" 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="83349187" start="0" end="2" time = "3.610016" name = "Rijnkaai" distance = "50.139114" start_bearing = "178.03859" end_bearing = "176.24828" 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="23361255" start="0" end="2" time = "4.742435" name = "Rijnkaai" distance = "65.86715" start_bearing = "-175.4139" end_bearing = "179.32198" 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="19584404" start="0" end="1" time = "17.841076" name = "Rijnkaai" distance = "35.51344" start_bearing = "-164.95361" end_bearing = "-164.95361" 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="82652955" start="0" end="3" time = "7.2567635" name = "Rijnkaai" distance = "90.70954" start_bearing = "-158.13142" end_bearing = "-164.4072" description = "" />
<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="22957749" start="0" end="3" time = "5.8082724" name = "Tavernierkaai" distance = "72.60341" start_bearing = "-151.02586" end_bearing = "-145.00798" 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="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="22957751" start="0" end="1" time = "2.317422" name = "Orteliuskaai" distance = "32.186417" start_bearing = "-158.25922" end_bearing = "-158.25922" 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="25788113" start="0" end="6" time = "17.696148" name = "Jordaenskaai" distance = "245.77983" start_bearing = "-157.96378" end_bearing = "-158.80594" 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="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="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="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="4322890" start="0" end="1" time = "3.0917888" name = " (R1) " distance = "103.05962" start_bearing = "-180.0" end_bearing = "180.0" description = "" />
<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="4322584" start="0" end="18" time = "62.07714" name = " (R1) " distance = "1724.3651" start_bearing = "173.4802" end_bearing = "137.81555" description = "" />
<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="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="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="4312416" start="0" end="1" time = "3.1672919" name = "" distance = "70.38426" start_bearing = "-131.5834" end_bearing = "-131.5834" description = "" />
<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="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="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="4395067" start="0" end="1" time = "26.002739" name = " (N184) " distance = "16.712315" start_bearing = "-79.69515" end_bearing = "-79.69515" description = "" />
<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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="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="8052374" start="0" end="3" time = "27.157873" name = "Frankrijklei" distance = "35.96455" start_bearing = "-35.90972" end_bearing = "-44.464542" 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="4446716" start="0" end="7" time = "3.168966" name = "Leopoldplaats" distance = "39.612076" start_bearing = "-59.743565" end_bearing = "-8.972627" 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="7940955" start="0" end="2" time = "6.4086165" name = "Komedieplaats" distance = "80.107704" start_bearing = "-46.684685" end_bearing = "-51.608463" 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="4446775" start="0" end="16" time = "15.203991" name = "Huidevettersstraat" distance = "190.0499" start_bearing = "-8.746162" end_bearing = "-1.1457628" 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="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="19752616" start="0" end="1" time = "27.84184" name = "Meirbrug" distance = "35.52302" start_bearing = "-75.08797" end_bearing = "-75.08797" 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="7940939" start="0" end="6" time = "5.6946187" name = "Schoenmarkt" distance = "71.18273" start_bearing = "-103.392494" end_bearing = "-96.94099" 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="76441130" start="0" end="3" time = "27.35271" name = "Schoenmarkt" distance = "29.40888" start_bearing = "-82.874985" end_bearing = "-69.04422" 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="19882382" start="0" end="3" time = "1.5475764" name = "" distance = "19.344706" start_bearing = "-90.0" end_bearing = "-147.65256" 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="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="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>
</router_tests>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<router_tests>
<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="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" />

View file

@ -3,6 +3,7 @@ package net.osmand;
import java.nio.ByteBuffer;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
import net.osmand.binary.RouteDataObject;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
@ -42,7 +43,7 @@ public class NativeLibrary {
public long nativeHandler;
public RouteDataObject[] objects;
public RouteRegion region;
public RouteSubregion region;
public NativeRouteSearchResult(long nativeHandler, RouteDataObject[] objects) {
this.nativeHandler = nativeHandler;
this.objects = objects;
@ -76,7 +77,7 @@ public class NativeLibrary {
if(rs.nativeHandler == 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) {
NativeRouteSearchResult lr = loadRoutingData(reg, reg.getName(), reg.getFilePointer(), left, right, top, bottom, loadObjects);
public NativeRouteSearchResult loadRouteRegion(RouteSubregion sub, boolean loadObjects) {
NativeRouteSearchResult lr = loadRoutingData(sub.routeReg, sub.routeReg.getName(), sub.routeReg.getFilePointer(),
sub, loadObjects);
if(lr != null && lr.nativeHandler != 0){
lr.region = reg;
lr.region = sub;
}
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);
protected static native void deleteRouteSearchResult(long searchResultHandle);

View file

@ -49,7 +49,7 @@ public class BinaryInspector {
// 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
}

View file

@ -1962,16 +1962,30 @@ public class BinaryMapIndexReader {
public void initRouteRegionsIfNeeded(SearchRequest<RouteDataObject> req) throws IOException {
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.numberOfAcceptedObjects = 0;
req.numberOfAcceptedSubtrees = 0;
req.numberOfReadSubtrees = 0;
if(routeAdapter != null){
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 net.osmand.LogUtil;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.binary.OsmandOdb.IdTable;
import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteDataBlock;
@ -154,7 +155,7 @@ public class BinaryMapRouteReaderAdapter {
}
public static class RouteRegion extends BinaryIndexPart {
int regionsRead;
public int regionsRead;
List<RouteSubregion> subregions = new ArrayList<RouteSubregion>();
List<RouteTypeRule> routeEncodingRules = new ArrayList<BinaryMapRouteReaderAdapter.RouteTypeRule>();
@ -214,6 +215,7 @@ public class BinaryMapRouteReaderAdapter {
}
}
// Used in C++
public static class RouteSubregion {
private final static int INT_SIZE = 4;
public final RouteRegion routeReg;
@ -250,6 +252,16 @@ public class BinaryMapRouteReaderAdapter {
}
return shallow;
}
public int countSubregions(){
int cnt = 1;
if (subregions != null) {
for (RouteSubregion s : subregions) {
cnt += s.countSubregions();
}
}
return cnt;
}
}
private CodedInputStreamRAF codedIS;
@ -576,6 +588,11 @@ public class BinaryMapRouteReaderAdapter {
break;
case RouteDataBox.SHIFTTODATA_FIELD_NUMBER :
thisTree.shiftToData = readInt();
if(!readChildren) {
// usually 0
thisTree.subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
readChildren = true;
}
break;
case RouteDataBox.BOXES_FIELD_NUMBER :
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 {
List<RouteSubregion> toLoad = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
searchRouteRegion(req, list, toLoad);
public void loadRouteRegionData(List<RouteSubregion> toLoad, ResultMatcher<RouteDataObject> matcher) throws IOException {
Collections.sort(toLoad, new Comparator<RouteSubregion>() {
@Override
public int compare(RouteSubregion o1, RouteSubregion o2) {
@ -643,7 +673,7 @@ public class BinaryMapRouteReaderAdapter {
}
for (RouteDataObject ro : rs.dataObjects) {
if (ro != null) {
req.publish(ro);
matcher.publish(ro);
}
}
// free objects
@ -651,8 +681,9 @@ public class BinaryMapRouteReaderAdapter {
}
}
private void searchRouteRegion(SearchRequest<RouteDataObject> req, List<RouteSubregion> list, List<RouteSubregion> toLoad) throws IOException {
for(RouteSubregion rs : list){
public List<RouteSubregion> searchRouteRegionTree(SearchRequest<RouteDataObject> req, List<RouteSubregion> list,
List<RouteSubregion> toLoad) throws IOException {
for (RouteSubregion rs : list) {
if (req.intersects(rs.left, rs.top, rs.right, rs.bottom)) {
if (rs.subregions == null) {
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);
codedIS.popLimit(old);
}
searchRouteRegion(req, rs.subregions, toLoad);
searchRouteRegionTree(req, rs.subregions, toLoad);
if (rs.shiftToData != 0) {
toLoad.add(rs);
}
}
}
return toLoad;
}
}

View file

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

View file

@ -1,7 +1,5 @@
package net.osmand.router;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import java.io.IOException;
@ -11,23 +9,13 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.TreeSet;
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.osm.MapRenderingTypes;
import net.osmand.osm.MapUtils;
import net.osmand.router.RoutingContext.RoutingTile;
import org.apache.commons.logging.Log;
@ -35,8 +23,7 @@ public class BinaryRoutePlanner {
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
private final int REVERSE_WAY_RESTRICTION_ONLY = 1024;
private final NativeLibrary nativeLib;
private final Map<BinaryMapIndexReader, List<RouteSubregion>> map = new LinkedHashMap<BinaryMapIndexReader, List<RouteSubregion>>();
private final int STANDARD_ROAD_IN_QUEUE_OVERHEAD = 900;
protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
@ -44,24 +31,6 @@ public class BinaryRoutePlanner {
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) {
// translate into meters
double dy = convert31YToMeters(y1, y2);
@ -102,49 +71,38 @@ public class BinaryRoutePlanner {
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 py = MapUtils.get31TileNumberY(lat);
// put in map to avoid duplicate map loading
TIntObjectHashMap<RoutingTile> ts = new TIntObjectHashMap<RoutingContext.RoutingTile>();
// calculate box to load neighbor tiles
RoutingTile 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);
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);
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
ctx.loadTileData(px, py, 16, dataObjects);
if (dataObjects.isEmpty()) {
ctx.loadTileData(px, py, 14, dataObjects);
}
RouteSegment road = null;
double sdist = 0;
double sdist = 0;
int foundProjX = 0;
int foundProjY = 0;
for(RouteDataObject r : dataObjects){
if(r.getPointsLength() > 1){
for (RouteDataObject r : dataObjects) {
if (r.getPointsLength() > 1) {
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 pry = r.getPoint31YTile(j);
double projection = calculateProjection(r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1), r.getPoint31XTile(j), r.getPoint31YTile(j),
px, py);
if(projection < 0){
double projection = calculateProjection(r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1), r.getPoint31XTile(j),
r.getPoint31YTile(j), px, py);
if (projection < 0) {
prx = r.getPoint31XTile(j - 1);
pry = r.getPoint31YTile(j - 1);
} else if(projection >= mDist * mDist){
} else if (projection >= mDist * mDist) {
prx = r.getPoint31XTile(j);
pry = r.getPoint31YTile(j);
} else {
prx = (int) (r.getPoint31XTile(j - 1) + (r.getPoint31XTile(j) - r.getPoint31XTile(j - 1))* (projection / (mDist *mDist)));
pry = (int) (r.getPoint31YTile(j - 1) + (r.getPoint31YTile(j) - r.getPoint31YTile(j - 1)) * (projection / (mDist *mDist)));
prx = (int) (r.getPoint31XTile(j - 1) + (r.getPoint31XTile(j) - r.getPoint31XTile(j - 1))
* (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);
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
ctx.registerRouteDataObject(road.getRoad(), ctx.getRoutingTile(foundProjX, foundProjY));
ctx.registerRouteDataObject(foundProjX, foundProjY, road.getRoad());
}
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) {
ArrayList<RouteSegment> ps = new ArrayList<RouteSegment>(intermediate);
ArrayList<RouteSegmentResult> firstPartRecalculatedRoute = null;
@ -187,68 +145,74 @@ public class BinaryRoutePlanner {
ps.add(0, start);
List<RouteSegmentResult> results = new ArrayList<RouteSegmentResult>();
for (int i = 0; i < ps.size() - 1; i++) {
RoutingContext local = new RoutingContext(ctx.config);
local.copyLoadedDataAndClearCaches(ctx);
RoutingContext local = new RoutingContext(ctx);
if(i == 0) {
local.previouslyCalculatedRoute = firstPartRecalculatedRoute;
}
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);
ctx.distinctLoadedTiles += local.distinctLoadedTiles;
ctx.distinctUnloadedTiles.addAll(local.distinctUnloadedTiles);
ctx.loadedTiles += local.loadedTiles;
ctx.visitedSegments += local.visitedSegments;
ctx.loadedPrevUnloadedTiles += local.loadedPrevUnloadedTiles;
ctx.timeToCalculate += local.timeToCalculate;
ctx.timeToLoad += local.timeToLoad;
ctx.timeToLoadHeaders += local.timeToLoadHeaders;
ctx.relaxedSegments += local.relaxedSegments;
List<RoutingTile> toUnload = new ArrayList<RoutingContext.RoutingTile>();
for(RoutingTile t : local.tiles.valueCollection()){
if(!ctx.tiles.contains(t.getId())) {
toUnload.add(t);
}
}
for(RoutingTile tl : toUnload) {
local.unloadTile(tl, false);
}
local.unloadAllData(ctx);
if(restPartRecalculatedRoute != null) {
results.addAll(restPartRecalculatedRoute);
break;
}
}
Object[] vls = ctx.tiles.values();
for (Object tl : vls) {
if (((RoutingTile) tl).isLoaded()) {
ctx.unloadTile((RoutingTile) tl, false);
}
}
ctx.unloadAllData();
printResults(ctx, start, end, results);
return results;
}
return searchRoute(ctx, start, end, leftSideNavigation);
}
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException {
List<RouteSegmentResult> result = searchRouteInternal(ctx, start, end, leftSideNavigation);
@SuppressWarnings("static-access")
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) {
printResults(ctx, start, end, result);
}
Object[] vls = ctx.tiles.values();
for(Object tl : vls) {
ctx.unloadTile((RoutingTile) tl, false);
if (RoutingContext.SHOW_GC_SIZE) {
int sz = ctx.global.size;
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;
}
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)
* 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
ctx.timeToLoad = 0;
ctx.visitedSegments = 0;
@ -378,66 +342,19 @@ public class BinaryRoutePlanner {
graphSegments = graphDirectSegments;
}
if(ctx.runTilesGC()) {
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
}
if(ctx.runRelaxingStrategy() ) {
relaxNotNeededSegments(ctx, graphDirectSegments, true);
relaxNotNeededSegments(ctx, graphReverseSegments, false);
}
// check if interrupted
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
return new ArrayList<RouteSegmentResult>();
throw new InterruptedException("Route calculation interrupted");
}
}
println("Result is found");
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) {
@ -498,34 +415,28 @@ public class BinaryRoutePlanner {
System.out.println(logMsg);
}
private static void printInfo(String logMsg) {
log.warn(logMsg);
}
public void printDebugMemoryInformation(RoutingContext ctx, PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments,
TLongObjectHashMap<RouteSegment> visitedDirectSegments,TLongObjectHashMap<RouteSegment> visitedOppositeSegments) {
println("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6);
println("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + ctx.maxLoadedTiles);
println("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
" (distinct " + ctx.distinctUnloadedTiles.size()+") "+ ", loaded more than once same tiles "
printInfo("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6 + ", time to load headers : " + ctx.timeToLoadHeaders / 1e6);
int maxLoadedTiles = Math.max(ctx.maxLoadedTiles, ctx.getCurrentlyLoadedTiles());
printInfo("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + maxLoadedTiles);
printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
", loaded more than once same tiles "
+ 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) {
println("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
printInfo("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
}
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,
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
int x = road.getPoint31XTile(segmentEnd);
int y = road.getPoint31YTile(segmentEnd);
RoutingTile tile = loadRoutes(ctx, x, y);
if(positive) {
posSegmentDist += squareRootDist(x, y,
road.getPoint31XTile(segmentEnd - 1), road.getPoint31YTile(segmentEnd - 1));
@ -645,9 +555,14 @@ public class BinaryRoutePlanner {
}
obstacleMinusTime += obstacle;
}
long l = (((long) x) << 31) + (long) y;
RouteSegment next = tile.getSegment(l, ctx);
// int overhead = 0;
// could be expensive calculation
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
if (next != null) {
// TO-DO U-Turn
@ -886,8 +801,8 @@ public class BinaryRoutePlanner {
// calculate time
for (int i = 0; i < result.size(); i++) {
if(ctx.runTilesGC()) {
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
if(ctx.checkIfMemoryLimitCritical(ctx.config.memoryLimitation)) {
ctx.unloadUnusedTiles(ctx.config.memoryLimitation);
}
RouteSegmentResult rr = result.get(i);
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) {
RouteSegmentResult rr = result.get(routeInd);
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 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
while (routeSegment != null) {
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
// Influence on A* : f(x) + heuristicCoefficient*g(X)
public double heuristicCoefficient = 1;
public static final int DEFAULT_MEMORY_LIMIT = 30;
// 1.1 tile load parameters (should not affect routing)
public int ZOOM_TO_LOAD_TILES = 13; // 12?, 14?
public int ITERATIONS_TO_RUN_GC = 100;
public static int DEFAULT_DESIRABLE_TILES_IN_MEMORY = 30;
public int NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = DEFAULT_DESIRABLE_TILES_IN_MEMORY;
public int ZOOM_TO_LOAD_TILES = 16;
public int memoryLimitation;
// 1.2 Dynamic road prioritizing (heuristic)
public boolean useDynamicRoadPrioritising = true;
@ -53,10 +54,10 @@ public class RoutingConfiguration {
private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>();
private Map<String, String> attributes = new LinkedHashMap<String, String>();
public RoutingConfiguration build(String router, String... specialization) {
return build(router, null, specialization);
public RoutingConfiguration build(String router, int memoryLimitMB, String... 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)) {
router = defaultRouter;
}
@ -64,10 +65,15 @@ public class RoutingConfiguration {
i.initialDirection = direction;
i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
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);
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = parseSilentInt(getAttribute(router, "desirableTilesInMemory"),
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
if(desirable != 0) {
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.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
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">
<!-- 1. parameters of routing and different tweaks Influence on A* : -->
<!-- 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) -->
<attribute name="zoomToLoadTiles" value="13" />
<attribute name="iterationsToRunGC" value="125" />
<!-- by default it is 25 -->
<attribute name="desirableTilesInMemory" value="" />
<!-- by default 16 -->
<attribute name="zoomToLoadTiles" value="16" />
<!-- by default it is 30. Value specified here overwrites all others
(don't specify here ! it is device dependent) -->
<attribute name="memoryLimitInMB" value="" />
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
<attribute name="useDynamicRoadPrioritising" value="true" />
@ -129,7 +131,6 @@
</avoid>
</routingProfile>
<routingProfile name="bicycle" baseProfile="bicycle" restrictionsAware="true" minDefaultSpeed="7" maxDefaultSpeed="16"
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
<!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> -->

View file

@ -119,12 +119,11 @@ public class MapClusterLayer implements MapPanelLayer {
rs.add(new BinaryMapIndexReader(raf));
}
}
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(),
rs.toArray(new BinaryMapIndexReader[rs.size()]));
BinaryRoutePlanner router = new BinaryRoutePlanner();
Builder builder = RoutingConfiguration.getDefault();
RoutingConfiguration config = builder.build("car");
config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
RoutingContext ctx = new RoutingContext(config);
RoutingConfiguration config = builder.build("car", RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3);
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(),
rs.toArray(new BinaryMapIndexReader[rs.size()]));
// find closest way
RouteSegment st = router.findRouteSegment(lat, lon, ctx);
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;
}
@ -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>>();
List<RouteSegment> result = new ArrayList<BinaryRoutePlanner.RouteSegment>();
TLongHashSet visitedIds = new TLongHashSet();
@ -265,9 +264,7 @@ public class MapClusterLayer implements MapPanelLayer {
int x = road.getPoint31XTile(segmentEnd);
int y = road.getPoint31YTile(segmentEnd);
router.loadRoutes(ctx, x, y);
long l = (((long) x) << 31) + (long) y;
RouteSegment next = ctx.getRoutingTile(x, y).getSegment(l, ctx);
RouteSegment next = ctx.loadRouteSegment(x, y, 0);
RouteSegment toAdd = segment;
if (!onTheMap.contains(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.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.osm.Way;
import net.osmand.osm.OSMSettings.OSMTagKey;
import net.osmand.osm.Way;
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.RoutingConfiguration;
import net.osmand.router.RoutingConfiguration.Builder;
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.Element;
import org.w3c.dom.Node;
@ -52,11 +56,6 @@ import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
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 {
@ -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){
List<Way> res = new ArrayList<Way>();
long time = System.currentTimeMillis();
@ -625,11 +610,11 @@ public class MapRouterLayer implements MapPanelLayer {
}
String m = DataExtractionSettings.getSettings().getRouteMode();
String[] props = m.split("\\,");
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs);
RoutingConfiguration config = builder.build(props[0], props);
BinaryRoutePlanner router = new BinaryRoutePlanner();
RoutingConfiguration config = builder.build(props[0], RoutingConfiguration.DEFAULT_MEMORY_LIMIT / 2, props);
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
// config.ZOOM_TO_LOAD_TILES = 14;
RoutingContext ctx = new RoutingContext(config);
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(), rs);
ctx.previouslyCalculatedRoute = previousRoute;
log.info("Use " + config.routerName + "mode for routing");
@ -638,13 +623,13 @@ public class MapRouterLayer implements MapPanelLayer {
if (st == null) {
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);
if (e == null) {
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>();
if (intermediates != null) {
@ -763,6 +748,8 @@ public class MapRouterLayer implements MapPanelLayer {
}
} catch (IOException e) {
ExceptionHandler.handle(e);
} catch (InterruptedException e) {
ExceptionHandler.handle(e);
} finally {
playPauseButton.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"/>
</LinearLayout>
<CheckBox android:id="@+id/OptimalCheckox" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/non_optimal_route_calculation"/>
</LinearLayout>

View file

@ -1,5 +1,7 @@
<?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Данные на устройстве (%1$s свободно):</string>
<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_DM">ГГГ ММ.МММММ</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="search_address_top_text">Выберите адрес</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).
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 :
Updated
</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 :

View file

@ -59,6 +59,8 @@ public class OsmandSettings {
boolean set(T obj);
boolean setModeValue(ApplicationMode m, T obj);
T getModeValue(ApplicationMode m);
String getId();
@ -144,6 +146,11 @@ public class OsmandSettings {
public ApplicationMode getModeValue(ApplicationMode m) {
return m;
}
@Override
public boolean setModeValue(ApplicationMode m, ApplicationMode obj) {
throw new UnsupportedOperationException();
}
};
public ApplicationMode getApplicationMode(){
@ -241,6 +248,14 @@ public class OsmandSettings {
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(){
if(global){
return defaultValue;
@ -596,6 +611,10 @@ public class OsmandSettings {
// 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 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_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);
// 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)) {
SpannableString content = new SpannableString(textVersion);
content.setSpan(new ClickableSpan() {

View file

@ -292,7 +292,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
Object toShow = settings.getAndClearObjectToShow();
if(settings.isRouteToPointNavigateAndClear()){
// 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){
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();
Builder builder = new AlertDialog.Builder(mapActivity);
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];
buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton);
buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton);
@ -426,11 +427,16 @@ public class MapActivityActions implements DialogProvider {
if (buttons[i] != null) {
final int ind = 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() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
nonoptimal.setChecked(!settings.OPTIMAL_ROUTE_MODE.getModeValue(buttonAppMode));
for (int j = 0; j < buttons.length; j++) {
if (buttons[j] != null) {
if (buttons[j].isChecked() != (ind == j)) {
@ -461,15 +467,23 @@ public class MapActivityActions implements DialogProvider {
DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(to != null) {
mapActivity.navigateToPoint(to, false, -1);
}
if (!checkPointToNavigate()) {
return;
}
Location from = fromOrCurrent;
if(from == null) {
from = mapActivity.getLastKnownLocation();
}
if (from == null) {
AccessibleToast.makeText(mapActivity, R.string.unknown_from_location, Toast.LENGTH_LONG).show();
return;
}
ApplicationMode mode = getAppMode(buttons, settings);
routingHelper.setAppMode(mode);
settings.OPTIMAL_ROUTE_MODE.setModeValue(mode, !nonoptimal.isChecked());
settings.FOLLOW_THE_ROUTE.set(false);
settings.FOLLOW_THE_GPX_ROUTE.set(null);
routingHelper.setFollowingMode(false);
@ -481,12 +495,19 @@ public class MapActivityActions implements DialogProvider {
DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(to != null) {
mapActivity.navigateToPoint(to, false, -1);
}
if (!checkPointToNavigate()) {
return;
}
boolean msg = true;
Location current = from;
if (!mapActivity.isPointAccurateForRouting(from)) {
Location current = fromOrCurrent;
if(current == null) {
current = mapActivity.getLastKnownLocation();
}
if (!mapActivity.isPointAccurateForRouting(current)) {
current = null;
}
Location lastKnownLocation = mapActivity.getLastKnownLocation();
@ -507,6 +528,9 @@ public class MapActivityActions implements DialogProvider {
DialogInterface.OnClickListener useGpxNavigation = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(to != null) {
mapActivity.navigateToPoint(to, false, -1);
}
ApplicationMode mode = getAppMode(buttons, settings);
navigateUsingGPX(mode);
}
@ -734,16 +758,14 @@ public class MapActivityActions implements DialogProvider {
} else if (standardId == R.string.context_menu_item_navigate_point) {
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, -1);
} 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)
getDirections(loc, true);
getDirections(null, new LatLon(latitude, longitude), true);
} else if (standardId == R.string.context_menu_item_show_route) {
if (checkPointToNavigate()) {
Location loc = new Location("map");
loc.setLatitude(latitude);
loc.setLongitude(longitude);
getDirections(loc, true);
getDirections(loc, null, true);
}
} else if (standardId == R.string.context_menu_item_intermediate_point) {
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, mapActivity.getIntermediatePoints().size());
@ -957,8 +979,7 @@ public class MapActivityActions implements DialogProvider {
if (routingHelper.isRouteCalculated()) {
aboutRoute();
} else {
Location loc = mapActivity.getLastKnownLocation();
getDirections(loc, true);
getDirections(null, null, true);
}
return true;
}

View file

@ -11,10 +11,8 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.location.Location;
import android.location.LocationManager;
import android.view.View;
import android.widget.SeekBar;
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.GeneralRouter;
import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.Interruptable;
import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration;
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,
GPXRouteParams gpxRoute, RouteCalculationResult previousToRecalculate, boolean fast, boolean leftSide, Interruptable interruptable){
public RouteCalculationResult calculateRouteImpl(RouteCalcuationParams params){
long time = System.currentTimeMillis();
if (start != null && end != null) {
if (params.start != null && params.end != null) {
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 {
RouteCalculationResult res;
if(gpxRoute != null && !gpxRoute.points.isEmpty()){
res = calculateGpxRoute(start, end, gpxRoute, ctx, leftSide);
} else if (type == RouteService.YOURS) {
res = findYOURSRoute(start, end, mode, fast, ctx, leftSide);
} else if (type == RouteService.ORS) {
res = findORSRoute(start, end, mode, fast, ctx, leftSide);
} else if (type == RouteService.OSMAND) {
List<RouteSegmentResult> originalRoute = null;
if(previousToRecalculate != null) {
originalRoute = previousToRecalculate.getOriginalRoute();
}
res = findVectorMapsRoute(start, end, intermediates, mode, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide, interruptable);
if(params.gpxRoute != null && !params.gpxRoute.points.isEmpty()){
res = calculateGpxRoute(params);
} else if (params.type == RouteService.YOURS) {
res = findYOURSRoute(params);
} else if (params.type == RouteService.ORS) {
res = findORSRoute(params);
} else if (params.type == RouteService.OSMAND) {
res = findVectorMapsRoute(params);
} else {
res = findCloudMadeRoute(start, end, intermediates, mode, ctx, fast, leftSide);
res = findCloudMadeRoute(params);
}
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$
@ -186,27 +181,29 @@ public class RouteProvider {
return new RouteCalculationResult(null);
}
private RouteCalculationResult calculateGpxRoute(Location start, LatLon end, GPXRouteParams params, Context ctx, boolean leftSide) {
private RouteCalculationResult calculateGpxRoute(RouteCalcuationParams pars) {
RouteCalculationResult res;
// get the closest point to start and to end
float minDist = Integer.MAX_VALUE;
int startI = 0;
GPXRouteParams params = pars.gpxRoute;
List<Location> gpxRoute = params.points;
int endI = gpxRoute.size();
if (start != null) {
if (pars.start != null) {
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) {
startI = i;
minDist = d;
}
}
} else {
start = gpxRoute.get(0);
pars.start = gpxRoute.get(0);
}
Location l = new Location("temp"); //$NON-NLS-1$
l.setLatitude(end.getLatitude());
l.setLongitude(end.getLongitude());
l.setLatitude(pars.end.getLatitude());
l.setLongitude(pars.end.getLongitude());
minDist = Integer.MAX_VALUE;
// get in reverse order taking into account ways with cycle
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));
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 {
List<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>();
for (RouteDirectionInfo info : params.directions) {
@ -234,7 +232,8 @@ public class RouteProvider {
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;
}
@ -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 {
List<Location> res = new ArrayList<Location>();
StringBuilder uri = new StringBuilder();
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("&flon=").append(start.getLongitude()); //$NON-NLS-1$
uri.append("&tlat=").append(end.getLatitude()); //$NON-NLS-1$
uri.append("&tlon=").append(end.getLongitude()); //$NON-NLS-1$
if(ApplicationMode.PEDESTRIAN == mode){
uri.append("&flat=").append(params.start.getLatitude()); //$NON-NLS-1$
uri.append("&flon=").append(params.start.getLongitude()); //$NON-NLS-1$
uri.append("&tlat=").append(params.end.getLatitude()); //$NON-NLS-1$
uri.append("&tlon=").append(params.end.getLongitude()); //$NON-NLS-1$
if(ApplicationMode.PEDESTRIAN == params.mode){
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$
} else {
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);
URL url = new URL(uri.toString());
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,
List<RouteSegmentResult> previousRoute,
boolean leftSide, Interruptable interruptable) throws IOException {
protected RouteCalculationResult findVectorMapsRoute(RouteCalcuationParams params) throws IOException {
OsmandApplication app = (OsmandApplication) params.ctx.getApplicationContext();
BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles();
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeOsmandLibrary.getLoadedLibrary(), files);
BinaryRoutePlanner router = new BinaryRoutePlanner();
File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML);
RoutingConfiguration.Builder config ;
if (routingXml.exists() && routingXml.canRead()) {
@ -325,9 +324,9 @@ public class RouteProvider {
}
GeneralRouterProfile p ;
if (mode == ApplicationMode.BICYCLE) {
if (params.mode == ApplicationMode.BICYCLE) {
p = GeneralRouterProfile.BICYCLE;
} else if (mode == ApplicationMode.PEDESTRIAN) {
} else if (params.mode == ApplicationMode.PEDESTRIAN) {
p = GeneralRouterProfile.PEDESTRIAN;
} else {
p = GeneralRouterProfile.CAR;
@ -349,21 +348,36 @@ public class RouteProvider {
specs.add(GeneralRouter.AVOID_UNPAVED);
}
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));
ctx.interruptable = interruptable;
ctx.previouslyCalculatedRoute = previousRoute;
RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx);
float mb = (1 << 20);
Runtime rt = Runtime.getRuntime();
// make visible
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) {
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) {
return new RouteCalculationResult(app.getString(R.string.ending_point_too_far));
}
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
if (intermediates != null) {
if (params.intermediates != null) {
int ind = 1;
for (LatLon il : intermediates) {
for (LatLon il : params.intermediates) {
RouteSegment is = router.findRouteSegment(il.getLatitude(), il.getLongitude(), ctx);
if (is == null) {
return new RouteCalculationResult(app.getString(R.string.intermediate_point_too_far, "'" + ind + "'"));
@ -375,16 +389,19 @@ public class RouteProvider {
try {
List<RouteSegmentResult> result;
if(inters.size() > 0){
result = router.searchRoute(ctx, st, en, inters, leftSide);
result = router.searchRoute(ctx, st, en, inters, params.leftSide);
} else {
result = router.searchRoute(ctx, st, en, leftSide);
result = router.searchRoute(ctx, st, en, params.leftSide);
}
if(result == null || result.isEmpty()) {
// something really strange better to see that message on the scren
return new RouteCalculationResult("Empty result");
} 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) {
// ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE);
// 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 {
List<Location> res = new ArrayList<Location>();
List<RouteDirectionInfo> directions = null;
StringBuilder uri = new StringBuilder();
// 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(start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
uri.append(start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
if(intermediates != null && intermediates.size() > 0) {
uri.append(params.start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
uri.append(params.start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
if(params.intermediates != null && params.intermediates.size() > 0) {
uri.append("[");
boolean first = true;
for(LatLon il : intermediates) {
for(LatLon il : params.intermediates) {
if(!first){
uri.append(",");
} else {
@ -421,18 +438,18 @@ public class RouteProvider {
}
uri.append("],");
}
uri.append(end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$
uri.append(end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$
uri.append(params.end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$
uri.append(params.end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$
float speed = 1.5f;
if (ApplicationMode.PEDESTRIAN == mode) {
if (ApplicationMode.PEDESTRIAN == params.mode) {
uri.append("foot.gpx"); //$NON-NLS-1$
} else if (ApplicationMode.BICYCLE == mode) {
} else if (ApplicationMode.BICYCLE == params.mode) {
speed = 5.5f;
uri.append("bicycle.gpx"); //$NON-NLS-1$
} else {
speed = 15.3f;
if (fast) {
if (params.fast) {
uri.append("car.gpx"); //$NON-NLS-1$
} else {
uri.append("car/shortest.gpx"); //$NON-NLS-1$
@ -442,10 +459,11 @@ public class RouteProvider {
log.info("URL route " + uri);
URL url = new URL(uri.toString());
URLConnection connection = url.openConnection();
GPXFile gpxFile = GPXUtilities.loadGPXFile(ctx, connection.getInputStream(), false);
directions = parseCloudmadeRoute(res, gpxFile, false, leftSide, speed);
GPXFile gpxFile = GPXUtilities.loadGPXFile(params.ctx, connection.getInputStream(), false);
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,
@ -564,15 +582,14 @@ public class RouteProvider {
return directions;
}
protected RouteCalculationResult findORSRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, Context ctx,
boolean leftSide) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError,
protected RouteCalculationResult findORSRoute(RouteCalcuationParams params) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError,
SAXException {
List<Location> res = new ArrayList<Location>();
String rpref = "Fastest";
if (ApplicationMode.PEDESTRIAN == mode) {
if (ApplicationMode.PEDESTRIAN == params.mode) {
rpref = "Pedestrian";
} else if (ApplicationMode.BICYCLE == mode) {
} else if (ApplicationMode.BICYCLE == params.mode) {
rpref = "Bicycle";
// } else if (ApplicationMode.LOWTRAFFIC == mode) {
// rpref = "BicycleSafety";
@ -582,13 +599,13 @@ public class RouteProvider {
// rpref = "BicycleRoute";
// } else if (ApplicationMode.MTBIKE == mode) {
// rpref = "BicycleMTB";
} else if (!fast) {
} else if (!params.fast) {
rpref = "Shortest";
}
StringBuilder request = new StringBuilder();
request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(start.getLongitude()).append(',')
.append(start.getLatitude()).append("&end=").append(end.getLongitude()).append(',').append(end.getLatitude())
request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(params.start.getLongitude()).append(',')
.append(params.start.getLatitude()).append("&end=").append(params.end.getLongitude()).append(',').append(params.end.getLatitude())
.append("&preference=").append(rpref);
// TODO if we would get instructions from the service, we could use this language setting
// .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){

View file

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

View file

@ -14,6 +14,7 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
@ -42,7 +43,11 @@ public class MonitoringInfoControl {
monitoringServices.setOnClickListener(new View.OnClickListener() {
@Override
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;

View file

@ -281,14 +281,20 @@ bool readRouteTree(CodedInputStream* input, RouteSubregion* thisTree, RouteSubre
break;
}
case OsmAndRoutingIndex_RouteDataBox::kBoxesFieldNumber: {
RouteSubregion subregion;
readInt(input, &subregion.length);
subregion.filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(subregion.length);
readRouteTree(input, &subregion, thisTree, depth - 1, true);
input->PopLimit(oldLimit);
input->Seek(subregion.filePointer + subregion.length);
thisTree->subregions.push_back(subregion);
if (readChildren) {
RouteSubregion subregion;
readInt(input, &subregion.length);
subregion.filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(subregion.length);
readRouteTree(input, &subregion, thisTree, depth - 1, true);
input->PopLimit(oldLimit);
input->Seek(subregion.filePointer + subregion.length);
thisTree->subregions.push_back(subregion);
} else {
if (!skipUnknownFields(input, tag)) {
return false;
}
}
break;
}
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); }
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();
UNORDERED(set)<long long> ids;
int count = 0;
bool basemapExists = false;
for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) {
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)){
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);
uint32_t old = cis.PushLimit(routingIndex->length);
readRoutingIndex(&cis, &(*routingIndex));
cis.PopLimit(old);
} else {
continue;
}
// init decoding rules
if (routingIndex->decodingRules.size() == 0) {
routingIndex->subregions.clear();
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);
uint32_t old = cis.PushLimit(routingIndex->length);
readRoutingIndex(&cis, &(*routingIndex));
cis.PopLimit(old);
}
// could be simplified but it will be concurrency with init block
lseek(file->routefd, 0, SEEK_SET);
FileInputStream input(file->routefd);
@ -1360,23 +1354,17 @@ void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, Rout
CodedInputStream cis(&input);
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;
int cnt = 0;
for (std::vector<RouteSubregion>::iterator subreg = toLoad.begin(); subreg != toLoad.end(); subreg++) {
cis.Seek(subreg->filePointer + subreg->mapDataBlock);
uint32_t length;
cis.ReadVarint32(&length);
uint32_t old = cis.PushLimit(length);
readRouteTreeData(&cis, &(*subreg), iteration);
list.insert(list.end(), iteration.begin(), iteration.end());
iteration.clear();
cis.PopLimit(old);
}
std::vector<RouteDataObject*>::iterator rs = list.begin();
// cis.Seek(sub->filePointer);
// uint32_t old = cis.PushLimit(sub->length);
// readRouteTree(&cis, &(*sub), NULL, 0, true);
// cis.PopLimit(old);
cis.Seek(sub->filePointer + sub->mapDataBlock);
uint32_t length;
cis.ReadVarint32(&length);
uint32_t old = cis.PushLimit(length);
readRouteTreeData(&cis, &(*sub), list);
cis.PopLimit(old);
}
}

View file

@ -235,7 +235,11 @@ struct SearchQuery {
ocean = mixed = false;
}
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) {
@ -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);

View file

@ -398,6 +398,16 @@ jclass jclass_NativeRouteSearchResult = 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)
{
jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext");
@ -444,6 +454,17 @@ void loadJniRenderingContext(JNIEnv* env)
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");
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)
@ -565,17 +586,25 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_getRoute
return res;
}
//protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int fpointer, int left, int right, int top, int bottom,
// boolean loadObjects!);
//protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int regfp, RouteSubregion subreg,
// boolean loadObjects);
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;
ind.filePointer = filepointer;
ind.filePointer = regFilePointer;
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;
SearchQuery q(left, right, top, bottom);
searchRouteRegion(&q, result, &ind);
SearchQuery q;
searchRouteRegion(&q, result, &ind, &sub);
if (loadObjects) {