Merge branch 'master' into travel_obf_gpx

# Conflicts:
#	OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java
This commit is contained in:
Dima-1 2021-01-08 13:31:56 +02:00
commit 279349919d
77 changed files with 1031 additions and 349 deletions

View file

@ -2544,7 +2544,7 @@ public class GPXUtilities {
if (maxlat == null) { if (maxlat == null) {
maxlat = parser.getAttributeValue("", "maxLat"); maxlat = parser.getAttributeValue("", "maxLat");
} }
if (maxlat == null) { if (maxlon == null) {
maxlon = parser.getAttributeValue("", "maxLon"); maxlon = parser.getAttributeValue("", "maxLon");
} }

View file

@ -1,11 +1,5 @@
package net.osmand.binary; package net.osmand.binary;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion; import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion;
import net.osmand.binary.BinaryMapAddressReaderAdapter.CitiesBlock; import net.osmand.binary.BinaryMapAddressReaderAdapter.CitiesBlock;
@ -29,6 +23,12 @@ import net.osmand.binary.OsmandIndex.TransportPart;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
public class CachedOsmandIndexes { public class CachedOsmandIndexes {
private OsmAndStoredIndex storedIndex; private OsmAndStoredIndex storedIndex;
@ -46,10 +46,12 @@ public class CachedOsmandIndexes {
storedIndexBuilder.setDateCreated(System.currentTimeMillis()); storedIndexBuilder.setDateCreated(System.currentTimeMillis());
if (storedIndex != null) { if (storedIndex != null) {
for (FileIndex ex : storedIndex.getFileIndexList()) { for (FileIndex ex : storedIndex.getFileIndexList()) {
if (!ex.getFileName().equals(f.getName())) {
storedIndexBuilder.addFileIndex(ex); storedIndexBuilder.addFileIndex(ex);
} }
} }
} }
}
FileIndex.Builder fileIndex = OsmandIndex.FileIndex.newBuilder(); FileIndex.Builder fileIndex = OsmandIndex.FileIndex.newBuilder();
long d = reader.getDateCreated(); long d = reader.getDateCreated();
@ -172,10 +174,10 @@ public class CachedOsmandIndexes {
routing.addSubregions(rpart); routing.addSubregions(rpart);
} }
public BinaryMapIndexReader getReader(File f) throws IOException { public BinaryMapIndexReader getReader(File f, boolean useStoredIndex) throws IOException {
RandomAccessFile mf = new RandomAccessFile(f.getPath(), "r"); RandomAccessFile mf = new RandomAccessFile(f.getPath(), "r");
FileIndex found = null; FileIndex found = null;
if (storedIndex != null) { if (storedIndex != null && useStoredIndex) {
for (int i = 0; i < storedIndex.getFileIndexCount(); i++) { for (int i = 0; i < storedIndex.getFileIndexCount(); i++) {
FileIndex fi = storedIndex.getFileIndex(i); FileIndex fi = storedIndex.getFileIndex(i);
if (f.length() == fi.getSize() && f.getName().equals(fi.getFileName())) { if (f.length() == fi.getSize() && f.getName().equals(fi.getFileName())) {

View file

@ -533,16 +533,19 @@ public class BinaryRoutePlanner {
long fid = to.getRoad().getId(); long fid = to.getRoad().getId();
for (int i = 0; i < from.getRoad().getRestrictionLength(); i++) { for (int i = 0; i < from.getRoad().getRestrictionLength(); i++) {
long id = from.getRoad().getRestrictionId(i); long id = from.getRoad().getRestrictionId(i);
if (fid == id) {
int tp = from.getRoad().getRestrictionType(i); int tp = from.getRoad().getRestrictionType(i);
if (tp == MapRenderingTypes.RESTRICTION_NO_LEFT_TURN || if (fid == id) {
tp == MapRenderingTypes.RESTRICTION_NO_RIGHT_TURN || if (tp == MapRenderingTypes.RESTRICTION_NO_LEFT_TURN
tp == MapRenderingTypes.RESTRICTION_NO_STRAIGHT_ON || || tp == MapRenderingTypes.RESTRICTION_NO_RIGHT_TURN
tp == MapRenderingTypes.RESTRICTION_NO_U_TURN) { || tp == MapRenderingTypes.RESTRICTION_NO_STRAIGHT_ON
|| tp == MapRenderingTypes.RESTRICTION_NO_U_TURN) {
return false; return false;
} }
break; break;
} }
if (tp == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) {
return false;
}
} }
} }
return true; return true;
@ -647,24 +650,36 @@ public class BinaryRoutePlanner {
int type = -1; int type = -1;
if (!reverseWay) { if (!reverseWay) {
for (int i = 0; i < road.getRestrictionLength(); i++) { for (int i = 0; i < road.getRestrictionLength(); i++) {
int rt = road.getRestrictionType(i);
long rv = road.getRestrictionVia(i);
if (road.getRestrictionId(i) == next.road.id) { if (road.getRestrictionId(i) == next.road.id) {
if(!via || road.getRestrictionVia(i) == viaId) { if (!via || rv == viaId) {
type = road.getRestrictionType(i); type = rt;
break; break;
} }
} }
if (rv == viaId && rt == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) {
type = MapRenderingTypes.RESTRICTION_NO_STRAIGHT_ON;
break;
}
} }
} else { } else {
for (int i = 0; i < next.road.getRestrictionLength(); i++) { for (int i = 0; i < next.road.getRestrictionLength(); i++) {
int rt = next.road.getRestrictionType(i); int rt = next.road.getRestrictionType(i);
long rv = next.road.getRestrictionVia(i);
long restrictedTo = next.road.getRestrictionId(i); long restrictedTo = next.road.getRestrictionId(i);
if (restrictedTo == road.id) { if (restrictedTo == road.id) {
if(!via || next.road.getRestrictionVia(i) == viaId) { if (!via || rv == viaId) {
type = rt; type = rt;
break; break;
} }
} }
if (rv == viaId && rt == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) {
type = MapRenderingTypes.RESTRICTION_NO_STRAIGHT_ON;
break;
}
// Check if there is restriction only to the other than current road // Check if there is restriction only to the other than current road
if (rt == MapRenderingTypes.RESTRICTION_ONLY_RIGHT_TURN || rt == MapRenderingTypes.RESTRICTION_ONLY_LEFT_TURN if (rt == MapRenderingTypes.RESTRICTION_ONLY_RIGHT_TURN || rt == MapRenderingTypes.RESTRICTION_ONLY_LEFT_TURN
|| rt == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) { || rt == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) {

View file

@ -34,6 +34,7 @@ import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
@ -41,6 +42,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -68,6 +70,9 @@ public class SearchUICore {
private static boolean debugMode = false; private static boolean debugMode = false;
private static final Set<String> FILTER_DUPLICATE_POI_SUBTYPE = new TreeSet<String>(
Arrays.asList("building", "internet_access_yes"));
public SearchUICore(MapPoiTypes poiTypes, String locale, boolean transliterate) { public SearchUICore(MapPoiTypes poiTypes, String locale, boolean transliterate) {
this.poiTypes = poiTypes; this.poiTypes = poiTypes;
taskQueue = new LinkedBlockingQueue<Runnable>(); taskQueue = new LinkedBlockingQueue<Runnable>();
@ -244,12 +249,17 @@ public class SearchUICore {
String type2 = a2.getType().getKeyName(); String type2 = a2.getType().getKeyName();
String subType1 = a1.getSubType(); String subType1 = a1.getSubType();
String subType2 = a2.getSubType(); String subType2 = a2.getSubType();
if(a1.getId().longValue() == a2.getId().longValue() && (subType1.equals("building") || subType2.equals("building"))) {
boolean isEqualId = a1.getId().longValue() == a2.getId().longValue();
if (isEqualId && (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1)
|| FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2))) {
return true; return true;
}
if (!type1.equals(type2)) { } else if (!type1.equals(type2)) {
return false; return false;
} }
if (type1.equals("natural")) { if (type1.equals("natural")) {
similarityRadius = 50000; similarityRadius = 50000;
} else if (subType1.equals(subType2)) { } else if (subType1.equals(subType2)) {
@ -987,15 +997,29 @@ public class SearchUICore {
// here 2 points are amenity // here 2 points are amenity
Amenity a1 = (Amenity) o1.object; Amenity a1 = (Amenity) o1.object;
Amenity a2 = (Amenity) o2.object; Amenity a2 = (Amenity) o2.object;
String type1 = a1.getType().getKeyName(); String type1 = a1.getType().getKeyName();
String type2 = a2.getType().getKeyName(); String type2 = a2.getType().getKeyName();
int cmp = c.collator.compare(type1, type2); String subType1 = a1.getSubType() == null ? "" : a1.getSubType();
String subType2 = a2.getSubType() == null ? "" : a2.getSubType();
int cmp = 0;
if (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType1)) {
cmp = 1;
} else if (FILTER_DUPLICATE_POI_SUBTYPE.contains(subType2)) {
cmp = -1;
}
if (cmp != 0) {
return cmp;
}
cmp = c.collator.compare(type1, type2);
if (cmp != 0) { if (cmp != 0) {
return cmp; return cmp;
} }
String subType1 = a1.getSubType() == null ? "" : a1.getSubType();
String subType2 = a2.getSubType() == null ? "" : a2.getSubType();
cmp = c.collator.compare(subType1, subType2); cmp = c.collator.compare(subType1, subType2);
if (cmp != 0) { if (cmp != 0) {
return cmp; return cmp;

View file

@ -15,13 +15,11 @@ import java.util.TreeSet;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.LatLon;
import org.junit.Assert; import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
@ -76,12 +74,22 @@ public class RouteTestingTest {
} else { } else {
binaryMapIndexReaders = new BinaryMapIndexReader[]{new BinaryMapIndexReader(raf, new File(fl))}; binaryMapIndexReaders = new BinaryMapIndexReader[]{new BinaryMapIndexReader(raf, new File(fl))};
} }
for (int planRoadDirection = -1; planRoadDirection <= 1; planRoadDirection++) {
if (params.containsKey("wrongPlanRoadDirection")) {
if (params.get("wrongPlanRoadDirection").equals(planRoadDirection + "")) {
continue;
}
}
RoutingConfiguration config = builder.build(params.containsKey("vehicle") ? params.get("vehicle") : "car", RoutingConfiguration config = builder.build(params.containsKey("vehicle") ? params.get("vehicle") : "car",
RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3, params); RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3, params);
config.planRoadDirection = planRoadDirection;
RoutingContext ctx = fe.buildRoutingContext(config, null, binaryMapIndexReaders, RoutingContext ctx = fe.buildRoutingContext(config, null, binaryMapIndexReaders,
RoutePlannerFrontEnd.RouteCalculationMode.NORMAL); RoutePlannerFrontEnd.RouteCalculationMode.NORMAL);
ctx.leftSideNavigation = false; ctx.leftSideNavigation = false;
List<RouteSegmentResult> routeSegments = fe.searchRoute(ctx, te.getStartPoint(), te.getEndPoint(), te.getTransitPoint()); List<RouteSegmentResult> routeSegments = fe.searchRoute(ctx, te.getStartPoint(), te.getEndPoint(),
te.getTransitPoint());
Set<Long> reachedSegments = new TreeSet<Long>(); Set<Long> reachedSegments = new TreeSet<Long>();
Assert.assertNotNull(routeSegments); Assert.assertNotNull(routeSegments);
int prevSegment = -1; int prevSegment = -1;
@ -89,7 +97,8 @@ public class RouteTestingTest {
if (i == routeSegments.size() || routeSegments.get(i).getTurnType() != null) { if (i == routeSegments.size() || routeSegments.get(i).getTurnType() != null) {
if (prevSegment >= 0) { if (prevSegment >= 0) {
String name = routeSegments.get(prevSegment).getDescription(); String name = routeSegments.get(prevSegment).getDescription();
long segmentId = routeSegments.get(prevSegment).getObject().getId() >> (RouteResultPreparation.SHIFT_ID); long segmentId = routeSegments.get(prevSegment).getObject()
.getId() >> (RouteResultPreparation.SHIFT_ID);
System.out.println("segmentId: " + segmentId + " description: " + name); System.out.println("segmentId: " + segmentId + " description: " + name);
} }
prevSegment = i; prevSegment = i;
@ -110,7 +119,7 @@ public class RouteTestingTest {
+ reachedSegments.toString(), reachedSegments.contains(es.getKey())); + reachedSegments.toString(), reachedSegments.contains(es.getKey()));
} }
} }
}
} }
} }

View file

@ -267,4 +267,7 @@
<string name="privacy_policy_agree">\"Jarraitu\" sakatuz, Telegram eta OsmAnd pribatutasun-politiken baldintzak onartzen dituzu.</string> <string name="privacy_policy_agree">\"Jarraitu\" sakatuz, Telegram eta OsmAnd pribatutasun-politiken baldintzak onartzen dituzu.</string>
<string name="privacy_policy_telegram_client">OsmAnd aztarnariak Telegram plataforma irekia erabiltzen duten bezeroetako bat da. Zure kontaktuek Telegram-eko beste edozein bezero erabil dezakete.</string> <string name="privacy_policy_telegram_client">OsmAnd aztarnariak Telegram plataforma irekia erabiltzen duten bezeroetako bat da. Zure kontaktuek Telegram-eko beste edozein bezero erabil dezakete.</string>
<string name="last_update_from_telegram_date">Telegram-eko azken eguneratzea: %1$s</string> <string name="last_update_from_telegram_date">Telegram-eko azken eguneratzea: %1$s</string>
<string name="shared_string_export">Esportatu</string>
<string name="logcat_buffer">Logcat bufferra</string>
<string name="send_report">Bidali txostena</string>
</resources> </resources>

View file

@ -14,7 +14,7 @@
app:theme="?attr/toolbar_theme" app:theme="?attr/toolbar_theme"
android:background="?attr/pstsTabBackground"/> android:background="?attr/pstsTabBackground"/>
<WebView <net.osmand.plus.widgets.WebViewEx
android:id="@+id/webView" android:id="@+id/webView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"/>

View file

@ -63,7 +63,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="0dp"> android:layout_height="0dp">
<WebView
<net.osmand.plus.widgets.WebViewEx
android:id="@+id/content_web_view" android:id="@+id/content_web_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"/>

View file

@ -4,7 +4,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<WebView android:id="@+id/webView" <net.osmand.plus.widgets.WebViewEx
android:id="@+id/webView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1"/> android:layout_weight="1"/>

View file

@ -4,12 +4,12 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<WebView <net.osmand.plus.widgets.WebViewEx
android:id="@+id/webView" android:id="@+id/webView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
</WebView> </net.osmand.plus.widgets.WebViewEx>
<include layout="@layout/mapillary_no_internet" <include layout="@layout/mapillary_no_internet"
android:id="@+id/mapillaryNoInternetLayout" android:id="@+id/mapillaryNoInternetLayout"

View file

@ -3,7 +3,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<WebView <net.osmand.plus.widgets.WebViewEx
android:id="@+id/printDialogWebview" android:id="@+id/printDialogWebview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />

View file

@ -74,7 +74,7 @@
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1"> android:layout_weight="1">
<WebView <net.osmand.plus.widgets.WebViewEx
android:id="@+id/content_web_view" android:id="@+id/content_web_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />

View file

@ -4032,4 +4032,19 @@
<string name="routing_attr_allow_intermittent_description">Gewässer erlauben, die nicht ständig Wasser führen</string> <string name="routing_attr_allow_intermittent_description">Gewässer erlauben, die nicht ständig Wasser führen</string>
<string name="routing_attr_allow_intermittent_name">Gewässer erlauben, die nicht ständig Wasser führen</string> <string name="routing_attr_allow_intermittent_name">Gewässer erlauben, die nicht ständig Wasser führen</string>
<string name="voice_prompts_timetable">Zeiten der Sprachansagen</string> <string name="voice_prompts_timetable">Zeiten der Sprachansagen</string>
<string name="add_online_routing_engine">Online Routenplaner hinzufügen</string>
<string name="edit_online_routing_engine">Online Routenplaner bearbeiten</string>
<string name="shared_string_vehicle">Fahrzeug</string>
<string name="shared_string_api_key">API Schlüssel</string>
<string name="shared_string_server_url">Server URL</string>
<string name="shared_string_enter_param">Parameter eingeben</string>
<string name="online_routing_example_hint">Die URL mit allen Parametern wird so aussehen:</string>
<string name="test_route_calculation">Routenberechnung testen</string>
<string name="routing_engine_vehicle_type_foot">Zu Fuß</string>
<string name="routing_engine_vehicle_type_bike">Fahrrad</string>
<string name="routing_engine_vehicle_type_car">Auto</string>
<string name="message_error_recheck_parameters">Fehler, Parameter erneut prüfen</string>
<string name="shared_string_subtype">Subtyp</string>
<string name="keep_it_empty_if_not">Leer lassen, wenn kein API-Schlüssel vorhanden</string>
<string name="copy_address">Adresse kopieren</string>
</resources> </resources>

View file

@ -4028,4 +4028,20 @@
<string name="routing_attr_allow_intermittent_description">Permesi navigi per periode sekiĝantaj akvovojoj</string> <string name="routing_attr_allow_intermittent_description">Permesi navigi per periode sekiĝantaj akvovojoj</string>
<string name="routing_attr_allow_intermittent_name">Permesi sezonajn akvovojojn</string> <string name="routing_attr_allow_intermittent_name">Permesi sezonajn akvovojojn</string>
<string name="voice_prompts_timetable">Tempoj de voĉaj anoncoj</string> <string name="voice_prompts_timetable">Tempoj de voĉaj anoncoj</string>
<string name="add_online_routing_engine">Aldoni enretan navigilon</string>
<string name="edit_online_routing_engine">Redakti enretan navigilon</string>
<string name="shared_string_subtype">Subspeco</string>
<string name="shared_string_vehicle">Veturilo</string>
<string name="shared_string_api_key">API-ŝlosilo</string>
<string name="shared_string_server_url">Ligilo al servilo</string>
<string name="shared_string_enter_param">Enigu parametron</string>
<string name="keep_it_empty_if_not">Se malnecesa, enigu nenion</string>
<string name="online_routing_example_hint">Ligilo kun ĉiuj parametroj aspektos kiel tiu ĉi:</string>
<string name="routing_engine_vehicle_type_driving">Stirado</string>
<string name="test_route_calculation">Testi kalkuli kurson</string>
<string name="routing_engine_vehicle_type_foot">Piediranto</string>
<string name="routing_engine_vehicle_type_bike">Biciklo</string>
<string name="routing_engine_vehicle_type_car">Aŭtomobilo</string>
<string name="message_error_recheck_parameters">Eraro, rekontrolu parametrojn</string>
<string name="copy_address">Kopii adreson</string>
</resources> </resources>

View file

@ -4033,4 +4033,20 @@
<string name="routing_attr_allow_intermittent_description">Permite cursos de agua intermitentes</string> <string name="routing_attr_allow_intermittent_description">Permite cursos de agua intermitentes</string>
<string name="routing_attr_allow_intermittent_name">Permitir cursos de agua intermitentes</string> <string name="routing_attr_allow_intermittent_name">Permitir cursos de agua intermitentes</string>
<string name="voice_prompts_timetable">Tiempo de los avisos por voz</string> <string name="voice_prompts_timetable">Tiempo de los avisos por voz</string>
<string name="add_online_routing_engine">Añadir motor de navegación en línea</string>
<string name="edit_online_routing_engine">Editar motor de navegación en línea</string>
<string name="shared_string_subtype">Subtipo</string>
<string name="shared_string_vehicle">Vehículo</string>
<string name="shared_string_api_key">Clave de la API</string>
<string name="shared_string_server_url">URL del servidor</string>
<string name="shared_string_enter_param">Ingresa parámetro</string>
<string name="keep_it_empty_if_not">Si no, mantenerlo vacío</string>
<string name="online_routing_example_hint">La URL con todos los parámetros se verá así:</string>
<string name="test_route_calculation">Cálculo de la ruta de prueba</string>
<string name="routing_engine_vehicle_type_driving">Automóvil</string>
<string name="routing_engine_vehicle_type_foot">Peatón</string>
<string name="routing_engine_vehicle_type_bike">Bicicleta</string>
<string name="routing_engine_vehicle_type_car">Automóvil</string>
<string name="message_error_recheck_parameters">Error, vuelve a comprobar los parámetros</string>
<string name="copy_address">Copiar dirección</string>
</resources> </resources>

View file

@ -785,7 +785,7 @@
<string name="no_fav_to_save">Ez dago gogoko punturik gordetzeko</string> <string name="no_fav_to_save">Ez dago gogoko punturik gordetzeko</string>
<string name="shared_string_import">Inportatu</string> <string name="shared_string_import">Inportatu</string>
<string name="error_occurred_loading_gpx">Ezin izan da GPX kargatu.</string> <string name="error_occurred_loading_gpx">Ezin izan da GPX kargatu.</string>
<string name="send_report">Bidali informea</string> <string name="send_report">Bidali txostena</string>
<string name="none_region_found">Ezin izan da deskargatutako maparik aurkitu memoria txartelean.</string> <string name="none_region_found">Ezin izan da deskargatutako maparik aurkitu memoria txartelean.</string>
<string name="poi_namefinder_query_empty">Idatzi interesgune bat bilatzeko</string> <string name="poi_namefinder_query_empty">Idatzi interesgune bat bilatzeko</string>
<string name="any_poi">Edozein</string> <string name="any_poi">Edozein</string>
@ -4008,4 +4008,18 @@ Area honi dagokio: %1$s x %2$s</string>
<string name="plan_route_split_before">Zatitu aurretik</string> <string name="plan_route_split_before">Zatitu aurretik</string>
<string name="plan_route_split_after">Zatitu ondoren</string> <string name="plan_route_split_after">Zatitu ondoren</string>
<string name="plan_route_add_new_segment">Gehitu segmentu berria</string> <string name="plan_route_add_new_segment">Gehitu segmentu berria</string>
<string name="shared_string_subtype">Azpimota</string>
<string name="shared_string_vehicle">Ibilgailua</string>
<string name="shared_string_api_key">API gakoa</string>
<string name="shared_string_server_url">Zerbitzariaren URLa</string>
<string name="shared_string_enter_param">Sartu parametroa</string>
<string name="keep_it_empty_if_not">Mantendu hutsik hala ez bada</string>
<string name="online_routing_example_hint">Parametro guztiak dituen URLak itxura hau izango du:</string>
<string name="test_route_calculation">Proba ibilbidearen kalkulua</string>
<string name="routing_engine_vehicle_type_driving">Gidatzen</string>
<string name="routing_engine_vehicle_type_foot">Oinez</string>
<string name="routing_engine_vehicle_type_bike">Bizikleta</string>
<string name="routing_engine_vehicle_type_car">Kotxea</string>
<string name="message_error_recheck_parameters">Errorea, egiaztatu parametroak berriro</string>
<string name="copy_address">Kopiatu helbidea</string>
</resources> </resources>

View file

@ -163,7 +163,7 @@
<string name="local_osm_changes_backup">پشتیبان‌گیری در قالب تغییر OSM</string> <string name="local_osm_changes_backup">پشتیبان‌گیری در قالب تغییر OSM</string>
<string name="delete_point">حذف نقطه</string> <string name="delete_point">حذف نقطه</string>
<string name="use_kalman_filter_compass">استفاده از پالایهٔ Kalman</string> <string name="use_kalman_filter_compass">استفاده از پالایهٔ Kalman</string>
<string name="cancel_route">حذف مسیر</string> <string name="cancel_route">کنارگذاشتن مسیر؟</string>
<string name="max_speed_none">هیچ‌کدام</string> <string name="max_speed_none">هیچ‌کدام</string>
<string name="dropbox_plugin_name">افزونهٔ دراپ‌باکس</string> <string name="dropbox_plugin_name">افزونهٔ دراپ‌باکس</string>
<string name="av_use_external_recorder_descr">برای فیلم‌برداری از ضبط‌کنندهٔ سیستم استفاده شود.</string> <string name="av_use_external_recorder_descr">برای فیلم‌برداری از ضبط‌کنندهٔ سیستم استفاده شود.</string>
@ -644,7 +644,7 @@
<string name="auto_announce_off">توقف اعلام خودکار</string> <string name="auto_announce_off">توقف اعلام خودکار</string>
<string name="use_fluorescent_overlays_descr">برای نمایش ردها و مسیرها از رنگ‌های شب‌نما استفاده شود.</string> <string name="use_fluorescent_overlays_descr">برای نمایش ردها و مسیرها از رنگ‌های شب‌نما استفاده شود.</string>
<string name="offline_edition">ویرایش آفلاین</string> <string name="offline_edition">ویرایش آفلاین</string>
<string name="offline_edition_descr">ویرایش‌ها را همیشه آفلاین انجام می‌دهم.</string> <string name="offline_edition_descr">اگر ویرایش آفلاین فعال باشد، تغییرات ابتدا روی دستگاه ذخیره می‌شود و با درخواست شما آپلود می‌گردد. در غیر این صورت دردَم آپلود خواهد شد.</string>
<string name="local_openstreetmap_uploading">در حال آپلود…</string> <string name="local_openstreetmap_uploading">در حال آپلود…</string>
<string name="local_openstreetmap_were_uploaded">تعداد {0} یادداشت/POI آپلود شد</string> <string name="local_openstreetmap_were_uploaded">تعداد {0} یادداشت/POI آپلود شد</string>
<string name="update_poi_does_not_change_indexes">تغییراتی که به‌وسیلهٔ برنامه روی POIها انجام می‌دهید روی نقشه‌های دانلود‌شده تأثیری ندارد. تغییرات روی فایل دیگری در دستگاه ذخیره می‌شود.</string> <string name="update_poi_does_not_change_indexes">تغییراتی که به‌وسیلهٔ برنامه روی POIها انجام می‌دهید روی نقشه‌های دانلود‌شده تأثیری ندارد. تغییرات روی فایل دیگری در دستگاه ذخیره می‌شود.</string>
@ -1687,7 +1687,7 @@
<string name="access_direction_haptic_feedback_descr">بیان‌کردن جهت مقصد با لرزش.</string> <string name="access_direction_haptic_feedback_descr">بیان‌کردن جهت مقصد با لرزش.</string>
<string name="use_osm_live_routing_description">مسیریابی با استفاده از به‌روزرسانی‌های OsmAnd Live فعال شود.</string> <string name="use_osm_live_routing_description">مسیریابی با استفاده از به‌روزرسانی‌های OsmAnd Live فعال شود.</string>
<string name="use_osm_live_routing">مسیریابی با OsmAnd Live</string> <string name="use_osm_live_routing">مسیریابی با OsmAnd Live</string>
<string name="access_no_destination">مقصد تنظیم نشده</string> <string name="access_no_destination">افزونهٔ قابلیت دسترسی: مقصدی تنظیم نشده</string>
<string name="map_widget_magnetic_bearing">سویهٔ مغناطیسی</string> <string name="map_widget_magnetic_bearing">سویهٔ مغناطیسی</string>
<string name="map_widget_bearing">سویهٔ نسبی</string> <string name="map_widget_bearing">سویهٔ نسبی</string>
<string name="access_disable_offroute_recalc">اگر از مسیر خارج شدم، مسیر تازه‌ای پیدا نکن</string> <string name="access_disable_offroute_recalc">اگر از مسیر خارج شدم، مسیر تازه‌ای پیدا نکن</string>
@ -2151,7 +2151,7 @@
<string name="number_of_contributors">تعداد مشارکت‌کنندگان</string> <string name="number_of_contributors">تعداد مشارکت‌کنندگان</string>
<string name="number_of_edits">تعداد ویرایش‌ها</string> <string name="number_of_edits">تعداد ویرایش‌ها</string>
<string name="reports_for">گزارش برای</string> <string name="reports_for">گزارش برای</string>
<string name="file_name_containes_illegal_char">در نام فایل از نویسهٔ غیرمجاز استفاده شده است</string> <string name="file_name_containes_illegal_char">نویسهٔ غیرمجاز در نام فایل</string>
<string name="configure_screen_quick_action">کنش فوری</string> <string name="configure_screen_quick_action">کنش فوری</string>
<string name="quick_action_item_action">کنش %d</string> <string name="quick_action_item_action">کنش %d</string>
<string name="quick_action_item_screen">صفحهٔ %d</string> <string name="quick_action_item_screen">صفحهٔ %d</string>
@ -2301,7 +2301,7 @@
<string name="quick_action_showhide_osmbugs_descr">دکمه‌ای برای آشکار/پنهان کردن یادداشت‌های OSM بر روی نقشه.</string> <string name="quick_action_showhide_osmbugs_descr">دکمه‌ای برای آشکار/پنهان کردن یادداشت‌های OSM بر روی نقشه.</string>
<string name="sorted_by_distance">مرتب‌شده بر اساس مسافت</string> <string name="sorted_by_distance">مرتب‌شده بر اساس مسافت</string>
<string name="search_favorites">جست‌وجو در علاقه‌مندی‌ها</string> <string name="search_favorites">جست‌وجو در علاقه‌مندی‌ها</string>
<string name="hillshade_menu_download_descr">«لایهٔ سایه‌روشن» را دانلود کنید تا سایه‌های عمودی را ببینید.</string> <string name="hillshade_menu_download_descr">لایهٔ «سایه‌روشن» را دانلود کنید تا سایه‌زنی‌های عمودی را ببینید.</string>
<string name="hillshade_purchase_header">افزونهٔ «منحنی‌های میزان» را نصب کنید تا طبقه‌بندی عمودی محدوده‌ها را ببینید.</string> <string name="hillshade_purchase_header">افزونهٔ «منحنی‌های میزان» را نصب کنید تا طبقه‌بندی عمودی محدوده‌ها را ببینید.</string>
<string name="hide_from_zoom_level">از این زوم پنهان شود</string> <string name="hide_from_zoom_level">از این زوم پنهان شود</string>
<string name="srtm_menu_download_descr">نقشهٔ «منحنی میزان» را برای استفاده در این منطقه دانلود کنید.</string> <string name="srtm_menu_download_descr">نقشهٔ «منحنی میزان» را برای استفاده در این منطقه دانلود کنید.</string>
@ -2664,7 +2664,7 @@
<string name="copy_location_name">کپی موقعیت/نام POI</string> <string name="copy_location_name">کپی موقعیت/نام POI</string>
<string name="toast_empty_name_error">مکان بی‌نام</string> <string name="toast_empty_name_error">مکان بی‌نام</string>
<string name="show_closed_notes">دیدن یادداشت‌های بسته</string> <string name="show_closed_notes">دیدن یادداشت‌های بسته</string>
<string name="switch_osm_notes_visibility_desc">پنهان/آشکارکردن یادداشت‌های OSM.</string> <string name="switch_osm_notes_visibility_desc">پنهان یا آشکارکردن یادداشت‌های OSM.</string>
<string name="gpx_file_desc">GPX - مناسب برای استفاده در JOSM یا سایر ویرایشگرهای OSM.</string> <string name="gpx_file_desc">GPX - مناسب برای استفاده در JOSM یا سایر ویرایشگرهای OSM.</string>
<string name="osc_file_desc">OSC - مناسب برای استفاده در OSM.</string> <string name="osc_file_desc">OSC - مناسب برای استفاده در OSM.</string>
<string name="shared_string_gpx_file">فایل GPX</string> <string name="shared_string_gpx_file">فایل GPX</string>
@ -3188,9 +3188,9 @@
<string name="rendering_attr_showLez_description">محدوده‌های کاهش آلودگی هوای شهر را روی نقشه نشان بده. روی مسیریابی اثر نمی‌گذارد.</string> <string name="rendering_attr_showLez_description">محدوده‌های کاهش آلودگی هوای شهر را روی نقشه نشان بده. روی مسیریابی اثر نمی‌گذارد.</string>
<string name="rendering_attr_showLez_name">محدوده‌های کاهش</string> <string name="rendering_attr_showLez_name">محدوده‌های کاهش</string>
<string name="temporary_conditional_routing">در نظر گرفتن محدودیت‌های موقت در مسیریابی</string> <string name="temporary_conditional_routing">در نظر گرفتن محدودیت‌های موقت در مسیریابی</string>
<string name="routing_attr_piste_type_downhill_name">اسکی آلپاین/دان‌هیل</string> <string name="routing_attr_piste_type_downhill_name">اسکی آلپاین و دانهیل</string>
<string name="routing_attr_piste_type_downhill_description">سراشیبی‌های اسکی آلپاین یا دان‌هیل و دسترسی به بالابرهای اسکی.</string> <string name="routing_attr_piste_type_downhill_description">سراشیبی‌های اسکی آلپاین یا دان‌هیل و دسترسی به بالابرهای اسکی.</string>
<string name="routing_attr_piste_type_nordic_name">اسکی کراس/نوردیک</string> <string name="routing_attr_piste_type_nordic_name">اسکی کراس‌کانتری و نوردیک</string>
<string name="routing_attr_piste_type_nordic_description">مسیرهای اسکی کراس یا نوردیک.</string> <string name="routing_attr_piste_type_nordic_description">مسیرهای اسکی کراس یا نوردیک.</string>
<string name="shared_string_crash">شکست</string> <string name="shared_string_crash">شکست</string>
<string name="shared_string_open_track">باز کن</string> <string name="shared_string_open_track">باز کن</string>
@ -3456,7 +3456,7 @@
<string name="button_rate">امتیاز بدهید</string> <string name="button_rate">امتیاز بدهید</string>
<string name="monitoring_prefs_descr">ناوبری، صحت ردنگاری</string> <string name="monitoring_prefs_descr">ناوبری، صحت ردنگاری</string>
<string name="multimedia_notes_prefs_descr">اندازهٔ عکس، کیفیت صدا و ویدئو</string> <string name="multimedia_notes_prefs_descr">اندازهٔ عکس، کیفیت صدا و ویدئو</string>
<string name="osm_editing_prefs_descr">ثبت ورود، گذرواژه، ویرایش آفلاین</string> <string name="osm_editing_prefs_descr">نام کاربری، گذرواژه، ویرایش آفلاین</string>
<string name="accessibility_prefs_descr">انتخاب نماد، رنگ و نام</string> <string name="accessibility_prefs_descr">انتخاب نماد، رنگ و نام</string>
<string name="live_monitoring">ردیابی آنلاین</string> <string name="live_monitoring">ردیابی آنلاین</string>
<string name="save_track_logging_accuracy">صحت ردنگاری</string> <string name="save_track_logging_accuracy">صحت ردنگاری</string>
@ -3464,7 +3464,7 @@
<string name="photo_notes">یادداشت‌های عکسی</string> <string name="photo_notes">یادداشت‌های عکسی</string>
<string name="route_recalculation">محاسبهٔ مجدد مسیر</string> <string name="route_recalculation">محاسبهٔ مجدد مسیر</string>
<string name="login_and_pass">نام کاربری و گذرواژه</string> <string name="login_and_pass">نام کاربری و گذرواژه</string>
<string name="plugin_global_prefs_info">این تنظیمات افزونه، سراسری است و روی همهٔ پروفایل‌ها به کار گرفته می‌شود.</string> <string name="plugin_global_prefs_info">این تنظیمات افزونه، سراسری است و روی همهٔ پروفایل‌ها به کار گرفته می‌شود</string>
<string name="osm_editing">ویرایش OSM</string> <string name="osm_editing">ویرایش OSM</string>
<string name="app_mode_osm">OSM</string> <string name="app_mode_osm">OSM</string>
<string name="select_nav_icon_descr">نمادی که هنگام حرکت یا ناوبری نمایش داده می‌شود.</string> <string name="select_nav_icon_descr">نمادی که هنگام حرکت یا ناوبری نمایش داده می‌شود.</string>
@ -3594,7 +3594,7 @@
<string name="shared_string_terrain">ناهمواری‌ها</string> <string name="shared_string_terrain">ناهمواری‌ها</string>
<string name="hillshade_description">نقشهٔ سایه‌روشن که شیب‌ها، بلندی‌ها و پستی‌ها را با استفاده از سایه‌های تیره نمایان می‌کند.</string> <string name="hillshade_description">نقشهٔ سایه‌روشن که شیب‌ها، بلندی‌ها و پستی‌ها را با استفاده از سایه‌های تیره نمایان می‌کند.</string>
<string name="terrain_slider_description">کمینه و بیشینهٔ زوم برای نمایش لایه را مشخص کنید.</string> <string name="terrain_slider_description">کمینه و بیشینهٔ زوم برای نمایش لایه را مشخص کنید.</string>
<string name="hillshade_download_description">برای مشاهدهٔ سایه‌روشن‌ها روی نقشه باید نقشهٔ دیگری را نیز دانلود کنید.</string> <string name="hillshade_download_description">"باید نقشهٔ دیگری را نیز دانلود کنید تا سایه‌روشن‌ها را روی نقشه ببینید."</string>
<string name="slope_download_description">برای مشاهدهٔ شیب‌ها روی نقشه باید نقشهٔ دیگری را نیز دانلود کنید.</string> <string name="slope_download_description">برای مشاهدهٔ شیب‌ها روی نقشه باید نقشهٔ دیگری را نیز دانلود کنید.</string>
<string name="slope_read_more">دربارهٔ شیب‌ها می‌توانید در %1$s بیشتر بخوانید.</string> <string name="slope_read_more">دربارهٔ شیب‌ها می‌توانید در %1$s بیشتر بخوانید.</string>
<string name="shared_string_transparency">شفافیت</string> <string name="shared_string_transparency">شفافیت</string>
@ -3604,7 +3604,7 @@
<string name="shared_string_hillshade">سایه‌روشن</string> <string name="shared_string_hillshade">سایه‌روشن</string>
<string name="n_items_of_z">%1$s از %2$s</string> <string name="n_items_of_z">%1$s از %2$s</string>
<string name="download_slope_maps">شیب‌ها</string> <string name="download_slope_maps">شیب‌ها</string>
<string name="quick_action_show_hide_terrain">آشکار/پنهان کردن ناهمواری‌ها</string> <string name="quick_action_show_hide_terrain">آشکار یا پنهان کردن ناهمواری‌ها</string>
<string name="quick_action_terrain_hide">پنهان‌کردن ناهمواری‌ها</string> <string name="quick_action_terrain_hide">پنهان‌کردن ناهمواری‌ها</string>
<string name="quick_action_terrain_show">نمایش ناهمواری‌ها</string> <string name="quick_action_terrain_show">نمایش ناهمواری‌ها</string>
<string name="quick_action_terrain_descr">دکمه‌ای برای آشکار یا پنهان کردن لایهٔ ناهمواری‌ها روی نقشه.</string> <string name="quick_action_terrain_descr">دکمه‌ای برای آشکار یا پنهان کردن لایهٔ ناهمواری‌ها روی نقشه.</string>
@ -3717,12 +3717,12 @@
\n \n
\n</string> \n</string>
<string name="back_to_editing">بازگشت به ویرایش</string> <string name="back_to_editing">بازگشت به ویرایش</string>
<string name="create_edit_poi">ایجاد / ویرایش POI</string> <string name="create_edit_poi">ایجاد یا ویرایش POI</string>
<string name="add_edit_favorite">افزودن / ویرایش علاقه‌مندی</string> <string name="add_edit_favorite">افزودن یا ویرایش علاقه‌مندی</string>
<string name="additional_actions_descr">برای دسترسی به این کنش‌ها می‌توانید روی دکمهٔ «%1$s» بزنید.</string> <string name="additional_actions_descr">برای دسترسی به این کنش‌ها می‌توانید روی دکمهٔ «%1$s» بزنید.</string>
<string name="quick_action_transport_hide">مخفی‌کردن حمل‌ونقل عمومی</string> <string name="quick_action_transport_hide">مخفی‌کردن حمل‌ونقل عمومی</string>
<string name="quick_action_transport_show">نمایش حمل‌ونقل عمومی</string> <string name="quick_action_transport_show">نمایش حمل‌ونقل عمومی</string>
<string name="quick_action_show_hide_transport">آشکار/پنهان کردن حمل‌ونقل عمومی</string> <string name="quick_action_show_hide_transport">آشکار یا پنهان کردن حمل‌ونقل عمومی</string>
<string name="quick_action_transport_descr">دکمه‌ای برای آشکار یا پنهان کردن حمل‌ونقل عمومی روی نقشه.</string> <string name="quick_action_transport_descr">دکمه‌ای برای آشکار یا پنهان کردن حمل‌ونقل عمومی روی نقشه.</string>
<string name="quick_action_switch_profile_descr">با لمس دکمهٔ عملیاتی بین پروفایل‌های انتخاب‌شده جابه‌جا شوید.</string> <string name="quick_action_switch_profile_descr">با لمس دکمهٔ عملیاتی بین پروفایل‌های انتخاب‌شده جابه‌جا شوید.</string>
<string name="shared_string_add_profile">افزودن پروفایل</string> <string name="shared_string_add_profile">افزودن پروفایل</string>
@ -3823,7 +3823,7 @@
<string name="quick_action_remove_next_destination">حذف نزدیک‌ترین مقصد</string> <string name="quick_action_remove_next_destination">حذف نزدیک‌ترین مقصد</string>
<string name="please_provide_point_name_error">لطفاً نام نقطه را بنویسید</string> <string name="please_provide_point_name_error">لطفاً نام نقطه را بنویسید</string>
<string name="search_download_wikipedia_maps">دانلود نقشه‌های ویکی‌پدیا</string> <string name="search_download_wikipedia_maps">دانلود نقشه‌های ویکی‌پدیا</string>
<string name="plugin_wikipedia_description">از ویکی‌پدیا دربارهٔ نقاط توجه اطلاعات کسب کنید؛ مانند یک راهنمای آفلاین جیبی. کافی است افزونهٔ ویکی‌پدیا را فعال کنید و از مقاله‌های مربوط به چیزهای دوروبرتان لذت ببرید.</string> <string name="plugin_wikipedia_description">دربارهٔ نقاط توجه، از ویکی‌پدیا اطلاعات کسب کنید. یک راهنمای آفلاینِ جیبی که مقاله‌هایی دربارهٔ مکان‌ها و مقصدها دارد.</string>
<string name="app_mode_wheelchair">صندلی چرخ‌دار</string> <string name="app_mode_wheelchair">صندلی چرخ‌دار</string>
<string name="osm_edit_closed_note">یادداشت اُاِس‌اِمی بسته</string> <string name="osm_edit_closed_note">یادداشت اُاِس‌اِمی بسته</string>
<string name="add_hidden_group_info">نقطهٔ اضافه‌شده روی نقشه دیده نمی‌شود، زیرا گروه انتخاب‌شده پنهان است. آن را در «%s» پیدا می‌کنید.</string> <string name="add_hidden_group_info">نقطهٔ اضافه‌شده روی نقشه دیده نمی‌شود، زیرا گروه انتخاب‌شده پنهان است. آن را در «%s» پیدا می‌کنید.</string>
@ -3864,11 +3864,11 @@
\n</string> \n</string>
<string name="plan_route_trim_before">حذفِ قبل</string> <string name="plan_route_trim_before">حذفِ قبل</string>
<string name="plan_route_trim_after">حذفِ بعد</string> <string name="plan_route_trim_after">حذفِ بعد</string>
<string name="plan_route_change_route_type_before">تغییر نوع مسیرِ بعد آن</string> <string name="plan_route_change_route_type_before">تغییر نوع مسیرِ بعد</string>
<string name="plan_route_change_route_type_after">تغییر نوع مسیرِ قبل آن</string> <string name="plan_route_change_route_type_after">تغییر نوع مسیرِ قبل</string>
<string name="track_coloring_solid">تک‌رنگ</string> <string name="track_coloring_solid">تک‌رنگ</string>
<string name="lenght_limit_description">طول وسیلهٔ نقلیهٔ خود را مشخص کنید. ممکن است محدودیت‌های مسیر برای وسایل نقلیهٔ طویل اِعمال شود.</string> <string name="lenght_limit_description">طول وسیلهٔ نقلیهٔ خود را مشخص کنید. ممکن است محدودیت‌های مسیر برای وسایل نقلیهٔ طویل اِعمال شود.</string>
<string name="quick_action_remove_next_destination_descr">مقصد کنونی مسیر حذف خواهد شد. اگر این قرار است مقصد باشد، ناوبری متوقف می‌شود.</string> <string name="quick_action_remove_next_destination_descr">مقصد بعدیِ مسیر شما را حذف خواهد کرد. البته اگر مقصد نهایی باشد، ناوبری را متوقف می‌کند.</string>
<string name="add_to_a_track">افزودن به یک رد</string> <string name="add_to_a_track">افزودن به یک رد</string>
<string name="save_as_new_track">ذخیره به‌عنوان رد جدید</string> <string name="save_as_new_track">ذخیره به‌عنوان رد جدید</string>
<string name="reverse_route">برعکس‌کردن مسیر</string> <string name="reverse_route">برعکس‌کردن مسیر</string>
@ -3886,7 +3886,7 @@
<string name="navigation_profile">پروفایل ناوبری</string> <string name="navigation_profile">پروفایل ناوبری</string>
<string name="route_between_points_add_track_desc">یک فایل رد انتخاب کنید تا پارهٔ جدید را به آن بیفزایید.</string> <string name="route_between_points_add_track_desc">یک فایل رد انتخاب کنید تا پارهٔ جدید را به آن بیفزایید.</string>
<string name="street_level_imagery">تصاویر نمای خیابان</string> <string name="street_level_imagery">تصاویر نمای خیابان</string>
<string name="plan_route_exit_dialog_descr">آیا می‌خواهید خارج شوید و همهٔ تغییرات مسیر طراحی‌شده را از بین ببرید؟</string> <string name="plan_route_exit_dialog_descr">آیا می‌خواهید همهٔ تغییرات در مسیر طراحی‌شده از بین برود؟</string>
<string name="in_case_of_reverse_direction">اگر برعکس حرکت کردم</string> <string name="in_case_of_reverse_direction">اگر برعکس حرکت کردم</string>
<string name="start_of_the_track">ابتدای رد</string> <string name="start_of_the_track">ابتدای رد</string>
<string name="follow_track_descr">انتخاب فایل رد برای دنبال‌کردن</string> <string name="follow_track_descr">انتخاب فایل رد برای دنبال‌کردن</string>
@ -3963,15 +3963,15 @@
\nنمودار پس از بازمحاسبهٔ مسیر فراهم می‌شود.</string> \nنمودار پس از بازمحاسبهٔ مسیر فراهم می‌شود.</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string> <string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="message_you_need_add_two_points_to_show_graphs">دست‌کم دو نقطه اضافه کنید</string> <string name="message_you_need_add_two_points_to_show_graphs">دست‌کم دو نقطه اضافه کنید</string>
<string name="login_open_street_map">ثبت ورود در اوپن‌استریت‌مپ</string> <string name="login_open_street_map">ورود به اوپن‌استریت‌مپ</string>
<string name="login_open_street_map_org">ثبت ورود در OpenStreetMap.org</string> <string name="login_open_street_map_org">ورود به OpenStreetMap.org</string>
<string name="sign_in_with_open_street_map">ثبت ورود از طریق اوپن‌استریت‌مپ</string> <string name="sign_in_with_open_street_map">ثبت ورود از طریق اوپن‌استریت‌مپ</string>
<string name="open_street_map_login_mode">برای آپلود تغییرات جدید باید ثبت ورود (login) کنید. <string name="open_street_map_login_mode">برای آپلود تغییرات جدید باید وارد شوید (login).
\n \n
\nبرای ثبت ورود می‌توانید از روش امن OAuth یا روش نام کاربری و گذرواژه استفاده کنید.</string> \nبرای ورود می‌توانید از روش امن OAuth یا روش نام کاربری و گذرواژه استفاده کنید.</string>
<string name="use_login_password">استفاده از نام کاربری و گذرواژه</string> <string name="use_login_password">استفاده از نام کاربری و گذرواژه</string>
<string name="login_account">حساب</string> <string name="login_account">حساب</string>
<string name="user_login">ثبت ورود</string> <string name="user_login">ورود</string>
<string name="manage_subscription">مدیریت اشتراک</string> <string name="manage_subscription">مدیریت اشتراک</string>
<string name="subscription_payment_issue_title">روی دکمه بزنید و یک شیوهٔ پرداخت در گوگل‌پلی تنظیم کنید تا اشتراک خود را اصلاح نمایید.</string> <string name="subscription_payment_issue_title">روی دکمه بزنید و یک شیوهٔ پرداخت در گوگل‌پلی تنظیم کنید تا اشتراک خود را اصلاح نمایید.</string>
<string name="markers_history">تاریخچهٔ نشانه‌ها</string> <string name="markers_history">تاریخچهٔ نشانه‌ها</string>
@ -4006,4 +4006,35 @@
<string name="plan_route_add_new_segment">افزودن یک بخش جدید</string> <string name="plan_route_add_new_segment">افزودن یک بخش جدید</string>
<string name="profile_type_osmand_string">نمایهٔ OsmAnd</string> <string name="profile_type_osmand_string">نمایهٔ OsmAnd</string>
<string name="profile_type_user_string">نمایهٔ کاربر</string> <string name="profile_type_user_string">نمایهٔ کاربر</string>
<string name="voice_prompts_timetable">زمان‌های پیام‌های گفتاری</string>
<string name="navigate_point_mgrs">MGRS</string>
<string name="navigate_point_format_mgrs">MGRS</string>
<string name="mgrs_format_descr">OsmAnd از MGRS استفاده می‌کند که شبیه قالب UTM NATO است.</string>
<string name="contour_lines_thanks">سپاسگزاریم که Contour lines را خریدید</string>
<string name="enter_text_separated">برچسب‌ها را بنویسید و با کاما جدا کنید.</string>
<string name="osm_edit_close_note">بستن یادداشت OSM</string>
<string name="osm_edit_comment_note">نظردادن به یادداشت OSM</string>
<string name="osm_login_descr">می‌توانید با روش ایمن OAuth وارد شوید یا از نام‌کاربری و گذرواژه‌تان استفاده کنید.</string>
<string name="app_mode_motorboat">قایق‌موتوری</string>
<string name="cannot_upload_image">آپلود عکس ناموفق بود، لطفاً بعداً دوباره امتحان کنید</string>
<string name="select_picture">انتخاب تصویر</string>
<string name="shared_string_resources">منابع</string>
<string name="approximate_file_size">اندازهٔ تخمینی فایل</string>
<string name="select_data_to_export">دادهٔ موردنظر برای برون‌برد در فایل را انتخاب کنید.</string>
<string name="file_size_needed_for_import">برای درون‌برد لازم است</string>
<string name="reverse_all_points">برعکس‌کردن همهٔ نقطه‌ها</string>
<string name="profile_by_default_description">پروفایلِ هنگام شروع برنامه را انتخاب کنید.</string>
<string name="shared_string_last_used">آخرین استفاده</string>
<string name="add_online_routing_engine">افزودن موتور مسیریابی آنلاین</string>
<string name="edit_online_routing_engine">ویرایش موتور مسیریابی آنلاین</string>
<string name="shared_string_vehicle">وسیله نقلیه</string>
<string name="shared_string_api_key">کلید API</string>
<string name="shared_string_enter_param">پارامتر را وارد کنید</string>
<string name="online_routing_example_hint">URL با همهٔ پارامترها شبیه این است:</string>
<string name="test_route_calculation">آزمایش محاسبهٔ مسیر</string>
<string name="routing_engine_vehicle_type_driving">رانندگی</string>
<string name="routing_engine_vehicle_type_foot">پا</string>
<string name="routing_engine_vehicle_type_bike">دوچرخه</string>
<string name="routing_engine_vehicle_type_car">خودرو</string>
<string name="message_error_recheck_parameters">خطا، پارامترها را بازبینی کنید</string>
</resources> </resources>

View file

@ -3895,4 +3895,12 @@
<string name="poi_water_source_tap">Robinet</string> <string name="poi_water_source_tap">Robinet</string>
<string name="poi_vaccination_covid19">Vaccination : covid19</string> <string name="poi_vaccination_covid19">Vaccination : covid19</string>
<string name="poi_health_specialty_vaccination_yes">Vaccination</string> <string name="poi_health_specialty_vaccination_yes">Vaccination</string>
<string name="poi_wildlife_crossing_bat_tunnel">Tunnel à chauve-souris</string>
<string name="poi_wildlife_crossing_bat_bridge">Pont à chauve-souris</string>
<string name="poi_wildlife_crossing">Passage de faune</string>
<string name="poi_swimming_area">Zone de baignade</string>
<string name="poi_lavoir">Lavoir</string>
<string name="poi_waste_transfer_station">Station de traitement des déchets</string>
<string name="poi_weightbridge">Pont de levage</string>
<string name="poi_ranger_station">Poste de garde forestier</string>
</resources> </resources>

View file

@ -4007,4 +4007,20 @@
<string name="routing_attr_allow_streams_description">Autoriser les cours deau et les drains</string> <string name="routing_attr_allow_streams_description">Autoriser les cours deau et les drains</string>
<string name="routing_attr_allow_streams_name">Autoriser les cours deau et les drains</string> <string name="routing_attr_allow_streams_name">Autoriser les cours deau et les drains</string>
<string name="voice_prompts_timetable">Nombre d\'annonces vocales</string> <string name="voice_prompts_timetable">Nombre d\'annonces vocales</string>
<string name="keep_it_empty_if_not">Si non, laissez vide</string>
<string name="shared_string_subtype">Sous-type</string>
<string name="shared_string_vehicle">Véhicule</string>
<string name="shared_string_api_key">Clé d\'API</string>
<string name="shared_string_server_url">URL du serveur</string>
<string name="shared_string_enter_param">Saisissez le paramètre</string>
<string name="test_route_calculation">Calculer un itinéraire dessai</string>
<string name="routing_engine_vehicle_type_driving">En voiture</string>
<string name="routing_engine_vehicle_type_foot">A pieds</string>
<string name="routing_engine_vehicle_type_bike">Vélo</string>
<string name="routing_engine_vehicle_type_car">Automobile</string>
<string name="message_error_recheck_parameters">Erreur, vérifiez les paramètres</string>
<string name="add_online_routing_engine">Ajouter un moteur de routage en ligne</string>
<string name="edit_online_routing_engine">Modifier le moteur de routage en ligne</string>
<string name="online_routing_example_hint">L\'URL avec tous les paramètres sera de la forme :</string>
<string name="copy_address">Copier l\'adresse</string>
</resources> </resources>

View file

@ -585,7 +585,7 @@
<string name="choose_intersected_street">Keresztező utca kijelölése</string> <string name="choose_intersected_street">Keresztező utca kijelölése</string>
<string name="Closest_Amenities">Legközelebbi hasznos létesítmények</string> <string name="Closest_Amenities">Legközelebbi hasznos létesítmények</string>
<string name="app_mode_default">Térképböngészés</string> <string name="app_mode_default">Térképböngészés</string>
<string name="app_mode_car">Vezetés</string> <string name="app_mode_car">Autóvezetés</string>
<string name="app_mode_bicycle">Kerékpározás</string> <string name="app_mode_bicycle">Kerékpározás</string>
<string name="app_mode_pedestrian">Gyaloglás</string> <string name="app_mode_pedestrian">Gyaloglás</string>
<string name="position_on_map_center">Középen</string> <string name="position_on_map_center">Középen</string>
@ -1292,7 +1292,7 @@
<string name="speak_poi">Közeli érdekes helyek (POI)</string> <string name="speak_poi">Közeli érdekes helyek (POI)</string>
<string name="download_additional_maps">Letöltöd a hiányzó térképeket %1$s (%2$d MB)?</string> <string name="download_additional_maps">Letöltöd a hiányzó térképeket %1$s (%2$d MB)?</string>
<string name="rendering_value_browse_map_name">Térképböngészés</string> <string name="rendering_value_browse_map_name">Térképböngészés</string>
<string name="rendering_value_car_name">Autó</string> <string name="rendering_value_car_name">Személyautó</string>
<string name="rendering_value_bicycle_name">Kerékpár</string> <string name="rendering_value_bicycle_name">Kerékpár</string>
<string name="rendering_value_pedestrian_name">Gyalogos</string> <string name="rendering_value_pedestrian_name">Gyalogos</string>
<string name="record_plugin_description">Ez a bővítmény aktiválja a nyomvonalak rögzítésének és mentésének lehetőségét, ha megnyomja a GPX naplózó gombot a térképképernyőn, valamint képes minden navigációs útvonalat automatikusan egy GPX-fájlba naplózni. <string name="record_plugin_description">Ez a bővítmény aktiválja a nyomvonalak rögzítésének és mentésének lehetőségét, ha megnyomja a GPX naplózó gombot a térképképernyőn, valamint képes minden navigációs útvonalat automatikusan egy GPX-fájlba naplózni.
@ -4019,4 +4019,21 @@
<string name="routing_attr_allow_streams_name">Patakok és vízelvezető árkok engedélyezése</string> <string name="routing_attr_allow_streams_name">Patakok és vízelvezető árkok engedélyezése</string>
<string name="routing_attr_allow_intermittent_description">Időszakos vízfolyások engedélyezése</string> <string name="routing_attr_allow_intermittent_description">Időszakos vízfolyások engedélyezése</string>
<string name="routing_attr_allow_intermittent_name">Időszakos vízfolyások engedélyezése</string> <string name="routing_attr_allow_intermittent_name">Időszakos vízfolyások engedélyezése</string>
<string name="routing_engine_vehicle_type_driving">Autóvezetés</string>
<string name="routing_engine_vehicle_type_foot">Gyaloglás</string>
<string name="routing_engine_vehicle_type_bike">Kerékpár</string>
<string name="routing_engine_vehicle_type_car">Személyautó</string>
<string name="voice_prompts_timetable">Hangutasítások ideje</string>
<string name="add_online_routing_engine">Online útvonaltervező hozzáadása</string>
<string name="edit_online_routing_engine">Online útvonaltervező szerkesztése</string>
<string name="shared_string_subtype">Altípus</string>
<string name="shared_string_vehicle">Jármű</string>
<string name="shared_string_api_key">API-kulcs</string>
<string name="shared_string_server_url">Kiszolgáló URL-je</string>
<string name="shared_string_enter_param">Paraméter megadása</string>
<string name="keep_it_empty_if_not">Hagyja üresen, ha nem</string>
<string name="online_routing_example_hint">Az összes paraméterrel rendelkező URL így néz ki:</string>
<string name="test_route_calculation">Útvonaltervezés kipróbálása</string>
<string name="message_error_recheck_parameters">Hiba, ellenőrizze újra a paramétereket</string>
<string name="copy_address">Cím másolása</string>
</resources> </resources>

View file

@ -4032,4 +4032,20 @@
<string name="gpx_upload_public_visibility_descr">„ציבורי” משמעו שהעקבות מופיעים באופן ציבורי בעקבות ה־GPS שלך וברישומי עקבות GPS ציבוריים וברישומי מעקב ציבוריים עם חותמות זמן בתצורה גולמית. הנתונים שמוגשים דרך ה־API אינם מפנים אל עמוד העקבות שלך. חותמות הזמן של נקודות המעקב אינן זמינות דרך ה־API של ה־GPS ונקודות המעקב אינן מסודרות בהתאם לזמן שתועדו.</string> <string name="gpx_upload_public_visibility_descr">„ציבורי” משמעו שהעקבות מופיעים באופן ציבורי בעקבות ה־GPS שלך וברישומי עקבות GPS ציבוריים וברישומי מעקב ציבוריים עם חותמות זמן בתצורה גולמית. הנתונים שמוגשים דרך ה־API אינם מפנים אל עמוד העקבות שלך. חותמות הזמן של נקודות המעקב אינן זמינות דרך ה־API של ה־GPS ונקודות המעקב אינן מסודרות בהתאם לזמן שתועדו.</string>
<string name="gpx_upload_private_visibility_descr">„פרטי” משמעות שהעקבות לא תופענה ברישומים ציבוריים אך נקודות מעקב ממתוכן תהיינה זמינות בסדר אקראי דרך ה־API הציבורי של ה־GPS ללא חותמות זמן.</string> <string name="gpx_upload_private_visibility_descr">„פרטי” משמעות שהעקבות לא תופענה ברישומים ציבוריים אך נקודות מעקב ממתוכן תהיינה זמינות בסדר אקראי דרך ה־API הציבורי של ה־GPS ללא חותמות זמן.</string>
<string name="voice_prompts_timetable">זמני הכרזות</string> <string name="voice_prompts_timetable">זמני הכרזות</string>
<string name="add_online_routing_engine">הוספת מנוע ניווט מקוון</string>
<string name="edit_online_routing_engine">עריכת מנוע הניווט המקוון</string>
<string name="shared_string_subtype">תת־סוג</string>
<string name="shared_string_vehicle">כלי רכב</string>
<string name="shared_string_api_key">מפתח API</string>
<string name="shared_string_server_url">כתובת השרת</string>
<string name="shared_string_enter_param">נא למלא משתנים</string>
<string name="keep_it_empty_if_not">להשאיר ריק אם לא</string>
<string name="online_routing_example_hint">כתובת עם כל המשתנים נראית כך:</string>
<string name="test_route_calculation">בדיקת חישוב מסלול</string>
<string name="routing_engine_vehicle_type_driving">נהיגה</string>
<string name="routing_engine_vehicle_type_foot">ברגל</string>
<string name="routing_engine_vehicle_type_bike">אופנוע</string>
<string name="routing_engine_vehicle_type_car">מכונית</string>
<string name="message_error_recheck_parameters">שגיאה, נא לבדוק את המשתנים מחדש</string>
<string name="copy_address">העתקת כתובת</string>
</resources> </resources>

View file

@ -2350,4 +2350,10 @@
<string name="profile_type_base_string">ბაზური პროფილი</string> <string name="profile_type_base_string">ბაზური პროფილი</string>
<string name="profile_type_descr_string">ტიპი: %s</string> <string name="profile_type_descr_string">ტიპი: %s</string>
<string name="settings_routing_mode_string">რეჟიმი: %s</string> <string name="settings_routing_mode_string">რეჟიმი: %s</string>
<string name="routing_attr_avoid_footways_description">საცალფეხო გზების არიდება</string>
<string name="routing_attr_avoid_footways_name">საცალფეხო ფზების არიდება</string>
<string name="shared_string_is_saved">შენახულია</string>
<string name="sort_last_modified">ბოლო ცვლილება</string>
<string name="sort_name_descending">სახელი: ჰ-ა</string>
<string name="sort_name_ascending">სახელი: ა-ჰ</string>
</resources> </resources>

View file

@ -121,7 +121,7 @@
<string name="poi_vehicle_inspection">Stacja diagnostyczna</string> <string name="poi_vehicle_inspection">Stacja diagnostyczna</string>
<string name="poi_car_wash">Myjnia samochodowa</string> <string name="poi_car_wash">Myjnia samochodowa</string>
<string name="poi_fuel">Stacja benzynowa;Stacja paliw;CPN;Tanksztela</string> <string name="poi_fuel">Stacja benzynowa;Stacja paliw;CPN;Tanksztela</string>
<string name="poi_electricity_combined_charging">Stacja ładowania</string> <string name="poi_electricity_combined_charging">Stacja ładująca; Stacja ładowania pojazdów elektrycznych; Stacja ładująca EV; Elektryczny punkt ładowania; Punkt ładowania; Elektroniczna stacja ładująca; Sprzęt do zasilania pojazdów elektrycznych</string>
<string name="poi_vehicle_ramp">Podnośnik</string> <string name="poi_vehicle_ramp">Podnośnik</string>
<string name="poi_compressed_air">Kompresor</string> <string name="poi_compressed_air">Kompresor</string>
<string name="poi_parking">Parking</string> <string name="poi_parking">Parking</string>
@ -3880,4 +3880,20 @@
<string name="poi_water_source_river">Rzeka</string> <string name="poi_water_source_river">Rzeka</string>
<string name="poi_vaccination_covid19">Szczepienia: COVID19</string> <string name="poi_vaccination_covid19">Szczepienia: COVID19</string>
<string name="poi_health_specialty_vaccination_yes">Szczepienia</string> <string name="poi_health_specialty_vaccination_yes">Szczepienia</string>
<string name="poi_swimming_area">Kąpielisko</string>
<string name="poi_waste_transfer_station">Stacja przeładunkowa</string>
<string name="poi_weightbridge">Waga pomostowa</string>
<string name="poi_ranger_station">Stacja strażników</string>
<string name="poi_water_source_powered_pump">Pompa zasilana</string>
<string name="poi_water_source_water_works">Stacja uzdatniania wody</string>
<string name="poi_water_source_tube_well">Studnia rurowa</string>
<string name="poi_lifeguard_base">Baza ratowników</string>
<string name="poi_mobile_money_agent">Mobilny agent pieniędzy</string>
<string name="poi_liaison_subnational">Subnarodowe</string>
<string name="poi_liaison_representative_office">Przedstawicielstwo</string>
<string name="poi_consulate_honorary_consul">Konsul honorowy</string>
<string name="poi_consulate_consular_office">Biuro konsularne</string>
<string name="poi_embassy_interests_section">Sekcja zainteresowań</string>
<string name="poi_diplomatic_liaison">Łączność</string>
<string name="poi_liaison_filter">Łączność</string>
</resources> </resources>

View file

@ -4032,4 +4032,17 @@
<string name="routing_attr_allow_streams_name">Zezwalaj na strumienie i dreny</string> <string name="routing_attr_allow_streams_name">Zezwalaj na strumienie i dreny</string>
<string name="routing_attr_allow_intermittent_description">Zezwalaj na przerywane drogi wodne</string> <string name="routing_attr_allow_intermittent_description">Zezwalaj na przerywane drogi wodne</string>
<string name="routing_attr_allow_intermittent_name">Zezwalaj na przerywane drogi wodne</string> <string name="routing_attr_allow_intermittent_name">Zezwalaj na przerywane drogi wodne</string>
<string name="voice_prompts_timetable">Czas monitów głosowych</string>
<string name="shared_string_subtype">Podtyp</string>
<string name="shared_string_vehicle">Pojazd</string>
<string name="shared_string_api_key">Klucz API</string>
<string name="shared_string_server_url">Adres URL serwera</string>
<string name="shared_string_enter_param">Wpisz param</string>
<string name="keep_it_empty_if_not">Jeśli nie, zostaw to puste</string>
<string name="online_routing_example_hint">Adres URL ze wszystkimi parametrami będzie wyglądał następująco:</string>
<string name="test_route_calculation">Obliczanie trasy testowej</string>
<string name="routing_engine_vehicle_type_bike">Rower</string>
<string name="routing_engine_vehicle_type_car">Samochód</string>
<string name="message_error_recheck_parameters">Błąd, ponownie sprawdź parametry</string>
<string name="copy_address">Skopiuj adres</string>
</resources> </resources>

View file

@ -4023,4 +4023,19 @@
<string name="routing_attr_allow_intermittent_description">Permitir vias de água intermitentes</string> <string name="routing_attr_allow_intermittent_description">Permitir vias de água intermitentes</string>
<string name="routing_attr_allow_intermittent_name">Permitir vias de água intermitentes</string> <string name="routing_attr_allow_intermittent_name">Permitir vias de água intermitentes</string>
<string name="voice_prompts_timetable">Horários de avisos de voz</string> <string name="voice_prompts_timetable">Horários de avisos de voz</string>
<string name="add_online_routing_engine">Adicionar mecanismo de roteamento online</string>
<string name="edit_online_routing_engine">Editar mecanismo de roteamento online</string>
<string name="shared_string_subtype">Subtipo</string>
<string name="shared_string_vehicle">Veículo</string>
<string name="shared_string_api_key">Chave de API</string>
<string name="shared_string_server_url">URL do servidor</string>
<string name="shared_string_enter_param">Digite o parâmetro</string>
<string name="keep_it_empty_if_not">Mantenha-o vazio se não</string>
<string name="online_routing_example_hint">O URL com todos os parâmetros terá a seguinte aparência:</string>
<string name="test_route_calculation">Cálculo da rota de teste</string>
<string name="routing_engine_vehicle_type_driving">Dirigindo</string>
<string name="routing_engine_vehicle_type_foot"></string>
<string name="routing_engine_vehicle_type_bike">Bicicleta</string>
<string name="routing_engine_vehicle_type_car">Carro</string>
<string name="message_error_recheck_parameters">Erro, verifique novamente os parâmetros</string>
</resources> </resources>

View file

@ -618,7 +618,7 @@
<string name="map_online_data_descr">Imprea sas mapas in lìnia (iscàrriga e archìvia sos tasseddos in sischeda de memòria).</string> <string name="map_online_data_descr">Imprea sas mapas in lìnia (iscàrriga e archìvia sos tasseddos in sischeda de memòria).</string>
<string name="shared_string_online_maps">Mapas in lìnia</string> <string name="shared_string_online_maps">Mapas in lìnia</string>
<string name="online_map_settings_descr">Ischerta sas mitzas de sas mapas in lìnia o de sos tasseddos in cache.</string> <string name="online_map_settings_descr">Ischerta sas mitzas de sas mapas in lìnia o de sos tasseddos in cache.</string>
<string name="osmand_accessibility_description">Permitit de impreare sas funtzionalidades pro s\'atzessibilidade de su dispositivu ditetamente in OsmAnd, e fatzilitat, pro nàrrere, sa modìfica de sa lestresa de sas boghes de sìntesi vocale, sa cunfiguratzione de su movimentu de s\'ischermu, simpreu de una trackball pro s\'ismanniamentu o de uninterfàtzia vocale pro cosas che s\'annùntziu de sa positzione tua.</string> <string name="osmand_accessibility_description">Permitit de impreare sas funtzionalidades pro s\'atzessibilidade de su dispositivu diretamente in OsmAnd, e fatzìlitat, pro nàrrere, sa modìfica de sa lestresa de sas boghes de sìntesi vocale, sa cunfiguratzione de su movimentu de s\'ischermu, simpreu de una trackball pro s\'ismanniamentu o de uninterfache vocale pro cosas che s\'annùntziu de sa positzione tua.</string>
<string name="plugins_screen">Estensiones</string> <string name="plugins_screen">Estensiones</string>
<string name="prefs_plugins_descr">Sas estensiones abìlitant funtzionalidades agiuntivas e impostatziones avantzadas.</string> <string name="prefs_plugins_descr">Sas estensiones abìlitant funtzionalidades agiuntivas e impostatziones avantzadas.</string>
<string name="prefs_plugins">Estensiones</string> <string name="prefs_plugins">Estensiones</string>
@ -909,7 +909,7 @@
<string name="search_osm_offline">Chirca impreende sa positzione geogràfica</string> <string name="search_osm_offline">Chirca impreende sa positzione geogràfica</string>
<string name="system_locale">Sistema</string> <string name="system_locale">Sistema</string>
<string name="preferred_locale_descr">Limba de interfache de s\'aplicatzione (impreada a pustis chi as a torrare a allùghere OsmAnd).</string> <string name="preferred_locale_descr">Limba de interfache de s\'aplicatzione (impreada a pustis chi as a torrare a allùghere OsmAnd).</string>
<string name="preferred_locale">Limba interfàtzia</string> <string name="preferred_locale">Limba de interfache</string>
<string name="incomplete_locale">non cumpridu</string> <string name="incomplete_locale">non cumpridu</string>
<string name="shared_string_next">Imbeniente</string> <string name="shared_string_next">Imbeniente</string>
<string name="shared_string_previous">Antepostu</string> <string name="shared_string_previous">Antepostu</string>

View file

@ -4028,4 +4028,19 @@
<string name="routing_attr_allow_intermittent_description">Povoliť dočasné vodné toky</string> <string name="routing_attr_allow_intermittent_description">Povoliť dočasné vodné toky</string>
<string name="routing_attr_allow_intermittent_name">Povoliť dočasné vodné toky</string> <string name="routing_attr_allow_intermittent_name">Povoliť dočasné vodné toky</string>
<string name="voice_prompts_timetable">Časy hlasových pokynov</string> <string name="voice_prompts_timetable">Časy hlasových pokynov</string>
<string name="add_online_routing_engine">Pridať online navigačnú službu</string>
<string name="edit_online_routing_engine">Upraviť online navigačnú službu</string>
<string name="shared_string_subtype">Podtyp</string>
<string name="shared_string_vehicle">Vozidlo</string>
<string name="shared_string_api_key">Kľúč API</string>
<string name="shared_string_server_url">Adresa URL serveru</string>
<string name="shared_string_enter_param">Zadajte parameter</string>
<string name="keep_it_empty_if_not">Ak nie, ponechajte prázdne</string>
<string name="online_routing_example_hint">Adresa URL so všetkými parametrami bude vyzerať nasledovne:</string>
<string name="test_route_calculation">Vyskúšať výpočet trasy</string>
<string name="routing_engine_vehicle_type_driving">Vedenie vozidla</string>
<string name="routing_engine_vehicle_type_foot">Chôdza</string>
<string name="routing_engine_vehicle_type_bike">Bicykel</string>
<string name="routing_engine_vehicle_type_car">Auto</string>
<string name="message_error_recheck_parameters">Chyba, skontrolujte parametre</string>
</resources> </resources>

View file

@ -944,7 +944,7 @@
<string name="poi_route_hiking_lwn_poi">Yerel yürüyüş güzergahı</string> <string name="poi_route_hiking_lwn_poi">Yerel yürüyüş güzergahı</string>
<string name="poi_route_hiking_ref_poi">Yürüyüş yolu başvurusu</string> <string name="poi_route_hiking_ref_poi">Yürüyüş yolu başvurusu</string>
<string name="poi_opening_hours">Çalışma saatleri</string> <string name="poi_opening_hours">Çalışma saatleri</string>
<string name="poi_collection_times">Koleksiyon kez</string> <string name="poi_collection_times">Toplama zamanları</string>
<string name="poi_description">ıklama</string> <string name="poi_description">ıklama</string>
<string name="poi_phone">Telefon</string> <string name="poi_phone">Telefon</string>
<string name="poi_website">İnternet sitesi</string> <string name="poi_website">İnternet sitesi</string>
@ -3137,4 +3137,12 @@
<string name="poi_diplomatic_services_non_immigrant_visas_filter">Göçmen olmayan vizeleri</string> <string name="poi_diplomatic_services_non_immigrant_visas_filter">Göçmen olmayan vizeleri</string>
<string name="poi_military_checkpoint">Askeri denetim noktası</string> <string name="poi_military_checkpoint">Askeri denetim noktası</string>
<string name="poi_checkpoint_hiking">Yürüyüş denetim noktası</string> <string name="poi_checkpoint_hiking">Yürüyüş denetim noktası</string>
<string name="poi_street_cabinet_street_lighting">Dolap türü: sokak aydınlatması</string>
<string name="poi_street_cabinet_water_management">Dolap türü: su yönetimi</string>
<string name="poi_street_cabinet_waste">Dolap türü: atık</string>
<string name="poi_street_cabinet_postal_service">Dolap türü: posta hizmeti</string>
<string name="poi_street_cabinet_gas">Dolap türü: gaz</string>
<string name="poi_street_cabinet_cable_tv">Dolap türü: kablo tv</string>
<string name="poi_street_cabinet_telecom">Dolap türü: telefon</string>
<string name="poi_street_cabinet_power">Dolap türü: elektrik</string>
</resources> </resources>

View file

@ -1701,7 +1701,7 @@
<string name="remove_the_tag">Etiketi Kaldır</string> <string name="remove_the_tag">Etiketi Kaldır</string>
<string name="version_settings_descr">Gecelik derlemeleri indir.</string> <string name="version_settings_descr">Gecelik derlemeleri indir.</string>
<string name="version_settings">kurar</string> <string name="version_settings">kurar</string>
<string name="rendering_attr_streetLighting_name">Sokak Aydınlatma</string> <string name="rendering_attr_streetLighting_name">Sokak aydınlatma</string>
<string name="proxy_pref_title">Vekil sunucu</string> <string name="proxy_pref_title">Vekil sunucu</string>
<string name="proxy_pref_descr">Bir proxy sunucusu belirtin.</string> <string name="proxy_pref_descr">Bir proxy sunucusu belirtin.</string>
<string name="settings_privacy">Gizlilik</string> <string name="settings_privacy">Gizlilik</string>
@ -3982,5 +3982,21 @@
<string name="routing_attr_allow_streams_name">Dere ve kanalizasyonlara izin ver</string> <string name="routing_attr_allow_streams_name">Dere ve kanalizasyonlara izin ver</string>
<string name="routing_attr_allow_intermittent_description">Aralıklı su yollarına izin verin</string> <string name="routing_attr_allow_intermittent_description">Aralıklı su yollarına izin verin</string>
<string name="routing_attr_allow_intermittent_name">Aralıklı su yollarına izin ver</string> <string name="routing_attr_allow_intermittent_name">Aralıklı su yollarına izin ver</string>
<string name="voice_prompts_timetable">Sesli uyarı zamanı</string> <string name="voice_prompts_timetable">Sesli uyarı zamanları</string>
<string name="add_online_routing_engine">Çevrim içi yönlendirme motoru ekle</string>
<string name="edit_online_routing_engine">Çevrim içi yönlendirme motorunu düzenle</string>
<string name="shared_string_subtype">Alt tür</string>
<string name="shared_string_vehicle">Araç</string>
<string name="shared_string_api_key">API anahtarı</string>
<string name="shared_string_server_url">Sunucu URL\'si</string>
<string name="shared_string_enter_param">Parametre gir</string>
<string name="keep_it_empty_if_not">Değilse boş tut</string>
<string name="online_routing_example_hint">Tüm parametreleri ile URL şu şekilde görünecektir:</string>
<string name="test_route_calculation">Güzergah hesaplamayı test et</string>
<string name="routing_engine_vehicle_type_driving">Araba sürme</string>
<string name="routing_engine_vehicle_type_foot">Yürüme</string>
<string name="routing_engine_vehicle_type_bike">Bisiklet</string>
<string name="routing_engine_vehicle_type_car">Araba</string>
<string name="message_error_recheck_parameters">Hata, parametreleri tekrar gözden geçirin</string>
<string name="copy_address">Adresi kopyala</string>
</resources> </resources>

View file

@ -4024,4 +4024,19 @@
<string name="routing_attr_allow_streams_description">Дозволити потоки та стічні канали</string> <string name="routing_attr_allow_streams_description">Дозволити потоки та стічні канали</string>
<string name="routing_attr_allow_streams_name">Дозволити потоки та стічні канали</string> <string name="routing_attr_allow_streams_name">Дозволити потоки та стічні канали</string>
<string name="voice_prompts_timetable">Голосові підказки</string> <string name="voice_prompts_timetable">Голосові підказки</string>
<string name="add_online_routing_engine">Додати мережний рушій маршрутизації</string>
<string name="edit_online_routing_engine">Змінити мережний рушій маршрутизації</string>
<string name="shared_string_subtype">Підтип</string>
<string name="shared_string_vehicle">Транспортний засіб</string>
<string name="shared_string_api_key">Ключ API</string>
<string name="shared_string_server_url">URL-адреса сервера</string>
<string name="shared_string_enter_param">Введіть параметр</string>
<string name="keep_it_empty_if_not">Залиште порожнім, якщо не маєте ключа API</string>
<string name="online_routing_example_hint">URL-адреса з усіма параметрами виглядатиме так:</string>
<string name="test_route_calculation">Тестове обчислення маршруту</string>
<string name="routing_engine_vehicle_type_driving">Водіння</string>
<string name="routing_engine_vehicle_type_foot">Пішки</string>
<string name="routing_engine_vehicle_type_bike">Велосипед</string>
<string name="routing_engine_vehicle_type_car">Автомобіль</string>
<string name="message_error_recheck_parameters">Помилка, повторно перевірте параметри</string>
</resources> </resources>

View file

@ -4023,4 +4023,20 @@
<string name="routing_attr_allow_intermittent_description">允許間歇水路</string> <string name="routing_attr_allow_intermittent_description">允許間歇水路</string>
<string name="routing_attr_allow_intermittent_name">允許間歇水路</string> <string name="routing_attr_allow_intermittent_name">允許間歇水路</string>
<string name="voice_prompts_timetable">語音提示時間</string> <string name="voice_prompts_timetable">語音提示時間</string>
<string name="add_online_routing_engine">新增線上路線引擎</string>
<string name="edit_online_routing_engine">編輯線上路線引擎</string>
<string name="shared_string_subtype">子類型</string>
<string name="shared_string_vehicle">車輛</string>
<string name="shared_string_api_key">API 金鑰</string>
<string name="shared_string_server_url">伺服器 URL</string>
<string name="shared_string_enter_param">輸入參數</string>
<string name="keep_it_empty_if_not">否則請保持空白</string>
<string name="online_routing_example_hint">帶有所有參數的 URL 如下所示:</string>
<string name="test_route_calculation">測試路線計算</string>
<string name="routing_engine_vehicle_type_driving">駕駛</string>
<string name="routing_engine_vehicle_type_foot">步行</string>
<string name="routing_engine_vehicle_type_bike">自行車</string>
<string name="routing_engine_vehicle_type_car">汽車</string>
<string name="message_error_recheck_parameters">錯誤,重新檢查參數</string>
<string name="copy_address">複製地址</string>
</resources> </resources>

View file

@ -11,6 +11,10 @@
Thx - Hardy Thx - Hardy
--> -->
<string name="online_routing_engines">Online routing engines</string>
<string name="online_routing_engine">Online routing engine</string>
<string name="copy_address">Copy address</string>
<string name="message_error_recheck_parameters">Error, recheck parameters</string> <string name="message_error_recheck_parameters">Error, recheck parameters</string>
<string name="routing_engine_vehicle_type_car">Car</string> <string name="routing_engine_vehicle_type_car">Car</string>
<string name="routing_engine_vehicle_type_bike">Bike</string> <string name="routing_engine_vehicle_type_bike">Bike</string>
@ -4026,5 +4030,4 @@
<string name="routing_attr_freeride_policy_description">\'Freeride\' and \'Off-piste\' are unofficial routes and passages. Typically ungroomed, unmaintained and not checked in the evening. Enter at your own risk.</string> <string name="routing_attr_freeride_policy_description">\'Freeride\' and \'Off-piste\' are unofficial routes and passages. Typically ungroomed, unmaintained and not checked in the evening. Enter at your own risk.</string>
<string name="voice_prompts_timetable">Voice prompts times</string> <string name="voice_prompts_timetable">Voice prompts times</string>
</resources> </resources>

View file

@ -23,12 +23,13 @@ import android.util.AttributeSet;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.webkit.WebView;
import net.osmand.plus.widgets.WebViewEx;
/** /**
* WebView that its scroll position can be observed. * WebView that its scroll position can be observed.
*/ */
public class ObservableWebView extends WebView implements Scrollable { public class ObservableWebView extends WebViewEx implements Scrollable {
// Fields that should be saved onSaveInstanceState // Fields that should be saved onSaveInstanceState
private int mPrevScrollY; private int mPrevScrollY;

View file

@ -812,8 +812,7 @@ public class OsmAndLocationProvider implements SensorEventListener {
setLocation(location); setLocation(location);
} }
private void setLocation(net.osmand.Location location) { private void setLocation(net.osmand.Location location) { if (location == null) {
if (location == null) {
updateGPSInfo(null); updateGPSInfo(null);
} }

View file

@ -3,7 +3,6 @@
*/ */
package net.osmand.plus.activities; package net.osmand.plus.activities;
import android.view.Window;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;

View file

@ -576,7 +576,7 @@ public class DownloadIndexesThread {
manager.indexVoiceFiles(this); manager.indexVoiceFiles(this);
manager.indexFontFiles(this); manager.indexFontFiles(this);
if (vectorMapsToReindex) { if (vectorMapsToReindex) {
warnings = manager.indexingMaps(this); warnings = manager.indexingMaps(this, filesToReindex);
} }
List<String> wns = manager.indexAdditionalMaps(this); List<String> wns = manager.indexAdditionalMaps(this);
if (wns != null) { if (wns != null) {

View file

@ -29,20 +29,29 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.osm.PoiCategory;
import net.osmand.osm.PoiType;
import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.*; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.Version;
import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
@ -51,6 +60,7 @@ import net.osmand.plus.mapcontextmenu.builders.cards.CardsRowBuilder;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask;
import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard; import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard;
import net.osmand.plus.mapcontextmenu.controllers.AmenityMenuController;
import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController;
import net.osmand.plus.openplacereviews.AddPhotosBottomSheetDialogFragment; import net.osmand.plus.openplacereviews.AddPhotosBottomSheetDialogFragment;
import net.osmand.plus.openplacereviews.OPRConstants; import net.osmand.plus.openplacereviews.OPRConstants;
@ -65,6 +75,7 @@ import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.widgets.tools.ClickableSpanTouchListener; import net.osmand.plus.widgets.tools.ClickableSpanTouchListener;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.openplacereviews.opendb.util.exception.FailedVerificationException; import org.openplacereviews.opendb.util.exception.FailedVerificationException;
@ -72,7 +83,13 @@ import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener;
@ -91,13 +108,15 @@ public class MenuBuilder {
private boolean firstRow; private boolean firstRow;
protected boolean matchWidthDivider; protected boolean matchWidthDivider;
protected boolean light; protected boolean light;
private long objectId; private Amenity amenity;
private LatLon latLon; private LatLon latLon;
private boolean hidden; private boolean hidden;
private boolean showTitleIfTruncated = true; private boolean showTitleIfTruncated = true;
private boolean showNearestWiki = false; private boolean showNearestWiki = false;
private boolean showNearestPoi = false;
private boolean showOnlinePhotos = true; private boolean showOnlinePhotos = true;
protected List<Amenity> nearestWiki = new ArrayList<>(); protected List<Amenity> nearestWiki = new ArrayList<>();
protected List<Amenity> nearestPoi = new ArrayList<>();
private List<OsmandPlugin> menuPlugins = new ArrayList<>(); private List<OsmandPlugin> menuPlugins = new ArrayList<>();
@Nullable @Nullable
private CardsRowBuilder onlinePhotoCardsRow; private CardsRowBuilder onlinePhotoCardsRow;
@ -208,10 +227,18 @@ public class MenuBuilder {
return showNearestWiki; return showNearestWiki;
} }
public boolean isShowNearestPoi() {
return showNearestPoi;
}
public void setShowNearestWiki(boolean showNearestWiki) { public void setShowNearestWiki(boolean showNearestWiki) {
this.showNearestWiki = showNearestWiki; this.showNearestWiki = showNearestWiki;
} }
public void setShowNearestPoi(boolean showNearestPoi) {
this.showNearestPoi = showNearestPoi;
}
public void setShowTitleIfTruncated(boolean showTitleIfTruncated) { public void setShowTitleIfTruncated(boolean showTitleIfTruncated) {
this.showTitleIfTruncated = showTitleIfTruncated; this.showTitleIfTruncated = showTitleIfTruncated;
} }
@ -224,9 +251,8 @@ public class MenuBuilder {
this.showOnlinePhotos = showOnlinePhotos; this.showOnlinePhotos = showOnlinePhotos;
} }
public void setShowNearestWiki(boolean showNearestWiki, long objectId) { public void setAmenity(Amenity amenity) {
this.objectId = objectId; this.amenity = amenity;
this.showNearestWiki = showNearestWiki;
} }
public void addMenuPlugin(OsmandPlugin plugin) { public void addMenuPlugin(OsmandPlugin plugin) {
@ -246,6 +272,7 @@ public class MenuBuilder {
buildTitleRow(view); buildTitleRow(view);
} }
buildNearestWikiRow(view); buildNearestWikiRow(view);
buildNearestPoiRow(view);
if (needBuildPlainMenuItems()) { if (needBuildPlainMenuItems()) {
buildPlainMenuItems(view); buildPlainMenuItems(view);
} }
@ -325,10 +352,20 @@ public class MenuBuilder {
} }
protected void buildNearestWikiRow(View view) { protected void buildNearestWikiRow(View view) {
if (processNearestWiki() && nearestWiki.size() > 0) { buildNearestRow(view, nearestWiki, processNearestWiki(),
buildRow(view, R.drawable.ic_action_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", 0, R.drawable.ic_action_wikipedia, app.getString(R.string.wiki_around));
true, getCollapsableWikiView(view.getContext(), true), }
false, 0, false, null, false);
protected void buildNearestPoiRow(View view) {
buildNearestRow(view, nearestPoi, processNearestPoi(),
nearestPoi.isEmpty() ? 0 : AmenityMenuController.getRightIconId(nearestPoi.get(0)),
app.getString(R.string.speak_poi));
}
protected void buildNearestRow(View view, List<Amenity> nearestAmenities, boolean process, int iconId, String text) {
if (process && nearestAmenities.size() > 0) {
buildRow(view, iconId, null, text + " (" + nearestAmenities.size() + ")", 0, true,
getCollapsableView(view.getContext(), true, nearestAmenities), false, 0, false, null, false);
} }
} }
@ -1118,20 +1155,23 @@ public class MenuBuilder {
return new CollapsableView(textView, this, collapsed); return new CollapsableView(textView, this, collapsed);
} }
protected CollapsableView getCollapsableWikiView(Context context, boolean collapsed) { protected CollapsableView getCollapsableView(Context context, boolean collapsed, List<Amenity> nearestAmenities) {
LinearLayout view = (LinearLayout) buildCollapsableContentView(context, collapsed, true); LinearLayout view = (LinearLayout) buildCollapsableContentView(context, collapsed, true);
for (final Amenity wiki : nearestWiki) { for (final Amenity poi : nearestAmenities) {
TextViewEx button = buildButtonInCollapsableView(context, false, false); TextViewEx button = buildButtonInCollapsableView(context, false, false);
String name = wiki.getName(preferredMapAppLang, transliterateNames); String name = poi.getName(preferredMapAppLang, transliterateNames);
if (Algorithms.isBlank(name)) {
name = AmenityMenuController.getTypeStr(poi);
}
button.setText(name); button.setText(name);
button.setOnClickListener(new View.OnClickListener() { button.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
LatLon latLon = new LatLon(wiki.getLocation().getLatitude(), wiki.getLocation().getLongitude()); LatLon latLon = new LatLon(poi.getLocation().getLatitude(), poi.getLocation().getLongitude());
PointDescription pointDescription = mapActivity.getMapLayers().getPoiMapLayer().getObjectName(wiki); PointDescription pointDescription = mapActivity.getMapLayers().getPoiMapLayer().getObjectName(poi);
mapActivity.getContextMenu().show(latLon, pointDescription, wiki); mapActivity.getContextMenu().show(latLon, pointDescription, poi);
} }
}); });
view.addView(button); view.addView(button);
@ -1191,14 +1231,36 @@ public class MenuBuilder {
} }
protected boolean processNearestWiki() { protected boolean processNearestWiki() {
if (showNearestWiki && latLon != null) { if (showNearestWiki && latLon != null && amenity != null) {
QuadRect rect = MapUtils.calculateLatLonBbox( PoiUIFilter filter = app.getPoiFilters().getTopWikiPoiFilter();
latLon.getLatitude(), latLon.getLongitude(), 250); if (filter != null) {
PoiUIFilter wikiPoiFilter = app.getPoiFilters().getTopWikiPoiFilter(); nearestWiki = getSortedAmenities(filter, latLon);
return true;
}
}
return false;
}
nearestWiki = getAmenities(rect, wikiPoiFilter); protected boolean processNearestPoi() {
if (showNearestPoi && latLon != null && amenity != null) {
PoiCategory pc = amenity.getType();
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
PoiUIFilter filter = app.getPoiFilters().getFilterById(PoiUIFilter.STD_PREFIX + pt.getKeyName());
if (filter != null) {
nearestPoi = getSortedAmenities(filter, latLon);
return true;
}
}
return false;
}
Collections.sort(nearestWiki, new Comparator<Amenity>() { private List<Amenity> getSortedAmenities(PoiUIFilter filter, final LatLon latLon) {
QuadRect rect = MapUtils.calculateLatLonBbox(latLon.getLatitude(), latLon.getLongitude(), 250);
List<Amenity> nearestAmenities = getAmenities(rect, filter);
nearestAmenities.remove(amenity);
Collections.sort(nearestAmenities, new Comparator<Amenity>() {
@Override @Override
public int compare(Amenity o1, Amenity o2) { public int compare(Amenity o1, Amenity o2) {
@ -1207,17 +1269,8 @@ public class MenuBuilder {
return Double.compare(d1, d2); return Double.compare(d1, d2);
} }
}); });
Long id = objectId;
List<Amenity> wikiList = new ArrayList<>(); return nearestAmenities;
for (Amenity wiki : nearestWiki) {
if (wiki.getId().equals(id)) {
wikiList.add(wiki);
}
}
nearestWiki.removeAll(wikiList);
return true;
}
return false;
} }
private List<Amenity> getAmenities(QuadRect rect, PoiUIFilter wikiPoiFilter) { private List<Amenity> getAmenities(QuadRect rect, PoiUIFilter wikiPoiFilter) {

View file

@ -35,6 +35,7 @@ import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.mapcontextmenu.CollapsableView; import net.osmand.plus.mapcontextmenu.CollapsableView;
import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.controllers.AmenityMenuController;
import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.views.layers.POIMapLayer; import net.osmand.plus.views.layers.POIMapLayer;
@ -78,7 +79,9 @@ public class AmenityMenuBuilder extends MenuBuilder {
public AmenityMenuBuilder(@NonNull MapActivity mapActivity, final @NonNull Amenity amenity) { public AmenityMenuBuilder(@NonNull MapActivity mapActivity, final @NonNull Amenity amenity) {
super(mapActivity); super(mapActivity);
this.amenity = amenity; this.amenity = amenity;
setShowNearestWiki(true, amenity.getId()); setAmenity(amenity);
setShowNearestWiki(true);
setShowNearestPoi(!amenity.getType().isWiki());
metricSystem = mapActivity.getMyApplication().getSettings().METRIC_SYSTEM.get(); metricSystem = mapActivity.getMyApplication().getSettings().METRIC_SYSTEM.get();
} }
@ -86,6 +89,10 @@ public class AmenityMenuBuilder extends MenuBuilder {
protected void buildNearestWikiRow(View view) { protected void buildNearestWikiRow(View view) {
} }
@Override
protected void buildNearestPoiRow(View view) {
}
private void buildRow(View view, int iconId, String text, String textPrefix, private void buildRow(View view, int iconId, String text, String textPrefix,
boolean collapsable, final CollapsableView collapsableView, boolean collapsable, final CollapsableView collapsableView,
int textColor, boolean isWiki, boolean isText, boolean needLinks, int textColor, boolean isWiki, boolean isText, boolean needLinks,
@ -664,11 +671,19 @@ public class AmenityMenuBuilder extends MenuBuilder {
if (processNearestWiki() && nearestWiki.size() > 0) { if (processNearestWiki() && nearestWiki.size() > 0) {
AmenityInfoRow wikiInfo = new AmenityInfoRow( AmenityInfoRow wikiInfo = new AmenityInfoRow(
"nearest_wiki", R.drawable.ic_plugin_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", true, "nearest_wiki", R.drawable.ic_plugin_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", true,
getCollapsableWikiView(view.getContext(), true), getCollapsableView(view.getContext(), true, nearestWiki),
0, false, false, false, 1000, null, false, false, false, 0); 0, false, false, false, 1000, null, false, false, false, 0);
buildAmenityRow(view, wikiInfo); buildAmenityRow(view, wikiInfo);
} }
if (processNearestPoi() && nearestPoi.size() > 0) {
AmenityInfoRow poiInfo = new AmenityInfoRow(
"nearest_poi", AmenityMenuController.getRightIconId(amenity), null, app.getString(R.string.speak_poi) + " (" + nearestPoi.size() + ")", true,
getCollapsableView(view.getContext(), true, nearestPoi),
0, false, false, false, 1000, null, false, false, false, 0);
buildAmenityRow(view, poiInfo);
}
if (osmEditingEnabled && amenity.getId() != null if (osmEditingEnabled && amenity.getId() != null
&& amenity.getId() > 0 && && amenity.getId() > 0 &&
(amenity.getId() % 2 == 0 || (amenity.getId() >> 1) < Integer.MAX_VALUE)) { (amenity.getId() % 2 == 0 || (amenity.getId() >> 1) < Integer.MAX_VALUE)) {

View file

@ -59,9 +59,9 @@ public class FavouritePointMenuBuilder extends MenuBuilder {
} }
@Override @Override
protected void buildNearestWikiRow(View view) { protected void buildNearestRow(View view, List<Amenity> nearestAmenities, boolean process, int iconId, String text) {
if (originObject == null || !(originObject instanceof Amenity)) { if (originObject == null || !(originObject instanceof Amenity)) {
super.buildNearestWikiRow(view); super.buildNearestRow(view, nearestAmenities, process, iconId, text);
} }
} }

View file

@ -1,6 +1,7 @@
package net.osmand.plus.mapcontextmenu.builders.cards; package net.osmand.plus.mapcontextmenu.builders.cards;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -23,6 +24,7 @@ import androidx.core.content.ContextCompat;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.widgets.WebViewEx;
public abstract class AbstractCard { public abstract class AbstractCard {
@ -55,7 +57,7 @@ public abstract class AbstractCard {
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
protected static void openUrl(@NonNull Context ctx, protected static void openUrl(@NonNull Activity ctx,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
@Nullable String title, @Nullable String title,
@NonNull String url, @NonNull String url,
@ -90,7 +92,7 @@ public abstract class AbstractCard {
} }
}); });
final WebView wv = new WebView(ctx); final WebView wv = new WebViewEx(ctx);
wv.setWebViewClient(new WebViewClient() { wv.setWebViewClient(new WebViewClient() {
@Override @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { public boolean shouldOverrideUrlLoading(WebView view, String url) {

View file

@ -116,7 +116,7 @@ public class AmenityMenuController extends MenuController {
return getRightIconId(amenity); return getRightIconId(amenity);
} }
private static int getRightIconId(Amenity amenity) { public static int getRightIconId(Amenity amenity) {
String id = null; String id = null;
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType()); PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
if (st != null) { if (st != null) {

View file

@ -36,6 +36,7 @@ public class ShareMenu extends BaseMenuController {
public enum ShareItem { public enum ShareItem {
MESSAGE(R.drawable.ic_action_message, R.string.shared_string_send), MESSAGE(R.drawable.ic_action_message, R.string.shared_string_send),
CLIPBOARD(R.drawable.ic_action_copy, R.string.shared_string_copy), CLIPBOARD(R.drawable.ic_action_copy, R.string.shared_string_copy),
ADDRESS(R.drawable.ic_action_copy, R.string.copy_address),
NAME(R.drawable.ic_action_copy, R.string.copy_location_name), NAME(R.drawable.ic_action_copy, R.string.copy_location_name),
COORDINATES(R.drawable.ic_action_copy, R.string.copy_coordinates), COORDINATES(R.drawable.ic_action_copy, R.string.copy_coordinates),
GEO(R.drawable.ic_world_globe_dark, R.string.share_geo), GEO(R.drawable.ic_world_globe_dark, R.string.share_geo),
@ -66,6 +67,7 @@ public class ShareMenu extends BaseMenuController {
List<ShareItem> list = new LinkedList<>(); List<ShareItem> list = new LinkedList<>();
list.add(ShareItem.MESSAGE); list.add(ShareItem.MESSAGE);
list.add(ShareItem.CLIPBOARD); list.add(ShareItem.CLIPBOARD);
list.add(ShareItem.ADDRESS);
list.add(ShareItem.NAME); list.add(ShareItem.NAME);
list.add(ShareItem.COORDINATES); list.add(ShareItem.COORDINATES);
list.add(ShareItem.GEO); list.add(ShareItem.GEO);
@ -121,6 +123,15 @@ public class ShareMenu extends BaseMenuController {
case CLIPBOARD: case CLIPBOARD:
ShareDialog.sendToClipboard(mapActivity, sms); ShareDialog.sendToClipboard(mapActivity, sms);
break; break;
case ADDRESS:
if (!Algorithms.isEmpty(address)) {
ShareDialog.sendToClipboard(mapActivity, address);
} else {
Toast.makeText(mapActivity,
R.string.no_address_found,
Toast.LENGTH_LONG).show();
}
break;
case NAME: case NAME:
if (!Algorithms.isEmpty(title)) { if (!Algorithms.isEmpty(title)) {
ShareDialog.sendToClipboard(mapActivity, title); ShareDialog.sendToClipboard(mapActivity, title);

View file

@ -19,6 +19,7 @@ import com.google.android.material.appbar.AppBarLayout;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BaseOsmAndDialogFragment; import net.osmand.plus.base.BaseOsmAndDialogFragment;
import net.osmand.plus.widgets.WebViewEx;
public class GpxDescriptionDialogFragment extends BaseOsmAndDialogFragment { public class GpxDescriptionDialogFragment extends BaseOsmAndDialogFragment {
@ -48,7 +49,7 @@ public class GpxDescriptionDialogFragment extends BaseOsmAndDialogFragment {
AppBarLayout appBar = new AppBarLayout(ctx); AppBarLayout appBar = new AppBarLayout(ctx);
appBar.addView(topBar); appBar.addView(topBar);
WebView webView = new WebView(ctx); WebView webView = new WebViewEx(ctx);
webView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); webView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
webView.getSettings().setTextZoom((int) (getResources().getConfiguration().fontScale * 100f)); webView.getSettings().setTextZoom((int) (getResources().getConfiguration().fontScale * 100f));
Bundle args = getArguments(); Bundle args = getArguments();

View file

@ -3,6 +3,7 @@ package net.osmand.plus.onlinerouting;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -28,9 +29,11 @@ public class OnlineRoutingEngine {
public OnlineRoutingEngine(@NonNull String stringKey, public OnlineRoutingEngine(@NonNull String stringKey,
@NonNull ServerType serverType, @NonNull ServerType serverType,
@NonNull String vehicleKey, @NonNull String vehicleKey,
Map<String, String> params) { @Nullable Map<String, String> params) {
this(stringKey, serverType, vehicleKey); this(stringKey, serverType, vehicleKey);
this.params = params; if (!Algorithms.isEmpty(params)) {
this.params.putAll(params);
}
} }
public OnlineRoutingEngine(@NonNull String stringKey, public OnlineRoutingEngine(@NonNull String stringKey,
@ -96,8 +99,9 @@ public class OnlineRoutingEngine {
} }
public static OnlineRoutingEngine createNewEngine(@NonNull ServerType serverType, public static OnlineRoutingEngine createNewEngine(@NonNull ServerType serverType,
@NonNull String vehicleKey) { @NonNull String vehicleKey,
return new OnlineRoutingEngine(generateKey(), serverType, vehicleKey); @Nullable Map<String, String> params) {
return new OnlineRoutingEngine(generateKey(), serverType, vehicleKey, params);
} }
private static String generateKey() { private static String generateKey() {

View file

@ -402,7 +402,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
if (isEditingMode()) { if (isEditingMode()) {
engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.serverType, engine.getVehicleKey()); engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.serverType, engine.getVehicleKey());
} else { } else {
engineToSave = OnlineRoutingEngine.createNewEngine(engine.serverType, engine.getVehicleKey()); engineToSave = OnlineRoutingEngine.createNewEngine(engine.serverType, engine.getVehicleKey(), null);
} }
engineToSave.putParameter(EngineParameterType.CUSTOM_SERVER_URL, engine.customServerUrl); engineToSave.putParameter(EngineParameterType.CUSTOM_SERVER_URL, engine.customServerUrl);

View file

@ -91,7 +91,7 @@ public class OnlineRoutingHelper {
JSONObject json = new JSONObject(jsonString); JSONObject json = new JSONObject(jsonString);
readFromJson(json, engines); readFromJson(json, engines);
} catch (JSONException e) { } catch (JSONException e) {
LOG.debug("Error when create a new JSONObject: " + e.toString()); LOG.debug("Error when reading engines from JSON ", e);
} }
} }
return engines; return engines;
@ -99,17 +99,19 @@ public class OnlineRoutingHelper {
private void saveToSettings() { private void saveToSettings() {
if (!Algorithms.isEmpty(cachedEngines)) { if (!Algorithms.isEmpty(cachedEngines)) {
try {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
if (writeToJson(json, cachedEngines)) { writeToJson(json, cachedEngines);
settings.ONLINE_ROUTING_ENGINES.set(json.toString()); settings.ONLINE_ROUTING_ENGINES.set(json.toString());
} catch (JSONException e) {
LOG.debug("Error when writing engines to JSON ", e);
} }
} else { } else {
settings.ONLINE_ROUTING_ENGINES.set(null); settings.ONLINE_ROUTING_ENGINES.set(null);
} }
} }
private static void readFromJson(JSONObject json, List<OnlineRoutingEngine> engines) { public static void readFromJson(JSONObject json, List<OnlineRoutingEngine> engines) throws JSONException {
try {
if (!json.has("items")) { if (!json.has("items")) {
return; return;
} }
@ -126,17 +128,13 @@ public class OnlineRoutingHelper {
HashMap<String, String> params = gson.fromJson(paramsString, type); HashMap<String, String> params = gson.fromJson(paramsString, type);
engines.add(new OnlineRoutingEngine(key, serverType, vehicleKey, params)); engines.add(new OnlineRoutingEngine(key, serverType, vehicleKey, params));
} }
} catch (JSONException e) {
LOG.debug("Error when reading engines from JSON: " + e.toString());
}
} }
private static boolean writeToJson(JSONObject json, List<OnlineRoutingEngine> engines) { public static void writeToJson(JSONObject json, List<OnlineRoutingEngine> engines) throws JSONException {
JSONArray jsonArray = new JSONArray(); JSONArray jsonArray = new JSONArray();
Gson gson = new Gson(); Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, String>>() { Type type = new TypeToken<HashMap<String, String>>() {
}.getType(); }.getType();
try {
for (OnlineRoutingEngine engine : engines) { for (OnlineRoutingEngine engine : engines) {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put("key", engine.getStringKey()); jsonObject.put("key", engine.getStringKey());
@ -146,10 +144,5 @@ public class OnlineRoutingHelper {
jsonArray.put(jsonObject); jsonArray.put(jsonObject);
} }
json.put("items", jsonArray); json.put("items", jsonArray);
return true;
} catch (JSONException e) {
LOG.debug("Error when writing engines to JSON: " + e.toString());
return false;
}
} }
} }

View file

@ -138,7 +138,11 @@ public class OsmOAuthAuthorizationAdapter {
@Override @Override
protected void onPostExecute(@NonNull OAuth1RequestToken requestToken) { protected void onPostExecute(@NonNull OAuth1RequestToken requestToken) {
if (requestToken != null) {
loadWebView(rootLayout, nightMode, client.getService().getAuthorizationUrl(requestToken)); loadWebView(rootLayout, nightMode, client.getService().getAuthorizationUrl(requestToken));
} else {
app.showShortToastMessage(app.getString(R.string.internet_not_available));
}
} }
} }

View file

@ -45,7 +45,11 @@ public class OsmOAuthHelper {
} }
public void authorize(@NonNull String oauthVerifier) { public void authorize(@NonNull String oauthVerifier) {
if (oauthVerifier != null) {
authorizationAdapter.authorize(oauthVerifier, this); authorizationAdapter.authorize(oauthVerifier, this);
} else {
updateAdapter();
}
} }
public void resetAuthorization() { public void resetAuthorization() {

View file

@ -621,7 +621,11 @@ public class ResourceManager {
} }
} }
public List<String> indexingMaps(final IProgress progress) { public List<String> indexingMaps(IProgress progress) {
return indexingMaps(progress, Collections.<File>emptyList());
}
public List<String> indexingMaps(final IProgress progress, List<File> filesToReindex) {
long val = System.currentTimeMillis(); long val = System.currentTimeMillis();
ArrayList<File> files = new ArrayList<File>(); ArrayList<File> files = new ArrayList<File>();
File appPath = context.getAppPath(null); File appPath = context.getAppPath(null);
@ -688,7 +692,7 @@ public class ResourceManager {
try { try {
BinaryMapIndexReader mapReader = null; BinaryMapIndexReader mapReader = null;
try { try {
mapReader = cachedOsmandIndexes.getReader(f); mapReader = cachedOsmandIndexes.getReader(f, !filesToReindex.contains(f));
if (mapReader.getVersion() != IndexConstants.BINARY_MAP_VERSION) { if (mapReader.getVersion() != IndexConstants.BINARY_MAP_VERSION) {
mapReader = null; mapReader = null;
} }

View file

@ -24,7 +24,8 @@ public enum ExportSettingsType {
MAP_SOURCES(R.string.quick_action_map_source_title, R.drawable.ic_map), MAP_SOURCES(R.string.quick_action_map_source_title, R.drawable.ic_map),
OFFLINE_MAPS(R.string.shared_string_maps, R.drawable.ic_map), OFFLINE_MAPS(R.string.shared_string_maps, R.drawable.ic_map),
TTS_VOICE(R.string.local_indexes_cat_tts, R.drawable.ic_action_volume_up), TTS_VOICE(R.string.local_indexes_cat_tts, R.drawable.ic_action_volume_up),
VOICE(R.string.local_indexes_cat_voice, R.drawable.ic_action_volume_up); VOICE(R.string.local_indexes_cat_voice, R.drawable.ic_action_volume_up),
ONLINE_ROUTING_ENGINES(R.string.online_routing_engines, R.drawable.ic_world_globe_dark);
@StringRes @StringRes
private final int titleId; private final int titleId;
@ -59,6 +60,6 @@ public enum ExportSettingsType {
public boolean isResourcesCategory() { public boolean isResourcesCategory() {
return this == CUSTOM_RENDER_STYLE || this == CUSTOM_ROUTING || this == MAP_SOURCES return this == CUSTOM_RENDER_STYLE || this == CUSTOM_ROUTING || this == MAP_SOURCES
|| this == OFFLINE_MAPS || this == VOICE || this == TTS_VOICE; || this == OFFLINE_MAPS || this == VOICE || this == TTS_VOICE || this == ONLINE_ROUTING_ENGINES;
} }
} }

View file

@ -48,7 +48,6 @@ import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.mapillary.MapillaryPlugin; import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format; import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format;
import net.osmand.plus.mapmarkers.MapMarkersMode; import net.osmand.plus.mapmarkers.MapMarkersMode;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.profiles.LocationIcon; import net.osmand.plus.profiles.LocationIcon;
import net.osmand.plus.profiles.NavigationIcon; import net.osmand.plus.profiles.NavigationIcon;
import net.osmand.plus.profiles.ProfileIconColors; import net.osmand.plus.profiles.ProfileIconColors;
@ -1016,7 +1015,7 @@ public class OsmandSettings {
ROUTE_SERVICE.setModeDefaultValue(ApplicationMode.AIRCRAFT, RouteService.STRAIGHT); ROUTE_SERVICE.setModeDefaultValue(ApplicationMode.AIRCRAFT, RouteService.STRAIGHT);
} }
public final CommonPreference<String> ONLINE_ROUTING_ENGINES = new StringPreference(this, "online_routing_engines", null); public final CommonPreference<String> ONLINE_ROUTING_ENGINES = new StringPreference(this, "online_routing_engines", null).makeGlobal();
public final CommonPreference<NavigationIcon> NAVIGATION_ICON = new EnumStringPreference<>(this, "navigation_icon", NavigationIcon.DEFAULT, NavigationIcon.values()).makeProfile().cache(); public final CommonPreference<NavigationIcon> NAVIGATION_ICON = new EnumStringPreference<>(this, "navigation_icon", NavigationIcon.DEFAULT, NavigationIcon.values()).makeProfile().cache();

View file

@ -92,11 +92,6 @@ public class AvoidRoadsSettingsItem extends CollectionSettingsItem<AvoidRoadInfo
return false; return false;
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@Override @Override
public boolean shouldShowDuplicates() { public boolean shouldShowDuplicates() {
return false; return false;

View file

@ -72,6 +72,11 @@ public abstract class CollectionSettingsItem<T> extends SettingsItem {
return true; return true;
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
public abstract boolean isDuplicate(@NonNull T item); public abstract boolean isDuplicate(@NonNull T item);
@NonNull @NonNull

View file

@ -109,11 +109,6 @@ public class FavoritesSettingsItem extends CollectionSettingsItem<FavoriteGroup>
return false; return false;
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@NonNull @NonNull
@Override @Override
public FavoriteGroup renameItem(@NonNull FavoriteGroup item) { public FavoriteGroup renameItem(@NonNull FavoriteGroup item) {

View file

@ -103,11 +103,6 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem<MapMarker
return false; return false;
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@NonNull @NonNull
@Override @Override
public MapMarker renameItem(@NonNull MapMarker item) { public MapMarker renameItem(@NonNull MapMarker item) {

View file

@ -130,11 +130,6 @@ public class MapSourcesSettingsItem extends CollectionSettingsItem<ITileSource>
return "map_sources"; return "map_sources";
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@Override @Override
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException { void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
try { try {

View file

@ -103,11 +103,6 @@ public class MarkersSettingsItem extends CollectionSettingsItem<MapMarker> {
return false; return false;
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@NonNull @NonNull
@Override @Override
public MapMarker renameItem(@NonNull MapMarker item) { public MapMarker renameItem(@NonNull MapMarker item) {

View file

@ -0,0 +1,137 @@
package net.osmand.plus.settings.backend.backup;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameterType;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class OnlineRoutingSettingsItem extends CollectionSettingsItem<OnlineRoutingEngine> {
private OnlineRoutingHelper onlineRoutingHelper;
public OnlineRoutingSettingsItem(@NonNull OsmandApplication app, @NonNull List<OnlineRoutingEngine> items) {
super(app, null, items);
}
public OnlineRoutingSettingsItem(@NonNull OsmandApplication app, @Nullable OnlineRoutingSettingsItem baseItem, @NonNull List<OnlineRoutingEngine> items) {
super(app, baseItem, items);
}
public OnlineRoutingSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app, json);
}
@Override
protected void init() {
super.init();
onlineRoutingHelper = app.getOnlineRoutingHelper();
existingItems = new ArrayList<>(onlineRoutingHelper.getEngines());
}
@NonNull
@Override
public SettingsItemType getType() {
return SettingsItemType.ONLINE_ROUTING_ENGINES;
}
@NonNull
@Override
public String getName() {
return "online_routing_engines";
}
@NonNull
@Override
public String getPublicName(@NonNull Context ctx) {
return ctx.getString(R.string.online_routing_engine);
}
@Override
public void apply() {
List<OnlineRoutingEngine> newItems = getNewItems();
if (!newItems.isEmpty() || !duplicateItems.isEmpty()) {
appliedItems = new ArrayList<>(newItems);
for (OnlineRoutingEngine duplicate : duplicateItems) {
if (shouldReplace) {
onlineRoutingHelper.deleteEngine(duplicate.getStringKey());
}
appliedItems.add(shouldReplace ? duplicate : renameItem(duplicate));
}
for (OnlineRoutingEngine engine : appliedItems) {
onlineRoutingHelper.saveEngine(engine);
}
}
}
@Override
public boolean isDuplicate(@NonNull OnlineRoutingEngine routingEngine) {
for (OnlineRoutingEngine engine : existingItems) {
if (engine.getStringKey().equals(routingEngine.getStringKey())
|| engine.getName(app).equals(routingEngine.getName(app))) {
return true;
}
}
return false;
}
@NonNull
@Override
public OnlineRoutingEngine renameItem(@NonNull OnlineRoutingEngine item) {
int number = 0;
while (true) {
number++;
OnlineRoutingEngine renamedItem = OnlineRoutingEngine.createNewEngine(item.getServerType(), item.getVehicleKey(), item.getParams());
renamedItem.putParameter(EngineParameterType.CUSTOM_NAME, renamedItem.getName(app) + "_" + number);
if (!isDuplicate(renamedItem)) {
return renamedItem;
}
}
}
@Override
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
try {
OnlineRoutingHelper.readFromJson(json, items);
} catch (JSONException e) {
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
throw new IllegalArgumentException("Json parse error", e);
}
}
@Override
void writeItemsToJson(@NonNull JSONObject json) {
if (!items.isEmpty()) {
try {
OnlineRoutingHelper.writeToJson(json, items);
} catch (JSONException e) {
warnings.add(app.getString(R.string.settings_item_write_error, String.valueOf(getType())));
SettingsHelper.LOG.error("Failed write to json", e);
}
}
}
@Nullable
@Override
SettingsItemReader<? extends SettingsItem> getReader() {
return getJsonReader();
}
@Nullable
@Override
SettingsItemWriter<? extends SettingsItem> getWriter() {
return getJsonWriter();
}
}

View file

@ -113,11 +113,6 @@ public class OsmEditsSettingsItem extends CollectionSettingsItem<OpenstreetmapPo
return ctx.getString(R.string.osm_edits); return ctx.getString(R.string.osm_edits);
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@Override @Override
public boolean shouldShowDuplicates() { public boolean shouldShowDuplicates() {
return false; return false;

View file

@ -106,11 +106,6 @@ public class OsmNotesSettingsItem extends CollectionSettingsItem<OsmNotesPoint>
return ctx.getString(R.string.osm_notes); return ctx.getString(R.string.osm_notes);
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@Override @Override
public boolean shouldShowDuplicates() { public boolean shouldShowDuplicates() {
return false; return false;

View file

@ -105,11 +105,6 @@ public class PoiUiFiltersSettingsItem extends CollectionSettingsItem<PoiUIFilter
return "poi_ui_filters"; return "poi_ui_filters";
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@Override @Override
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException { void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
try { try {

View file

@ -89,11 +89,6 @@ public class QuickActionsSettingsItem extends CollectionSettingsItem<QuickAction
} }
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@NonNull @NonNull
@Override @Override
public String getName() { public String getName() {

View file

@ -148,11 +148,6 @@ public class SearchHistorySettingsItem extends CollectionSettingsItem<HistoryEnt
return false; return false;
} }
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@NonNull @NonNull
@Override @Override
public HistoryEntry renameItem(@NonNull HistoryEntry item) { public HistoryEntry renameItem(@NonNull HistoryEntry item) {

View file

@ -33,6 +33,7 @@ import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;
@ -624,6 +625,10 @@ public class SettingsHelper {
resourcesItems.put(ExportSettingsType.CUSTOM_ROUTING, Arrays.asList(fl)); resourcesItems.put(ExportSettingsType.CUSTOM_ROUTING, Arrays.asList(fl));
} }
} }
List<OnlineRoutingEngine> onlineRoutingEngines = app.getOnlineRoutingHelper().getEngines();
if (!Algorithms.isEmpty(onlineRoutingEngines)) {
resourcesItems.put(ExportSettingsType.ONLINE_ROUTING_ENGINES, onlineRoutingEngines);
}
List<ITileSource> iTileSources = new ArrayList<>(); List<ITileSource> iTileSources = new ArrayList<>();
Set<String> tileSourceNames = app.getSettings().getTileSourceEntries(true).keySet(); Set<String> tileSourceNames = app.getSettings().getTileSourceEntries(true).keySet();
for (String name : tileSourceNames) { for (String name : tileSourceNames) {
@ -701,6 +706,7 @@ public class SettingsHelper {
List<MapMarkersGroup> markersGroups = new ArrayList<>(); List<MapMarkersGroup> markersGroups = new ArrayList<>();
List<MapMarkersGroup> markersHistoryGroups = new ArrayList<>(); List<MapMarkersGroup> markersHistoryGroups = new ArrayList<>();
List<HistoryEntry> historyEntries = new ArrayList<>(); List<HistoryEntry> historyEntries = new ArrayList<>();
List<OnlineRoutingEngine> onlineRoutingEngines = new ArrayList<>();
for (Object object : data) { for (Object object : data) {
if (object instanceof QuickAction) { if (object instanceof QuickAction) {
@ -741,6 +747,8 @@ public class SettingsHelper {
historyEntries.add((HistoryEntry) object); historyEntries.add((HistoryEntry) object);
} else if (object instanceof GlobalSettingsItem) { } else if (object instanceof GlobalSettingsItem) {
settingsItems.add((GlobalSettingsItem) object); settingsItems.add((GlobalSettingsItem) object);
} else if (object instanceof OnlineRoutingEngine) {
onlineRoutingEngines.add((OnlineRoutingEngine) object);
} }
} }
if (!quickActions.isEmpty()) { if (!quickActions.isEmpty()) {
@ -793,6 +801,9 @@ public class SettingsHelper {
if (!historyEntries.isEmpty()) { if (!historyEntries.isEmpty()) {
settingsItems.add(new SearchHistorySettingsItem(app, historyEntries)); settingsItems.add(new SearchHistorySettingsItem(app, historyEntries));
} }
if (!onlineRoutingEngines.isEmpty()) {
settingsItems.add(new OnlineRoutingSettingsItem(app, onlineRoutingEngines));
}
return settingsItems; return settingsItems;
} }
@ -848,6 +859,7 @@ public class SettingsHelper {
List<MapMarkersGroup> markersGroups = new ArrayList<>(); List<MapMarkersGroup> markersGroups = new ArrayList<>();
List<MapMarkersGroup> markersHistoryGroups = new ArrayList<>(); List<MapMarkersGroup> markersHistoryGroups = new ArrayList<>();
List<HistoryEntry> historyEntries = new ArrayList<>(); List<HistoryEntry> historyEntries = new ArrayList<>();
List<OnlineRoutingEngine> onlineRoutingEngines = new ArrayList<>();
for (SettingsItem item : settingsItems) { for (SettingsItem item : settingsItems) {
switch (item.getType()) { switch (item.getType()) {
@ -942,6 +954,10 @@ public class SettingsHelper {
case GPX: case GPX:
tracksFilesList.add((GpxSettingsItem) item); tracksFilesList.add((GpxSettingsItem) item);
break; break;
case ONLINE_ROUTING_ENGINES:
OnlineRoutingSettingsItem onlineRoutingSettingsItem = (OnlineRoutingSettingsItem) item;
onlineRoutingEngines.addAll(onlineRoutingSettingsItem.getItems());
break;
default: default:
break; break;
} }
@ -1004,6 +1020,9 @@ public class SettingsHelper {
if (!historyEntries.isEmpty()) { if (!historyEntries.isEmpty()) {
settingsToOperate.put(ExportSettingsType.SEARCH_HISTORY, historyEntries); settingsToOperate.put(ExportSettingsType.SEARCH_HISTORY, historyEntries);
} }
if (!onlineRoutingEngines.isEmpty()) {
settingsToOperate.put(ExportSettingsType.ONLINE_ROUTING_ENGINES, onlineRoutingEngines);
}
return settingsToOperate; return settingsToOperate;
} }

View file

@ -19,5 +19,6 @@ public enum SettingsItemType {
FAVOURITES, FAVOURITES,
ACTIVE_MARKERS, ACTIVE_MARKERS,
HISTORY_MARKERS, HISTORY_MARKERS,
SEARCH_HISTORY SEARCH_HISTORY,
ONLINE_ROUTING_ENGINES
} }

View file

@ -146,6 +146,9 @@ class SettingsItemsFactory {
case GPX: case GPX:
item = new GpxSettingsItem(app, json); item = new GpxSettingsItem(app, json);
break; break;
case ONLINE_ROUTING_ENGINES:
item = new OnlineRoutingSettingsItem(app, json);
break;
} }
return item; return item;
} }

View file

@ -23,6 +23,7 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.ProfileIconColors; import net.osmand.plus.profiles.ProfileIconColors;
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources; import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
@ -163,6 +164,9 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView
itemHolder.icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_flag, activeColorRes)); itemHolder.icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_flag, activeColorRes));
} else if (currentItem instanceof HistoryEntry) { } else if (currentItem instanceof HistoryEntry) {
itemHolder.title.setText(((HistoryEntry) currentItem).getName().getName()); itemHolder.title.setText(((HistoryEntry) currentItem).getName().getName());
} else if (currentItem instanceof OnlineRoutingEngine) {
itemHolder.title.setText(((OnlineRoutingEngine) currentItem).getName(app));
itemHolder.icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_world_globe_dark, activeColorRes));
} }
itemHolder.divider.setVisibility(shouldShowDivider(position) ? View.VISIBLE : View.GONE); itemHolder.divider.setVisibility(shouldShowDivider(position) ? View.VISIBLE : View.GONE);
} }

View file

@ -40,6 +40,7 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;
@ -362,6 +363,10 @@ public class ExportItemsBottomSheet extends MenuBottomSheetDialogFragment {
HistoryEntry historyEntry = (HistoryEntry) object; HistoryEntry historyEntry = (HistoryEntry) object;
builder.setTitle(historyEntry.getName().getName()); builder.setTitle(historyEntry.getName().getName());
builder.setIcon(uiUtilities.getIcon(R.drawable.ic_action_history, activeColorRes)); builder.setIcon(uiUtilities.getIcon(R.drawable.ic_action_history, activeColorRes));
} else if (object instanceof OnlineRoutingEngine) {
OnlineRoutingEngine onlineRoutingEngine = (OnlineRoutingEngine) object;
builder.setTitle(onlineRoutingEngine.getName(app));
builder.setIcon(uiUtilities.getIcon(R.drawable.ic_world_globe_dark, activeColorRes));
} }
} }

View file

@ -24,6 +24,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment; import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment;
@ -36,6 +37,7 @@ import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.settings.backend.OsmAndAppCustomization;
import net.osmand.plus.settings.backend.backup.SettingsHelper; import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.settings.backend.backup.SettingsItem; import net.osmand.plus.settings.backend.backup.SettingsItem;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import java.util.List; import java.util.List;
@ -150,12 +152,11 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
dismissFragment(); dismissFragment();
fm.popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE); fm.popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE);
switch (type) { switch (type) {
case CUSTOM_ROUTING: case GLOBAL:
case PROFILE: case PROFILE:
BaseSettingsFragment.showInstance( case CUSTOM_ROUTING:
requireActivity(), case ONLINE_ROUTING_ENGINES:
BaseSettingsFragment.SettingsScreenType.MAIN_SETTINGS BaseSettingsFragment.showInstance(requireActivity(), SettingsScreenType.MAIN_SETTINGS);
);
break; break;
case QUICK_ACTIONS: case QUICK_ACTIONS:
fm.beginTransaction() fm.beginTransaction()
@ -190,19 +191,13 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
case AVOID_ROADS: case AVOID_ROADS:
new AvoidRoadsBottomSheetDialogFragment().show(fm, AvoidRoadsBottomSheetDialogFragment.TAG); new AvoidRoadsBottomSheetDialogFragment().show(fm, AvoidRoadsBottomSheetDialogFragment.TAG);
break; break;
case TRACKS:
case OSM_NOTES: case OSM_NOTES:
case OSM_EDITS: case OSM_EDITS:
OsmAndAppCustomization appCustomization = app.getAppCustomization();
final Intent favorites = new Intent(activity, appCustomization.getFavoritesActivity());
favorites.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
app.getSettings().FAVORITES_TAB.set(OsmEditingPlugin.OSM_EDIT_TAB);
startActivity(favorites);
break;
case FAVORITES: case FAVORITES:
Intent favoritesActivity = new Intent(activity, app.getAppCustomization().getFavoritesActivity()); case MULTIMEDIA_NOTES:
favoritesActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); int tabId = getFavoritesTabId(type);
app.getSettings().FAVORITES_TAB.set(FavoritesActivity.FAV_TAB); openFavouritesActivity(activity, tabId);
startActivity(favoritesActivity);
break; break;
case SEARCH_HISTORY: case SEARCH_HISTORY:
if (activity instanceof MapActivity) { if (activity instanceof MapActivity) {
@ -221,6 +216,29 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
} }
} }
private void openFavouritesActivity(Activity activity, int tabType) {
OsmAndAppCustomization appCustomization = app.getAppCustomization();
Intent favoritesActivity = new Intent(activity, appCustomization.getFavoritesActivity());
favoritesActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
app.getSettings().FAVORITES_TAB.set(tabType);
startActivity(favoritesActivity);
}
private int getFavoritesTabId(ExportSettingsType type) {
switch (type) {
case OSM_NOTES:
case OSM_EDITS:
return OsmEditingPlugin.OSM_EDIT_TAB;
case MULTIMEDIA_NOTES:
return AudioVideoNotesPlugin.NOTES_TAB;
case TRACKS:
return FavoritesActivity.GPX_TAB;
case FAVORITES:
default:
return FavoritesActivity.FAV_TAB;
}
}
@Override @Override
public int getStatusBarColorId() { public int getStatusBarColorId() {
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light; return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;

View file

@ -34,6 +34,7 @@ import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
@ -205,6 +206,7 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment {
List<MapMarker> mapMarkers = new ArrayList<>(); List<MapMarker> mapMarkers = new ArrayList<>();
List<MapMarker> mapMarkersGroups = new ArrayList<>(); List<MapMarker> mapMarkersGroups = new ArrayList<>();
List<HistoryEntry> historyEntries = new ArrayList<>(); List<HistoryEntry> historyEntries = new ArrayList<>();
List<OnlineRoutingEngine> onlineRoutingEngines = new ArrayList<>();
for (Object object : duplicatesList) { for (Object object : duplicatesList) {
if (object instanceof ApplicationMode.ApplicationModeBean) { if (object instanceof ApplicationMode.ApplicationModeBean) {
@ -250,6 +252,8 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment {
} }
} else if (object instanceof HistoryEntry) { } else if (object instanceof HistoryEntry) {
historyEntries.add((HistoryEntry) object); historyEntries.add((HistoryEntry) object);
} else if (object instanceof OnlineRoutingEngine) {
onlineRoutingEngines.add((OnlineRoutingEngine) object);
} }
} }
if (!profiles.isEmpty()) { if (!profiles.isEmpty()) {
@ -320,6 +324,10 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment {
duplicates.add(getString(R.string.markers_history)); duplicates.add(getString(R.string.markers_history));
duplicates.addAll(mapMarkersGroups); duplicates.addAll(mapMarkersGroups);
} }
if (!onlineRoutingEngines.isEmpty()) {
duplicates.add(getString(R.string.online_routing_engines));
duplicates.addAll(onlineRoutingEngines);
}
return duplicates; return duplicates;
} }

View file

@ -36,6 +36,7 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
@ -50,6 +51,7 @@ import net.osmand.plus.settings.backend.backup.GpxSettingsItem;
import net.osmand.plus.settings.backend.backup.HistoryMarkersSettingsItem; import net.osmand.plus.settings.backend.backup.HistoryMarkersSettingsItem;
import net.osmand.plus.settings.backend.backup.MapSourcesSettingsItem; import net.osmand.plus.settings.backend.backup.MapSourcesSettingsItem;
import net.osmand.plus.settings.backend.backup.MarkersSettingsItem; import net.osmand.plus.settings.backend.backup.MarkersSettingsItem;
import net.osmand.plus.settings.backend.backup.OnlineRoutingSettingsItem;
import net.osmand.plus.settings.backend.backup.OsmEditsSettingsItem; import net.osmand.plus.settings.backend.backup.OsmEditsSettingsItem;
import net.osmand.plus.settings.backend.backup.OsmNotesSettingsItem; import net.osmand.plus.settings.backend.backup.OsmNotesSettingsItem;
import net.osmand.plus.settings.backend.backup.PoiUiFiltersSettingsItem; import net.osmand.plus.settings.backend.backup.PoiUiFiltersSettingsItem;
@ -347,6 +349,7 @@ public class ImportSettingsFragment extends BaseSettingsListFragment {
List<MapMarkersGroup> markersGroups = new ArrayList<>(); List<MapMarkersGroup> markersGroups = new ArrayList<>();
List<MapMarkersGroup> markersHistoryGroups = new ArrayList<>(); List<MapMarkersGroup> markersHistoryGroups = new ArrayList<>();
List<HistoryEntry> historyEntries = new ArrayList<>(); List<HistoryEntry> historyEntries = new ArrayList<>();
List<OnlineRoutingEngine> onlineRoutingEngines = new ArrayList<>();
for (Object object : data) { for (Object object : data) {
if (object instanceof ApplicationModeBean) { if (object instanceof ApplicationModeBean) {
appModeBeans.add((ApplicationModeBean) object); appModeBeans.add((ApplicationModeBean) object);
@ -384,6 +387,8 @@ public class ImportSettingsFragment extends BaseSettingsListFragment {
} }
} else if (object instanceof HistoryEntry) { } else if (object instanceof HistoryEntry) {
historyEntries.add((HistoryEntry) object); historyEntries.add((HistoryEntry) object);
} else if (object instanceof OnlineRoutingEngine) {
onlineRoutingEngines.add((OnlineRoutingEngine) object);
} }
} }
if (!appModeBeans.isEmpty()) { if (!appModeBeans.isEmpty()) {
@ -435,6 +440,10 @@ public class ImportSettingsFragment extends BaseSettingsListFragment {
SearchHistorySettingsItem baseItem = getBaseItem(SettingsItemType.SEARCH_HISTORY, SearchHistorySettingsItem.class); SearchHistorySettingsItem baseItem = getBaseItem(SettingsItemType.SEARCH_HISTORY, SearchHistorySettingsItem.class);
settingsItems.add(new SearchHistorySettingsItem(app, baseItem, historyEntries)); settingsItems.add(new SearchHistorySettingsItem(app, baseItem, historyEntries));
} }
if (!onlineRoutingEngines.isEmpty()) {
OnlineRoutingSettingsItem baseItem = getBaseItem(SettingsItemType.ONLINE_ROUTING_ENGINES, OnlineRoutingSettingsItem.class);
settingsItems.add(new OnlineRoutingSettingsItem(app, baseItem, onlineRoutingEngines));
}
return settingsItems; return settingsItems;
} }

View file

@ -16,7 +16,6 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ExportSettingsType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -154,6 +153,10 @@ public class ImportedSettingsItemsAdapter extends
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_history, activeColorRes)); holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_history, activeColorRes));
holder.title.setText(R.string.shared_string_search_history); holder.title.setText(R.string.shared_string_search_history);
break; break;
case ONLINE_ROUTING_ENGINES:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_world_globe_dark, activeColorRes));
holder.title.setText(R.string.online_routing_engines);
break;
} }
} }

View file

@ -0,0 +1,49 @@
package net.osmand.plus.widgets;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.util.AttributeSet;
import android.webkit.WebView;
import net.osmand.plus.OsmandApplication;
public class WebViewEx extends WebView {
public WebViewEx(Context context) {
super(context);
fixWebViewResetsLocaleToUserDefault(context);
}
public WebViewEx(Context context, AttributeSet attrs) {
super(context, attrs);
fixWebViewResetsLocaleToUserDefault(context);
}
public WebViewEx(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
fixWebViewResetsLocaleToUserDefault(context);
}
public WebViewEx(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
fixWebViewResetsLocaleToUserDefault(context);
}
public WebViewEx(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
super(context, attrs, defStyleAttr, privateBrowsing);
fixWebViewResetsLocaleToUserDefault(context);
}
public void fixWebViewResetsLocaleToUserDefault(Context ctx) {
// issue details: https://issuetracker.google.com/issues/37113860
// also see: https://gist.github.com/amake/0ac7724681ac1c178c6f95a5b09f03ce
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
OsmandApplication app = (OsmandApplication) ctx.getApplicationContext();
app.checkPreferredLocale();
ctx.getResources().updateConfiguration(
new Configuration(app.getResources().getConfiguration()),
ctx.getResources().getDisplayMetrics());
}
}
}

View file

@ -17,7 +17,6 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.webkit.WebSettings; import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@ -28,7 +27,6 @@ import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.browser.customtabs.CustomTabsIntent; import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.view.MotionEventCompat;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;

View file

@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.osmand.Collator; import net.osmand.Collator;
import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.OsmAndCollator; import net.osmand.OsmAndCollator;
@ -21,6 +23,7 @@ import net.osmand.osm.PoiCategory;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.helpers.ColorDialogs; import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.wikivoyage.data.TravelArticle.TravelArticleIdentifier; import net.osmand.plus.wikivoyage.data.TravelArticle.TravelArticleIdentifier;
import net.osmand.search.core.SearchPhrase.NameStringMatcher;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
@ -84,7 +87,7 @@ public class TravelObfHelper implements TravelHelper {
} }
@NonNull @NonNull
public List<TravelArticle> loadPopularArticles() { public synchronized List<TravelArticle> loadPopularArticles() {
String lang = app.getLanguage(); String lang = app.getLanguage();
List<TravelArticle> popularArticles = new ArrayList<>(); List<TravelArticle> popularArticles = new ArrayList<>();
for (BinaryMapIndexReader reader : getReaders()) { for (BinaryMapIndexReader reader : getReaders()) {
@ -230,13 +233,27 @@ public class TravelObfHelper implements TravelHelper {
@NonNull @NonNull
@Override @Override
public List<WikivoyageSearchResult> search(@NonNull String searchQuery) { public synchronized List<WikivoyageSearchResult> search(@NonNull String searchQuery) {
List<WikivoyageSearchResult> res = new ArrayList<>(); List<WikivoyageSearchResult> res = new ArrayList<>();
Map<File, List<Amenity>> amenityMap = new HashMap<>(); Map<File, List<Amenity>> amenityMap = new HashMap<>();
final String appLang = app.getLanguage();
final NameStringMatcher nm = new NameStringMatcher(searchQuery, StringMatcherMode.CHECK_STARTS_FROM_SPACE);
for (BinaryMapIndexReader reader : getReaders()) { for (BinaryMapIndexReader reader : getReaders()) {
try { try {
SearchRequest<Amenity> searchRequest = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, searchQuery, SearchRequest<Amenity> searchRequest = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, searchQuery,
0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchRouteArticleFilter(), null, null); 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchRouteArticleFilter(), new ResultMatcher<Amenity>() {
@Override
public boolean publish(Amenity object) {
List<String> otherNames = object.getAllNames(false);
String localeName = object.getName(appLang);
return nm.matches(localeName) || nm.matches(otherNames);
}
@Override
public boolean isCancelled() {
return false;
}
}, null);
List<Amenity> amenities = reader.searchPoiByName(searchRequest); List<Amenity> amenities = reader.searchPoiByName(searchRequest);
if (!Algorithms.isEmpty(amenities)) { if (!Algorithms.isEmpty(amenities)) {
@ -247,14 +264,35 @@ public class TravelObfHelper implements TravelHelper {
} }
} }
if (!Algorithms.isEmpty(amenityMap)) { if (!Algorithms.isEmpty(amenityMap)) {
String appLang = app.getLanguage(); final boolean appLangEn = "en".equals(appLang);
for (Entry<File, List<Amenity>> entry : amenityMap.entrySet()) { for (Entry<File, List<Amenity>> entry : amenityMap.entrySet()) {
File file = entry.getKey(); File file = entry.getKey();
for (Amenity amenity : entry.getValue()) { for (Amenity amenity : entry.getValue()) {
Set<String> nameLangs = getLanguages(amenity); Set<String> nameLangs = getLanguages(amenity);
if (nameLangs.contains(appLang)) { if (nameLangs.contains(appLang)) {
TravelArticle article = readArticle(file, amenity, appLang, entry.getValue()); TravelArticle article = readArticle(file, amenity, appLang, entry.getValue());
WikivoyageSearchResult r = new WikivoyageSearchResult(article, new ArrayList<>(nameLangs)); ArrayList<String> langs = new ArrayList<>(nameLangs);
Collections.sort(langs, new Comparator<String>() {
@Override
public int compare(String l1, String l2) {
if (l1.equals(appLang)) {
l1 = "1";
}
if (l2.equals(appLang)) {
l2 = "1";
}
if (!appLangEn) {
if (l1.equals("en")) {
l1 = "2";
}
if (l2.equals("en")) {
l2 = "2";
}
}
return l1.compareTo(l2);
}
});
WikivoyageSearchResult r = new WikivoyageSearchResult(article, langs);
res.add(r); res.add(r);
} }
} }

View file

@ -27,13 +27,14 @@ import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemSelectedListener; import com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemSelectedListener;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.plus.AppInitializer;
import net.osmand.plus.LockableViewPager; import net.osmand.plus.LockableViewPager;
import net.osmand.plus.OnDialogFragmentResultListener; import net.osmand.plus.OnDialogFragmentResultListener;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.TabActivity; import net.osmand.plus.activities.TabActivity;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents; import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikipedia.WikiArticleHelper;
import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment;
import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelArticle;
@ -314,8 +315,25 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv
public void populateData() { public void populateData() {
switchProgressBarVisibility(true); switchProgressBarVisibility(true);
if (app.isApplicationInitializing()) {
final WeakReference<WikivoyageExploreActivity> activityRef = new WeakReference<>(this);
app.getAppInitializer().addListener(new AppInitializer.AppInitializeListener() {
@Override
public void onProgress(AppInitializer init, AppInitializer.InitEvents event) {
}
@Override
public void onFinish(AppInitializer init) {
WikivoyageExploreActivity activity = activityRef.get();
if (AndroidUtils.isActivityNotDestroyed(activity)) {
new LoadWikivoyageData(activity).execute();
}
}
});
} else {
new LoadWikivoyageData(this).execute(); new LoadWikivoyageData(this).execute();
} }
}
private void onDataLoaded() { private void onDataLoaded() {
switchProgressBarVisibility(false); switchProgressBarVisibility(false);
@ -364,8 +382,8 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv
private static class LoadWikivoyageData extends AsyncTask<Void, Void, Void> { private static class LoadWikivoyageData extends AsyncTask<Void, Void, Void> {
private WeakReference<WikivoyageExploreActivity> activityRef; private final WeakReference<WikivoyageExploreActivity> activityRef;
private TravelHelper travelHelper; private final TravelHelper travelHelper;
LoadWikivoyageData(WikivoyageExploreActivity activity) { LoadWikivoyageData(WikivoyageExploreActivity activity) {
travelHelper = activity.getMyApplication().getTravelHelper(); travelHelper = activity.getMyApplication().getTravelHelper();
@ -381,7 +399,7 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv
@Override @Override
protected void onPostExecute(Void result) { protected void onPostExecute(Void result) {
WikivoyageExploreActivity activity = activityRef.get(); WikivoyageExploreActivity activity = activityRef.get();
if (activity != null) { if (AndroidUtils.isActivityNotDestroyed(activity)) {
activity.onDataLoaded(); activity.onDataLoaded();
} }
} }