BRouter: offline Fahrrad-Routing für Android

Super Arndt.
Wenn du mir jetzt noch verraten tust, welche Datei man in Osmand hacken muß, wo sie zu finden ist und welche Zeile durch was zu ersetzen ist.LG Volker

Suche mal nach “www.yournavigation.org/api/1.0/gosmore.php?format=kml” in den Java-Dateien und ersetze das durch “h2096617.stratoserver.net:7777/brouter?format=kml”.

Ich bin wieder einen schönen Schritt weiter, indem ich diesen “Online-Dienst” auf dem Telefon laufen lasse, womit es dann natürlich ein Offline-Dienst wird, aber das ist ja mein Ziel, eine voll-konfigurierbare Offline-Lösung zu schaffen, weshalb ich über diese Online-Spielereien auch garnicht so viel reden wollte. Insbesondere die Möglichkeit, in einem integrierten Routing mit automatischer Neuberechnung auch Sperrgebiete zu berücksichtigen hatte ich vorher nicht. Das geht jetzt.

Das ist schon ganz cool, und ich habe dazu dier Version BRouter 0.9.1 deployed, die diesen Android Dienst startet. Der notwendige Patch zu OsmAnd ist aber leider immer noch nur Hackern zugänglich, funktioniert wie oben beschrieben, nur dass es statt “h2096617.stratoserver.net:7777” dann “localhost:17777” heisst, damit OsmAnd auf einen lokal laufenden Service zugreift.

Ich habe selber von einem cleveren User eine Anleitung bekommen, wie man den Patch mit dem “apktool” hinkriegt, ohne OsmAnd wirklich von den Sourcen bauen zu müssen.

Ich würde ja gerne ein gepatches OsmAnd APK zur Verfügung stellen, aber das lässt die Lizenz wohl nicht zu.

Das mit dem Offline interface ist ein “uraltes” Thema (alt gemessem am Tempo der Entwicklung auf diesem Feld), siehe hier:

https://groups.google.com/forum/?fromgroups#!topic/osmand/paCDL5_xHkk

https://groups.google.com/forum/?fromgroups#!msg/osmand/CTwTvlKSHKQ/Bz98kmpxxD0J

Und das Thema ist auch noch nicht zu Ende, ein “entgültiges” Offline-Interface, was dann auch in die OsmAnd releases eingehen könnte, braucht sicher noch bisschen Hirnschmalz, und insbesondere die schnelle, partielle Neuberechnung, die ich unter dem Zwiten dieser Links mal beschrieben hatte, die muss ich jetzt endlich mal machen.

Hallo,

darf ich mal kurz dazwischen funken?

Kann man den BRouter nicht unter Verwendung der “INTENTS” -Schnittstelle mit OruxMaps “verheiraten”. Da steht zum Beispiel im Manual unter anderem folgendes:

OruxMaps INTEGRATION

…You can also show a route based on a set of points and / or waypoints:
//Offline map on current position
//Intent i = new Intent("com.oruxmaps. VIEW_MAP_OFFLINE ");
//Online map
Intent i = new Intent(“com.oruxmaps.VIEW_MAP_ONLINE”);
//Waypoints
double[] targetLat = {33.4,8.3,22.2};
double [] targetLon = {33.4,8.3,22.3};
String [] targetNames = {“point alpha”,“point beta”};
i.putExtra(“targetLat”, targetLat);
i.putExtra(“targetLon”, targetLon);
i.putExtra(“targetName”, targetNames);
//Track points
double[] targetLatPoints = {33.43,8.32,22.24};

Ich habe aber keine Ahnung was Intents sind. Mit diesen kann man wohl ein Programm von einem anderen Programm fernsteuern, falls ich das richtig verstanden habe. Eventuell kann man dort im Forum erforderliche Intents vorschlagen, um BRouter nahtlos zu integrieren

…oder liege ich da voll daneben?
…dann SORRY…

Viele Grüsse
Achim

Nein, genau richtig. Es geht darum, die HTTP-Schnittstelle durch eine zu ersetzen, die zum Android Programmiermodell passt. Intents sind dabei nur die Nachrichten samt Empfaengeradresse, die da ausgetauscht werden, eine Schnittstelle wäre z.B. ein “Bound Service”. Hat gegenüber meine jetztigen Implementierung auch so Vorteile, dass man den Dienst nicht starten muss (sondern das macht der anfragende Client implizit) und dass man einen Auswahldialog bekommt, wenn es mehrere Implementierungen für einen angefragten Dienst (hier: Routenberechnung) gibt. Aber ich bin da noch im unteren Teil der Lernkurve…

Gruss, Arndt

PS: tolle E-Bike Runde heute durch den Odenwald, 60km/600 Höhenmeter und ich hab’s vorher gewusst und der Akku hat gehalten :slight_smile:

Kein Glück hier mit dem Server-Mode auf Android, BRouter schmiert nach wenigen Sekunden mit “BRouter angehalten” und irgendeiner NullPointerException bei RouterService onStart-irgendwas ab (sieht man nur in logcat, andere Log-Dateien habe ich vergeblich gesucht). Beim Start kommt zunächst noch eine Liste, in der man ein Profil auswählen kann, dann eine Meldung, dass keine from/to-Knoten für Locus definiert wurde. Hier wähle ich “Server-Modus”. Es erscheint eine kurze Meldung dass der Server-Modus gestartet wurde, dann folgt recht schnell der Absturz. Keine Ahnung, was da los ist, bei mir funktioniert es jedenfalls nicht.

Also ich habe gestern mal versucht, die Zeile zu ersetzen. Ich weiß nicht mal, wo ich nach was für einer Datei ich suchen muss.

Kann man nicht ein kleines Programm schreiben, was die Zeile ersetzt. Ähnlich wie Map Tweak für Locus https://play.google.com/store/apps/details?id=com.mjk.locusmaptweak&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5tamsubG9jdXNtYXB0d2VhayJd

Es geht um diese Zeile in der Klasse RouteProvider. Das Kompilieren von Quellen ist hier recht detailliert beschrieben. Ich gehe mal davon aus, dass du dir das freiwillig nicht antun willst.

Nein nicht wirklich.

Ich habe eigentlich keine Ahnung von Android. Deswegen kann ich auch nicht beurteilen, was dieser MapTweak bei Locus wirklich macht. Die Frage ist, ob man das Kompilieren nicht mit einer Art Patch umgehen könnte. Denn bei jeder Verionsänderung von Osmand neu zu kompilieren, ist auch nicht sehr produktiv.

Eigentlich dachte ich mir, ich müsste eine Datei auf meinem Telephon mit einem Texteditor öffnen und umschreiben. Mir war/ist unklar, wo die Datei überhaupt zu finden wäre. Also ähnlich wie bei Windows die EXE-Dateien.

In einer APK-Datei (die eine ZIP-Datei ist und nur anders heisst) sind die compilierten Java-Klassen alle in der Date “classes.dex” in übersetzer Form enthalten. Es gibt mächtige Tools, um APKs zu modifizieren, die “classes.dex” zu disassemblieren in so einer Art Assembler-Code ( “smali”-Dateien, die man lesen und verändern kan), das ganze wieder zu re-assemblieren und anschliessend neu zu signieren.

(Einfach mal googeln nach "apktool, smali, baksmali, APK Manager 5.0.2 und so)

So in der Art hatte ich das gemacht. Das ist zwar eine nette Spielerei, aber es lohnt sich nicht, irgendwas geht dann doch immer nicht.

Ich muss jetzt einfach mich doch mal durchbeissen, den OsmAnd Source-Build hinbekommen, ein vernünftiges Interface entwickeln und als GIT-Pull-Request ins OsmAnd Release bekommen. Victor sperrt sich ja nicht, obwohl das ja zu befürchten wäre, dass sie OsmAnd abschotten wollen gegen externe Router, aber ich glaube, das ist nicht der Fall, also mach ich’s jetzt einfach richtig, dauert halt nur noch bisschen.

Schaust Du dir die NullPointerException in Post #97 noch an, brauchst Du noch mehr Details? Ich hatte 3-4h für einen funktionsfähigen OsmAnd Source-Build investiert, nur um dann festzustellen, dass BRouter bei mir nicht im Server-Modus läuft. Wirklich sehr ärgerlich, dabei wollte ich den Router doch gerne mal testen.

Hallo Arndt,

planst du auch eine nahtlose Integration in OruxMaps mit Hilfe der Intents ? OSMAND hat ja schon ein Routing drin, was aber bei OruxMaps noch (?) fehlt. Da wäre der BRouter eine wirkliche sinnvolle Ergänzung.

Viele Grüsse
Achim

Ich komme erst am Sonntag wieder dazu.

Hast Du denn einen Stacktrace? Und welche Android Version? Bei mir läuft es auf 2.3.6 stabil, während ich bei 4.0.1 eher mal eine vorzeitgen Dienst-Stop kriege, was aber nicht wirklich ein Fehler ist, weil Android darf das.

Ich hab’ Dir einen Download-Link geschickt für die BRouter-Sourcen, vielleicht magst Du’s ja selber mal im Debugger laufen lassen. Der Dienst, um den es geht, ist in der Klasse BRouterService.

Ich könnte den folgenden Stacktrace anbieten, den ich mit adb logcat eingesammelt habe. Vielleicht ist das einfach irgendein dummer Folgefehler, weil irgendwas in meiner Umgebung nicht stimmt oder vergessen wurde zu installieren und damit RouteServer nicht sauber instantiiert werden konnte? Leider habe ich ansonsten keine Meldung gefunden, die mich weitergebracht hätte. Getestet hatte ich BRouter mit Android 4.1.2.


/dalvikvm(30137): threadid=1: thread exiting with uncaught exception (group=0x40d412a0)
E/AndroidRuntime(30137): FATAL EXCEPTION: main
E/AndroidRuntime(30137): java.lang.RuntimeException: Unable to start service btools.routingapp.BRouterService@41a27468 with null: java.lang.NullPointerException
E/AndroidRuntime(30137): 	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2548)
E/AndroidRuntime(30137): 	at android.app.ActivityThread.access$1900(ActivityThread.java:140)
E/AndroidRuntime(30137): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1324)
E/AndroidRuntime(30137): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(30137): 	at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(30137): 	at android.app.ActivityThread.main(ActivityThread.java:4898)
E/AndroidRuntime(30137): 	at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(30137): 	at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(30137): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
E/AndroidRuntime(30137): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
E/AndroidRuntime(30137): 	at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(30137): Caused by: java.lang.NullPointerException
E/AndroidRuntime(30137): 	at btools.routingapp.BRouterService.onStartCommand(BRouterService.java:42)
E/AndroidRuntime(30137): 	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2531)
E/AndroidRuntime(30137): 	... 10 more

Mail geht übrigens am besten über OSM Nachricht senden, den Forum-Mailer habe ich nicht aktiv.

Danke, da wird Service.onStartCommand mit einem null-intent gerufen und die API sieht das wohl auch vor (wenn Android einen Dienst re-instanziert auf einem neuen Prozess, auch wenn ich nicht verstehe, warum Android das tun sollte)

Hab’ jetzt bisschen dran geschraubt, (Version 0.9.2) so dass es zumindest anders ist (REDELIVER_INTENT, own process, null-check) und auf meinen beiden Geräten getestet, ich krieg nach wie vor paar störende Dienst-Stops auf dem Android-4 Gerät, aber wie gesagt, das liegt einfach am System, davon abgesehen läuft es bei mir stabil.

Vielleicht gibst Du dem nochmal einen Versuch.

Mit meinem eigentlichen Plan, ein neues, besseres, Interface zu implementieren, bin ich noch nicht weitergekommen.

Den Source-Link habe ich auch erneuert und an Deine bevorzugte Postbox geschickt.

Gruss, Arndt

Wir versuchten gerade mit BRouter offline Fahrrad-Routing für Android von den Koordinaten Freiburg Hbf From-Latitude 47.999160°N From-Longitude 7.843040°E nach München Hbf To-Latitude 48.140232°N To-Longitude 11.558335°E eine etwas längere Route zu erstellen. Obwohl bei uns die Dateien E5_N45.rd5, E5_N50.rd5, E10_N45.rd5, E10_N50.rd5 hinterlegt sind, erhalten wir die Meldung “An Error occured, multiple from-positions!(coodinate-source” angezeigt. Für kleinere Routing funktioniert BRouter ohne Probleme. Mit der online Version von BRouter erhalten wir die Meldung “Fehler: Datei http://h2096617.stratoserver.net/cgi-bin/brouter.sh?7.843040_47.999160_11.558335_48.140232_trekking_0 kann nicht abgerufen werden. Status: .” angezeigt. Woran könnte es liegen, dass die Fehlermeldung bei uns erscheint? Ist die Route etwas zu lange?

“multiple from-positions” hat mit der Länge der Route nichts zu tun, es heisst, dass der “from” (und/oder “to”) Wegpunkt mehrfach vorhanden ist. Einfach nochmal alle löschen und neu anlegen.

Bei “View Route” ist der Timeout ziemlich kurz und auch nicht von mir gemacht, sondern von dem Trackviewer.

Wenn Du “Download GPX” benutzt, ist der Timeout 30 Minuten, also solange da keiner dazwischenfunkt (jede neue Berechnung schiesst die laufende ab!) kann man da auch lange Routen mit ausrechnen.

Dein Beispiel hab ich eben mal gerechnet und das ging in wenigen Minuten (384 km, 1755 Höhenmeter).

Die GPX Datei musst Du dann lokal speiechern und in einem beliebigen Trackviewer ansehen (z.B. hier: http://www.gpswandern.de/gpxviewer/gpxviewer.shtml )

Ok, die offline App BRouter startet nun ohne Fehlermeldung. Wir hatten einfach vergessen die alten Werte unter OruxMaps zu löschen. Wenn wir jetzt allerdings mit dem Routing Profil car-test die Berechnung starten, stürzt die App nach ca. über Links: 510000 in 659s (772 l/s) immer ab. Woran könnte dies liegen?

Es ist ein Speicherüberlauf. Das Problem ist allerdings speziell für das car-routing, weil meine Caching-Architektur mit dem Fall nicht klarkommt, dass in dem Profil nur über den kleineren Teil der Nodes geroutet werden kann, die anderen Nodes bleiben dann quasi in der Pipleline hängen und verschwinden nicht mehr aus dem Memory (Die selbe Strecke mit “trekking-steep” schafft mein Handy anstandslos in 20 Minuten.)

Ich denke mal drüber nach. Also die triviale Lösung ist natürlich, für’s Car-Routing eigene Datefiles zu erzeugen, in denen die Feldwege garnicht drin sind (so machens die anderen ja auch) aber das widerspricht dem Konzept eines voll konfigurierbaren Routers. Vielleicht fällt mir aber auch was klügeres ein.

Für den Online-Dienst habe ich den Speicher jetzt mal auf 128 MB hochgesetzt, damit kannst Du Dir die Strecke ausrechnen. Mit den 24 MB, die Android einem Prozess zugesteht, geht car-test auf der Strecke leider (noch) nicht.

Hallo Arndt,

wird es für Deine Online-Version auch irgendwann via-Punkte geben?

Viele Grüße :smiley: