diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl index ca19b48c83..92115f873b 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl @@ -92,6 +92,9 @@ import net.osmand.aidlapi.copyfile.CopyFileParams; import net.osmand.aidlapi.navigation.ANavigationUpdateParams; import net.osmand.aidlapi.navigation.ANavigationVoiceRouterMessageParams; +import net.osmand.aidlapi.navigation.ABlockedRoad; +import net.osmand.aidlapi.navigation.AddBlockedRoadParams; +import net.osmand.aidlapi.navigation.RemoveBlockedRoadParams; import net.osmand.aidlapi.contextmenu.ContextMenuButtonsParams; import net.osmand.aidlapi.contextmenu.UpdateContextMenuButtonsParams; @@ -892,4 +895,10 @@ interface IOsmAndAidlInterface { boolean selectProfile(in SelectProfileParams params); boolean getProfiles(out List profiles); + + boolean getBlockedRoads(out List blockedRoads); + + boolean addRoadBlock(in AddBlockedRoadParams params); + + boolean removeRoadBlock(in RemoveBlockedRoadParams params); } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/ABlockedRoad.aidl b/OsmAnd-api/src/net/osmand/aidlapi/navigation/ABlockedRoad.aidl new file mode 100644 index 0000000000..23c31596d5 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/ABlockedRoad.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidlapi.navigation; + +parcelable ABlockedRoad; \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/ABlockedRoad.java b/OsmAnd-api/src/net/osmand/aidlapi/navigation/ABlockedRoad.java new file mode 100644 index 0000000000..e83f64334b --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/ABlockedRoad.java @@ -0,0 +1,85 @@ +package net.osmand.aidlapi.navigation; + +import android.os.Bundle; +import android.os.Parcel; + +import net.osmand.aidlapi.AidlParams; + +public class ABlockedRoad extends AidlParams { + + private long roadId; + private double latitude; + private double longitude; + private double direction; + private String name; + private String appModeKey; + + public ABlockedRoad(long roadId, double latitude, double longitude, double direction, String name, String appModeKey) { + this.roadId = roadId; + this.latitude = latitude; + this.longitude = longitude; + this.direction = direction; + this.name = name; + this.appModeKey = appModeKey; + } + + protected ABlockedRoad(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public ABlockedRoad createFromParcel(Parcel in) { + return new ABlockedRoad(in); + } + + @Override + public ABlockedRoad[] newArray(int size) { + return new ABlockedRoad[size]; + } + }; + + public long getRoadId() { + return roadId; + } + + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + + public double getDirection() { + return direction; + } + + public String getName() { + return name; + } + + public String getAppModeKey() { + return appModeKey; + } + + @Override + protected void readFromBundle(Bundle bundle) { + roadId = bundle.getLong("roadId"); + latitude = bundle.getDouble("latitude"); + longitude = bundle.getDouble("longitude"); + direction = bundle.getDouble("direction"); + name = bundle.getString("name"); + appModeKey = bundle.getString("appModeKey"); + } + + @Override + public void writeToBundle(Bundle bundle) { + bundle.putLong("roadId", roadId); + bundle.putDouble("latitude", latitude); + bundle.putDouble("longitude", longitude); + bundle.putDouble("direction", direction); + bundle.putString("name", name); + bundle.putString("appModeKey", appModeKey); + } +} \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/AddBlockedRoadParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/navigation/AddBlockedRoadParams.aidl new file mode 100644 index 0000000000..5eb74b0b53 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/AddBlockedRoadParams.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidlapi.navigation; + +parcelable AddBlockedRoadParams; diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/AddBlockedRoadParams.java b/OsmAnd-api/src/net/osmand/aidlapi/navigation/AddBlockedRoadParams.java new file mode 100644 index 0000000000..b64a9d32ce --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/AddBlockedRoadParams.java @@ -0,0 +1,46 @@ +package net.osmand.aidlapi.navigation; + +import android.os.Bundle; +import android.os.Parcel; + +import net.osmand.aidlapi.AidlParams; + +public class AddBlockedRoadParams extends AidlParams { + + private ABlockedRoad blockedRoad; + + public AddBlockedRoadParams(ABlockedRoad blockedRoad) { + this.blockedRoad = blockedRoad; + } + + public AddBlockedRoadParams(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public AddBlockedRoadParams createFromParcel(Parcel in) { + return new AddBlockedRoadParams(in); + } + + @Override + public AddBlockedRoadParams[] newArray(int size) { + return new AddBlockedRoadParams[size]; + } + }; + + public ABlockedRoad getBlockedRoad() { + return blockedRoad; + } + + @Override + public void writeToBundle(Bundle bundle) { + bundle.putParcelable("blockedRoad", blockedRoad); + } + + @Override + protected void readFromBundle(Bundle bundle) { + bundle.setClassLoader(ABlockedRoad.class.getClassLoader()); + blockedRoad = bundle.getParcelable("blockedRoad"); + } +} \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateGpxParams.java b/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateGpxParams.java index 8b4901b35e..e6fad0c1b1 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateGpxParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateGpxParams.java @@ -11,15 +11,18 @@ public class NavigateGpxParams extends AidlParams { private String data; private Uri uri; private boolean force; + private boolean needLocationPermission; - public NavigateGpxParams(String data, boolean force) { + public NavigateGpxParams(String data, boolean force, boolean needLocationPermission) { this.data = data; this.force = force; + this.needLocationPermission = needLocationPermission; } - public NavigateGpxParams(Uri uri, boolean force) { + public NavigateGpxParams(Uri uri, boolean force, boolean needLocationPermission) { this.uri = uri; this.force = force; + this.needLocationPermission = needLocationPermission; } public NavigateGpxParams(Parcel in) { @@ -50,11 +53,16 @@ public class NavigateGpxParams extends AidlParams { return force; } + public boolean isNeedLocationPermission() { + return needLocationPermission; + } + @Override public void writeToBundle(Bundle bundle) { bundle.putString("data", data); bundle.putParcelable("uri", uri); bundle.putBoolean("force", force); + bundle.putBoolean("needLocationPermission", needLocationPermission); } @Override @@ -62,5 +70,6 @@ public class NavigateGpxParams extends AidlParams { data = bundle.getString("data"); uri = bundle.getParcelable("uri"); force = bundle.getBoolean("force"); + needLocationPermission = bundle.getBoolean("needLocationPermission"); } } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateParams.java b/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateParams.java index 6dff82b7e4..ad83489f17 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateParams.java @@ -17,8 +17,10 @@ public class NavigateParams extends AidlParams { private double destLon; private boolean force; + private boolean needLocationPermission; - public NavigateParams(String startName, double startLat, double startLon, String destName, double destLat, double destLon, String profile, boolean force) { + public NavigateParams(String startName, double startLat, double startLon, String destName, double destLat, + double destLon, String profile, boolean force, boolean needLocationPermission) { this.startName = startName; this.startLat = startLat; this.startLon = startLon; @@ -27,6 +29,7 @@ public class NavigateParams extends AidlParams { this.destLon = destLon; this.profile = profile; this.force = force; + this.needLocationPermission = needLocationPermission; } public NavigateParams(Parcel in) { @@ -77,6 +80,10 @@ public class NavigateParams extends AidlParams { return force; } + public boolean isNeedLocationPermission() { + return needLocationPermission; + } + @Override public void writeToBundle(Bundle bundle) { bundle.putString("startName", startName); @@ -87,6 +94,7 @@ public class NavigateParams extends AidlParams { bundle.putDouble("destLon", destLon); bundle.putString("profile", profile); bundle.putBoolean("force", force); + bundle.putBoolean("needLocationPermission", needLocationPermission); } @Override @@ -99,5 +107,6 @@ public class NavigateParams extends AidlParams { destLon = bundle.getDouble("destLon"); profile = bundle.getString("profile"); force = bundle.getBoolean("force"); + needLocationPermission = bundle.getBoolean("needLocationPermission"); } } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateSearchParams.java b/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateSearchParams.java index d548dab2f3..a5edc7524c 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateSearchParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/NavigateSearchParams.java @@ -17,10 +17,11 @@ public class NavigateSearchParams extends AidlParams { private double searchLon; private boolean force; + private boolean needLocationPermission; public NavigateSearchParams(String startName, double startLat, double startLon, - String searchQuery, double searchLat, double searchLon, - String profile, boolean force) { + String searchQuery, double searchLat, double searchLon, + String profile, boolean force, boolean needLocationPermission) { this.startName = startName; this.startLat = startLat; this.startLon = startLon; @@ -29,6 +30,7 @@ public class NavigateSearchParams extends AidlParams { this.searchLon = searchLon; this.profile = profile; this.force = force; + this.needLocationPermission = needLocationPermission; } public NavigateSearchParams(Parcel in) { @@ -79,6 +81,10 @@ public class NavigateSearchParams extends AidlParams { return force; } + public boolean isNeedLocationPermission() { + return needLocationPermission; + } + @Override public void writeToBundle(Bundle bundle) { bundle.putString("startName", startName); @@ -89,6 +95,7 @@ public class NavigateSearchParams extends AidlParams { bundle.putBoolean("force", force); bundle.putDouble("searchLat", searchLat); bundle.putDouble("searchLon", searchLon); + bundle.putBoolean("needLocationPermission", needLocationPermission); } @Override @@ -101,5 +108,6 @@ public class NavigateSearchParams extends AidlParams { force = bundle.getBoolean("force"); searchLat = bundle.getDouble("searchLat"); searchLon = bundle.getDouble("searchLon"); + needLocationPermission = bundle.getBoolean("needLocationPermission"); } } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/RemoveBlockedRoadParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/navigation/RemoveBlockedRoadParams.aidl new file mode 100644 index 0000000000..02c9f36f0c --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/RemoveBlockedRoadParams.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidlapi.navigation; + +parcelable RemoveBlockedRoadParams; diff --git a/OsmAnd-api/src/net/osmand/aidlapi/navigation/RemoveBlockedRoadParams.java b/OsmAnd-api/src/net/osmand/aidlapi/navigation/RemoveBlockedRoadParams.java new file mode 100644 index 0000000000..1cb4e2e6a5 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/navigation/RemoveBlockedRoadParams.java @@ -0,0 +1,46 @@ +package net.osmand.aidlapi.navigation; + +import android.os.Bundle; +import android.os.Parcel; + +import net.osmand.aidlapi.AidlParams; + +public class RemoveBlockedRoadParams extends AidlParams { + + private ABlockedRoad blockedRoad; + + public RemoveBlockedRoadParams(ABlockedRoad blockedRoad) { + this.blockedRoad = blockedRoad; + } + + public RemoveBlockedRoadParams(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public RemoveBlockedRoadParams createFromParcel(Parcel in) { + return new RemoveBlockedRoadParams(in); + } + + @Override + public RemoveBlockedRoadParams[] newArray(int size) { + return new RemoveBlockedRoadParams[size]; + } + }; + + public ABlockedRoad getBlockedRoad() { + return blockedRoad; + } + + @Override + public void writeToBundle(Bundle bundle) { + bundle.putParcelable("blockedRoad", blockedRoad); + } + + @Override + protected void readFromBundle(Bundle bundle) { + bundle.setClassLoader(ABlockedRoad.class.getClassLoader()); + blockedRoad = bundle.getParcelable("blockedRoad"); + } +} \ No newline at end of file diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java index 5e45a893ba..f0b26d09e8 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java @@ -1538,9 +1538,20 @@ public class BinaryMapIndexReader { return request; } - - public static SearchRequest buildSearchRouteRequest(int sleft, int sright, int stop, int sbottom, - ResultMatcher matcher){ + + public static SearchRequest buildSearchPoiRequest(LatLon latLon, int radius, int zoom, + SearchPoiTypeFilter poiTypeFilter, + ResultMatcher matcher) { + SearchRequest request = new SearchRequest<>(); + request.setBBoxRadius(latLon.getLatitude(), latLon.getLongitude(), radius); + request.zoom = zoom; + request.poiTypeFilter = poiTypeFilter; + request.resultMatcher = matcher; + return request; + } + + public static SearchRequest buildSearchRouteRequest(int sleft, int sright, int stop, int sbottom, + ResultMatcher matcher) { SearchRequest request = new SearchRequest(); request.left = sleft; request.right = sright; @@ -1557,6 +1568,10 @@ public class BinaryMapIndexReader { } public static SearchRequest buildSearchPoiRequest(int x, int y, String nameFilter, int sleft, int sright, int stop, int sbottom, ResultMatcher resultMatcher, ResultMatcher rawDataCollector) { + return buildSearchPoiRequest(x, y, nameFilter, sleft, sright, stop, sbottom, null, resultMatcher, null); + } + + public static SearchRequest buildSearchPoiRequest(int x, int y, String nameFilter, int sleft, int sright, int stop, int sbottom, SearchPoiTypeFilter poiTypeFilter, ResultMatcher resultMatcher, ResultMatcher rawDataCollector) { SearchRequest request = new SearchRequest(); request.x = x; request.y = y; @@ -1564,6 +1579,7 @@ public class BinaryMapIndexReader { request.right = sright; request.top = stop; request.bottom = sbottom; + request.poiTypeFilter = poiTypeFilter; request.resultMatcher = resultMatcher; request.rawDataCollector = rawDataCollector; request.nameQuery = nameFilter.trim(); diff --git a/OsmAnd/assets/bundled_assets.xml b/OsmAnd/assets/bundled_assets.xml index 9b69d7250c..d5626ac886 100644 --- a/OsmAnd/assets/bundled_assets.xml +++ b/OsmAnd/assets/bundled_assets.xml @@ -8,6 +8,7 @@ + diff --git a/OsmAnd/res/values-ar/phrases.xml b/OsmAnd/res/values-ar/phrases.xml index 5b5499949f..a369c15aab 100644 --- a/OsmAnd/res/values-ar/phrases.xml +++ b/OsmAnd/res/values-ar/phrases.xml @@ -3364,8 +3364,8 @@ الرابط أماكن لوقوف السيارات قبر - جنس المجتمع: ذكر - جنس المجتمع: أنثى + نوع المجتمع: ذكر + نوع المجتمع: أنثى لا نعم حمام القدم @@ -3659,4 +3659,17 @@ حطام سفينة حجر الشاهد القائم الروني دبابة تاريخية + بحيرة + نهر + بئر + مضخة + خزان مياه + حنفية + أعمال مياه + شيب مياه + لقاح كورونا COVID19 + يتوفر لدهم لقاح + منصة الانقاذ + صفارت إنذار + نوع المجتمع: مختلط \ No newline at end of file diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml index 5fa56c8b47..5406e3a1e1 100644 --- a/OsmAnd/res/values-de/phrases.xml +++ b/OsmAnd/res/values-de/phrases.xml @@ -1528,8 +1528,8 @@ Baden: ja Baden: nein Bootslager - Brücke Nr. - Tunnel Nr. + Bauwerksnummer + Bauwerksnummer Nr. Passagiere Fahrzeuge @@ -3889,4 +3889,16 @@ Rettungsschwimmerbasis Impfung: COVID19 Impfung + Rammbrunnen + See + Fluss + Brunnen + Angetriebene Pumpe + Wassertank + Wasserhahn + Wasserwerk + Waschplatz für Wäsche + Müllumladestation + Fahrzeugwaage + Rangerstation \ No newline at end of file diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index f8133d7c17..7ec31aa8a6 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -562,7 +562,7 @@ Sprachansagen Sprachansage Vektorkarten wurden nicht geladen - GPX-Daten konnten nicht gelesen werden + GPX-Daten konnten nicht gelesen werden. Offline-Vektorkarten Suche nach Verbindung an Haltestelle Bearbeite POI @@ -1960,7 +1960,7 @@ Relative Peilung Zeit zwischen automatischen Ansagen Magnetische Peilung - Ziel ist nicht festgelegt + Modul für Bedienungshilfen: Ziel ist nicht festgelegt OsmAnd-Live-Navigation Akkustand Karte bewegen, um die Position der Markierung zu verändern @@ -2170,7 +2170,7 @@ Karten-Overlay wurde in „%s“ geändert. Karten-Underlay wurde in „%s“ geändert. Ungültiger OLC - +\n Kurzer OLC \nBitte geben Sie einen vollständigen Code ein Gültiger vollständiger OLC @@ -3520,7 +3520,7 @@ Das importierte Profil enthält zusätzliche Daten. Klicken Sie auf \"Importieren\", um nur Profildaten zu importieren, oder wählen Sie zusätzliche Daten aus. Sie können zusätzliche Daten zum Exportieren zusammen mit dem Profil auswählen. Antarktis - Sie können alle Ihre noch nicht hochgeladenen Bearbeitungen oder OSM-Fehlermeldungen in %1$s anzeigen. Hochgeladene Punkte werden in OsmAnd nicht angezeigt. + Betrachten Sie alle Ihre noch nicht hochgeladenen Bearbeitungen oder OSM-Hinweise in %1$s. Bereits hochgeladene Änderungen werden nicht mehr angezeigt. Empfehlung: Versuchen Sie zunächst, die Bewegungserkennung über den Filter zur Mindestabstandsmessung (B) zu verwenden. Das kann zu besseren Ergebnissen führen und Sie werden weniger Daten verlieren. Sollten Ihre Tracks bei niedrigen Geschwindigkeiten ungenau bleiben, versuchen Sie hier Werte ungleich Null. Bitte beachten Sie, dass einige Messungen (einige netzwerkbasierte Methoden) möglicherweise überhaupt keine Geschwindigkeitswerte anzeigen. In diesem Fall wird nichts aufgezeichnet. Es werden nur Punkte aufgezeichnet, die mit der gewählten Mindestgenauigkeit bestimmt wurden (in Metern/Fuß, wie von Android je nach Chipsatz bereitgestellt). Die Genauigkeit beschreibt die Nähe der Messungen zur wahren Position und steht nicht unmittelbar in Bezug zur Präzision, der Streuung wiederholter Messungen. Bemerkung: Wenn das GPS unmittelbar vor einer Aufzeichnung ausgeschaltet war, kann der erste gemessene Punkt eine verminderte Genauigkeit haben, sodass wir in unserem Code vielleicht eine Sekunde oder so warten wollen, bevor ein Punkt (oder der beste von 3 aufeinanderfolgenden Punkten usw.) aufgezeichnet wird. Das ist aber noch nicht implementiert. @@ -3801,9 +3801,9 @@ Bitte geben Sie Ihre Fahrzeuglänge an. Für lange Fahrzeuge könnten einige Streckenabschnitte nicht befahrbar sein. Nächstgelegenen Zielpunkt löschen Bitte geben Sie einen Namen für das Profil an - Der aktuelle Punkt auf der Route wird gelöscht. Wenn es das Ziel ist, wird die Navigation gestoppt. + Löscht das nächste Ziel auf Ihrer Route. Wenn dies das endgültige Ziel ist, wird die Navigation gestoppt. Wikipedia-Karten herunterladen - Info über Sehenswürdigkeiten erhalten Sie bei Wikipedia. Es ist Ihr Offline-Wegweiser für die Hosentasche - aktivieren Sie einfach das Wikipedia-Modul und genießen Sie Artikel über Objekte in Ihrer Umgebung. + Holen Sie sich Informationen über Sehenswürdigkeiten aus Wikipedia, einem Offline-Reiseführer für die Hosentasche mit Artikeln über Orte und Ziele. Enduro Motorroller Rollstuhl @@ -3844,7 +3844,7 @@ Adresse hinzufügen Adresse eingeben Bilder auf Straßenebene - Sind Sie sicher, dass Sie alle Änderungen an der geplanten Route verwerfen wollen, indem Sie sie schließen\? + Sind Sie sicher, dass Sie alle Änderungen an der geplanten Route verwerfen wollen\? Routentyp davor ändern Routentyp danach ändern Davor trimmen @@ -3877,7 +3877,7 @@ Während der Navigation automatisch Track aufzeichnen Track Route Track Datei zum Folgen auswählen, oder vom Gerät importieren. - Die GPX-Aufzeichnung wird angehalten, wenn OsmAnd beendet wird (über „zuletzt verwendete Apps“). (Die Hintergrunddienst-Anzeige verschwindet aus der Android-Benachrichtigungsleiste.) + Die Track-Aufzeichnung wird angehalten, wenn OsmAnd beendet wird (über „zuletzt verwendete Apps“). (Die Hintergrunddienst-Anzeige verschwindet aus der Android-Benachrichtigungsleiste.) Aufzeichnungsintervall für die generelle Track-Aufzeichnung festlegen (wird über die Schaltfläche \'Routenaufzeichung\' auf dem Kartenbildschirm angeschaltet). Als nächstes können Sie Ihren Track mit einem Ihrer Navigationsprofile auf die nächstgelegene erlaubte Straße einrasten lassen, um diese Option zu nutzen. Track-Wegpunkt hinzufügen @@ -3913,12 +3913,12 @@ Name: A – Z Start- und Zielsymbole Vielen Dank für den Kauf von \'Höhenlinien\' - Das Abonnement wird pro ausgewähltem Zeitraum berechnet. Sie können das Abonnement jederzeit über die AppGallery kündigen. - Die Bezahlung wird Ihrem AppGallery-Konto bei der Bestätigung des Kaufs belastet. + Das Abonnement wird für den gewählten Zeitraum berechnet. Sie können es jederzeit in Ihrer AppGallery kündigen. + Ihr AppGallery-Konto wird mit der Kaufbestätigung belastet. \n -\nDas Abonnement verlängert sich automatisch, sofern es nicht vor dem Verlängerungsdatum gekündigt wird. Ihr Konto wird für den Verlängerungszeitraum (Monat / drei Monate / Jahr) nur am Verlängerungsdatum belastet. +\nDas Abonnement verlängert sich automatisch, wenn es nicht vor dem Verlängerungsdatum gekündigt wird. Ihr Konto wird erst am Verlängerungsdatum für den Verlängerungszeitraum (Monat/drei Monate/Jahr) belastet. \n -\nSie können Ihre Abonnements verwalten und kündigen, indem Sie zu Ihren AppGallery-Einstellungen gehen. +\nSie können Ihre Abonnements in Ihren AppGallery-Einstellungen verwalten und kündigen. Vermeidet Fußwege Keine Fußwege Entwicklung @@ -3942,7 +3942,7 @@ Bitte warten Sie. \nDie Grafik wird nach der Neuberechnung der Route verfügbar sein. Einrichtung - ÖPNV + Verkehr Dienstleistung Reisen Sport @@ -3953,7 +3953,7 @@ Spezial Fügen Sie mindestens zwei Punkte hinzu Abonnement verwalten - Es gibt ein Problem mit Ihrem Abonnement. Tippen Sie auf die Schaltfläche, um zu den Einstellungen des Google Play Abonnements zu gelangen und Ihre Zahlungsmethode zu überprüfen. + Tippen Sie auf die Schaltfläche, um eine Zahlungsmethode auf Google Play einzurichten und Ihr Abonnement zu bestätigen. OsmAnd Live Abonnement ist abgelaufen OsmAnd Live Abonnement wurde ausgesetzt OsmAnd Live Abonnement liegt auf Eis @@ -4020,4 +4020,7 @@ Lücke Segmente verbinden Neues Segment hinzufügen + OsmAnd-Profil + Benutzerprofil + Alle Punkte umkehren \ No newline at end of file diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml index f3ba290f90..7949fb2046 100644 --- a/OsmAnd/res/values-eo/phrases.xml +++ b/OsmAnd/res/values-eo/phrases.xml @@ -3887,4 +3887,6 @@ krano akvokondukilo puto tuba (abisena) + Pezilo por aŭtomobiloj + Oficejo de naturrezervejo \ No newline at end of file diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml index eeb3cd5c9d..7aa4610509 100644 --- a/OsmAnd/res/values-es-rAR/phrases.xml +++ b/OsmAnd/res/values-es-rAR/phrases.xml @@ -3901,4 +3901,8 @@ Canilla Planta potabilizadora Pozo entubado + Báscula puente + Estación de guardabosques + Lavadero público de ropa + Estación de transferencia de residuos \ No newline at end of file diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 4618562b7e..01a7bc425a 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -4023,4 +4023,5 @@ \n Perfil de OsmAnd Perfil de usuario + Invertir todos los puntos \ No newline at end of file diff --git a/OsmAnd/res/values-et/phrases.xml b/OsmAnd/res/values-et/phrases.xml index 381bede727..8ef9bbe198 100644 --- a/OsmAnd/res/values-et/phrases.xml +++ b/OsmAnd/res/values-et/phrases.xml @@ -3843,4 +3843,18 @@ Ei Sireen Vetelpäästejaam + Õde + Vaktsineerimine + Vaktsineerimine: COVID19 + Puurkaev + Veevärgi ettevõte + Veekraan + Veepaak + Mootoriga veepump + Kaev + Jõgi + Järv + Mobiiliraha müügikoht + Pargivahi maja + Autokaal \ No newline at end of file diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index 835fad3539..cd68aefcae 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -3850,4 +3850,6 @@ Tükelda pärast Tükelda enne Liida lõigud + Kasutajaprofiil + OsmAnd profiil \ No newline at end of file diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index f7493ff42e..e5a0251d4b 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -3987,4 +3987,23 @@ ساخت حساب جدید حساب کاربری دارم تاریخچهٔ جست‌وجو + دستگاه شما تنها %1$s فضای خالی دارد. لطفا مقادری فضا خالی کنید و یا تعداد موارد برون‌ریزی را کاهش دهید. + فضای کافی موجود نیست + گروه‌هایی را که درون‌ریزی خواهند شد را انتخاب کنید. + مواردی را که درون‌ریزی خواهند شد را انتخاب کنید. + افزودن به مپیلاری + افزودن به OpenPlaceReviews + برای امتحان کردن بارگذاری یادداشت / نقاط توجه و GPX از dev.openstreetmap.org به جای openstreetmep.org استفاده کنید. + از dev.openstreetmap.org استفاده کنید + برنامه OsmAnd عکس‌ها را از چند منبع نشان می‌دهد: +\nاز OpenPlaceReview برای عکس‌های نقاط توجه؛ +\nاز مپیلاری برای تصویر سطح خیابان؛ +\nاز وب و ویکی‌پدیا برای عکس‌های نقاط توجه متناسب با داده‌های اوپن‌استریت‌مپ. + هواپیمای سبک + اتصال بخش‌ها + "تقطیع از این جا به قبل" + تقطیع از این جا به بعد + افزودن یک بخش جدید + نمایهٔ OsmAnd + نمایهٔ کاربر \ No newline at end of file diff --git a/OsmAnd/res/values-fi/strings.xml b/OsmAnd/res/values-fi/strings.xml index 4cd281d671..026179f02c 100644 --- a/OsmAnd/res/values-fi/strings.xml +++ b/OsmAnd/res/values-fi/strings.xml @@ -305,7 +305,7 @@ Näytä vain Seuraa Valitse päämäärä ensin - Ohjeet + Reittiohjeet Avoinna Ladataan katuja/rakennuksia… Ladataan postinumeroita… @@ -390,7 +390,7 @@ Tapahtui odottamaton virhe suoritettaessa toimintoa {0}. Avoinna Tallenna nimellä - Valitse tien väriteema: + Valitse tien värimaailma: Salli GPS:n käyttö asetuksista Autotuki Muokkaa näyttöä @@ -412,7 +412,7 @@ Aikarajoitettu pysäköinti Aika rajoittamaton pysäköinti Pysäköidyn autosi sijainti. %1$s - Nouda auto kello: + Nouda ajoneuvo kello: PM AM U-Käännös @@ -488,7 +488,7 @@ Esteettömyys moodi Globaalien systeemiasetusten mukaan ZXing viivakoodinlukusovellusta ei ole asennettuna. Etsitäänkö se Google Playstä? - Tien väriteema + Tien värimaailma Näytä kohteen suunta Laske mahdollisesti epäoptimaalinen reitti pitkille matkoille Käytä aina offline editointia @@ -836,7 +836,7 @@ Maailmanlaajuiset tiedot (välillä 70 astetta pohjoista ja 70 astetta eteläist Nauhoitettu Nauhoita Ei dataa - Korkeuskäyräviivojen väripaletti + Korkeuskäyräviivojen värimaailma Miniminopeuden kirjaaminen Aseta miniminopeus kirjattavalle pisteelle. Liikkeen tunnistuksen kirjaus @@ -847,7 +847,7 @@ Maailmanlaajuiset tiedot (välillä 70 astetta pohjoista ja 70 astetta eteläist Näytä Joulupyhän KP:t\? Vaaleanruskea Tummanruskea - Korkeuskäyrien väripaletti + Korkeuskäyrien värimaailma Tienpinnan eheys Kirjoita kaupunki, osoite, KP:n nimi Muokkaa luokkia @@ -1728,7 +1728,7 @@ Maailmanlaajuiset tiedot (välillä 70 astetta pohjoista ja 70 astetta eteläist Paina ja pidä nähdäksesi kartalla Alas/Ylös: %1$s - Laske OsmAnd reitin segmentti ilman internettiä + OsmAnd reittisegmentin laskeminen ilman internettiä Laske OsmAnd reitti ensimmäiselle ja viimeiselle reitin segmentille Käytetäänkö näytettävää jälkeä suunnistuksessa\? Lisää myöhemmäksi päämääräksi @@ -2208,7 +2208,7 @@ Jos pidät OsmAndista ja OSMsta ja haluat tukea niitä, on tämä täydellinen t Kasvata haun laajuutta Muokkaa hakusanoja tai lisää haun laajuutta. Tämän toimintonappulan tökkääminen näyttää tai piilottaa OSM-huomautukset kartalla. - Väriskeema + Värimaailma Salli yksityisalueet Salli pääsy yksityisalueille. Ota käyttöön animoitu sijaintini kartan vieritys navigaation aikana. @@ -2571,6 +2571,47 @@ Jos pidät OsmAndista ja OSMsta ja haluat tukea niitä, on tämä täydellinen t Viikko Suuntima Suunnittele reitti - Viimeksi muokattu + Viimeksi muokatut Luo uusi reitti + Valitse väri + Valitse kuvake + Valitse ryhmä + Lisää kuvaus + Vain seuraava segmentti lasketaan uudelleen valitulla profiililla. + Seuraava segmentti + Kaikki seuraavat segmentit + Edellinen segmentti + Kaikki edelliset segmentit + Vain valittu segmentti lasketaan uudelleen käyttämällä valittua profiilia. + Kaikki seuraavat segmentit lasketaan uudelleen käyttämällä valittua profiilia. + Kaikki edelliset segmentit lasketaan uudelleen käyttämällä valittua profiilia. + Yhdistä segmentit + Lisää uusi segmentti + Kahdeksankulmio + Neliö + Ympyrä + Valitse muoto + Palauta oletusarvot + Kaikki profiiliasetukset palautettu oletusarvoihin. + Kaikki laajennuksen asetukset palautettu oletusarvoihin. + Sovelluksen oletus (%s) + Palauta oletus kohteiden järjestys + Näytön oletusaikakatkaisu + Järjestelmän oletus + Muokkaa profiililuetteloa + Muokkaa profiileja + Tuo profiili + Valittu profiili + Mukavuus + Matkailu + Erityinen + Urheilu + OsmAnd-latauspalvelu + Palvelu + Hätätapaus + Liikenne + Näytä julkinen liikenne + Piilota julkinen liikenne + Symbolit + Korvaa toinen kohde tällä. \ No newline at end of file diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index cc4f1eb7f8..fc753fd72b 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3813,7 +3813,7 @@ Seuil de distance Profil de navigation Photos des rues - Voulez-vous vraiment fermer l\'itinéraire planifié sans enregistrer \? (vous perdrez vos modifications) + Souhaitez-vous vraiment ignorer toutes les modifications apportées à l\'itinéraire planifié \? Si inversion du sens Point de la trace vers lequel naviguer Enregistrer le parcours @@ -3852,7 +3852,7 @@ Reprendre l\'enregistrement du trajet Suspendre l\'enregistrement du trajet Définit la fréquence d’enregistrement des points du parcours (activable depuis le gadget \"Enregistrement\" sur la carte). - Suspend l\'enregistrement du parcours lorsque l\'application est arrêtée via Applications récentes ; les indications OsmAnd ne seront plus affichées dans la barre de notifications. + L\'enregistrement de l\'itinéraire sera suspendu si l\'application est arrêtée via Applications récentes (les indications OsmAnd ne seront plus affichées dans la barre de notifications). Tous les segments suivants seront recalculés avec le profil sélectionné. Tous les segments précédents seront recalculés avec le profil sélectionné. Tous les segments suivants @@ -3885,7 +3885,7 @@ Nom : A – Z Icônes de départ et d\'arrivée Merci pour votre achat de \'Courbes de niveaux\' - Abonnement facturé pour chaque période sélectionnée. Annulation possible à tout moment sur AppGallery. + L\'abonnement est facturé pour la période sélectionnée. Annulation possible à tout moment sur AppGallery. Éviter les trottoirs Éviter les trottoirs Développement @@ -3995,4 +3995,7 @@ Ajouter un nouveau segment « Identifiable » siginifie que la trace sera affichée publiquement dans « Mes traces GPS » ainsi que dans les listes de traces GPS publiques. Ainsi les autres utilisateurs peuvent télécharger la trace brute et l\'associer avec votre nom d\'utilisateur. Les données de points de passage horodatés fournis par l\'API GPS publique feront référence à la page d\'origine de votre trace. « Public » signifie que la trace est affichée publiquement dans vos traces GPS et dans les listes de traces GPS publiques. Les données diffusées via l\'API ne font pas référence à votre page de traces. Les horodatages des points de trace ne sont pas disponibles via l\'API GPS publique et les points de trace ne sont pas classés par ordre chronologique. + Profil OsmAnd + Profil utilisateur + Inverser tous les points \ No newline at end of file diff --git a/OsmAnd/res/values-iw/phrases.xml b/OsmAnd/res/values-iw/phrases.xml index d23f018e7c..6ad03cdbfe 100644 --- a/OsmAnd/res/values-iw/phrases.xml +++ b/OsmAnd/res/values-iw/phrases.xml @@ -2174,4 +2174,40 @@ לוח זמנים כוורת דבורים חנות אגוזים + תת־קרקעי + רחוב + חנייה + נתיב + ירוק + מדרכה + קיבולת זרימה של ברז כיבוי + שירותים לאזרח + ויזות למהגרים + קונסוליה + שגרירות + לוח זמנים + מילוי מי שתייה + חץ + רטט + לחץ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index fdcadfd9f0..66d06edf99 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4018,4 +4018,7 @@ \n • תמיכה בצבעים מותאמים אישית למועדפים ולנקודות דרך במסלול \n \n + פרופיל + פרופיל + להפוך את כל \ No newline at end of file diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index 89b718abcd..aa5dcb1a44 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -2904,7 +2904,7 @@ Veityper Gå av på Sitt på stoppet - Vis/skjul GPX-spor + Vis/skjul spor Knapp for å vise eller skjule valgte spor på kartet. Skjul spor Vis spor @@ -2945,9 +2945,9 @@ Fast dekke Betong Brostein - Rustikk brostein + Naturlig brostein Steinbelagt - Småstein + Rullestein Stein Metall Tre @@ -3031,15 +3031,15 @@ Tillat OsmAnd å samle inn og behandle anonym programbruksdata. Ingen data om din plassering, eller om plasseringer du ser på kartet blir samlet inn. \n \nDu kan alltid endre ditt valg i \"Innstillinger\" → \"Personvern og sikkerhet\". - Velg hvilken data du ønsker å dele: + Velg typen data du vil dele: Nedlastede kart Besøkte skjermer Definer hvilken data du ønsker å dele med OsmAnd. - Hjelp oss å forstå hvilke kart over hvilke regioner og land som er mest populære. - Hjelp oss å fastslå popularitet for OsmAnd-funksjoner. - Trykk \"Tillat\" hvis du samtykker du til vår %1$s + Hjelp oss å forstå hvilke land- og regionkart som er mest populære. + Hjelp oss å forstå hvilke OsmAnd-funksjoner som er mest populære. + Trykk \"Tillat\" hvis du er enig med vår %1$s Personvern og sikkerhet - Velg data til deling + Velg hvilke data du deler Nei takk Tillat Profilnavn @@ -3048,8 +3048,8 @@ Hest Helikopter Du kan legge til din egen endrede versjon av filen routing.xml til i ..osmand/routing - Skikjøring - Skikjøring + Stå på ski + Ski Vis kompasslinjal Skjul kompasslinjal Velg ikon @@ -3103,10 +3103,10 @@ Terreng Sett opp profil Antall overganger - Pendlebuss - Tunnelbane + Skyttelbuss + T-bane Baser din egendefinerte profil på en av de forvalgte programprofilene, dette definerer grunnleggende oppsett, som forvalg synliget for miniprogrammer, enheter for hastighet og distanse. Dette er de forvalgte programprofilene, sammen med eksempler på egentilpassede profiler de kan utvides til: - Alle typer offentlig transport + Offentlige transporttyper Endre kartforstørrelse ved å rulle hjulet opp og ned. Escape tar deg tilbake til WunderLINQ-programmet. Legg til minst ett element i listen i hurtighandlingsinnstillingene Bakker for alpin skisport og tilgang til skiheiser. @@ -3125,8 +3125,8 @@ Minimumshastighet Maksimumshastighet Standardhastighet - Endre forvalgte hastighetsinnstillinger - Sett min/maks -hastighet + Endre standardhastighetsinnstillinger + Still inn min/maks-hastighet Ny profil Krasj OsmAnd krasjet tidligere. Hjelp til å forbedre OsmAnd ved å dele feilmeldingen. @@ -3157,11 +3157,11 @@ Scooter Vannrett nøyaktighet: %1$s, loddrett: %2$s Vannrett nøyaktighet: %s - Profil beholder sine egne innstillinger - Velg kartinnstillinger for profilen - Velg skjerminnstillinger for profilen + Profilen beholder sine egne innstillinger + Velg kartalternativer for profilen + Velg skjermalternativer for profilen Velg navigeringsinnstillinger for profilen - Angi øvre grense for endringer + Bestem det maksimale antall overganger Eksterne inndataenheter Velg en enhet for ekstern kontroll, som f.eks. tastatur eller WunderLINQ. Tastatur @@ -3309,10 +3309,10 @@ Overgang Spor lagret Tomt filnavn - Vekk for sving + Slå på skjermen ved sving Juster hvor lenge skjermen skal forbli påslått. Bruk nærhetssensor - Vift hånden din over toppen av skjermen for å skru den på under navigasjon. + Å bevege hånden over skjermen vil slå den på. Klasse 1 Klasse 2 Klasse 3 @@ -3939,4 +3939,5 @@ Logg inn på OpenStreetMap.org OsmAnd-profil Brukerprofil + Bedøm \ No newline at end of file diff --git a/OsmAnd/res/values-pl/strings.xml b/OsmAnd/res/values-pl/strings.xml index 9e18f5c096..f3ca626e16 100644 --- a/OsmAnd/res/values-pl/strings.xml +++ b/OsmAnd/res/values-pl/strings.xml @@ -1941,7 +1941,7 @@ Cienki Średni Gruby - Nie ustalono celu + Wtyczka ułatwień dostępu: nie ustawiono miejsca docelowego Utrzymywanie trasy po zboczeniu z niej Brak ponownego przeliczania trasy po zjechaniu z trasy. Orientacja magnetyczna @@ -3791,9 +3791,9 @@ Usuń najbliższy punkt docelowy Steruj poziomem powiększenia mapy za pomocą przycisków głośności na urządzeniu. Podaj nazwę punktu - Bieżący punkt docelowy na trasie zostanie usunięty. Jeśli będzie to miejsce docelowe, nawigacja zostanie zatrzymana. + Usuwa następny cel na trasie. Jeśli jest to miejsce docelowe, nawigacja zostanie zatrzymana. Pobierz mapy Wikipedii - Uzyskaj informacje o interesujących miejscach z Wikipedii. Jest to kieszonkowy przewodnik offline - wystarczy włączyć wtyczkę Wikipedii i cieszyć się artykułami o obiektach wokół ciebie. + Uzyskaj informacje o ciekawych miejscach z Wikipedii, kieszonkowego przewodnika offline zawierającego artykuły o miejscach i celach. Motocykl Enduro Skuter Określ długość pojazdu dozwoloną na trasach. @@ -3839,7 +3839,7 @@ Wybierz sposób łączenia punktów, za pomocą linii prostej, lub oblicz trasę między nimi w sposób określony poniżej. Następnie przyciągnij trasę do najbliższej dozwolonej drogi za pomocą jednego z profili nawigacji, aby skorzystać z tej opcji. Zdjęcia z poziomu ulicy - Czy na pewno chcesz odrzucić wszystkie zmiany w zaplanowanej trasie, zamykając ją\? + Czy na pewno chcesz odrzucić wszystkie zmiany w zaplanowanej trasie\? W przypadku odwrotnego kierunku Przejdź z mojej lokalizacji na trasę Sportowy wózek inwalidzki @@ -3912,7 +3912,7 @@ Co nowego Ikony startu i końca Dziękujemy za zakup \"Linii konturowych\" - Subskrypcja naliczona za wybrany okres. Anuluj ją w AppGallery w dowolnym momencie. + Subskrypcja jest naliczana za wybrany okres. Anuluj go w AppGallery w dowolnym momencie. Płatność zostanie pobrana z konta AppGallery po potwierdzeniu zakupu. \n \nSubskrypcja jest automatycznie odnawiana, chyba że zostanie anulowana przed datą odnowienia. Twoje konto zostanie obciążone opłatą za okres odnowienia (miesiąc/trzy miesiące/rok) tylko w dniu odnowienia. @@ -3937,7 +3937,7 @@ MGRS Użyj 2-fazowego algorytmu routingu A * Wykres - %1$s dane dostępne tylko na drogach, aby je uzyskać, musisz obliczyć trasę za pomocą opcji „Trasa między punktami”. + %1$s dane dostępne tylko na drogach, oblicz trasę, korzystając z opcji „Trasa między punktami”, aby wyświetlić wykresy. Proszę czekać. \nWykres będzie dostępny po ponownym obliczeniu trasy. Mapy lokalne @@ -3956,7 +3956,7 @@ Subskrypcja OsmAnd Live została wstrzymana Do jazdy skuterem śnieżnym z wyznaczonymi drogami i torami. Dodaj co najmniej dwa punkty - Wystąpił problem z Twoją subskrypcją. Naciśnij przycisk, aby przejść do ustawień subskrypcji Google Play i naprawić metodę płatności. + Stuknij przycisk, aby skonfigurować metodę płatności w Google Play i naprawić subskrypcję. Subskrypcja OsmAnd Live jest wstrzymana Login Zaloguj się do OpenStreetMap @@ -4021,4 +4021,7 @@ \n• Obsługa niestandardowych kolorów dla ulubionych i śledzenia punktów trasy \n \n + Profil OsmAnd + Profil użytkownika + Odwróć wszystkie punkty \ No newline at end of file diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml index 466eae1657..c74187b593 100644 --- a/OsmAnd/res/values-pt-rBR/phrases.xml +++ b/OsmAnd/res/values-pt-rBR/phrases.xml @@ -3894,4 +3894,6 @@ Toque Estação de tratamento de água Bem embalado + Balança + Posto de guarda florestal \ No newline at end of file diff --git a/OsmAnd/res/values-sc/phrases.xml b/OsmAnd/res/values-sc/phrases.xml index 0aeaf1f00b..939dd49e0c 100644 --- a/OsmAnd/res/values-sc/phrases.xml +++ b/OsmAnd/res/values-sc/phrases.xml @@ -3890,4 +3890,8 @@ Isceta Òperas idràulicas Putzu a tubu + Bilàntzia a ponte + Istatzione de sos rangers + Sabunadòrgiu + Istatzione de tramudòngiu de s\'arga \ No newline at end of file diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index 68e3956fb4..44d5d37f94 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -4013,4 +4013,7 @@ \n • Suportu pro colores personalizados pro sos preferidos e sos puntos de coladòrgiu de sas rastas \n \n + Profilu de OsmAnd + Profilu de s\'impreadore + Fùrria totu sos puntos \ No newline at end of file diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 3a606aac2e..d798541848 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -4016,4 +4016,6 @@ \n• Podpora vlastných farieb pre obľúbené položky a sledovanie trasových bodov \n \n + Profil OsmAnd + Profil používateľa \ No newline at end of file diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index b018a39601..4be2bd1df1 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3973,4 +3973,5 @@ \n OsmAnd profili Kullanıcı profili + Tüm noktaları tersine çevir \ No newline at end of file diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml index 2454d78d33..6991f87786 100644 --- a/OsmAnd/res/values-uk/phrases.xml +++ b/OsmAnd/res/values-uk/phrases.xml @@ -3882,4 +3882,8 @@ Резервуар для води Озеро Річка + Лісництво + Автомобільні ваги + Громадська пральня + Станція перевезення відходів \ No newline at end of file diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 9ac26b675a..0ea2ee3374 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4012,4 +4012,7 @@ \n• Підтримка власних кольорів закладок та маршрутних точок треку \n \n + Профіль OsmAnd + Профіль користувача + Повернути назад всі точки \ No newline at end of file diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml index 3a13797bd1..ca44b815e7 100644 --- a/OsmAnd/res/values-zh-rTW/phrases.xml +++ b/OsmAnd/res/values-zh-rTW/phrases.xml @@ -3893,4 +3893,6 @@ 點擊 自來水廠 管井 + 地磅 + 護林員站 \ No newline at end of file diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 055ed90025..28c17c4a5d 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4318,4 +4318,13 @@ Well River Lake + + Ranger station + Weightbridge + + Waste transfer station + + Lavoir + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 56d61d25ff..b1df50c808 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Reverse all points • Added option to export and import all data including settings, resources, my places\n\n • Plan Route: graphs for track segments with route, and added the ability to create and edit multiple track segments\n\n diff --git a/OsmAnd/src/net/osmand/access/AccessibilityPlugin.java b/OsmAnd/src/net/osmand/access/AccessibilityPlugin.java index eb806a5a33..fefc2d9dda 100644 --- a/OsmAnd/src/net/osmand/access/AccessibilityPlugin.java +++ b/OsmAnd/src/net/osmand/access/AccessibilityPlugin.java @@ -56,7 +56,7 @@ public class AccessibilityPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.osmand_accessibility_description); } diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 6b9bb29dea..15f7dd123b 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -43,6 +43,7 @@ import net.osmand.aidl.tiles.ASqliteDbFile; import net.osmand.aidlapi.customization.AProfile; import net.osmand.aidlapi.info.AppInfoParams; import net.osmand.aidlapi.map.ALatLon; +import net.osmand.aidlapi.navigation.ABlockedRoad; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; @@ -62,6 +63,7 @@ import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.dialogs.GpxAppearanceAdapter; +import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.ColorDialogs; import net.osmand.plus.helpers.ExternalApiHelper; import net.osmand.plus.helpers.LockHelper; @@ -138,8 +140,11 @@ import static net.osmand.aidlapi.OsmandAidlConstants.COPY_FILE_UNSUPPORTED_FILE_ import static net.osmand.aidlapi.OsmandAidlConstants.COPY_FILE_WRITE_LOCK_ERROR; import static net.osmand.aidlapi.OsmandAidlConstants.OK_RESPONSE; import static net.osmand.plus.FavouritesDbHelper.FILE_TO_SAVE; +import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_ANGLE; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_LANES; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_NAME; +import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_POSSIBLY_LEFT; +import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_POSSIBLY_RIGHT; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_TURN; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DISTANCE; import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_IMMINENT; @@ -177,6 +182,7 @@ public class OsmandAidlApi { private static final String AIDL_DATA = "aidl_data"; private static final String AIDL_URI = "aidl_uri"; private static final String AIDL_FORCE = "aidl_force"; + private static final String AIDL_LOCATION_PERMISSION = "aidl_location_permission"; private static final String AIDL_SEARCH_QUERY = "aidl_search_query"; private static final String AIDL_SEARCH_LAT = "aidl_search_lat"; private static final String AIDL_SEARCH_LON = "aidl_search_lon"; @@ -208,7 +214,7 @@ public class OsmandAidlApi { private static final ApplicationMode DEFAULT_PROFILE = ApplicationMode.CAR; - private static final ApplicationMode[] VALID_PROFILES = new ApplicationMode[]{ + private static final ApplicationMode[] VALID_PROFILES = new ApplicationMode[] { ApplicationMode.CAR, ApplicationMode.BICYCLE, ApplicationMode.PEDESTRIAN @@ -287,7 +293,7 @@ public class OsmandAidlApi { } private void initOsmandTelegram() { - String[] packages = new String[]{"net.osmand.telegram", "net.osmand.telegram.debug"}; + String[] packages = new String[] {"net.osmand.telegram", "net.osmand.telegram.debug"}; Intent intent = new Intent("net.osmand.telegram.InitApp"); for (String pack : packages) { intent.setComponent(new ComponentName(pack, "net.osmand.telegram.InitAppBroadcastReceiver")); @@ -601,6 +607,7 @@ public class OsmandAidlApi { final RoutingHelper routingHelper = app.getRoutingHelper(); boolean force = intent.getBooleanExtra(AIDL_FORCE, true); + final boolean locationPermission = intent.getBooleanExtra(AIDL_LOCATION_PERMISSION, false); if (routingHelper.isFollowingMode() && !force) { mapActivity.getMapActions().stopNavigationActionConfirm(new DialogInterface.OnDismissListener() { @@ -608,12 +615,12 @@ public class OsmandAidlApi { public void onDismiss(DialogInterface dialog) { MapActivity mapActivity = mapActivityRef.get(); if (mapActivity != null && !routingHelper.isFollowingMode()) { - ExternalApiHelper.startNavigation(mapActivity, start, startDesc, dest, destDesc, profile); + ExternalApiHelper.startNavigation(mapActivity, start, startDesc, dest, destDesc, profile, locationPermission); } } }); } else { - ExternalApiHelper.startNavigation(mapActivity, start, startDesc, dest, destDesc, profile); + ExternalApiHelper.startNavigation(mapActivity, start, startDesc, dest, destDesc, profile, locationPermission); } } } @@ -667,6 +674,7 @@ public class OsmandAidlApi { if (searchLocation != null) { final RoutingHelper routingHelper = app.getRoutingHelper(); boolean force = intent.getBooleanExtra(AIDL_FORCE, true); + final boolean locationPermission = intent.getBooleanExtra(AIDL_LOCATION_PERMISSION, false); if (routingHelper.isFollowingMode() && !force) { mapActivity.getMapActions().stopNavigationActionConfirm(new DialogInterface.OnDismissListener() { @@ -674,12 +682,14 @@ public class OsmandAidlApi { public void onDismiss(DialogInterface dialog) { MapActivity mapActivity = mapActivityRef.get(); if (mapActivity != null && !routingHelper.isFollowingMode()) { - ExternalApiHelper.searchAndNavigate(mapActivity, searchLocation, start, startDesc, profile, searchQuery, false); + ExternalApiHelper.searchAndNavigate(mapActivity, searchLocation, start, + startDesc, profile, searchQuery, false, locationPermission); } } }); } else { - ExternalApiHelper.searchAndNavigate(mapActivity, searchLocation, start, startDesc, profile, searchQuery, false); + ExternalApiHelper.searchAndNavigate(mapActivity, searchLocation, start, + startDesc, profile, searchQuery, false, locationPermission); } } } @@ -698,7 +708,8 @@ public class OsmandAidlApi { GPXFile gpx = loadGpxFileFromIntent(mapActivity, intent); if (gpx != null) { boolean force = intent.getBooleanExtra(AIDL_FORCE, false); - ExternalApiHelper.saveAndNavigateGpx(mapActivity, gpx, force); + boolean locationPermission = intent.getBooleanExtra(AIDL_LOCATION_PERMISSION, false); + ExternalApiHelper.saveAndNavigateGpx(mapActivity, gpx, force, locationPermission); } } } @@ -1652,8 +1663,8 @@ public class OsmandAidlApi { } boolean navigate(String startName, double startLat, double startLon, - String destName, double destLat, double destLon, - String profile, boolean force) { + String destName, double destLat, double destLon, + String profile, boolean force, boolean requestLocationPermission) { Intent intent = new Intent(); intent.setAction(AIDL_NAVIGATE); intent.putExtra(AIDL_START_NAME, startName); @@ -1664,13 +1675,14 @@ public class OsmandAidlApi { intent.putExtra(AIDL_DEST_LON, destLon); intent.putExtra(AIDL_PROFILE, profile); intent.putExtra(AIDL_FORCE, force); + intent.putExtra(AIDL_LOCATION_PERMISSION, requestLocationPermission); app.sendBroadcast(intent); return true; } boolean navigateSearch(String startName, double startLat, double startLon, - String searchQuery, double searchLat, double searchLon, - String profile, boolean force) { + String searchQuery, double searchLat, double searchLon, + String profile, boolean force, boolean requestLocationPermission) { Intent intent = new Intent(); intent.setAction(AIDL_NAVIGATE_SEARCH); intent.putExtra(AIDL_START_NAME, startName); @@ -1681,6 +1693,7 @@ public class OsmandAidlApi { intent.putExtra(AIDL_SEARCH_LON, searchLon); intent.putExtra(AIDL_PROFILE, profile); intent.putExtra(AIDL_FORCE, force); + intent.putExtra(AIDL_LOCATION_PERMISSION, requestLocationPermission); app.sendBroadcast(intent); return true; } @@ -1720,12 +1733,13 @@ public class OsmandAidlApi { return true; } - boolean navigateGpx(String data, Uri uri, boolean force) { + boolean navigateGpx(String data, Uri uri, boolean force, boolean requestLocationPermission) { Intent intent = new Intent(); intent.setAction(AIDL_NAVIGATE_GPX); intent.putExtra(AIDL_DATA, data); intent.putExtra(AIDL_URI, uri); intent.putExtra(AIDL_FORCE, force); + intent.putExtra(AIDL_LOCATION_PERMISSION, requestLocationPermission); app.sendBroadcast(intent); return true; } @@ -1791,6 +1805,9 @@ public class OsmandAidlApi { RouteDirectionInfo a = ni.directionInfo; bundle.putString(prefix + PARAM_NT_DIRECTION_NAME, RoutingHelper.formatStreetName(a.getStreetName(), a.getRef(), a.getDestinationName(), "")); bundle.putString(prefix + PARAM_NT_DIRECTION_TURN, tt.toXmlString()); + bundle.putFloat(prefix + PARAM_NT_DIRECTION_ANGLE, tt.getTurnAngle()); + bundle.putBoolean(prefix + PARAM_NT_DIRECTION_POSSIBLY_LEFT, tt.isPossibleLeftTurn()); + bundle.putBoolean(prefix + PARAM_NT_DIRECTION_POSSIBLY_RIGHT, tt.isPossibleRightTurn()); if (tt.getLanes() != null) { bundle.putString(prefix + PARAM_NT_DIRECTION_LANES, Arrays.toString(tt.getLanes())); } @@ -1798,7 +1815,7 @@ public class OsmandAidlApi { } boolean search(final String searchQuery, final int searchType, final double latitude, final double longitude, - final int radiusLevel, final int totalLimit, final SearchCompleteCallback callback) { + final int radiusLevel, final int totalLimit, final SearchCompleteCallback callback) { if (Algorithms.isEmpty(searchQuery) || latitude == 0 || longitude == 0 || callback == null) { return false; } @@ -2167,7 +2184,7 @@ public class OsmandAidlApi { } boolean getBitmapForGpx(final Uri gpxUri, final float density, final int widthPixels, - final int heightPixels, final int color, final GpxBitmapCreatedCallback callback) { + final int heightPixels, final int color, final GpxBitmapCreatedCallback callback) { if (gpxUri == null || callback == null) { return false; } @@ -2368,6 +2385,25 @@ public class OsmandAidlApi { return true; } + public boolean getBlockedRoads(List blockedRoads) { + Map impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads(); + for (AvoidRoadInfo info : impassableRoads.values()) { + blockedRoads.add(new ABlockedRoad(info.id, info.latitude, info.longitude, info.direction, info.name, info.appModeKey)); + } + return true; + } + + public boolean addRoadBlock(ABlockedRoad road) { + LatLon latLon = new LatLon(road.getLatitude(), road.getLongitude()); + app.getAvoidSpecificRoads().addImpassableRoad(null, latLon, false, false, null); + return true; + } + + public boolean removeRoadBlock(ABlockedRoad road) { + app.getAvoidSpecificRoads().removeImpassableRoad(new LatLon(road.getLatitude(), road.getLongitude())); + return true; + } + private static class FileCopyInfo { long startTime; long lastAccessTime; diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java index 99e888973f..2760dbe1d0 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java @@ -44,6 +44,7 @@ import net.osmand.aidl.gpx.RemoveGpxParams; import net.osmand.aidl.gpx.ShowGpxParams; import net.osmand.aidl.gpx.StartGpxRecordingParams; import net.osmand.aidl.gpx.StopGpxRecordingParams; +import net.osmand.aidl.lock.SetLockStateParams; import net.osmand.aidl.map.ALatLon; import net.osmand.aidl.map.SetMapLocationParams; import net.osmand.aidl.maplayer.AddMapLayerParams; @@ -85,10 +86,9 @@ import net.osmand.aidl.quickaction.QuickActionParams; import net.osmand.aidl.search.SearchParams; import net.osmand.aidl.search.SearchResult; import net.osmand.aidl.tiles.ASqliteDbFile; -import net.osmand.aidl.lock.SetLockStateParams; import net.osmand.data.LatLon; -import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -736,7 +736,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { return params != null && api != null && api.navigate( params.getStartName(), params.getStartLat(), params.getStartLon(), params.getDestName(), params.getDestLat(), params.getDestLon(), - params.getProfile(), params.isForce()); + params.getProfile(), params.isForce(), params.isNeedLocationPermission()); } catch (Exception e) { handleException(e); return false; @@ -747,7 +747,8 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { public boolean navigateGpx(NavigateGpxParams params) { try { OsmandAidlApi api = getApi("navigateGpx"); - return params != null && api != null && api.navigateGpx(params.getData(), params.getUri(), params.isForce()); + return params != null && api != null && api.navigateGpx(params.getData(), params.getUri(), + params.isForce(), params.isNeedLocationPermission()); } catch (Exception e) { handleException(e); return false; @@ -857,7 +858,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { return params != null && api != null && api.navigateSearch( params.getStartName(), params.getStartLat(), params.getStartLon(), params.getSearchQuery(), params.getSearchLat(), params.getSearchLon(), - params.getProfile(), params.isForce()); + params.getProfile(), params.isForce(), params.isNeedLocationPermission()); } catch (Exception e) { handleException(e); return false; @@ -1328,6 +1329,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { return false; } } + @Override public boolean setLockState(SetLockStateParams params) { try { diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 9943257c03..5fa2f75421 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -73,13 +73,16 @@ import net.osmand.aidlapi.navdrawer.NavDrawerFooterParams; import net.osmand.aidlapi.navdrawer.NavDrawerHeaderParams; import net.osmand.aidlapi.navdrawer.NavDrawerItem; import net.osmand.aidlapi.navdrawer.SetNavDrawerItemsParams; +import net.osmand.aidlapi.navigation.ABlockedRoad; import net.osmand.aidlapi.navigation.ANavigationUpdateParams; import net.osmand.aidlapi.navigation.ANavigationVoiceRouterMessageParams; +import net.osmand.aidlapi.navigation.AddBlockedRoadParams; import net.osmand.aidlapi.navigation.MuteNavigationParams; import net.osmand.aidlapi.navigation.NavigateGpxParams; import net.osmand.aidlapi.navigation.NavigateParams; import net.osmand.aidlapi.navigation.NavigateSearchParams; import net.osmand.aidlapi.navigation.PauseNavigationParams; +import net.osmand.aidlapi.navigation.RemoveBlockedRoadParams; import net.osmand.aidlapi.navigation.ResumeNavigationParams; import net.osmand.aidlapi.navigation.StopNavigationParams; import net.osmand.aidlapi.navigation.UnmuteNavigationParams; @@ -693,7 +696,7 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener return params != null && api != null && api.navigate( params.getStartName(), params.getStartLat(), params.getStartLon(), params.getDestName(), params.getDestLat(), params.getDestLon(), - params.getProfile(), params.isForce()); + params.getProfile(), params.isForce(), params.isNeedLocationPermission()); } catch (Exception e) { handleException(e); return false; @@ -704,7 +707,8 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener public boolean navigateGpx(NavigateGpxParams params) { try { OsmandAidlApi api = getApi("navigateGpx"); - return params != null && api != null && api.navigateGpx(params.getData(), params.getUri(), params.isForce()); + return params != null && api != null && api.navigateGpx(params.getData(), params.getUri(), + params.isForce(), params.isNeedLocationPermission()); } catch (Exception e) { handleException(e); return false; @@ -814,7 +818,7 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener return params != null && api != null && api.navigateSearch( params.getStartName(), params.getStartLat(), params.getStartLon(), params.getSearchQuery(), params.getSearchLat(), params.getSearchLon(), - params.getProfile(), params.isForce()); + params.getProfile(), params.isForce(), params.isNeedLocationPermission()); } catch (Exception e) { handleException(e); return false; @@ -1396,6 +1400,49 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener return false; } } + + @Override + public boolean getBlockedRoads(List blockedRoads) { + try { + OsmandAidlApi api = getApi("getBlockedRoads"); + return api != null && api.getBlockedRoads(blockedRoads); + } catch (Exception e) { + handleException(e); + return false; + } + } + + @Override + public boolean addRoadBlock(AddBlockedRoadParams params) { + try { + OsmandAidlApi api = getApi("addRoadBlock"); + if (params != null && api != null) { + ABlockedRoad road = params.getBlockedRoad(); + if (road != null) { + return api.addRoadBlock(road); + } + } + } catch (Exception e) { + handleException(e); + } + return false; + } + + @Override + public boolean removeRoadBlock(RemoveBlockedRoadParams params) { + try { + OsmandAidlApi api = getApi("removeRoadBlock"); + if (params != null && api != null) { + ABlockedRoad road = params.getBlockedRoad(); + if (road != null) { + return api.removeRoadBlock(road); + } + } + } catch (Exception e) { + handleException(e); + } + return false; + } }; private void setCustomization(OsmandAidlApi api, CustomizationInfoParams params) { diff --git a/OsmAnd/src/net/osmand/aidl/navigation/NavigateGpxParams.java b/OsmAnd/src/net/osmand/aidl/navigation/NavigateGpxParams.java index 6e8fb8efe7..0944c1a5f9 100644 --- a/OsmAnd/src/net/osmand/aidl/navigation/NavigateGpxParams.java +++ b/OsmAnd/src/net/osmand/aidl/navigation/NavigateGpxParams.java @@ -9,15 +9,18 @@ public class NavigateGpxParams implements Parcelable { private String data; private Uri uri; private boolean force; + private boolean needLocationPermission; - public NavigateGpxParams(String data, boolean force) { + public NavigateGpxParams(String data, boolean force, boolean needLocationPermission) { this.data = data; this.force = force; + this.needLocationPermission = needLocationPermission; } - public NavigateGpxParams(Uri uri, boolean force) { + public NavigateGpxParams(Uri uri, boolean force, boolean needLocationPermission) { this.uri = uri; this.force = force; + this.needLocationPermission = needLocationPermission; } public NavigateGpxParams(Parcel in) { @@ -48,22 +51,27 @@ public class NavigateGpxParams implements Parcelable { return force; } + public boolean isNeedLocationPermission() { + return needLocationPermission; + } + @Override public void writeToParcel(Parcel out, int flags) { out.writeString(data); out.writeParcelable(uri, flags); out.writeByte((byte) (force ? 1 : 0)); + out.writeByte((byte) (needLocationPermission ? 1 : 0)); } private void readFromParcel(Parcel in) { data = in.readString(); uri = in.readParcelable(Uri.class.getClassLoader()); force = in.readByte() != 0; + needLocationPermission = in.readByte() != 0; } @Override public int describeContents() { return 0; } - } diff --git a/OsmAnd/src/net/osmand/aidl/navigation/NavigateParams.java b/OsmAnd/src/net/osmand/aidl/navigation/NavigateParams.java index 8b0bdeb1eb..ce3b7ae0e6 100644 --- a/OsmAnd/src/net/osmand/aidl/navigation/NavigateParams.java +++ b/OsmAnd/src/net/osmand/aidl/navigation/NavigateParams.java @@ -13,8 +13,10 @@ public class NavigateParams implements Parcelable { private double destLon; private String profile; private boolean force; + private boolean needLocationPermission; - public NavigateParams(String startName, double startLat, double startLon, String destName, double destLat, double destLon, String profile, boolean force) { + public NavigateParams(String startName, double startLat, double startLon, String destName, double destLat, + double destLon, String profile, boolean force, boolean needLocationPermission) { this.startName = startName; this.startLat = startLat; this.startLon = startLon; @@ -23,6 +25,7 @@ public class NavigateParams implements Parcelable { this.destLon = destLon; this.profile = profile; this.force = force; + this.needLocationPermission = needLocationPermission; } public NavigateParams(Parcel in) { @@ -73,6 +76,10 @@ public class NavigateParams implements Parcelable { return force; } + public boolean isNeedLocationPermission() { + return needLocationPermission; + } + @Override public void writeToParcel(Parcel out, int flags) { out.writeString(startName); @@ -83,6 +90,7 @@ public class NavigateParams implements Parcelable { out.writeDouble(destLon); out.writeString(profile); out.writeByte((byte) (force ? 1 : 0)); + out.writeByte((byte) (needLocationPermission ? 1 : 0)); } private void readFromParcel(Parcel in) { @@ -94,11 +102,11 @@ public class NavigateParams implements Parcelable { destLon = in.readDouble(); profile = in.readString(); force = in.readByte() != 0; + needLocationPermission = in.readByte() != 0; } @Override public int describeContents() { return 0; } - } diff --git a/OsmAnd/src/net/osmand/aidl/navigation/NavigateSearchParams.java b/OsmAnd/src/net/osmand/aidl/navigation/NavigateSearchParams.java index b092bcd4eb..8fc9ccea18 100644 --- a/OsmAnd/src/net/osmand/aidl/navigation/NavigateSearchParams.java +++ b/OsmAnd/src/net/osmand/aidl/navigation/NavigateSearchParams.java @@ -13,10 +13,11 @@ public class NavigateSearchParams implements Parcelable { private double searchLon; private String profile; private boolean force; + private boolean needLocationPermission; public NavigateSearchParams(String startName, double startLat, double startLon, String searchQuery, double searchLat, double searchLon, - String profile, boolean force) { + String profile, boolean force, boolean needLocationPermission) { this.startName = startName; this.startLat = startLat; this.startLon = startLon; @@ -25,6 +26,7 @@ public class NavigateSearchParams implements Parcelable { this.searchLon = searchLon; this.profile = profile; this.force = force; + this.needLocationPermission = needLocationPermission; } public NavigateSearchParams(Parcel in) { @@ -75,6 +77,10 @@ public class NavigateSearchParams implements Parcelable { return force; } + public boolean isNeedLocationPermission() { + return needLocationPermission; + } + @Override public void writeToParcel(Parcel out, int flags) { out.writeString(startName); @@ -85,6 +91,7 @@ public class NavigateSearchParams implements Parcelable { out.writeByte((byte) (force ? 1 : 0)); out.writeDouble(searchLat); out.writeDouble(searchLon); + out.writeByte((byte) (needLocationPermission ? 1 : 0)); } private void readFromParcel(Parcel in) { @@ -96,11 +103,11 @@ public class NavigateSearchParams implements Parcelable { force = in.readByte() != 0; searchLat = in.readDouble(); searchLon = in.readDouble(); + needLocationPermission = in.readByte() != 0; } @Override public int describeContents() { return 0; } - } diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 00b5d2dc80..c372a4de98 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -461,7 +461,6 @@ public class AppInitializer implements IProgress { // TODOTRAVEL_OBF_HELPER check ResourceManager and use TravelObfHelper app.travelHelper = !TravelDbHelper.checkIfDbFileExists(app) ? new TravelObfHelper(app) : new TravelDbHelper(app); - app.travelHelper.initializeDataOnAppStartup(); app.travelHelper = startupInit(app.travelHelper, TravelHelper.class); app.lockHelper = startupInit(new LockHelper(app), LockHelper.class); @@ -661,7 +660,7 @@ public class AppInitializer implements IProgress { initPoiTypes(); notifyEvent(InitEvents.POI_TYPES_INITIALIZED); app.resourceManager.reloadIndexesOnStart(this, warnings); - + app.travelHelper.initializeDataOnAppStartup(); // native depends on renderers initNativeCore(); notifyEvent(InitEvents.NATIVE_INITIALIZED); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 313fa6b917..8541ab5e87 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -1195,6 +1195,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0); getMapLayers().getContextMenuLayer().enterAddGpxPointMode(newGpxPoint); } else if (toShow instanceof GpxData) { + hideContextAndRouteInfoMenues(); + GpxData gpxData = (GpxData) toShow; QuadRect qr = gpxData.getRect(); mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0); diff --git a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java index c42e4de8aa..b7f15624b4 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java @@ -581,7 +581,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.audionotes_plugin_description); } diff --git a/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java b/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java index e5d7b3e11d..10997d0f07 100644 --- a/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java +++ b/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java @@ -37,7 +37,7 @@ public class OsmandDevelopmentPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.osmand_development_plugin_description); } diff --git a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java index 22e0607c7f..bfa84b8474 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java +++ b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java @@ -26,7 +26,6 @@ import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.QuadPoint; import net.osmand.data.RotatedTileBox; -import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -35,6 +34,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper.RouteSegmentSearchResult; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.views.layers.ContextMenuLayer; import net.osmand.router.RouteSegmentResult; import net.osmand.router.RoutingConfiguration; @@ -59,7 +59,7 @@ public class AvoidSpecificRoads { loadImpassableRoads(); } - public void loadImpassableRoads(){ + public void loadImpassableRoads() { for (AvoidRoadInfo avoidRoadInfo : app.getSettings().getImpassableRoadPoints()) { impassableRoads.put(new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude), avoidRoadInfo); } @@ -390,7 +390,14 @@ public class AvoidSpecificRoads { if (avoidRoadInfo == null) { avoidRoadInfo = new AvoidRoadInfo(); } - avoidRoadInfo.id = object != null ? object.id : 0; + if (object != null) { + avoidRoadInfo.id = object.id; +// avoidRoadInfo.direction = object.directionRoute(0, true); + avoidRoadInfo.direction = Double.NaN; + } else { + avoidRoadInfo.id = 0; + avoidRoadInfo.direction = Double.NaN; + } avoidRoadInfo.latitude = lat; avoidRoadInfo.longitude = lon; avoidRoadInfo.appModeKey = appModeKey; @@ -400,6 +407,7 @@ public class AvoidSpecificRoads { public static class AvoidRoadInfo { public long id; + public double direction = Double.NaN; public double latitude; public double longitude; public String name; diff --git a/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java index 57d6039145..a81540be89 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java @@ -30,6 +30,7 @@ import net.osmand.data.PointDescription; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; @@ -129,6 +130,7 @@ public class ExternalApiHelper { public static final String PARAM_URI = "uri"; public static final String PARAM_DATA = "data"; public static final String PARAM_FORCE = "force"; + public static final String PARAM_LOCATION_PERMISSION = "location_permission"; public static final String PARAM_START_NAME = "start_name"; public static final String PARAM_DEST_NAME = "dest_name"; @@ -151,6 +153,9 @@ public class ExternalApiHelper { public static final String PARAM_NT_DIRECTION_NAME = "turn_name"; public static final String PARAM_NT_DIRECTION_TURN = "turn_type"; public static final String PARAM_NT_DIRECTION_LANES = "turn_lanes"; + public static final String PARAM_NT_DIRECTION_ANGLE = "turn_angle"; + public static final String PARAM_NT_DIRECTION_POSSIBLY_LEFT = "turn_possibly_left"; + public static final String PARAM_NT_DIRECTION_POSSIBLY_RIGHT = "turn_possibly_right"; public static final String PARAM_CLOSE_AFTER_COMMAND = "close_after_command"; @@ -237,7 +242,8 @@ public class ExternalApiHelper { if (gpx != null) { if (navigate) { boolean force = uri.getBooleanQueryParameter(PARAM_FORCE, false); - saveAndNavigateGpx(mapActivity, gpx, force); + boolean locationPermission = uri.getBooleanQueryParameter(PARAM_LOCATION_PERMISSION, false); + saveAndNavigateGpx(mapActivity, gpx, force, locationPermission); } else { app.getSelectedGpxHelper().setGpxFileToDisplay(gpx); } @@ -289,6 +295,7 @@ public class ExternalApiHelper { final PointDescription destDesc = new PointDescription(PointDescription.POINT_TYPE_LOCATION, destName); boolean force = uri.getBooleanQueryParameter(PARAM_FORCE, false); + final boolean locationPermission = uri.getBooleanQueryParameter(PARAM_LOCATION_PERMISSION, false); final RoutingHelper routingHelper = app.getRoutingHelper(); if (routingHelper.isFollowingMode() && !force) { @@ -297,12 +304,12 @@ public class ExternalApiHelper { @Override public void onDismiss(DialogInterface dialog) { if (!routingHelper.isFollowingMode()) { - startNavigation(mapActivity, start, startDesc, dest, destDesc, profile); + startNavigation(mapActivity, start, startDesc, dest, destDesc, profile, locationPermission); } } }); } else { - startNavigation(mapActivity, start, startDesc, dest, destDesc, profile); + startNavigation(mapActivity, start, startDesc, dest, destDesc, profile, locationPermission); } } @@ -348,6 +355,7 @@ public class ExternalApiHelper { resultCode = RESULT_CODE_ERROR_SEARCH_LOCATION_UNDEFINED; } else { boolean force = uri.getBooleanQueryParameter(PARAM_FORCE, false); + final boolean locationPermission = uri.getBooleanQueryParameter(PARAM_LOCATION_PERMISSION, false); final RoutingHelper routingHelper = app.getRoutingHelper(); if (routingHelper.isFollowingMode() && !force) { @@ -356,12 +364,12 @@ public class ExternalApiHelper { @Override public void onDismiss(DialogInterface dialog) { if (!routingHelper.isFollowingMode()) { - searchAndNavigate(mapActivity, searchLocation, start, startDesc, profile, searchQuery, showSearchResults); + searchAndNavigate(mapActivity, searchLocation, start, startDesc, profile, searchQuery, showSearchResults, locationPermission); } } }); } else { - searchAndNavigate(mapActivity, searchLocation, start, startDesc, profile, searchQuery, showSearchResults); + searchAndNavigate(mapActivity, searchLocation, start, startDesc, profile, searchQuery, showSearchResults, locationPermission); } resultCode = Activity.RESULT_OK; } @@ -629,7 +637,8 @@ public class ExternalApiHelper { return null; } - public static void saveAndNavigateGpx(MapActivity mapActivity, final GPXFile gpxFile, final boolean force) { + public static void saveAndNavigateGpx(MapActivity mapActivity, final GPXFile gpxFile, + final boolean force, final boolean checkLocationPermission) { final WeakReference mapActivityRef = new WeakReference<>(mapActivity); if (Algorithms.isEmpty(gpxFile.path)) { @@ -670,12 +679,12 @@ public class ExternalApiHelper { public void onDismiss(DialogInterface dialog) { MapActivity mapActivity = mapActivityRef.get(); if (mapActivity != null && !routingHelper.isFollowingMode()) { - ExternalApiHelper.startNavigation(mapActivity, gpxFile); + ExternalApiHelper.startNavigation(mapActivity, gpxFile, checkLocationPermission); } } }); } else { - startNavigation(mapActivity, gpxFile); + startNavigation(mapActivity, gpxFile, checkLocationPermission); } } } @@ -690,6 +699,9 @@ public class ExternalApiHelper { RouteDirectionInfo a = ni.directionInfo; result.putExtra(prefix + PARAM_NT_DIRECTION_NAME, RoutingHelper.formatStreetName(a.getStreetName(), a.getRef(), a.getDestinationName(), "")); result.putExtra(prefix + PARAM_NT_DIRECTION_TURN, tt.toXmlString()); + result.putExtra(prefix + PARAM_NT_DIRECTION_ANGLE, tt.getTurnAngle()); + result.putExtra(prefix + PARAM_NT_DIRECTION_POSSIBLY_LEFT, tt.isPossibleLeftTurn()); + result.putExtra(prefix + PARAM_NT_DIRECTION_POSSIBLY_RIGHT, tt.isPossibleRightTurn()); if (tt.getLanes() != null) { result.putExtra(prefix + PARAM_NT_DIRECTION_LANES, Arrays.toString(tt.getLanes())); } @@ -705,23 +717,22 @@ public class ExternalApiHelper { mapContextMenu.show(new LatLon(lat, lon), pointDescription, object); } - static public void startNavigation(MapActivity mapActivity, - @NonNull GPXFile gpx) { - startNavigation(mapActivity, gpx, null, null, null, null, null); + static public void startNavigation(MapActivity mapActivity, @NonNull GPXFile gpx, boolean checkLocationPermission) { + startNavigation(mapActivity, gpx, null, null, null, null, null, checkLocationPermission); } static public void startNavigation(MapActivity mapActivity, @Nullable LatLon from, @Nullable PointDescription fromDesc, @Nullable LatLon to, @Nullable PointDescription toDesc, - @NonNull ApplicationMode mode) { - startNavigation(mapActivity, null, from, fromDesc, to, toDesc, mode); + @NonNull ApplicationMode mode, boolean checkLocationPermission) { + startNavigation(mapActivity, null, from, fromDesc, to, toDesc, mode, checkLocationPermission); } static private void startNavigation(MapActivity mapActivity, GPXFile gpx, LatLon from, PointDescription fromDesc, LatLon to, PointDescription toDesc, - ApplicationMode mode) { + ApplicationMode mode, boolean checkLocationPermission) { OsmandApplication app = mapActivity.getMyApplication(); RoutingHelper routingHelper = app.getRoutingHelper(); if (gpx == null) { @@ -745,12 +756,15 @@ public class ExternalApiHelper { app.getRoutingHelper().notifyIfRouteIsCalculated(); routingHelper.setCurrentLocation(app.getLocationProvider().getLastKnownLocation(), false); } + if (checkLocationPermission) { + OsmAndLocationProvider.requestFineLocationPermissionIfNeeded(mapActivity); + } } static public void searchAndNavigate(@NonNull MapActivity mapActivity, @NonNull final LatLon searchLocation, @Nullable final LatLon from, @Nullable final PointDescription fromDesc, @NonNull final ApplicationMode mode, @NonNull final String searchQuery, - final boolean showSearchResults) { + final boolean showSearchResults, final boolean checkLocationPermission) { final WeakReference mapActivityRef = new WeakReference<>(mapActivity); OsmandApplication app = mapActivity.getMyApplication(); @@ -791,7 +805,7 @@ public class ExternalApiHelper { LatLon to = new LatLon(res.getLatitude(), res.getLongitude()); PointDescription toDesc = new PointDescription( PointDescription.POINT_TYPE_TARGET, res.getLocalName() + ", " + res.getLocalTypeName()); - startNavigation(mapActivity, from, fromDesc, to, toDesc, mode); + startNavigation(mapActivity, from, fromDesc, to, toDesc, mode, checkLocationPermission); } else { mapActivity.getMyApplication().showToastMessage(mapActivity.getString(R.string.search_nothing_found)); } diff --git a/OsmAnd/src/net/osmand/plus/helpers/WaypointDialogHelper.java b/OsmAnd/src/net/osmand/plus/helpers/WaypointDialogHelper.java index 19cd646ecb..8d0d8210c1 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/WaypointDialogHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/WaypointDialogHelper.java @@ -39,15 +39,17 @@ import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** + * */ public class WaypointDialogHelper { private MapActivity mapActivity; private OsmandApplication app; private WaypointHelper waypointHelper; - private List helperCallbacks= new ArrayList<>(); + private List helperCallbacks = new ArrayList<>(); private boolean flat; private List deletedPoints; @@ -242,8 +244,8 @@ public class WaypointDialogHelper { // switch start & finish public static void switchStartAndFinish(TargetPointsHelper targetPointsHelper, TargetPoint finish, - Activity ctx, TargetPoint start, OsmandApplication app, - WaypointDialogHelper helper) { + Activity ctx, TargetPoint start, OsmandApplication app, + WaypointDialogHelper helper) { if (finish == null) { app.showShortToastMessage(R.string.mark_final_location_first); } else { @@ -263,6 +265,20 @@ public class WaypointDialogHelper { } } + public static void reverseAllPoints(OsmandApplication app, Activity ctx, + WaypointDialogHelper helper) { + TargetPointsHelper targets = app.getTargetPointsHelper(); + if (!targets.getAllPoints().isEmpty()) { + List points = targets.getAllPoints(); + Collections.reverse(points); + TargetPoint start = points.get(0); + targets.setStartPoint(start.point, false, start.getOriginalPointDescription()); + points.remove(start); + targets.reorderAllTargetPoints(points, true); + updateControls(ctx, helper); + } + } + public static void updateControls(Activity ctx, WaypointDialogHelper helper) { if (helper != null && helper.helperCallbacks != null) { for (WaypointDialogHelperCallback callback : helper.helperCallbacks) { @@ -278,7 +294,7 @@ public class WaypointDialogHelper { } public static void replaceStartWithFirstIntermediate(TargetPointsHelper targetPointsHelper, Activity ctx, - WaypointDialogHelper helper) { + WaypointDialogHelper helper) { List intermediatePoints = targetPointsHelper.getIntermediatePointsWithTarget(); TargetPoint firstIntermediate = intermediatePoints.remove(0); targetPointsHelper.setStartPoint(new LatLon(firstIntermediate.getLatitude(), @@ -443,7 +459,8 @@ public class WaypointDialogHelper { @Override public void createMenuItems(Bundle savedInstanceState) { items.add(new TitleItem(getString(R.string.shared_string_options))); - + final OsmandApplication app = requiredMyApplication(); + final TargetPointsHelper targetsHelper = app.getTargetPointsHelper(); BaseBottomSheetItem sortDoorToDoorItem = new SimpleBottomSheetItem.Builder() .setIcon(getContentIcon(R.drawable.ic_action_sort_door_to_door)) .setTitle(getString(R.string.intermediate_items_sort_by_distance)) @@ -491,6 +508,30 @@ public class WaypointDialogHelper { .create(); items.add(reorderStartAndFinishItem); + BaseBottomSheetItem reorderAllItems = new SimpleBottomSheetItem.Builder() + .setIcon(getContentIcon(R.drawable.ic_action_sort_reverse_order)) + .setTitle(getString(R.string.reverse_all_points)) + .setLayoutId(R.layout.bottom_sheet_item_simple) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + WaypointDialogHelper.reverseAllPoints( + app, + mapActivity, + mapActivity.getDashboard().getWaypointDialogHelper() + ); + } + dismiss(); + } + }) + .create(); + int intermediateSize = targetsHelper.getIntermediatePoints().size(); + if (intermediateSize > 2) { + items.add(reorderAllItems); + } + items.add(new DividerHalfItem(getContext())); final BaseBottomSheetItem[] addWaypointItem = new BaseBottomSheetItem[1]; diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java index 7883e2c5f0..770f973592 100644 --- a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java @@ -83,7 +83,7 @@ public class MapillaryPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.plugin_mapillary_descr); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index c54dd93a08..3d8d9163b0 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -70,13 +70,14 @@ import net.osmand.plus.measurementtool.command.MovePointCommand; import net.osmand.plus.measurementtool.command.RemovePointCommand; import net.osmand.plus.measurementtool.command.ReorderPointCommand; import net.osmand.plus.measurementtool.command.ReversePointsCommand; -import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet; -import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DialogMode; import net.osmand.plus.measurementtool.command.SplitPointsCommand; +import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet; +import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.OnAppModeConfiguredCallback; +import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DialogMode; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.views.layers.MapControlsLayer; +import net.osmand.plus.views.layers.MapControlsLayer.MapControlsThemeInfoProvider; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarView; @@ -108,8 +109,8 @@ import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCo public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener, OptionsFragmentListener, GpxApproximationFragmentListener, SelectedPointFragmentListener, - SaveAsNewTrackFragmentListener, MapControlsLayer.MapControlsThemeInfoProvider, - RouteOptionsBottomSheet.OnAppModeConfiguredCallback{ + SaveAsNewTrackFragmentListener, MapControlsThemeInfoProvider, + OnAppModeConfiguredCallback { public static final String TAG = MeasurementToolFragment.class.getSimpleName(); public static final String TAPS_DISABLED_KEY = "taps_disabled_key"; @@ -179,7 +180,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route return mainView.getHeight(); } - public boolean shouldShowXAxisPoints () { + public boolean shouldShowXAxisPoints() { return false; } } @@ -546,7 +547,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route if (savedInstanceState == null) { if (fileName != null) { addNewGpxData(getGpxFile(fileName)); - } else if (editingCtx.isApproximationNeeded()) { + } else if (editingCtx.isApproximationNeeded() && isFollowTrackMode()) { enterApproximationMode(mapActivity); } } else { diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 7429caadd6..16c60911df 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -117,7 +117,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.record_plugin_description); } diff --git a/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java b/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java index d0632d812a..63c17ceece 100644 --- a/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java +++ b/OsmAnd/src/net/osmand/plus/notifications/NavigationNotification.java @@ -17,6 +17,7 @@ import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat.BigTextStyle; import androidx.core.app.NotificationCompat.Builder; +import net.osmand.Location; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; @@ -77,7 +78,7 @@ public class NavigationNotification extends OsmandNotification { RoutingHelper routingHelper = app.getRoutingHelper(); routingHelper.setRoutePlanningMode(false); routingHelper.setFollowingMode(true); - routingHelper.setCurrentLocation(app.getLocationProvider().getLastKnownLocation(), false); + routingHelper.setCurrentLocation(getLastKnownLocation(), false); } }, new IntentFilter(OSMAND_RESUME_NAVIGATION_SERVICE_ACTION)); @@ -136,10 +137,15 @@ public class NavigationNotification extends OsmandNotification { if (service != null && (service.getUsedBy() & USED_BY_NAVIGATION) != 0) { color = app.getResources().getColor(R.color.osmand_orange); - String distanceStr = OsmAndFormatter.getFormattedDistance(app.getRoutingHelper().getLeftDistance(), app); - String timeStr = OsmAndFormatter.getFormattedDuration(app.getRoutingHelper().getLeftTime(), app); + String distanceStr = OsmAndFormatter.getFormattedDistance(routingHelper.getLeftDistance(), app); + String timeStr = OsmAndFormatter.getFormattedDuration(routingHelper.getLeftTime(), app); String etaStr = SimpleDateFormat.getTimeInstance(DateFormat.SHORT) - .format(new Date(System.currentTimeMillis() + app.getRoutingHelper().getLeftTime() * 1000)); + .format(new Date(System.currentTimeMillis() + routingHelper.getLeftTime() * 1000)); + String speedStr = null; + Location location = getLastKnownLocation(); + if (location != null && location.hasSpeed()) { + speedStr = OsmAndFormatter.getFormattedSpeed(location.getSpeed(), app); + } TurnType turnType = null; boolean deviatedFromRoute; @@ -199,9 +205,12 @@ public class NavigationNotification extends OsmandNotification { notificationText.append("\n"); } } - - notificationText.append(distanceStr).append(" • ").append(timeStr).append(" • ").append(etaStr); - + notificationText.append(distanceStr) + .append(" • ").append(timeStr) + .append(" • ").append(etaStr); + if (speedStr != null) { + notificationText.append(" • ").append(speedStr); + } } else { notificationTitle = app.getString(R.string.shared_string_navigation); String error = routingHelper.getLastRouteCalcErrorShort(); @@ -211,7 +220,6 @@ public class NavigationNotification extends OsmandNotification { notificationText.append(error); } } - } else if (routingHelper.isRoutePlanningMode() && routingHelper.isPauseNavigation()) { ongoing = false; notificationTitle = app.getString(R.string.shared_string_navigation); @@ -266,6 +274,10 @@ public class NavigationNotification extends OsmandNotification { } } + private Location getLastKnownLocation() { + return app.getLocationProvider().getLastKnownLocation(); + } + public Bitmap drawableToBitmap(Drawable drawable) { int height = (int) app.getResources().getDimension(android.R.dimen.notification_large_icon_height); int width = (int) app.getResources().getDimension(android.R.dimen.notification_large_icon_width); diff --git a/OsmAnd/src/net/osmand/plus/openseamapsplugin/NauticalMapsPlugin.java b/OsmAnd/src/net/osmand/plus/openseamapsplugin/NauticalMapsPlugin.java index 7eb775c3a4..2db924aea3 100644 --- a/OsmAnd/src/net/osmand/plus/openseamapsplugin/NauticalMapsPlugin.java +++ b/OsmAnd/src/net/osmand/plus/openseamapsplugin/NauticalMapsPlugin.java @@ -42,7 +42,7 @@ public class NauticalMapsPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(net.osmand.plus.R.string.plugin_nautical_descr); } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java index 90da6cc65d..a9a3262216 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java @@ -378,7 +378,7 @@ public class OsmEditingPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.osm_editing_plugin_description); } diff --git a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java index 464e719a49..26a9a6d0a7 100644 --- a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java +++ b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java @@ -168,7 +168,7 @@ public class ParkingPositionPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.osmand_parking_plugin_description); } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java index e96edba607..d1696c82a1 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java @@ -89,7 +89,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { } @Override - public String getDescription() { + public CharSequence getDescription() { return app.getString(R.string.osmand_rastermaps_plugin_description); } diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index f8c25683db..ffd8bb4e83 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -801,7 +801,7 @@ public class ResourceManager { return warnings; } - private List getTravelRepositories() { + public List getTravelRepositories() { List fileNames = new ArrayList<>(travelRepositories.keySet()); Collections.sort(fileNames, Algorithms.getStringVersionComparator()); List res = new ArrayList<>(); @@ -814,7 +814,7 @@ public class ResourceManager { return res; } - private List getTravelRepositories(double topLat, double leftLon, double bottomLat, double rightLon) { + public List getTravelRepositories(double topLat, double leftLon, double bottomLat, double rightLon) { List fileNames = new ArrayList<>(travelRepositories.keySet()); Collections.sort(fileNames, Algorithms.getStringVersionComparator()); int leftX31 = MapUtils.get31TileNumberX(leftLon); diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java index 461f947592..8daf44e8e8 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java @@ -101,7 +101,8 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { DIRECTIONS(), PLAN_ROUTE(MuteSoundRoutingParameter.class, RouteSimulationItem.class, - GpxLocalRoutingParameter.class); + GpxLocalRoutingParameter.class, + ShowAlongTheRouteItem.class); private final Class[] excludeParameters; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java index 9f112b498e..9a5cdb7d79 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java @@ -92,6 +92,14 @@ public class ApplicationMode { .icon(R.drawable.ic_action_pedestrian_dark) .description(R.string.base_profile_descr_pedestrian).reg(); + public static final ApplicationMode TRUCK = create(ApplicationMode.CAR, R.string.app_mode_truck, "truck") + .icon(R.drawable.ic_action_truck_dark) + .description(R.string.app_mode_truck).reg(); + + public static final ApplicationMode MOTORCYCLE = create(ApplicationMode.CAR, R.string.app_mode_motorcycle, "motorcycle") + .icon(R.drawable.ic_action_motorcycle_dark) + .description(R.string.app_mode_motorcycle).reg(); + public static final ApplicationMode PUBLIC_TRANSPORT = createBase(R.string.app_mode_public_transport, "public_transport") .icon(R.drawable.ic_action_bus_dark) .description(R.string.base_profile_descr_public_transport).reg(); @@ -108,14 +116,6 @@ public class ApplicationMode { .icon(R.drawable.ic_action_skiing) .description(R.string.base_profile_descr_ski).reg(); - public static final ApplicationMode TRUCK = create(ApplicationMode.CAR, R.string.app_mode_truck, "truck") - .icon(R.drawable.ic_action_truck_dark) - .description(R.string.app_mode_truck).reg(); - - public static final ApplicationMode MOTORCYCLE = create(ApplicationMode.CAR, R.string.app_mode_motorcycle, "motorcycle") - .icon(R.drawable.ic_action_motorcycle_dark) - .description(R.string.app_mode_motorcycle).reg(); - public static List values(OsmandApplication app) { if (customizationListener == null) { customizationListener = new OsmAndAppCustomization.OsmAndAppCustomizationListener() { @@ -512,6 +512,14 @@ public class ApplicationMode { mode.app = app; mode.updateAppModeIcon(); } + if (app.getSettings().APP_MODE_ORDER.isSetForMode(PEDESTRIAN)) { + if (!app.getSettings().APP_MODE_ORDER.isSetForMode(TRUCK)) { + TRUCK.setOrder(PEDESTRIAN.getOrder() + 1); + } + if (!app.getSettings().APP_MODE_ORDER.isSetForMode(MOTORCYCLE)) { + MOTORCYCLE.setOrder(PEDESTRIAN.getOrder() + 1); + } + } } private static void initCustomModes(OsmandApplication app) { @@ -606,7 +614,7 @@ public class ApplicationMode { return gson.toJson(toModeBean()); } - public ApplicationModeBean toModeBean(){ + public ApplicationModeBean toModeBean() { ApplicationModeBean mb = new ApplicationModeBean(); mb.stringKey = stringKey; mb.userProfileName = getUserProfileName(); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java b/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java index 80242478e5..25586ef35a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ImpassableRoadsStorage.java @@ -12,6 +12,7 @@ import java.util.StringTokenizer; class ImpassableRoadsStorage extends SettingsMapPointsStorage { protected String roadsIdsKey; + protected String directionsKey; protected String appModeKey; public ImpassableRoadsStorage(OsmandSettings osmandSettings) { @@ -19,6 +20,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { pointsKey = OsmandSettings.IMPASSABLE_ROAD_POINTS; descriptionsKey = OsmandSettings.IMPASSABLE_ROADS_DESCRIPTIONS; roadsIdsKey = OsmandSettings.IMPASSABLE_ROADS_IDS; + directionsKey = OsmandSettings.IMPASSABLE_ROADS_DIRECTIONS; appModeKey = OsmandSettings.IMPASSABLE_ROADS_APP_MODE_KEYS; } @@ -37,6 +39,21 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { return list; } + public List getDirections(int size) { + List list = new ArrayList<>(); + String directions = getSettingsAPI().getString(getOsmandSettings().getGlobalPreferences(), directionsKey, ""); + if (directions.trim().length() > 0) { + StringTokenizer tok = new StringTokenizer(directions, ","); + while (tok.hasMoreTokens() && list.size() <= size) { + list.add(Double.parseDouble(tok.nextToken())); + } + } + while (list.size() < size) { + list.add(0.0); + } + return list; + } + public List getAppModeKeys(int size) { List list = new ArrayList<>(); String roadIds = getSettingsAPI().getString(getOsmandSettings().getGlobalPreferences(), appModeKey, ""); @@ -55,6 +72,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { public List getImpassableRoadsInfo() { List points = getPoints(); List roadIds = getRoadIds(points.size()); + List directions = getDirections(points.size()); List appModeKeys = getAppModeKeys(points.size()); List descriptions = getPointDescriptions(points.size()); @@ -68,6 +86,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { avoidRoadInfo.id = roadIds.get(i); avoidRoadInfo.latitude = latLon.getLatitude(); avoidRoadInfo.longitude = latLon.getLongitude(); + avoidRoadInfo.direction = directions.get(i); avoidRoadInfo.name = description.getName(); avoidRoadInfo.appModeKey = appModeKeys.get(i); avoidRoadsInfo.add(avoidRoadInfo); @@ -79,15 +98,17 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { public boolean addImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) { List points = getPoints(); List roadIds = getRoadIds(points.size()); + List directions = getDirections(points.size()); List appModeKeys = getAppModeKeys(points.size()); List descriptions = getPointDescriptions(points.size()); roadIds.add(0, avoidRoadInfo.id); + directions.add(0, avoidRoadInfo.direction); points.add(0, new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude)); appModeKeys.add(0, avoidRoadInfo.appModeKey); descriptions.add(0, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name))); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys, directions); } public boolean updateImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) { @@ -96,13 +117,15 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { int index = points.indexOf(new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude)); if (index != -1) { List roadIds = getRoadIds(points.size()); + List directions = getDirections(points.size()); List appModeKeys = getAppModeKeys(points.size()); List descriptions = getPointDescriptions(points.size()); roadIds.set(index, avoidRoadInfo.id); + directions.set(index, avoidRoadInfo.direction); appModeKeys.set(index, avoidRoadInfo.appModeKey); descriptions.set(index, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name))); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys, directions); } return false; } @@ -111,15 +134,17 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { public boolean deletePoint(int index) { List points = getPoints(); List roadIds = getRoadIds(points.size()); + List directions = getDirections(points.size()); List appModeKeys = getAppModeKeys(points.size()); List descriptions = getPointDescriptions(points.size()); if (index < points.size()) { points.remove(index); roadIds.remove(index); + directions.remove(index); appModeKeys.remove(index); descriptions.remove(index); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys, directions); } return false; } @@ -128,6 +153,7 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { public boolean deletePoint(LatLon latLon) { List points = getPoints(); List roadIds = getRoadIds(points.size()); + List directions = getDirections(points.size()); List appModeKeys = getAppModeKeys(points.size()); List descriptions = getPointDescriptions(points.size()); @@ -135,9 +161,10 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { if (index != -1) { points.remove(index); roadIds.remove(index); + directions.remove(index); appModeKeys.remove(index); descriptions.remove(index); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys, directions); } return false; } @@ -146,21 +173,23 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { public boolean movePoint(LatLon latLonEx, LatLon latLonNew) { List points = getPoints(); List roadIds = getRoadIds(points.size()); + List directions = getDirections(points.size()); List appModeKeys = getAppModeKeys(points.size()); List descriptions = getPointDescriptions(points.size()); int i = points.indexOf(latLonEx); if (i != -1) { points.set(i, latLonNew); - return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys); + return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys, directions); } else { return false; } } - public boolean saveAvoidRoadData(List points, List descriptions, - List roadIds, List appModeKeys) { - return savePoints(points, descriptions) && saveRoadIds(roadIds) && saveAppModeKeys(appModeKeys); + public boolean saveAvoidRoadData(List points, List descriptions, List roadIds, + List appModeKeys, List directions) { + return savePoints(points, descriptions) && saveRoadIds(roadIds) + && saveAppModeKeys(appModeKeys) && saveDirections(directions); } public boolean saveRoadIds(List roadIds) { @@ -177,6 +206,20 @@ class ImpassableRoadsStorage extends SettingsMapPointsStorage { .commit(); } + public boolean saveDirections(List directions) { + StringBuilder stringBuilder = new StringBuilder(); + Iterator iterator = directions.iterator(); + while (iterator.hasNext()) { + stringBuilder.append(iterator.next()); + if (iterator.hasNext()) { + stringBuilder.append(","); + } + } + return getSettingsAPI().edit(getOsmandSettings().getGlobalPreferences()) + .putString(directionsKey, stringBuilder.toString()) + .commit(); + } + public boolean saveAppModeKeys(List appModeKeys) { StringBuilder stringBuilder = new StringBuilder(); Iterator iterator = appModeKeys.iterator(); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index e5fa9065cd..fbac3348e8 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -978,7 +978,16 @@ public class OsmandSettings { ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.SKI, "ski"); } - public final CommonPreference ROUTE_SERVICE = new EnumStringPreference<>(this, "route_service", RouteService.OSMAND, RouteService.values()).makeProfile().cache(); + public final CommonPreference ROUTE_SERVICE = new EnumStringPreference(this, "route_service", RouteService.OSMAND, RouteService.values()) { + @Override + public RouteService getModeValue(ApplicationMode mode) { + if (mode == ApplicationMode.DEFAULT) { + return RouteService.STRAIGHT; + } else { + return super.getModeValue(mode); + } + } + }.makeProfile().cache(); { ROUTE_SERVICE.setModeDefaultValue(ApplicationMode.DEFAULT, RouteService.STRAIGHT); @@ -2097,6 +2106,7 @@ public class OsmandSettings { public static final String IMPASSABLE_ROAD_POINTS = "impassable_road_points"; public static final String IMPASSABLE_ROADS_DESCRIPTIONS = "impassable_roads_descriptions"; public static final String IMPASSABLE_ROADS_IDS = "impassable_roads_ids"; + public static final String IMPASSABLE_ROADS_DIRECTIONS = "impassable_roads_directions"; public static final String IMPASSABLE_ROADS_APP_MODE_KEYS = "impassable_roads_app_mode_keys"; public void backupPointToStart() { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/AvoidRoadsSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/AvoidRoadsSettingsItem.java index 6507ab874e..a65a60b2d7 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/AvoidRoadsSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/AvoidRoadsSettingsItem.java @@ -9,6 +9,7 @@ import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.helpers.AvoidSpecificRoads; +import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; @@ -19,16 +20,16 @@ import org.json.JSONObject; import java.util.ArrayList; import java.util.List; -public class AvoidRoadsSettingsItem extends CollectionSettingsItem { +public class AvoidRoadsSettingsItem extends CollectionSettingsItem { private OsmandSettings settings; private AvoidSpecificRoads specificRoads; - public AvoidRoadsSettingsItem(@NonNull OsmandApplication app, @NonNull List items) { + public AvoidRoadsSettingsItem(@NonNull OsmandApplication app, @NonNull List items) { super(app, null, items); } - public AvoidRoadsSettingsItem(@NonNull OsmandApplication app, @Nullable AvoidRoadsSettingsItem baseItem, @NonNull List items) { + public AvoidRoadsSettingsItem(@NonNull OsmandApplication app, @Nullable AvoidRoadsSettingsItem baseItem, @NonNull List items) { super(app, baseItem, items); } @@ -64,16 +65,16 @@ public class AvoidRoadsSettingsItem extends CollectionSettingsItem newItems = getNewItems(); + List newItems = getNewItems(); if (!newItems.isEmpty() || !duplicateItems.isEmpty()) { appliedItems = new ArrayList<>(newItems); - for (AvoidSpecificRoads.AvoidRoadInfo duplicate : duplicateItems) { + for (AvoidRoadInfo duplicate : duplicateItems) { LatLon latLon = new LatLon(duplicate.latitude, duplicate.longitude); if (settings.removeImpassableRoad(latLon)) { settings.addImpassableRoad(duplicate); } } - for (AvoidSpecificRoads.AvoidRoadInfo avoidRoad : appliedItems) { + for (AvoidRoadInfo avoidRoad : appliedItems) { settings.addImpassableRoad(avoidRoad); } specificRoads.loadImpassableRoads(); @@ -82,8 +83,8 @@ public class AvoidRoadsSettingsItem extends CollectionSettingsItem existingTravelBooks = new ArrayList<>(); - private List popularArticles = new ArrayList(); + private List popularArticles = new ArrayList<>(); public TravelDbHelper(OsmandApplication application) { @@ -126,6 +126,7 @@ public class TravelDbHelper implements TravelHelper { return false; } + @Override public TravelLocalDataHelper getBookmarksHelper() { return localDataHelper; } @@ -135,6 +136,7 @@ public class TravelDbHelper implements TravelHelper { return selectedTravelBook != null; } + @Override public void initializeDataOnAppStartup() { List files = getPossibleFiles(); String travelBook = application.getSettings().SELECTED_TRAVEL_BOOK.get(); @@ -168,12 +170,14 @@ public class TravelDbHelper implements TravelHelper { return null; } + @Override public void initializeDataToDisplay() { localDataHelper.refreshCachedData(); loadPopularArticles(); } + @Override public String getSelectedTravelBookName() { if (selectedTravelBook != null) { return selectedTravelBook.getName(); @@ -210,8 +214,9 @@ public class TravelDbHelper implements TravelHelper { } } + @Override @NonNull - public List search(final String searchQuery) { + public List search(@NonNull String searchQuery) { List res = new ArrayList<>(); SQLiteConnection conn = openConnection(); String[] queries = searchQuery.replace('_', ' ').replace('/', ' ').split(" "); @@ -260,6 +265,7 @@ public class TravelDbHelper implements TravelHelper { return list; } + @Override @NonNull public List getPopularArticles() { return popularArticles; @@ -270,7 +276,7 @@ public class TravelDbHelper implements TravelHelper { String language = application.getLanguage(); SQLiteConnection conn = openConnection(); if (conn == null) { - popularArticles = new ArrayList(); + popularArticles = new ArrayList<>(); return popularArticles; } String LANG_WHERE = " WHERE " + ARTICLES_COL_LANG + " = '" + language + "'"; @@ -376,7 +382,7 @@ public class TravelDbHelper implements TravelHelper { return res; } - private void sortSearchResults(final String searchQuery, List list) { + private void sortSearchResults(@NonNull final String searchQuery, @NonNull List list) { Collections.sort(list, new Comparator() { @Override public int compare(WikivoyageSearchResult o1, WikivoyageSearchResult o2) { @@ -444,8 +450,9 @@ public class TravelDbHelper implements TravelHelper { } @NonNull + @Override public LinkedHashMap> getNavigationMap( - final TravelArticle article) { + @NonNull final TravelArticle article) { String lang = article.getLang(); String title = article.getTitle(); if (TextUtils.isEmpty(lang) || TextUtils.isEmpty(title)) { @@ -533,8 +540,9 @@ public class TravelDbHelper implements TravelHelper { return res; } + @Override @Nullable - public TravelArticle getArticleById(String routeId, String lang) { + public TravelArticle getArticleById(@NonNull String routeId, @NonNull String lang) { TravelArticle res = null; SQLiteConnection conn = openConnection(); if (conn != null && !Algorithms.isEmpty(routeId)) { @@ -550,8 +558,9 @@ public class TravelDbHelper implements TravelHelper { return res; } + @Override @Nullable - public TravelArticle getArticleByTitle(String title, String lang) { + public TravelArticle getArticleByTitle(@NonNull String title, @NonNull String lang) { TravelArticle res = null; SQLiteConnection conn = openConnection(); if (conn != null) { @@ -567,7 +576,9 @@ public class TravelDbHelper implements TravelHelper { return res; } - public String getArticleId(String title, String lang) { + @NonNull + @Override + public String getArticleId(@NonNull String title, @NonNull String lang) { String res = ""; SQLiteConnection conn = openConnection(); if (conn != null) { @@ -585,7 +596,8 @@ public class TravelDbHelper implements TravelHelper { } @NonNull - public ArrayList getArticleLangs(String routeId) { + @Override + public ArrayList getArticleLangs(@NonNull String routeId) { ArrayList res = new ArrayList<>(); SQLiteConnection conn = openConnection(); if (conn != null) { @@ -652,12 +664,16 @@ public class TravelDbHelper implements TravelHelper { return nm.substring(0, nm.indexOf('.')).replace('_', ' '); } - public String getGPXName(TravelArticle article) { + @NonNull + @Override + public String getGPXName(@NonNull final TravelArticle article) { return article.getTitle().replace('/', '_').replace('\'', '_') .replace('\"', '_') + IndexConstants.GPX_FILE_EXT; } - public File createGpxFile(TravelArticle article) { + @NonNull + @Override + public File createGpxFile(@NonNull final TravelArticle article) { final GPXFile gpx = article.getGpxFile(); File file = application.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article)); if (!file.exists()) { diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java index 79df7bdfeb..b55c398817 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java @@ -3,11 +3,8 @@ package net.osmand.plus.wikivoyage.data; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.plus.OsmandApplication; - import java.io.File; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -22,25 +19,31 @@ public interface TravelHelper { boolean isAnyTravelBookPresent(); @NonNull - List search(final String searchQuery); + List search(@NonNull String searchQuery); @NonNull List getPopularArticles(); - Map> getNavigationMap( - final TravelArticle article); + @NonNull + Map> getNavigationMap(@NonNull final TravelArticle article); - TravelArticle getArticleById(String routeId, String lang); + @Nullable + TravelArticle getArticleById(@NonNull String routeId, @NonNull String lang); - TravelArticle getArticleByTitle(String title, String lang); + @Nullable + TravelArticle getArticleByTitle(@NonNull String title, @NonNull String lang); - String getArticleId(String title, String lang); + @NonNull + String getArticleId(@NonNull String title, @NonNull String lang); - ArrayList getArticleLangs(String articleId); + @NonNull + ArrayList getArticleLangs(@NonNull String routeId); - String getGPXName(TravelArticle article); + @NonNull + String getGPXName(@NonNull final TravelArticle article); - File createGpxFile(TravelArticle article); + @NonNull + File createGpxFile(@NonNull final TravelArticle article); // TODO: this method should be deleted once TravelDBHelper is deleted // For TravelOBFHelper it could always return "" and should be no problem diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index 5743041407..d64bed4ebe 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -118,6 +118,7 @@ public class TravelLocalDataHelper { saved.content = WikiArticleHelper.getPartialContent(article.getContent()); saved.lat = article.lat; saved.lon = article.lon; + saved.routeId = article.routeId; savedArticles.add(saved); dbHelper.addSavedArticle(saved); notifySavedUpdated(); @@ -168,7 +169,7 @@ public class TravelLocalDataHelper { private static class WikivoyageLocalDataDbHelper { - private static final int DB_VERSION = 4; + private static final int DB_VERSION = 5; private static final String DB_NAME = "wikivoyage_local_data"; private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history"; @@ -202,6 +203,7 @@ public class TravelLocalDataHelper { private static final String BOOKMARKS_COL_TRAVEL_BOOK = "travel_book"; private static final String BOOKMARKS_COL_LAT = "lat"; private static final String BOOKMARKS_COL_LON = "lon"; + private static final String BOOKMARKS_COL_ROUTE_ID = "route_id"; private static final String BOOKMARKS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " + BOOKMARKS_TABLE_NAME + " (" + @@ -212,7 +214,8 @@ public class TravelLocalDataHelper { BOOKMARKS_COL_PARTIAL_CONTENT + " TEXT, " + BOOKMARKS_COL_TRAVEL_BOOK + " TEXT, " + BOOKMARKS_COL_LAT + " double, " + - BOOKMARKS_COL_LON + " double);"; + BOOKMARKS_COL_LON + " double, " + + BOOKMARKS_COL_ROUTE_ID + " TEXT" + ");"; private static final String BOOKMARKS_TABLE_SELECT = "SELECT " + BOOKMARKS_COL_ARTICLE_TITLE + ", " + @@ -221,7 +224,8 @@ public class TravelLocalDataHelper { BOOKMARKS_COL_IMAGE_TITLE + ", " + BOOKMARKS_COL_PARTIAL_CONTENT + ", " + BOOKMARKS_COL_LAT + ", " + - BOOKMARKS_COL_LON + + BOOKMARKS_COL_LON + ", " + + BOOKMARKS_COL_ROUTE_ID + " FROM " + BOOKMARKS_TABLE_NAME; private final OsmandApplication context; @@ -271,6 +275,9 @@ public class TravelLocalDataHelper { conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_LAT + " double"); conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_LON + " double"); } + if (oldVersion < 5) { + conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_ROUTE_ID + " TEXT"); + } } @NonNull @@ -420,11 +427,12 @@ public class TravelLocalDataHelper { BOOKMARKS_COL_PARTIAL_CONTENT + ", " + BOOKMARKS_COL_TRAVEL_BOOK + ", " + BOOKMARKS_COL_LAT + ", " + - BOOKMARKS_COL_LON + - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + BOOKMARKS_COL_LON + ", " + + BOOKMARKS_COL_ROUTE_ID + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; conn.execSQL(query, new Object[]{article.title, article.lang, article.aggregatedPartOf, article.imageTitle, article.content, - travelBook, article.lat, article.lon}); + travelBook, article.lat, article.lon, article.routeId}); } finally { conn.close(); } @@ -475,6 +483,7 @@ public class TravelLocalDataHelper { res.content = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_PARTIAL_CONTENT)); res.lat = cursor.getDouble(cursor.getColumnIndex(BOOKMARKS_COL_LAT)); res.lon = cursor.getDouble(cursor.getColumnIndex(BOOKMARKS_COL_LON)); + res.routeId = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_ROUTE_ID)); return res; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index df54776ab8..e1dc65ebfd 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -3,116 +3,385 @@ package net.osmand.plus.wikivoyage.data; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.Collator; import net.osmand.CollatorStringMatcher; import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.IndexConstants; +import net.osmand.OsmAndCollator; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter; import net.osmand.data.Amenity; -import net.osmand.data.MapObject; +import net.osmand.data.LatLon; +import net.osmand.osm.PoiCategory; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.api.SQLiteAPI; import net.osmand.util.Algorithms; +import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Map; +import static net.osmand.CollatorStringMatcher.StringMatcherMode.CHECK_EQUALS_FROM_SPACE; + public class TravelObfHelper implements TravelHelper { private static final Log LOG = PlatformUtil.getLog(TravelObfHelper.class); + public static final String ROUTE_ARTICLE = "route_article"; + public static final int SEARCH_RADIUS = 100000; + private final OsmandApplication app; + private final Collator collator; - private final OsmandApplication application; + private List popularArticles = new ArrayList<>(); + private final Map cachedArticles; + private final TravelLocalDataHelper localDataHelper; - private TravelLocalDataHelper localDataHelper; - - private List popularArticles = new ArrayList(); - - - public TravelObfHelper(OsmandApplication application) { - this.application = application; - localDataHelper = new TravelLocalDataHelper(application); + public TravelObfHelper(OsmandApplication app) { + this.app = app; + collator = OsmAndCollator.primaryCollator(); + localDataHelper = new TravelLocalDataHelper(app); + cachedArticles = new HashMap<>(); } + @Override public TravelLocalDataHelper getBookmarksHelper() { return localDataHelper; } @Override public void initializeDataOnAppStartup() { - } @Override - public boolean isAnyTravelBookPresent() { - return checkIfObfFileExists(application); - } - - public void initializeDataToDisplay() { localDataHelper.refreshCachedData(); loadPopularArticles(); } - @NonNull - public List search(final String searchQuery) { - List res = new ArrayList<>(); + public List loadPopularArticles() { + String language = app.getLanguage(); + List popularArticles = new ArrayList<>(); + for (BinaryMapIndexReader travelBookReader : getTravelBookReaders()) { + try { + final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); + BinaryMapIndexReader.SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest( + location, SEARCH_RADIUS, -1, getSearchRouteArticleFilter(), null); + List amenities = travelBookReader.searchPoi(req); + if (amenities.size() > 0) { + for (Amenity a : amenities) { + if (!Algorithms.isEmpty(a.getName(language))) { + TravelArticle article = readArticle(a, language); + popularArticles.add(article); + cachedArticles.put(article.routeId, article); + if (popularArticles.size() >= 100) { + break; + } + } + } + Collections.sort(popularArticles, new Comparator() { + @Override + public int compare(TravelArticle article1, TravelArticle article2) { + int d1 = (int) (MapUtils.getDistance(article1.getLat(), article1.getLon(), + location.getLatitude(), location.getLongitude())); + int d2 = (int) (MapUtils.getDistance(article2.getLat(), article2.getLon(), + location.getLatitude(), location.getLongitude())); + return d1 < d2 ? -1 : (d1 == d2 ? 0 : 1); + } + }); + } + } catch (Exception e) { + LOG.error(e.getMessage()); + } + } + this.popularArticles = popularArticles; + return popularArticles; + } + + SearchPoiTypeFilter getSearchRouteArticleFilter() { + return new SearchPoiTypeFilter() { + @Override + public boolean accept(PoiCategory type, String subcategory) { + return subcategory.equals(ROUTE_ARTICLE); + } + + @Override + public boolean isEmpty() { + return false; + } + }; + } + + private TravelArticle readArticle(@NonNull Amenity amenity, @Nullable String lang) { + TravelArticle res = new TravelArticle(); + String title = Algorithms.isEmpty(amenity.getName(lang)) ? amenity.getName() : amenity.getName(lang); + if (Algorithms.isEmpty(title)) { + Map namesMap = amenity.getNamesMap(true); + if (!namesMap.isEmpty()) { + lang = namesMap.keySet().iterator().next(); + title = amenity.getName(lang); + } + } + res.title = title; + res.content = amenity.getDescription(lang); + res.isPartOf = emptyIfNull(amenity.getTagContent(Amenity.IS_PART, lang)); + res.lat = amenity.getLocation().getLatitude(); + res.lon = amenity.getLocation().getLongitude(); + res.imageTitle = emptyIfNull(amenity.getTagContent(Amenity.IMAGE_TITLE, lang)); + res.routeId = getRouteId(amenity); + res.originalId = 0; + res.lang = lang; + res.contentsJson = emptyIfNull(amenity.getTagContent(Amenity.CONTENT_JSON, lang)); + res.aggregatedPartOf = emptyIfNull(amenity.getTagContent(Amenity.IS_AGGR_PART, lang)); return res; } + private String emptyIfNull(String text) { + return text == null ? "" : text; + } + + private String getRouteId(Amenity amenity) { + return amenity.getTagContent(Amenity.ROUTE_ID, null); + } + + @Override + public boolean isAnyTravelBookPresent() { + return !Algorithms.isEmpty(getTravelBookReaders()); + } + @NonNull + @Override + public List search(@NonNull String searchQuery) { + List res = new ArrayList<>(); + List searchObjects = null; + for (BinaryMapIndexReader reader : app.getResourceManager().getTravelRepositories()) { + try { + BinaryMapIndexReader.SearchRequest searchRequest = BinaryMapIndexReader. + buildSearchPoiRequest(0, 0, searchQuery, + 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchRouteArticleFilter(), null, null); + + searchObjects = reader.searchPoiByName(searchRequest); + } catch (IOException e) { + LOG.error(e); + } + } + if (!Algorithms.isEmpty(searchObjects)) { + String baseLng = app.getLanguage(); + for (Amenity obj : searchObjects) { + WikivoyageSearchResult r = new WikivoyageSearchResult(); + TravelArticle article = readArticle(obj, baseLng); + r.articleTitles = new ArrayList<>(Collections.singletonList(article.title)); + r.imageTitle = article.imageTitle; + r.routeId = article.routeId; + r.isPartOf = new ArrayList<>(Collections.singletonList(article.isPartOf)); + r.langs = new ArrayList<>(Collections.singletonList(baseLng)); + res.add(r); + cachedArticles.put(article.routeId, article); + } + res = new ArrayList<>(groupSearchResultsByRouteId(res)); + sortSearchResults(res); + } + return res; + } + + private void sortSearchResults(@NonNull List list) { + Collections.sort(list, new Comparator() { + + @Override + public int compare(WikivoyageSearchResult res1, WikivoyageSearchResult res2) { + return collator.compare(res1.articleTitles.get(0), res2.articleTitles.get(0)); + } + }); + } + + @NonNull + private Collection groupSearchResultsByRouteId(@NonNull List res) { + String baseLng = app.getLanguage(); + Map wikivoyage = new HashMap<>(); + for (WikivoyageSearchResult rs : res) { + WikivoyageSearchResult prev = wikivoyage.get(rs.routeId); + if (prev != null) { + int insInd = prev.langs.size(); + if (rs.langs.get(0).equals(baseLng)) { + insInd = 0; + } else if (rs.langs.get(0).equals("en")) { + if (!prev.langs.get(0).equals(baseLng)) { + insInd = 0; + } else { + insInd = 1; + } + } + prev.articleTitles.add(insInd, rs.articleTitles.get(0)); + prev.langs.add(insInd, rs.langs.get(0)); + prev.isPartOf.add(insInd, rs.isPartOf.get(0)); + } else { + wikivoyage.put(rs.routeId, rs); + } + } + return wikivoyage.values(); + } + + @NonNull + @Override public List getPopularArticles() { return popularArticles; } + @NonNull @Override - public Map> getNavigationMap(TravelArticle article) { - return null; + public Map> getNavigationMap(@NonNull final TravelArticle article) { + return Collections.emptyMap(); } @Override - public TravelArticle getArticleById(String routeId, String lang) { - return null; + public TravelArticle getArticleById(@NonNull String routeId, @NonNull String lang) { + TravelArticle article = cachedArticles.get(routeId); + if (article != null) { + return article; + } else { + return getArticleByIdFromTravelBooks(routeId, lang); + } } - @Override - public TravelArticle getArticleByTitle(String title, String lang) { - return null; + private TravelArticle getArticleByIdFromTravelBooks(final String routeId, final String lang) { + TravelArticle article = null; + final List amenities = new ArrayList<>(); + for (BinaryMapIndexReader travelBookReader : getTravelBookReaders()) { + try { + BinaryMapIndexReader.SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest( + 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, -1, getSearchRouteArticleFilter(), + new ResultMatcher() { + boolean done = false; + + @Override + public boolean publish(Amenity amenity) { + if (getRouteId(amenity).equals(routeId)) { + amenities.add(amenity); + done = true; + } + return false; + } + + @Override + public boolean isCancelled() { + return done; + } + }); + + travelBookReader.searchPoi(req); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + if (!amenities.isEmpty()) { + article = readArticle(amenities.get(0), lang); + cachedArticles.put(article.routeId, article); + } + } + return article; } + @Nullable @Override - public String getArticleId(String title, String lang) { - return null; + public TravelArticle getArticleByTitle(@NonNull final String title, @NonNull final String lang) { + TravelArticle article = null; + final List amenities = new ArrayList<>(); + for (BinaryMapIndexReader travelBookReader : getTravelBookReaders()) { + try { + BinaryMapIndexReader.SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest( + 0, 0, title, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchRouteArticleFilter(), + new ResultMatcher() { + boolean done = false; + + @Override + public boolean publish(Amenity amenity) { + if (CollatorStringMatcher.cmatches(collator, title, amenity.getName(lang), CHECK_EQUALS_FROM_SPACE)) { + amenities.add(amenity); + done = true; + } + return false; + } + + @Override + public boolean isCancelled() { + return done; + } + }, null); + + travelBookReader.searchPoiByName(req); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + if (!amenities.isEmpty()) { + article = readArticle(amenities.get(0), lang); + cachedArticles.put(article.routeId, article); + } + } + return article; } - @Override - public ArrayList getArticleLangs(String articleId) { - return null; + private List getTravelBookReaders() { + if (!app.isApplicationInitializing()) { + return app.getResourceManager().getTravelRepositories(); + } else { + return new ArrayList<>(); + } } @NonNull - public List loadPopularArticles() { - popularArticles = new ArrayList<>(); - return popularArticles; + @Override + public String getArticleId(@NonNull String title, @NonNull String lang) { + TravelArticle a = null; + for (TravelArticle article : cachedArticles.values()) { + if (article.getTitle().equals(title)) { + a = article; + break; + } + } + if (a == null) { + TravelArticle article = getArticleByTitle(title, lang); + if (article != null) { + a = article; + } + } + return a != null && a.getRouteId() != null ? a.getRouteId() : ""; } - public String getGPXName(TravelArticle article) { + @NonNull + @Override + public ArrayList getArticleLangs(@NonNull String routeId) { + ArrayList res = new ArrayList<>(); + res.add("en"); + for (TravelArticle article : popularArticles) { + if (article.getRouteId().equals(routeId)) { + res.add(article.getLang()); + } + } + return res; + } + + @NonNull + @Override + public String getGPXName(@NonNull final TravelArticle article) { return article.getTitle().replace('/', '_').replace('\'', '_') .replace('\"', '_') + IndexConstants.GPX_FILE_EXT; } - public File createGpxFile(TravelArticle article) { - final GPXUtilities.GPXFile gpx = article.getGpxFile(); - File file = application.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article)); + @NonNull + @Override + public File createGpxFile(@NonNull final TravelArticle article) { + final GPXFile gpx = article.getGpxFile(); + File file = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article)); if (!file.exists()) { GPXUtilities.writeGpxFile(file, gpx); } @@ -121,18 +390,6 @@ public class TravelObfHelper implements TravelHelper { @Override public String getSelectedTravelBookName() { - return null; + return ""; } - - public static boolean checkIfObfFileExists(OsmandApplication app) { - File[] files = app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).listFiles(); - if (files != null) { - for (File f : files) { - if (f.getName().contains(IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT)) { - return true; - } - } - } - return false; - } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java index 73da16bf2e..45047e2e1c 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java @@ -38,6 +38,7 @@ import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelHelper; +import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import net.osmand.plus.wikivoyage.search.WikivoyageSearchDialogFragment; import net.osmand.util.Algorithms; @@ -45,7 +46,8 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; -public class WikivoyageExploreActivity extends TabActivity implements DownloadEvents, OnDialogFragmentResultListener { +public class WikivoyageExploreActivity extends TabActivity implements DownloadEvents, OnDialogFragmentResultListener, + TravelLocalDataHelper.Listener { private static final String TAB_SELECTED = "tab_selected"; private static final String ROUTE_ID_KEY = "route_id_key"; @@ -59,7 +61,6 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv protected List> fragments = new ArrayList<>(); private LockableViewPager viewPager; - private boolean updateNeeded; @Override public void onCreate(Bundle savedInstanceState) { @@ -190,6 +191,7 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv setIntent(null); } getMyApplication().getDownloadThread().setUiActivity(this); + app.getTravelHelper().getBookmarksHelper().addListener(this); } protected void parseLaunchIntentLink(Uri data) { @@ -211,6 +213,7 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv protected void onPause() { super.onPause(); getMyApplication().getDownloadThread().resetUiActivity(this); + app.getTravelHelper().getBookmarksHelper().removeListener(this); } @Nullable @@ -225,7 +228,7 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv } @Nullable - private SavedArticlesTabFragment getSavedArticlesTabFragment() { + public SavedArticlesTabFragment getSavedArticlesTabFragment() { for (WeakReference ref : fragments) { Fragment f = ref.get(); if (f instanceof SavedArticlesTabFragment) { @@ -319,16 +322,13 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv updateFragments(); } - private void updateFragments() { + public void updateFragments() { ExploreTabFragment exploreTabFragment = getExploreTabFragment(); SavedArticlesTabFragment savedArticlesTabFragment = getSavedArticlesTabFragment(); if (exploreTabFragment != null && savedArticlesTabFragment != null && exploreTabFragment.isAdded() && savedArticlesTabFragment.isAdded()) { exploreTabFragment.populateData(); savedArticlesTabFragment.savedArticlesUpdated(); - updateNeeded = false; - } else { - updateNeeded = true; } } @@ -353,9 +353,12 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv } public void onTabFragmentResume(Fragment fragment) { - if (updateNeeded) { - updateFragments(); - } + updateFragments(); + } + + @Override + public void savedArticlesUpdated() { + updateFragments(); } private static class LoadWikivoyageData extends AsyncTask {