Merge branch 'preciseRouting'
This commit is contained in:
commit
6a38053226
33 changed files with 1196 additions and 918 deletions
|
@ -23,7 +23,7 @@ import org.xml.sax.SAXException;
|
||||||
public class JUnitRouteTest {
|
public class JUnitRouteTest {
|
||||||
|
|
||||||
static BinaryMapIndexReader[] rs;
|
static BinaryMapIndexReader[] rs;
|
||||||
private NativeSwingRendering lib;
|
static NativeSwingRendering lib;
|
||||||
@Before
|
@Before
|
||||||
public void setupFiles() throws IOException {
|
public void setupFiles() throws IOException {
|
||||||
if(rs != null){
|
if(rs != null){
|
||||||
|
@ -51,27 +51,27 @@ public class JUnitRouteTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runCZ() throws SAXException, IOException, ParserConfigurationException {
|
public void runCZ() throws Exception {
|
||||||
RouterTestsSuite.test(lib, getClass().getResourceAsStream("cz.test.xml"), rs, RoutingConfiguration.getDefault());
|
RouterTestsSuite.test(lib, getClass().getResourceAsStream("cz.test.xml"), rs, RoutingConfiguration.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runNL() throws SAXException, IOException, ParserConfigurationException {
|
public void runNL() throws Exception {
|
||||||
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl.test.xml"), rs, RoutingConfiguration.getDefault());
|
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl.test.xml"), rs, RoutingConfiguration.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runNL2() throws SAXException, IOException, ParserConfigurationException {
|
public void runNL2() throws Exception {
|
||||||
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl2.test.xml"), rs, RoutingConfiguration.getDefault());
|
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl2.test.xml"), rs, RoutingConfiguration.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runNLLeid() throws SAXException, IOException, ParserConfigurationException {
|
public void runNLLeid() throws Exception {
|
||||||
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl_leid.test.xml"), rs, RoutingConfiguration.getDefault());
|
RouterTestsSuite.test(lib, getClass().getResourceAsStream("nl_leid.test.xml"), rs, RoutingConfiguration.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runBLR() throws SAXException, IOException, ParserConfigurationException {
|
public void runBLR() throws Exception {
|
||||||
RouterTestsSuite.test(lib, getClass().getResourceAsStream("blr.test.xml"), rs, RoutingConfiguration.getDefault());
|
RouterTestsSuite.test(lib, getClass().getResourceAsStream("blr.test.xml"), rs, RoutingConfiguration.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import net.osmand.NativeLibrary;
|
import net.osmand.NativeLibrary;
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
@ -17,6 +16,7 @@ import net.osmand.router.BinaryRoutePlanner;
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||||
import net.osmand.router.RouteSegmentResult;
|
import net.osmand.router.RouteSegmentResult;
|
||||||
import net.osmand.router.RoutingConfiguration;
|
import net.osmand.router.RoutingConfiguration;
|
||||||
|
import net.osmand.router.RoutingConfiguration.Builder;
|
||||||
import net.osmand.router.RoutingContext;
|
import net.osmand.router.RoutingContext;
|
||||||
import net.osmand.swing.DataExtractionSettings;
|
import net.osmand.swing.DataExtractionSettings;
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public class RouterTestsSuite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
|
public static void main(String[] args) throws Exception {
|
||||||
Parameters params = Parameters.init(args);
|
Parameters params = Parameters.init(args);
|
||||||
if(params.tests.isEmpty() || params.obfDir == null) {
|
if(params.tests.isEmpty() || params.obfDir == null) {
|
||||||
println("Run router tests is console utility to test route calculation for osmand.");
|
println("Run router tests is console utility to test route calculation for osmand.");
|
||||||
|
@ -116,15 +116,13 @@ public class RouterTestsSuite {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean test(NativeLibrary lib, InputStream resource, BinaryMapIndexReader[] rs, RoutingConfiguration.Builder config) throws SAXException, IOException, ParserConfigurationException {
|
public static boolean test(NativeLibrary lib, InputStream resource, BinaryMapIndexReader[] rs, RoutingConfiguration.Builder config) throws Exception {
|
||||||
Document testSuite = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(resource));
|
Document testSuite = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(resource));
|
||||||
NodeList tests = testSuite.getElementsByTagName("test");
|
NodeList tests = testSuite.getElementsByTagName("test");
|
||||||
|
|
||||||
for (int i = 0; i < tests.getLength(); i++) {
|
for (int i = 0; i < tests.getLength(); i++) {
|
||||||
Element e = (Element) tests.item(i);
|
Element e = (Element) tests.item(i);
|
||||||
BinaryRoutePlanner router = new BinaryRoutePlanner(lib, rs);
|
testRoute(e, config, lib, rs);
|
||||||
RoutingConfiguration.DEFAULT_DESIRABLE_TILES_IN_MEMORY = 100;
|
|
||||||
testRoute(e, router, config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -147,7 +145,7 @@ public class RouterTestsSuite {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testRoute(Element testCase, BinaryRoutePlanner planner, RoutingConfiguration.Builder config) throws IOException, SAXException {
|
private static void testRoute(Element testCase, Builder config, NativeLibrary lib, BinaryMapIndexReader[] rs) throws IOException, SAXException, InterruptedException {
|
||||||
String vehicle = testCase.getAttribute("vehicle");
|
String vehicle = testCase.getAttribute("vehicle");
|
||||||
int loadedTiles = (int) parseFloat(testCase, "loadedTiles");
|
int loadedTiles = (int) parseFloat(testCase, "loadedTiles");
|
||||||
int visitedSegments = (int) parseFloat(testCase, "visitedSegments");
|
int visitedSegments = (int) parseFloat(testCase, "visitedSegments");
|
||||||
|
@ -159,7 +157,9 @@ public class RouterTestsSuite {
|
||||||
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because 'best_percent' attribute is not specified \n\n" );
|
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because 'best_percent' attribute is not specified \n\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RoutingContext ctx = new RoutingContext(config.build(vehicle));
|
BinaryRoutePlanner router = new BinaryRoutePlanner();
|
||||||
|
RoutingContext ctx = new RoutingContext(config.build(vehicle, RoutingConfiguration.DEFAULT_MEMORY_LIMIT),
|
||||||
|
lib, rs);
|
||||||
String skip = testCase.getAttribute("skip_comment");
|
String skip = testCase.getAttribute("skip_comment");
|
||||||
if (skip != null && skip.length() > 0) {
|
if (skip != null && skip.length() > 0) {
|
||||||
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because '" + skip + "'\n\n" );
|
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because '" + skip + "'\n\n" );
|
||||||
|
@ -169,17 +169,17 @@ public class RouterTestsSuite {
|
||||||
|
|
||||||
double startLat = Double.parseDouble(testCase.getAttribute("start_lat"));
|
double startLat = Double.parseDouble(testCase.getAttribute("start_lat"));
|
||||||
double startLon = Double.parseDouble(testCase.getAttribute("start_lon"));
|
double startLon = Double.parseDouble(testCase.getAttribute("start_lon"));
|
||||||
RouteSegment startSegment = planner.findRouteSegment(startLat, startLon, ctx);
|
RouteSegment startSegment = router.findRouteSegment(startLat, startLon, ctx);
|
||||||
double endLat = Double.parseDouble(testCase.getAttribute("target_lat"));
|
double endLat = Double.parseDouble(testCase.getAttribute("target_lat"));
|
||||||
double endLon = Double.parseDouble(testCase.getAttribute("target_lon"));
|
double endLon = Double.parseDouble(testCase.getAttribute("target_lon"));
|
||||||
RouteSegment endSegment = planner.findRouteSegment(endLat, endLon, ctx);
|
RouteSegment endSegment = router.findRouteSegment(endLat, endLon, ctx);
|
||||||
if(startSegment == null){
|
if(startSegment == null){
|
||||||
throw new IllegalArgumentException("Start segment is not found for test : " + testDescription);
|
throw new IllegalArgumentException("Start segment is not found for test : " + testDescription);
|
||||||
}
|
}
|
||||||
if(endSegment == null){
|
if(endSegment == null){
|
||||||
throw new IllegalArgumentException("End segment is not found for test : " + testDescription);
|
throw new IllegalArgumentException("End segment is not found for test : " + testDescription);
|
||||||
}
|
}
|
||||||
List<RouteSegmentResult> route = planner.searchRoute(ctx, startSegment, endSegment, false);
|
List<RouteSegmentResult> route = router.searchRoute(ctx, startSegment, endSegment, false);
|
||||||
float completeTime = 0;
|
float completeTime = 0;
|
||||||
float completeDistance = 0;
|
float completeDistance = 0;
|
||||||
for (int i = 0; i < route.size(); i++) {
|
for (int i = 0; i < route.size(); i++) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<router_tests>
|
<router_tests>
|
||||||
<test regions="" description="Belarus" best_percent="5" vehicle="car"
|
<test regions="" description="Belarus" best_percent="5" vehicle="car"
|
||||||
start_lat="53.91102495838691" start_lon="27.579245567321777" target_lat="53.908383230651346" target_lon="27.48626947402954" complete_time="1093.2324" loadedTiles = "10" visitedSegments = "832" complete_distance = "9285.089" >
|
start_lat="53.91102495838691" start_lon="27.579245567321777" target_lat="53.908383230651346" target_lon="27.48626947402954" complete_time="1093.2324" loadedTiles = "220" visitedSegments = "832" complete_distance = "9285.089" >
|
||||||
<segment id="40885459" start="3" end="2" time = "10.731602" name = "" distance = "89.43001" turn = "Go ahead" start_bearing = "30.2094" end_bearing = "30.2094" description = "Go ahead and go 89.43 meters" />
|
<segment id="40885459" start="3" end="2" time = "10.731602" name = "" distance = "89.43001" turn = "Go ahead" start_bearing = "30.2094" end_bearing = "30.2094" description = "Go ahead and go 89.43 meters" />
|
||||||
<segment id="40885456" start="1" end="0" time = "0.7542267" name = "" distance = "6.2852225" turn = "Turn left" start_bearing = "-57.804268" end_bearing = "-57.804268" description = "Turn left and go 47.32 meters" />
|
<segment id="40885456" start="1" end="0" time = "0.7542267" name = "" distance = "6.2852225" turn = "Turn left" start_bearing = "-57.804268" end_bearing = "-57.804268" description = "Turn left and go 47.32 meters" />
|
||||||
<segment id="40885457" start="1" end="0" time = "1.6372955" name = "" distance = "13.64413" start_bearing = "-57.47511" end_bearing = "-57.47511" description = "" />
|
<segment id="40885457" start="1" end="0" time = "1.6372955" name = "" distance = "13.64413" start_bearing = "-57.47511" end_bearing = "-57.47511" description = "" />
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<router_tests>
|
<router_tests>
|
||||||
<test regions="" description="Czech" best_percent="10" vehicle="car"
|
<test regions="" description="Czech" best_percent="10" vehicle="car"
|
||||||
start_lat="50.07577452522076" start_lon="14.45427417755127" target_lat="49.120547036367746" target_lon="16.335017681121826" complete_time="7241.0713" loadedTiles = "250" visitedSegments = "2598" complete_distance = "204110.28" >
|
start_lat="50.07577452522076" start_lon="14.45427417755127" target_lat="49.120547036367746" target_lon="16.335017681121826" complete_time="7241.0713" loadedTiles = "580" visitedSegments = "2598" complete_distance = "204110.28" >
|
||||||
<segment id="148483636" start="1" end="3" time = "7.144318" name = "" distance = "69.45865" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-13.969152" end_bearing = "-15.124007" description = "Go ahead and go 184.99 meters" />
|
<segment id="148483636" start="1" end="3" time = "7.144318" name = "" distance = "69.45865" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-13.969152" end_bearing = "-15.124007" description = "Go ahead and go 184.99 meters" />
|
||||||
<segment id="38611055" start="0" end="3" time = "11.883394" name = "Perunova" distance = "115.533" start_bearing = "-13.348727" end_bearing = "-14.32272" description = "" />
|
<segment id="38611055" start="0" end="3" time = "11.883394" name = "Perunova" distance = "115.533" start_bearing = "-13.348727" end_bearing = "-14.32272" description = "" />
|
||||||
<segment id="128493079" start="0" end="10" time = "27.32003" name = "Vinohradská" distance = "341.5004" turn = "Turn right" turn_angle = "99.87288" start_bearing = "85.550156" end_bearing = "84.289406" description = "Turn right and go 341.50 meters" />
|
<segment id="128493079" start="0" end="10" time = "27.32003" name = "Vinohradská" distance = "341.5004" turn = "Turn right" turn_angle = "99.87288" start_bearing = "85.550156" end_bearing = "84.289406" description = "Turn right and go 341.50 meters" />
|
||||||
|
|
|
@ -1,21 +1,28 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<router_tests>
|
<router_tests>
|
||||||
<test regions="" description="Long route to Maastricht" best_percent="5" vehicle="car"
|
<test regions="" description="Long route to Maastricht" best_percent="5" vehicle="car"
|
||||||
start_lat="52.290868841722975" start_lon="4.831130504608154" target_lat="50.85492897352447" target_lon="5.701689720153809" complete_time="6897.156" loadedTiles = "185" visitedSegments = "3542" complete_distance = "208149.2" >
|
start_lat="52.290868841722975" start_lon="4.831130504608154" target_lat="50.85492897352447" target_lon="5.701689720153809" complete_time="7043.331" loadedTiles = "1785" visitedSegments = "4456" complete_distance = "208488.69" >
|
||||||
<segment id="7366509" start="9" end="11" time = "9.088743" name = "" distance = "75.739525" turn = "Go ahead" turn_angle = "0.0" start_bearing = "115.31378" end_bearing = "115.46335" description = "Go ahead and go 75.74 meters" />
|
<segment id="7366509" start="9" end="11" time = "9.088743" name = "" distance = "75.739525" turn = "Go ahead" turn_angle = "0.0" start_bearing = "115.31378" end_bearing = "115.46335" description = "Go ahead and go 75.74 meters" />
|
||||||
<segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" turn = "Turn right" turn_angle = "89.33931" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "Turn right and go 26.76 meters" />
|
<segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" turn = "Turn right" turn_angle = "89.33931" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "Turn right and go 26.76 meters" />
|
||||||
<segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 774.68 meters" />
|
<segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 761.63 meters" />
|
||||||
<segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" />
|
<segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" />
|
||||||
<segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" />
|
<segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" />
|
||||||
<segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" />
|
<segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" />
|
||||||
<segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" />
|
<segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" />
|
||||||
<segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" />
|
<segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" />
|
||||||
<segment id="7365071" start="0" end="1" time = "0.9398953" name = "Zetterij" distance = "13.054101" start_bearing = "117.97948" end_bearing = "117.97948" description = "" />
|
<segment id="7365070" start="0" end="1" time = "1.0716465" name = "Bovenkerkerweg (N521) " distance = "14.883979" turn = "Turn right" turn_angle = "94.95008" start_bearing = "-170.42577" end_bearing = "-170.42577" description = "Turn right and go 58.89 meters" />
|
||||||
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" turn = "Turn left" turn_angle = "-105.37932" start_bearing = "12.60016" end_bearing = "12.60016" description = "Turn left and go 968.58 meters" />
|
<segment id="7365086" start="0" end="1" time = "3.1682494" name = "Bovenkerkerweg (N521) " distance = "44.003468" start_bearing = "-172.57889" end_bearing = "-172.57889" description = "" />
|
||||||
|
<segment id="7365086" start="1" end="3" time = "30.227621" name = "Bovenkerkerweg (N521) " distance = "72.60584" turn = "Keep right" turn_angle = "1.9589691" start_bearing = "-170.61992" end_bearing = "-173.29016" description = "Keep right and go 110.76 meters" />
|
||||||
|
<segment id="7365099" start="0" end="3" time = "2.747028" name = "Bovenkerkerweg (N521) " distance = "38.15317" start_bearing = "-173.21103" end_bearing = "-177.61406" description = "" />
|
||||||
|
<segment id="7365062" start="6" end="7" time = "0.84723866" name = "Beneluxbaan" distance = "11.767203" turn = "Make uturn" turn_angle = "0.0" start_bearing = "97.0165" end_bearing = "97.0165" description = "Make uturn and go 1105.87 meters" />
|
||||||
|
<segment id="7365101" start="0" end="3" time = "2.8561046" name = "Bovenkerkerweg (N521) " distance = "39.66812" start_bearing = "10.885527" end_bearing = "11.458753" description = "" />
|
||||||
|
<segment id="7365085" start="0" end="1" time = "8.459829" name = "Bovenkerkerweg (N521) " distance = "117.49763" start_bearing = "6.4971123" end_bearing = "6.4971123" description = "" />
|
||||||
|
<segment id="7365069" start="0" end="1" time = "0.57796" name = "Bovenkerkerweg (N521) " distance = "8.027223" start_bearing = "5.3145456" end_bearing = "5.3145456" description = "" />
|
||||||
|
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" start_bearing = "12.60016" end_bearing = "12.60016" description = "" />
|
||||||
<segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" />
|
<segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" />
|
||||||
<segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" />
|
<segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" />
|
||||||
<segment id="7364781" start="0" end="6" time = "54.49686" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" />
|
<segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" />
|
||||||
<segment id="7364782" start="1" end="0" time = "16.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
|
<segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
|
||||||
<segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" />
|
<segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" />
|
||||||
<segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" />
|
<segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" />
|
||||||
<segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" />
|
<segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" />
|
||||||
|
@ -32,10 +39,10 @@
|
||||||
<segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" />
|
<segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" />
|
||||||
<segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" />
|
<segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" />
|
||||||
<segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" />
|
<segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" />
|
||||||
<segment id="58384522" start="0" end="4" time = "20.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" />
|
<segment id="58384522" start="0" end="4" time = "30.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" />
|
||||||
<segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" />
|
<segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" />
|
||||||
<segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" />
|
<segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" />
|
||||||
<segment id="49900222" start="0" end="1" time = "16.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" />
|
<segment id="49900222" start="0" end="1" time = "26.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" />
|
||||||
<segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" />
|
<segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" />
|
||||||
<segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" />
|
<segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" />
|
||||||
<segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" />
|
<segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" />
|
||||||
|
@ -85,7 +92,7 @@
|
||||||
<segment id="80761369" start="0" end="1" time = "1.9537628" name = " (A2) " distance = "54.27119" start_bearing = "-178.45705" end_bearing = "-178.45705" description = "" />
|
<segment id="80761369" start="0" end="1" time = "1.9537628" name = " (A2) " distance = "54.27119" start_bearing = "-178.45705" end_bearing = "-178.45705" description = "" />
|
||||||
<segment id="80761365" start="0" end="6" time = "11.0511" name = " (A2) " distance = "306.975" start_bearing = "-176.12459" end_bearing = "-171.34746" description = "" />
|
<segment id="80761365" start="0" end="6" time = "11.0511" name = " (A2) " distance = "306.975" start_bearing = "-176.12459" end_bearing = "-171.34746" description = "" />
|
||||||
<segment id="152126643" start="0" end="2" time = "16.587639" name = " (A2) " distance = "460.76776" start_bearing = "-168.47627" end_bearing = "-165.6754" description = "" />
|
<segment id="152126643" start="0" end="2" time = "16.587639" name = " (A2) " distance = "460.76776" start_bearing = "-168.47627" end_bearing = "-165.6754" description = "" />
|
||||||
<segment id="93810171" start="0" end="1" time = "8.644352" name = " (A2) " distance = "240.1209" turn = "Keep left" turn_angle = "-1.1266632" lanes = "[1, 1, 0, 0]" start_bearing = "-166.80206" end_bearing = "-166.80206" description = "Keep left[1, 1, 0, 0] and go 4539.38 meters (*)" />
|
<segment id="93810171" start="0" end="1" time = "8.644352" name = " (A2) " distance = "240.1209" turn = "Keep left" turn_angle = "-1.1266632" lanes = "[1, 1, 0, 0]" start_bearing = "-166.80206" end_bearing = "-166.80206" description = "Keep left[1, 1, 0, 0] and go 4539.38 meters" />
|
||||||
<segment id="7054468" start="0" end="2" time = "29.638718" name = " (A2) " distance = "823.2977" start_bearing = "-167.47635" end_bearing = "-165.95709" description = "" />
|
<segment id="7054468" start="0" end="2" time = "29.638718" name = " (A2) " distance = "823.2977" start_bearing = "-167.47635" end_bearing = "-165.95709" description = "" />
|
||||||
<segment id="7054457" start="0" end="1" time = "3.6500416" name = " (A2) " distance = "101.390045" start_bearing = "-166.36688" end_bearing = "-166.36688" description = "" />
|
<segment id="7054457" start="0" end="1" time = "3.6500416" name = " (A2) " distance = "101.390045" start_bearing = "-166.36688" end_bearing = "-166.36688" description = "" />
|
||||||
<segment id="7054352" start="0" end="3" time = "24.02921" name = " (A2) " distance = "667.478" start_bearing = "-165.3489" end_bearing = "-165.1765" description = "" />
|
<segment id="7054352" start="0" end="3" time = "24.02921" name = " (A2) " distance = "667.478" start_bearing = "-165.3489" end_bearing = "-165.1765" description = "" />
|
||||||
|
@ -144,18 +151,18 @@
|
||||||
<segment id="7083242" start="0" end="8" time = "23.373617" name = " (A2) " distance = "779.12054" start_bearing = "-177.66797" end_bearing = "-177.48619" description = "" />
|
<segment id="7083242" start="0" end="8" time = "23.373617" name = " (A2) " distance = "779.12054" start_bearing = "-177.66797" end_bearing = "-177.48619" description = "" />
|
||||||
<segment id="7083262" start="0" end="1" time = "1.0658783" name = " (A2) " distance = "35.529278" start_bearing = "-176.44215" end_bearing = "-176.44215" description = "" />
|
<segment id="7083262" start="0" end="1" time = "1.0658783" name = " (A2) " distance = "35.529278" start_bearing = "-176.44215" end_bearing = "-176.44215" description = "" />
|
||||||
<segment id="60928833" start="0" end="1" time = "25.311256" name = " (A2) " distance = "843.7085" start_bearing = "-177.94655" end_bearing = "-177.94655" description = "" />
|
<segment id="60928833" start="0" end="1" time = "25.311256" name = " (A2) " distance = "843.7085" start_bearing = "-177.94655" end_bearing = "-177.94655" description = "" />
|
||||||
<segment id="7082839" start="0" end="10" time = "58.871197" name = " (A2) " distance = "1962.3732" turn = "Keep left" turn_angle = "0.121292114" lanes = "[1, 1, 1, 0]" start_bearing = "-177.82526" end_bearing = "176.08842" description = "Keep left[1, 1, 1, 0] and go 2067.44 meters (*)" />
|
<segment id="7082839" start="0" end="10" time = "58.871197" name = " (A2) " distance = "1962.3732" turn = "Keep left" turn_angle = "0.121292114" lanes = "[1, 1, 1, 0]" start_bearing = "-177.82526" end_bearing = "176.08842" description = "Keep left[1, 1, 1, 0] and go 4778.54 meters (*)" />
|
||||||
<segment id="87195824" start="0" end="1" time = "3.1519196" name = " (A2) " distance = "105.06398" start_bearing = "175.76361" end_bearing = "175.76361" description = "" />
|
<segment id="87195824" start="0" end="1" time = "3.1519196" name = " (A2) " distance = "105.06398" start_bearing = "175.76361" end_bearing = "175.76361" description = "" />
|
||||||
<segment id="87195824" start="1" end="9" time = "24.882273" name = " (A2) " distance = "829.40906" turn = "Keep left" turn_angle = "0.11303711" lanes = "[1, 1, 1, 0]" start_bearing = "175.87665" end_bearing = "158.7495" description = "Keep left[1, 1, 1, 0] and go 2711.10 meters (*)" />
|
<segment id="87195824" start="1" end="9" time = "24.882273" name = " (A2) " distance = "829.40906" start_bearing = "175.87665" end_bearing = "158.7495" description = "" />
|
||||||
<segment id="87195830" start="0" end="7" time = "19.536932" name = " (A2) " distance = "651.231" start_bearing = "157.98872" end_bearing = "135.32278" description = "" />
|
<segment id="87195830" start="0" end="7" time = "19.536932" name = " (A2) " distance = "651.231" start_bearing = "157.98872" end_bearing = "135.32278" description = "" />
|
||||||
<segment id="7082846" start="0" end="1" time = "1.332016" name = " (A2) " distance = "44.40053" start_bearing = "132.66948" end_bearing = "132.66948" description = "" />
|
<segment id="7082846" start="0" end="1" time = "1.332016" name = " (A2) " distance = "44.40053" start_bearing = "132.66948" end_bearing = "132.66948" description = "" />
|
||||||
<segment id="7082849" start="0" end="3" time = "12.256795" name = " (A2) " distance = "408.5598" start_bearing = "129.9005" end_bearing = "123.859245" description = "" />
|
<segment id="7082849" start="0" end="3" time = "12.256795" name = " (A2) " distance = "408.5598" start_bearing = "129.9005" end_bearing = "123.859245" description = "" />
|
||||||
<segment id="7082851" start="0" end="1" time = "1.7693062" name = " (A2) " distance = "58.976868" start_bearing = "124.133446" end_bearing = "124.133446" description = "" />
|
<segment id="7082851" start="0" end="1" time = "1.7693062" name = " (A2) " distance = "58.976868" start_bearing = "124.133446" end_bearing = "124.133446" description = "" />
|
||||||
<segment id="7081833" start="0" end="9" time = "21.555794" name = " (A2) " distance = "718.5264" start_bearing = "125.44192" end_bearing = "141.00053" description = "" />
|
<segment id="7081833" start="0" end="9" time = "21.555794" name = " (A2) " distance = "718.5264" start_bearing = "125.44192" end_bearing = "141.00053" description = "" />
|
||||||
<segment id="7081833" start="9" end="11" time = "18.920055" name = " (A2) " distance = "630.6685" turn = "Keep left" turn_angle = "1.3838348" lanes = "[1, 1, 1, 0]" start_bearing = "142.38437" end_bearing = "143.98479" description = "Keep left[1, 1, 1, 0] and go 1705.73 meters (*)" />
|
<segment id="7081833" start="9" end="11" time = "18.920055" name = " (A2) " distance = "630.6685" turn = "Keep left" turn_angle = "1.3838348" lanes = "[1, 1, 1, 0]" start_bearing = "142.38437" end_bearing = "143.98479" description = "Keep left[1, 1, 1, 0] and go 4214.98 meters (*)" />
|
||||||
<segment id="7081844" start="0" end="1" time = "0.74438155" name = " (A2) " distance = "24.812717" start_bearing = "144.41263" end_bearing = "144.41263" description = "" />
|
<segment id="7081844" start="0" end="1" time = "0.74438155" name = " (A2) " distance = "24.812717" start_bearing = "144.41263" end_bearing = "144.41263" description = "" />
|
||||||
<segment id="7081846" start="0" end="2" time = "31.507397" name = " (A2) " distance = "1050.2466" start_bearing = "144.40886" end_bearing = "145.51918" description = "" />
|
<segment id="7081846" start="0" end="2" time = "31.507397" name = " (A2) " distance = "1050.2466" start_bearing = "144.40886" end_bearing = "145.51918" description = "" />
|
||||||
<segment id="7081846" start="2" end="3" time = "0.46107167" name = " (A2) " distance = "15.369055" turn = "Keep left" turn_angle = "0.04182434" lanes = "[1, 1, 1, 0]" start_bearing = "145.561" end_bearing = "145.561" description = "Keep left[1, 1, 1, 0] and go 2509.26 meters (*)" />
|
<segment id="7081846" start="2" end="3" time = "0.46107167" name = " (A2) " distance = "15.369055" start_bearing = "145.561" end_bearing = "145.561" description = "" />
|
||||||
<segment id="7081825" start="0" end="1" time = "1.5179313" name = " (A2) " distance = "50.59771" start_bearing = "145.9634" end_bearing = "145.9634" description = "" />
|
<segment id="7081825" start="0" end="1" time = "1.5179313" name = " (A2) " distance = "50.59771" start_bearing = "145.9634" end_bearing = "145.9634" description = "" />
|
||||||
<segment id="7081704" start="0" end="3" time = "36.545654" name = " (A2) " distance = "1218.1884" start_bearing = "145.98322" end_bearing = "145.91476" description = "" />
|
<segment id="7081704" start="0" end="3" time = "36.545654" name = " (A2) " distance = "1218.1884" start_bearing = "145.98322" end_bearing = "145.91476" description = "" />
|
||||||
<segment id="7081701" start="0" end="1" time = "3.0920525" name = " (A2) " distance = "103.068405" start_bearing = "146.47978" end_bearing = "146.47978" description = "" />
|
<segment id="7081701" start="0" end="1" time = "3.0920525" name = " (A2) " distance = "103.068405" start_bearing = "146.47978" end_bearing = "146.47978" description = "" />
|
||||||
|
@ -163,7 +170,7 @@
|
||||||
<segment id="7081386" start="0" end="1" time = "6.63905" name = " (A2) " distance = "221.30167" start_bearing = "145.88553" end_bearing = "145.88553" description = "" />
|
<segment id="7081386" start="0" end="1" time = "6.63905" name = " (A2) " distance = "221.30167" start_bearing = "145.88553" end_bearing = "145.88553" description = "" />
|
||||||
<segment id="7081384" start="0" end="1" time = "1.1803325" name = " (A2) " distance = "39.344418" start_bearing = "145.42284" end_bearing = "145.42284" description = "" />
|
<segment id="7081384" start="0" end="1" time = "1.1803325" name = " (A2) " distance = "39.344418" start_bearing = "145.42284" end_bearing = "145.42284" description = "" />
|
||||||
<segment id="7081015" start="0" end="3" time = "21.335112" name = " (A2) " distance = "711.17035" start_bearing = "145.26582" end_bearing = "140.59818" description = "" />
|
<segment id="7081015" start="0" end="3" time = "21.335112" name = " (A2) " distance = "711.17035" start_bearing = "145.26582" end_bearing = "140.59818" description = "" />
|
||||||
<segment id="54318418" start="0" end="27" time = "123.92231" name = " (A2) " distance = "4130.7437" turn = "Keep left" turn_angle = "-2.0806732" lanes = "[1, 1, 0, 0]" start_bearing = "138.5175" end_bearing = "164.93518" description = "Keep left[1, 1, 0, 0] and go 7595.80 meters (*)" />
|
<segment id="54318418" start="0" end="27" time = "123.92231" name = " (A2) " distance = "4130.7437" turn = "Keep left" turn_angle = "-2.0806732" lanes = "[1, 1, 0, 0]" start_bearing = "138.5175" end_bearing = "164.93518" description = "Keep left[1, 1, 0, 0] and go 7595.80 meters" />
|
||||||
<segment id="6950203" start="0" end="1" time = "1.0974485" name = " (A2) " distance = "36.581615" start_bearing = "166.4589" end_bearing = "166.4589" description = "" />
|
<segment id="6950203" start="0" end="1" time = "1.0974485" name = " (A2) " distance = "36.581615" start_bearing = "166.4589" end_bearing = "166.4589" description = "" />
|
||||||
<segment id="35286295" start="0" end="4" time = "8.819818" name = " (A2) " distance = "293.9939" start_bearing = "167.24911" end_bearing = "172.56018" description = "" />
|
<segment id="35286295" start="0" end="4" time = "8.819818" name = " (A2) " distance = "293.9939" start_bearing = "167.24911" end_bearing = "172.56018" description = "" />
|
||||||
<segment id="35266566" start="0" end="2" time = "3.0470872" name = " (A2) " distance = "101.56957" start_bearing = "174.98376" end_bearing = "177.47758" description = "" />
|
<segment id="35266566" start="0" end="2" time = "3.0470872" name = " (A2) " distance = "101.56957" start_bearing = "174.98376" end_bearing = "177.47758" description = "" />
|
||||||
|
@ -195,10 +202,10 @@
|
||||||
<segment id="7173912" start="0" end="8" time = "12.146003" name = " (A2) " distance = "404.86673" start_bearing = "164.6402" end_bearing = "175.66768" description = "" />
|
<segment id="7173912" start="0" end="8" time = "12.146003" name = " (A2) " distance = "404.86673" start_bearing = "164.6402" end_bearing = "175.66768" description = "" />
|
||||||
<segment id="7173915" start="0" end="1" time = "1.8925273" name = " (A2) " distance = "63.084244" start_bearing = "177.30571" end_bearing = "177.30571" description = "" />
|
<segment id="7173915" start="0" end="1" time = "1.8925273" name = " (A2) " distance = "63.084244" start_bearing = "177.30571" end_bearing = "177.30571" description = "" />
|
||||||
<segment id="7173917" start="0" end="1" time = "1.7798107" name = " (A2) " distance = "59.32702" start_bearing = "178.19316" end_bearing = "178.19316" description = "" />
|
<segment id="7173917" start="0" end="1" time = "1.7798107" name = " (A2) " distance = "59.32702" start_bearing = "178.19316" end_bearing = "178.19316" description = "" />
|
||||||
<segment id="7173917" start="1" end="2" time = "4.5603037" name = " (A2) " distance = "152.01012" turn = "Keep left" turn_angle = "0.6930847" lanes = "[1, 1, 0]" start_bearing = "178.88625" end_bearing = "178.88625" description = "Keep left[1, 1, 0] and go 1775.60 meters (*)" />
|
<segment id="7173917" start="1" end="2" time = "4.5603037" name = " (A2) " distance = "152.01012" turn = "Keep left" turn_angle = "0.6930847" lanes = "[1, 1, 0]" start_bearing = "178.88625" end_bearing = "178.88625" description = "Keep left[1, 1, 0] and go 6521.90 meters (*)" />
|
||||||
<segment id="7173905" start="0" end="1" time = "1.4901867" name = " (A2) " distance = "49.67289" start_bearing = "-180.0" end_bearing = "180.0" description = "" />
|
<segment id="7173905" start="0" end="1" time = "1.4901867" name = " (A2) " distance = "49.67289" start_bearing = "-180.0" end_bearing = "180.0" description = "" />
|
||||||
<segment id="7173935" start="0" end="5" time = "47.21756" name = " (A2) " distance = "1573.9186" start_bearing = "178.95203" end_bearing = "176.12459" description = "" />
|
<segment id="7173935" start="0" end="5" time = "47.21756" name = " (A2) " distance = "1573.9186" start_bearing = "178.95203" end_bearing = "176.12459" description = "" />
|
||||||
<segment id="7173935" start="5" end="21" time = "142.38881" name = " (A2) " distance = "4746.2935" turn = "Keep left" turn_angle = "-1.4848022" lanes = "[1, 1, 0]" start_bearing = "174.63979" end_bearing = "145.51537" description = "Keep left[1, 1, 0] and go 4746.29 meters (*)" />
|
<segment id="7173935" start="5" end="21" time = "142.38881" name = " (A2) " distance = "4746.2935" start_bearing = "174.63979" end_bearing = "145.51537" description = "" />
|
||||||
<segment id="7173935" start="21" end="29" time = "67.018425" name = " (A2) " distance = "2233.9475" turn = "Keep left" turn_angle = "-0.6148071" lanes = "[1, 1, 0]" start_bearing = "144.90056" end_bearing = "141.10718" description = "Keep left[1, 1, 0] and go 2233.95 meters (*)" />
|
<segment id="7173935" start="21" end="29" time = "67.018425" name = " (A2) " distance = "2233.9475" turn = "Keep left" turn_angle = "-0.6148071" lanes = "[1, 1, 0]" start_bearing = "144.90056" end_bearing = "141.10718" description = "Keep left[1, 1, 0] and go 2233.95 meters (*)" />
|
||||||
<segment id="7173935" start="29" end="32" time = "14.9291725" name = " (A2) " distance = "497.63907" turn = "Keep left" turn_angle = "-1.8707886" lanes = "[1, 1, 0]" start_bearing = "139.23639" end_bearing = "138.31236" description = "Keep left[1, 1, 0] and go 1980.99 meters (*)" />
|
<segment id="7173935" start="29" end="32" time = "14.9291725" name = " (A2) " distance = "497.63907" turn = "Keep left" turn_angle = "-1.8707886" lanes = "[1, 1, 0]" start_bearing = "139.23639" end_bearing = "138.31236" description = "Keep left[1, 1, 0] and go 1980.99 meters (*)" />
|
||||||
<segment id="7179075" start="0" end="1" time = "1.5465801" name = " (A2) " distance = "51.55267" start_bearing = "138.19594" end_bearing = "138.19594" description = "" />
|
<segment id="7179075" start="0" end="1" time = "1.5465801" name = " (A2) " distance = "51.55267" start_bearing = "138.19594" end_bearing = "138.19594" description = "" />
|
||||||
|
@ -250,14 +257,14 @@
|
||||||
<segment id="34601788" start="0" end="2" time = "17.838524" name = " (A2;A67) " distance = "594.61743" start_bearing = "92.92696" end_bearing = "92.76961" description = "" />
|
<segment id="34601788" start="0" end="2" time = "17.838524" name = " (A2;A67) " distance = "594.61743" start_bearing = "92.92696" end_bearing = "92.76961" description = "" />
|
||||||
<segment id="129359000" start="0" end="1" time = "0.8941588" name = " (A2;A67) " distance = "29.80529" start_bearing = "92.80981" end_bearing = "92.80981" description = "" />
|
<segment id="129359000" start="0" end="1" time = "0.8941588" name = " (A2;A67) " distance = "29.80529" start_bearing = "92.80981" end_bearing = "92.80981" description = "" />
|
||||||
<segment id="129359001" start="0" end="1" time = "0.17860866" name = " (A2;A67) " distance = "5.953622" start_bearing = "91.7357" end_bearing = "91.7357" description = "" />
|
<segment id="129359001" start="0" end="1" time = "0.17860866" name = " (A2;A67) " distance = "5.953622" start_bearing = "91.7357" end_bearing = "91.7357" description = "" />
|
||||||
<segment id="41960113" start="0" end="9" time = "12.305996" name = " (A2) " distance = "410.19983" turn = "Keep left" turn_angle = "0.41725922" lanes = "[1, 1, 0, 0]" start_bearing = "92.15296" end_bearing = "107.69364" description = "Keep left[1, 1, 0, 0] and go 6969.30 meters (*)" />
|
<segment id="41960113" start="0" end="9" time = "12.305996" name = " (A2) " distance = "410.19983" turn = "Keep left" turn_angle = "0.41725922" lanes = "[1, 1, 0, 0]" start_bearing = "92.15296" end_bearing = "107.69364" description = "Keep left[1, 1, 0, 0] and go 6969.30 meters" />
|
||||||
<segment id="46177355" start="0" end="3" time = "2.9886634" name = " (A2) " distance = "99.62211" start_bearing = "107.61258" end_bearing = "111.48204" description = "" />
|
<segment id="46177355" start="0" end="3" time = "2.9886634" name = " (A2) " distance = "99.62211" start_bearing = "107.61258" end_bearing = "111.48204" description = "" />
|
||||||
<segment id="7181608" start="0" end="13" time = "14.447598" name = " (A2) " distance = "481.5866" start_bearing = "112.94894" end_bearing = "141.93434" description = "" />
|
<segment id="7181608" start="0" end="13" time = "14.447598" name = " (A2) " distance = "481.5866" start_bearing = "112.94894" end_bearing = "141.93434" description = "" />
|
||||||
<segment id="129358985" start="0" end="2" time = "2.1925447" name = " (A2) " distance = "73.08482" start_bearing = "146.47247" end_bearing = "146.47247" description = "" />
|
<segment id="129358985" start="0" end="2" time = "2.1925447" name = " (A2) " distance = "73.08482" start_bearing = "146.47247" end_bearing = "146.47247" description = "" />
|
||||||
<segment id="129358986" start="0" end="10" time = "15.391882" name = " (A2) " distance = "513.0627" start_bearing = "148.48593" end_bearing = "174.4588" description = "" />
|
<segment id="129358986" start="0" end="10" time = "15.391882" name = " (A2) " distance = "513.0627" start_bearing = "148.48593" end_bearing = "174.4588" description = "" />
|
||||||
<segment id="57124219" start="0" end="1" time = "3.6961312" name = " (A2) " distance = "123.20437" start_bearing = "163.70851" end_bearing = "163.70851" description = "" />
|
<segment id="57124219" start="0" end="1" time = "3.6961312" name = " (A2) " distance = "123.20437" start_bearing = "163.70851" end_bearing = "163.70851" description = "" />
|
||||||
<segment id="7138181" start="0" end="11" time = "158.05623" name = " (A2) " distance = "5268.541" start_bearing = "164.86745" end_bearing = "150.9332" description = "" />
|
<segment id="7138181" start="0" end="11" time = "158.05623" name = " (A2) " distance = "5268.541" start_bearing = "164.86745" end_bearing = "150.9332" description = "" />
|
||||||
<segment id="7138582" start="0" end="1" time = "12.939249" name = " (A2) " distance = "431.3083" turn = "Keep left" turn_angle = "1.0292664" lanes = "[1, 1, 0]" start_bearing = "151.96246" end_bearing = "151.96246" description = "Keep left[1, 1, 0] and go 4949.16 meters (*)" />
|
<segment id="7138582" start="0" end="1" time = "12.939249" name = " (A2) " distance = "431.3083" turn = "Keep left" turn_angle = "1.0292664" lanes = "[1, 1, 0]" start_bearing = "151.96246" end_bearing = "151.96246" description = "Keep left[1, 1, 0] and go 6302.33 meters (*)" />
|
||||||
<segment id="7138584" start="0" end="1" time = "1.9605826" name = " (A2) " distance = "65.35275" start_bearing = "151.7652" end_bearing = "151.7652" description = "" />
|
<segment id="7138584" start="0" end="1" time = "1.9605826" name = " (A2) " distance = "65.35275" start_bearing = "151.7652" end_bearing = "151.7652" description = "" />
|
||||||
<segment id="7138593" start="0" end="8" time = "22.77318" name = " (A2) " distance = "759.106" start_bearing = "149.63991" end_bearing = "122.376434" description = "" />
|
<segment id="7138593" start="0" end="8" time = "22.77318" name = " (A2) " distance = "759.106" start_bearing = "149.63991" end_bearing = "122.376434" description = "" />
|
||||||
<segment id="7138594" start="0" end="1" time = "1.104279" name = " (A2) " distance = "36.809303" start_bearing = "122.19573" end_bearing = "122.19573" description = "" />
|
<segment id="7138594" start="0" end="1" time = "1.104279" name = " (A2) " distance = "36.809303" start_bearing = "122.19573" end_bearing = "122.19573" description = "" />
|
||||||
|
@ -267,7 +274,7 @@
|
||||||
<segment id="7138608" start="0" end="1" time = "0.5713057" name = " (A2) " distance = "19.043524" start_bearing = "121.53479" end_bearing = "121.53479" description = "" />
|
<segment id="7138608" start="0" end="1" time = "0.5713057" name = " (A2) " distance = "19.043524" start_bearing = "121.53479" end_bearing = "121.53479" description = "" />
|
||||||
<segment id="7138570" start="0" end="4" time = "30.841974" name = " (A2) " distance = "1028.0658" start_bearing = "122.167595" end_bearing = "120.012825" description = "" />
|
<segment id="7138570" start="0" end="4" time = "30.841974" name = " (A2) " distance = "1028.0658" start_bearing = "122.167595" end_bearing = "120.012825" description = "" />
|
||||||
<segment id="7137120" start="0" end="9" time = "60.733063" name = " (A2) " distance = "2024.4354" start_bearing = "119.456055" end_bearing = "142.62645" description = "" />
|
<segment id="7137120" start="0" end="9" time = "60.733063" name = " (A2) " distance = "2024.4354" start_bearing = "119.456055" end_bearing = "142.62645" description = "" />
|
||||||
<segment id="7137120" start="9" end="12" time = "19.791756" name = " (A2) " distance = "659.72516" turn = "Keep left" turn_angle = "-0.8337555" lanes = "[1, 1, 0]" start_bearing = "141.7927" end_bearing = "142.10811" description = "Keep left[1, 1, 0] and go 1353.16 meters (*)" />
|
<segment id="7137120" start="9" end="12" time = "19.791756" name = " (A2) " distance = "659.72516" start_bearing = "141.7927" end_bearing = "142.10811" description = "" />
|
||||||
<segment id="7137076" start="0" end="1" time = "1.9422636" name = " (A2) " distance = "64.74212" start_bearing = "142.06673" end_bearing = "142.06673" description = "" />
|
<segment id="7137076" start="0" end="1" time = "1.9422636" name = " (A2) " distance = "64.74212" start_bearing = "142.06673" end_bearing = "142.06673" description = "" />
|
||||||
<segment id="7137093" start="0" end="2" time = "18.860876" name = " (A2) " distance = "628.6958" start_bearing = "143.43219" end_bearing = "148.48138" description = "" />
|
<segment id="7137093" start="0" end="2" time = "18.860876" name = " (A2) " distance = "628.6958" start_bearing = "143.43219" end_bearing = "148.48138" description = "" />
|
||||||
<segment id="7137085" start="0" end="2" time = "8.986393" name = " (A2) " distance = "299.54642" turn = "Keep left" turn_angle = "-1.9695587" lanes = "[1, 1, 0]" start_bearing = "146.51183" end_bearing = "144.0556" description = "Keep left[1, 1, 0] and go 2280.14 meters (*)" />
|
<segment id="7137085" start="0" end="2" time = "8.986393" name = " (A2) " distance = "299.54642" turn = "Keep left" turn_angle = "-1.9695587" lanes = "[1, 1, 0]" start_bearing = "146.51183" end_bearing = "144.0556" description = "Keep left[1, 1, 0] and go 2280.14 meters (*)" />
|
||||||
|
@ -282,17 +289,17 @@
|
||||||
<segment id="7134786" start="0" end="4" time = "6.239682" name = " (A2) " distance = "207.9894" start_bearing = "132.66269" end_bearing = "143.909" description = "" />
|
<segment id="7134786" start="0" end="4" time = "6.239682" name = " (A2) " distance = "207.9894" start_bearing = "132.66269" end_bearing = "143.909" description = "" />
|
||||||
<segment id="7134786" start="4" end="18" time = "46.656086" name = " (A2) " distance = "1555.2029" turn = "Keep left" turn_angle = "3.9660034" lanes = "[1, 1, 0]" start_bearing = "147.875" end_bearing = "129.92787" description = "Keep left[1, 1, 0] and go 1555.20 meters (*)" />
|
<segment id="7134786" start="4" end="18" time = "46.656086" name = " (A2) " distance = "1555.2029" turn = "Keep left" turn_angle = "3.9660034" lanes = "[1, 1, 0]" start_bearing = "147.875" end_bearing = "129.92787" description = "Keep left[1, 1, 0] and go 1555.20 meters (*)" />
|
||||||
<segment id="7133368" start="0" end="45" time = "161.42354" name = " (A2) " distance = "5380.784" turn = "Keep left" turn_angle = "-7.772148" lanes = "[1, 1, 0]" start_bearing = "122.15572" end_bearing = "127.22508" description = "Keep left[1, 1, 0] and go 5380.78 meters (*)" />
|
<segment id="7133368" start="0" end="45" time = "161.42354" name = " (A2) " distance = "5380.784" turn = "Keep left" turn_angle = "-7.772148" lanes = "[1, 1, 0]" start_bearing = "122.15572" end_bearing = "127.22508" description = "Keep left[1, 1, 0] and go 5380.78 meters (*)" />
|
||||||
<segment id="6735354" start="0" end="1" time = "3.023609" name = " (A2) " distance = "100.78696" turn = "Keep left" turn_angle = "7.550812" lanes = "[1, 1, 0]" start_bearing = "134.7759" end_bearing = "134.7759" description = "Keep left[1, 1, 0] and go 3543.38 meters (*)" />
|
<segment id="6735354" start="0" end="1" time = "3.023609" name = " (A2) " distance = "100.78696" turn = "Keep left" turn_angle = "7.550812" lanes = "[1, 1, 0]" start_bearing = "134.7759" end_bearing = "134.7759" description = "Keep left[1, 1, 0] and go 6298.18 meters (*)" />
|
||||||
<segment id="57123265" start="0" end="4" time = "11.997399" name = " (A2) " distance = "399.9133" start_bearing = "139.2456" end_bearing = "150.65193" description = "" />
|
<segment id="57123265" start="0" end="4" time = "11.997399" name = " (A2) " distance = "399.9133" start_bearing = "139.2456" end_bearing = "150.65193" description = "" />
|
||||||
<segment id="6735330" start="0" end="1" time = "1.8624623" name = " (A2) " distance = "62.082073" start_bearing = "152.81473" end_bearing = "152.81473" description = "" />
|
<segment id="6735330" start="0" end="1" time = "1.8624623" name = " (A2) " distance = "62.082073" start_bearing = "152.81473" end_bearing = "152.81473" description = "" />
|
||||||
<segment id="6735347" start="0" end="3" time = "19.002733" name = " (A2) " distance = "633.4244" start_bearing = "153.98177" end_bearing = "158.04019" description = "" />
|
<segment id="6735347" start="0" end="3" time = "19.002733" name = " (A2) " distance = "633.4244" start_bearing = "153.98177" end_bearing = "158.04019" description = "" />
|
||||||
<segment id="6735335" start="0" end="1" time = "2.4163463" name = " (A2) " distance = "80.54487" start_bearing = "159.67686" end_bearing = "159.67686" description = "" />
|
<segment id="6735335" start="0" end="1" time = "2.4163463" name = " (A2) " distance = "80.54487" start_bearing = "159.67686" end_bearing = "159.67686" description = "" />
|
||||||
<segment id="6733875" start="0" end="12" time = "67.998856" name = " (A2) " distance = "2266.6284" start_bearing = "158.63722" end_bearing = "121.59014" description = "" />
|
<segment id="6733875" start="0" end="12" time = "67.998856" name = " (A2) " distance = "2266.6284" start_bearing = "158.63722" end_bearing = "121.59014" description = "" />
|
||||||
<segment id="6733875" start="12" end="30" time = "82.64402" name = " (A2) " distance = "2754.8008" turn = "Keep left" turn_angle = "-0.029792786" lanes = "[1, 1, 0]" start_bearing = "121.56035" end_bearing = "146.53694" description = "Keep left[1, 1, 0] and go 2754.80 meters (*)" />
|
<segment id="6733875" start="12" end="30" time = "82.64402" name = " (A2) " distance = "2754.8008" start_bearing = "121.56035" end_bearing = "146.53694" description = "" />
|
||||||
<segment id="6733875" start="30" end="31" time = "5.352952" name = " (A2) " distance = "178.43173" turn = "Keep left" turn_angle = "-1.6221619" lanes = "[1, 1, 0]" start_bearing = "144.91478" end_bearing = "144.91478" description = "Keep left[1, 1, 0] and go 2295.99 meters (*)" />
|
<segment id="6733875" start="30" end="31" time = "5.352952" name = " (A2) " distance = "178.43173" turn = "Keep left" turn_angle = "-1.6221619" lanes = "[1, 1, 0]" start_bearing = "144.91478" end_bearing = "144.91478" description = "Keep left[1, 1, 0] and go 7194.36 meters (*)" />
|
||||||
<segment id="6733858" start="0" end="1" time = "1.2741007" name = " (A2) " distance = "42.47002" start_bearing = "144.78241" end_bearing = "144.78241" description = "" />
|
<segment id="6733858" start="0" end="1" time = "1.2741007" name = " (A2) " distance = "42.47002" start_bearing = "144.78241" end_bearing = "144.78241" description = "" />
|
||||||
<segment id="6761009" start="0" end="8" time = "62.252544" name = " (A2) " distance = "2075.0847" start_bearing = "142.9811" end_bearing = "149.37885" description = "" />
|
<segment id="6761009" start="0" end="8" time = "62.252544" name = " (A2) " distance = "2075.0847" start_bearing = "142.9811" end_bearing = "149.37885" description = "" />
|
||||||
<segment id="6761009" start="8" end="19" time = "146.95122" name = " (A2) " distance = "4898.3735" turn = "Keep left" turn_angle = "0.2501831" lanes = "[1, 1, 0]" start_bearing = "149.62903" end_bearing = "157.77496" description = "Keep left[1, 1, 0] and go 4898.37 meters (*)" />
|
<segment id="6761009" start="8" end="19" time = "146.95122" name = " (A2) " distance = "4898.3735" start_bearing = "149.62903" end_bearing = "157.77496" description = "" />
|
||||||
<segment id="6761009" start="19" end="27" time = "28.343882" name = " (A2) " distance = "944.796" turn = "Keep left" turn_angle = "1.53656" lanes = "[1, 1, 0]" start_bearing = "159.31152" end_bearing = "138.09918" description = "Keep left[1, 1, 0] and go 4997.55 meters (*)" />
|
<segment id="6761009" start="19" end="27" time = "28.343882" name = " (A2) " distance = "944.796" turn = "Keep left" turn_angle = "1.53656" lanes = "[1, 1, 0]" start_bearing = "159.31152" end_bearing = "138.09918" description = "Keep left[1, 1, 0] and go 4997.55 meters (*)" />
|
||||||
<segment id="6760794" start="0" end="11" time = "48.690052" name = " (A2) " distance = "1623.0017" start_bearing = "137.40173" end_bearing = "113.73268" description = "" />
|
<segment id="6760794" start="0" end="11" time = "48.690052" name = " (A2) " distance = "1623.0017" start_bearing = "137.40173" end_bearing = "113.73268" description = "" />
|
||||||
<segment id="37874907" start="0" end="1" time = "1.0846229" name = " (A2) " distance = "36.154095" start_bearing = "114.14554" end_bearing = "114.14554" description = "" />
|
<segment id="37874907" start="0" end="1" time = "1.0846229" name = " (A2) " distance = "36.154095" start_bearing = "114.14554" end_bearing = "114.14554" description = "" />
|
||||||
|
@ -318,8 +325,8 @@
|
||||||
<segment id="6756968" start="0" end="12" time = "51.92214" name = " (A2) " distance = "1730.7379" start_bearing = "-131.39786" end_bearing = "-151.28493" description = "" />
|
<segment id="6756968" start="0" end="12" time = "51.92214" name = " (A2) " distance = "1730.7379" start_bearing = "-131.39786" end_bearing = "-151.28493" description = "" />
|
||||||
<segment id="6756967" start="0" end="1" time = "0.86474246" name = " (A2) " distance = "28.824747" start_bearing = "-151.12456" end_bearing = "-151.12456" description = "" />
|
<segment id="6756967" start="0" end="1" time = "0.86474246" name = " (A2) " distance = "28.824747" start_bearing = "-151.12456" end_bearing = "-151.12456" description = "" />
|
||||||
<segment id="6764626" start="0" end="13" time = "76.00803" name = " (A2) " distance = "2533.601" start_bearing = "-151.3797" end_bearing = "-170.0643" description = "" />
|
<segment id="6764626" start="0" end="13" time = "76.00803" name = " (A2) " distance = "2533.601" start_bearing = "-151.3797" end_bearing = "-170.0643" description = "" />
|
||||||
<segment id="6764626" start="13" end="22" time = "39.152573" name = " (A2) " distance = "1305.0857" turn = "Keep left" turn_angle = "-3.17984" lanes = "[1, 1, 0]" start_bearing = "-173.24414" end_bearing = "171.15948" description = "Keep left[1, 1, 0] and go 1305.09 meters (*)" />
|
<segment id="6764626" start="13" end="22" time = "39.152573" name = " (A2) " distance = "1305.0857" turn = "Keep left" turn_angle = "-3.17984" lanes = "[1, 1, 0]" start_bearing = "-173.24414" end_bearing = "171.15948" description = "Keep left[1, 1, 0] and go 3249.24 meters (*)" />
|
||||||
<segment id="6764626" start="22" end="28" time = "34.96675" name = " (A2) " distance = "1165.5583" turn = "Keep left" turn_angle = "0.58154297" lanes = "[1, 1, 0]" start_bearing = "171.74103" end_bearing = "-178.93416" description = "Keep left[1, 1, 0] and go 1944.16 meters (*)" />
|
<segment id="6764626" start="22" end="28" time = "34.96675" name = " (A2) " distance = "1165.5583" start_bearing = "171.74103" end_bearing = "-178.93416" description = "" />
|
||||||
<segment id="6764627" start="0" end="1" time = "1.2607403" name = " (A2) " distance = "42.024677" start_bearing = "-176.93352" end_bearing = "-176.93352" description = "" />
|
<segment id="6764627" start="0" end="1" time = "1.2607403" name = " (A2) " distance = "42.024677" start_bearing = "-176.93352" end_bearing = "-176.93352" description = "" />
|
||||||
<segment id="6764640" start="0" end="2" time = "6.8866363" name = " (A2) " distance = "229.55453" start_bearing = "-177.31622" end_bearing = "-173.53018" description = "" />
|
<segment id="6764640" start="0" end="2" time = "6.8866363" name = " (A2) " distance = "229.55453" start_bearing = "-177.31622" end_bearing = "-173.53018" description = "" />
|
||||||
<segment id="6764637" start="0" end="1" time = "1.7470565" name = " (A2) " distance = "58.235214" start_bearing = "-173.29016" end_bearing = "-173.29016" description = "" />
|
<segment id="6764637" start="0" end="1" time = "1.7470565" name = " (A2) " distance = "58.235214" start_bearing = "-173.29016" end_bearing = "-173.29016" description = "" />
|
||||||
|
@ -334,19 +341,24 @@
|
||||||
<segment id="6776798" start="0" end="3" time = "13.407926" name = " (A2) " distance = "446.93085" start_bearing = "-163.23038" end_bearing = "-167.19052" description = "" />
|
<segment id="6776798" start="0" end="3" time = "13.407926" name = " (A2) " distance = "446.93085" start_bearing = "-163.23038" end_bearing = "-167.19052" description = "" />
|
||||||
<segment id="6776788" start="0" end="1" time = "1.570805" name = " (A2) " distance = "52.36016" start_bearing = "-171.61038" end_bearing = "-171.61038" description = "" />
|
<segment id="6776788" start="0" end="1" time = "1.570805" name = " (A2) " distance = "52.36016" start_bearing = "-171.61038" end_bearing = "-171.61038" description = "" />
|
||||||
<segment id="6774982" start="0" end="11" time = "31.075895" name = " (A2) " distance = "1035.8632" start_bearing = "-174.4368" end_bearing = "155.75833" description = "" />
|
<segment id="6774982" start="0" end="11" time = "31.075895" name = " (A2) " distance = "1035.8632" start_bearing = "-174.4368" end_bearing = "155.75833" description = "" />
|
||||||
<segment id="6774982" start="11" end="16" time = "8.318511" name = " (A2) " distance = "277.2837" turn = "Keep left" turn_angle = "1.7171173" lanes = "[1, 1, 0]" start_bearing = "157.47545" end_bearing = "165.72327" description = "Keep left[1, 1, 0] and go 2484.68 meters (*)" />
|
<segment id="6774984" start="0" end="3" time = "8.277423" name = " (A2) " distance = "275.9141" turn = "Keep right" turn_angle = "8.29628" lanes = "[0, 0, 1]" start_bearing = "164.05461" end_bearing = "164.55247" description = "Keep right[0, 0, 1] and go 675.00 meters" />
|
||||||
<segment id="6774986" start="0" end="1" time = "1.193324" name = " (A2) " distance = "39.777462" start_bearing = "167.14766" end_bearing = "167.14766" description = "" />
|
<segment id="6774985" start="0" end="1" time = "1.1368768" name = " (A2) " distance = "37.895893" start_bearing = "166.94069" end_bearing = "166.94069" description = "" />
|
||||||
<segment id="6774822" start="0" end="7" time = "22.103643" name = " (A2) " distance = "736.7881" start_bearing = "168.73532" end_bearing = "-175.156" description = "" />
|
<segment id="6774979" start="0" end="1" time = "0.96351945" name = " (A2) " distance = "32.117313" start_bearing = "168.36636" end_bearing = "168.36636" description = "" />
|
||||||
<segment id="6775285" start="0" end="1" time = "2.0140622" name = " (A2) " distance = "67.1354" start_bearing = "-175.16959" end_bearing = "-175.16959" description = "" />
|
<segment id="6774821" start="0" end="5" time = "9.872207" name = " (A2) " distance = "329.07355" start_bearing = "170.36246" end_bearing = "176.13081" description = "" />
|
||||||
<segment id="6775316" start="0" end="3" time = "31.417942" name = " (A2) " distance = "1047.2646" start_bearing = "-175.58209" end_bearing = "-177.13759" description = "" />
|
<segment id="6774821" start="5" end="8" time = "10.706974" name = " (A2) " distance = "356.8991" turn = "Keep left" turn_angle = "5.017029" lanes = "[1, 0]" start_bearing = "-178.85216" end_bearing = "-174.92787" description = "Keep left[1, 0] and go 478.32 meters" />
|
||||||
|
<segment id="6775289" start="0" end="1" time = "0.4754576" name = " (A2) " distance = "15.848586" start_bearing = "-175.12073" end_bearing = "-175.12073" description = "" />
|
||||||
|
<segment id="6775286" start="0" end="1" time = "1.9916139" name = " (A2) " distance = "66.38713" start_bearing = "-174.54448" end_bearing = "-174.54448" description = "" />
|
||||||
|
<segment id="6775315" start="0" end="1" time = "1.175504" name = " (A2) " distance = "39.183464" start_bearing = "-176.40643" end_bearing = "-176.40643" description = "" />
|
||||||
|
<segment id="6775263" start="0" end="1" time = "14.832899" name = " (A2) " distance = "494.42993" turn = "Keep left" turn_angle = "0.9855652" lanes = "[1, 0]" start_bearing = "-175.42087" end_bearing = "-175.42087" description = "Keep left[1, 0] and go 1326.35 meters" />
|
||||||
|
<segment id="6775253" start="0" end="4" time = "15.464679" name = " (A2) " distance = "515.48926" start_bearing = "-175.13548" end_bearing = "179.25352" description = "" />
|
||||||
<segment id="6775293" start="0" end="3" time = "8.217698" name = " (A2) " distance = "273.92325" start_bearing = "178.83086" end_bearing = "173.03853" description = "" />
|
<segment id="6775293" start="0" end="3" time = "8.217698" name = " (A2) " distance = "273.92325" start_bearing = "178.83086" end_bearing = "173.03853" description = "" />
|
||||||
<segment id="80503748" start="0" end="1" time = "1.2753391" name = " (A2) " distance = "42.511303" start_bearing = "172.01514" end_bearing = "172.01514" description = "" />
|
<segment id="80503748" start="0" end="1" time = "1.2753391" name = " (A2) " distance = "42.511303" start_bearing = "172.01514" end_bearing = "172.01514" description = "" />
|
||||||
<segment id="80503746" start="0" end="5" time = "20.195436" name = " (A2) " distance = "673.1812" turn = "Keep left" turn_angle = "-3.4476776" lanes = "[1, 1, 0]" start_bearing = "168.56746" end_bearing = "174.3032" description = "Keep left[1, 1, 0] and go 1875.95 meters (*)" />
|
<segment id="80503746" start="0" end="5" time = "20.195436" name = " (A2) " distance = "673.1812" turn = "Keep left" turn_angle = "-3.4476776" lanes = "[1, 1, 0]" start_bearing = "168.56746" end_bearing = "174.3032" description = "Keep left[1, 1, 0] and go 2945.10 meters (*)" />
|
||||||
<segment id="6775303" start="0" end="1" time = "2.5965672" name = " (A2) " distance = "86.55224" start_bearing = "177.13136" end_bearing = "177.13136" description = "" />
|
<segment id="6775303" start="0" end="1" time = "2.5965672" name = " (A2) " distance = "86.55224" start_bearing = "177.13136" end_bearing = "177.13136" description = "" />
|
||||||
<segment id="6773089" start="0" end="5" time = "14.480419" name = " (A2) " distance = "482.68063" start_bearing = "177.7094" end_bearing = "-171.79578" description = "" />
|
<segment id="6773089" start="0" end="5" time = "14.480419" name = " (A2) " distance = "482.68063" start_bearing = "177.7094" end_bearing = "-171.79578" description = "" />
|
||||||
<segment id="6773086" start="0" end="1" time = "0.97906727" name = " (A2) " distance = "32.635574" start_bearing = "-170.75389" end_bearing = "-170.75389" description = "" />
|
<segment id="6773086" start="0" end="1" time = "0.97906727" name = " (A2) " distance = "32.635574" start_bearing = "-170.75389" end_bearing = "-170.75389" description = "" />
|
||||||
<segment id="6777666" start="0" end="7" time = "18.026918" name = " (A2) " distance = "600.8972" start_bearing = "-169.69516" end_bearing = "-160.51387" description = "" />
|
<segment id="6777666" start="0" end="7" time = "18.026918" name = " (A2) " distance = "600.8972" start_bearing = "-169.69516" end_bearing = "-160.51387" description = "" />
|
||||||
<segment id="6777666" start="7" end="8" time = "2.2491179" name = " (A2) " distance = "74.9706" turn = "Keep left" turn_angle = "1.9710846" lanes = "[1, 1, 0]" start_bearing = "-158.54279" end_bearing = "-158.54279" description = "Keep left[1, 1, 0] and go 1069.15 meters (*)" />
|
<segment id="6777666" start="7" end="8" time = "2.2491179" name = " (A2) " distance = "74.9706" start_bearing = "-158.54279" end_bearing = "-158.54279" description = "" />
|
||||||
<segment id="163556624" start="0" end="1" time = "0.64583343" name = " (A2) " distance = "21.527779" start_bearing = "-157.61986" end_bearing = "-157.61986" description = "" />
|
<segment id="163556624" start="0" end="1" time = "0.64583343" name = " (A2) " distance = "21.527779" start_bearing = "-157.61986" end_bearing = "-157.61986" description = "" />
|
||||||
<segment id="163556988" start="0" end="5" time = "18.745827" name = " (A2) " distance = "624.86084" start_bearing = "-155.4445" end_bearing = "-149.23146" description = "" />
|
<segment id="163556988" start="0" end="5" time = "18.745827" name = " (A2) " distance = "624.86084" start_bearing = "-155.4445" end_bearing = "-149.23146" description = "" />
|
||||||
<segment id="6777681" start="0" end="1" time = "1.31523" name = " (A2) " distance = "43.841" start_bearing = "-148.86969" end_bearing = "-148.86969" description = "" />
|
<segment id="6777681" start="0" end="1" time = "1.31523" name = " (A2) " distance = "43.841" start_bearing = "-148.86969" end_bearing = "-148.86969" description = "" />
|
||||||
|
@ -371,20 +383,21 @@
|
||||||
<segment id="7125104" start="0" end="1" time = "0.87968373" name = " (A2) " distance = "21.992092" start_bearing = "-140.5722" end_bearing = "-140.5722" description = "" />
|
<segment id="7125104" start="0" end="1" time = "0.87968373" name = " (A2) " distance = "21.992092" start_bearing = "-140.5722" end_bearing = "-140.5722" description = "" />
|
||||||
<segment id="132365571" start="0" end="5" time = "26.710241" name = " (A2) " distance = "519.3658" start_bearing = "-141.59787" end_bearing = "-145.58632" description = "" />
|
<segment id="132365571" start="0" end="5" time = "26.710241" name = " (A2) " distance = "519.3658" start_bearing = "-141.59787" end_bearing = "-145.58632" description = "" />
|
||||||
<segment id="7125108" start="0" end="1" time = "3.795417" name = " (A2) " distance = "52.714127" start_bearing = "-143.29416" end_bearing = "-143.29416" description = "" />
|
<segment id="7125108" start="0" end="1" time = "3.795417" name = " (A2) " distance = "52.714127" start_bearing = "-143.29416" end_bearing = "-143.29416" description = "" />
|
||||||
<segment id="74176013" start="0" end="5" time = "48.209896" name = "Viaductweg" distance = "252.9152" turn = "Turn right" turn_angle = "82.28676" start_bearing = "-61.007404" end_bearing = "-68.404686" description = "Turn right and go 557.98 meters" />
|
<segment id="74176013" start="0" end="5" time = "68.20989" name = "Viaductweg" distance = "252.9152" turn = "Turn right" turn_angle = "82.28676" start_bearing = "-61.007404" end_bearing = "-68.404686" description = "Turn right and go 724.83 meters" />
|
||||||
<segment id="7125080" start="0" end="3" time = "22.315641" name = "Viaductweg" distance = "132.08797" start_bearing = "-69.443954" end_bearing = "-67.22757" description = "" />
|
<segment id="7125080" start="0" end="3" time = "32.31564" name = "Viaductweg" distance = "132.08797" start_bearing = "-69.443954" end_bearing = "-67.22757" description = "" />
|
||||||
<segment id="7126430" start="0" end="1" time = "1.6430479" name = "Viaductweg" distance = "29.666143" start_bearing = "-65.46227" end_bearing = "-65.46227" description = "" />
|
<segment id="7126430" start="0" end="1" time = "1.6430479" name = "Viaductweg" distance = "29.666143" start_bearing = "-65.46227" end_bearing = "-65.46227" description = "" />
|
||||||
<segment id="7126427" start="0" end="6" time = "10.318509" name = "Viaductweg" distance = "143.31262" start_bearing = "-65.64201" end_bearing = "-83.198685" description = "" />
|
<segment id="7126427" start="0" end="6" time = "10.318509" name = "Viaductweg" distance = "143.31262" start_bearing = "-65.64201" end_bearing = "-83.198685" description = "" />
|
||||||
<segment id="7126427" start="6" end="13" time = "12.012888" name = "Viaductweg" distance = "166.84567" turn = "Keep left" turn_angle = "-1.0907211" start_bearing = "-84.289406" end_bearing = "-97.0165" description = "Keep left and go 166.85 meters (*)" />
|
<segment id="7126427" start="6" end="13" time = "12.012888" name = "Viaductweg" distance = "166.84567" start_bearing = "-84.289406" end_bearing = "-97.0165" description = "" />
|
||||||
<segment id="7126424" start="0" end="1" time = "16.031185" name = "" distance = "12.889814" turn = "Turn left" turn_angle = "-91.472435" start_bearing = "171.51106" end_bearing = "171.51106" description = "Turn left and go 561.36 meters" />
|
<segment id="7126424" start="0" end="1" time = "26.031185" name = "" distance = "12.889814" turn = "Turn left" turn_angle = "-91.472435" start_bearing = "171.51106" end_bearing = "171.51106" description = "Turn left and go 872.82 meters" />
|
||||||
<segment id="102699301" start="0" end="5" time = "18.381628" name = "Franciscus Romanusweg" distance = "46.967056" start_bearing = "171.8699" end_bearing = "-159.22775" description = "" />
|
<segment id="102699301" start="0" end="5" time = "28.381628" name = "Franciscus Romanusweg" distance = "46.967056" start_bearing = "171.8699" end_bearing = "-159.22775" description = "" />
|
||||||
<segment id="144552858" start="10" end="0" time = "14.33854" name = "Franciscus Romanusweg" distance = "199.1464" start_bearing = "-123.69007" end_bearing = "-95.59934" description = "" />
|
<segment id="144552858" start="10" end="0" time = "14.33854" name = "Franciscus Romanusweg" distance = "199.1464" start_bearing = "-123.69007" end_bearing = "-95.59934" description = "" />
|
||||||
<segment id="32102945" start="7" end="0" time = "22.397062" name = "Franciscus Romanusweg" distance = "102.73698" start_bearing = "-94.76364" end_bearing = "-134.44374" description = "" />
|
<segment id="32102945" start="7" end="0" time = "32.39706" name = "Franciscus Romanusweg" distance = "102.73698" start_bearing = "-94.76364" end_bearing = "-134.44374" description = "" />
|
||||||
<segment id="7126419" start="18" end="4" time = "14.372538" name = "Franciscus Romanusweg" distance = "199.61858" start_bearing = "-135.0" end_bearing = "171.8699" description = "" />
|
<segment id="7126419" start="18" end="4" time = "14.372538" name = "Franciscus Romanusweg" distance = "199.61858" start_bearing = "-135.0" end_bearing = "171.8699" description = "" />
|
||||||
<segment id="7126419" start="4" end="0" time = "14.157407" name = "Franciscus Romanusweg" distance = "196.63066" turn = "Keep left" turn_angle = "-0.07077026" start_bearing = "171.79913" end_bearing = "171.17232" description = "Keep left and go 196.63 meters (*)" />
|
<segment id="7126419" start="4" end="0" time = "14.157407" name = "Franciscus Romanusweg" distance = "196.63066" start_bearing = "171.79913" end_bearing = "171.17232" description = "" />
|
||||||
<segment id="7126340" start="3" end="0" time = "11.169105" name = "Antonius Bieleveltstraat" distance = "108.58852" turn = "Turn left" turn_angle = "-97.285736" start_bearing = "73.88658" end_bearing = "136.25446" description = "Turn left and go 108.59 meters" />
|
<segment id="7126414" start="1" end="0" time = "1.3585912" name = "Franciscus Romanusweg" distance = "22.643187" start_bearing = "175.156" end_bearing = "175.156" description = "" />
|
||||||
<segment id="7126350" start="6" end="0" time = "11.346093" name = "Schildersplein" distance = "110.30924" turn = "Turn right" turn_angle = "90.667496" start_bearing = "-133.07805" end_bearing = "135.0" description = "Turn right and go 157.22 meters" />
|
<segment id="7126200" start="0" end="4" time = "6.637338" name = "Franciscus Romanusweg" distance = "92.18526" start_bearing = "178.2643" end_bearing = "-169.38034" description = "" />
|
||||||
<segment id="7126313" start="1" end="0" time = "4.8251657" name = "Valentijn Clotsstraat" distance = "46.91133" start_bearing = "132.89091" end_bearing = "132.89091" description = "" />
|
<segment id="7126312" start="0" end="4" time = "11.829202" name = "Karel de Vogelstraat" distance = "115.00613" turn = "Turn left" turn_angle = "-90.10545" start_bearing = "100.514206" end_bearing = "35.387886" description = "Turn left and go 115.01 meters" />
|
||||||
|
<segment id="7126313" start="1" end="0" time = "4.8251657" name = "Valentijn Clotsstraat" distance = "46.91133" turn = "Turn right" turn_angle = "97.50303" start_bearing = "132.89091" end_bearing = "132.89091" description = "Turn right and go 46.91 meters" />
|
||||||
<segment id="7126355" start="4" end="0" time = "5.2888374" name = "Gebroeders Hermansstraat" distance = "51.419254" turn = "Turn left" turn_angle = "-81.665085" start_bearing = "51.22583" end_bearing = "136.49434" description = "Turn left and go 51.42 meters" />
|
<segment id="7126355" start="4" end="0" time = "5.2888374" name = "Gebroeders Hermansstraat" distance = "51.419254" turn = "Turn left" turn_angle = "-81.665085" start_bearing = "51.22583" end_bearing = "136.49434" description = "Turn left and go 51.42 meters" />
|
||||||
<segment id="7126356" start="3" end="2" time = "0.0" name = "" distance = "0.0" turn = "Turn right" turn_angle = "81.091034" start_bearing = "-142.41463" end_bearing = "-140.19443" description = "Turn right and go 0.00 meters" />
|
<segment id="7126356" start="3" end="2" time = "0.0" name = "" distance = "0.0" turn = "Turn right" turn_angle = "81.091034" start_bearing = "-142.41463" end_bearing = "-140.19443" description = "Turn right and go 0.00 meters" />
|
||||||
</test>
|
</test>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<router_tests>
|
<router_tests>
|
||||||
<test regions="" description="Route to Antwerpen" best_percent="10" vehicle="car"
|
<test regions="" description="Route to Antwerpen" best_percent="10" vehicle="car"
|
||||||
start_lat="52.29344776082418" start_lon="4.834756851196289" target_lat="51.21717320613008" target_lon="4.402492046356201" complete_time="5541.6855" loadedTiles = "438" visitedSegments = "9031" complete_distance = "155763.8" >
|
start_lat="52.29344776082418" start_lon="4.834756851196289" target_lat="51.21717320613008" target_lon="4.402492046356201" complete_time="5953.306" loadedTiles = "3120" visitedSegments = "11834" complete_distance = "159654.98" >
|
||||||
<segment id="7367192" start="1" end="0" time = "1.9570006" name = "" distance = "24.462507" turn = "Go ahead" turn_angle = "0.0" start_bearing = "108.39158" end_bearing = "108.39158" description = "Go ahead and go 24.46 meters" />
|
<segment id="7367192" start="1" end="0" time = "1.9570006" name = "" distance = "24.462507" turn = "Go ahead" turn_angle = "0.0" start_bearing = "108.39158" end_bearing = "108.39158" description = "Go ahead and go 24.46 meters" />
|
||||||
<segment id="7366497" start="4" end="0" time = "8.245201" name = "Noorddammerweg" distance = "103.06502" turn = "Turn right" turn_angle = "96.414085" start_bearing = "-155.19434" end_bearing = "-129.80557" description = "Turn right and go 127.54 meters" />
|
<segment id="7366497" start="4" end="0" time = "8.245201" name = "Noorddammerweg" distance = "103.06502" turn = "Turn right" turn_angle = "96.414085" start_bearing = "-155.19434" end_bearing = "-129.80557" description = "Turn right and go 127.54 meters" />
|
||||||
<segment id="7366502" start="1" end="0" time = "2.9368546" name = "Urbanusparkstraat" distance = "24.473787" start_bearing = "-116.56505" end_bearing = "-116.56505" description = "" />
|
<segment id="7366502" start="1" end="0" time = "2.9368546" name = "Urbanusparkstraat" distance = "24.473787" start_bearing = "-116.56505" end_bearing = "-116.56505" description = "" />
|
||||||
|
@ -10,18 +10,25 @@
|
||||||
<segment id="7366534" start="1" end="0" time = "4.5096536" name = "Sint Urbanuspark" distance = "56.37067" start_bearing = "-158.61427" end_bearing = "-158.61427" description = "" />
|
<segment id="7366534" start="1" end="0" time = "4.5096536" name = "Sint Urbanuspark" distance = "56.37067" start_bearing = "-158.61427" end_bearing = "-158.61427" description = "" />
|
||||||
<segment id="7366606" start="1" end="0" time = "4.542828" name = "Sint Urbanuspark" distance = "56.785347" start_bearing = "-153.1908" end_bearing = "-153.1908" description = "" />
|
<segment id="7366606" start="1" end="0" time = "4.542828" name = "Sint Urbanuspark" distance = "56.785347" start_bearing = "-153.1908" end_bearing = "-153.1908" description = "" />
|
||||||
<segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "" />
|
<segment id="47633918" start="2" end="1" time = "2.140907" name = "Noorddammerweg" distance = "26.761337" start_bearing = "-155.19734" end_bearing = "-155.19734" description = "" />
|
||||||
<segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 774.68 meters" />
|
<segment id="7367247" start="2" end="0" time = "20.482542" name = "Zetterij" distance = "256.03177" turn = "Turn left" turn_angle = "-90.48619" start_bearing = "114.31647" end_bearing = "106.46359" description = "Turn left and go 761.63 meters" />
|
||||||
<segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" />
|
<segment id="7364788" start="4" end="0" time = "23.708342" name = "Zetterij" distance = "296.35428" start_bearing = "108.9465" end_bearing = "115.2737" description = "" />
|
||||||
<segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" />
|
<segment id="7364764" start="1" end="0" time = "1.6481074" name = "Zetterij" distance = "20.601343" start_bearing = "111.709885" end_bearing = "111.709885" description = "" />
|
||||||
<segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" />
|
<segment id="7364763" start="1" end="0" time = "6.9382887" name = "Zetterij" distance = "86.728615" start_bearing = "112.44515" end_bearing = "112.44515" description = "" />
|
||||||
<segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" />
|
<segment id="7364766" start="1" end="0" time = "1.1748635" name = "Zetterij" distance = "14.685793" start_bearing = "119.27525" end_bearing = "119.27525" description = "" />
|
||||||
<segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" />
|
<segment id="7364508" start="0" end="2" time = "6.2802095" name = "Zetterij" distance = "87.225136" start_bearing = "110.00669" end_bearing = "94.62415" description = "" />
|
||||||
<segment id="7365071" start="0" end="1" time = "0.9398953" name = "Zetterij" distance = "13.054101" start_bearing = "117.97948" end_bearing = "117.97948" description = "" />
|
<segment id="7365070" start="0" end="1" time = "1.0716465" name = "Bovenkerkerweg (N521) " distance = "14.883979" turn = "Turn right" turn_angle = "94.95008" start_bearing = "-170.42577" end_bearing = "-170.42577" description = "Turn right and go 58.89 meters" />
|
||||||
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" turn = "Turn left" turn_angle = "-105.37932" start_bearing = "12.60016" end_bearing = "12.60016" description = "Turn left and go 968.58 meters" />
|
<segment id="7365086" start="0" end="1" time = "3.1682494" name = "Bovenkerkerweg (N521) " distance = "44.003468" start_bearing = "-172.57889" end_bearing = "-172.57889" description = "" />
|
||||||
|
<segment id="7365086" start="1" end="3" time = "30.227621" name = "Bovenkerkerweg (N521) " distance = "72.60584" turn = "Keep right" turn_angle = "1.9589691" start_bearing = "-170.61992" end_bearing = "-173.29016" description = "Keep right and go 110.76 meters" />
|
||||||
|
<segment id="7365099" start="0" end="3" time = "2.747028" name = "Bovenkerkerweg (N521) " distance = "38.15317" start_bearing = "-173.21103" end_bearing = "-177.61406" description = "" />
|
||||||
|
<segment id="7365062" start="6" end="7" time = "0.84723866" name = "Beneluxbaan" distance = "11.767203" turn = "Make uturn" turn_angle = "0.0" start_bearing = "97.0165" end_bearing = "97.0165" description = "Make uturn and go 1105.87 meters" />
|
||||||
|
<segment id="7365101" start="0" end="3" time = "2.8561046" name = "Bovenkerkerweg (N521) " distance = "39.66812" start_bearing = "10.885527" end_bearing = "11.458753" description = "" />
|
||||||
|
<segment id="7365085" start="0" end="1" time = "8.459829" name = "Bovenkerkerweg (N521) " distance = "117.49763" start_bearing = "6.4971123" end_bearing = "6.4971123" description = "" />
|
||||||
|
<segment id="7365069" start="0" end="1" time = "0.57796" name = "Bovenkerkerweg (N521) " distance = "8.027223" start_bearing = "5.3145456" end_bearing = "5.3145456" description = "" />
|
||||||
|
<segment id="7364510" start="0" end="1" time = "1.1475279" name = "Bovenkerkerweg (N521) " distance = "15.937888" start_bearing = "12.60016" end_bearing = "12.60016" description = "" />
|
||||||
<segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" />
|
<segment id="7364786" start="0" end="2" time = "9.050575" name = "Bovenkerkerweg (N521) " distance = "125.70244" start_bearing = "7.8605475" end_bearing = "-2.726311" description = "" />
|
||||||
<segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" />
|
<segment id="7364769" start="0" end="2" time = "16.702217" name = "Bovenkerkerweg (N521) " distance = "278.3703" start_bearing = "10.541818" end_bearing = "8.130102" description = "" />
|
||||||
<segment id="7364781" start="0" end="6" time = "54.49686" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" />
|
<segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" start_bearing = "8.130102" end_bearing = "9.901572" description = "" />
|
||||||
<segment id="7364782" start="1" end="0" time = "16.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
|
<segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
|
||||||
<segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" />
|
<segment id="7364779" start="0" end="5" time = "13.558414" name = "Keizer Karelweg" distance = "188.31131" start_bearing = "96.254036" end_bearing = "66.169136" description = "" />
|
||||||
<segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" />
|
<segment id="7364775" start="1" end="0" time = "4.9813266" name = "Keizer Karelweg" distance = "69.18509" start_bearing = "62.372807" end_bearing = "62.372807" description = "" />
|
||||||
<segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" />
|
<segment id="7364776" start="0" end="1" time = "4.9812937" name = "Keizer Karelweg" distance = "69.18464" start_bearing = "62.334564" end_bearing = "62.334564" description = "" />
|
||||||
|
@ -38,10 +45,10 @@
|
||||||
<segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" />
|
<segment id="48147997" start="0" end="2" time = "2.944532" name = "Keizer Karelweg" distance = "40.89628" start_bearing = "57.707115" end_bearing = "51.679886" description = "" />
|
||||||
<segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" />
|
<segment id="7364498" start="0" end="2" time = "3.2543092" name = "Keizer Karelweg" distance = "45.198742" start_bearing = "52.460567" end_bearing = "70.857735" description = "" />
|
||||||
<segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" />
|
<segment id="7364496" start="0" end="1" time = "1.0199182" name = "Keizer Karelweg" distance = "14.165531" start_bearing = "53.746162" end_bearing = "53.746162" description = "" />
|
||||||
<segment id="58384522" start="0" end="4" time = "20.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" />
|
<segment id="58384522" start="0" end="4" time = "30.041615" name = "Keizer Karelweg" distance = "70.02242" start_bearing = "9.050722" end_bearing = "19.798876" description = "" />
|
||||||
<segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" />
|
<segment id="7364485" start="0" end="2" time = "5.4958763" name = "Keizer Karelweg" distance = "76.33162" start_bearing = "28.694904" end_bearing = "18.610165" description = "" />
|
||||||
<segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" />
|
<segment id="7364485" start="2" end="3" time = "2.772" name = "Keizer Karelweg" distance = "38.500004" turn = "Keep right" turn_angle = "7.832197" start_bearing = "26.442362" end_bearing = "26.442362" description = "Keep right and go 38.50 meters" />
|
||||||
<segment id="49900222" start="0" end="1" time = "16.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" />
|
<segment id="49900222" start="0" end="1" time = "26.05053" name = " (5) " distance = "29.181383" turn = "Keep right" turn_angle = "26.471804" start_bearing = "52.914165" end_bearing = "52.914165" description = "Keep right and go 29.18 meters" />
|
||||||
<segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" />
|
<segment id="7364501" start="1" end="14" time = "15.055797" name = " (5) " distance = "418.21658" turn = "Turn right" turn_angle = "72.713745" start_bearing = "125.62791" end_bearing = "101.61149" description = "Turn right and go 860.22 meters" />
|
||||||
<segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" />
|
<segment id="7363599" start="0" end="2" time = "15.912092" name = "Burgemeester van Sonweg (A9) " distance = "442.0026" start_bearing = "110.03965" end_bearing = "111.34803" description = "" />
|
||||||
<segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" />
|
<segment id="73841697" start="0" end="1" time = "3.0741942" name = "Burgemeester van Sonweg (A9) " distance = "85.39429" turn = "Keep left" turn_angle = "-1.123169" lanes = "[1, 1, 1, 0]" start_bearing = "110.22486" end_bearing = "110.22486" description = "Keep left[1, 1, 1, 0] and go 5031.67 meters (*)" />
|
||||||
|
@ -82,26 +89,21 @@
|
||||||
<segment id="127580802" start="3" end="5" time = "23.851204" name = " (A2) " distance = "662.53345" turn = "Keep left" turn_angle = "-0.8713379" lanes = "[1, 1, 1, 1, 1, 0]" start_bearing = "156.3491" end_bearing = "157.03491" description = "Keep left[1, 1, 1, 1, 1, 0] and go 3086.16 meters (*)" />
|
<segment id="127580802" start="3" end="5" time = "23.851204" name = " (A2) " distance = "662.53345" turn = "Keep left" turn_angle = "-0.8713379" lanes = "[1, 1, 1, 1, 1, 0]" start_bearing = "156.3491" end_bearing = "157.03491" description = "Keep left[1, 1, 1, 1, 1, 0] and go 3086.16 meters (*)" />
|
||||||
<segment id="76140687" start="0" end="1" time = "1.273901" name = " (A2) " distance = "35.38614" start_bearing = "157.15196" end_bearing = "157.15196" description = "" />
|
<segment id="76140687" start="0" end="1" time = "1.273901" name = " (A2) " distance = "35.38614" start_bearing = "157.15196" end_bearing = "157.15196" description = "" />
|
||||||
<segment id="76140684" start="0" end="12" time = "85.97655" name = " (A2) " distance = "2388.2375" start_bearing = "158.17053" end_bearing = "133.95096" description = "" />
|
<segment id="76140684" start="0" end="12" time = "85.97655" name = " (A2) " distance = "2388.2375" start_bearing = "158.17053" end_bearing = "133.95096" description = "" />
|
||||||
<segment id="7063640" start="0" end="4" time = "22.955816" name = " (A2) " distance = "637.66156" turn = "Keep right" turn_angle = "5.8865967" lanes = "[0, 0, 0, 0, 1, 1]" start_bearing = "139.83755" end_bearing = "133.75592" description = "Keep right[0, 0, 0, 0, 1, 1] and go 637.66 meters" />
|
<segment id="79262900" start="0" end="8" time = "33.028996" name = " (A2) " distance = "917.4721" turn = "Keep left" turn_angle = "-1.6629486" lanes = "[1, 1, 1, 1, 0, 0]" start_bearing = "132.28801" end_bearing = "124.28688" description = "Keep left[1, 1, 1, 1, 0, 0] and go 6977.00 meters" />
|
||||||
<segment id="80749050" start="0" end="8" time = "29.595013" name = " (A2) " distance = "822.08374" turn = "Keep left" turn_angle = "-6.2392197" lanes = "[1, 0, 0]" start_bearing = "127.5167" end_bearing = "124.00188" description = "Keep left[1, 0, 0] and go 1675.15 meters (*)" />
|
<segment id="79262901" start="0" end="11" time = "83.45524" name = " (A2) " distance = "2318.2012" start_bearing = "123.34157" end_bearing = "138.1617" description = "" />
|
||||||
<segment id="80749051" start="0" end="1" time = "5.690788" name = " (A2) " distance = "158.07745" start_bearing = "123.72714" end_bearing = "123.72714" description = "" />
|
<segment id="7061299" start="0" end="4" time = "12.982101" name = " (A2) " distance = "360.61395" start_bearing = "137.78456" end_bearing = "139.08562" description = "" />
|
||||||
<segment id="114712634" start="0" end="5" time = "25.019554" name = " (A2) " distance = "694.9876" start_bearing = "123.795296" end_bearing = "122.66091" description = "" />
|
<segment id="151258641" start="0" end="6" time = "22.246897" name = " (A2) " distance = "617.96936" start_bearing = "143.19708" end_bearing = "150.50703" description = "" />
|
||||||
<segment id="80749052" start="0" end="7" time = "27.790503" name = " (A2) " distance = "771.95844" turn = "Keep left" turn_angle = "1.7918243" start_bearing = "124.452736" end_bearing = "135.1993" description = "Keep left and go 3777.28 meters (*)" />
|
<segment id="80761370" start="0" end="9" time = "58.68163" name = "Leidsche Rijntunnel (A2) " distance = "1630.0453" start_bearing = "153.77612" end_bearing = "172.87498" description = "" />
|
||||||
<segment id="99998240" start="0" end="10" time = "39.82047" name = " (A2) " distance = "1106.1241" start_bearing = "137.54857" end_bearing = "150.25511" description = "" />
|
<segment id="80761383" start="0" end="2" time = "11.184597" name = " (A2) " distance = "310.68326" start_bearing = "174.99852" end_bearing = "179.38173" description = "" />
|
||||||
<segment id="32512734" start="0" end="9" time = "59.071857" name = "Leidsche Rijntunnel (A2) " distance = "1640.885" start_bearing = "153.49524" end_bearing = "174.09386" description = "" />
|
<segment id="80761369" start="0" end="1" time = "1.9537628" name = " (A2) " distance = "54.27119" start_bearing = "-178.45705" end_bearing = "-178.45705" description = "" />
|
||||||
<segment id="51795374" start="0" end="2" time = "9.2991705" name = " (A2) " distance = "258.3103" start_bearing = "176.55423" end_bearing = "179.28766" description = "" />
|
<segment id="80761365" start="0" end="6" time = "11.0511" name = " (A2) " distance = "306.975" start_bearing = "-176.12459" end_bearing = "-171.34746" description = "" />
|
||||||
<segment id="51795374" start="2" end="3" time = "1.7690709" name = " (A2) " distance = "49.14086" turn = "Keep left" turn_angle = "-0.5798187" lanes = "[1, 1, 0, 0]" start_bearing = "178.70784" end_bearing = "178.70784" description = "Keep left[1, 1, 0, 0] and go 1041.26 meters (*)" />
|
<segment id="152126643" start="0" end="2" time = "16.587639" name = " (A2) " distance = "460.76776" start_bearing = "-168.47627" end_bearing = "-165.6754" description = "" />
|
||||||
<segment id="51763743" start="0" end="1" time = "1.9273798" name = " (A2) " distance = "53.53833" start_bearing = "-178.62674" end_bearing = "-178.62674" description = "" />
|
<segment id="93810171" start="0" end="1" time = "8.644352" name = " (A2) " distance = "240.1209" turn = "Keep left" turn_angle = "-1.1266632" lanes = "[1, 1, 0, 0]" start_bearing = "-166.80206" end_bearing = "-166.80206" description = "Keep left[1, 1, 0, 0] and go 4539.38 meters" />
|
||||||
<segment id="51764573" start="0" end="6" time = "12.954628" name = " (A2) " distance = "359.8508" start_bearing = "-175.96658" end_bearing = "-171.84186" description = "" />
|
<segment id="7054468" start="0" end="2" time = "29.638718" name = " (A2) " distance = "823.2977" start_bearing = "-167.47635" end_bearing = "-165.95709" description = "" />
|
||||||
<segment id="114712628" start="0" end="2" time = "7.6056266" name = " (A2) " distance = "211.26741" start_bearing = "-170.33298" end_bearing = "-165.04005" description = "" />
|
<segment id="7054457" start="0" end="1" time = "3.6500416" name = " (A2) " distance = "101.390045" start_bearing = "-166.36688" end_bearing = "-166.36688" description = "" />
|
||||||
<segment id="45356321" start="0" end="1" time = "13.2288" name = " (A2) " distance = "367.46667" start_bearing = "-164.98569" end_bearing = "-164.98569" description = "" />
|
<segment id="7054352" start="0" end="3" time = "24.02921" name = " (A2) " distance = "667.478" start_bearing = "-165.3489" end_bearing = "-165.1765" description = "" />
|
||||||
<segment id="93810170" start="0" end="18" time = "32.24873" name = " (A2) " distance = "895.7981" turn = "Keep right" turn_angle = "1.6514435" lanes = "[0, 0, 1]" start_bearing = "-163.33424" end_bearing = "-165.01373" description = "Keep right[0, 0, 1] and go 4389.06 meters (*)" />
|
<segment id="78380419" start="0" end="1" time = "1.7932974" name = " (A2) " distance = "49.81382" start_bearing = "-165.75967" end_bearing = "-165.75967" description = "" />
|
||||||
<segment id="7054459" start="0" end="1" time = "0.5385003" name = " (A2) " distance = "14.958343" start_bearing = "-165.11374" end_bearing = "-165.11374" description = "" />
|
<segment id="78380416" start="0" end="1" time = "6.098158" name = " (A2) " distance = "169.39328" start_bearing = "-164.95683" end_bearing = "-164.95683" description = "" />
|
||||||
<segment id="7054436" start="0" end="1" time = "3.7654755" name = " (A2) " distance = "104.59655" start_bearing = "-165.37912" end_bearing = "-165.37912" description = "" />
|
|
||||||
<segment id="7065542" start="0" end="2" time = "16.98387" name = " (A2) " distance = "471.77417" start_bearing = "-166.1587" end_bearing = "-165.21095" description = "" />
|
|
||||||
<segment id="7065536" start="0" end="1" time = "7.173017" name = " (A2) " distance = "199.25047" start_bearing = "-166.11705" end_bearing = "-166.11705" description = "" />
|
|
||||||
<segment id="78380417" start="0" end="1" time = "1.6784111" name = " (A2) " distance = "46.62253" start_bearing = "-167.54431" end_bearing = "-167.54431" description = "" />
|
|
||||||
<segment id="78380413" start="0" end="1" time = "6.054087" name = " (A2) " distance = "168.1691" start_bearing = "-168.89789" end_bearing = "-168.89789" description = "" />
|
|
||||||
<segment id="7064773" start="0" end="10" time = "66.43809" name = " (A2) " distance = "1845.5026" start_bearing = "-165.6186" end_bearing = "-178.60915" description = "" />
|
<segment id="7064773" start="0" end="10" time = "66.43809" name = " (A2) " distance = "1845.5026" start_bearing = "-165.6186" end_bearing = "-178.60915" description = "" />
|
||||||
<segment id="48836778" start="0" end="1" time = "1.2691222" name = " (A2) " distance = "35.2534" start_bearing = "-177.61406" end_bearing = "-177.61406" description = "" />
|
<segment id="48836778" start="0" end="1" time = "1.2691222" name = " (A2) " distance = "35.2534" start_bearing = "-177.61406" end_bearing = "-177.61406" description = "" />
|
||||||
<segment id="48836779" start="0" end="3" time = "21.856815" name = " (A2) " distance = "607.1338" start_bearing = "-179.3338" end_bearing = "-178.12825" description = "" />
|
<segment id="48836779" start="0" end="3" time = "21.856815" name = " (A2) " distance = "607.1338" start_bearing = "-179.3338" end_bearing = "-178.12825" description = "" />
|
||||||
|
@ -146,15 +148,15 @@
|
||||||
<segment id="7105838" start="0" end="4" time = "12.845104" name = " (A27) " distance = "428.17014" start_bearing = "-147.84592" end_bearing = "-151.59348" description = "" />
|
<segment id="7105838" start="0" end="4" time = "12.845104" name = " (A27) " distance = "428.17014" start_bearing = "-147.84592" end_bearing = "-151.59348" description = "" />
|
||||||
<segment id="7105835" start="0" end="1" time = "1.1449802" name = " (A27) " distance = "38.166004" start_bearing = "-152.30673" end_bearing = "-152.30673" description = "" />
|
<segment id="7105835" start="0" end="1" time = "1.1449802" name = " (A27) " distance = "38.166004" start_bearing = "-152.30673" end_bearing = "-152.30673" description = "" />
|
||||||
<segment id="7105842" start="0" end="11" time = "107.7067" name = " (A27) " distance = "3590.2234" start_bearing = "-155.1287" end_bearing = "-166.30568" description = "" />
|
<segment id="7105842" start="0" end="11" time = "107.7067" name = " (A27) " distance = "3590.2234" start_bearing = "-155.1287" end_bearing = "-166.30568" description = "" />
|
||||||
<segment id="7109387" start="0" end="1" time = "9.073263" name = " (A27) " distance = "302.44208" turn = "Keep left" turn_angle = "0.164505" lanes = "[1, 1, 0]" start_bearing = "-166.14117" end_bearing = "-166.14117" description = "Keep left[1, 1, 0] and go 3105.36 meters (*)" />
|
<segment id="7109387" start="0" end="1" time = "9.073263" name = " (A27) " distance = "302.44208" turn = "Keep left" turn_angle = "0.164505" lanes = "[1, 1, 0]" start_bearing = "-166.14117" end_bearing = "-166.14117" description = "Keep left[1, 1, 0] and go 5594.20 meters (*)" />
|
||||||
<segment id="7109392" start="0" end="1" time = "2.1320362" name = " (A27) " distance = "71.06787" start_bearing = "-166.68306" end_bearing = "-166.68306" description = "" />
|
<segment id="7109392" start="0" end="1" time = "2.1320362" name = " (A27) " distance = "71.06787" start_bearing = "-166.68306" end_bearing = "-166.68306" description = "" />
|
||||||
<segment id="7109396" start="0" end="1" time = "9.105985" name = " (A27) " distance = "303.5328" start_bearing = "-166.04816" end_bearing = "-166.04816" description = "" />
|
<segment id="7109396" start="0" end="1" time = "9.105985" name = " (A27) " distance = "303.5328" start_bearing = "-166.04816" end_bearing = "-166.04816" description = "" />
|
||||||
<segment id="7109400" start="0" end="6" time = "30.953196" name = " (A27) " distance = "1031.7732" start_bearing = "-167.03697" end_bearing = "-158.87846" description = "" />
|
<segment id="7109400" start="0" end="6" time = "30.953196" name = " (A27) " distance = "1031.7732" start_bearing = "-167.03697" end_bearing = "-158.87846" description = "" />
|
||||||
<segment id="7109402" start="0" end="1" time = "2.1459546" name = " (A27) " distance = "71.53182" start_bearing = "-159.66669" end_bearing = "-159.66669" description = "" />
|
<segment id="7109402" start="0" end="1" time = "2.1459546" name = " (A27) " distance = "71.53182" start_bearing = "-159.66669" end_bearing = "-159.66669" description = "" />
|
||||||
<segment id="7109403" start="0" end="2" time = "39.75041" name = " (A27) " distance = "1325.0135" start_bearing = "-158.95221" end_bearing = "-159.1193" description = "" />
|
<segment id="7109403" start="0" end="2" time = "39.75041" name = " (A27) " distance = "1325.0135" start_bearing = "-158.95221" end_bearing = "-159.1193" description = "" />
|
||||||
<segment id="7109403" start="2" end="7" time = "69.964554" name = " (A27) " distance = "2332.1519" turn = "Keep left" turn_angle = "-0.13427734" lanes = "[1, 1, 0]" start_bearing = "-159.25357" end_bearing = "-163.85815" description = "Keep left[1, 1, 0] and go 2488.84 meters (*)" />
|
<segment id="7109403" start="2" end="7" time = "69.964554" name = " (A27) " distance = "2332.1519" start_bearing = "-159.25357" end_bearing = "-163.85815" description = "" />
|
||||||
<segment id="28196316" start="0" end="1" time = "5.6407747" name = " (A27) " distance = "156.6882" start_bearing = "-163.61809" end_bearing = "-163.61809" description = "" />
|
<segment id="28196316" start="0" end="1" time = "5.6407747" name = " (A27) " distance = "156.6882" start_bearing = "-163.61809" end_bearing = "-163.61809" description = "" />
|
||||||
<segment id="10196765" start="0" end="1" time = "22.247164" name = " (A27) " distance = "617.9768" turn = "Keep left" turn_angle = "-0.49978638" lanes = "[1, 1, 0, 0]" start_bearing = "-164.11787" end_bearing = "-164.11787" description = "Keep left[1, 1, 0, 0] and go 2155.25 meters (*)" />
|
<segment id="10196765" start="0" end="1" time = "22.247164" name = " (A27) " distance = "617.9768" turn = "Keep left" turn_angle = "-0.49978638" lanes = "[1, 1, 0, 0]" start_bearing = "-164.11787" end_bearing = "-164.11787" description = "Keep left[1, 1, 0, 0] and go 2155.25 meters" />
|
||||||
<segment id="43545572" start="0" end="1" time = "1.1079632" name = " (A27) " distance = "30.776758" start_bearing = "-163.86441" end_bearing = "-163.86441" description = "" />
|
<segment id="43545572" start="0" end="1" time = "1.1079632" name = " (A27) " distance = "30.776758" start_bearing = "-163.86441" end_bearing = "-163.86441" description = "" />
|
||||||
<segment id="43545571" start="0" end="1" time = "6.129849" name = " (A27) " distance = "170.27359" start_bearing = "-164.27641" end_bearing = "-164.27641" description = "" />
|
<segment id="43545571" start="0" end="1" time = "6.129849" name = " (A27) " distance = "170.27359" start_bearing = "-164.27641" end_bearing = "-164.27641" description = "" />
|
||||||
<segment id="7111062" start="0" end="1" time = "3.681373" name = " (A27) " distance = "102.26036" start_bearing = "-164.53667" end_bearing = "-164.53667" description = "" />
|
<segment id="7111062" start="0" end="1" time = "3.681373" name = " (A27) " distance = "102.26036" start_bearing = "-164.53667" end_bearing = "-164.53667" description = "" />
|
||||||
|
@ -173,10 +175,10 @@
|
||||||
<segment id="85076242" start="0" end="1" time = "1.6107373" name = " (A27) " distance = "53.691242" start_bearing = "-167.06454" end_bearing = "-167.06454" description = "" />
|
<segment id="85076242" start="0" end="1" time = "1.6107373" name = " (A27) " distance = "53.691242" start_bearing = "-167.06454" end_bearing = "-167.06454" description = "" />
|
||||||
<segment id="7118606" start="0" end="2" time = "5.0012426" name = " (A27) " distance = "166.70808" turn = "Keep left" turn_angle = "-1.3887634" lanes = "[1, 1, 0]" start_bearing = "-168.45331" end_bearing = "-170.20853" description = "Keep left[1, 1, 0] and go 2906.29 meters (*)" />
|
<segment id="7118606" start="0" end="2" time = "5.0012426" name = " (A27) " distance = "166.70808" turn = "Keep left" turn_angle = "-1.3887634" lanes = "[1, 1, 0]" start_bearing = "-168.45331" end_bearing = "-170.20853" description = "Keep left[1, 1, 0] and go 2906.29 meters (*)" />
|
||||||
<segment id="7118631" start="0" end="5" time = "82.18753" name = " (A27) " distance = "2739.5842" start_bearing = "-173.15642" end_bearing = "178.0464" description = "" />
|
<segment id="7118631" start="0" end="5" time = "82.18753" name = " (A27) " distance = "2739.5842" start_bearing = "-173.15642" end_bearing = "178.0464" description = "" />
|
||||||
<segment id="7118631" start="5" end="17" time = "67.97151" name = " (A27) " distance = "2265.7168" turn = "Keep left" turn_angle = "-0.51820374" lanes = "[1, 1, 0]" start_bearing = "177.5282" end_bearing = "-163.64418" description = "Keep left[1, 1, 0] and go 3546.68 meters (*)" />
|
<segment id="7118631" start="5" end="17" time = "67.97151" name = " (A27) " distance = "2265.7168" turn = "Keep left" turn_angle = "-0.51820374" lanes = "[1, 1, 0]" start_bearing = "177.5282" end_bearing = "-163.64418" description = "Keep left[1, 1, 0] and go 4487.76 meters (*)" />
|
||||||
<segment id="7118867" start="0" end="1" time = "3.947046" name = " (A27) " distance = "131.5682" start_bearing = "-163.6786" end_bearing = "-163.6786" description = "" />
|
<segment id="7118867" start="0" end="1" time = "3.947046" name = " (A27) " distance = "131.5682" start_bearing = "-163.6786" end_bearing = "-163.6786" description = "" />
|
||||||
<segment id="7118635" start="0" end="8" time = "34.481792" name = " (A27) " distance = "1149.3931" start_bearing = "-163.27983" end_bearing = "-152.46683" description = "" />
|
<segment id="7118635" start="0" end="8" time = "34.481792" name = " (A27) " distance = "1149.3931" start_bearing = "-163.27983" end_bearing = "-152.46683" description = "" />
|
||||||
<segment id="7118635" start="8" end="14" time = "28.23234" name = " (A27) " distance = "941.07794" turn = "Keep left" turn_angle = "1.8730164" lanes = "[1, 1, 0]" start_bearing = "-150.59381" end_bearing = "-143.1301" description = "Keep left[1, 1, 0] and go 941.08 meters (*)" />
|
<segment id="7118635" start="8" end="14" time = "28.23234" name = " (A27) " distance = "941.07794" start_bearing = "-150.59381" end_bearing = "-143.1301" description = "" />
|
||||||
<segment id="7269367" start="0" end="5" time = "11.039033" name = " (A27) " distance = "367.96774" turn = "Keep left" turn_angle = "1.8817291" lanes = "[1, 1, 0]" start_bearing = "-141.24837" end_bearing = "-134.22127" description = "Keep left[1, 1, 0] and go 3099.88 meters (*)" />
|
<segment id="7269367" start="0" end="5" time = "11.039033" name = " (A27) " distance = "367.96774" turn = "Keep left" turn_angle = "1.8817291" lanes = "[1, 1, 0]" start_bearing = "-141.24837" end_bearing = "-134.22127" description = "Keep left[1, 1, 0] and go 3099.88 meters (*)" />
|
||||||
<segment id="7269370" start="0" end="1" time = "1.28553" name = " (A27) " distance = "42.850998" start_bearing = "-132.92996" end_bearing = "-132.92996" description = "" />
|
<segment id="7269370" start="0" end="1" time = "1.28553" name = " (A27) " distance = "42.850998" start_bearing = "-132.92996" end_bearing = "-132.92996" description = "" />
|
||||||
<segment id="7269381" start="0" end="1" time = "13.34158" name = " (A27) " distance = "444.71933" start_bearing = "-132.06519" end_bearing = "-132.06519" description = "" />
|
<segment id="7269381" start="0" end="1" time = "13.34158" name = " (A27) " distance = "444.71933" start_bearing = "-132.06519" end_bearing = "-132.06519" description = "" />
|
||||||
|
@ -200,11 +202,11 @@
|
||||||
<segment id="7263539" start="0" end="1" time = "13.529672" name = " (A27) " distance = "450.989" turn = "Keep left" turn_angle = "0.5317688" lanes = "[1, 1, 0]" start_bearing = "-144.64249" end_bearing = "-144.64249" description = "Keep left[1, 1, 0] and go 573.67 meters (*)" />
|
<segment id="7263539" start="0" end="1" time = "13.529672" name = " (A27) " distance = "450.989" turn = "Keep left" turn_angle = "0.5317688" lanes = "[1, 1, 0]" start_bearing = "-144.64249" end_bearing = "-144.64249" description = "Keep left[1, 1, 0] and go 573.67 meters (*)" />
|
||||||
<segment id="7263540" start="0" end="1" time = "2.1952474" name = " (A27) " distance = "73.17491" start_bearing = "-144.76836" end_bearing = "-144.76836" description = "" />
|
<segment id="7263540" start="0" end="1" time = "2.1952474" name = " (A27) " distance = "73.17491" start_bearing = "-144.76836" end_bearing = "-144.76836" description = "" />
|
||||||
<segment id="7263534" start="0" end="1" time = "1.48518" name = " (A27) " distance = "49.505997" start_bearing = "-145.16777" end_bearing = "-145.16777" description = "" />
|
<segment id="7263534" start="0" end="1" time = "1.48518" name = " (A27) " distance = "49.505997" start_bearing = "-145.16777" end_bearing = "-145.16777" description = "" />
|
||||||
<segment id="7263551" start="0" end="1" time = "8.081274" name = " (A27) " distance = "269.3758" turn = "Keep left" turn_angle = "0.65522766" lanes = "[1, 1, 0]" start_bearing = "-144.51254" end_bearing = "-144.51254" description = "Keep left[1, 1, 0] and go 3445.65 meters (*)" />
|
<segment id="7263551" start="0" end="1" time = "8.081274" name = " (A27) " distance = "269.3758" turn = "Keep left" turn_angle = "0.65522766" lanes = "[1, 1, 0]" start_bearing = "-144.51254" end_bearing = "-144.51254" description = "Keep left[1, 1, 0] and go 4618.85 meters (*)" />
|
||||||
<segment id="7263543" start="0" end="1" time = "1.4930464" name = " (A27) " distance = "49.76821" start_bearing = "-144.33705" end_bearing = "-144.33705" description = "" />
|
<segment id="7263543" start="0" end="1" time = "1.4930464" name = " (A27) " distance = "49.76821" start_bearing = "-144.33705" end_bearing = "-144.33705" description = "" />
|
||||||
<segment id="7263541" start="0" end="2" time = "11.839014" name = " (A27) " distance = "394.6338" start_bearing = "-145.24902" end_bearing = "-145.88075" description = "" />
|
<segment id="7263541" start="0" end="2" time = "11.839014" name = " (A27) " distance = "394.6338" start_bearing = "-145.24902" end_bearing = "-145.88075" description = "" />
|
||||||
<segment id="7263262" start="0" end="11" time = "81.95613" name = " (A27) " distance = "2731.8708" start_bearing = "-147.21733" end_bearing = "-132.22498" description = "" />
|
<segment id="7263262" start="0" end="11" time = "81.95613" name = " (A27) " distance = "2731.8708" start_bearing = "-147.21733" end_bearing = "-132.22498" description = "" />
|
||||||
<segment id="7263262" start="11" end="18" time = "29.815554" name = " (A27) " distance = "993.85175" turn = "Keep left" turn_angle = "0.36386108" lanes = "[1, 1, 0]" start_bearing = "-131.86111" end_bearing = "-143.02669" description = "Keep left[1, 1, 0] and go 1173.20 meters (*)" />
|
<segment id="7263262" start="11" end="18" time = "29.815554" name = " (A27) " distance = "993.85175" start_bearing = "-131.86111" end_bearing = "-143.02669" description = "" />
|
||||||
<segment id="7219085" start="0" end="1" time = "2.0454745" name = " (A27) " distance = "68.18248" start_bearing = "-143.31764" end_bearing = "-143.31764" description = "" />
|
<segment id="7219085" start="0" end="1" time = "2.0454745" name = " (A27) " distance = "68.18248" start_bearing = "-143.31764" end_bearing = "-143.31764" description = "" />
|
||||||
<segment id="7219039" start="0" end="1" time = "3.334863" name = " (A27) " distance = "111.162094" start_bearing = "-142.7682" end_bearing = "-142.7682" description = "" />
|
<segment id="7219039" start="0" end="1" time = "3.334863" name = " (A27) " distance = "111.162094" start_bearing = "-142.7682" end_bearing = "-142.7682" description = "" />
|
||||||
<segment id="7219034" start="0" end="2" time = "12.746751" name = " (A27) " distance = "424.89166" turn = "Keep left" turn_angle = "-0.589859" lanes = "[1, 1, 0]" start_bearing = "-143.35806" end_bearing = "-145.30484" description = "Keep left[1, 1, 0] and go 1365.41 meters (*)" />
|
<segment id="7219034" start="0" end="2" time = "12.746751" name = " (A27) " distance = "424.89166" turn = "Keep left" turn_angle = "-0.589859" lanes = "[1, 1, 0]" start_bearing = "-143.35806" end_bearing = "-145.30484" description = "Keep left[1, 1, 0] and go 1365.41 meters (*)" />
|
||||||
|
@ -219,7 +221,7 @@
|
||||||
<segment id="7220805" start="6" end="10" time = "51.539986" name = " (A58) " distance = "1717.9994" turn = "Keep left" turn_angle = "2.5764084" lanes = "[1, 1, 0]" start_bearing = "-122.23798" end_bearing = "-117.04074" description = "Keep left[1, 1, 0] and go 3497.83 meters (*)" />
|
<segment id="7220805" start="6" end="10" time = "51.539986" name = " (A58) " distance = "1717.9994" turn = "Keep left" turn_angle = "2.5764084" lanes = "[1, 1, 0]" start_bearing = "-122.23798" end_bearing = "-117.04074" description = "Keep left[1, 1, 0] and go 3497.83 meters (*)" />
|
||||||
<segment id="7221420" start="0" end="1" time = "1.9121938" name = " (A58) " distance = "63.73979" start_bearing = "-117.30431" end_bearing = "-117.30431" description = "" />
|
<segment id="7221420" start="0" end="1" time = "1.9121938" name = " (A58) " distance = "63.73979" start_bearing = "-117.30431" end_bearing = "-117.30431" description = "" />
|
||||||
<segment id="7221419" start="0" end="19" time = "51.48283" name = " (A58) " distance = "1716.0944" start_bearing = "-115.9752" end_bearing = "-88.17446" description = "" />
|
<segment id="7221419" start="0" end="19" time = "51.48283" name = " (A58) " distance = "1716.0944" start_bearing = "-115.9752" end_bearing = "-88.17446" description = "" />
|
||||||
<segment id="56501888" start="0" end="1" time = "3.3406813" name = " (A16) " distance = "111.35604" turn = "Keep left" turn_angle = "-0.870697" lanes = "[1, 0, 0]" start_bearing = "-89.04516" end_bearing = "-89.04516" description = "Keep left[1, 0, 0] and go 3625.03 meters" />
|
<segment id="56501888" start="0" end="1" time = "3.3406813" name = " (A16) " distance = "111.35604" turn = "Keep left" turn_angle = "-0.870697" lanes = "[1, 0, 0]" start_bearing = "-89.04516" end_bearing = "-89.04516" description = "Keep left[1, 0, 0] and go 4532.32 meters" />
|
||||||
<segment id="7230700" start="0" end="2" time = "15.107924" name = " (A16) " distance = "503.59747" start_bearing = "-87.86395" end_bearing = "-87.70623" description = "" />
|
<segment id="7230700" start="0" end="2" time = "15.107924" name = " (A16) " distance = "503.59747" start_bearing = "-87.86395" end_bearing = "-87.70623" description = "" />
|
||||||
<segment id="7230677" start="0" end="1" time = "1.2922341" name = " (A16) " distance = "43.074467" start_bearing = "-87.55295" end_bearing = "-87.55295" description = "" />
|
<segment id="7230677" start="0" end="1" time = "1.2922341" name = " (A16) " distance = "43.074467" start_bearing = "-87.55295" end_bearing = "-87.55295" description = "" />
|
||||||
<segment id="7230685" start="0" end="1" time = "1.2477278" name = " (A16) " distance = "41.590923" start_bearing = "-87.97268" end_bearing = "-87.97268" description = "" />
|
<segment id="7230685" start="0" end="1" time = "1.2477278" name = " (A16) " distance = "41.590923" start_bearing = "-87.97268" end_bearing = "-87.97268" description = "" />
|
||||||
|
@ -228,7 +230,7 @@
|
||||||
<segment id="92292395" start="0" end="2" time = "0.8898133" name = " (A16) " distance = "29.660442" start_bearing = "119.577835" end_bearing = "123.27489" description = "" />
|
<segment id="92292395" start="0" end="2" time = "0.8898133" name = " (A16) " distance = "29.660442" start_bearing = "119.577835" end_bearing = "123.27489" description = "" />
|
||||||
<segment id="92292384" start="0" end="4" time = "3.73704" name = " (A16) " distance = "124.568" start_bearing = "138.65222" end_bearing = "158.76529" description = "" />
|
<segment id="92292384" start="0" end="4" time = "3.73704" name = " (A16) " distance = "124.568" start_bearing = "138.65222" end_bearing = "158.76529" description = "" />
|
||||||
<segment id="7230924" start="1" end="10" time = "72.10512" name = " (A16) " distance = "2403.504" start_bearing = "169.56697" end_bearing = "-174.40125" description = "" />
|
<segment id="7230924" start="1" end="10" time = "72.10512" name = " (A16) " distance = "2403.504" start_bearing = "169.56697" end_bearing = "-174.40125" description = "" />
|
||||||
<segment id="7230924" start="10" end="14" time = "27.218878" name = " (A16) " distance = "907.2959" turn = "Keep left" turn_angle = "0.2219696" lanes = "[1, 1, 0]" start_bearing = "-174.17928" end_bearing = "-166.34499" description = "Keep left[1, 1, 0] and go 907.30 meters (*)" />
|
<segment id="7230924" start="10" end="14" time = "27.218878" name = " (A16) " distance = "907.2959" start_bearing = "-174.17928" end_bearing = "-166.34499" description = "" />
|
||||||
<segment id="7230924" start="14" end="19" time = "40.624348" name = " (A16) " distance = "1354.1449" turn = "Keep left" turn_angle = "2.1087189" lanes = "[1, 1, 0]" start_bearing = "-164.23627" end_bearing = "-160.95901" description = "Keep left[1, 1, 0] and go 4952.99 meters (*)" />
|
<segment id="7230924" start="14" end="19" time = "40.624348" name = " (A16) " distance = "1354.1449" turn = "Keep left" turn_angle = "2.1087189" lanes = "[1, 1, 0]" start_bearing = "-164.23627" end_bearing = "-160.95901" description = "Keep left[1, 1, 0] and go 4952.99 meters (*)" />
|
||||||
<segment id="5094229" start="0" end="10" time = "107.96547" name = " (E19) " distance = "3598.8489" start_bearing = "-160.84958" end_bearing = "-166.38635" description = "" />
|
<segment id="5094229" start="0" end="10" time = "107.96547" name = " (E19) " distance = "3598.8489" start_bearing = "-160.84958" end_bearing = "-166.38635" description = "" />
|
||||||
<segment id="5094229" start="10" end="18" time = "95.98541" name = " (E19) " distance = "3199.5134" turn = "Keep left" turn_angle = "-0.7148895" lanes = "[1, 1, 0]" start_bearing = "-167.10124" end_bearing = "-163.62823" description = "Keep left[1, 1, 0] and go 3199.51 meters (*)" />
|
<segment id="5094229" start="10" end="18" time = "95.98541" name = " (E19) " distance = "3199.5134" turn = "Keep left" turn_angle = "-0.7148895" lanes = "[1, 1, 0]" start_bearing = "-167.10124" end_bearing = "-163.62823" description = "Keep left[1, 1, 0] and go 3199.51 meters (*)" />
|
||||||
|
@ -247,59 +249,53 @@
|
||||||
<segment id="146511986" start="0" end="12" time = "40.64995" name = " (E19) " distance = "1354.9982" start_bearing = "-96.938385" end_bearing = "-115.788925" description = "" />
|
<segment id="146511986" start="0" end="12" time = "40.64995" name = " (E19) " distance = "1354.9982" start_bearing = "-96.938385" end_bearing = "-115.788925" description = "" />
|
||||||
<segment id="146511986" start="12" end="66" time = "42.2464" name = " (E19) " distance = "1408.2133" turn = "Keep left" turn_angle = "-0.77612305" start_bearing = "-116.56505" end_bearing = "-146.92932" description = "Keep left and go 2377.37 meters (*)" />
|
<segment id="146511986" start="12" end="66" time = "42.2464" name = " (E19) " distance = "1408.2133" turn = "Keep left" turn_angle = "-0.77612305" start_bearing = "-116.56505" end_bearing = "-146.92932" description = "Keep left and go 2377.37 meters (*)" />
|
||||||
<segment id="4322956" start="0" end="10" time = "29.07467" name = " (R1) " distance = "969.15564" start_bearing = "-158.4047" end_bearing = "-179.59422" description = "" />
|
<segment id="4322956" start="0" end="10" time = "29.07467" name = " (R1) " distance = "969.15564" start_bearing = "-158.4047" end_bearing = "-179.59422" description = "" />
|
||||||
<segment id="4322894" start="0" end="4" time = "15.602006" name = "" distance = "346.71124" turn = "Keep right" turn_angle = "5.7493896" start_bearing = "-173.84483" end_bearing = "180.0" description = "Keep right and go 346.71 meters" />
|
<segment id="48525690" start="0" end="2" time = "11.406443" name = " (R1) " distance = "380.21475" turn = "Keep left" turn_angle = "-1.7390594" start_bearing = "178.66672" end_bearing = "178.84267" description = "Keep left and go 3762.28 meters (*)" />
|
||||||
<segment id="4322895" start="0" end="2" time = "3.3338234" name = "" distance = "74.08497" turn = "Keep right" turn_angle = "15.811371" start_bearing = "-164.18863" end_bearing = "-143.55556" description = "Keep right and go 74.08 meters" />
|
<segment id="4322890" start="0" end="1" time = "3.0917888" name = " (R1) " distance = "103.05962" start_bearing = "-180.0" end_bearing = "180.0" description = "" />
|
||||||
<segment id="8052353" start="0" end="1" time = "6.27333" name = "Groenendaallaan (N129) " distance = "104.555504" turn = "Turn slightly right" turn_angle = "54.170517" start_bearing = "-89.38504" end_bearing = "-89.38504" description = "Turn slightly right and go 312.18 meters" />
|
<segment id="4322864" start="0" end="3" time = "15.195565" name = " (R1) " distance = "506.5188" start_bearing = "179.7205" end_bearing = "176.42366" description = "" />
|
||||||
<segment id="23386081" start="0" end="3" time = "29.949045" name = "Groenendaallaan (N129) " distance = "207.62564" start_bearing = "-91.04479" end_bearing = "-90.47351" description = "" />
|
<segment id="4322584" start="0" end="18" time = "62.07714" name = " (R1) " distance = "1724.3651" start_bearing = "173.4802" end_bearing = "137.81555" description = "" />
|
||||||
<segment id="23385761" start="0" end="1" time = "2.3713744" name = "Groenendaallaan (N129) " distance = "32.935757" turn = "Keep left" turn_angle = "4.8982925" start_bearing = "-85.57522" end_bearing = "-85.57522" description = "Keep left and go 128.72 meters" />
|
<segment id="4322569" start="0" end="11" time = "37.73253" name = " (R1) " distance = "1048.1259" start_bearing = "136.1935" end_bearing = "167.69199" description = "" />
|
||||||
<segment id="23385640" start="0" end="1" time = "17.049618" name = "Groenendaallaan" distance = "28.466919" start_bearing = "-86.28471" end_bearing = "-86.28471" description = "" />
|
<segment id="4322548" start="0" end="9" time = "37.797874" name = " (R1) " distance = "1049.941" turn = "Keep left" turn_angle = "4.876602" start_bearing = "172.56859" end_bearing = "-148.27234" description = "Keep left and go 1049.94 meters (*)" />
|
||||||
<segment id="12985644" start="0" end="2" time = "17.797262" name = "Groenendaallaan (N101) " distance = "38.85086" start_bearing = "-91.33222" end_bearing = "-90.45114" description = "" />
|
<segment id="4312411" start="0" end="4" time = "12.700957" name = "" distance = "282.2435" turn = "Keep right" turn_angle = "8.655991" start_bearing = "-139.61635" end_bearing = "-135.0" description = "Keep right and go 466.72 meters" />
|
||||||
<segment id="23385755" start="0" end="1" time = "2.0496185" name = "Groenendaallaan (N101) " distance = "28.466923" start_bearing = "-94.604485" end_bearing = "-94.604485" description = "" />
|
<segment id="4312416" start="0" end="1" time = "3.1672919" name = "" distance = "70.38426" start_bearing = "-131.5834" end_bearing = "-131.5834" description = "" />
|
||||||
<segment id="23385755" start="1" end="4" time = "24.253155" name = "Groenendaallaan (N101) " distance = "128.51604" turn = "Keep left" turn_angle = "3.736435" start_bearing = "-90.86805" end_bearing = "-92.97373" description = "Keep left and go 315.10 meters (*)" />
|
<segment id="4312424" start="0" end="2" time = "5.134262" name = "" distance = "114.09471" start_bearing = "-135.54565" end_bearing = "-142.83553" description = "" />
|
||||||
<segment id="83289991" start="0" end="5" time = "9.595843" name = "Groenendaallaan (N101) " distance = "186.58585" start_bearing = "-96.77957" end_bearing = "-85.083435" description = "" />
|
<segment id="4312429" start="0" end="2" time = "3.6745079" name = "" distance = "81.65573" turn = "Keep right" turn_angle = "2.3079834" start_bearing = "-140.52754" end_bearing = "-132.18445" description = "Keep right and go 81.66 meters" />
|
||||||
<segment id="83289991" start="5" end="6" time = "1.7055488" name = "Groenendaallaan (N101) " distance = "33.16345" turn = "Keep left" turn_angle = "-12.361893" start_bearing = "-97.44533" end_bearing = "-97.44533" description = "Keep left and go 76.67 meters" />
|
<segment id="146171826" start="0" end="2" time = "3.7306597" name = "Luitenant Lippenslaan (N184) " distance = "62.17766" turn = "Turn slightly right" turn_angle = "51.157074" start_bearing = "-81.027374" end_bearing = "-80.01059" description = "Turn slightly right and go 1112.29 meters" />
|
||||||
<segment id="23135820" start="0" end="2" time = "17.237564" name = "Straatsburgbrug (N101) " distance = "43.508186" start_bearing = "-109.30867" end_bearing = "-127.25529" description = "" />
|
<segment id="4395067" start="0" end="1" time = "26.002739" name = " (N184) " distance = "16.712315" start_bearing = "-79.69515" end_bearing = "-79.69515" description = "" />
|
||||||
<segment id="23135820" start="2" end="7" time = "13.779428" name = "Straatsburgbrug (N101) " distance = "267.93332" turn = "Keep left" turn_angle = "-17.293846" start_bearing = "-144.54913" end_bearing = "-165.66893" description = "Keep left and go 1050.13 meters" />
|
<segment id="4453106" start="0" end="6" time = "42.581" name = "Plantin en Moretuslei (N184) " distance = "293.01666" start_bearing = "-84.33272" end_bearing = "-84.770546" description = "" />
|
||||||
<segment id="23135823" start="0" end="5" time = "12.410626" name = "Straatsburgbrug (N101) " distance = "241.31773" start_bearing = "-161.98022" end_bearing = "-135.0" description = "" />
|
<segment id="35006131" start="0" end="4" time = "16.293785" name = "Plantin en Moretuslei (N184) " distance = "271.56308" start_bearing = "-81.809135" end_bearing = "-79.597755" description = "" />
|
||||||
<segment id="23135833" start="0" end="8" time = "11.765425" name = "Straatsburgbrug (N101) " distance = "228.77214" start_bearing = "-131.33221" end_bearing = "-28.096178" description = "" />
|
<segment id="29218710" start="0" end="8" time = "28.1292" name = "Plantin en Moretuslei (N184) " distance = "468.82" start_bearing = "-75.28796" end_bearing = "-101.04094" description = "" />
|
||||||
<segment id="23362097" start="0" end="6" time = "25.592014" name = "Siberiastraat (N101) " distance = "176.53357" start_bearing = "-35.202183" end_bearing = "-90.0" description = "" />
|
<segment id="34785645" start="0" end="2" time = "34.048256" name = "Plantin en Moretuslei (N184) " distance = "150.80424" turn = "Keep right" turn_angle = "30.52707" start_bearing = "-70.51387" end_bearing = "-84.97339" description = "Keep right and go 530.39 meters" />
|
||||||
<segment id="23362104" start="0" end="1" time = "2.7786715" name = "Siberiabrug (N101) " distance = "46.31119" start_bearing = "-89.06844" end_bearing = "-89.06844" description = "" />
|
<segment id="50897387" start="0" end="1" time = "1.1658815" name = "Plantin en Moretuslei (N184) " distance = "19.43136" start_bearing = "-90.0" end_bearing = "-90.0" description = "" />
|
||||||
<segment id="23362109" start="0" end="5" time = "5.355517" name = "Siberiastraat (N101) " distance = "89.25862" start_bearing = "-90.0" end_bearing = "-122.330185" description = "" />
|
<segment id="34785644" start="0" end="4" time = "6.0505266" name = "Plantin en Moretuslei (N184) " distance = "100.84211" start_bearing = "-91.39718" end_bearing = "-96.84277" description = "" />
|
||||||
<segment id="83290899" start="0" end="2" time = "1.2550789" name = "Siberiastraat (N101) " distance = "20.917982" turn = "Keep left" turn_angle = "-32.84047" start_bearing = "-155.17065" end_bearing = "-167.125" description = "Keep left and go 200.86 meters" />
|
<segment id="43287076" start="1" end="0" time = "25.86766" name = "Plantin en Moretuslei" distance = "12.050846" start_bearing = "-96.05419" end_bearing = "-96.05419" description = "" />
|
||||||
<segment id="15555547" start="1" end="0" time = "1.1728384" name = "Siberiastraat (N101) " distance = "19.547306" start_bearing = "-137.72632" end_bearing = "-137.72632" description = "" />
|
<segment id="50897385" start="0" end="1" time = "39.183067" name = "Plantin en Moretuslei (N184) " distance = "236.38448" start_bearing = "-96.983826" end_bearing = "-96.983826" description = "" />
|
||||||
<segment id="23008534" start="0" end="4" time = "9.623776" name = "Siberiastraat (N101) " distance = "160.39627" start_bearing = "-137.96486" end_bearing = "-139.27477" description = "" />
|
<segment id="21080483" start="0" end="1" time = "0.7834903" name = "Plantin en Moretuslei (N184) " distance = "10.881809" start_bearing = "-74.42746" end_bearing = "-74.42746" description = "" />
|
||||||
<segment id="23008534" start="4" end="6" time = "3.1598182" name = "Siberiastraat (N101) " distance = "52.663635" turn = "Keep left" turn_angle = "-2.25737" start_bearing = "-141.53214" end_bearing = "-145.89354" description = "Keep left and go 348.54 meters" />
|
<segment id="29239262" start="0" end="1" time = "1.9438865" name = "Plantin en Moretuslei (N184) " distance = "26.998425" turn = "Keep left" turn_angle = "-20.766968" start_bearing = "-95.19443" end_bearing = "-95.19443" description = "Keep left and go 1284.23 meters" />
|
||||||
<segment id="23541825" start="0" end="3" time = "17.776953" name = "Oosterweelsteenweg" distance = "222.2119" start_bearing = "-176.3396" end_bearing = "-161.56505" description = "" />
|
<segment id="4394995" start="0" end="1" time = "25.981947" name = "Plantin en Moretuslei (N184) " distance = "13.63815" start_bearing = "-98.130104" end_bearing = "-98.130104" description = "" />
|
||||||
<segment id="23361097" start="0" end="5" time = "5.8934116" name = "Mosselstraat" distance = "73.66764" start_bearing = "-130.85538" end_bearing = "-104.38139" description = "" />
|
<segment id="4394994" start="0" end="1" time = "26.742825" name = "Van Eycklei (N184) " distance = "24.205906" start_bearing = "-99.6052" end_bearing = "-99.6052" description = "" />
|
||||||
<segment id="46420908" start="0" end="8" time = "16.047739" name = "Sloepenweg" distance = "222.88528" turn = "Turn slightly left" turn_angle = "-46.26085" start_bearing = "-150.64224" end_bearing = "150.64224" description = "Turn slightly left and go 308.08 meters" />
|
<segment id="34855821" start="0" end="1" time = "2.282983" name = "Van Eycklei (N184) " distance = "31.7081" start_bearing = "-97.16724" end_bearing = "-97.16724" description = "" />
|
||||||
<segment id="33886773" start="0" end="3" time = "6.1337266" name = "Sloepenweg" distance = "85.19065" start_bearing = "106.03994" end_bearing = "131.39153" description = "" />
|
<segment id="34855824" start="0" end="8" time = "32.686893" name = "Van Eycklei (N184) " distance = "453.98465" start_bearing = "-84.99417" end_bearing = "-56.309933" description = "" />
|
||||||
<segment id="117440382" start="0" end="1" time = "2.4762578" name = "Rijnkaai" distance = "34.39247" turn = "Turn slightly right" turn_angle = "47.369843" start_bearing = "178.76137" end_bearing = "178.76137" description = "Turn slightly right and go 1717.08 meters" />
|
<segment id="4394980" start="0" end="1" time = "25.729961" name = "Maria-Henriëttalei (N184) " distance = "12.16601" start_bearing = "-46.301952" end_bearing = "-46.301952" description = "" />
|
||||||
<segment id="117440385" start="0" end="1" time = "3.4957857" name = "Kattendijkbrug" distance = "48.55258" start_bearing = "179.77878" end_bearing = "179.77878" description = "" />
|
<segment id="4430256" start="0" end="2" time = "31.529934" name = "Maria-Henriëttalei (N184) " distance = "108.83224" start_bearing = "-50.833004" end_bearing = "-47.683777" description = "" />
|
||||||
<segment id="133648996" start="0" end="2" time = "5.0220265" name = "Rijnkaai" distance = "69.75037" start_bearing = "179.80174" end_bearing = "-171.8699" description = "" />
|
<segment id="133434343" start="0" end="1" time = "0.48502362" name = "Maria-Henriëttalei (N184) " distance = "8.083727" start_bearing = "-31.429565" end_bearing = "-31.429565" description = "" />
|
||||||
<segment id="120143807" start="0" end="3" time = "3.6428173" name = "Rijnkaai" distance = "45.535217" start_bearing = "-145.49147" end_bearing = "-111.54098" description = "" />
|
<segment id="8052374" start="0" end="3" time = "27.157873" name = "Frankrijklei" distance = "35.96455" start_bearing = "-35.90972" end_bearing = "-44.464542" description = "" />
|
||||||
<segment id="120143808" start="0" end="4" time = "8.720661" name = "Rijnkaai" distance = "121.1203" start_bearing = "-137.04541" end_bearing = "179.19307" description = "" />
|
<segment id="4446690" start="0" end="4" time = "32.2554" name = "Bourlastraat" distance = "90.6925" start_bearing = "-47.935673" end_bearing = "-71.87814" description = "" />
|
||||||
<segment id="83349187" start="0" end="2" time = "3.610016" name = "Rijnkaai" distance = "50.139114" start_bearing = "178.03859" end_bearing = "176.24828" description = "" />
|
<segment id="4446716" start="0" end="7" time = "3.168966" name = "Leopoldplaats" distance = "39.612076" start_bearing = "-59.743565" end_bearing = "-8.972627" description = "" />
|
||||||
<segment id="50883861" start="0" end="2" time = "4.1431518" name = "Rijnkaai" distance = "57.543777" start_bearing = "158.1986" end_bearing = "169.57928" description = "" />
|
<segment id="7940942" start="0" end="8" time = "28.65889" name = "Leopoldstraat" distance = "358.2361" start_bearing = "-4.969741" end_bearing = "-23.498566" description = "" />
|
||||||
<segment id="23361255" start="0" end="2" time = "4.742435" name = "Rijnkaai" distance = "65.86715" start_bearing = "-175.4139" end_bearing = "179.32198" description = "" />
|
<segment id="7940955" start="0" end="2" time = "6.4086165" name = "Komedieplaats" distance = "80.107704" start_bearing = "-46.684685" end_bearing = "-51.608463" description = "" />
|
||||||
<segment id="133656814" start="0" end="2" time = "3.3451478" name = "Rijnkaai" distance = "46.46039" start_bearing = "-169.33022" end_bearing = "-167.41231" description = "" />
|
<segment id="4446795" start="0" end="2" time = "1.3632743" name = "Komedieplaats" distance = "17.04093" turn = "Keep right" turn_angle = "11.372105" start_bearing = "-40.23636" end_bearing = "-27.645975" description = "Keep right and go 226.12 meters" />
|
||||||
<segment id="19584404" start="0" end="1" time = "17.841076" name = "Rijnkaai" distance = "35.51344" start_bearing = "-164.95361" end_bearing = "-164.95361" description = "" />
|
<segment id="4446775" start="0" end="16" time = "15.203991" name = "Huidevettersstraat" distance = "190.0499" start_bearing = "-8.746162" end_bearing = "-1.1457628" description = "" />
|
||||||
<segment id="133656813" start="0" end="1" time = "3.7797394" name = "Rijnkaai" distance = "47.246742" start_bearing = "-160.92291" end_bearing = "-160.92291" description = "" />
|
<segment id="4446826" start="0" end="3" time = "1.5223826" name = "Meir" distance = "19.029783" start_bearing = "-7.6960516" end_bearing = "-30.963757" description = "" />
|
||||||
<segment id="82652955" start="0" end="3" time = "7.2567635" name = "Rijnkaai" distance = "90.70954" start_bearing = "-158.13142" end_bearing = "-164.4072" description = "" />
|
<segment id="25150191" start="0" end="5" time = "27.61911" name = "Meir" distance = "32.738888" turn = "Keep left" turn_angle = "-32.47119" start_bearing = "-63.434948" end_bearing = "-69.14554" description = "Keep left and go 439.14 meters" />
|
||||||
<segment id="32874073" start="0" end="7" time = "16.602541" name = "Tavernierkaai" distance = "207.53177" start_bearing = "-169.77783" end_bearing = "-160.34618" description = "" />
|
<segment id="19752616" start="0" end="1" time = "27.84184" name = "Meirbrug" distance = "35.52302" start_bearing = "-75.08797" end_bearing = "-75.08797" description = "" />
|
||||||
<segment id="22957749" start="0" end="3" time = "5.8082724" name = "Tavernierkaai" distance = "72.60341" start_bearing = "-151.02586" end_bearing = "-145.00798" description = "" />
|
<segment id="33682293" start="0" end="1" time = "0.71734244" name = "Meirbrug" distance = "8.966781" start_bearing = "-86.00909" end_bearing = "-86.00909" description = "" />
|
||||||
<segment id="82651772" start="0" end="2" time = "2.1968422" name = "Tavernierkaai" distance = "27.460526" start_bearing = "-149.96672" end_bearing = "-147.17146" description = "" />
|
<segment id="7940939" start="0" end="6" time = "5.6946187" name = "Schoenmarkt" distance = "71.18273" start_bearing = "-103.392494" end_bearing = "-96.94099" description = "" />
|
||||||
<segment id="22957750" start="0" end="5" time = "21.785543" name = "Van Meterenkaai" distance = "94.243675" start_bearing = "-146.92932" end_bearing = "-150.41223" description = "" />
|
<segment id="76441128" start="0" end="5" time = "5.179564" name = "Schoenmarkt" distance = "64.74455" start_bearing = "-94.159645" end_bearing = "-80.37184" description = "" />
|
||||||
<segment id="22957751" start="0" end="1" time = "2.317422" name = "Orteliuskaai" distance = "32.186417" start_bearing = "-158.25922" end_bearing = "-158.25922" description = "" />
|
<segment id="76441130" start="0" end="3" time = "27.35271" name = "Schoenmarkt" distance = "29.40888" start_bearing = "-82.874985" end_bearing = "-69.04422" description = "" />
|
||||||
<segment id="22957752" start="0" end="2" time = "8.450739" name = "Jordaenskaai" distance = "117.37138" start_bearing = "-158.61746" end_bearing = "-155.77225" description = "" />
|
<segment id="19752819" start="0" end="5" time = "5.676056" name = "Groenplaats" distance = "70.9507" start_bearing = "-73.73979" end_bearing = "-68.06462" description = "" />
|
||||||
<segment id="25788113" start="0" end="6" time = "17.696148" name = "Jordaenskaai" distance = "245.77983" start_bearing = "-157.96378" end_bearing = "-158.80594" description = "" />
|
<segment id="19882382" start="0" end="3" time = "1.5475764" name = "" distance = "19.344706" start_bearing = "-90.0" end_bearing = "-147.65256" description = "" />
|
||||||
<segment id="82652959" start="0" end="2" time = "4.6872363" name = "Jordaenskaai" distance = "65.1005" start_bearing = "-158.1986" end_bearing = "-158.65422" description = "" />
|
<segment id="7940936" start="15" end="14" time = "37.753136" name = "Nationalestraat" distance = "106.27612" start_bearing = "-154.78815" end_bearing = "-154.78815" description = "" />
|
||||||
<segment id="22957753" start="0" end="2" time = "10.221777" name = "Ernest Van Dijckkaai" distance = "141.96913" start_bearing = "-157.03622" end_bearing = "-156.81464" description = "" />
|
<segment id="22092951" start="0" end="3" time = "40.335327" name = "Lombardenvest" distance = "149.09346" turn = "Turn left" turn_angle = "-106.25054" start_bearing = "98.96131" end_bearing = "112.306206" description = "Turn left and go 149.09 meters" />
|
||||||
<segment id="18954370" start="0" end="3" time = "30.17769" name = "Suikerrui" distance = "147.56088" turn = "Turn left" turn_angle = "-84.42139" start_bearing = "118.76398" end_bearing = "114.26589" description = "Turn left and go 512.98 meters" />
|
|
||||||
<segment id="23220777" start="0" end="1" time = "1.0868886" name = "Suikerrui" distance = "10.566973" start_bearing = "132.76883" end_bearing = "132.76883" description = "" />
|
|
||||||
<segment id="19078058" start="0" end="5" time = "12.994094" name = "Oude Koornmarkt" distance = "126.331474" start_bearing = "132.8142" end_bearing = "150.21947" description = "" />
|
|
||||||
<segment id="82654432" start="0" end="3" time = "11.758362" name = "Oude Koornmarkt" distance = "114.31741" start_bearing = "162.62924" end_bearing = "-169.24203" description = "" />
|
|
||||||
<segment id="19078060" start="0" end="4" time = "11.74693" name = "Kammenstraat" distance = "114.20627" start_bearing = "-175.45801" end_bearing = "167.90524" description = "" />
|
|
||||||
<segment id="22092951" start="0" end="3" time = "30.335327" name = "Lombardenvest" distance = "149.09346" turn = "Turn left" turn_angle = "-68.94393" start_bearing = "98.96131" end_bearing = "112.306206" description = "Turn left and go 149.09 meters" />
|
|
||||||
<segment id="22093399" start="0" end="1" time = "3.7942796" name = "" distance = "36.88883" turn = "Turn right" turn_angle = "60.98716" start_bearing = "173.29337" end_bearing = "173.29337" description = "Turn right and go 36.89 meters" />
|
<segment id="22093399" start="0" end="1" time = "3.7942796" name = "" distance = "36.88883" turn = "Turn right" turn_angle = "60.98716" start_bearing = "173.29337" end_bearing = "173.29337" description = "Turn right and go 36.89 meters" />
|
||||||
</test>
|
</test>
|
||||||
</router_tests>
|
</router_tests>
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<router_tests>
|
<router_tests>
|
||||||
<test regions="" description="Amstelveen-Leiden" best_percent="5" vehicle="car"
|
<test regions="" description="Amstelveen-Leiden" best_percent="5" vehicle="car"
|
||||||
start_lat="52.291026337270445" start_lon="4.848833084106445" target_lat="52.16400849542039" target_lon="4.478881359100342" complete_time="1810.644" loadedTiles = "45" visitedSegments = "2512" complete_distance = "41994.66" >
|
start_lat="52.291026337270445" start_lon="4.848833084106445" target_lat="52.16400849542039" target_lon="4.478881359100342" complete_time="1810.644" loadedTiles = "650" visitedSegments = "2512" complete_distance = "41994.66" >
|
||||||
<segment id="48102635" start="9" end="17" time = "26.337616" name = "" distance = "365.80023" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-80.22256" end_bearing = "-79.69515" description = "Go ahead and go 365.80 meters" />
|
<segment id="48102635" start="9" end="17" time = "26.337616" name = "" distance = "365.80023" turn = "Go ahead" turn_angle = "0.0" start_bearing = "-80.22256" end_bearing = "-79.69515" description = "Go ahead and go 365.80 meters" />
|
||||||
<segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" turn = "Turn right" turn_angle = "87.82526" start_bearing = "8.130102" end_bearing = "9.901572" description = "Turn right and go 548.57 meters" />
|
<segment id="7364781" start="0" end="6" time = "64.496864" name = "Handweg" distance = "548.56757" turn = "Turn right" turn_angle = "87.82526" start_bearing = "8.130102" end_bearing = "9.901572" description = "Turn right and go 548.57 meters" />
|
||||||
<segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
|
<segment id="7364782" start="1" end="0" time = "26.062386" name = "Keizer Karelweg" distance = "14.755359" turn = "Turn right" turn_angle = "89.328316" start_bearing = "99.22989" end_bearing = "99.22989" description = "Turn right and go 917.26 meters" />
|
||||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
import net.osmand.render.RenderingRuleSearchRequest;
|
import net.osmand.render.RenderingRuleSearchRequest;
|
||||||
import net.osmand.render.RenderingRulesStorage;
|
import net.osmand.render.RenderingRulesStorage;
|
||||||
|
@ -42,7 +43,7 @@ public class NativeLibrary {
|
||||||
|
|
||||||
public long nativeHandler;
|
public long nativeHandler;
|
||||||
public RouteDataObject[] objects;
|
public RouteDataObject[] objects;
|
||||||
public RouteRegion region;
|
public RouteSubregion region;
|
||||||
public NativeRouteSearchResult(long nativeHandler, RouteDataObject[] objects) {
|
public NativeRouteSearchResult(long nativeHandler, RouteDataObject[] objects) {
|
||||||
this.nativeHandler = nativeHandler;
|
this.nativeHandler = nativeHandler;
|
||||||
this.objects = objects;
|
this.objects = objects;
|
||||||
|
@ -76,7 +77,7 @@ public class NativeLibrary {
|
||||||
if(rs.nativeHandler == 0) {
|
if(rs.nativeHandler == 0) {
|
||||||
throw new IllegalStateException("Native route handler is 0");
|
throw new IllegalStateException("Native route handler is 0");
|
||||||
}
|
}
|
||||||
return getRouteDataObjects(rs.region, rs.nativeHandler, x31, y31);
|
return getRouteDataObjects(rs.region.routeReg, rs.nativeHandler, x31, y31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,16 +95,17 @@ public class NativeLibrary {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public NativeRouteSearchResult loadRouteRegion(RouteRegion reg, int left, int right, int top, int bottom, boolean loadObjects) {
|
public NativeRouteSearchResult loadRouteRegion(RouteSubregion sub, boolean loadObjects) {
|
||||||
NativeRouteSearchResult lr = loadRoutingData(reg, reg.getName(), reg.getFilePointer(), left, right, top, bottom, loadObjects);
|
NativeRouteSearchResult lr = loadRoutingData(sub.routeReg, sub.routeReg.getName(), sub.routeReg.getFilePointer(),
|
||||||
|
sub, loadObjects);
|
||||||
if(lr != null && lr.nativeHandler != 0){
|
if(lr != null && lr.nativeHandler != 0){
|
||||||
lr.region = reg;
|
lr.region = sub;
|
||||||
}
|
}
|
||||||
return lr;
|
return lr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int fpointer, int left, int right, int top, int bottom,
|
protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int regfp,RouteSubregion subreg,
|
||||||
boolean loadObjects);
|
boolean loadObjects);
|
||||||
|
|
||||||
protected static native void deleteRouteSearchResult(long searchResultHandle);
|
protected static native void deleteRouteSearchResult(long searchResultHandle);
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class BinaryInspector {
|
||||||
// test cases show info
|
// test cases show info
|
||||||
|
|
||||||
|
|
||||||
//inspector(new String[]{"-vaddress",/* "-bbox=-121.785,37.35,-121.744,37.33", */"/home/victor/projects/OsmAnd/data/osm-gen/Map.obf"});
|
inspector(new String[]{/*"-vaddress", "-bbox=-121.785,37.35,-121.744,37.33", */"/home/victor/projects/OsmAnd/data/osm-gen/Netherlands_europe.obf"});
|
||||||
// test case extract parts
|
// test case extract parts
|
||||||
// test case
|
// test case
|
||||||
}
|
}
|
||||||
|
|
|
@ -1963,15 +1963,29 @@ public class BinaryMapIndexReader {
|
||||||
routeAdapter.initRouteTypesIfNeeded(req);
|
routeAdapter.initRouteTypesIfNeeded(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void searchRouteIndex(SearchRequest<RouteDataObject> req, List<RouteSubregion> list) throws IOException {
|
public List<RouteSubregion> searchRouteIndexTree(SearchRequest<RouteDataObject> req, List<RouteSubregion> list) throws IOException {
|
||||||
req.numberOfVisitedObjects = 0;
|
req.numberOfVisitedObjects = 0;
|
||||||
req.numberOfAcceptedObjects = 0;
|
req.numberOfAcceptedObjects = 0;
|
||||||
req.numberOfAcceptedSubtrees = 0;
|
req.numberOfAcceptedSubtrees = 0;
|
||||||
req.numberOfReadSubtrees = 0;
|
req.numberOfReadSubtrees = 0;
|
||||||
if(routeAdapter != null){
|
if(routeAdapter != null){
|
||||||
initRouteRegionsIfNeeded(req);
|
initRouteRegionsIfNeeded(req);
|
||||||
routeAdapter.searchRouteRegion(req, list);
|
return routeAdapter.searchRouteRegionTree(req, list, new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>());
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadRouteIndexData(List<RouteSubregion> toLoad, ResultMatcher<RouteDataObject> matcher) throws IOException {
|
||||||
|
if(routeAdapter != null){
|
||||||
|
routeAdapter.loadRouteRegionData(toLoad, matcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<RouteDataObject> loadRouteIndexData(RouteSubregion rs) throws IOException {
|
||||||
|
if(routeAdapter != null){
|
||||||
|
return routeAdapter.loadRouteRegionData(rs);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,6 +13,7 @@ import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.osmand.LogUtil;
|
import net.osmand.LogUtil;
|
||||||
|
import net.osmand.ResultMatcher;
|
||||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||||
import net.osmand.binary.OsmandOdb.IdTable;
|
import net.osmand.binary.OsmandOdb.IdTable;
|
||||||
import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteDataBlock;
|
import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteDataBlock;
|
||||||
|
@ -154,7 +155,7 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RouteRegion extends BinaryIndexPart {
|
public static class RouteRegion extends BinaryIndexPart {
|
||||||
int regionsRead;
|
public int regionsRead;
|
||||||
|
|
||||||
List<RouteSubregion> subregions = new ArrayList<RouteSubregion>();
|
List<RouteSubregion> subregions = new ArrayList<RouteSubregion>();
|
||||||
List<RouteTypeRule> routeEncodingRules = new ArrayList<BinaryMapRouteReaderAdapter.RouteTypeRule>();
|
List<RouteTypeRule> routeEncodingRules = new ArrayList<BinaryMapRouteReaderAdapter.RouteTypeRule>();
|
||||||
|
@ -214,6 +215,7 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used in C++
|
||||||
public static class RouteSubregion {
|
public static class RouteSubregion {
|
||||||
private final static int INT_SIZE = 4;
|
private final static int INT_SIZE = 4;
|
||||||
public final RouteRegion routeReg;
|
public final RouteRegion routeReg;
|
||||||
|
@ -250,6 +252,16 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
}
|
}
|
||||||
return shallow;
|
return shallow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int countSubregions(){
|
||||||
|
int cnt = 1;
|
||||||
|
if (subregions != null) {
|
||||||
|
for (RouteSubregion s : subregions) {
|
||||||
|
cnt += s.countSubregions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodedInputStreamRAF codedIS;
|
private CodedInputStreamRAF codedIS;
|
||||||
|
@ -576,6 +588,11 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
break;
|
break;
|
||||||
case RouteDataBox.SHIFTTODATA_FIELD_NUMBER :
|
case RouteDataBox.SHIFTTODATA_FIELD_NUMBER :
|
||||||
thisTree.shiftToData = readInt();
|
thisTree.shiftToData = readInt();
|
||||||
|
if(!readChildren) {
|
||||||
|
// usually 0
|
||||||
|
thisTree.subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
|
||||||
|
readChildren = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case RouteDataBox.BOXES_FIELD_NUMBER :
|
case RouteDataBox.BOXES_FIELD_NUMBER :
|
||||||
if(readChildren){
|
if(readChildren){
|
||||||
|
@ -617,12 +634,25 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void searchRouteRegion(SearchRequest<RouteDataObject> req, List<RouteSubregion> list) throws IOException {
|
|
||||||
List<RouteSubregion> toLoad = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
|
public List<RouteDataObject> loadRouteRegionData(RouteSubregion rs) throws IOException {
|
||||||
searchRouteRegion(req, list, toLoad);
|
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 loadRouteRegionData(List<RouteSubregion> toLoad, ResultMatcher<RouteDataObject> matcher) throws IOException {
|
||||||
Collections.sort(toLoad, new Comparator<RouteSubregion>() {
|
Collections.sort(toLoad, new Comparator<RouteSubregion>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(RouteSubregion o1, RouteSubregion o2) {
|
public int compare(RouteSubregion o1, RouteSubregion o2) {
|
||||||
|
@ -643,7 +673,7 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
}
|
}
|
||||||
for (RouteDataObject ro : rs.dataObjects) {
|
for (RouteDataObject ro : rs.dataObjects) {
|
||||||
if (ro != null) {
|
if (ro != null) {
|
||||||
req.publish(ro);
|
matcher.publish(ro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// free objects
|
// free objects
|
||||||
|
@ -651,8 +681,9 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchRouteRegion(SearchRequest<RouteDataObject> req, List<RouteSubregion> list, List<RouteSubregion> toLoad) throws IOException {
|
public List<RouteSubregion> searchRouteRegionTree(SearchRequest<RouteDataObject> req, List<RouteSubregion> list,
|
||||||
for(RouteSubregion rs : list){
|
List<RouteSubregion> toLoad) throws IOException {
|
||||||
|
for (RouteSubregion rs : list) {
|
||||||
if (req.intersects(rs.left, rs.top, rs.right, rs.bottom)) {
|
if (req.intersects(rs.left, rs.top, rs.right, rs.bottom)) {
|
||||||
if (rs.subregions == null) {
|
if (rs.subregions == null) {
|
||||||
codedIS.seek(rs.filePointer);
|
codedIS.seek(rs.filePointer);
|
||||||
|
@ -660,13 +691,14 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
readRouteTree(rs, null, req.contains(rs.left, rs.top, rs.right, rs.bottom) ? -1 : 1, false);
|
readRouteTree(rs, null, req.contains(rs.left, rs.top, rs.right, rs.bottom) ? -1 : 1, false);
|
||||||
codedIS.popLimit(old);
|
codedIS.popLimit(old);
|
||||||
}
|
}
|
||||||
searchRouteRegion(req, rs.subregions, toLoad);
|
searchRouteRegionTree(req, rs.subregions, toLoad);
|
||||||
|
|
||||||
if (rs.shiftToData != 0) {
|
if (rs.shiftToData != 0) {
|
||||||
toLoad.add(rs);
|
toLoad.add(rs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.osmand.binary;
|
package net.osmand.binary;
|
||||||
|
|
||||||
|
|
||||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package net.osmand.router;
|
package net.osmand.router;
|
||||||
|
|
||||||
import gnu.trove.iterator.TIntObjectIterator;
|
|
||||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
|
||||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -11,23 +9,13 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import net.osmand.LogUtil;
|
import net.osmand.LogUtil;
|
||||||
import net.osmand.NativeLibrary;
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter;
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
import net.osmand.osm.MapRenderingTypes;
|
import net.osmand.osm.MapRenderingTypes;
|
||||||
import net.osmand.osm.MapUtils;
|
import net.osmand.osm.MapUtils;
|
||||||
import net.osmand.router.RoutingContext.RoutingTile;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
@ -35,8 +23,7 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
||||||
private final int REVERSE_WAY_RESTRICTION_ONLY = 1024;
|
private final int REVERSE_WAY_RESTRICTION_ONLY = 1024;
|
||||||
private final NativeLibrary nativeLib;
|
private final int STANDARD_ROAD_IN_QUEUE_OVERHEAD = 900;
|
||||||
private final Map<BinaryMapIndexReader, List<RouteSubregion>> map = new LinkedHashMap<BinaryMapIndexReader, List<RouteSubregion>>();
|
|
||||||
|
|
||||||
protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
|
protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
|
||||||
|
|
||||||
|
@ -44,24 +31,6 @@ public class BinaryRoutePlanner {
|
||||||
private static final float TURN_DEGREE_MIN = 45;
|
private static final float TURN_DEGREE_MIN = 45;
|
||||||
|
|
||||||
|
|
||||||
public BinaryRoutePlanner(NativeLibrary nativeLib, BinaryMapIndexReader... map) {
|
|
||||||
this.nativeLib = nativeLib;
|
|
||||||
if(nativeLib != null) {
|
|
||||||
RoutingConfiguration.DEFAULT_DESIRABLE_TILES_IN_MEMORY = 100;
|
|
||||||
}
|
|
||||||
for (BinaryMapIndexReader mr : map) {
|
|
||||||
List<RouteRegion> rr = mr.getRoutingIndexes();
|
|
||||||
List<RouteSubregion> subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
|
|
||||||
for (RouteRegion r : rr) {
|
|
||||||
for (RouteSubregion rs : r.getSubregions()) {
|
|
||||||
subregions.add(new RouteSubregion(rs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.map.put(mr, subregions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static double squareRootDist(int x1, int y1, int x2, int y2) {
|
private static double squareRootDist(int x1, int y1, int x2, int y2) {
|
||||||
// translate into meters
|
// translate into meters
|
||||||
double dy = convert31YToMeters(y1, y2);
|
double dy = convert31YToMeters(y1, y2);
|
||||||
|
@ -102,49 +71,38 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
|
|
||||||
public RouteSegment findRouteSegment(double lat, double lon, RoutingContext ctx) throws IOException {
|
public RouteSegment findRouteSegment(double lat, double lon, RoutingContext ctx) throws IOException {
|
||||||
int zoomAround = 15;
|
|
||||||
int coordinatesShift = (1 << (31 - zoomAround));
|
|
||||||
int px = MapUtils.get31TileNumberX(lon);
|
int px = MapUtils.get31TileNumberX(lon);
|
||||||
int py = MapUtils.get31TileNumberY(lat);
|
int py = MapUtils.get31TileNumberY(lat);
|
||||||
// put in map to avoid duplicate map loading
|
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
||||||
TIntObjectHashMap<RoutingTile> ts = new TIntObjectHashMap<RoutingContext.RoutingTile>();
|
ctx.loadTileData(px, py, 16, dataObjects);
|
||||||
// calculate box to load neighbor tiles
|
if (dataObjects.isEmpty()) {
|
||||||
RoutingTile rt = ctx.getRoutingTile(px - coordinatesShift, py - coordinatesShift);
|
ctx.loadTileData(px, py, 14, dataObjects);
|
||||||
ts.put(rt.getId(), rt);
|
|
||||||
rt = ctx.getRoutingTile(px + coordinatesShift, py - coordinatesShift);
|
|
||||||
ts.put(rt.getId(), rt);
|
|
||||||
rt = ctx.getRoutingTile(px - coordinatesShift, py + coordinatesShift);
|
|
||||||
ts.put(rt.getId(), rt);
|
|
||||||
rt = ctx.getRoutingTile(px + coordinatesShift, py + coordinatesShift);
|
|
||||||
ts.put(rt.getId(), rt);
|
|
||||||
|
|
||||||
List<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
|
||||||
Iterator<RoutingTile> it = ts.valueCollection().iterator();
|
|
||||||
while(it.hasNext()){
|
|
||||||
ctx.loadTileData(it.next(), dataObjects, nativeLib, map);
|
|
||||||
}
|
}
|
||||||
RouteSegment road = null;
|
RouteSegment road = null;
|
||||||
double sdist = 0;
|
double sdist = 0;
|
||||||
int foundProjX = 0;
|
int foundProjX = 0;
|
||||||
int foundProjY = 0;
|
int foundProjY = 0;
|
||||||
|
|
||||||
for(RouteDataObject r : dataObjects){
|
for (RouteDataObject r : dataObjects) {
|
||||||
if(r.getPointsLength() > 1){
|
if (r.getPointsLength() > 1) {
|
||||||
for (int j = 1; j < r.getPointsLength(); j++) {
|
for (int j = 1; j < r.getPointsLength(); j++) {
|
||||||
double mDist = squareRootDist(r.getPoint31XTile(j), r.getPoint31YTile(j), r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1));
|
double mDist = squareRootDist(r.getPoint31XTile(j), r.getPoint31YTile(j), r.getPoint31XTile(j - 1),
|
||||||
|
r.getPoint31YTile(j - 1));
|
||||||
int prx = r.getPoint31XTile(j);
|
int prx = r.getPoint31XTile(j);
|
||||||
int pry = r.getPoint31YTile(j);
|
int pry = r.getPoint31YTile(j);
|
||||||
double projection = calculateProjection(r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1), r.getPoint31XTile(j), r.getPoint31YTile(j),
|
double projection = calculateProjection(r.getPoint31XTile(j - 1), r.getPoint31YTile(j - 1), r.getPoint31XTile(j),
|
||||||
px, py);
|
r.getPoint31YTile(j), px, py);
|
||||||
if(projection < 0){
|
if (projection < 0) {
|
||||||
prx = r.getPoint31XTile(j - 1);
|
prx = r.getPoint31XTile(j - 1);
|
||||||
pry = r.getPoint31YTile(j - 1);
|
pry = r.getPoint31YTile(j - 1);
|
||||||
} else if(projection >= mDist * mDist){
|
} else if (projection >= mDist * mDist) {
|
||||||
prx = r.getPoint31XTile(j);
|
prx = r.getPoint31XTile(j);
|
||||||
pry = r.getPoint31YTile(j);
|
pry = r.getPoint31YTile(j);
|
||||||
} else {
|
} else {
|
||||||
prx = (int) (r.getPoint31XTile(j - 1) + (r.getPoint31XTile(j) - r.getPoint31XTile(j - 1))* (projection / (mDist *mDist)));
|
prx = (int) (r.getPoint31XTile(j - 1) + (r.getPoint31XTile(j) - r.getPoint31XTile(j - 1))
|
||||||
pry = (int) (r.getPoint31YTile(j - 1) + (r.getPoint31YTile(j) - r.getPoint31YTile(j - 1)) * (projection / (mDist *mDist)));
|
* (projection / (mDist * mDist)));
|
||||||
|
pry = (int) (r.getPoint31YTile(j - 1) + (r.getPoint31YTile(j) - r.getPoint31YTile(j - 1))
|
||||||
|
* (projection / (mDist * mDist)));
|
||||||
}
|
}
|
||||||
double currentsDist = squareDist(prx, pry, px, py);
|
double currentsDist = squareDist(prx, pry, px, py);
|
||||||
if (road == null || currentsDist < sdist) {
|
if (road == null || currentsDist < sdist) {
|
||||||
|
@ -158,14 +116,14 @@ public class BinaryRoutePlanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(road != null) {
|
if (road != null) {
|
||||||
// re-register the best road because one more point was inserted
|
// re-register the best road because one more point was inserted
|
||||||
ctx.registerRouteDataObject(road.getRoad(), ctx.getRoutingTile(foundProjX, foundProjY));
|
ctx.registerRouteDataObject(foundProjX, foundProjY, road.getRoad());
|
||||||
}
|
}
|
||||||
return road;
|
return road;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, List<RouteSegment> intermediate, boolean leftSideNavigation) throws IOException {
|
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, List<RouteSegment> intermediate, boolean leftSideNavigation) throws IOException, InterruptedException {
|
||||||
if(intermediate != null && intermediate.size() > 0) {
|
if(intermediate != null && intermediate.size() > 0) {
|
||||||
ArrayList<RouteSegment> ps = new ArrayList<RouteSegment>(intermediate);
|
ArrayList<RouteSegment> ps = new ArrayList<RouteSegment>(intermediate);
|
||||||
ArrayList<RouteSegmentResult> firstPartRecalculatedRoute = null;
|
ArrayList<RouteSegmentResult> firstPartRecalculatedRoute = null;
|
||||||
|
@ -187,68 +145,74 @@ public class BinaryRoutePlanner {
|
||||||
ps.add(0, start);
|
ps.add(0, start);
|
||||||
List<RouteSegmentResult> results = new ArrayList<RouteSegmentResult>();
|
List<RouteSegmentResult> results = new ArrayList<RouteSegmentResult>();
|
||||||
for (int i = 0; i < ps.size() - 1; i++) {
|
for (int i = 0; i < ps.size() - 1; i++) {
|
||||||
RoutingContext local = new RoutingContext(ctx.config);
|
RoutingContext local = new RoutingContext(ctx);
|
||||||
local.copyLoadedDataAndClearCaches(ctx);
|
|
||||||
if(i == 0) {
|
if(i == 0) {
|
||||||
local.previouslyCalculatedRoute = firstPartRecalculatedRoute;
|
local.previouslyCalculatedRoute = firstPartRecalculatedRoute;
|
||||||
}
|
}
|
||||||
local.visitor = ctx.visitor;
|
local.visitor = ctx.visitor;
|
||||||
List<RouteSegmentResult> res = searchRouteInternal(local, ps.get(i), ps.get(i + 1), leftSideNavigation);
|
List<RouteSegmentResult> res = searchRouteInternalPrepare(local, ps.get(i), ps.get(i + 1), leftSideNavigation);
|
||||||
|
|
||||||
results.addAll(res);
|
results.addAll(res);
|
||||||
ctx.distinctLoadedTiles += local.distinctLoadedTiles;
|
ctx.distinctLoadedTiles += local.distinctLoadedTiles;
|
||||||
ctx.distinctUnloadedTiles.addAll(local.distinctUnloadedTiles);
|
|
||||||
ctx.loadedTiles += local.loadedTiles;
|
ctx.loadedTiles += local.loadedTiles;
|
||||||
ctx.visitedSegments += local.visitedSegments;
|
ctx.visitedSegments += local.visitedSegments;
|
||||||
ctx.loadedPrevUnloadedTiles += local.loadedPrevUnloadedTiles;
|
ctx.loadedPrevUnloadedTiles += local.loadedPrevUnloadedTiles;
|
||||||
ctx.timeToCalculate += local.timeToCalculate;
|
ctx.timeToCalculate += local.timeToCalculate;
|
||||||
ctx.timeToLoad += local.timeToLoad;
|
ctx.timeToLoad += local.timeToLoad;
|
||||||
|
ctx.timeToLoadHeaders += local.timeToLoadHeaders;
|
||||||
ctx.relaxedSegments += local.relaxedSegments;
|
ctx.relaxedSegments += local.relaxedSegments;
|
||||||
|
|
||||||
List<RoutingTile> toUnload = new ArrayList<RoutingContext.RoutingTile>();
|
local.unloadAllData(ctx);
|
||||||
for(RoutingTile t : local.tiles.valueCollection()){
|
|
||||||
if(!ctx.tiles.contains(t.getId())) {
|
|
||||||
toUnload.add(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(RoutingTile tl : toUnload) {
|
|
||||||
local.unloadTile(tl, false);
|
|
||||||
}
|
|
||||||
if(restPartRecalculatedRoute != null) {
|
if(restPartRecalculatedRoute != null) {
|
||||||
results.addAll(restPartRecalculatedRoute);
|
results.addAll(restPartRecalculatedRoute);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object[] vls = ctx.tiles.values();
|
ctx.unloadAllData();
|
||||||
for (Object tl : vls) {
|
|
||||||
if (((RoutingTile) tl).isLoaded()) {
|
|
||||||
ctx.unloadTile((RoutingTile) tl, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printResults(ctx, start, end, results);
|
printResults(ctx, start, end, results);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
return searchRoute(ctx, start, end, leftSideNavigation);
|
return searchRoute(ctx, start, end, leftSideNavigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException {
|
@SuppressWarnings("static-access")
|
||||||
List<RouteSegmentResult> result = searchRouteInternal(ctx, start, end, leftSideNavigation);
|
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
|
||||||
|
if(ctx.SHOW_GC_SIZE){
|
||||||
|
long h1 = ctx.runGCUsedMemory();
|
||||||
|
float mb = (1 << 20);
|
||||||
|
log.warn("Used before routing " + h1 / mb+ " actual");
|
||||||
|
}
|
||||||
|
List<RouteSegmentResult> result = searchRouteInternalPrepare(ctx, start, end, leftSideNavigation);
|
||||||
if(result != null) {
|
if(result != null) {
|
||||||
printResults(ctx, start, end, result);
|
printResults(ctx, start, end, result);
|
||||||
}
|
}
|
||||||
Object[] vls = ctx.tiles.values();
|
if (RoutingContext.SHOW_GC_SIZE) {
|
||||||
for(Object tl : vls) {
|
int sz = ctx.global.size;
|
||||||
ctx.unloadTile((RoutingTile) tl, false);
|
log.warn("Subregion size " + ctx.subregionTiles.size() + " " + " tiles " + ctx.indexedSubregions.size());
|
||||||
|
ctx.runGCUsedMemory();
|
||||||
|
long h1 = ctx.runGCUsedMemory();
|
||||||
|
ctx.unloadAllData();
|
||||||
|
ctx.runGCUsedMemory();
|
||||||
|
long h2 = ctx.runGCUsedMemory();
|
||||||
|
float mb = (1 << 20);
|
||||||
|
log.warn("Unload context : estimated " + sz / mb + " ?= " + (h1 - h2) / mb + " actual");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<RouteSegmentResult> searchRouteInternalPrepare(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
|
||||||
|
// Split into 2 methods to let GC work in between
|
||||||
|
searchRouteInternal(ctx, start, end, leftSideNavigation);
|
||||||
|
// 4. Route is found : collect all segments and prepare result
|
||||||
|
return prepareResult(ctx, start, end, leftSideNavigation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
||||||
* return list of segments
|
* return list of segments
|
||||||
*/
|
*/
|
||||||
public List<RouteSegmentResult> searchRouteInternal(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException {
|
private void searchRouteInternal(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
|
||||||
// measure time
|
// measure time
|
||||||
ctx.timeToLoad = 0;
|
ctx.timeToLoad = 0;
|
||||||
ctx.visitedSegments = 0;
|
ctx.visitedSegments = 0;
|
||||||
|
@ -378,66 +342,19 @@ public class BinaryRoutePlanner {
|
||||||
graphSegments = graphDirectSegments;
|
graphSegments = graphDirectSegments;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx.runTilesGC()) {
|
|
||||||
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
|
|
||||||
}
|
|
||||||
if(ctx.runRelaxingStrategy() ) {
|
if(ctx.runRelaxingStrategy() ) {
|
||||||
relaxNotNeededSegments(ctx, graphDirectSegments, true);
|
relaxNotNeededSegments(ctx, graphDirectSegments, true);
|
||||||
relaxNotNeededSegments(ctx, graphReverseSegments, false);
|
relaxNotNeededSegments(ctx, graphReverseSegments, false);
|
||||||
}
|
}
|
||||||
// check if interrupted
|
// check if interrupted
|
||||||
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
||||||
return new ArrayList<RouteSegmentResult>();
|
throw new InterruptedException("Route calculation interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println("Result is found");
|
println("Result is found");
|
||||||
printDebugMemoryInformation(ctx, graphDirectSegments, graphReverseSegments, visitedDirectSegments, visitedOppositeSegments);
|
printDebugMemoryInformation(ctx, graphDirectSegments, graphReverseSegments, visitedDirectSegments, visitedOppositeSegments);
|
||||||
|
|
||||||
// 4. Route is found : collect all segments and prepare result
|
|
||||||
List<RouteSegmentResult> resultPrepared = prepareResult(ctx, start, end, leftSideNavigation);
|
|
||||||
return resultPrepared;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unloadUnusedTiles(RoutingContext ctx, int desirableSize) {
|
|
||||||
// now delete all
|
|
||||||
List<RoutingTile> list = new ArrayList<RoutingContext.RoutingTile>();
|
|
||||||
TIntObjectIterator<RoutingTile> it = ctx.tiles.iterator();
|
|
||||||
int loaded = 0;
|
|
||||||
while(it.hasNext()) {
|
|
||||||
it.advance();
|
|
||||||
RoutingTile t = it.value();
|
|
||||||
if(t.isLoaded()) {
|
|
||||||
list.add(t);
|
|
||||||
loaded++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
ctx.maxLoadedTiles = Math.max(ctx.maxLoadedTiles, ctx.getCurrentlyLoadedTiles());
|
|
||||||
Collections.sort(list, new Comparator<RoutingTile>() {
|
|
||||||
private int pow(int base, int pw) {
|
|
||||||
int r = 1;
|
|
||||||
for (int i = 0; i < pw; i++) {
|
|
||||||
r *= base;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int compare(RoutingTile o1, RoutingTile o2) {
|
|
||||||
int v1 = (o1.access + 1) * pow(10, o1.getUnloadCont() -1);
|
|
||||||
int v2 = (o2.access + 1) * pow(10, o2.getUnloadCont() -1);
|
|
||||||
return v1 < v2 ? -1 : (v1 == v2 ? 0 : 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (loaded >= 0.9f * desirableSize) {
|
|
||||||
int toUnload = Math.max(loaded / 5, loaded - desirableSize);
|
|
||||||
for (int i = 0; i < loaded; i++) {
|
|
||||||
list.get(i).access = 0;
|
|
||||||
if (i < toUnload) {
|
|
||||||
ctx.unloadTile(list.get(i), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, boolean inverse) {
|
private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, boolean inverse) {
|
||||||
|
@ -498,34 +415,28 @@ public class BinaryRoutePlanner {
|
||||||
System.out.println(logMsg);
|
System.out.println(logMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void printInfo(String logMsg) {
|
||||||
|
log.warn(logMsg);
|
||||||
|
}
|
||||||
|
|
||||||
public void printDebugMemoryInformation(RoutingContext ctx, PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments,
|
public void printDebugMemoryInformation(RoutingContext ctx, PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments,
|
||||||
TLongObjectHashMap<RouteSegment> visitedDirectSegments,TLongObjectHashMap<RouteSegment> visitedOppositeSegments) {
|
TLongObjectHashMap<RouteSegment> visitedDirectSegments,TLongObjectHashMap<RouteSegment> visitedOppositeSegments) {
|
||||||
println("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6);
|
printInfo("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6 + ", time to load headers : " + ctx.timeToLoadHeaders / 1e6);
|
||||||
println("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + ctx.maxLoadedTiles);
|
int maxLoadedTiles = Math.max(ctx.maxLoadedTiles, ctx.getCurrentlyLoadedTiles());
|
||||||
println("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
|
printInfo("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + maxLoadedTiles);
|
||||||
" (distinct " + ctx.distinctUnloadedTiles.size()+") "+ ", loaded more than once same tiles "
|
printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
|
||||||
|
", loaded more than once same tiles "
|
||||||
+ ctx.loadedPrevUnloadedTiles );
|
+ ctx.loadedPrevUnloadedTiles );
|
||||||
println("Visited roads, " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments);
|
printInfo("Visited roads, " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments);
|
||||||
if (graphDirectSegments != null && graphReverseSegments != null) {
|
if (graphDirectSegments != null && graphReverseSegments != null) {
|
||||||
println("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
|
printInfo("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
|
||||||
}
|
}
|
||||||
if (visitedDirectSegments != null && visitedOppositeSegments != null) {
|
if (visitedDirectSegments != null && visitedOppositeSegments != null) {
|
||||||
println("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
|
printInfo("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoutingTile loadRoutes(final RoutingContext ctx, int tile31X, int tile31Y) {
|
|
||||||
final RoutingTile tile = ctx.getRoutingTile(tile31X, tile31Y);
|
|
||||||
if (tile.isLoaded()) {
|
|
||||||
tile.access++;
|
|
||||||
return tile;
|
|
||||||
}
|
|
||||||
ctx.loadTileData(tile, null, nativeLib, map);
|
|
||||||
return tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private boolean processRouteSegment(final RoutingContext ctx, boolean reverseWaySearch,
|
private boolean processRouteSegment(final RoutingContext ctx, boolean reverseWaySearch,
|
||||||
PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int targetEndX, int targetEndY,
|
PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int targetEndX, int targetEndY,
|
||||||
|
@ -620,7 +531,6 @@ public class BinaryRoutePlanner {
|
||||||
// 2. calculate point and try to load neighbor ways if they are not loaded
|
// 2. calculate point and try to load neighbor ways if they are not loaded
|
||||||
int x = road.getPoint31XTile(segmentEnd);
|
int x = road.getPoint31XTile(segmentEnd);
|
||||||
int y = road.getPoint31YTile(segmentEnd);
|
int y = road.getPoint31YTile(segmentEnd);
|
||||||
RoutingTile tile = loadRoutes(ctx, x, y);
|
|
||||||
if(positive) {
|
if(positive) {
|
||||||
posSegmentDist += squareRootDist(x, y,
|
posSegmentDist += squareRootDist(x, y,
|
||||||
road.getPoint31XTile(segmentEnd - 1), road.getPoint31YTile(segmentEnd - 1));
|
road.getPoint31XTile(segmentEnd - 1), road.getPoint31YTile(segmentEnd - 1));
|
||||||
|
@ -645,9 +555,14 @@ public class BinaryRoutePlanner {
|
||||||
}
|
}
|
||||||
obstacleMinusTime += obstacle;
|
obstacleMinusTime += obstacle;
|
||||||
}
|
}
|
||||||
|
// int overhead = 0;
|
||||||
long l = (((long) x) << 31) + (long) y;
|
// could be expensive calculation
|
||||||
RouteSegment next = tile.getSegment(l, ctx);
|
int overhead = (ctx.visitedSegments - ctx.relaxedSegments ) *
|
||||||
|
STANDARD_ROAD_IN_QUEUE_OVERHEAD;
|
||||||
|
if(overhead > ctx.config.memoryLimitation * 0.95){
|
||||||
|
throw new OutOfMemoryError("There is no enough memory " + ctx.config.memoryLimitation/(1<<20) + " Mb");
|
||||||
|
}
|
||||||
|
RouteSegment next = ctx.loadRouteSegment(x, y, ctx.config.memoryLimitation - overhead);
|
||||||
// 3. get intersected ways
|
// 3. get intersected ways
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
// TO-DO U-Turn
|
// TO-DO U-Turn
|
||||||
|
@ -886,8 +801,8 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
// calculate time
|
// calculate time
|
||||||
for (int i = 0; i < result.size(); i++) {
|
for (int i = 0; i < result.size(); i++) {
|
||||||
if(ctx.runTilesGC()) {
|
if(ctx.checkIfMemoryLimitCritical(ctx.config.memoryLimitation)) {
|
||||||
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
|
ctx.unloadUnusedTiles(ctx.config.memoryLimitation);
|
||||||
}
|
}
|
||||||
RouteSegmentResult rr = result.get(i);
|
RouteSegmentResult rr = result.get(i);
|
||||||
RouteDataObject road = rr.getObject();
|
RouteDataObject road = rr.getObject();
|
||||||
|
@ -1240,8 +1155,6 @@ public class BinaryRoutePlanner {
|
||||||
private void attachRoadSegments(RoutingContext ctx, List<RouteSegmentResult> result, int routeInd, int pointInd, boolean plus) {
|
private void attachRoadSegments(RoutingContext ctx, List<RouteSegmentResult> result, int routeInd, int pointInd, boolean plus) {
|
||||||
RouteSegmentResult rr = result.get(routeInd);
|
RouteSegmentResult rr = result.get(routeInd);
|
||||||
RouteDataObject road = rr.getObject();
|
RouteDataObject road = rr.getObject();
|
||||||
RoutingTile tl = loadRoutes(ctx, road.getPoint31XTile(pointInd), road.getPoint31YTile(pointInd));
|
|
||||||
long l = getPoint(road, pointInd);
|
|
||||||
long nextL = pointInd < road.getPointsLength() - 1 ? getPoint(road, pointInd + 1) : 0;
|
long nextL = pointInd < road.getPointsLength() - 1 ? getPoint(road, pointInd + 1) : 0;
|
||||||
long prevL = pointInd > 0 ? getPoint(road, pointInd - 1) : 0;
|
long prevL = pointInd > 0 ? getPoint(road, pointInd - 1) : 0;
|
||||||
|
|
||||||
|
@ -1264,7 +1177,7 @@ public class BinaryRoutePlanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RouteSegment routeSegment = tl.getSegment(l, ctx);
|
RouteSegment routeSegment = ctx.loadRouteSegment(road.getPoint31XTile(pointInd), road.getPoint31YTile(pointInd), ctx.config.memoryLimitation);
|
||||||
// try to attach all segments except with current id
|
// try to attach all segments except with current id
|
||||||
while (routeSegment != null) {
|
while (routeSegment != null) {
|
||||||
if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) {
|
if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) {
|
||||||
|
@ -1343,45 +1256,4 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class SegmentStat {
|
|
||||||
String name;
|
|
||||||
Set<Float> set = new TreeSet<Float>();
|
|
||||||
|
|
||||||
public SegmentStat(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addNumber(float v) {
|
|
||||||
set.add(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
int segmentation = 7;
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(name).append(" (").append(set.size()).append(") : ");
|
|
||||||
float s = set.size() / ((float) segmentation);
|
|
||||||
int k = 0, number = 0;
|
|
||||||
float limit = 0, value = 0;
|
|
||||||
Iterator<Float> it = set.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
k++;
|
|
||||||
number++;
|
|
||||||
value += it.next();
|
|
||||||
if (k >= limit) {
|
|
||||||
limit += s;
|
|
||||||
sb.append(value / number).append(" ");
|
|
||||||
number = 0;
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(number > 0) {
|
|
||||||
sb.append(value / number).append(" ");
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,12 @@ public class RoutingConfiguration {
|
||||||
// Influence on A* : f(x) + heuristicCoefficient*g(X)
|
// Influence on A* : f(x) + heuristicCoefficient*g(X)
|
||||||
public double heuristicCoefficient = 1;
|
public double heuristicCoefficient = 1;
|
||||||
|
|
||||||
|
public static final int DEFAULT_MEMORY_LIMIT = 30;
|
||||||
|
|
||||||
|
|
||||||
// 1.1 tile load parameters (should not affect routing)
|
// 1.1 tile load parameters (should not affect routing)
|
||||||
public int ZOOM_TO_LOAD_TILES = 13; // 12?, 14?
|
public int ZOOM_TO_LOAD_TILES = 16;
|
||||||
public int ITERATIONS_TO_RUN_GC = 100;
|
public int memoryLimitation;
|
||||||
public static int DEFAULT_DESIRABLE_TILES_IN_MEMORY = 30;
|
|
||||||
public int NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = DEFAULT_DESIRABLE_TILES_IN_MEMORY;
|
|
||||||
|
|
||||||
// 1.2 Dynamic road prioritizing (heuristic)
|
// 1.2 Dynamic road prioritizing (heuristic)
|
||||||
public boolean useDynamicRoadPrioritising = true;
|
public boolean useDynamicRoadPrioritising = true;
|
||||||
|
@ -53,10 +54,10 @@ public class RoutingConfiguration {
|
||||||
private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>();
|
private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>();
|
||||||
private Map<String, String> attributes = new LinkedHashMap<String, String>();
|
private Map<String, String> attributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
public RoutingConfiguration build(String router, String... specialization) {
|
public RoutingConfiguration build(String router, int memoryLimitMB, String... specialization) {
|
||||||
return build(router, null, specialization);
|
return build(router, null, memoryLimitMB, specialization);
|
||||||
}
|
}
|
||||||
public RoutingConfiguration build(String router, Double direction, String... specialization) {
|
public RoutingConfiguration build(String router, Double direction, int memoryLimitMB, String... specialization) {
|
||||||
if (!routers.containsKey(router)) {
|
if (!routers.containsKey(router)) {
|
||||||
router = defaultRouter;
|
router = defaultRouter;
|
||||||
}
|
}
|
||||||
|
@ -64,10 +65,15 @@ public class RoutingConfiguration {
|
||||||
i.initialDirection = direction;
|
i.initialDirection = direction;
|
||||||
i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
|
i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||||
i.ITERATIONS_TO_RUN_GC = parseSilentInt(getAttribute(router, "iterationsToRunGC"), i.ITERATIONS_TO_RUN_GC);
|
int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
|
||||||
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = parseSilentInt(getAttribute(router, "desirableTilesInMemory"),
|
if(desirable != 0) {
|
||||||
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
|
i.memoryLimitation = desirable * (1 << 20);
|
||||||
|
} else {
|
||||||
|
if(memoryLimitMB == 0) {
|
||||||
|
memoryLimitMB = DEFAULT_MEMORY_LIMIT;
|
||||||
|
}
|
||||||
|
i.memoryLimitation = memoryLimitMB * (1 << 20);
|
||||||
|
}
|
||||||
i.useDynamicRoadPrioritising = parseSilentBoolean(getAttribute(router, "useDynamicRoadPrioritising"), i.useDynamicRoadPrioritising);
|
i.useDynamicRoadPrioritising = parseSilentBoolean(getAttribute(router, "useDynamicRoadPrioritising"), i.useDynamicRoadPrioritising);
|
||||||
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
|
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
|
||||||
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);
|
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);
|
||||||
|
|
|
@ -1,37 +1,50 @@
|
||||||
package net.osmand.router;
|
package net.osmand.router;
|
||||||
|
|
||||||
|
import gnu.trove.iterator.TIntObjectIterator;
|
||||||
|
import gnu.trove.iterator.TLongIterator;
|
||||||
import gnu.trove.map.TLongObjectMap;
|
import gnu.trove.map.TLongObjectMap;
|
||||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
|
||||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
import gnu.trove.set.TLongSet;
|
|
||||||
import gnu.trove.set.hash.TIntHashSet;
|
|
||||||
import gnu.trove.set.hash.TLongHashSet;
|
import gnu.trove.set.hash.TLongHashSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import net.osmand.LogUtil;
|
||||||
import net.osmand.NativeLibrary;
|
import net.osmand.NativeLibrary;
|
||||||
import net.osmand.NativeLibrary.NativeRouteSearchResult;
|
import net.osmand.NativeLibrary.NativeRouteSearchResult;
|
||||||
import net.osmand.ResultMatcher;
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||||
|
import net.osmand.binary.BinaryMapRouteReaderAdapter;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
|
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
|
||||||
public class RoutingContext {
|
public class RoutingContext {
|
||||||
|
|
||||||
|
public static final boolean SHOW_GC_SIZE = false;
|
||||||
|
private final static Log log = LogUtil.getLog(RoutingContext.class);
|
||||||
|
public static final int OPTION_NO_LOAD = 0;
|
||||||
|
public static final int OPTION_SMART_LOAD = 1;
|
||||||
|
public static final int OPTION_IN_MEMORY_LOAD = 2;
|
||||||
|
// Final context variables
|
||||||
public final RoutingConfiguration config;
|
public final RoutingConfiguration config;
|
||||||
|
public final NativeLibrary nativeLib;
|
||||||
|
public final Map<BinaryMapIndexReader, List<RouteSubregion>> map = new LinkedHashMap<BinaryMapIndexReader, List<RouteSubregion>>();
|
||||||
|
public final Map<RouteRegion, BinaryMapIndexReader> reverseMap = new LinkedHashMap<RouteRegion, BinaryMapIndexReader>();
|
||||||
|
|
||||||
// 1. Initial variables
|
// 1. Initial variables
|
||||||
private int garbageCollectorIteration = 0;
|
|
||||||
private int relaxingIteration = 0;
|
private int relaxingIteration = 0;
|
||||||
public long firstRoadId = 0;
|
public long firstRoadId = 0;
|
||||||
public int firstRoadDirection = 0;
|
public int firstRoadDirection = 0;
|
||||||
|
@ -39,16 +52,18 @@ public class RoutingContext {
|
||||||
public Interruptable interruptable;
|
public Interruptable interruptable;
|
||||||
public List<RouteSegmentResult> previouslyCalculatedRoute;
|
public List<RouteSegmentResult> previouslyCalculatedRoute;
|
||||||
|
|
||||||
|
|
||||||
// 2. Routing memory cache (big objects)
|
// 2. Routing memory cache (big objects)
|
||||||
TIntObjectHashMap<RoutingTile> tiles = new TIntObjectHashMap<RoutingContext.RoutingTile>();
|
TLongObjectHashMap<List<RoutingSubregionTile>> indexedSubregions = new TLongObjectHashMap<List<RoutingSubregionTile>>();
|
||||||
|
TLongObjectHashMap<List<RouteDataObject>> tileRoutes = new TLongObjectHashMap<List<RouteDataObject>>();
|
||||||
|
|
||||||
|
// need to be array list and keep sorted Another option to use hashmap but it is more memory expensive
|
||||||
|
List<RoutingSubregionTile> subregionTiles = new ArrayList<RoutingSubregionTile>();
|
||||||
|
|
||||||
// 3. Warm object caches
|
// 3. Warm object caches
|
||||||
TLongSet nonRestrictedIds = new TLongHashSet();
|
|
||||||
ArrayList<RouteSegment> segmentsToVisitPrescripted = new ArrayList<BinaryRoutePlanner.RouteSegment>(5);
|
ArrayList<RouteSegment> segmentsToVisitPrescripted = new ArrayList<BinaryRoutePlanner.RouteSegment>(5);
|
||||||
ArrayList<RouteSegment> segmentsToVisitNotForbidden = new ArrayList<BinaryRoutePlanner.RouteSegment>(5);
|
ArrayList<RouteSegment> segmentsToVisitNotForbidden = new ArrayList<BinaryRoutePlanner.RouteSegment>(5);
|
||||||
|
|
||||||
|
|
||||||
// 4. Final results
|
// 4. Final results
|
||||||
RouteSegment finalDirectRoute = null;
|
RouteSegment finalDirectRoute = null;
|
||||||
int finalDirectEndSegment = 0;
|
int finalDirectEndSegment = 0;
|
||||||
|
@ -57,21 +72,61 @@ public class RoutingContext {
|
||||||
|
|
||||||
|
|
||||||
// 5. debug information (package accessor)
|
// 5. debug information (package accessor)
|
||||||
|
public TileStatistics global = new TileStatistics();
|
||||||
long timeToLoad = 0;
|
long timeToLoad = 0;
|
||||||
|
long timeToLoadHeaders = 0;
|
||||||
|
long timeToFindInitialSegments = 0;
|
||||||
long timeToCalculate = 0;
|
long timeToCalculate = 0;
|
||||||
public int loadedTiles = 0;
|
public int loadedTiles = 0;
|
||||||
int distinctLoadedTiles = 0;
|
int distinctLoadedTiles = 0;
|
||||||
int maxLoadedTiles = 0;
|
int maxLoadedTiles = 0;
|
||||||
int loadedPrevUnloadedTiles = 0;
|
int loadedPrevUnloadedTiles = 0;
|
||||||
int unloadedTiles = 0;
|
int unloadedTiles = 0;
|
||||||
TIntHashSet distinctUnloadedTiles = new TIntHashSet();
|
|
||||||
public int visitedSegments = 0;
|
public int visitedSegments = 0;
|
||||||
public int relaxedSegments = 0;
|
public int relaxedSegments = 0;
|
||||||
// callback of processing segments
|
// callback of processing segments
|
||||||
RouteSegmentVisitor visitor = null;
|
RouteSegmentVisitor visitor = null;
|
||||||
|
|
||||||
public RoutingContext(RoutingConfiguration config) {
|
|
||||||
|
|
||||||
|
public RoutingContext(RoutingContext cp) {
|
||||||
|
this.config = cp.config;
|
||||||
|
this.map.putAll(cp.map);
|
||||||
|
this.reverseMap.putAll(cp.reverseMap);
|
||||||
|
this.nativeLib = cp.nativeLib;
|
||||||
|
// copy local data and clear caches
|
||||||
|
for(RoutingSubregionTile tl : subregionTiles) {
|
||||||
|
if(tl.isLoaded()) {
|
||||||
|
subregionTiles.add(tl);
|
||||||
|
for (RouteSegment rs : tl.routes.valueCollection()) {
|
||||||
|
RouteSegment s = rs;
|
||||||
|
while (s != null) {
|
||||||
|
s.parentRoute = null;
|
||||||
|
s.parentSegmentEnd = 0;
|
||||||
|
s.distanceFromStart = 0;
|
||||||
|
s.distanceToEnd = 0;
|
||||||
|
s = s.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoutingContext(RoutingConfiguration config, NativeLibrary nativeLibrary, BinaryMapIndexReader[] map) {
|
||||||
|
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.reverseMap.put(r, mr);
|
||||||
|
}
|
||||||
|
this.map.put(mr, subregions);
|
||||||
|
}
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
// this.nativeLib = null;
|
||||||
|
this.nativeLib = nativeLibrary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,24 +136,16 @@ public class RoutingContext {
|
||||||
|
|
||||||
public int getCurrentlyLoadedTiles() {
|
public int getCurrentlyLoadedTiles() {
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
Iterator<RoutingTile> it = tiles.valueCollection().iterator();
|
for(RoutingSubregionTile t : this.subregionTiles){
|
||||||
while (it.hasNext()) {
|
if(t.isLoaded()) {
|
||||||
if (it.next().isLoaded()) {
|
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runTilesGC() {
|
public int getCurrentEstimatedSize(){
|
||||||
garbageCollectorIteration++;
|
return global.size;
|
||||||
int loadedTilesCritical = config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY * 3 /2;
|
|
||||||
if (garbageCollectorIteration > config.ITERATIONS_TO_RUN_GC ||
|
|
||||||
getCurrentlyLoadedTiles() > loadedTilesCritical) {
|
|
||||||
garbageCollectorIteration = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runRelaxingStrategy(){
|
public boolean runRelaxingStrategy(){
|
||||||
|
@ -113,7 +160,6 @@ public class RoutingContext {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setVisitor(RouteSegmentVisitor visitor) {
|
public void setVisitor(RouteSegmentVisitor visitor) {
|
||||||
this.visitor = visitor;
|
this.visitor = visitor;
|
||||||
}
|
}
|
||||||
|
@ -138,8 +184,6 @@ public class RoutingContext {
|
||||||
config.useDynamicRoadPrioritising = useDynamicRoadPrioritising;
|
config.useDynamicRoadPrioritising = useDynamicRoadPrioritising;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void setRouter(VehicleRouter router) {
|
public void setRouter(VehicleRouter router) {
|
||||||
config.router = router;
|
config.router = router;
|
||||||
}
|
}
|
||||||
|
@ -169,309 +213,426 @@ public class RoutingContext {
|
||||||
config.heuristicCoefficient);
|
config.heuristicCoefficient);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoutingTile getRoutingTile(int x31, int y31){
|
public void registerRouteDataObject(int x31, int y31, RouteDataObject o ) {
|
||||||
int xloc = x31 >> (31 - config.ZOOM_TO_LOAD_TILES);
|
|
||||||
int yloc = y31 >> (31 - config.ZOOM_TO_LOAD_TILES);
|
|
||||||
int l = (xloc << config.ZOOM_TO_LOAD_TILES) + yloc;
|
|
||||||
RoutingTile tl = tiles.get(l);
|
|
||||||
if(tl == null) {
|
|
||||||
tl = new RoutingTile(xloc, yloc, config.ZOOM_TO_LOAD_TILES);
|
|
||||||
tiles.put(l, tl);
|
|
||||||
}
|
|
||||||
return tiles.get(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unloadTile(RoutingTile tile, boolean createEmpty){
|
|
||||||
int l = (tile.tileX << config.ZOOM_TO_LOAD_TILES) + tile.tileY;
|
|
||||||
RoutingTile old = tiles.remove(l);
|
|
||||||
RoutingTile n = new RoutingTile(tile.tileX, tile.tileY, config.ZOOM_TO_LOAD_TILES);
|
|
||||||
n.isLoaded = old.isLoaded;
|
|
||||||
n.setUnloaded();
|
|
||||||
tiles.put(l, n);
|
|
||||||
unloadedTiles++;
|
|
||||||
distinctUnloadedTiles.add(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void loadTileData(final RoutingTile tile, final List<RouteDataObject> toFillIn, NativeLibrary nativeLib,
|
|
||||||
Map<BinaryMapIndexReader, List<RouteSubregion>> map) {
|
|
||||||
|
|
||||||
long now = System.nanoTime();
|
|
||||||
final int zoomToLoad = 31 - tile.getZoom();
|
|
||||||
final int tileX = tile.getTileX();
|
|
||||||
final int tileY = tile.getTileY();
|
|
||||||
ResultMatcher<RouteDataObject> matcher = new ResultMatcher<RouteDataObject>() {
|
|
||||||
int intersectionObjects = 0, all = 0, allout = 0;
|
|
||||||
@Override
|
|
||||||
public boolean publish(RouteDataObject o) {
|
|
||||||
if(o.getPointsLength() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
all++;
|
|
||||||
boolean out = false;
|
|
||||||
int minx, maxx, miny, maxy;
|
|
||||||
minx = maxx = o.getPoint31XTile(0);
|
|
||||||
miny = maxy = o.getPoint31YTile(0);
|
|
||||||
for (int ti = 0; ti < o.getPointsLength(); ti++) {
|
|
||||||
minx = Math.min(o.getPoint31XTile(ti), minx);
|
|
||||||
maxx = Math.max(o.getPoint31XTile(ti), maxx);
|
|
||||||
miny = Math.min(o.getPoint31YTile(ti), miny);
|
|
||||||
maxy = Math.max(o.getPoint31YTile(ti), maxy);
|
|
||||||
if(!tile.checkContains(o.getPoint31XTile(ti), o.getPoint31YTile(ti))) {
|
|
||||||
out = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
minx = minx >> zoomToLoad;
|
|
||||||
maxx = maxx >> zoomToLoad;
|
|
||||||
miny = miny >> zoomToLoad;
|
|
||||||
maxy = maxy >> zoomToLoad;
|
|
||||||
if(minx > tileX || maxx < tileX || miny > tileY || maxy < tileY) {
|
|
||||||
allout++;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(out) {
|
|
||||||
intersectionObjects++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toFillIn != null) {
|
|
||||||
if (getRouter().acceptLine(o)) {
|
|
||||||
toFillIn.add(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
registerRouteDataObject(o, tile);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Tile " + tileX + "/"+ tileY + " boundaries " + intersectionObjects + " of " + all + " out " + allout;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCancelled() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
boolean loadData = toFillIn != null;
|
|
||||||
List<NativeRouteSearchResult> nativeRouteSearchResults = new ArrayList<NativeRouteSearchResult>();
|
|
||||||
SearchRequest<RouteDataObject> request = BinaryMapIndexReader.buildSearchRouteRequest(tileX << zoomToLoad,
|
|
||||||
(tileX + 1) << zoomToLoad, tileY << zoomToLoad, (tileY + 1) << zoomToLoad, matcher);
|
|
||||||
for (Entry<BinaryMapIndexReader, List<RouteSubregion>> r : map.entrySet()) {
|
|
||||||
if(nativeLib != null) {
|
|
||||||
try {
|
|
||||||
r.getKey().initRouteRegionsIfNeeded(request);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Loading data exception", e);
|
|
||||||
}
|
|
||||||
for(RouteRegion reg : r.getKey().getRoutingIndexes()) {
|
|
||||||
NativeRouteSearchResult rs = nativeLoadRegion(request, reg, nativeLib, loadData);
|
|
||||||
if(rs != null) {
|
|
||||||
if(!loadData){
|
|
||||||
if (rs.nativeHandler != 0) {
|
|
||||||
nativeRouteSearchResults.add(rs);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(rs.objects != null){
|
|
||||||
for(RouteDataObject ro : rs.objects) {
|
|
||||||
if(ro != null) {
|
|
||||||
request.publish(ro);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
r.getKey().searchRouteIndex(request, r.getValue());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Loading data exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadedTiles++;
|
|
||||||
if (tile.isUnloaded()) {
|
|
||||||
loadedPrevUnloadedTiles++;
|
|
||||||
} else {
|
|
||||||
distinctLoadedTiles++;
|
|
||||||
}
|
|
||||||
tile.setLoaded();
|
|
||||||
if(nativeRouteSearchResults.size() > 0) {
|
|
||||||
tile.nativeLib = nativeLib;
|
|
||||||
tile.nativeResults = nativeRouteSearchResults;
|
|
||||||
|
|
||||||
}
|
|
||||||
timeToLoad += (System.nanoTime() - now);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private NativeRouteSearchResult nativeLoadRegion(SearchRequest<RouteDataObject> request, RouteRegion reg, NativeLibrary nativeLib, boolean loadData) {
|
|
||||||
boolean intersects = false;
|
|
||||||
for(RouteSubregion sub : reg.getSubregions()) {
|
|
||||||
if(request.intersects(sub.left, sub.top, sub.right, sub.bottom)) {
|
|
||||||
intersects = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(intersects) {
|
|
||||||
return nativeLib.loadRouteRegion(reg, request.getLeft(), request.getRight(), request.getTop(), request.getBottom(), loadData);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*private */void registerRouteDataObject(RouteDataObject o, RoutingTile suggestedTile ) {
|
|
||||||
if(!getRouter().acceptLine(o)){
|
if(!getRouter().acceptLine(o)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RoutingTile tl = suggestedTile;
|
long tileId = getRoutingTile(x31, y31, 0, OPTION_NO_LOAD);
|
||||||
RouteDataObject old = tl.idObjects.get(o.id);
|
List<RouteDataObject> routes = tileRoutes.get(tileId);
|
||||||
// sometimes way is present only partially in one index
|
if(routes == null){
|
||||||
if (old != null && old.getPointsLength() >= o.getPointsLength()) {
|
routes = new ArrayList<RouteDataObject>();
|
||||||
return;
|
tileRoutes.put(tileId, routes);
|
||||||
};
|
|
||||||
for (int j = 0; j < o.getPointsLength(); j++) {
|
|
||||||
int x = o.getPoint31XTile(j);
|
|
||||||
int y = o.getPoint31YTile(j);
|
|
||||||
if(!tl.checkContains(x, y)){
|
|
||||||
// don't register in different tiles
|
|
||||||
// in order to throw out tile object easily
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long l = (((long) x) << 31) + (long) y;
|
|
||||||
RouteSegment segment = new RouteSegment(o , j);
|
|
||||||
RouteSegment prev = tl.getSegment(l, this);
|
|
||||||
boolean i = true;
|
|
||||||
if (prev != null) {
|
|
||||||
if (old == null) {
|
|
||||||
segment.next = prev;
|
|
||||||
} else if (prev.road == old) {
|
|
||||||
segment.next = prev.next;
|
|
||||||
} else {
|
|
||||||
// segment somewhere in the middle replace element in linked list
|
|
||||||
RouteSegment rr = prev;
|
|
||||||
while (rr != null) {
|
|
||||||
if (rr.road == old) {
|
|
||||||
prev.next = segment;
|
|
||||||
segment.next = rr.next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prev = rr;
|
|
||||||
rr = rr.next;
|
|
||||||
}
|
|
||||||
i = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i) {
|
|
||||||
tl.routes.put(l, segment);
|
|
||||||
tl.idObjects.put(o.id, o);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
routes.add(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyLoadedDataAndClearCaches(RoutingContext ctx) {
|
public void unloadAllData() {
|
||||||
for(RoutingTile tl : ctx.tiles.valueCollection()) {
|
unloadAllData(null);
|
||||||
if(tl.isLoaded()) {
|
|
||||||
this.tiles.put(tl.getId(), tl);
|
|
||||||
for(RouteSegment rs : tl.routes.valueCollection()) {
|
|
||||||
RouteSegment s = rs;
|
|
||||||
while(s != null) {
|
|
||||||
s.parentRoute = null;
|
|
||||||
s.parentSegmentEnd = 0;
|
|
||||||
s.distanceFromStart = 0;
|
|
||||||
s.distanceToEnd = 0;
|
|
||||||
s = s.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RoutingTile {
|
public void unloadAllData(RoutingContext except) {
|
||||||
private int tileX;
|
for (RoutingSubregionTile tl : subregionTiles) {
|
||||||
private int tileY;
|
if (tl.isLoaded()) {
|
||||||
private int zoom;
|
if(except == null || except.searchSubregionTile(tl.subregion) < 0){
|
||||||
private int isLoaded;
|
tl.unload();
|
||||||
// make it without get/set for fast access
|
unloadedTiles ++;
|
||||||
public int access;
|
global.size -= tl.tileStatistics.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subregionTiles.clear();
|
||||||
|
tileRoutes.clear();
|
||||||
|
indexedSubregions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private NativeLibrary nativeLib;
|
private int searchSubregionTile(RouteSubregion subregion){
|
||||||
// null if it doesn't work with native results
|
RoutingSubregionTile key = new RoutingSubregionTile(subregion);
|
||||||
private List<NativeRouteSearchResult> nativeResults;
|
long now = System.nanoTime();
|
||||||
private TLongHashSet excludeDuplications = new TLongHashSet();
|
int ind = Collections.binarySearch(subregionTiles, key, new Comparator<RoutingSubregionTile>() {
|
||||||
|
@Override
|
||||||
|
public int compare(RoutingSubregionTile o1, RoutingSubregionTile o2) {
|
||||||
|
if(o1.subregion.left == o2.subregion.left) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return o1.subregion.left < o2.subregion.left ? 1 : -1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (ind >= 0) {
|
||||||
|
for (int i = ind; i <= subregionTiles.size(); i++) {
|
||||||
|
if (i == subregionTiles.size() || subregionTiles.get(i).subregion.left > subregion.left) {
|
||||||
|
ind = -i - 1;
|
||||||
|
return ind;
|
||||||
|
}
|
||||||
|
if (subregionTiles.get(i).subregion == subregion) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeToLoadHeaders += (System.nanoTime() - now);
|
||||||
|
return ind;
|
||||||
|
}
|
||||||
|
|
||||||
private TLongObjectMap<RouteSegment> routes = new TLongObjectHashMap<RouteSegment>();
|
|
||||||
private TLongObjectHashMap<RouteDataObject> idObjects = new TLongObjectHashMap<RouteDataObject>();
|
|
||||||
|
|
||||||
public RouteSegment getSegment(long id, RoutingContext ctx) {
|
|
||||||
if(nativeResults != null) {
|
public RouteSegment loadRouteSegment(int x31, int y31, int memoryLimit) {
|
||||||
RouteSegment original = loadNativeRouteSegment(id, ctx);
|
long tileId = getRoutingTile(x31, y31, memoryLimit, OPTION_SMART_LOAD);
|
||||||
|
TLongObjectHashMap<RouteDataObject> excludeDuplications = new TLongObjectHashMap<RouteDataObject>();
|
||||||
|
RouteSegment original = null;
|
||||||
|
if (tileRoutes.containsKey(tileId)) {
|
||||||
|
List<RouteDataObject> routes = tileRoutes.get(tileId);
|
||||||
|
if (routes != null) {
|
||||||
|
for (RouteDataObject ro : routes) {
|
||||||
|
for (int i = 0; i < ro.pointsX.length; i++) {
|
||||||
|
if (ro.getPoint31XTile(i) == x31 && ro.getPoint31YTile(i) == y31) {
|
||||||
|
excludeDuplications.put(ro.id, ro);
|
||||||
|
RouteSegment segment = new RouteSegment(ro, i);
|
||||||
|
segment.next = original;
|
||||||
|
original = segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<RoutingSubregionTile> subregions = indexedSubregions.get(tileId);
|
||||||
|
if (subregions != null) {
|
||||||
|
for (RoutingSubregionTile rs : subregions) {
|
||||||
|
original = rs.loadRouteSegment(x31, y31, this, excludeDuplications, original);
|
||||||
|
}
|
||||||
|
}
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
return routes.get(id);
|
|
||||||
|
private void loadSubregionTile(final RoutingSubregionTile ts, boolean loadObjectsInMemory) {
|
||||||
|
boolean wasUnloaded = ts.isUnloaded();
|
||||||
|
int ucount = ts.getUnloadCont();
|
||||||
|
if (nativeLib == null) {
|
||||||
|
long now = System.nanoTime();
|
||||||
|
try {
|
||||||
|
BinaryMapIndexReader reader = reverseMap.get(ts.subregion.routeReg);
|
||||||
|
ts.setLoadedNonNative();
|
||||||
|
List<RouteDataObject> res = reader.loadRouteIndexData(ts.subregion);
|
||||||
|
// System.out.println(ts.subregion.shiftToData + " " + res);
|
||||||
|
for(RouteDataObject ro : res){
|
||||||
|
if(ro != null && config.router.acceptLine(ro)) {
|
||||||
|
ts.add(ro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Loading data exception", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RouteSegment loadNativeRouteSegment(long id, RoutingContext ctx) {
|
timeToLoad += (System.nanoTime() - now);
|
||||||
int y31 = (int) (id & Integer.MAX_VALUE);
|
} else {
|
||||||
int x31 = (int) (id >> 31);
|
long now = System.nanoTime();
|
||||||
excludeDuplications.clear();
|
NativeRouteSearchResult ns = nativeLib.loadRouteRegion(ts.subregion, loadObjectsInMemory);
|
||||||
RouteSegment original = null;
|
// System.out.println(ts.subregion.shiftToData + " " + Arrays.toString(ns.objects));
|
||||||
RouteSegment prev = null;
|
ts.setLoadedNative(ns, this);
|
||||||
for (NativeRouteSearchResult rs : nativeResults) {
|
timeToLoad += (System.nanoTime() - now);
|
||||||
RouteDataObject[] res = nativeLib.getDataObjects(rs, x31, y31);
|
}
|
||||||
|
loadedTiles++;
|
||||||
|
if (wasUnloaded) {
|
||||||
|
if(ucount == 1) {
|
||||||
|
loadedPrevUnloadedTiles++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(global != null) {
|
||||||
|
global.allRoutes += ts.tileStatistics.allRoutes;
|
||||||
|
global.coordinates += ts.tileStatistics.coordinates;
|
||||||
|
}
|
||||||
|
distinctLoadedTiles++;
|
||||||
|
}
|
||||||
|
global.size += ts.tileStatistics.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<RoutingSubregionTile> loadTileHeaders(final int x31, final int y31) {
|
||||||
|
final int zoomToLoad = 31 - config.ZOOM_TO_LOAD_TILES;
|
||||||
|
int tileX = x31 >> zoomToLoad;
|
||||||
|
int tileY = y31 >> zoomToLoad;
|
||||||
|
|
||||||
|
SearchRequest<RouteDataObject> request = BinaryMapIndexReader.buildSearchRouteRequest(tileX << zoomToLoad,
|
||||||
|
(tileX + 1) << zoomToLoad, tileY << zoomToLoad, (tileY + 1) << zoomToLoad, null);
|
||||||
|
List<RoutingSubregionTile> collection = null;
|
||||||
|
for (Entry<BinaryMapIndexReader, List<RouteSubregion>> r : map.entrySet()) {
|
||||||
|
// load headers same as we do in non-native
|
||||||
|
// if(nativeLib == null) {
|
||||||
|
try {
|
||||||
|
if (r.getValue().size() > 0) {
|
||||||
|
long now = System.nanoTime();
|
||||||
|
// int rg = r.getValue().get(0).routeReg.regionsRead;
|
||||||
|
List<RouteSubregion> subregs = r.getKey().searchRouteIndexTree(request, r.getValue());
|
||||||
|
for (RouteSubregion sr : subregs) {
|
||||||
|
int ind = searchSubregionTile(sr);
|
||||||
|
RoutingSubregionTile found;
|
||||||
|
if (ind < 0) {
|
||||||
|
found = new RoutingSubregionTile(sr);
|
||||||
|
subregionTiles.add(-(ind + 1), found);
|
||||||
|
} else {
|
||||||
|
found = subregionTiles.get(ind);
|
||||||
|
}
|
||||||
|
if(collection == null) {
|
||||||
|
collection = new ArrayList<RoutingContext.RoutingSubregionTile>(4);
|
||||||
|
}
|
||||||
|
collection.add(found);
|
||||||
|
}
|
||||||
|
timeToLoadHeaders += (System.nanoTime() - now);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Loading data exception", e);
|
||||||
|
}
|
||||||
|
// } else {
|
||||||
|
// throw new UnsupportedOperationException();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadTileData(int x31, int y31, int zoomAround, final List<RouteDataObject> toFillIn) {
|
||||||
|
int coordinatesShift = (1 << (31 - zoomAround));
|
||||||
|
TLongHashSet ts = new TLongHashSet();
|
||||||
|
long now = System.nanoTime();
|
||||||
|
ts.add(getRoutingTile(x31 - coordinatesShift, y31 - coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
|
||||||
|
ts.add(getRoutingTile(x31 + coordinatesShift, y31 - coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
|
||||||
|
ts.add(getRoutingTile(x31 - coordinatesShift, y31 + coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
|
||||||
|
ts.add(getRoutingTile(x31 + coordinatesShift, y31 + coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
|
||||||
|
TLongIterator it = ts.iterator();
|
||||||
|
while(it.hasNext()){
|
||||||
|
getAllObjects(it.next(), toFillIn);
|
||||||
|
}
|
||||||
|
timeToFindInitialSegments += (System.nanoTime() - now);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private long getRoutingTile(int x31, int y31, int memoryLimit, int loadOptions){
|
||||||
|
// long now = System.nanoTime();
|
||||||
|
long xloc = x31 >> (31 - config.ZOOM_TO_LOAD_TILES);
|
||||||
|
long yloc = y31 >> (31 - config.ZOOM_TO_LOAD_TILES);
|
||||||
|
long tileId = (xloc << config.ZOOM_TO_LOAD_TILES) + yloc;
|
||||||
|
if (loadOptions != OPTION_NO_LOAD) {
|
||||||
|
if( memoryLimit == 0){
|
||||||
|
memoryLimit = config.memoryLimitation;
|
||||||
|
}
|
||||||
|
if (getCurrentEstimatedSize() > 0.9 * memoryLimit) {
|
||||||
|
int sz1 = getCurrentEstimatedSize();
|
||||||
|
long h1 = 0;
|
||||||
|
if (SHOW_GC_SIZE && sz1 > 0.7 * memoryLimit) {
|
||||||
|
runGCUsedMemory();
|
||||||
|
h1 = runGCUsedMemory();
|
||||||
|
}
|
||||||
|
int clt = getCurrentlyLoadedTiles();
|
||||||
|
long us1 = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
|
||||||
|
unloadUnusedTiles(memoryLimit);
|
||||||
|
if (h1 != 0 && getCurrentlyLoadedTiles() != clt) {
|
||||||
|
int sz2 = getCurrentEstimatedSize();
|
||||||
|
runGCUsedMemory();
|
||||||
|
long h2 = runGCUsedMemory();
|
||||||
|
float mb = (1 << 20);
|
||||||
|
log.warn("Unload tiles : estimated " + (sz1 - sz2) / mb + " ?= " + (h1 - h2) / mb + " actual");
|
||||||
|
log.warn("Used after " + h2 / mb + " of " + Runtime.getRuntime().totalMemory() / mb + " max "
|
||||||
|
+ Runtime.getRuntime().maxMemory() / mb);
|
||||||
|
} else {
|
||||||
|
float mb = (1 << 20);
|
||||||
|
int sz2 = getCurrentEstimatedSize();
|
||||||
|
log.warn("Unload tiles : occupied before " + sz1 / mb + " Mb - now " + sz2 / mb + "MB " +
|
||||||
|
memoryLimit/mb + " limit MB " + config.memoryLimitation/mb);
|
||||||
|
long us2 = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
|
||||||
|
log.warn("Used memory before " + us1 / mb + "after " + us1 / mb + " of max " + Runtime.getRuntime().maxMemory() / mb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!indexedSubregions.containsKey(tileId)) {
|
||||||
|
List<RoutingSubregionTile> collection = loadTileHeaders(x31, y31);
|
||||||
|
indexedSubregions.put(tileId, collection);
|
||||||
|
}
|
||||||
|
List<RoutingSubregionTile> subregions = indexedSubregions.get(tileId);
|
||||||
|
if (subregions != null) {
|
||||||
|
for (RoutingSubregionTile ts : subregions) {
|
||||||
|
if (!ts.isLoaded()) {
|
||||||
|
loadSubregionTile(ts, loadOptions == OPTION_IN_MEMORY_LOAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// timeToLoad += (System.nanoTime() - now);
|
||||||
|
return tileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public boolean checkIfMemoryLimitCritical(int memoryLimit) {
|
||||||
|
return getCurrentEstimatedSize() > 0.9 * memoryLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unloadUnusedTiles(int memoryLimit) {
|
||||||
|
float desirableSize = memoryLimit * 0.7f;
|
||||||
|
List<RoutingSubregionTile> list = new ArrayList<RoutingSubregionTile>(subregionTiles.size() / 2);
|
||||||
|
int loaded = 0;
|
||||||
|
for(RoutingSubregionTile t : subregionTiles) {
|
||||||
|
if(t.isLoaded()) {
|
||||||
|
list.add(t);
|
||||||
|
loaded++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maxLoadedTiles = Math.max(maxLoadedTiles, getCurrentlyLoadedTiles());
|
||||||
|
Collections.sort(list, new Comparator<RoutingSubregionTile>() {
|
||||||
|
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(RoutingSubregionTile o1, RoutingSubregionTile 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
int i = 0;
|
||||||
|
while(getCurrentEstimatedSize() >= desirableSize && (list.size() - i) > loaded / 5 && i < list.size()) {
|
||||||
|
RoutingSubregionTile unload = list.get(i);
|
||||||
|
i++;
|
||||||
|
// System.out.println("Unload " + unload);
|
||||||
|
unload.unload();
|
||||||
|
unloadedTiles ++;
|
||||||
|
global.size -= unload.tileStatistics.size;
|
||||||
|
// tile could be cleaned from routing tiles and deleted from whole list
|
||||||
|
|
||||||
|
}
|
||||||
|
for(RoutingSubregionTile t : subregionTiles) {
|
||||||
|
t.access /= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getAllObjects(long tileId, final List<RouteDataObject> toFillIn) {
|
||||||
|
TLongObjectHashMap<RouteDataObject> excludeDuplications = new TLongObjectHashMap<RouteDataObject>();
|
||||||
|
if (tileRoutes.containsKey(tileId)) {
|
||||||
|
List<RouteDataObject> routes = tileRoutes.get(tileId);
|
||||||
|
if (routes != null) {
|
||||||
|
for (RouteDataObject ro : routes) {
|
||||||
|
if (!excludeDuplications.contains(ro.id)) {
|
||||||
|
excludeDuplications.put(ro.id, ro);
|
||||||
|
toFillIn.add(ro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<RoutingSubregionTile> subregions = indexedSubregions.get(tileId);
|
||||||
|
if (subregions != null) {
|
||||||
|
for (RoutingSubregionTile rs : subregions) {
|
||||||
|
rs.loadAllObjects(toFillIn, this, excludeDuplications);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected static long runGCUsedMemory() {
|
||||||
|
Runtime runtime = Runtime.getRuntime();
|
||||||
|
long usedMem1 = runtime.totalMemory() - runtime.freeMemory();
|
||||||
|
long usedMem2 = Long.MAX_VALUE;
|
||||||
|
int cnt = 4;
|
||||||
|
while (cnt-- >= 0) {
|
||||||
|
for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++i) {
|
||||||
|
runtime.runFinalization();
|
||||||
|
runtime.gc();
|
||||||
|
Thread.yield();
|
||||||
|
|
||||||
|
usedMem2 = usedMem1;
|
||||||
|
usedMem1 = runtime.totalMemory() - runtime.freeMemory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return usedMem1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static class RoutingSubregionTile {
|
||||||
|
public final RouteSubregion subregion;
|
||||||
|
// make it without get/set for fast access
|
||||||
|
public int access;
|
||||||
|
public TileStatistics tileStatistics = new TileStatistics();
|
||||||
|
|
||||||
|
private NativeRouteSearchResult searchResult = null;
|
||||||
|
private int isLoaded = 0;
|
||||||
|
private TLongObjectMap<RouteSegment> routes = null;
|
||||||
|
|
||||||
|
public RoutingSubregionTile(RouteSubregion subregion) {
|
||||||
|
this.subregion = subregion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAllObjects(final List<RouteDataObject> toFillIn, RoutingContext ctx, TLongObjectHashMap<RouteDataObject> excludeDuplications) {
|
||||||
|
if(routes != null) {
|
||||||
|
Iterator<RouteSegment> it = routes.valueCollection().iterator();
|
||||||
|
while(it.hasNext()){
|
||||||
|
RouteSegment rs = it.next();
|
||||||
|
while(rs != null){
|
||||||
|
RouteDataObject ro = rs.road;
|
||||||
|
if (!excludeDuplications.contains(ro.id)) {
|
||||||
|
excludeDuplications.put(ro.id, ro);
|
||||||
|
toFillIn.add(ro);
|
||||||
|
}
|
||||||
|
rs = rs.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(searchResult != null) {
|
||||||
|
RouteDataObject[] objects = searchResult.objects;
|
||||||
|
if(objects != null) {
|
||||||
|
for(RouteDataObject ro : objects) {
|
||||||
|
if (ro != null && !excludeDuplications.contains(ro.id)) {
|
||||||
|
excludeDuplications.put(ro.id, ro);
|
||||||
|
toFillIn.add(ro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RouteSegment loadRouteSegment(int x31, int y31, RoutingContext ctx,
|
||||||
|
TLongObjectHashMap<RouteDataObject> excludeDuplications, RouteSegment original) {
|
||||||
|
if(searchResult == null && routes == null) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
access++;
|
||||||
|
if (searchResult == null) {
|
||||||
|
long l = (((long) x31) << 31) + (long) y31;
|
||||||
|
RouteSegment segment = routes.get(l);
|
||||||
|
while (segment != null) {
|
||||||
|
RouteDataObject ro = segment.road;
|
||||||
|
RouteDataObject toCmp = excludeDuplications.get(ro.id);
|
||||||
|
if (toCmp == null || toCmp.getPointsLength() < ro.getPointsLength()) {
|
||||||
|
excludeDuplications.put(ro.id, ro);
|
||||||
|
RouteSegment s = new RouteSegment(ro, segment.getSegmentStart());
|
||||||
|
s.next = original;
|
||||||
|
original = s;
|
||||||
|
}
|
||||||
|
segment = segment.next;
|
||||||
|
}
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
// Native use case
|
||||||
|
RouteDataObject[] res = ctx.nativeLib.getDataObjects(searchResult, x31, y31);
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
for (RouteDataObject ro : res) {
|
for (RouteDataObject ro : res) {
|
||||||
boolean accept = ro != null && !excludeDuplications.contains(ro.id);
|
RouteDataObject toCmp = excludeDuplications.get(ro.id);
|
||||||
if(ctx != null && accept) {
|
boolean accept = ro != null && (toCmp == null || toCmp.getPointsLength() < ro.getPointsLength());
|
||||||
|
if (ctx != null && accept) {
|
||||||
accept = ctx.getRouter().acceptLine(ro);
|
accept = ctx.getRouter().acceptLine(ro);
|
||||||
}
|
}
|
||||||
if (accept) {
|
if (accept) {
|
||||||
excludeDuplications.add(ro.id);
|
excludeDuplications.put(ro.id, ro);
|
||||||
for (int i = 0; i < ro.pointsX.length; i++) {
|
for (int i = 0; i < ro.pointsX.length; i++) {
|
||||||
if (ro.getPoint31XTile(i) == x31 && ro.getPoint31YTile(i) == y31) {
|
if (ro.getPoint31XTile(i) == x31 && ro.getPoint31YTile(i) == y31) {
|
||||||
RouteSegment segment = new RouteSegment(ro, i);
|
RouteSegment segment = new RouteSegment(ro, i);
|
||||||
if (prev != null) {
|
segment.next = original;
|
||||||
prev.next = segment;
|
|
||||||
prev = segment;
|
|
||||||
} else {
|
|
||||||
original = segment;
|
original = segment;
|
||||||
prev = segment;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoutingTile(int tileX, int tileY, int zoom) {
|
|
||||||
this.tileX = tileX;
|
|
||||||
this.tileY = tileY;
|
|
||||||
this.zoom = zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(){
|
|
||||||
return (tileX << zoom) + tileY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getZoom() {
|
|
||||||
return zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTileX() {
|
|
||||||
return tileX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTileY() {
|
|
||||||
return tileY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
return isLoaded > 0;
|
return isLoaded > 0;
|
||||||
}
|
}
|
||||||
|
@ -484,28 +645,109 @@ public class RoutingContext {
|
||||||
return isLoaded < 0;
|
return isLoaded < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnloaded() {
|
public void unload() {
|
||||||
if(isLoaded == 0) {
|
if(isLoaded == 0) {
|
||||||
this.isLoaded = -1;
|
this.isLoaded = -1;
|
||||||
} else {
|
} else {
|
||||||
isLoaded = -Math.abs(isLoaded);
|
isLoaded = -Math.abs(isLoaded);
|
||||||
}
|
}
|
||||||
if(nativeResults != null) {
|
if(searchResult != null) {
|
||||||
for(NativeRouteSearchResult rs : nativeResults) {
|
searchResult.deleteNativeResult();
|
||||||
rs.deleteNativeResult();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
searchResult = null;
|
||||||
|
routes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoaded() {
|
public void setLoadedNonNative(){
|
||||||
isLoaded = Math.abs(isLoaded) + 1;
|
isLoaded = Math.abs(isLoaded) + 1;
|
||||||
|
routes = new TLongObjectHashMap<BinaryRoutePlanner.RouteSegment>();
|
||||||
|
tileStatistics = new TileStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void add(RouteDataObject ro) {
|
||||||
public boolean checkContains(int x31, int y31) {
|
tileStatistics.addObject(ro);
|
||||||
return tileX == (x31 >> (31 - zoom)) && tileY == (y31 >> (31 - zoom));
|
for (int i = 0; i < ro.pointsX.length; i++) {
|
||||||
|
int x31 = ro.getPoint31XTile(i);
|
||||||
|
int y31 = ro.getPoint31YTile(i);
|
||||||
|
long l = (((long) x31) << 31) + (long) y31;
|
||||||
|
RouteSegment segment = new RouteSegment(ro, i);
|
||||||
|
if (!routes.containsKey(l)) {
|
||||||
|
routes.put(l, segment);
|
||||||
|
} else {
|
||||||
|
RouteSegment orig = routes.get(l);
|
||||||
|
while (orig.next != null) {
|
||||||
|
orig = orig.next;
|
||||||
|
}
|
||||||
|
orig.next = segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLoadedNative(NativeRouteSearchResult r, RoutingContext ctx) {
|
||||||
|
isLoaded = Math.abs(isLoaded) + 1;
|
||||||
|
tileStatistics = new TileStatistics();
|
||||||
|
if (r.objects != null) {
|
||||||
|
searchResult = null;
|
||||||
|
routes = new TLongObjectHashMap<BinaryRoutePlanner.RouteSegment>();
|
||||||
|
for (RouteDataObject ro : r.objects) {
|
||||||
|
if (ro != null && ctx.config.router.acceptLine(ro)) {
|
||||||
|
add(ro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
searchResult = r;
|
||||||
|
tileStatistics.size += 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class TileStatistics {
|
||||||
|
public int size = 0;
|
||||||
|
public int allRoutes = 0;
|
||||||
|
public int coordinates = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "All routes " + allRoutes +
|
||||||
|
" size " + (size / 1024f) + " KB coordinates " + coordinates + " ratio coord " + (((float)size) / coordinates)
|
||||||
|
+ " ratio routes " + (((float)size) / allRoutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addObject(RouteDataObject o) {
|
||||||
|
allRoutes++;
|
||||||
|
coordinates += o.getPointsLength() * 2;
|
||||||
|
// calculate size
|
||||||
|
int sz = 0;
|
||||||
|
sz += 8 + 4; // overhead
|
||||||
|
if (o.names != null) {
|
||||||
|
sz += 12;
|
||||||
|
TIntObjectIterator<String> it = o.names.iterator();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
it.advance();
|
||||||
|
String vl = it.value();
|
||||||
|
sz += 12 + vl.length();
|
||||||
|
}
|
||||||
|
sz += 12 + o.names.size() * 25;
|
||||||
|
}
|
||||||
|
sz += 8; // id
|
||||||
|
// coordinates
|
||||||
|
sz += (8 + 4 + 4 * o.getPointsLength()) * 4;
|
||||||
|
sz += o.types == null ? 4 : (8 + 4 + 4 * o.types.length);
|
||||||
|
sz += o.restrictions == null ? 4 : (8 + 4 + 8 * o.restrictions.length);
|
||||||
|
sz += 4;
|
||||||
|
if (o.pointTypes != null) {
|
||||||
|
sz += 8 + 4 * o.pointTypes.length;
|
||||||
|
for (int i = 0; i < o.pointTypes.length; i++) {
|
||||||
|
sz += 4;
|
||||||
|
if (o.pointTypes[i] != null) {
|
||||||
|
sz += 8 + 8 * o.pointTypes[i].length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Standard overhead?
|
||||||
|
size += sz * 3.5;
|
||||||
|
// size += coordinates * 20;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,13 +2,15 @@
|
||||||
<osmand_routing_config defaultProfile="car">
|
<osmand_routing_config defaultProfile="car">
|
||||||
<!-- 1. parameters of routing and different tweaks Influence on A* : -->
|
<!-- 1. parameters of routing and different tweaks Influence on A* : -->
|
||||||
<!-- f(x) + heuristicCoefficient*g(X) -->
|
<!-- f(x) + heuristicCoefficient*g(X) -->
|
||||||
<attribute name="heuristicCoefficient" value="1.0" />
|
<!-- TEMPORARY needs to be reverted to 1 -->
|
||||||
|
<attribute name="heuristicCoefficient" value="" />
|
||||||
|
|
||||||
<!-- 1.1 tile load parameters (should not affect routing) -->
|
<!-- 1.1 tile load parameters (should not affect routing) -->
|
||||||
<attribute name="zoomToLoadTiles" value="13" />
|
<!-- by default 16 -->
|
||||||
<attribute name="iterationsToRunGC" value="125" />
|
<attribute name="zoomToLoadTiles" value="16" />
|
||||||
<!-- by default it is 25 -->
|
<!-- by default it is 30. Value specified here overwrites all others
|
||||||
<attribute name="desirableTilesInMemory" value="" />
|
(don't specify here ! it is device dependent) -->
|
||||||
|
<attribute name="memoryLimitInMB" value="" />
|
||||||
|
|
||||||
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
|
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
|
||||||
<attribute name="useDynamicRoadPrioritising" value="true" />
|
<attribute name="useDynamicRoadPrioritising" value="true" />
|
||||||
|
@ -129,7 +131,6 @@
|
||||||
</avoid>
|
</avoid>
|
||||||
</routingProfile>
|
</routingProfile>
|
||||||
|
|
||||||
|
|
||||||
<routingProfile name="bicycle" baseProfile="bicycle" restrictionsAware="true" minDefaultSpeed="7" maxDefaultSpeed="16"
|
<routingProfile name="bicycle" baseProfile="bicycle" restrictionsAware="true" minDefaultSpeed="7" maxDefaultSpeed="16"
|
||||||
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
|
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
|
||||||
<!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> -->
|
<!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> -->
|
||||||
|
|
|
@ -119,12 +119,11 @@ public class MapClusterLayer implements MapPanelLayer {
|
||||||
rs.add(new BinaryMapIndexReader(raf));
|
rs.add(new BinaryMapIndexReader(raf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(),
|
BinaryRoutePlanner router = new BinaryRoutePlanner();
|
||||||
rs.toArray(new BinaryMapIndexReader[rs.size()]));
|
|
||||||
Builder builder = RoutingConfiguration.getDefault();
|
Builder builder = RoutingConfiguration.getDefault();
|
||||||
RoutingConfiguration config = builder.build("car");
|
RoutingConfiguration config = builder.build("car", RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3);
|
||||||
config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
|
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(),
|
||||||
RoutingContext ctx = new RoutingContext(config);
|
rs.toArray(new BinaryMapIndexReader[rs.size()]));
|
||||||
// find closest way
|
// find closest way
|
||||||
RouteSegment st = router.findRouteSegment(lat, lon, ctx);
|
RouteSegment st = router.findRouteSegment(lat, lon, ctx);
|
||||||
if (st != null) {
|
if (st != null) {
|
||||||
|
@ -174,7 +173,7 @@ public class MapClusterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
List<RouteSegment> results = searchCluster(ctx, st, router);
|
List<RouteSegment> results = searchCluster(ctx, st);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +186,7 @@ public class MapClusterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<RouteSegment> searchCluster(RoutingContext ctx, RouteSegment st, BinaryRoutePlanner router) throws IOException {
|
private List<RouteSegment> searchCluster(RoutingContext ctx, RouteSegment st) throws IOException {
|
||||||
Queue<List<RouteSegment>> queue = new LinkedList<List<RouteSegment>>();
|
Queue<List<RouteSegment>> queue = new LinkedList<List<RouteSegment>>();
|
||||||
List<RouteSegment> result = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
List<RouteSegment> result = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
||||||
TLongHashSet visitedIds = new TLongHashSet();
|
TLongHashSet visitedIds = new TLongHashSet();
|
||||||
|
@ -265,9 +264,7 @@ public class MapClusterLayer implements MapPanelLayer {
|
||||||
|
|
||||||
int x = road.getPoint31XTile(segmentEnd);
|
int x = road.getPoint31XTile(segmentEnd);
|
||||||
int y = road.getPoint31YTile(segmentEnd);
|
int y = road.getPoint31YTile(segmentEnd);
|
||||||
router.loadRoutes(ctx, x, y);
|
RouteSegment next = ctx.loadRouteSegment(x, y, 0);
|
||||||
long l = (((long) x) << 31) + (long) y;
|
|
||||||
RouteSegment next = ctx.getRoutingTile(x, y).getSegment(l, ctx);
|
|
||||||
RouteSegment toAdd = segment;
|
RouteSegment toAdd = segment;
|
||||||
if (!onTheMap.contains(toAdd.getRoad().getId())) {
|
if (!onTheMap.contains(toAdd.getRoad().getId())) {
|
||||||
onTheMap.add(toAdd.getRoad().getId());
|
onTheMap.add(toAdd.getRoad().getId());
|
||||||
|
|
|
@ -35,16 +35,20 @@ import net.osmand.data.DataTileManager;
|
||||||
import net.osmand.osm.Entity;
|
import net.osmand.osm.Entity;
|
||||||
import net.osmand.osm.LatLon;
|
import net.osmand.osm.LatLon;
|
||||||
import net.osmand.osm.MapUtils;
|
import net.osmand.osm.MapUtils;
|
||||||
import net.osmand.osm.Way;
|
|
||||||
import net.osmand.osm.OSMSettings.OSMTagKey;
|
import net.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
|
import net.osmand.osm.Way;
|
||||||
import net.osmand.router.BinaryRoutePlanner;
|
import net.osmand.router.BinaryRoutePlanner;
|
||||||
|
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||||
|
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
|
||||||
import net.osmand.router.RouteSegmentResult;
|
import net.osmand.router.RouteSegmentResult;
|
||||||
import net.osmand.router.RoutingConfiguration;
|
import net.osmand.router.RoutingConfiguration;
|
||||||
import net.osmand.router.RoutingConfiguration.Builder;
|
import net.osmand.router.RoutingConfiguration.Builder;
|
||||||
import net.osmand.router.RoutingContext;
|
import net.osmand.router.RoutingContext;
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
|
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.json.JSONTokener;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -52,11 +56,6 @@ import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.json.JSONTokener;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class MapRouterLayer implements MapPanelLayer {
|
public class MapRouterLayer implements MapPanelLayer {
|
||||||
|
@ -305,20 +304,6 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// for vector rendering we should extract from osm
|
|
||||||
// 1. Ways (different kinds) with tag highway= ?,highway=stop ...
|
|
||||||
// 2. Junction = roundabout
|
|
||||||
// 3. barrier, traffic_calming=bump
|
|
||||||
// 4. Save {name, ref} of way to unify it
|
|
||||||
|
|
||||||
// + for future routing we should extract from osm
|
|
||||||
// 1. oneway
|
|
||||||
// 2. max_speed
|
|
||||||
// 3. toll
|
|
||||||
// 4. traffic_signals
|
|
||||||
// 5. max_heigtht, max_width, min_speed, ...
|
|
||||||
// 6. incline ?
|
|
||||||
|
|
||||||
public static List<Way> route_YOURS(LatLon start, LatLon end){
|
public static List<Way> route_YOURS(LatLon start, LatLon end){
|
||||||
List<Way> res = new ArrayList<Way>();
|
List<Way> res = new ArrayList<Way>();
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
|
@ -625,11 +610,11 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
String m = DataExtractionSettings.getSettings().getRouteMode();
|
String m = DataExtractionSettings.getSettings().getRouteMode();
|
||||||
String[] props = m.split("\\,");
|
String[] props = m.split("\\,");
|
||||||
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs);
|
BinaryRoutePlanner router = new BinaryRoutePlanner();
|
||||||
RoutingConfiguration config = builder.build(props[0], props);
|
RoutingConfiguration config = builder.build(props[0], RoutingConfiguration.DEFAULT_MEMORY_LIMIT / 2, props);
|
||||||
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
|
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
|
||||||
// config.ZOOM_TO_LOAD_TILES = 14;
|
// config.ZOOM_TO_LOAD_TILES = 14;
|
||||||
RoutingContext ctx = new RoutingContext(config);
|
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(), rs);
|
||||||
ctx.previouslyCalculatedRoute = previousRoute;
|
ctx.previouslyCalculatedRoute = previousRoute;
|
||||||
log.info("Use " + config.routerName + "mode for routing");
|
log.info("Use " + config.routerName + "mode for routing");
|
||||||
|
|
||||||
|
@ -638,13 +623,13 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
if (st == null) {
|
if (st == null) {
|
||||||
throw new RuntimeException("Starting point for route not found");
|
throw new RuntimeException("Starting point for route not found");
|
||||||
}
|
}
|
||||||
System.out.println("ROAD TO START " + st.getRoad().getHighway() + " " + st.getRoad().id);
|
log.info("Start road " + st.getRoad().getHighway() + " " + st.getRoad().id);
|
||||||
|
|
||||||
RouteSegment e = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx);
|
RouteSegment e = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx);
|
||||||
if (e == null) {
|
if (e == null) {
|
||||||
throw new RuntimeException("End point to calculate route was not found");
|
throw new RuntimeException("End point to calculate route was not found");
|
||||||
}
|
}
|
||||||
System.out.println("ROAD TO END " + e.getRoad().getHighway() + " " + e.getRoad().id);
|
log.info("End road " + e.getRoad().getHighway() + " " + e.getRoad().id);
|
||||||
|
|
||||||
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
||||||
if (intermediates != null) {
|
if (intermediates != null) {
|
||||||
|
@ -763,6 +748,8 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ExceptionHandler.handle(e);
|
ExceptionHandler.handle(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
ExceptionHandler.handle(e);
|
||||||
} finally {
|
} finally {
|
||||||
playPauseButton.setVisible(false);
|
playPauseButton.setVisible(false);
|
||||||
nextTurn.setVisible(false);
|
nextTurn.setVisible(false);
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
<ToggleButton android:contentDescription="@string/app_mode_pedestrian" android:textOn="" android:textOff="" android:id="@+id/PedestrianButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:background="@drawable/pedestrian_icon"/>
|
<ToggleButton android:contentDescription="@string/app_mode_pedestrian" android:textOn="" android:textOff="" android:id="@+id/PedestrianButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:background="@drawable/pedestrian_icon"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<CheckBox android:id="@+id/OptimalCheckox" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/non_optimal_route_calculation"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<resources><string name="download_link_and_local_description">Загрузите или обновите локальные данные.
|
<resources>
|
||||||
|
<string name="non_optimal_route_calculation">Рассчитать неоптимальный (возможно) маршрут на длинные дистанции</string>
|
||||||
|
<string name="download_link_and_local_description">Загрузите или обновите локальные данные.
|
||||||
\nЧтобы получить дополнительную информацию о карте, выделите её в списке. Удерживайте карту, если вы хотите удалить или деактивировать.
|
\nЧтобы получить дополнительную информацию о карте, выделите её в списке. Удерживайте карту, если вы хотите удалить или деактивировать.
|
||||||
\nДанные на устройстве (%1$s свободно):</string>
|
\nДанные на устройстве (%1$s свободно):</string>
|
||||||
<string name="tip_recent_changes_0_8_3_t">"Изменения в 0.8.3:
|
<string name="tip_recent_changes_0_8_3_t">"Изменения в 0.8.3:
|
||||||
|
@ -735,7 +737,7 @@
|
||||||
<string name="navigate_point_format_D">ГГГ.ГГГГ</string>
|
<string name="navigate_point_format_D">ГГГ.ГГГГ</string>
|
||||||
<string name="navigate_point_format_DM">ГГГ ММ.МММММ</string>
|
<string name="navigate_point_format_DM">ГГГ ММ.МММММ</string>
|
||||||
<string name="navigate_point_format_DMS">ГГГ ММ СС.ССССС</string>
|
<string name="navigate_point_format_DMS">ГГГ ММ СС.ССССС</string>
|
||||||
<string name="search_shown_on_map">Отобразить на карте</string>
|
<string name="search_shown_on_map">Показать</string>
|
||||||
<string name="navigate_point_cancel">Отмена</string>
|
<string name="navigate_point_cancel">Отмена</string>
|
||||||
<string name="search_address_top_text">Выберите адрес</string>
|
<string name="search_address_top_text">Выберите адрес</string>
|
||||||
<string name="search_address_region">Регион</string>
|
<string name="search_address_region">Регион</string>
|
||||||
|
|
|
@ -9,7 +9,10 @@
|
||||||
1. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
1. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
||||||
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||||
-->
|
-->
|
||||||
|
<string name="enable_plugin_monitoring_services">Enable monitoring plugins (tracking, live tracking) to use monitoring services </string>
|
||||||
|
<string name="non_optimal_route_calculation">Calculate possibly non-optimal route over long distances</string>
|
||||||
<string name="tip_recent_changes_0_8_4_t">Changes in 0.8.4 :
|
<string name="tip_recent_changes_0_8_4_t">Changes in 0.8.4 :
|
||||||
|
Updated
|
||||||
</string>
|
</string>
|
||||||
<string name="gps_not_available">Please enable GPS in the settings</string>
|
<string name="gps_not_available">Please enable GPS in the settings</string>
|
||||||
<string name="tip_recent_changes_0_8_3_t">Changes in 0.8.3 :
|
<string name="tip_recent_changes_0_8_3_t">Changes in 0.8.3 :
|
||||||
|
|
|
@ -59,6 +59,8 @@ public class OsmandSettings {
|
||||||
|
|
||||||
boolean set(T obj);
|
boolean set(T obj);
|
||||||
|
|
||||||
|
boolean setModeValue(ApplicationMode m, T obj);
|
||||||
|
|
||||||
T getModeValue(ApplicationMode m);
|
T getModeValue(ApplicationMode m);
|
||||||
|
|
||||||
String getId();
|
String getId();
|
||||||
|
@ -144,6 +146,11 @@ public class OsmandSettings {
|
||||||
public ApplicationMode getModeValue(ApplicationMode m) {
|
public ApplicationMode getModeValue(ApplicationMode m) {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setModeValue(ApplicationMode m, ApplicationMode obj) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public ApplicationMode getApplicationMode(){
|
public ApplicationMode getApplicationMode(){
|
||||||
|
@ -241,6 +248,14 @@ public class OsmandSettings {
|
||||||
defaultValues.put(mode, defValue);
|
defaultValues.put(mode, defValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setModeValue(ApplicationMode mode, T obj){
|
||||||
|
if(global) {
|
||||||
|
return set(obj);
|
||||||
|
}
|
||||||
|
return setValue(getProfilePreferences(mode), obj);
|
||||||
|
}
|
||||||
|
|
||||||
public T getProfileDefaultValue(){
|
public T getProfileDefaultValue(){
|
||||||
if(global){
|
if(global){
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
@ -596,6 +611,10 @@ public class OsmandSettings {
|
||||||
|
|
||||||
// this value string is synchronized with settings_pref.xml preference name
|
// this value string is synchronized with settings_pref.xml preference name
|
||||||
public final OsmandPreference<Boolean> FAST_ROUTE_MODE = new BooleanPreference("fast_route_mode", true).makeProfile();
|
public final OsmandPreference<Boolean> FAST_ROUTE_MODE = new BooleanPreference("fast_route_mode", true).makeProfile();
|
||||||
|
public final CommonPreference<Boolean> OPTIMAL_ROUTE_MODE = new BooleanPreference("optimal_route_mode", true).makeProfile();
|
||||||
|
{
|
||||||
|
OPTIMAL_ROUTE_MODE.setModeDefaultValue(ApplicationMode.PEDESTRIAN, false);
|
||||||
|
}
|
||||||
|
|
||||||
public final OsmandPreference<Boolean> SHOW_SPEED_LIMITS = new BooleanPreference("show_speed_limits", true).makeGlobal().cache();
|
public final OsmandPreference<Boolean> SHOW_SPEED_LIMITS = new BooleanPreference("show_speed_limits", true).makeGlobal().cache();
|
||||||
public final OsmandPreference<Boolean> SHOW_CAMERAS = new BooleanPreference("show_cameras", true).makeGlobal().cache();
|
public final OsmandPreference<Boolean> SHOW_CAMERAS = new BooleanPreference("show_cameras", true).makeGlobal().cache();
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class MainMenuActivity extends Activity {
|
||||||
SharedPreferences prefs = activity.getApplicationContext().getSharedPreferences("net.osmand.settings", MODE_WORLD_READABLE);
|
SharedPreferences prefs = activity.getApplicationContext().getSharedPreferences("net.osmand.settings", MODE_WORLD_READABLE);
|
||||||
|
|
||||||
// only one commit should be with contribution version flag
|
// only one commit should be with contribution version flag
|
||||||
// prefs.edit().putBoolean(CONTRIBUTION_VERSION_FLAG, true).commit();
|
prefs.edit().putBoolean(CONTRIBUTION_VERSION_FLAG, true).commit();
|
||||||
if (prefs.contains(CONTRIBUTION_VERSION_FLAG)) {
|
if (prefs.contains(CONTRIBUTION_VERSION_FLAG)) {
|
||||||
SpannableString content = new SpannableString(textVersion);
|
SpannableString content = new SpannableString(textVersion);
|
||||||
content.setSpan(new ClickableSpan() {
|
content.setSpan(new ClickableSpan() {
|
||||||
|
|
|
@ -292,7 +292,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
|
||||||
Object toShow = settings.getAndClearObjectToShow();
|
Object toShow = settings.getAndClearObjectToShow();
|
||||||
if(settings.isRouteToPointNavigateAndClear()){
|
if(settings.isRouteToPointNavigateAndClear()){
|
||||||
// always enable and follow and let calculate it (GPS is not accessible in garage)
|
// always enable and follow and let calculate it (GPS is not accessible in garage)
|
||||||
mapActions.getDirections(getLastKnownLocation(), false);
|
mapActions.getDirections(null, null, false);
|
||||||
}
|
}
|
||||||
if(mapLabelToShow != null && latLonToShow != null){
|
if(mapLabelToShow != null && latLonToShow != null){
|
||||||
mapLayers.getContextMenuLayer().setSelectedObject(toShow);
|
mapLayers.getContextMenuLayer().setSelectedObject(toShow);
|
||||||
|
|
|
@ -407,13 +407,14 @@ public class MapActivityActions implements DialogProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void getDirections(final Location from, boolean gpxRouteEnabled) {
|
public void getDirections(final Location fromOrCurrent, final LatLon to, boolean gpxRouteEnabled) {
|
||||||
|
|
||||||
final RoutingHelper routingHelper = mapActivity.getRoutingHelper();
|
final RoutingHelper routingHelper = mapActivity.getRoutingHelper();
|
||||||
|
|
||||||
Builder builder = new AlertDialog.Builder(mapActivity);
|
Builder builder = new AlertDialog.Builder(mapActivity);
|
||||||
|
|
||||||
View view = mapActivity.getLayoutInflater().inflate(R.layout.calculate_route, null);
|
View view = mapActivity.getLayoutInflater().inflate(R.layout.calculate_route, null);
|
||||||
|
final CheckBox nonoptimal = (CheckBox) view.findViewById(R.id.OptimalCheckox);
|
||||||
final ToggleButton[] buttons = new ToggleButton[ApplicationMode.values().length];
|
final ToggleButton[] buttons = new ToggleButton[ApplicationMode.values().length];
|
||||||
buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton);
|
buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton);
|
||||||
buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton);
|
buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton);
|
||||||
|
@ -426,11 +427,16 @@ public class MapActivityActions implements DialogProvider {
|
||||||
if (buttons[i] != null) {
|
if (buttons[i] != null) {
|
||||||
final int ind = i;
|
final int ind = i;
|
||||||
ToggleButton b = buttons[i];
|
ToggleButton b = buttons[i];
|
||||||
b.setChecked(appMode == ApplicationMode.values()[i]);
|
final ApplicationMode buttonAppMode = ApplicationMode.values()[i];
|
||||||
|
b.setChecked(appMode == buttonAppMode);
|
||||||
|
if(b.isChecked()) {
|
||||||
|
nonoptimal.setChecked(!settings.OPTIMAL_ROUTE_MODE.getModeValue(buttonAppMode));
|
||||||
|
}
|
||||||
b.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
b.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
|
nonoptimal.setChecked(!settings.OPTIMAL_ROUTE_MODE.getModeValue(buttonAppMode));
|
||||||
for (int j = 0; j < buttons.length; j++) {
|
for (int j = 0; j < buttons.length; j++) {
|
||||||
if (buttons[j] != null) {
|
if (buttons[j] != null) {
|
||||||
if (buttons[j].isChecked() != (ind == j)) {
|
if (buttons[j].isChecked() != (ind == j)) {
|
||||||
|
@ -461,15 +467,23 @@ public class MapActivityActions implements DialogProvider {
|
||||||
DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener() {
|
DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if(to != null) {
|
||||||
|
mapActivity.navigateToPoint(to, false, -1);
|
||||||
|
}
|
||||||
if (!checkPointToNavigate()) {
|
if (!checkPointToNavigate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Location from = fromOrCurrent;
|
||||||
|
if(from == null) {
|
||||||
|
from = mapActivity.getLastKnownLocation();
|
||||||
|
}
|
||||||
if (from == null) {
|
if (from == null) {
|
||||||
AccessibleToast.makeText(mapActivity, R.string.unknown_from_location, Toast.LENGTH_LONG).show();
|
AccessibleToast.makeText(mapActivity, R.string.unknown_from_location, Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ApplicationMode mode = getAppMode(buttons, settings);
|
ApplicationMode mode = getAppMode(buttons, settings);
|
||||||
routingHelper.setAppMode(mode);
|
routingHelper.setAppMode(mode);
|
||||||
|
settings.OPTIMAL_ROUTE_MODE.setModeValue(mode, !nonoptimal.isChecked());
|
||||||
settings.FOLLOW_THE_ROUTE.set(false);
|
settings.FOLLOW_THE_ROUTE.set(false);
|
||||||
settings.FOLLOW_THE_GPX_ROUTE.set(null);
|
settings.FOLLOW_THE_GPX_ROUTE.set(null);
|
||||||
routingHelper.setFollowingMode(false);
|
routingHelper.setFollowingMode(false);
|
||||||
|
@ -481,12 +495,19 @@ public class MapActivityActions implements DialogProvider {
|
||||||
DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener() {
|
DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if(to != null) {
|
||||||
|
mapActivity.navigateToPoint(to, false, -1);
|
||||||
|
}
|
||||||
if (!checkPointToNavigate()) {
|
if (!checkPointToNavigate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean msg = true;
|
boolean msg = true;
|
||||||
Location current = from;
|
Location current = fromOrCurrent;
|
||||||
if (!mapActivity.isPointAccurateForRouting(from)) {
|
if(current == null) {
|
||||||
|
current = mapActivity.getLastKnownLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mapActivity.isPointAccurateForRouting(current)) {
|
||||||
current = null;
|
current = null;
|
||||||
}
|
}
|
||||||
Location lastKnownLocation = mapActivity.getLastKnownLocation();
|
Location lastKnownLocation = mapActivity.getLastKnownLocation();
|
||||||
|
@ -507,6 +528,9 @@ public class MapActivityActions implements DialogProvider {
|
||||||
DialogInterface.OnClickListener useGpxNavigation = new DialogInterface.OnClickListener() {
|
DialogInterface.OnClickListener useGpxNavigation = new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if(to != null) {
|
||||||
|
mapActivity.navigateToPoint(to, false, -1);
|
||||||
|
}
|
||||||
ApplicationMode mode = getAppMode(buttons, settings);
|
ApplicationMode mode = getAppMode(buttons, settings);
|
||||||
navigateUsingGPX(mode);
|
navigateUsingGPX(mode);
|
||||||
}
|
}
|
||||||
|
@ -734,16 +758,14 @@ public class MapActivityActions implements DialogProvider {
|
||||||
} else if (standardId == R.string.context_menu_item_navigate_point) {
|
} else if (standardId == R.string.context_menu_item_navigate_point) {
|
||||||
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, -1);
|
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, -1);
|
||||||
} else if (standardId == R.string.context_menu_item_directions) {
|
} else if (standardId == R.string.context_menu_item_directions) {
|
||||||
Location loc = mapActivity.getLastKnownLocation();
|
|
||||||
mapActivity.navigateToPoint(new LatLon(latitude, longitude), false, -1);
|
|
||||||
// always enable and follow and let calculate it (GPS is not accessible in garage)
|
// always enable and follow and let calculate it (GPS is not accessible in garage)
|
||||||
getDirections(loc, true);
|
getDirections(null, new LatLon(latitude, longitude), true);
|
||||||
} else if (standardId == R.string.context_menu_item_show_route) {
|
} else if (standardId == R.string.context_menu_item_show_route) {
|
||||||
if (checkPointToNavigate()) {
|
if (checkPointToNavigate()) {
|
||||||
Location loc = new Location("map");
|
Location loc = new Location("map");
|
||||||
loc.setLatitude(latitude);
|
loc.setLatitude(latitude);
|
||||||
loc.setLongitude(longitude);
|
loc.setLongitude(longitude);
|
||||||
getDirections(loc, true);
|
getDirections(loc, null, true);
|
||||||
}
|
}
|
||||||
} else if (standardId == R.string.context_menu_item_intermediate_point) {
|
} else if (standardId == R.string.context_menu_item_intermediate_point) {
|
||||||
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, mapActivity.getIntermediatePoints().size());
|
mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, mapActivity.getIntermediatePoints().size());
|
||||||
|
@ -957,8 +979,7 @@ public class MapActivityActions implements DialogProvider {
|
||||||
if (routingHelper.isRouteCalculated()) {
|
if (routingHelper.isRouteCalculated()) {
|
||||||
aboutRoute();
|
aboutRoute();
|
||||||
} else {
|
} else {
|
||||||
Location loc = mapActivity.getLastKnownLocation();
|
getDirections(null, null, true);
|
||||||
getDirections(loc, true);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,8 @@ import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
|
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.AlertDialog.Builder;
|
import android.app.AlertDialog.Builder;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationManager;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -39,7 +39,6 @@ import net.osmand.router.BinaryRoutePlanner;
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||||
import net.osmand.router.GeneralRouter;
|
import net.osmand.router.GeneralRouter;
|
||||||
import net.osmand.router.GeneralRouter.GeneralRouterProfile;
|
import net.osmand.router.GeneralRouter.GeneralRouterProfile;
|
||||||
import net.osmand.router.Interruptable;
|
|
||||||
import net.osmand.router.RouteSegmentResult;
|
import net.osmand.router.RouteSegmentResult;
|
||||||
import net.osmand.router.RoutingConfiguration;
|
import net.osmand.router.RoutingConfiguration;
|
||||||
import net.osmand.router.RoutingContext;
|
import net.osmand.router.RoutingContext;
|
||||||
|
@ -147,29 +146,25 @@ public class RouteProvider {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, List<LatLon> intermediates, ApplicationMode mode, RouteService type, Context ctx,
|
public RouteCalculationResult calculateRouteImpl(RouteCalcuationParams params){
|
||||||
GPXRouteParams gpxRoute, RouteCalculationResult previousToRecalculate, boolean fast, boolean leftSide, Interruptable interruptable){
|
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
if (start != null && end != null) {
|
if (params.start != null && params.end != null) {
|
||||||
if(log.isInfoEnabled()){
|
if(log.isInfoEnabled()){
|
||||||
log.info("Start finding route from " + start + " to " + end +" using " + type.getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
log.info("Start finding route from " + params.start + " to " + params.end +" using " +
|
||||||
|
params.type.getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
RouteCalculationResult res;
|
RouteCalculationResult res;
|
||||||
if(gpxRoute != null && !gpxRoute.points.isEmpty()){
|
if(params.gpxRoute != null && !params.gpxRoute.points.isEmpty()){
|
||||||
res = calculateGpxRoute(start, end, gpxRoute, ctx, leftSide);
|
res = calculateGpxRoute(params);
|
||||||
} else if (type == RouteService.YOURS) {
|
} else if (params.type == RouteService.YOURS) {
|
||||||
res = findYOURSRoute(start, end, mode, fast, ctx, leftSide);
|
res = findYOURSRoute(params);
|
||||||
} else if (type == RouteService.ORS) {
|
} else if (params.type == RouteService.ORS) {
|
||||||
res = findORSRoute(start, end, mode, fast, ctx, leftSide);
|
res = findORSRoute(params);
|
||||||
} else if (type == RouteService.OSMAND) {
|
} else if (params.type == RouteService.OSMAND) {
|
||||||
List<RouteSegmentResult> originalRoute = null;
|
res = findVectorMapsRoute(params);
|
||||||
if(previousToRecalculate != null) {
|
|
||||||
originalRoute = previousToRecalculate.getOriginalRoute();
|
|
||||||
}
|
|
||||||
res = findVectorMapsRoute(start, end, intermediates, mode, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide, interruptable);
|
|
||||||
} else {
|
} else {
|
||||||
res = findCloudMadeRoute(start, end, intermediates, mode, ctx, fast, leftSide);
|
res = findCloudMadeRoute(params);
|
||||||
}
|
}
|
||||||
if(log.isInfoEnabled() ){
|
if(log.isInfoEnabled() ){
|
||||||
log.info("Finding route contained " + res.getImmutableLocations().size() + " points for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
log.info("Finding route contained " + res.getImmutableLocations().size() + " points for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
@ -186,27 +181,29 @@ public class RouteProvider {
|
||||||
return new RouteCalculationResult(null);
|
return new RouteCalculationResult(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RouteCalculationResult calculateGpxRoute(Location start, LatLon end, GPXRouteParams params, Context ctx, boolean leftSide) {
|
|
||||||
|
private RouteCalculationResult calculateGpxRoute(RouteCalcuationParams pars) {
|
||||||
RouteCalculationResult res;
|
RouteCalculationResult res;
|
||||||
// get the closest point to start and to end
|
// get the closest point to start and to end
|
||||||
float minDist = Integer.MAX_VALUE;
|
float minDist = Integer.MAX_VALUE;
|
||||||
int startI = 0;
|
int startI = 0;
|
||||||
|
GPXRouteParams params = pars.gpxRoute;
|
||||||
List<Location> gpxRoute = params.points;
|
List<Location> gpxRoute = params.points;
|
||||||
int endI = gpxRoute.size();
|
int endI = gpxRoute.size();
|
||||||
if (start != null) {
|
if (pars.start != null) {
|
||||||
for (int i = 0; i < gpxRoute.size(); i++) {
|
for (int i = 0; i < gpxRoute.size(); i++) {
|
||||||
float d = gpxRoute.get(i).distanceTo(start);
|
float d = gpxRoute.get(i).distanceTo(pars.start);
|
||||||
if (d < minDist) {
|
if (d < minDist) {
|
||||||
startI = i;
|
startI = i;
|
||||||
minDist = d;
|
minDist = d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
start = gpxRoute.get(0);
|
pars.start = gpxRoute.get(0);
|
||||||
}
|
}
|
||||||
Location l = new Location("temp"); //$NON-NLS-1$
|
Location l = new Location("temp"); //$NON-NLS-1$
|
||||||
l.setLatitude(end.getLatitude());
|
l.setLatitude(pars.end.getLatitude());
|
||||||
l.setLongitude(end.getLongitude());
|
l.setLongitude(pars.end.getLongitude());
|
||||||
minDist = Integer.MAX_VALUE;
|
minDist = Integer.MAX_VALUE;
|
||||||
// get in reverse order taking into account ways with cycle
|
// get in reverse order taking into account ways with cycle
|
||||||
for (int i = gpxRoute.size() - 1; i >= startI; i--) {
|
for (int i = gpxRoute.size() - 1; i >= startI; i--) {
|
||||||
|
@ -219,7 +216,8 @@ public class RouteProvider {
|
||||||
}
|
}
|
||||||
ArrayList<Location> sublist = new ArrayList<Location>(gpxRoute.subList(startI, endI));
|
ArrayList<Location> sublist = new ArrayList<Location>(gpxRoute.subList(startI, endI));
|
||||||
if(params.directions == null){
|
if(params.directions == null){
|
||||||
res = new RouteCalculationResult(sublist, params.directions, start, end, null, null, ctx, leftSide, true);
|
res = new RouteCalculationResult(sublist, params.directions, pars.start, pars.end, null, null,
|
||||||
|
pars.ctx, pars.leftSide, true);
|
||||||
} else {
|
} else {
|
||||||
List<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>();
|
List<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>();
|
||||||
for (RouteDirectionInfo info : params.directions) {
|
for (RouteDirectionInfo info : params.directions) {
|
||||||
|
@ -234,7 +232,8 @@ public class RouteProvider {
|
||||||
subdirections.add(ch);
|
subdirections.add(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = new RouteCalculationResult(sublist, subdirections, start, end, null, null, ctx, leftSide, true);
|
res = new RouteCalculationResult(sublist, subdirections, pars.start, pars.end, null, null,
|
||||||
|
pars.ctx, pars.leftSide, true);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -249,23 +248,23 @@ public class RouteProvider {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected RouteCalculationResult findYOURSRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, Context ctx, boolean leftSide) throws MalformedURLException, IOException,
|
protected RouteCalculationResult findYOURSRoute(RouteCalcuationParams params) throws MalformedURLException, IOException,
|
||||||
ParserConfigurationException, FactoryConfigurationError, SAXException {
|
ParserConfigurationException, FactoryConfigurationError, SAXException {
|
||||||
List<Location> res = new ArrayList<Location>();
|
List<Location> res = new ArrayList<Location>();
|
||||||
StringBuilder uri = new StringBuilder();
|
StringBuilder uri = new StringBuilder();
|
||||||
uri.append("http://www.yournavigation.org/api/1.0/gosmore.php?format=kml"); //$NON-NLS-1$
|
uri.append("http://www.yournavigation.org/api/1.0/gosmore.php?format=kml"); //$NON-NLS-1$
|
||||||
uri.append("&flat=").append(start.getLatitude()); //$NON-NLS-1$
|
uri.append("&flat=").append(params.start.getLatitude()); //$NON-NLS-1$
|
||||||
uri.append("&flon=").append(start.getLongitude()); //$NON-NLS-1$
|
uri.append("&flon=").append(params.start.getLongitude()); //$NON-NLS-1$
|
||||||
uri.append("&tlat=").append(end.getLatitude()); //$NON-NLS-1$
|
uri.append("&tlat=").append(params.end.getLatitude()); //$NON-NLS-1$
|
||||||
uri.append("&tlon=").append(end.getLongitude()); //$NON-NLS-1$
|
uri.append("&tlon=").append(params.end.getLongitude()); //$NON-NLS-1$
|
||||||
if(ApplicationMode.PEDESTRIAN == mode){
|
if(ApplicationMode.PEDESTRIAN == params.mode){
|
||||||
uri.append("&v=foot") ; //$NON-NLS-1$
|
uri.append("&v=foot") ; //$NON-NLS-1$
|
||||||
} else if(ApplicationMode.BICYCLE == mode){
|
} else if(ApplicationMode.BICYCLE == params.mode){
|
||||||
uri.append("&v=bicycle") ; //$NON-NLS-1$
|
uri.append("&v=bicycle") ; //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
uri.append("&v=motorcar"); //$NON-NLS-1$
|
uri.append("&v=motorcar"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
uri.append("&fast=").append(fast ? "1" : "0").append("&layer=mapnik"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
uri.append("&fast=").append(params.fast ? "1" : "0").append("&layer=mapnik"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||||
log.info("URL route " + uri);
|
log.info("URL route " + uri);
|
||||||
URL url = new URL(uri.toString());
|
URL url = new URL(uri.toString());
|
||||||
URLConnection connection = url.openConnection();
|
URLConnection connection = url.openConnection();
|
||||||
|
@ -304,14 +303,14 @@ public class RouteProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true);
|
return new RouteCalculationResult(res, null, params.start, params.end, null, null,
|
||||||
|
params.ctx, params.leftSide, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, List<LatLon> intermediates, ApplicationMode mode, OsmandApplication app,
|
protected RouteCalculationResult findVectorMapsRoute(RouteCalcuationParams params) throws IOException {
|
||||||
List<RouteSegmentResult> previousRoute,
|
OsmandApplication app = (OsmandApplication) params.ctx.getApplicationContext();
|
||||||
boolean leftSide, Interruptable interruptable) throws IOException {
|
|
||||||
BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles();
|
BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles();
|
||||||
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeOsmandLibrary.getLoadedLibrary(), files);
|
BinaryRoutePlanner router = new BinaryRoutePlanner();
|
||||||
File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML);
|
File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML);
|
||||||
RoutingConfiguration.Builder config ;
|
RoutingConfiguration.Builder config ;
|
||||||
if (routingXml.exists() && routingXml.canRead()) {
|
if (routingXml.exists() && routingXml.canRead()) {
|
||||||
|
@ -325,9 +324,9 @@ public class RouteProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneralRouterProfile p ;
|
GeneralRouterProfile p ;
|
||||||
if (mode == ApplicationMode.BICYCLE) {
|
if (params.mode == ApplicationMode.BICYCLE) {
|
||||||
p = GeneralRouterProfile.BICYCLE;
|
p = GeneralRouterProfile.BICYCLE;
|
||||||
} else if (mode == ApplicationMode.PEDESTRIAN) {
|
} else if (params.mode == ApplicationMode.PEDESTRIAN) {
|
||||||
p = GeneralRouterProfile.PEDESTRIAN;
|
p = GeneralRouterProfile.PEDESTRIAN;
|
||||||
} else {
|
} else {
|
||||||
p = GeneralRouterProfile.CAR;
|
p = GeneralRouterProfile.CAR;
|
||||||
|
@ -349,21 +348,36 @@ public class RouteProvider {
|
||||||
specs.add(GeneralRouter.AVOID_UNPAVED);
|
specs.add(GeneralRouter.AVOID_UNPAVED);
|
||||||
}
|
}
|
||||||
String[] specialization = specs.toArray(new String[specs.size()]);
|
String[] specialization = specs.toArray(new String[specs.size()]);
|
||||||
RoutingContext ctx = new RoutingContext(config.build(p.name().toLowerCase(), start.hasBearing() ? start.getBearing() / 180d * Math.PI : null, specialization));
|
float mb = (1 << 20);
|
||||||
ctx.interruptable = interruptable;
|
Runtime rt = Runtime.getRuntime();
|
||||||
ctx.previouslyCalculatedRoute = previousRoute;
|
// make visible
|
||||||
RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx);
|
int memoryLimit = (int) (0.95 * ((rt.maxMemory() - rt.totalMemory()) + rt.freeMemory()) / mb);
|
||||||
|
log.warn("Use " + memoryLimit + " MB Free " + rt.freeMemory() / mb + " of " + rt.totalMemory() / mb + " max " + rt.maxMemory() / mb);
|
||||||
|
|
||||||
|
RoutingConfiguration cf = config.build(p.name().toLowerCase(), params.start.hasBearing() ?
|
||||||
|
params.start.getBearing() / 180d * Math.PI : null,
|
||||||
|
memoryLimit, specialization);
|
||||||
|
if(!params.optimal){
|
||||||
|
cf.heuristicCoefficient *= 1.5;
|
||||||
|
}
|
||||||
|
RoutingContext ctx = new RoutingContext(cf, NativeOsmandLibrary.getLoadedLibrary(), files);
|
||||||
|
ctx.interruptable = params.interruptable;
|
||||||
|
if(params.previousToRecalculate != null) {
|
||||||
|
ctx.previouslyCalculatedRoute = params.previousToRecalculate.getOriginalRoute();
|
||||||
|
}
|
||||||
|
RouteSegment st= router.findRouteSegment(params.start.getLatitude(), params.start.getLongitude(), ctx);
|
||||||
if (st == null) {
|
if (st == null) {
|
||||||
return new RouteCalculationResult(app.getString(R.string.starting_point_too_far));
|
return new RouteCalculationResult(app.getString(R.string.starting_point_too_far));
|
||||||
}
|
}
|
||||||
RouteSegment en = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx);
|
RouteSegment en = router.findRouteSegment(params.end.getLatitude(),
|
||||||
|
params.end.getLongitude(), ctx);
|
||||||
if (en == null) {
|
if (en == null) {
|
||||||
return new RouteCalculationResult(app.getString(R.string.ending_point_too_far));
|
return new RouteCalculationResult(app.getString(R.string.ending_point_too_far));
|
||||||
}
|
}
|
||||||
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
||||||
if (intermediates != null) {
|
if (params.intermediates != null) {
|
||||||
int ind = 1;
|
int ind = 1;
|
||||||
for (LatLon il : intermediates) {
|
for (LatLon il : params.intermediates) {
|
||||||
RouteSegment is = router.findRouteSegment(il.getLatitude(), il.getLongitude(), ctx);
|
RouteSegment is = router.findRouteSegment(il.getLatitude(), il.getLongitude(), ctx);
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
return new RouteCalculationResult(app.getString(R.string.intermediate_point_too_far, "'" + ind + "'"));
|
return new RouteCalculationResult(app.getString(R.string.intermediate_point_too_far, "'" + ind + "'"));
|
||||||
|
@ -375,16 +389,19 @@ public class RouteProvider {
|
||||||
try {
|
try {
|
||||||
List<RouteSegmentResult> result;
|
List<RouteSegmentResult> result;
|
||||||
if(inters.size() > 0){
|
if(inters.size() > 0){
|
||||||
result = router.searchRoute(ctx, st, en, inters, leftSide);
|
result = router.searchRoute(ctx, st, en, inters, params.leftSide);
|
||||||
} else {
|
} else {
|
||||||
result = router.searchRoute(ctx, st, en, leftSide);
|
result = router.searchRoute(ctx, st, en, params.leftSide);
|
||||||
}
|
}
|
||||||
if(result == null || result.isEmpty()) {
|
if(result == null || result.isEmpty()) {
|
||||||
// something really strange better to see that message on the scren
|
// something really strange better to see that message on the scren
|
||||||
return new RouteCalculationResult("Empty result");
|
return new RouteCalculationResult("Empty result");
|
||||||
} else {
|
} else {
|
||||||
return new RouteCalculationResult(result, start, end, intermediates, app, leftSide);
|
return new RouteCalculationResult(result, params.start, params.end,
|
||||||
|
params.intermediates, app, params.leftSide);
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return new RouteCalculationResult("Route calculation was interrupted");
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
||||||
// ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE);
|
// ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
// ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
// ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||||
|
@ -398,19 +415,19 @@ public class RouteProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected RouteCalculationResult findCloudMadeRoute(Location start, LatLon end, List<LatLon> intermediates, ApplicationMode mode, Context ctx, boolean fast, boolean leftSide)
|
protected RouteCalculationResult findCloudMadeRoute(RouteCalcuationParams params)
|
||||||
throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException {
|
throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException {
|
||||||
List<Location> res = new ArrayList<Location>();
|
List<Location> res = new ArrayList<Location>();
|
||||||
List<RouteDirectionInfo> directions = null;
|
List<RouteDirectionInfo> directions = null;
|
||||||
StringBuilder uri = new StringBuilder();
|
StringBuilder uri = new StringBuilder();
|
||||||
// possibly hide that API key because it is privacy of osmand
|
// possibly hide that API key because it is privacy of osmand
|
||||||
uri.append("http://routes.cloudmade.com/A6421860EBB04234AB5EF2D049F2CD8F/api/0.3/"); //$NON-NLS-1$
|
uri.append("http://routes.cloudmade.com/A6421860EBB04234AB5EF2D049F2CD8F/api/0.3/"); //$NON-NLS-1$
|
||||||
uri.append(start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
uri.append(params.start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
uri.append(start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
uri.append(params.start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
if(intermediates != null && intermediates.size() > 0) {
|
if(params.intermediates != null && params.intermediates.size() > 0) {
|
||||||
uri.append("[");
|
uri.append("[");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for(LatLon il : intermediates) {
|
for(LatLon il : params.intermediates) {
|
||||||
if(!first){
|
if(!first){
|
||||||
uri.append(",");
|
uri.append(",");
|
||||||
} else {
|
} else {
|
||||||
|
@ -421,18 +438,18 @@ public class RouteProvider {
|
||||||
}
|
}
|
||||||
uri.append("],");
|
uri.append("],");
|
||||||
}
|
}
|
||||||
uri.append(end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$
|
uri.append(params.end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
uri.append(end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$
|
uri.append(params.end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
float speed = 1.5f;
|
float speed = 1.5f;
|
||||||
if (ApplicationMode.PEDESTRIAN == mode) {
|
if (ApplicationMode.PEDESTRIAN == params.mode) {
|
||||||
uri.append("foot.gpx"); //$NON-NLS-1$
|
uri.append("foot.gpx"); //$NON-NLS-1$
|
||||||
} else if (ApplicationMode.BICYCLE == mode) {
|
} else if (ApplicationMode.BICYCLE == params.mode) {
|
||||||
speed = 5.5f;
|
speed = 5.5f;
|
||||||
uri.append("bicycle.gpx"); //$NON-NLS-1$
|
uri.append("bicycle.gpx"); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
speed = 15.3f;
|
speed = 15.3f;
|
||||||
if (fast) {
|
if (params.fast) {
|
||||||
uri.append("car.gpx"); //$NON-NLS-1$
|
uri.append("car.gpx"); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
uri.append("car/shortest.gpx"); //$NON-NLS-1$
|
uri.append("car/shortest.gpx"); //$NON-NLS-1$
|
||||||
|
@ -442,10 +459,11 @@ public class RouteProvider {
|
||||||
log.info("URL route " + uri);
|
log.info("URL route " + uri);
|
||||||
URL url = new URL(uri.toString());
|
URL url = new URL(uri.toString());
|
||||||
URLConnection connection = url.openConnection();
|
URLConnection connection = url.openConnection();
|
||||||
GPXFile gpxFile = GPXUtilities.loadGPXFile(ctx, connection.getInputStream(), false);
|
GPXFile gpxFile = GPXUtilities.loadGPXFile(params.ctx, connection.getInputStream(), false);
|
||||||
directions = parseCloudmadeRoute(res, gpxFile, false, leftSide, speed);
|
directions = parseCloudmadeRoute(res, gpxFile, false, params.leftSide, speed);
|
||||||
|
|
||||||
return new RouteCalculationResult(res, directions, start, end, intermediates, null, ctx, leftSide, true);
|
return new RouteCalculationResult(res, directions, params.start, params.end, params.intermediates,
|
||||||
|
null, params.ctx, params.leftSide, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<RouteDirectionInfo> parseCloudmadeRoute(List<Location> res, GPXFile gpxFile, boolean osmandRouter,
|
private static List<RouteDirectionInfo> parseCloudmadeRoute(List<Location> res, GPXFile gpxFile, boolean osmandRouter,
|
||||||
|
@ -564,15 +582,14 @@ public class RouteProvider {
|
||||||
return directions;
|
return directions;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RouteCalculationResult findORSRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, Context ctx,
|
protected RouteCalculationResult findORSRoute(RouteCalcuationParams params) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError,
|
||||||
boolean leftSide) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError,
|
|
||||||
SAXException {
|
SAXException {
|
||||||
List<Location> res = new ArrayList<Location>();
|
List<Location> res = new ArrayList<Location>();
|
||||||
|
|
||||||
String rpref = "Fastest";
|
String rpref = "Fastest";
|
||||||
if (ApplicationMode.PEDESTRIAN == mode) {
|
if (ApplicationMode.PEDESTRIAN == params.mode) {
|
||||||
rpref = "Pedestrian";
|
rpref = "Pedestrian";
|
||||||
} else if (ApplicationMode.BICYCLE == mode) {
|
} else if (ApplicationMode.BICYCLE == params.mode) {
|
||||||
rpref = "Bicycle";
|
rpref = "Bicycle";
|
||||||
// } else if (ApplicationMode.LOWTRAFFIC == mode) {
|
// } else if (ApplicationMode.LOWTRAFFIC == mode) {
|
||||||
// rpref = "BicycleSafety";
|
// rpref = "BicycleSafety";
|
||||||
|
@ -582,13 +599,13 @@ public class RouteProvider {
|
||||||
// rpref = "BicycleRoute";
|
// rpref = "BicycleRoute";
|
||||||
// } else if (ApplicationMode.MTBIKE == mode) {
|
// } else if (ApplicationMode.MTBIKE == mode) {
|
||||||
// rpref = "BicycleMTB";
|
// rpref = "BicycleMTB";
|
||||||
} else if (!fast) {
|
} else if (!params.fast) {
|
||||||
rpref = "Shortest";
|
rpref = "Shortest";
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder request = new StringBuilder();
|
StringBuilder request = new StringBuilder();
|
||||||
request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(start.getLongitude()).append(',')
|
request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(params.start.getLongitude()).append(',')
|
||||||
.append(start.getLatitude()).append("&end=").append(end.getLongitude()).append(',').append(end.getLatitude())
|
.append(params.start.getLatitude()).append("&end=").append(params.end.getLongitude()).append(',').append(params.end.getLatitude())
|
||||||
.append("&preference=").append(rpref);
|
.append("&preference=").append(rpref);
|
||||||
// TODO if we would get instructions from the service, we could use this language setting
|
// TODO if we would get instructions from the service, we could use this language setting
|
||||||
// .append("&language=").append(Locale.getDefault().getLanguage());
|
// .append("&language=").append(Locale.getDefault().getLanguage());
|
||||||
|
@ -624,7 +641,7 @@ public class RouteProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true);
|
return new RouteCalculationResult(res, null, params.start, params.end, null, null, params.ctx, params.leftSide, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GPXFile createOsmandRouterGPX(RouteCalculationResult srcRoute){
|
public GPXFile createOsmandRouterGPX(RouteCalculationResult srcRoute){
|
||||||
|
|
|
@ -254,8 +254,8 @@ public class RoutingHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calculateRoute) {
|
if (calculateRoute) {
|
||||||
recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute,
|
recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, route.isCalculated() ? route
|
||||||
route.isCalculated()? route : null);
|
: null);
|
||||||
}
|
}
|
||||||
double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2;
|
double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2;
|
||||||
if(returnUpdatedLocation && locationProjection != null && currentLocation.distanceTo(locationProjection) < projectDist) {
|
if(returnUpdatedLocation && locationProjection != null && currentLocation.distanceTo(locationProjection) < projectDist) {
|
||||||
|
@ -569,24 +569,13 @@ public class RoutingHelper {
|
||||||
|
|
||||||
private class RouteRecalculationThread extends Thread implements Interruptable {
|
private class RouteRecalculationThread extends Thread implements Interruptable {
|
||||||
|
|
||||||
private final Location start;
|
|
||||||
private final LatLon end;
|
|
||||||
private final GPXRouteParams gpxRoute;
|
|
||||||
private final RouteCalculationResult previousRoute;
|
|
||||||
private RouteService service;
|
|
||||||
private boolean interrupted = false;
|
private boolean interrupted = false;
|
||||||
private final List<LatLon> intermediates;
|
private final RouteCalcuationParams params;
|
||||||
|
|
||||||
public RouteRecalculationThread(String name,
|
public RouteRecalculationThread(String name, RouteCalcuationParams params) {
|
||||||
Location start, LatLon end, List<LatLon> intermediates, GPXRouteParams gpxRoute, RouteCalculationResult previousRoute){
|
|
||||||
super(name);
|
super(name);
|
||||||
this.start = start;
|
this.params = params;
|
||||||
this.end = end;
|
params.interruptable = this;
|
||||||
this.intermediates = intermediates;
|
|
||||||
this.gpxRoute = gpxRoute;
|
|
||||||
this.previousRoute = previousRoute;
|
|
||||||
service = settings.ROUTER_SERVICE.getModeValue(mode);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopCalculation(){
|
public void stopCalculation(){
|
||||||
|
@ -600,10 +589,8 @@ public class RoutingHelper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
boolean leftSide = settings.LEFT_SIDE_NAVIGATION.get();
|
|
||||||
boolean fastRoute = settings.FAST_ROUTE_MODE.get();
|
RouteCalculationResult res = provider.calculateRouteImpl(params);
|
||||||
RouteCalculationResult res = provider.calculateRouteImpl(start, end, intermediates, mode, service, app, gpxRoute, previousRoute, fastRoute,
|
|
||||||
leftSide, this);
|
|
||||||
if (interrupted) {
|
if (interrupted) {
|
||||||
currentRunningJob = null;
|
currentRunningJob = null;
|
||||||
return;
|
return;
|
||||||
|
@ -611,7 +598,7 @@ public class RoutingHelper {
|
||||||
|
|
||||||
synchronized (RoutingHelper.this) {
|
synchronized (RoutingHelper.this) {
|
||||||
if (res.isCalculated()) {
|
if (res.isCalculated()) {
|
||||||
setNewRoute(res, start);
|
setNewRoute(res, params.start);
|
||||||
} else {
|
} else {
|
||||||
evalWaitInterval = evalWaitInterval * 3 / 2;
|
evalWaitInterval = evalWaitInterval * 3 / 2;
|
||||||
evalWaitInterval = Math.min(evalWaitInterval, 120000);
|
evalWaitInterval = Math.min(evalWaitInterval, 120000);
|
||||||
|
@ -622,7 +609,7 @@ public class RoutingHelper {
|
||||||
if (res.isCalculated()) {
|
if (res.isCalculated()) {
|
||||||
showMessage(app.getString(R.string.new_route_calculated_dist)
|
showMessage(app.getString(R.string.new_route_calculated_dist)
|
||||||
+ ": " + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), app)); //$NON-NLS-1$
|
+ ": " + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), app)); //$NON-NLS-1$
|
||||||
} else if (service != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) {
|
} else if (params.type != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) {
|
||||||
showMessage(app.getString(R.string.error_calculating_route)
|
showMessage(app.getString(R.string.error_calculating_route)
|
||||||
+ ":\n" + app.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG); //$NON-NLS-1$
|
+ ":\n" + app.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
|
@ -644,8 +631,20 @@ public class RoutingHelper {
|
||||||
if(currentRunningJob == null){
|
if(currentRunningJob == null){
|
||||||
// do not evaluate very often
|
// do not evaluate very often
|
||||||
if (System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval) {
|
if (System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval) {
|
||||||
|
RouteCalcuationParams params = new RouteCalcuationParams();
|
||||||
|
params.start = start;
|
||||||
|
params.end = end;
|
||||||
|
params.intermediates = intermediates;
|
||||||
|
params.gpxRoute = gpxRoute;
|
||||||
|
params.previousToRecalculate = previousRoute;
|
||||||
|
params.leftSide = settings.LEFT_SIDE_NAVIGATION.get();
|
||||||
|
params.optimal = settings.OPTIMAL_ROUTE_MODE.get();
|
||||||
|
params.fast = settings.FAST_ROUTE_MODE.get();
|
||||||
|
params.type = settings.ROUTER_SERVICE.getModeValue(mode);
|
||||||
|
params.mode = mode;
|
||||||
|
params.ctx = app;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
currentRunningJob = new RouteRecalculationThread("Calculating route", start, end, intermediates, gpxRoute, previousRoute); //$NON-NLS-1$
|
currentRunningJob = new RouteRecalculationThread("Calculating route", params); //$NON-NLS-1$
|
||||||
currentRunningJob.start();
|
currentRunningJob.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.Toast;
|
||||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -42,8 +43,12 @@ public class MonitoringInfoControl {
|
||||||
monitoringServices.setOnClickListener(new View.OnClickListener() {
|
monitoringServices.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
if(MonitoringInfoControl.this.monitoringServices.isEmpty()) {
|
||||||
|
Toast.makeText(view.getContext(), R.string.enable_plugin_monitoring_services, Toast.LENGTH_LONG).show();
|
||||||
|
} else {
|
||||||
showBgServiceQAction(monitoringServices, view, map);
|
showBgServiceQAction(monitoringServices, view, map);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return monitoringServices;
|
return monitoringServices;
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,6 +281,7 @@ bool readRouteTree(CodedInputStream* input, RouteSubregion* thisTree, RouteSubre
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OsmAndRoutingIndex_RouteDataBox::kBoxesFieldNumber: {
|
case OsmAndRoutingIndex_RouteDataBox::kBoxesFieldNumber: {
|
||||||
|
if (readChildren) {
|
||||||
RouteSubregion subregion;
|
RouteSubregion subregion;
|
||||||
readInt(input, &subregion.length);
|
readInt(input, &subregion.length);
|
||||||
subregion.filePointer = input->getTotalBytesRead();
|
subregion.filePointer = input->getTotalBytesRead();
|
||||||
|
@ -289,6 +290,11 @@ bool readRouteTree(CodedInputStream* input, RouteSubregion* thisTree, RouteSubre
|
||||||
input->PopLimit(oldLimit);
|
input->PopLimit(oldLimit);
|
||||||
input->Seek(subregion.filePointer + subregion.length);
|
input->Seek(subregion.filePointer + subregion.length);
|
||||||
thisTree->subregions.push_back(subregion);
|
thisTree->subregions.push_back(subregion);
|
||||||
|
} else {
|
||||||
|
if (!skipUnknownFields(input, tag)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -1310,11 +1316,10 @@ bool readRouteTreeData(CodedInputStream* input, RouteSubregion* s, std::vector<R
|
||||||
|
|
||||||
bool sortRouteRegions (const RouteSubregion& i,const RouteSubregion& j) { return (i.mapDataBlock<j.mapDataBlock); }
|
bool sortRouteRegions (const RouteSubregion& i,const RouteSubregion& j) { return (i.mapDataBlock<j.mapDataBlock); }
|
||||||
|
|
||||||
void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs){
|
void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub){
|
||||||
map<std::string, BinaryMapFile*>::iterator i = openFiles.begin();
|
map<std::string, BinaryMapFile*>::iterator i = openFiles.begin();
|
||||||
UNORDERED(set)<long long> ids;
|
UNORDERED(set)<long long> ids;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
bool basemapExists = false;
|
bool basemapExists = false;
|
||||||
for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) {
|
for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) {
|
||||||
BinaryMapFile* file = i->second;
|
BinaryMapFile* file = i->second;
|
||||||
|
@ -1326,19 +1331,10 @@ void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, Rout
|
||||||
if(rs != NULL && (rs->name != routingIndex->name || rs->filePointer != routingIndex->filePointer)){
|
if(rs != NULL && (rs->name != routingIndex->name || rs->filePointer != routingIndex->filePointer)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// check boundaries and init
|
|
||||||
|
// init decoding rules
|
||||||
if (routingIndex->decodingRules.size() == 0) {
|
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();
|
routingIndex->subregions.clear();
|
||||||
osmand_log_print(LOG_INFO, "Init native index %s", routingIndex->name.c_str());
|
|
||||||
lseek(file->routefd, 0, SEEK_SET);
|
lseek(file->routefd, 0, SEEK_SET);
|
||||||
FileInputStream input(file->routefd);
|
FileInputStream input(file->routefd);
|
||||||
input.SetCloseOnDelete(false);
|
input.SetCloseOnDelete(false);
|
||||||
|
@ -1349,10 +1345,8 @@ void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, Rout
|
||||||
uint32_t old = cis.PushLimit(routingIndex->length);
|
uint32_t old = cis.PushLimit(routingIndex->length);
|
||||||
readRoutingIndex(&cis, &(*routingIndex));
|
readRoutingIndex(&cis, &(*routingIndex));
|
||||||
cis.PopLimit(old);
|
cis.PopLimit(old);
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// could be simplified but it will be concurrency with init block
|
// could be simplified but it will be concurrency with init block
|
||||||
lseek(file->routefd, 0, SEEK_SET);
|
lseek(file->routefd, 0, SEEK_SET);
|
||||||
FileInputStream input(file->routefd);
|
FileInputStream input(file->routefd);
|
||||||
|
@ -1360,24 +1354,18 @@ void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, Rout
|
||||||
CodedInputStream cis(&input);
|
CodedInputStream cis(&input);
|
||||||
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2);
|
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2);
|
||||||
|
|
||||||
std::vector<RouteSubregion> toLoad;
|
|
||||||
searchRouteRegion(&cis, q, &(*routingIndex), routingIndex->subregions, toLoad, file);
|
|
||||||
sort(toLoad.begin(), toLoad.end(), sortRouteRegions);
|
|
||||||
|
|
||||||
std::vector<RouteDataObject*> iteration;
|
// cis.Seek(sub->filePointer);
|
||||||
int cnt = 0;
|
// uint32_t old = cis.PushLimit(sub->length);
|
||||||
for (std::vector<RouteSubregion>::iterator subreg = toLoad.begin(); subreg != toLoad.end(); subreg++) {
|
// readRouteTree(&cis, &(*sub), NULL, 0, true);
|
||||||
cis.Seek(subreg->filePointer + subreg->mapDataBlock);
|
// cis.PopLimit(old);
|
||||||
|
cis.Seek(sub->filePointer + sub->mapDataBlock);
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
cis.ReadVarint32(&length);
|
cis.ReadVarint32(&length);
|
||||||
uint32_t old = cis.PushLimit(length);
|
uint32_t old = cis.PushLimit(length);
|
||||||
readRouteTreeData(&cis, &(*subreg), iteration);
|
readRouteTreeData(&cis, &(*sub), list);
|
||||||
list.insert(list.end(), iteration.begin(), iteration.end());
|
|
||||||
iteration.clear();
|
|
||||||
cis.PopLimit(old);
|
cis.PopLimit(old);
|
||||||
}
|
}
|
||||||
std::vector<RouteDataObject*>::iterator rs = list.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,11 @@ struct SearchQuery {
|
||||||
ocean = mixed = false;
|
ocean = mixed = false;
|
||||||
}
|
}
|
||||||
SearchQuery(int l, int r, int t, int b) :
|
SearchQuery(int l, int r, int t, int b) :
|
||||||
req(req), left(l), right(r), top(t), bottom(b) {
|
left(l), right(r), top(t), bottom(b) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchQuery(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool publish(MapDataObject* obj) {
|
bool publish(MapDataObject* obj) {
|
||||||
|
@ -243,7 +247,7 @@ struct SearchQuery {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs = NULL);
|
void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub);
|
||||||
|
|
||||||
ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, std::string msgNothingFound);
|
ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, std::string msgNothingFound);
|
||||||
|
|
||||||
|
|
|
@ -398,6 +398,16 @@ jclass jclass_NativeRouteSearchResult = NULL;
|
||||||
jmethodID jmethod_NativeRouteSearchResult_init = NULL;
|
jmethodID jmethod_NativeRouteSearchResult_init = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
jclass jclass_RouteSubregion = NULL;
|
||||||
|
jfieldID jfield_RouteSubregion_length = NULL;
|
||||||
|
jfieldID jfield_RouteSubregion_filePointer= NULL;
|
||||||
|
jfieldID jfield_RouteSubregion_left = NULL;
|
||||||
|
jfieldID jfield_RouteSubregion_right = NULL;
|
||||||
|
jfieldID jfield_RouteSubregion_top = NULL;
|
||||||
|
jfieldID jfield_RouteSubregion_bottom = NULL;
|
||||||
|
jfieldID jfield_RouteSubregion_shiftToData = NULL;
|
||||||
|
|
||||||
|
|
||||||
void loadJniRenderingContext(JNIEnv* env)
|
void loadJniRenderingContext(JNIEnv* env)
|
||||||
{
|
{
|
||||||
jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext");
|
jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext");
|
||||||
|
@ -444,6 +454,17 @@ void loadJniRenderingContext(JNIEnv* env)
|
||||||
jfield_RouteDataObject_id = getFid(env, jclass_RouteDataObject, "id", "J" );
|
jfield_RouteDataObject_id = getFid(env, jclass_RouteDataObject, "id", "J" );
|
||||||
jmethod_RouteDataObject_init = env->GetMethodID(jclass_RouteDataObject, "<init>", "(Lnet/osmand/binary/BinaryMapRouteReaderAdapter$RouteRegion;[I[Ljava/lang/String;)V");
|
jmethod_RouteDataObject_init = env->GetMethodID(jclass_RouteDataObject, "<init>", "(Lnet/osmand/binary/BinaryMapRouteReaderAdapter$RouteRegion;[I[Ljava/lang/String;)V");
|
||||||
|
|
||||||
|
|
||||||
|
jclass_RouteSubregion = findClass(env, "net/osmand/binary/BinaryMapRouteReaderAdapter$RouteSubregion");
|
||||||
|
jfield_RouteSubregion_length= getFid(env, jclass_RouteSubregion, "length", "I" );
|
||||||
|
jfield_RouteSubregion_filePointer= getFid(env, jclass_RouteSubregion, "filePointer", "I" );
|
||||||
|
jfield_RouteSubregion_left= getFid(env, jclass_RouteSubregion, "left", "I" );
|
||||||
|
jfield_RouteSubregion_right= getFid(env, jclass_RouteSubregion, "right", "I" );
|
||||||
|
jfield_RouteSubregion_top= getFid(env, jclass_RouteSubregion, "top", "I" );
|
||||||
|
jfield_RouteSubregion_bottom= getFid(env, jclass_RouteSubregion, "bottom", "I" );
|
||||||
|
jfield_RouteSubregion_shiftToData= getFid(env, jclass_RouteSubregion, "shiftToData", "I" );
|
||||||
|
// public final RouteRegion routeReg;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc)
|
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, JNIRenderingContext* rc)
|
||||||
|
@ -565,17 +586,25 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_getRoute
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int fpointer, int left, int right, int top, int bottom,
|
//protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int regfp, RouteSubregion subreg,
|
||||||
// boolean loadObjects!);
|
// boolean loadObjects);
|
||||||
extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_NativeLibrary_loadRoutingData(JNIEnv* ienv,
|
extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_NativeLibrary_loadRoutingData(JNIEnv* ienv,
|
||||||
jobject obj, jobject reg, jstring regName, jint filepointer, jint left, jint right, jint top, jint bottom, jboolean loadObjects) {
|
jobject obj, jobject reg, jstring regName, jint regFilePointer,
|
||||||
|
jobject subreg, jboolean loadObjects) {
|
||||||
RoutingIndex ind;
|
RoutingIndex ind;
|
||||||
ind.filePointer = filepointer;
|
ind.filePointer = regFilePointer;
|
||||||
ind.name = getString(ienv, regName);
|
ind.name = getString(ienv, regName);
|
||||||
|
RouteSubregion sub;
|
||||||
|
sub.filePointer = ienv->GetIntField(subreg, jfield_RouteSubregion_filePointer);
|
||||||
|
sub.length = ienv->GetIntField(subreg, jfield_RouteSubregion_length);
|
||||||
|
sub.left = ienv->GetIntField(subreg, jfield_RouteSubregion_left);
|
||||||
|
sub.right = ienv->GetIntField(subreg, jfield_RouteSubregion_right);
|
||||||
|
sub.top = ienv->GetIntField(subreg, jfield_RouteSubregion_top);
|
||||||
|
sub.bottom = ienv->GetIntField(subreg, jfield_RouteSubregion_bottom);
|
||||||
|
sub.mapDataBlock= ienv->GetIntField(subreg, jfield_RouteSubregion_shiftToData);
|
||||||
std::vector<RouteDataObject*> result;
|
std::vector<RouteDataObject*> result;
|
||||||
SearchQuery q(left, right, top, bottom);
|
SearchQuery q;
|
||||||
searchRouteRegion(&q, result, &ind);
|
searchRouteRegion(&q, result, &ind, &sub);
|
||||||
|
|
||||||
|
|
||||||
if (loadObjects) {
|
if (loadObjects) {
|
||||||
|
|
Loading…
Reference in a new issue