From 07d6a357881a50294e356dcbceb86ae2fdad35e2 Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 30 Dec 2020 15:16:05 +0500 Subject: [PATCH 01/67] Fix #10395 --- .../builders/AmenityMenuBuilder.java | 178 ++++++++++++++++-- 1 file changed, 158 insertions(+), 20 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 12b1b0d497..60dd2ae2c1 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -15,10 +15,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.appcompat.view.ContextThemeWrapper; -import androidx.core.content.ContextCompat; - import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.data.Amenity; @@ -65,6 +61,11 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; + +import androidx.annotation.NonNull; +import androidx.appcompat.view.ContextThemeWrapper; +import androidx.core.content.ContextCompat; public class AmenityMenuBuilder extends MenuBuilder { @@ -86,18 +87,20 @@ public class AmenityMenuBuilder extends MenuBuilder { protected void buildNearestWikiRow(View view) { } - private void buildRow(View view, int iconId, String text, String textPrefix, + private void buildRow(View view, int iconId, String text, String textPrefix, String baseSocialMediaUrl, boolean collapsable, final CollapsableView collapsableView, int textColor, boolean isWiki, boolean isText, boolean needLinks, boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) { - buildRow(view, iconId == 0 ? null : getRowIcon(iconId), text, textPrefix, collapsable, collapsableView, textColor, + buildRow(view, iconId == 0 ? null : getRowIcon(iconId), text, textPrefix, baseSocialMediaUrl, + collapsable, collapsableView, textColor, isWiki, isText, needLinks, isPhoneNumber, isUrl, matchWidthDivider, textLinesLimit); } protected void buildRow(final View view, Drawable icon, final String text, final String textPrefix, - boolean collapsable, final CollapsableView collapsableView, - int textColor, boolean isWiki, boolean isText, boolean needLinks, - boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) { + final String baseSocialMediaUrl, boolean collapsable, + final CollapsableView collapsableView, int textColor, boolean isWiki, + boolean isText, boolean needLinks, boolean isPhoneNumber, boolean isUrl, + boolean matchWidthDivider, int textLinesLimit) { if (!isFirstRow()) { buildRowDivider(view); @@ -305,8 +308,15 @@ public class AmenityMenuBuilder extends MenuBuilder { WikipediaArticleWikiLinkFragment.showInstance(mapActivity.getSupportFragmentManager(), text); } } else { + String fullSocialMediaUrl; + if (baseSocialMediaUrl == null) { + fullSocialMediaUrl = text; + } else { + fullSocialMediaUrl = baseSocialMediaUrl + text; + } + Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(text)); + intent.setData(Uri.parse(fullSocialMediaUrl)); v.getContext().startActivity(intent); } } @@ -359,6 +369,7 @@ public class AmenityMenuBuilder extends MenuBuilder { continue; } + String baseSocialMediaUrl = null; String textPrefix = ""; CollapsableView collapsableView = null; boolean collapsable = false; @@ -392,6 +403,80 @@ public class AmenityMenuBuilder extends MenuBuilder { isUrl = true; } + if (!isUrl) { + isUrl = true; + baseSocialMediaUrl = "https://"; + + switch (key) { + case "facebook": + if (!vl.contains("facebook.com")) { + baseSocialMediaUrl = baseSocialMediaUrl + "www.facebook.com/"; + } + break; + + case "vk": + if (!vl.startsWith("vk.com")) { + baseSocialMediaUrl = baseSocialMediaUrl + "vk.com/"; + } + break; + + case "instagram": + if (!vl.contains("instagram.com")) { + baseSocialMediaUrl = baseSocialMediaUrl + "www.instagram.com/"; + } + break; + + case "twitter": + if (!vl.startsWith("twitter.com")) { + baseSocialMediaUrl = baseSocialMediaUrl + "twitter.com/"; + } + break; + + case "youtube": + // Only can process URL with domains and without HTTP, + // because account may be channel and user + if (!vl.contains("youtube.com")) { + baseSocialMediaUrl = null; + isUrl = false; + } + break; + + case "ok": + if (!vl.startsWith("ok.ru")) { + baseSocialMediaUrl = baseSocialMediaUrl + "ok.ru"; + } + break; + + case "telegram": + // Telegram can have different domens (t.me, tgme.pro,..) + String telegramUrlWithoutHttp = "[a-zA-Z0-9-]+\\.[a-zA-Z0-9-]+/[a-zA-Z0-9_]+"; + if (Pattern.matches(telegramUrlWithoutHttp, vl)) { + baseSocialMediaUrl = baseSocialMediaUrl + vl; + } else { + baseSocialMediaUrl = baseSocialMediaUrl + "t.me/"; + } + break; + + case "flickr": + if (!vl.contains("flickr.com")) { + baseSocialMediaUrl = baseSocialMediaUrl + "www.flickr.com/photos/"; + } + break; + + case "linkedin": + if (!vl.contains("linkedin.com")) { + baseSocialMediaUrl = null; + isUrl = false; + } + break; + + default: + isUrl = false; + baseSocialMediaUrl = null; + break; + } + } + if (pType != null && !pType.isText()) { String categoryName = pType.getPoiAdditionalCategory(); if (!Algorithms.isEmpty(categoryName)) { @@ -553,13 +638,13 @@ public class AmenityMenuBuilder extends MenuBuilder { vl, collapsable, collapsableView, 0, false, true, true, 0, "", false, false, matchWidthDivider, 0); } else if (icon != null) { - row = new AmenityInfoRow(key, icon, textPrefix, vl, collapsable, collapsableView, - textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName, - isPhoneNumber, isUrl, matchWidthDivider, 0); + row = new AmenityInfoRow(key, icon, textPrefix, vl, baseSocialMediaUrl, collapsable, + collapsableView, textColor, isWiki, isText, needLinks, poiTypeOrder, + poiTypeKeyName, isPhoneNumber, isUrl, matchWidthDivider, 0); } else { - row = new AmenityInfoRow(key, iconId, textPrefix, vl, collapsable, collapsableView, - textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName, - isPhoneNumber, isUrl, matchWidthDivider, 0); + row = new AmenityInfoRow(key, iconId, textPrefix, vl, baseSocialMediaUrl, collapsable, + collapsableView, textColor, isWiki, isText, needLinks, poiTypeOrder, + poiTypeKeyName, isPhoneNumber, isUrl, matchWidthDivider, 0); } if (isDescription) { descriptions.add(row); @@ -768,12 +853,14 @@ public class AmenityMenuBuilder extends MenuBuilder { public void buildAmenityRow(View view, AmenityInfoRow info) { if (info.icon != null) { - buildRow(view, info.icon, info.text, info.textPrefix, info.collapsable, info.collapsableView, - info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber, + buildRow(view, info.icon, info.text, info.textPrefix, info.baseSocialMediaUrl, + info.collapsable, info.collapsableView, info.textColor, info.isWiki, info.isText, + info.needLinks, info.isPhoneNumber, info.isUrl, info.matchWidthDivider, info.textLinesLimit); } else { - buildRow(view, info.iconId, info.text, info.textPrefix, info.collapsable, info.collapsableView, - info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber, + buildRow(view, info.iconId, info.text, info.textPrefix, info.baseSocialMediaUrl, + info.collapsable, info.collapsableView, info.textColor, info.isWiki, info.isText, + info.needLinks, info.isPhoneNumber, info.isUrl, info.matchWidthDivider, info.textLinesLimit); } } @@ -883,6 +970,7 @@ public class AmenityMenuBuilder extends MenuBuilder { private int iconId; private String textPrefix; private String text; + private String baseSocialMediaUrl; private CollapsableView collapsableView; private boolean collapsable; private int textColor; @@ -941,5 +1029,55 @@ public class AmenityMenuBuilder extends MenuBuilder { this.matchWidthDivider = matchWidthDivider; this.textLinesLimit = textLinesLimit; } + + public AmenityInfoRow(String key, Drawable icon, String textPrefix, String text, + String baseSocialMediaUrl, boolean collapsable, + CollapsableView collapsableView, int textColor, boolean isWiki, + boolean isText, boolean needLinks, int order, String name, + boolean isPhoneNumber, boolean isUrl, + boolean matchWidthDivider, int textLinesLimit) { + this.key = key; + this.icon = icon; + this.textPrefix = textPrefix; + this.text = text; + this.baseSocialMediaUrl = baseSocialMediaUrl; + this.collapsable = collapsable; + this.collapsableView = collapsableView; + this.textColor = textColor; + this.isWiki = isWiki; + this.isText = isText; + this.needLinks = needLinks; + this.order = order; + this.name = name; + this.isPhoneNumber = isPhoneNumber; + this.isUrl = isUrl; + this.matchWidthDivider = matchWidthDivider; + this.textLinesLimit = textLinesLimit; + } + + public AmenityInfoRow(String key, int iconId, String textPrefix, String text, + String baseSocialMediaUrl, boolean collapsable, + CollapsableView collapsableView, int textColor, boolean isWiki, + boolean isText, boolean needLinks, int order, String name, + boolean isPhoneNumber, boolean isUrl, + boolean matchWidthDivider, int textLinesLimit) { + this.key = key; + this.iconId = iconId; + this.textPrefix = textPrefix; + this.text = text; + this.baseSocialMediaUrl = baseSocialMediaUrl; + this.collapsable = collapsable; + this.collapsableView = collapsableView; + this.textColor = textColor; + this.isWiki = isWiki; + this.isText = isText; + this.needLinks = needLinks; + this.order = order; + this.name = name; + this.isPhoneNumber = isPhoneNumber; + this.isUrl = isUrl; + this.matchWidthDivider = matchWidthDivider; + this.textLinesLimit = textLinesLimit; + } } } From 2da563815d554248c34e5c5b82f5f189fd4254f3 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 30 Dec 2020 13:31:41 +0200 Subject: [PATCH 02/67] fix of the opportunity to find an address from external sources using google maps links --- .../activities/search/GeoIntentActivity.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java index 1e8ff552b4..951ba74b16 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java @@ -1,9 +1,12 @@ package net.osmand.plus.activities.search; import android.app.ProgressDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; @@ -26,6 +29,9 @@ import net.osmand.util.Algorithms; import net.osmand.util.GeoPointParserUtil; import net.osmand.util.GeoPointParserUtil.GeoParsedPoint; +import java.io.IOException; +import java.util.Locale; + public class GeoIntentActivity extends OsmandListActivity { private ProgressDialog progressDlg; @@ -53,7 +59,7 @@ public class GeoIntentActivity extends OsmandListActivity { if (intent != null) { final ProgressDialog progress = ProgressDialog.show(GeoIntentActivity.this, getString(R.string.searching), getString(R.string.searching_address)); - final GeoIntentTask task = new GeoIntentTask(progress, intent); + final GeoIntentTask task = new GeoIntentTask(progress, intent, this); progress.setOnCancelListener(new OnCancelListener() { @Override @@ -84,10 +90,12 @@ public class GeoIntentActivity extends OsmandListActivity { private class GeoIntentTask extends AsyncTask { private final ProgressDialog progress; private final Intent intent; + private Context context; - private GeoIntentTask(final ProgressDialog progress, final Intent intent) { + private GeoIntentTask(final ProgressDialog progress, final Intent intent, Context context) { this.progress = progress; this.intent = intent; + this.context = context; } @Override @@ -113,7 +121,21 @@ public class GeoIntentActivity extends OsmandListActivity { Thread.sleep(200); } Uri uri = intent.getData(); - return GeoPointParserUtil.parse(uri.toString()); + GeoParsedPoint gpp; + Address address = null; + try { + address = new Geocoder(context, Locale.getDefault()) + .getFromLocationName(uri.toString(), 1) + .get(0); + } catch (IndexOutOfBoundsException | IOException e) { + e.printStackTrace(); + } + if (address != null) { + gpp = new GeoParsedPoint(address.getLatitude(), address.getLongitude(), GeoParsedPoint.NO_ZOOM); + } else { + gpp = GeoPointParserUtil.parse(uri.toString()); + } + return gpp; } catch (Exception e) { return null; } From 0205628a486fabb96b2dae5d637909d8292fcb2f Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 31 Dec 2020 15:15:17 +0200 Subject: [PATCH 03/67] rolled back previous changes; fix address uri without lat & lon in searchRequest (example: geo:0,0?q=Van+Bleiswijkstraat+66,+2582+LG+The+Hague) --- .../net/osmand/util/GeoPointParserUtil.java | 4 +++ .../activities/search/GeoIntentActivity.java | 28 ++----------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java b/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java index 951ae870e2..f46f4f6f70 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java @@ -558,6 +558,10 @@ public class GeoPointParserUtil { if (lat == 0.0 && lon == 0.0 && positionInSearchRequestMatcher.find()) { lat = Double.valueOf(positionInSearchRequestMatcher.group(1)); lon = Double.valueOf(positionInSearchRequestMatcher.group(2)); + if (lat < -90 || lat > 90 || lon < -180 || lon > 180) { + lat = 0.0; + lon = 0.0; + } } } diff --git a/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java index 951ba74b16..1e8ff552b4 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java @@ -1,12 +1,9 @@ package net.osmand.plus.activities.search; import android.app.ProgressDialog; -import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.Intent; -import android.location.Address; -import android.location.Geocoder; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; @@ -29,9 +26,6 @@ import net.osmand.util.Algorithms; import net.osmand.util.GeoPointParserUtil; import net.osmand.util.GeoPointParserUtil.GeoParsedPoint; -import java.io.IOException; -import java.util.Locale; - public class GeoIntentActivity extends OsmandListActivity { private ProgressDialog progressDlg; @@ -59,7 +53,7 @@ public class GeoIntentActivity extends OsmandListActivity { if (intent != null) { final ProgressDialog progress = ProgressDialog.show(GeoIntentActivity.this, getString(R.string.searching), getString(R.string.searching_address)); - final GeoIntentTask task = new GeoIntentTask(progress, intent, this); + final GeoIntentTask task = new GeoIntentTask(progress, intent); progress.setOnCancelListener(new OnCancelListener() { @Override @@ -90,12 +84,10 @@ public class GeoIntentActivity extends OsmandListActivity { private class GeoIntentTask extends AsyncTask { private final ProgressDialog progress; private final Intent intent; - private Context context; - private GeoIntentTask(final ProgressDialog progress, final Intent intent, Context context) { + private GeoIntentTask(final ProgressDialog progress, final Intent intent) { this.progress = progress; this.intent = intent; - this.context = context; } @Override @@ -121,21 +113,7 @@ public class GeoIntentActivity extends OsmandListActivity { Thread.sleep(200); } Uri uri = intent.getData(); - GeoParsedPoint gpp; - Address address = null; - try { - address = new Geocoder(context, Locale.getDefault()) - .getFromLocationName(uri.toString(), 1) - .get(0); - } catch (IndexOutOfBoundsException | IOException e) { - e.printStackTrace(); - } - if (address != null) { - gpp = new GeoParsedPoint(address.getLatitude(), address.getLongitude(), GeoParsedPoint.NO_ZOOM); - } else { - gpp = GeoPointParserUtil.parse(uri.toString()); - } - return gpp; + return GeoPointParserUtil.parse(uri.toString()); } catch (Exception e) { return null; } From 6415db6230cb1f8bf8aba02d98be2477b01cc145 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sat, 2 Jan 2021 01:01:39 +0500 Subject: [PATCH 04/67] Refactor to simplify code --- .../builders/AmenityMenuBuilder.java | 230 ++++++------------ 1 file changed, 78 insertions(+), 152 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 60dd2ae2c1..25976b644f 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -87,17 +87,17 @@ public class AmenityMenuBuilder extends MenuBuilder { protected void buildNearestWikiRow(View view) { } - private void buildRow(View view, int iconId, String text, String textPrefix, String baseSocialMediaUrl, + private void buildRow(View view, int iconId, String text, String textPrefix, String socialMediaUrl, boolean collapsable, final CollapsableView collapsableView, int textColor, boolean isWiki, boolean isText, boolean needLinks, boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) { - buildRow(view, iconId == 0 ? null : getRowIcon(iconId), text, textPrefix, baseSocialMediaUrl, + buildRow(view, iconId == 0 ? null : getRowIcon(iconId), text, textPrefix, socialMediaUrl, collapsable, collapsableView, textColor, isWiki, isText, needLinks, isPhoneNumber, isUrl, matchWidthDivider, textLinesLimit); } protected void buildRow(final View view, Drawable icon, final String text, final String textPrefix, - final String baseSocialMediaUrl, boolean collapsable, + final String socialMediaUrl, boolean collapsable, final CollapsableView collapsableView, int textColor, boolean isWiki, boolean isText, boolean needLinks, boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) { @@ -308,15 +308,9 @@ public class AmenityMenuBuilder extends MenuBuilder { WikipediaArticleWikiLinkFragment.showInstance(mapActivity.getSupportFragmentManager(), text); } } else { - String fullSocialMediaUrl; - if (baseSocialMediaUrl == null) { - fullSocialMediaUrl = text; - } else { - fullSocialMediaUrl = baseSocialMediaUrl + text; - } - + String uri = socialMediaUrl == null ? text : socialMediaUrl; Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(fullSocialMediaUrl)); + intent.setData(Uri.parse(uri)); v.getContext().startActivity(intent); } } @@ -369,7 +363,7 @@ public class AmenityMenuBuilder extends MenuBuilder { continue; } - String baseSocialMediaUrl = null; + String socialMediaUrl = null; String textPrefix = ""; CollapsableView collapsableView = null; boolean collapsable = false; @@ -401,79 +395,10 @@ public class AmenityMenuBuilder extends MenuBuilder { if (vl.startsWith("http://") || vl.startsWith("https://") || vl.startsWith("HTTP://") || vl.startsWith("HTTPS://")) { isUrl = true; - } - - if (!isUrl) { - isUrl = true; - baseSocialMediaUrl = "https://"; - - switch (key) { - case "facebook": - if (!vl.contains("facebook.com")) { - baseSocialMediaUrl = baseSocialMediaUrl + "www.facebook.com/"; - } - break; - - case "vk": - if (!vl.startsWith("vk.com")) { - baseSocialMediaUrl = baseSocialMediaUrl + "vk.com/"; - } - break; - - case "instagram": - if (!vl.contains("instagram.com")) { - baseSocialMediaUrl = baseSocialMediaUrl + "www.instagram.com/"; - } - break; - - case "twitter": - if (!vl.startsWith("twitter.com")) { - baseSocialMediaUrl = baseSocialMediaUrl + "twitter.com/"; - } - break; - - case "youtube": - // Only can process URL with domains and without HTTP, - // because account may be channel and user - if (!vl.contains("youtube.com")) { - baseSocialMediaUrl = null; - isUrl = false; - } - break; - - case "ok": - if (!vl.startsWith("ok.ru")) { - baseSocialMediaUrl = baseSocialMediaUrl + "ok.ru"; - } - break; - - case "telegram": - // Telegram can have different domens (t.me, tgme.pro,..) - String telegramUrlWithoutHttp = "[a-zA-Z0-9-]+\\.[a-zA-Z0-9-]+/[a-zA-Z0-9_]+"; - if (Pattern.matches(telegramUrlWithoutHttp, vl)) { - baseSocialMediaUrl = baseSocialMediaUrl + vl; - } else { - baseSocialMediaUrl = baseSocialMediaUrl + "t.me/"; - } - break; - - case "flickr": - if (!vl.contains("flickr.com")) { - baseSocialMediaUrl = baseSocialMediaUrl + "www.flickr.com/photos/"; - } - break; - - case "linkedin": - if (!vl.contains("linkedin.com")) { - baseSocialMediaUrl = null; - isUrl = false; - } - break; - - default: - isUrl = false; - baseSocialMediaUrl = null; - break; + } else { + socialMediaUrl = getSocialMediaUrl(key, vl); + if (socialMediaUrl != null) { + isUrl = true; } } @@ -635,14 +560,14 @@ public class AmenityMenuBuilder extends MenuBuilder { AmenityInfoRow row; if (isDescription) { row = new AmenityInfoRow(key, R.drawable.ic_action_note_dark, textPrefix, - vl, collapsable, collapsableView, 0, false, true, - true, 0, "", false, false, matchWidthDivider, 0); + vl, null, collapsable, collapsableView, 0, false, + true, true, 0, "", false, false, matchWidthDivider, 0); } else if (icon != null) { - row = new AmenityInfoRow(key, icon, textPrefix, vl, baseSocialMediaUrl, collapsable, + row = new AmenityInfoRow(key, icon, textPrefix, vl, socialMediaUrl, collapsable, collapsableView, textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName, isPhoneNumber, isUrl, matchWidthDivider, 0); } else { - row = new AmenityInfoRow(key, iconId, textPrefix, vl, baseSocialMediaUrl, collapsable, + row = new AmenityInfoRow(key, iconId, textPrefix, vl, socialMediaUrl, collapsable, collapsableView, textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName, isPhoneNumber, isUrl, matchWidthDivider, 0); } @@ -691,8 +616,11 @@ public class AmenityMenuBuilder extends MenuBuilder { } boolean cuisineOrDish = categoryName.equals(Amenity.CUISINE) || categoryName.equals(Amenity.DISH); CollapsableView collapsableView = getPoiTypeCollapsableView(view.getContext(), true, categoryTypes, true, cuisineOrDish ? cuisineRow : null); - infoRows.add(new AmenityInfoRow(poiAdditionalCategoryName, icon, pType.getPoiAdditionalCategoryTranslation(), sb.toString(), true, collapsableView, - 0, false, false, false, pType.getOrder(), pType.getKeyName(), false, false, false, 1)); + infoRows.add(new AmenityInfoRow(poiAdditionalCategoryName, icon, + pType.getPoiAdditionalCategoryTranslation(), sb.toString(), null, + true, collapsableView, 0, false, false, + false, pType.getOrder(), pType.getKeyName(), false, + false, false, 1)); } } @@ -707,8 +635,10 @@ public class AmenityMenuBuilder extends MenuBuilder { } sb.append(pt.getTranslation()); } - infoRows.add(new AmenityInfoRow(poiCategory.getKeyName(), icon, poiCategory.getTranslation(), sb.toString(), true, collapsableView, - 0, false, false, false, 40, poiCategory.getKeyName(), false, false, false, 1)); + infoRows.add(new AmenityInfoRow(poiCategory.getKeyName(), icon, + poiCategory.getTranslation(), sb.toString(), null, true, + collapsableView, 0, false, false, false, 40, + poiCategory.getKeyName(), false, false, false, 1)); } Collections.sort(infoRows, new Comparator() { @@ -748,9 +678,11 @@ public class AmenityMenuBuilder extends MenuBuilder { if (processNearestWiki() && nearestWiki.size() > 0) { AmenityInfoRow wikiInfo = new AmenityInfoRow( - "nearest_wiki", R.drawable.ic_plugin_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", true, - getCollapsableWikiView(view.getContext(), true), - 0, false, false, false, 1000, null, false, false, false, 0); + "nearest_wiki", R.drawable.ic_plugin_wikipedia, null, + app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", null, + true, getCollapsableWikiView(view.getContext(), true), + 0, false, false, false, 1000, null, false, + false, false, 0); buildAmenityRow(view, wikiInfo); } @@ -853,12 +785,12 @@ public class AmenityMenuBuilder extends MenuBuilder { public void buildAmenityRow(View view, AmenityInfoRow info) { if (info.icon != null) { - buildRow(view, info.icon, info.text, info.textPrefix, info.baseSocialMediaUrl, + buildRow(view, info.icon, info.text, info.textPrefix, info.socialMediaUrl, info.collapsable, info.collapsableView, info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber, info.isUrl, info.matchWidthDivider, info.textLinesLimit); } else { - buildRow(view, info.iconId, info.text, info.textPrefix, info.baseSocialMediaUrl, + buildRow(view, info.iconId, info.text, info.textPrefix, info.socialMediaUrl, info.collapsable, info.collapsableView, info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber, info.isUrl, info.matchWidthDivider, info.textLinesLimit); @@ -964,13 +896,53 @@ public class AmenityMenuBuilder extends MenuBuilder { return new CollapsableView(view, this, collapsed); } + private String getSocialMediaUrl(String key, String value) { + // Regex for url without protocol, with at least 2 valid domains, slash and at least one + // char after it (e.g. a-c.com/a) + String urlMask = "[a-zA-Z0-9]+[-]*[a-zA-Z0-9]+(\\.[a-zA-Z0-9]+[-]*[a-zA-Z0-9]+)+\\/.+"; + + if (Pattern.matches(urlMask, value)) { + return "https://" + value; + } + + // Remove leading and closing slashes + StringBuilder sb = new StringBuilder(value.trim()); + if (sb.charAt(0) == '/') { + sb.deleteCharAt(0); + } + int lastIdx = sb.length() - 1; + if (sb.charAt(lastIdx) == '/') { + sb.deleteCharAt(lastIdx); + } + + // It cannot be username + if (sb.indexOf("/") != -1 || sb.indexOf(" ") != -1) { + return null; + } + + Map urls = new HashMap<>(7); + urls.put("facebook", "https://facebook.com/%s"); + urls.put("vk", "https://vk.com/%s"); + urls.put("instagram", "https://instagram.com/%s"); + urls.put("twitter", "https://twitter.com/%s"); + urls.put("ok", "https://ok.ru/%s"); + urls.put("telegram", "https://t.me/%s"); + urls.put("flickr", "https://flickr.com/%s"); + + if (urls.containsKey(key)) { + return String.format(urls.get(key), value); + } else { + return null; + } + } + private static class AmenityInfoRow { private String key; private Drawable icon; private int iconId; private String textPrefix; private String text; - private String baseSocialMediaUrl; + private String socialMediaUrl; private CollapsableView collapsableView; private boolean collapsable; private int textColor; @@ -985,14 +957,16 @@ public class AmenityMenuBuilder extends MenuBuilder { private int textLinesLimit; public AmenityInfoRow(String key, Drawable icon, String textPrefix, String text, - boolean collapsable, CollapsableView collapsableView, - int textColor, boolean isWiki, boolean isText, boolean needLinks, - int order, String name, boolean isPhoneNumber, boolean isUrl, + String socialMediaUrl, boolean collapsable, + CollapsableView collapsableView, int textColor, boolean isWiki, + boolean isText, boolean needLinks, int order, String name, + boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) { this.key = key; this.icon = icon; this.textPrefix = textPrefix; this.text = text; + this.socialMediaUrl = socialMediaUrl; this.collapsable = collapsable; this.collapsableView = collapsableView; this.textColor = textColor; @@ -1008,55 +982,7 @@ public class AmenityMenuBuilder extends MenuBuilder { } public AmenityInfoRow(String key, int iconId, String textPrefix, String text, - boolean collapsable, CollapsableView collapsableView, - int textColor, boolean isWiki, boolean isText, boolean needLinks, - int order, String name, boolean isPhoneNumber, boolean isUrl, - boolean matchWidthDivider, int textLinesLimit) { - this.key = key; - this.iconId = iconId; - this.textPrefix = textPrefix; - this.text = text; - this.collapsable = collapsable; - this.collapsableView = collapsableView; - this.textColor = textColor; - this.isWiki = isWiki; - this.isText = isText; - this.needLinks = needLinks; - this.order = order; - this.name = name; - this.isPhoneNumber = isPhoneNumber; - this.isUrl = isUrl; - this.matchWidthDivider = matchWidthDivider; - this.textLinesLimit = textLinesLimit; - } - - public AmenityInfoRow(String key, Drawable icon, String textPrefix, String text, - String baseSocialMediaUrl, boolean collapsable, - CollapsableView collapsableView, int textColor, boolean isWiki, - boolean isText, boolean needLinks, int order, String name, - boolean isPhoneNumber, boolean isUrl, - boolean matchWidthDivider, int textLinesLimit) { - this.key = key; - this.icon = icon; - this.textPrefix = textPrefix; - this.text = text; - this.baseSocialMediaUrl = baseSocialMediaUrl; - this.collapsable = collapsable; - this.collapsableView = collapsableView; - this.textColor = textColor; - this.isWiki = isWiki; - this.isText = isText; - this.needLinks = needLinks; - this.order = order; - this.name = name; - this.isPhoneNumber = isPhoneNumber; - this.isUrl = isUrl; - this.matchWidthDivider = matchWidthDivider; - this.textLinesLimit = textLinesLimit; - } - - public AmenityInfoRow(String key, int iconId, String textPrefix, String text, - String baseSocialMediaUrl, boolean collapsable, + String socialMediaUrl, boolean collapsable, CollapsableView collapsableView, int textColor, boolean isWiki, boolean isText, boolean needLinks, int order, String name, boolean isPhoneNumber, boolean isUrl, @@ -1065,7 +991,7 @@ public class AmenityMenuBuilder extends MenuBuilder { this.iconId = iconId; this.textPrefix = textPrefix; this.text = text; - this.baseSocialMediaUrl = baseSocialMediaUrl; + this.socialMediaUrl = socialMediaUrl; this.collapsable = collapsable; this.collapsableView = collapsableView; this.textColor = textColor; From ef39c2f79b8044ad9e7ba7a8cb2648c9f0bb3b00 Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 4 Jan 2021 02:36:07 +0500 Subject: [PATCH 05/67] =?UTF-8?q?Remove=20ex=D1=81essive=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapcontextmenu/builders/AmenityMenuBuilder.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 25976b644f..0a6ebe16d9 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -61,7 +61,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.regex.Pattern; import androidx.annotation.NonNull; import androidx.appcompat.view.ContextThemeWrapper; @@ -897,14 +896,6 @@ public class AmenityMenuBuilder extends MenuBuilder { } private String getSocialMediaUrl(String key, String value) { - // Regex for url without protocol, with at least 2 valid domains, slash and at least one - // char after it (e.g. a-c.com/a) - String urlMask = "[a-zA-Z0-9]+[-]*[a-zA-Z0-9]+(\\.[a-zA-Z0-9]+[-]*[a-zA-Z0-9]+)+\\/.+"; - - if (Pattern.matches(urlMask, value)) { - return "https://" + value; - } - // Remove leading and closing slashes StringBuilder sb = new StringBuilder(value.trim()); if (sb.charAt(0) == '/') { @@ -916,8 +907,8 @@ public class AmenityMenuBuilder extends MenuBuilder { } // It cannot be username - if (sb.indexOf("/") != -1 || sb.indexOf(" ") != -1) { - return null; + if (sb.indexOf("/") != -1) { + return "https://" + value; } Map urls = new HashMap<>(7); From 3566ec765254ceaa1150463ab12fa8463fb4aa1b Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 8 Jan 2021 19:05:02 +0200 Subject: [PATCH 06/67] fix previous changes; add new check; --- .../java/net/osmand/util/GeoPointParserUtil.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java b/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java index f46f4f6f70..3906aff004 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/GeoPointParserUtil.java @@ -553,14 +553,19 @@ public class GeoPointParserUtil { } if (searchRequest != null) { + String searchPattern = Pattern.compile("(?:\\.|,|\\s+|\\+|[+-]?\\d+(?:\\.\\d+)?)").pattern(); + String[] search = searchRequest.split(searchPattern); + if (search.length > 0) { + return new GeoParsedPoint(searchRequest); + } final Matcher positionInSearchRequestMatcher = positionPattern.matcher(searchRequest); if (lat == 0.0 && lon == 0.0 && positionInSearchRequestMatcher.find()) { - lat = Double.valueOf(positionInSearchRequestMatcher.group(1)); - lon = Double.valueOf(positionInSearchRequestMatcher.group(2)); - if (lat < -90 || lat > 90 || lon < -180 || lon > 180) { - lat = 0.0; - lon = 0.0; + double tempLat = Double.valueOf(positionInSearchRequestMatcher.group(1)); + double tempLon = Double.valueOf(positionInSearchRequestMatcher.group(2)); + if (tempLat >= -90 && tempLat <= 90 && tempLon >= -180 && tempLon <= 180) { + lat = tempLat; + lon = tempLon; } } } From 964f3e28121cc05a36da2cb533a41c43fe51b0c7 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 8 Jan 2021 21:46:28 +0200 Subject: [PATCH 07/67] Fix links to wikivoyage --- .../plus/wikivoyage/data/TravelObfHelper.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 45a8442614..55180b7ec3 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -492,7 +492,7 @@ public class TravelObfHelper implements TravelHelper { @Override public TravelArticle getArticleByTitle(@NonNull final String title, @NonNull QuadRect rect, @NonNull final String lang) { TravelArticle article = null; - List amenities = null; + final List amenities = new ArrayList<>(); int x = 0; int y = 0; int left = 0; @@ -510,8 +510,25 @@ public class TravelObfHelper implements TravelHelper { for (BinaryMapIndexReader reader : getReaders()) { try { SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest( - x, y, title, left, right, top, bottom, getSearchRouteArticleFilter(), null, null); - amenities = reader.searchPoiByName(req); + x, y, title, left, right, top, bottom, getSearchRouteArticleFilter(), + new ResultMatcher() { + boolean done = false; + + @Override + public boolean publish(Amenity amenity) { + if (Algorithms.stringsEqual(title, Algorithms.emptyIfNull(amenity.getName(lang)))) { + amenities.add(amenity); + done = true; + } + return false; + } + + @Override + public boolean isCancelled() { + return done; + } + }, null); + reader.searchPoiByName(req); } catch (IOException e) { LOG.error(e.getMessage()); } From 925ed873d40f13ca930c3d4864ee3e0789ef95d0 Mon Sep 17 00:00:00 2001 From: nautilusx Date: Fri, 8 Jan 2021 16:31:36 +0000 Subject: [PATCH 08/67] Translated using Weblate (German) Currently translated at 100.0% (3607 of 3607 strings) --- OsmAnd/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 4e20ce5f44..07a0ac5a36 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4047,4 +4047,5 @@ Subtyp Leer lassen, wenn kein API-Schlüssel vorhanden Adresse kopieren + Fahren \ No newline at end of file From bc9b3dbfc82f3cfd1d6a75159b1b870a2ff5c9ec Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 7 Jan 2021 20:17:26 +0000 Subject: [PATCH 09/67] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3607 of 3607 strings) --- OsmAnd/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index dfe36591a5..0262c62d31 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4039,4 +4039,5 @@ Велосипед Автомобіль Помилка, повторно перевірте параметри + Копіювати адресу \ No newline at end of file From fed66f053408819293b18205ae283234c3384c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1ns?= Date: Fri, 8 Jan 2021 14:24:57 +0000 Subject: [PATCH 10/67] Translated using Weblate (Galician) Currently translated at 99.8% (3602 of 3607 strings) --- OsmAnd/res/values-gl/strings.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml index f096f64d68..d9d8d1142c 100644 --- a/OsmAnd/res/values-gl/strings.xml +++ b/OsmAnd/res/values-gl/strings.xml @@ -4050,4 +4050,20 @@ Lon %2$s Permitir regatos e cunetas Permitir canles de auga intermitentes Permitir canles de auga intermitentes + Engadir motor de navegación en liña + Editar motor de navegación en liña + Subtipo + Vehículo + Chave da API + URL do servidor + Insire parámetro + Mantenlo baleiro se non + A URL con todos os parámetros será así: + Cálculo da ruta de proba + Conducindo + + Bicicleta + Coche + Erro, verifica novamente os parámetros + Copiar enderezo \ No newline at end of file From f4cdf8cade4a6b41d45d9f2bc1d9d31596de5f4c Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Thu, 7 Jan 2021 23:44:07 +0000 Subject: [PATCH 11/67] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3607 of 3607 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 8516bae334..7672038bad 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4038,4 +4038,5 @@ Bicicleta Carro Erro, verifique novamente os parâmetros + Copiar endereço \ No newline at end of file From b94e699674b26d3c838277c944870316c5e9414d Mon Sep 17 00:00:00 2001 From: ssantos Date: Thu, 7 Jan 2021 20:52:00 +0000 Subject: [PATCH 12/67] Translated using Weblate (Portuguese) Currently translated at 99.8% (3875 of 3881 strings) --- OsmAnd/res/values-pt/phrases.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml index a1ee9f3b00..9b7cae20de 100644 --- a/OsmAnd/res/values-pt/phrases.xml +++ b/OsmAnd/res/values-pt/phrases.xml @@ -3879,4 +3879,7 @@ Torneira Estação de tratamento de água Posto de guarda florestal + Túnel de morcegos + Ponte de morcegos + Área de natação \ No newline at end of file From d4c019d6e7baf86bdf633c49db9b20bcc9bff05f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Fri, 8 Jan 2021 15:24:31 +0000 Subject: [PATCH 13/67] Translated using Weblate (Icelandic) Currently translated at 100.0% (3607 of 3607 strings) --- OsmAnd/res/values-is/strings.xml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/OsmAnd/res/values-is/strings.xml b/OsmAnd/res/values-is/strings.xml index a5e5e86d40..62bafea541 100644 --- a/OsmAnd/res/values-is/strings.xml +++ b/OsmAnd/res/values-is/strings.xml @@ -4029,4 +4029,29 @@ Notandasnið Snúa við öllum punktum OsmAnd-snið + Tímasetning raddskipana + Veldu sniðið sem verður notað þegar forritið er ræst. + Síðast notað + Velja frekar gönguleiðir + Velja frekar gönguleiðir + Leyfa læki og afföll + Leyfa læki og afföll + Leyfa tímabundnar vatnaleiðir + Leyfa tímabundnar vatnaleiðir + Bæta við leiðagerð af netinu + Breyta nettengdri leiðagerð + Undirtegund + Farartæki + API-lykill + Vefslóð netþjóns + Setja inn breytu + Halda þessu auðu ef ekki + Vefslóð með öllum breytum mun líta svona út: + Útreikningur prufuleiðar + Akstur + Gangandi + Hjólandi + Bíll + Villa, yfirfarðu breytur + Afrita heimilisfang \ No newline at end of file From c9deb2e638ade924d5511d4584181d9a110aa76e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Fri, 8 Jan 2021 15:27:13 +0000 Subject: [PATCH 14/67] Translated using Weblate (Icelandic) Currently translated at 100.0% (3881 of 3881 strings) --- OsmAnd/res/values-is/phrases.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-is/phrases.xml b/OsmAnd/res/values-is/phrases.xml index fb51911ead..76fbd92412 100644 --- a/OsmAnd/res/values-is/phrases.xml +++ b/OsmAnd/res/values-is/phrases.xml @@ -286,7 +286,7 @@ Lífgas Fljótandi vetni Rafmagn - Hleðslustöð + Hleðslustöð;Hleðslustöð fyrir rafknúin farartæki;EV-hleðslustöð;Hleðslustæði;Rafhleðslustæði;Þjónustustöð fyrir rafknúin farartæki Loftdæla Mótorhjólastæði Aðgangur að bílastæði @@ -3883,4 +3883,8 @@ Þvottaþró (þvottaaðstaða) Á Bækistöð öryggisvarða + Göng fyrir leðurblökur + Brú fyrir leðurblökur + Þverun villtra dýra + Sundsvæði \ No newline at end of file From d8f458b8ffefab2eefc8c7af5e6b2e3bf8547f98 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 10 Jan 2021 05:48:42 +0500 Subject: [PATCH 15/67] Fix #10454 --- .../src/net/osmand/plus/poi/PoiUIFilter.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java index 1d3449640f..37b36fd08c 100644 --- a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java +++ b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java @@ -352,11 +352,11 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable } }; } - StringBuilder nmFilter = new StringBuilder(); String[] items = filter.split(" "); boolean allTime = false; boolean open = false; List poiAdditionalsFilter = null; + List unknownFilters = null; for (String s : items) { s = s.trim(); if (!Algorithms.isEmpty(s)) { @@ -373,21 +373,37 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable poiAdditionalsFilter.add(pt); } } else { - nmFilter.append(s).append(" "); + if (unknownFilters == null) { + unknownFilters = new ArrayList<>(); + } + unknownFilters.add(s); } } } - return getNameFilterInternal(nmFilter, allTime, open, poiAdditionalsFilter); + return getNameFilterInternal(unknownFilters, allTime, open, poiAdditionalsFilter); } - private AmenityNameFilter getNameFilterInternal(StringBuilder nmFilter, + private AmenityNameFilter getNameFilterInternal(final List unknownFilters, final boolean allTime, final boolean open, final List poiAdditionals) { - final CollatorStringMatcher sm = nmFilter.length() > 0 ? - new CollatorStringMatcher(nmFilter.toString().trim(), StringMatcherMode.CHECK_CONTAINS) : null; return new AmenityNameFilter() { @Override public boolean accept(Amenity a) { + CollatorStringMatcher sm = null; + + if (unknownFilters != null) { + StringBuilder nameFilter = new StringBuilder(); + for (String filter : unknownFilters) { + String formattedFilter = filter.replace(':', '_').toLowerCase(); + if (a.getAdditionalInfo(formattedFilter) == null) { + nameFilter.append(filter).append(" "); + } + } + if (nameFilter.length() > 0) { + sm = new CollatorStringMatcher(nameFilter.toString().trim(), StringMatcherMode.CHECK_CONTAINS); + } + } + if (sm != null) { List names = OsmAndFormatter.getPoiStringsWithoutType(a, app.getSettings().MAP_PREFERRED_LOCALE.get(), app.getSettings().MAP_TRANSLITERATE_NAMES.get()); From 862286fce62701af7b5f6190d21e7716b8867334 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 10 Jan 2021 06:13:56 +0500 Subject: [PATCH 16/67] Refactor --- .../src/net/osmand/plus/poi/PoiUIFilter.java | 247 +++++++++++------- 1 file changed, 150 insertions(+), 97 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java index 37b36fd08c..0d837f560a 100644 --- a/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java +++ b/OsmAnd/src/net/osmand/plus/poi/PoiUIFilter.java @@ -383,116 +383,169 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable return getNameFilterInternal(unknownFilters, allTime, open, poiAdditionalsFilter); } - private AmenityNameFilter getNameFilterInternal(final List unknownFilters, - final boolean allTime, final boolean open, final List poiAdditionals) { + private AmenityNameFilter getNameFilterInternal( + final List unknownFilters, final boolean shouldBeAllTime, + final boolean shouldBeOpened, final List selectedFilters + ) { return new AmenityNameFilter() { @Override - public boolean accept(Amenity a) { - CollatorStringMatcher sm = null; + public boolean accept(Amenity amenity) { + if (shouldBeAllTime) { + if (!"24/7".equalsIgnoreCase(amenity.getOpeningHours()) && + !"Mo-Su 00:00-24:00".equalsIgnoreCase(amenity.getOpeningHours())) { + return false; + } + } - if (unknownFilters != null) { - StringBuilder nameFilter = new StringBuilder(); - for (String filter : unknownFilters) { - String formattedFilter = filter.replace(':', '_').toLowerCase(); - if (a.getAdditionalInfo(formattedFilter) == null) { - nameFilter.append(filter).append(" "); - } - } - if (nameFilter.length() > 0) { - sm = new CollatorStringMatcher(nameFilter.toString().trim(), StringMatcherMode.CHECK_CONTAINS); - } + if (shouldBeOpened && !isOpened(amenity)) { + return false; } - - if (sm != null) { - List names = OsmAndFormatter.getPoiStringsWithoutType(a, - app.getSettings().MAP_PREFERRED_LOCALE.get(), app.getSettings().MAP_TRANSLITERATE_NAMES.get()); - boolean match = false; - for (String name : names) { - if (sm.matches(name)) { - match = true; - break; - } - } - if (!match) { - return false; - } - } - if (poiAdditionals != null) { - Map textPoiAdditionalsMap = new HashMap<>(); - Map> poiAdditionalCategoriesMap = new HashMap<>(); - for (PoiType pt : poiAdditionals) { - String category = pt.getPoiAdditionalCategory(); - List types = poiAdditionalCategoriesMap.get(category); - if (types == null) { - types = new ArrayList<>(); - poiAdditionalCategoriesMap.put(category, types); - } - types.add(pt); - String osmTag = pt.getOsmTag(); - if (osmTag.length() < pt.getKeyName().length()) { - PoiType textPoiType = poiTypes.getTextPoiAdditionalByKey(osmTag); - if (textPoiType != null) { - textPoiAdditionalsMap.put(pt, textPoiType); - } - } - } - for (List types : poiAdditionalCategoriesMap.values()) { - boolean acceptedAnyInCategory = false; - for (PoiType p : types) { - String inf = a.getAdditionalInfo(p.getKeyName()); - if (inf != null) { - acceptedAnyInCategory = true; - break; - } else { - PoiType textPoiType = textPoiAdditionalsMap.get(p); - if (textPoiType != null) { - inf = a.getAdditionalInfo(textPoiType.getKeyName()); - if (!Algorithms.isEmpty(inf)) { - String[] items = inf.split(";"); - String val = p.getOsmValue().trim().toLowerCase(); - for (String item : items) { - if (item.trim().toLowerCase().equals(val)) { - acceptedAnyInCategory = true; - break; - } - } - if (acceptedAnyInCategory) { - break; - } - } - } - } - } - if (!acceptedAnyInCategory) { - return false; - } - } + String nameFilter = extractNameFilter(amenity, unknownFilters); + if (!matchesAnyAmenityName(amenity, nameFilter)) { + return false; } - if (allTime) { - if (!"24/7".equalsIgnoreCase(a.getOpeningHours()) && !"Mo-Su 00:00-24:00".equalsIgnoreCase(a.getOpeningHours())) { - return false; - } - } - if (open) { - OpeningHours rs = OpeningHoursParser.parseOpenedHours(a.getOpeningHours()); - if (rs != null) { - Calendar inst = Calendar.getInstance(); - inst.setTimeInMillis(System.currentTimeMillis()); - boolean work = rs.isOpenedForTime(inst); - if (!work) { - return false; - } - } else { - return false; - } + + if (!acceptedAnyFilterOfEachCategory(amenity, selectedFilters)) { + return false; } + return true; } }; } + private boolean isOpened(Amenity amenity) { + OpeningHours openedHours = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours()); + if (openedHours == null) { + return false; + } + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + + return openedHours.isOpenedForTime(calendar); + } + + private String extractNameFilter(Amenity amenity, List unknownFilters) { + if (unknownFilters == null) { + return ""; + } + + StringBuilder nameFilter = new StringBuilder(); + for (String filter : unknownFilters) { + String formattedFilter = filter.replace(':', '_').toLowerCase(); + if (amenity.getAdditionalInfo(formattedFilter) == null) { + nameFilter.append(filter).append(" "); + } + } + + return nameFilter.toString(); + } + + private boolean matchesAnyAmenityName(Amenity amenity, String nameFilter) { + if (nameFilter.length() == 0) { + return true; + } + + final CollatorStringMatcher sm = + new CollatorStringMatcher(nameFilter.trim(), StringMatcherMode.CHECK_CONTAINS); + + List names = OsmAndFormatter.getPoiStringsWithoutType( + amenity, app.getSettings().MAP_PREFERRED_LOCALE.get(), + app.getSettings().MAP_TRANSLITERATE_NAMES.get()); + for (String name : names) { + if (sm.matches(name)) { + return true; + } + } + return false; + } + + private boolean acceptedAnyFilterOfEachCategory(Amenity amenity, List selectedFilters) { + if (selectedFilters == null) { + return true; + } + + Map> filterCategories = new HashMap<>(); + Map textFilters = new HashMap<>(); + + fillFilterCategories(selectedFilters, filterCategories, textFilters); + + for (List category : filterCategories.values()) { + if (!acceptedAnyFilterOfCategory(amenity, category, textFilters)) { + return false; + } + } + + return true; + } + + private void fillFilterCategories( + List selectedFilters, + Map> filterCategories, Map textFilters + ) { + for (PoiType filter : selectedFilters) { + String category = filter.getPoiAdditionalCategory(); + List filtersOfCategory = filterCategories.get(category); + if (filtersOfCategory == null) { + filtersOfCategory = new ArrayList<>(); + filterCategories.put(category, filtersOfCategory); + } + filtersOfCategory.add(filter); + + String osmTag = filter.getOsmTag(); + if (osmTag.length() < filter.getKeyName().length()) { + PoiType textFilter = poiTypes.getTextPoiAdditionalByKey(osmTag); + if (textFilter != null) { + textFilters.put(filter, textFilter); + } + } + } + } + + private boolean acceptedAnyFilterOfCategory( + Amenity amenity, List category, Map textFilters) { + for (PoiType filter : category) { + if (acceptedFilter(amenity, filter, textFilters)) { + return true; + } + } + + return false; + } + + private boolean acceptedFilter( + Amenity amenity, PoiType filter, Map textFilterCategories + ) { + String filterValue = amenity.getAdditionalInfo(filter.getKeyName()); + + if (filterValue != null) { + return true; + } + + PoiType textPoiType = textFilterCategories.get(filter); + if (textPoiType == null) { + return false; + } + + filterValue = amenity.getAdditionalInfo(textPoiType.getKeyName()); + if (Algorithms.isEmpty(filterValue)) { + return false; + } + + String[] items = filterValue.split(";"); + String val = filter.getOsmValue().trim().toLowerCase(); + for (String item : items) { + if (item.trim().toLowerCase().equals(val)) { + return true; + } + } + + return false; + } + public String getNameToken24H() { return app.getString(R.string.shared_string_is_open_24_7).replace(' ', '_').toLowerCase(); } From 1d50e188f42314918b960a2a45eb27bcd87495c6 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Fri, 8 Jan 2021 23:01:50 +0000 Subject: [PATCH 17/67] Translated using Weblate (French) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-fr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 008a82ffa3..ce2956037a 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4023,4 +4023,6 @@ Modifier le moteur de routage en ligne L\'URL avec tous les paramètres sera de la forme : Copier l\'adresse + Moteur de routage en ligne + Moteurs de routage en ligne \ No newline at end of file From e96159d97ab5b6a944ca1d01bf2cb0cf67d5a0ea Mon Sep 17 00:00:00 2001 From: Aleph Null Date: Fri, 8 Jan 2021 23:59:00 +0000 Subject: [PATCH 18/67] Translated using Weblate (German) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 07a0ac5a36..95433700a5 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4048,4 +4048,6 @@ Leer lassen, wenn kein API-Schlüssel vorhanden Adresse kopieren Fahren + Online Navigationssystem + Online Navigationssysteme \ No newline at end of file From ac987645f0665b1af254642825b90b78865e18f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Sat, 9 Jan 2021 05:53:22 +0000 Subject: [PATCH 19/67] Translated using Weblate (Turkish) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-tr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 2e1ed5e651..6974f656ce 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3999,4 +3999,6 @@ Araba Hata, parametreleri tekrar gözden geçirin Adresi kopyala + Çevrim içi yönlendirme motoru + Çevrim içi yönlendirme motorları \ No newline at end of file From 13521bf1c6f090b20de95b5884da9b202958494b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Sat, 9 Jan 2021 15:04:21 +0000 Subject: [PATCH 20/67] Translated using Weblate (Hungarian) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-hu/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index f411c3da1b..d764e136ea 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -4036,4 +4036,6 @@ Útvonaltervezés kipróbálása Hiba, ellenőrizze újra a paramétereket Cím másolása + Online útvonaltervező + Online útvonaltervezők \ No newline at end of file From 83600fdadfe89ed6cae44f27891d7cc6492b973e Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 8 Jan 2021 23:17:12 +0000 Subject: [PATCH 21/67] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-uk/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 0262c62d31..d40f3ce782 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4040,4 +4040,6 @@ Автомобіль Помилка, повторно перевірте параметри Копіювати адресу + Мережний рушій маршрутизації + Мережні рушії маршрутизації \ No newline at end of file From 0a18e1de1fccd07e1f6fc93f906493afc505430e Mon Sep 17 00:00:00 2001 From: ace shadow Date: Sat, 9 Jan 2021 21:10:08 +0000 Subject: [PATCH 22/67] Translated using Weblate (Slovak) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-sk/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 3af8231c15..56a700b27b 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -4043,4 +4043,7 @@ Bicykel Auto Chyba, skontrolujte parametre + Kopírovať adresu + Online navigačná služba + Online navigačné služby \ No newline at end of file From 73bfbfe76d38745a7ea865b4633699c00ede75b3 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sat, 9 Jan 2021 17:07:13 +0000 Subject: [PATCH 23/67] Translated using Weblate (Hebrew) Currently translated at 99.9% (3608 of 3609 strings) --- OsmAnd/res/values-iw/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index fa7a3545a9..e279d6d9b2 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4048,4 +4048,6 @@ מכונית שגיאה, נא לבדוק את המשתנים מחדש העתקת כתובת + מנוע ניווט מקוון + מנועי ניווט מקוונים \ No newline at end of file From 1f3af287a01271f9b81ad4dbec7432c826e5e606 Mon Sep 17 00:00:00 2001 From: Predatorix Phoenix Date: Sat, 9 Jan 2021 03:00:30 +0000 Subject: [PATCH 24/67] Translated using Weblate (German) Currently translated at 100.0% (3881 of 3881 strings) --- OsmAnd/res/values-de/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/phrases.xml b/OsmAnd/res/values-de/phrases.xml index bae219d165..8ea147711e 100644 --- a/OsmAnd/res/values-de/phrases.xml +++ b/OsmAnd/res/values-de/phrases.xml @@ -108,7 +108,7 @@ Höhleneingang Friedhof Ferienhaus - Ladestation + Ladestation;Ladestation für elektische Fahrzeuge;Aufladestation Drogerie Schach Kinderbekleidungsgeschäft From 2536688510e5af7d463e6a3f5ae95f6f5e1e3272 Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Sat, 9 Jan 2021 04:03:18 +0000 Subject: [PATCH 25/67] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 7672038bad..20e2f1a64e 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4039,4 +4039,6 @@ Carro Erro, verifique novamente os parâmetros Copiar endereço + Motor de encaminhamento online + Mecanismos de roteamento online \ No newline at end of file From 29d19d087a098e47731115d9c97a6d504d500986 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Sat, 9 Jan 2021 11:49:09 +0000 Subject: [PATCH 26/67] Translated using Weblate (Esperanto) Currently translated at 99.9% (3608 of 3609 strings) --- OsmAnd/res/values-eo/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 604d169270..933c81c0a8 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -4044,4 +4044,6 @@ Aŭtomobilo Eraro, rekontrolu parametrojn Kopii adreson + Enreta navigilo + Enretaj navigiloj \ No newline at end of file From 1cb0f08ca65fbd6877929ee0da0a4f90bda5c0ca Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 9 Jan 2021 03:54:09 +0000 Subject: [PATCH 27/67] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 9e432f64ed..4b5e87a853 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -4039,4 +4039,6 @@ 汽車 錯誤,重新檢查參數 複製地址 + 線上路線計算引擎 + 線上路線計算引擎 \ No newline at end of file From 85f1a51e215296842e63bc505e945aac29b0dfb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sat, 9 Jan 2021 07:09:10 +0000 Subject: [PATCH 28/67] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/nb_NO/ --- OsmAnd-telegram/res/values-nb/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd-telegram/res/values-nb/strings.xml b/OsmAnd-telegram/res/values-nb/strings.xml index 5b6d88b4af..e7a500ae94 100644 --- a/OsmAnd-telegram/res/values-nb/strings.xml +++ b/OsmAnd-telegram/res/values-nb/strings.xml @@ -1,8 +1,8 @@ - Endre batterioptimiseringsinnstillinger for mer stabil posisjonsdeling. + Endre batterioptimaliseringsinnstillinger for mer stabil posisjonsdeling. Bakgrunnsarbeid - Skru av batterioptimisering for OsmAnd-sporeren slik at det ikke plutselig skrur seg av når det er i bakgrunnen. + Skru av batterioptimalisering for OsmAnd-sporeren slik at det ikke plutselig skrur seg av når det er i bakgrunnen. Deling i bakgrunnen Gå til innstillinger Senere From 170deedad482ac19cd28072064f8c35314c287c6 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sun, 10 Jan 2021 15:04:47 +0200 Subject: [PATCH 29/67] Implement Online routing backend --- ...eet_item_with_descr_radio_and_icon_btn.xml | 13 +- .../plus/activities/MapActivityActions.java | 10 +- .../onlinerouting/OnlineRoutingEngine.java | 74 ++++++---- .../OnlineRoutingEngineFragment.java | 134 +++++++++--------- .../onlinerouting/OnlineRoutingHelper.java | 69 ++++++--- .../osmand/plus/onlinerouting/ServerType.java | 22 --- .../plus/onlinerouting/type/EngineType.java | 55 +++++++ .../onlinerouting/type/GraphhoperEngine.java | 60 ++++++++ .../plus/onlinerouting/type/OsrmEngine.java | 52 +++++++ .../plus/profiles/ProfileDataUtils.java | 34 +++-- .../profiles/SelectProfileBottomSheet.java | 75 ++++++---- .../osmand/plus/routing/RouteProvider.java | 38 ++++- .../plus/settings/backend/OsmandSettings.java | 1 - .../fragments/MainSettingsFragment.java | 4 +- .../fragments/NavigationFragment.java | 26 ++-- .../fragments/ProfileAppearanceFragment.java | 4 +- 16 files changed, 469 insertions(+), 202 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/ServerType.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml index d81614fbb1..c4dc6d4265 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml @@ -14,10 +14,11 @@ android:orientation="horizontal"> + app:srcCompat="@drawable/ic_action_settings" /> diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 3ed8053ca4..c526ddec2a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -63,8 +63,8 @@ import net.osmand.plus.measurementtool.MeasurementToolFragment; import net.osmand.plus.measurementtool.StartPlanRouteBottomSheet; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.osmedit.dialogs.DismissRouteBottomSheetFragment; +import net.osmand.plus.profiles.ProfileDataObject; import net.osmand.plus.profiles.ProfileDataUtils; -import net.osmand.plus.profiles.RoutingProfileDataObject; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.routepreparationmenu.WaypointsFragment; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; @@ -737,7 +737,7 @@ public class MapActivityActions implements DialogProvider { String modeDescription; - Map profilesObjects = ProfileDataUtils.getRoutingProfiles(app); + Map profilesObjects = ProfileDataUtils.getRoutingProfiles(app); for (final ApplicationMode appMode : activeModes) { if (appMode.isCustomProfile()) { modeDescription = getProfileDescription(app, appMode, profilesObjects, getString(R.string.profile_type_user_string)); @@ -1046,7 +1046,7 @@ public class MapActivityActions implements DialogProvider { //switch profile button ApplicationMode currentMode = app.getSettings().APPLICATION_MODE.get(); String modeDescription; - Map profilesObjects = ProfileDataUtils.getRoutingProfiles(app); + Map profilesObjects = ProfileDataUtils.getRoutingProfiles(app); if (currentMode.isCustomProfile()) { modeDescription = getProfileDescription(app, currentMode, profilesObjects, getString(R.string.profile_type_user_string)); } else { @@ -1087,12 +1087,12 @@ public class MapActivityActions implements DialogProvider { } private String getProfileDescription(OsmandApplication app, ApplicationMode mode, - Map profilesObjects, String defaultDescription) { + Map profilesObjects, String defaultDescription) { String description = defaultDescription; String routingProfileKey = mode.getRoutingProfile(); if (!Algorithms.isEmpty(routingProfileKey)) { - RoutingProfileDataObject profileDataObject = profilesObjects.get(routingProfileKey); + ProfileDataObject profileDataObject = profilesObjects.get(routingProfileKey); if (profileDataObject != null) { description = String.format(app.getString(R.string.profile_type_descr_string), Algorithms.capitalizeFirstLetterAndLowercase(profileDataObject.getName())); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java index 10ba169cb1..cf078f8b87 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java @@ -4,40 +4,51 @@ import android.content.Context; import androidx.annotation.NonNull; +import net.osmand.data.LatLon; import net.osmand.plus.R; +import net.osmand.plus.onlinerouting.type.EngineType; import net.osmand.util.Algorithms; import java.util.HashMap; +import java.util.List; import java.util.Map; public class OnlineRoutingEngine { public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; - public enum EngineParameterType { - CUSTOM_SERVER_URL, + public enum EngineParameter { CUSTOM_NAME, + CUSTOM_URL, API_KEY } private String stringKey; - private ServerType serverType; + private EngineType type; + private String customUrl; private String vehicleKey; private Map params = new HashMap<>(); + private OnlineRoutingEngine() {}; + public OnlineRoutingEngine(@NonNull String stringKey, - @NonNull ServerType serverType, + @NonNull EngineType type, @NonNull String vehicleKey, Map params) { - this(stringKey, serverType, vehicleKey); + this(stringKey, type, vehicleKey); this.params = params; } public OnlineRoutingEngine(@NonNull String stringKey, - @NonNull ServerType serverType, + @NonNull EngineType type, @NonNull String vehicleKey) { + this(type, vehicleKey); this.stringKey = stringKey; - this.serverType = serverType; + } + + private OnlineRoutingEngine(@NonNull EngineType type, + @NonNull String vehicleKey) { + this.type = type; this.vehicleKey = vehicleKey; } @@ -45,8 +56,15 @@ public class OnlineRoutingEngine { return stringKey; } - public ServerType getServerType() { - return serverType; + public EngineType getType() { + return type; + } + + public String getBaseUrl() { + if (Algorithms.isEmpty(customUrl)) { + return type.getStandardUrl(); + } + return customUrl; } public String getVehicleKey() { @@ -57,25 +75,16 @@ public class OnlineRoutingEngine { return params; } - public String getBaseUrl() { - String customServerUrl = getParameter(EngineParameterType.CUSTOM_SERVER_URL); - if (!Algorithms.isEmpty(customServerUrl)) { - return customServerUrl; - } else { - return serverType.getBaseUrl(); - } + public String getParameter(EngineParameter paramKey) { + return params.get(paramKey.name()); } - public String getParameter(EngineParameterType paramType) { - return params.get(paramType.name()); - } - - public void putParameter(EngineParameterType paramType, String paramValue) { - params.put(paramType.name(), paramValue); + public void putParameter(EngineParameter paramKey, String paramValue) { + params.put(paramKey.name(), paramValue); } public String getName(@NonNull Context ctx) { - String customName = getParameter(EngineParameterType.CUSTOM_NAME); + String customName = getParameter(EngineParameter.CUSTOM_NAME); if (customName != null) { return customName; } else { @@ -83,21 +92,30 @@ public class OnlineRoutingEngine { } } + public String createFullUrl(@NonNull List path) { + return type.createFullUrl(this, path); + } + private String getStandardName(@NonNull Context ctx) { - return getStandardName(ctx, serverType, vehicleKey); + return getStandardName(ctx, type, vehicleKey); } public static String getStandardName(@NonNull Context ctx, - @NonNull ServerType serverType, + @NonNull EngineType type, @NonNull String vehicleKey) { String vehicleTitle = VehicleType.toHumanString(ctx, vehicleKey); String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash); - return String.format(pattern, serverType.getTitle(), vehicleTitle); + return String.format(pattern, type.getTitle(), vehicleTitle); } - public static OnlineRoutingEngine createNewEngine(@NonNull ServerType serverType, + public static OnlineRoutingEngine createNewEngine(@NonNull EngineType type, @NonNull String vehicleKey) { - return new OnlineRoutingEngine(generateKey(), serverType, vehicleKey); + return new OnlineRoutingEngine(generateKey(), type, vehicleKey); + } + + public static OnlineRoutingEngine createTmpEngine(@NonNull EngineType type, + @NonNull String vehicleKey) { + return new OnlineRoutingEngine(type, vehicleKey); } private static String generateKey() { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 18b24a8762..9414b20a0e 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -30,7 +30,10 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; import net.osmand.plus.onlinerouting.OnlineRoutingCard.OnTextChangedListener; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameterType; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; +import net.osmand.plus.onlinerouting.type.EngineType; +import net.osmand.plus.onlinerouting.type.GraphhoperEngine; +import net.osmand.plus.onlinerouting.type.OsrmEngine; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; @@ -62,7 +65,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private View view; private ViewGroup segmentsContainer; private OnlineRoutingCard nameCard; - private OnlineRoutingCard serverCard; + private OnlineRoutingCard typeCard; private OnlineRoutingCard vehicleCard; private OnlineRoutingCard apiKeyCard; private OnlineRoutingCard exampleCard; @@ -143,7 +146,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { setupToolbar((Toolbar) view.findViewById(R.id.toolbar)); setupNameCard(); - setupServerCard(); + setupTypeCard(); setupVehicleCard(); setupApiKeyCard(); setupExampleCard(); @@ -152,7 +155,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { setupButtons(); - updateCardViews(nameCard, serverCard, vehicleCard, exampleCard); + updateCardViews(nameCard, typeCard, vehicleCard, exampleCard); return view; } @@ -174,38 +177,39 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { segmentsContainer.addView(nameCard.getView()); } - private void setupServerCard() { - serverCard = new OnlineRoutingCard(mapActivity, isNightMode()); - serverCard.build(mapActivity); - serverCard.setHeaderTitle(getString(R.string.shared_string_type)); + private void setupTypeCard() { + typeCard = new OnlineRoutingCard(mapActivity, isNightMode()); + typeCard.build(mapActivity); + typeCard.setHeaderTitle(getString(R.string.shared_string_type)); List serverItems = new ArrayList<>(); - for (ServerType server : ServerType.values()) { + for (EngineType server : EngineType.values()) { serverItems.add(new HorizontalSelectionItem(server.getTitle(), server)); } - serverCard.setSelectionMenu(serverItems, engine.serverType.getTitle(), + typeCard.setSelectionMenu(serverItems, engine.type.getTitle(), new CallbackWithObject() { @Override public boolean processResult(HorizontalSelectionItem result) { - ServerType server = (ServerType) result.getObject(); - if (engine.serverType != server) { - engine.serverType = server; - updateCardViews(nameCard, serverCard, exampleCard); + EngineType type = (EngineType) result.getObject(); + if (!Algorithms.objectEquals(engine.type.getStringKey(), type.getStringKey())) { + engine.type = type; + updateCardViews(nameCard, typeCard, exampleCard); return true; } return false; } }); - serverCard.setOnTextChangedListener(new OnTextChangedListener() { + typeCard.setOnTextChangedListener(new OnTextChangedListener() { @Override public void onTextChanged(boolean editedByUser, String text) { if (editedByUser) { engine.customServerUrl = text; + updateCardViews(exampleCard); } } }); - serverCard.setFieldBoxLabelText(getString(R.string.shared_string_server_url)); - serverCard.showDivider(); - segmentsContainer.addView(serverCard.getView()); + typeCard.setFieldBoxLabelText(getString(R.string.shared_string_server_url)); + typeCard.showDivider(); + segmentsContainer.addView(typeCard.getView()); } private void setupVehicleCard() { @@ -342,22 +346,28 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { for (BaseCard card : cardsToUpdate) { if (nameCard.equals(card)) { if (Algorithms.isEmpty(engine.customName)) { - String name = OnlineRoutingEngine.getStandardName(app, engine.serverType, engine.getVehicleKey()); + String name; + if (Algorithms.isEmpty(engine.getVehicleKey())) { + name = engine.type.getTitle(); + } else { + name = OnlineRoutingEngine.getStandardName(app, engine.type, engine.getVehicleKey()); + } nameCard.setEditedText(name); } - } else if (serverCard.equals(card)) { - serverCard.setHeaderSubtitle(engine.serverType.getTitle()); - serverCard.setEditedText(engine.getBaseUrl()); - if (engine.serverType == ServerType.GRAPHHOPER) { + } else if (typeCard.equals(card)) { + typeCard.setHeaderSubtitle(engine.type.getTitle()); + typeCard.setEditedText(engine.getBaseUrl()); + if (engine.type instanceof GraphhoperEngine) { apiKeyCard.show(); } else { apiKeyCard.hide(); } } else if (vehicleCard.equals(card)) { - vehicleCard.setHeaderSubtitle(engine.vehicleType.getTitle(app)); - if (engine.vehicleType == VehicleType.CUSTOM) { + VehicleType vt = VehicleType.getVehicleByKey(engine.getVehicleKey()); + vehicleCard.setHeaderSubtitle(vt.getTitle(app)); + if (vt == VehicleType.CUSTOM) { vehicleCard.showFieldBox(); vehicleCard.setEditedText(engine.getVehicleKey()); } else { @@ -400,15 +410,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void saveChanges() { OnlineRoutingEngine engineToSave; if (isEditingMode()) { - engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.serverType, engine.getVehicleKey()); + engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.type, engine.getVehicleKey()); } else { - engineToSave = OnlineRoutingEngine.createNewEngine(engine.serverType, engine.getVehicleKey()); + engineToSave = OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey()); } - engineToSave.putParameter(EngineParameterType.CUSTOM_SERVER_URL, engine.customServerUrl); - engineToSave.putParameter(EngineParameterType.CUSTOM_NAME, engine.customName); - if (engine.serverType == ServerType.GRAPHHOPER) { - engineToSave.putParameter(EngineParameterType.API_KEY, engine.apiKey); + engineToSave.putParameter(EngineParameter.CUSTOM_NAME, engine.customName); + engineToSave.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); + if (engine.type instanceof GraphhoperEngine) { + engineToSave.putParameter(EngineParameter.API_KEY, engine.apiKey); } helper.saveEngine(engineToSave); @@ -419,30 +429,18 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private String getTestUrl() { - String baseUrl = engine.serverType.getBaseUrl(); - String vehicle = engine.getVehicleKey(); - - LatLon startPoint = selectedLocation.getCityCenterLatLon(); - LatLon endPoint = selectedLocation.getCityAirportLatLon(); - - if (engine.serverType == ServerType.GRAPHHOPER) { - return baseUrl + "?" + "point=" + startPoint.getLatitude() - + "," + startPoint.getLongitude() - + "&" + "point=" + endPoint.getLatitude() - + "," + endPoint.getLongitude() - + "&" + "vehicle=" + vehicle - + (!Algorithms.isEmpty(engine.apiKey) ? ("&" + "key=" + engine.apiKey) : ""); - } else { - return baseUrl + vehicle + "/" + startPoint.getLatitude() - + "," + startPoint.getLongitude() - + ";" + endPoint.getLatitude() - + "," + endPoint.getLongitude() - + "?" + "geometries=geojson"; - } + List path = new ArrayList<>(); + path.add(selectedLocation.getCityCenterLatLon()); + path.add(selectedLocation.getCityAirportLatLon()); + OnlineRoutingEngine tmpEngine = + OnlineRoutingEngine.createTmpEngine(engine.type, engine.getVehicleKey()); + tmpEngine.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); + tmpEngine.putParameter(EngineParameter.API_KEY, engine.apiKey); + return tmpEngine.createFullUrl(path); } private void testEngineWork() { - final ServerType server = engine.serverType; + final EngineType type = engine.type; final ExampleLocation location = selectedLocation; AndroidNetworkUtils.sendRequestAsync(app, exampleCard.getEditedText(), null, null, false, false, new OnRequestResultListener() { @@ -453,9 +451,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { try { JSONObject obj = new JSONObject(response); - if (server == ServerType.GRAPHHOPER) { + if (type instanceof GraphhoperEngine) { resultOk = obj.has("paths"); - } else if (server == ServerType.OSRM) { + } else if (type instanceof OsrmEngine) { resultOk = obj.has("routes"); } } catch (JSONException e) { @@ -494,7 +492,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void saveState(Bundle outState) { outState.putString(ENGINE_NAME_KEY, engine.customName); - outState.putString(ENGINE_SERVER_KEY, engine.serverType.name()); + outState.putString(ENGINE_SERVER_KEY, engine.type.getStringKey()); outState.putString(ENGINE_SERVER_URL_KEY, engine.customServerUrl); outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); @@ -508,7 +506,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void restoreState(Bundle savedState) { engine.customName = savedState.getString(ENGINE_NAME_KEY); - engine.serverType = ServerType.valueOf(savedState.getString(ENGINE_SERVER_KEY)); + engine.type = EngineType.valueOf(savedState.getString(ENGINE_SERVER_KEY)); engine.customServerUrl = savedState.getString(ENGINE_SERVER_URL_KEY); engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY)); engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); @@ -519,16 +517,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void initState() { - engine.serverType = ServerType.values()[0]; + engine.type = EngineType.values()[0]; engine.vehicleType = VehicleType.values()[0]; selectedLocation = ExampleLocation.values()[0]; if (isEditingMode()) { OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey); if (editedEngine != null) { - engine.customName = editedEngine.getParameter(EngineParameterType.CUSTOM_NAME); - engine.serverType = editedEngine.getServerType(); - engine.customServerUrl = editedEngine.getParameter(EngineParameterType.CUSTOM_SERVER_URL); + engine.customName = editedEngine.getParameter(EngineParameter.CUSTOM_NAME); + engine.type = editedEngine.getType(); String vehicleKey = editedEngine.getVehicleKey(); if (vehicleKey != null) { VehicleType vehicleType = VehicleType.getVehicleByKey(vehicleKey); @@ -537,7 +534,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } engine.vehicleType = vehicleType; } - engine.apiKey = editedEngine.getParameter(EngineParameterType.API_KEY); + engine.apiKey = editedEngine.getParameter(EngineParameter.API_KEY); } } } @@ -583,7 +580,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static class OnlineRoutingEngineObject { private String customName; - private ServerType serverType; + private EngineType type; private String customServerUrl; private VehicleType vehicleType; private String customVehicleKey; @@ -596,15 +593,18 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return vehicleType.getKey(); } - public String getBaseUrl() { - return customServerUrl != null ? customServerUrl : serverType.getBaseUrl(); - } - public String getName(Context ctx) { if (customName != null) { return customName; } - return OnlineRoutingEngine.getStandardName(ctx, serverType, getVehicleKey()); + return OnlineRoutingEngine.getStandardName(ctx, type, getVehicleKey()); + } + + public String getBaseUrl() { + if (Algorithms.isEmpty(customServerUrl)) { + return type.getStandardUrl(); + } + return customServerUrl; } } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 8a9e42bd54..df91950174 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -6,7 +6,11 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import net.osmand.PlatformUtil; +import net.osmand.data.LatLon; +import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.Version; +import net.osmand.plus.onlinerouting.type.EngineType; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; @@ -15,9 +19,14 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.lang.reflect.Type; +import java.net.URLConnection; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -27,8 +36,7 @@ public class OnlineRoutingHelper { private OsmandApplication app; private OsmandSettings settings; - private List cachedEngines; - private Map cachedEnginesMap; + private Map cachedEngines; public OnlineRoutingHelper(OsmandApplication app) { this.app = app; @@ -38,23 +46,39 @@ public class OnlineRoutingHelper { @NonNull public List getEngines() { - return cachedEngines; + return new ArrayList<>(cachedEngines.values()); } public OnlineRoutingEngine getEngineByKey(String stringKey) { - return cachedEnginesMap.get(stringKey); + return cachedEngines.get(stringKey); + } + + public List calculateRouteOnline(@NonNull OnlineRoutingEngine engine, + @NonNull List path) throws IOException, JSONException { + String fullUrl = engine.createFullUrl(path); + String content = makeRequest(fullUrl); + return engine.getType().parseResponse(content); + } + + private String makeRequest(String url) throws IOException { + URLConnection connection = NetworkUtils.getHttpURLConnection(url); + connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); + StringBuilder content = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String s; + while ((s = reader.readLine()) != null) { + content.append(s); + } + try { + reader.close(); + } catch (IOException ignored) { + } + return content.toString(); } public void saveEngine(@NonNull OnlineRoutingEngine engine) { String stringKey = engine.getStringKey(); - OnlineRoutingEngine existedEngine = cachedEnginesMap.get(stringKey); - if (existedEngine != null) { - int index = cachedEngines.indexOf(existedEngine); - cachedEngines.set(index, engine); - } else { - cachedEngines.add(engine); - } - cachedEnginesMap.put(stringKey, engine); + cachedEngines.put(stringKey, engine); saveToSettings(); } @@ -67,19 +91,18 @@ public class OnlineRoutingHelper { public void deleteEngine(@NonNull OnlineRoutingEngine engine) { String stringKey = engine.getStringKey(); - if (cachedEnginesMap.containsKey(stringKey)) { - OnlineRoutingEngine existedEngine = cachedEnginesMap.remove(stringKey); - cachedEngines.remove(existedEngine); + if (cachedEngines.containsKey(stringKey)) { + cachedEngines.remove(stringKey); saveToSettings(); } } private void loadFromSettings() { - cachedEngines = readFromSettings(); - cachedEnginesMap = new HashMap<>(); - for (OnlineRoutingEngine engine : cachedEngines) { - cachedEnginesMap.put(engine.getStringKey(), engine); + Map cachedEngines = new LinkedHashMap<>(); + for (OnlineRoutingEngine engine : readFromSettings()) { + cachedEngines.put(engine.getStringKey(), engine); } + this.cachedEngines = cachedEngines; } @NonNull @@ -100,7 +123,7 @@ public class OnlineRoutingHelper { private void saveToSettings() { if (!Algorithms.isEmpty(cachedEngines)) { JSONObject json = new JSONObject(); - if (writeToJson(json, cachedEngines)) { + if (writeToJson(json, getEngines())) { settings.ONLINE_ROUTING_ENGINES.set(json.toString()); } } else { @@ -121,10 +144,10 @@ public class OnlineRoutingHelper { JSONObject object = itemsJson.getJSONObject(i); String key = object.getString("key"); String vehicleKey = object.getString("vehicle"); - ServerType serverType = ServerType.valueOf(object.getString("serverType")); + EngineType engineType = EngineType.valueOf(object.getString("type")); String paramsString = object.getString("params"); HashMap params = gson.fromJson(paramsString, type); - engines.add(new OnlineRoutingEngine(key, serverType, vehicleKey, params)); + engines.add(new OnlineRoutingEngine(key, engineType, vehicleKey, params)); } } catch (JSONException e) { LOG.debug("Error when reading engines from JSON: " + e.toString()); @@ -140,7 +163,7 @@ public class OnlineRoutingHelper { for (OnlineRoutingEngine engine : engines) { JSONObject jsonObject = new JSONObject(); jsonObject.put("key", engine.getStringKey()); - jsonObject.put("serverType", engine.getServerType().name()); + jsonObject.put("type", engine.getType().getStringKey()); jsonObject.put("vehicle", engine.getVehicleKey()); jsonObject.put("params", gson.toJson(engine.getParams(), type)); jsonArray.put(jsonObject); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ServerType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ServerType.java deleted file mode 100644 index 7eb30798d5..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ServerType.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.osmand.plus.onlinerouting; - -public enum ServerType { - GRAPHHOPER("Graphhoper", "https://graphhopper.com/api/1/route"), - OSRM("OSRM", "https://zlzk.biz/route/v1/"); - - ServerType(String title, String baseUrl) { - this.title = title; - this.baseUrl = baseUrl; - } - - private String title; - private String baseUrl; - - public String getTitle() { - return title; - } - - public String getBaseUrl() { - return baseUrl; - } -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java new file mode 100644 index 0000000000..bf8eaac493 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java @@ -0,0 +1,55 @@ +package net.osmand.plus.onlinerouting.type; + +import androidx.annotation.NonNull; + +import net.osmand.data.LatLon; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine; +import net.osmand.util.Algorithms; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; + +public abstract class EngineType { + + public abstract String getStringKey(); + + public abstract String getTitle(); + + public abstract String getStandardUrl(); + + public String createFullUrl(OnlineRoutingEngine engine, List path) { + StringBuilder sb = new StringBuilder(engine.getBaseUrl()); + createFullUrl(sb, engine, path); + return sb.toString(); + } + + protected abstract void createFullUrl(StringBuilder sb, + OnlineRoutingEngine engine, + List path); + + public List parseResponse(@NonNull String content) throws JSONException { + return parseResponse(new JSONObject(content), content); + } + + protected abstract List parseResponse(JSONObject obj, @NonNull String content) throws JSONException; + + public static EngineType[] values() { + EngineType[] types = new EngineType[] { + new GraphhoperEngine(), + new OsrmEngine() + }; + return types; + } + + public static EngineType valueOf(String key) { + EngineType[] values = values(); + for (EngineType type : values) { + if (Algorithms.objectEquals(type.getStringKey(), key)) { + return type; + } + } + return values[0]; + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java new file mode 100644 index 0000000000..ea9288e564 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java @@ -0,0 +1,60 @@ +package net.osmand.plus.onlinerouting.type; + +import androidx.annotation.NonNull; + +import net.osmand.data.LatLon; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; +import net.osmand.util.Algorithms; +import net.osmand.util.GeoPolylineParserUtil; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; + +public class GraphhoperEngine extends EngineType { + + @Override + public String getStringKey() { + return "graphhoper"; + } + + @Override + public String getTitle() { + return "Graphhoper"; + } + + @Override + public String getStandardUrl() { + return "https://graphhopper.com/api/1/route"; + } + + @Override + protected void createFullUrl(StringBuilder sb, + OnlineRoutingEngine engine, + List path) { + sb.append("?"); + for (LatLon point : path) { + sb.append("point=") + .append(point.getLatitude()) + .append(',') + .append(point.getLongitude()) + .append('&'); + } + sb.append("vehicle=").append(engine.getVehicleKey()); + + String apiKey = engine.getParameter(EngineParameter.API_KEY); + if (!Algorithms.isEmpty(apiKey)) { + sb.append('&').append("key=").append(apiKey); + } + } + + @Override + protected List parseResponse(JSONObject obj, @NonNull String content) throws JSONException { + return GeoPolylineParserUtil.parse( + obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), + GeoPolylineParserUtil.PRECISION_5); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java new file mode 100644 index 0000000000..003425809d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java @@ -0,0 +1,52 @@ +package net.osmand.plus.onlinerouting.type; + +import androidx.annotation.NonNull; + +import net.osmand.data.LatLon; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine; +import net.osmand.util.GeoPolylineParserUtil; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; + +public class OsrmEngine extends EngineType { + + @Override + public String getStringKey() { + return "osrm"; + } + + @Override + public String getTitle() { + return "OSRM"; + } + + @Override + public String getStandardUrl() { + return "https://router.project-osrm.org/route/v1/"; + } + + @Override + protected void createFullUrl(StringBuilder sb, + OnlineRoutingEngine engine, + List path) { + sb.append(engine.getVehicleKey()).append('/'); + for (int i = 0; i < path.size(); i++) { + LatLon point = path.get(i); + sb.append(point.getLongitude()).append(',').append(point.getLatitude()); + if (i < path.size() - 1) { + sb.append(';'); + } + } + } + + @Override + protected List parseResponse(@NonNull JSONObject obj, @NonNull String content) throws JSONException { + return GeoPolylineParserUtil.parse( + obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), + GeoPolylineParserUtil.PRECISION_5); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java index f769f69bdb..28967ba2f3 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java @@ -22,6 +22,7 @@ import java.util.Map; public class ProfileDataUtils { public static final String OSMAND_NAVIGATION = "osmand_navigation"; + public static final String ONLINE_NAVIGATION = "online_navigation"; public static List getDataObjects(OsmandApplication app, List appModes) { @@ -48,9 +49,9 @@ public class ProfileDataUtils { return description; } - public static List getSortedRoutingProfiles(OsmandApplication app) { - List result = new ArrayList<>(); - Map> routingProfilesByFileNames = getRoutingProfilesByFileNames(app); + public static List getSortedRoutingProfiles(OsmandApplication app) { + List result = new ArrayList<>(); + Map> routingProfilesByFileNames = getRoutingProfilesByFileNames(app); List fileNames = new ArrayList<>(routingProfilesByFileNames.keySet()); Collections.sort(fileNames, new Comparator() { @Override @@ -59,7 +60,7 @@ public class ProfileDataUtils { } }); for (String fileName : fileNames) { - List routingProfilesFromFile = routingProfilesByFileNames.get(fileName); + List routingProfilesFromFile = routingProfilesByFileNames.get(fileName); if (routingProfilesFromFile != null) { Collections.sort(routingProfilesFromFile); result.addAll(routingProfilesFromFile); @@ -77,14 +78,20 @@ public class ProfileDataUtils { return objects; } - public static Map> getRoutingProfilesByFileNames(OsmandApplication app) { - Map> result = new HashMap<>(); - for (final RoutingProfileDataObject profile : getRoutingProfiles(app).values()) { - String fileName = profile.getFileName() != null ? profile.getFileName() : OSMAND_NAVIGATION; + public static Map> getRoutingProfilesByFileNames(OsmandApplication app) { + Map> result = new HashMap<>(); + for (final ProfileDataObject profile : getRoutingProfiles(app).values()) { + String fileName = null; + if (profile instanceof RoutingProfileDataObject) { + fileName = ((RoutingProfileDataObject) profile).getFileName(); + } else if (profile instanceof OnlineRoutingEngineDataObject) { + fileName = ONLINE_NAVIGATION; + } + fileName = fileName != null ? fileName : OSMAND_NAVIGATION; if (result.containsKey(fileName)) { result.get(fileName).add(profile); } else { - result.put(fileName, new ArrayList() { + result.put(fileName, new ArrayList() { { add(profile); } }); } @@ -92,8 +99,8 @@ public class ProfileDataUtils { return result; } - public static Map getRoutingProfiles(OsmandApplication context) { - Map profilesObjects = new HashMap<>(); + public static Map getRoutingProfiles(OsmandApplication context) { + Map profilesObjects = new HashMap<>(); profilesObjects.put(RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), new RoutingProfileDataObject( RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), context.getString(RoutingProfilesResources.STRAIGHT_LINE_MODE.getStringRes()), @@ -119,11 +126,14 @@ public class ProfileDataUtils { for (RoutingConfiguration.Builder builder : context.getAllRoutingConfigs()) { collectRoutingProfilesFromConfig(context, builder, profilesObjects, disabledRouterNames); } + for (OnlineRoutingEngineDataObject onlineEngine : getOnlineRoutingProfiles(context)) { + profilesObjects.put(onlineEngine.getStringKey(), onlineEngine); + } return profilesObjects; } private static void collectRoutingProfilesFromConfig(OsmandApplication app, RoutingConfiguration.Builder builder, - Map profilesObjects, List disabledRouterNames) { + Map profilesObjects, List disabledRouterNames) { for (Map.Entry entry : builder.getAllRouters().entrySet()) { String routerKey = entry.getKey(); GeneralRouter router = entry.getValue(); diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index df2bd8b879..98ca4771cc 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.text.SpannableString; import android.text.Spanned; @@ -58,7 +59,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { public final static String PROFILE_KEY_ARG = "profile_key_arg"; public final static String USE_LAST_PROFILE_ARG = "use_last_profile_arg"; - public final static String IS_PROFILE_IMPORTED_ARG = "is_profile_imported_arg"; + public final static String PROFILES_LIST_UPDATED_ARG = "is_profiles_list_updated"; private DialogMode dialogMode; private final List profiles = new ArrayList<>(); @@ -130,7 +131,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { } Bundle args = new Bundle(); args.putString(PROFILE_KEY_ARG, item.getName()); - args.putBoolean(IS_PROFILE_IMPORTED_ARG, true); + args.putBoolean(PROFILES_LIST_UPDATED_ARG, true); listener.onSelectedType(args); dismiss(); break; @@ -234,9 +235,10 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; int iconDefaultColorResId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; + final boolean onlineRoutingProfile = profile instanceof OnlineRoutingEngineDataObject; View itemView = UiUtilities.getInflater(getContext(), nightMode).inflate( - profile instanceof OnlineRoutingEngineDataObject ? + onlineRoutingProfile ? R.layout.bottom_sheet_item_with_descr_radio_and_icon_btn : R.layout.bottom_sheet_item_with_descr_and_radio_btn, null); TextView tvTitle = itemView.findViewById(R.id.title); @@ -262,28 +264,52 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL); bottomDivider.setVisibility(showBottomDivider ? View.VISIBLE : View.INVISIBLE); - items.add(new BaseBottomSheetItem.Builder() - .setCustomView(itemView) - .setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - Bundle args = new Bundle(); - args.putString(PROFILE_KEY_ARG, profile.getStringKey()); - Fragment target = getTargetFragment(); - if (target instanceof OnSelectProfileCallback) { - if (profile instanceof OnlineRoutingEngineDataObject) { - if (getActivity() != null) { - OnlineRoutingEngineFragment.showInstance(getActivity(), getAppMode(), profile.getStringKey()); - } - dismiss(); - } else { - ((OnSelectProfileCallback) target).onProfileSelected(args); - } - } - dismiss(); + BaseBottomSheetItem.Builder builder = + new BaseBottomSheetItem.Builder().setCustomView(itemView); + + OnClickListener listener = new OnClickListener() { + @Override + public void onClick(View view) { + Bundle args = new Bundle(); + args.putString(PROFILE_KEY_ARG, profile.getStringKey()); + args.putBoolean(PROFILES_LIST_UPDATED_ARG, onlineRoutingProfile); + Fragment target = getTargetFragment(); + if (target instanceof OnSelectProfileCallback) { + ((OnSelectProfileCallback) target).onProfileSelected(args); + } + dismiss(); + } + }; + + if (onlineRoutingProfile) { + View basePart = itemView.findViewById(R.id.basic_item_body); + View endBtn = itemView.findViewById(R.id.end_button); + ImageView ivEndBtnIcon = itemView.findViewById(R.id.end_button_icon); + + Drawable drawable = getIcon(R.drawable.ic_action_settings, + nightMode ? + R.color.route_info_control_icon_color_dark : + R.color.route_info_control_icon_color_light); + if (Build.VERSION.SDK_INT >= 21) { + Drawable activeDrawable = getIcon(R.drawable.ic_action_settings, activeColorResId); + drawable = AndroidUtils.createPressedStateListDrawable(drawable, activeDrawable); + } + ivEndBtnIcon.setImageDrawable(drawable); + + basePart.setOnClickListener(listener); + endBtn.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (getActivity() != null) { + OnlineRoutingEngineFragment.showInstance(getActivity(), getAppMode(), profile.getStringKey()); } - }) - .create()); + dismiss(); + } + }); + } else { + builder.setOnClickListener(listener); + } + items.add(builder.create()); } private void addCheckableItem(int titleId, @@ -363,7 +389,6 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { case NAVIGATION_PROFILE: profiles.addAll(ProfileDataUtils.getSortedRoutingProfiles(app)); - profiles.addAll(ProfileDataUtils.getOnlineRoutingProfiles(app)); break; case DEFAULT_PROFILE: diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 37bb29d148..0ba23f118a 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -22,6 +22,8 @@ import net.osmand.data.LocationPoint; import net.osmand.data.WptLocationPoint; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine; +import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; @@ -91,7 +93,8 @@ public class RouteProvider { OSMAND("OsmAnd (offline)"), BROUTER("BRouter (offline)"), STRAIGHT("Straight line"), - DIRECT_TO("Direct To"); + DIRECT_TO("Direct To"), + ONLINE("Online engine"); private final String name; @@ -363,6 +366,8 @@ public class RouteProvider { res = findVectorMapsRoute(params, calcGPXRoute); } else if (params.mode.getRouteService() == RouteService.BROUTER) { res = findBROUTERRoute(params); + } else if (params.mode.getRouteService() == RouteService.ONLINE) { + res = findOnlineRoute(params); // } else if (params.type == RouteService.ORS) { // res = findORSRoute(params); // } else if (params.type == RouteService.OSRM) { @@ -383,6 +388,8 @@ public class RouteProvider { log.error("Failed to find route ", e); //$NON-NLS-1$ } catch (SAXException e) { log.error("Failed to find route ", e); //$NON-NLS-1$ + } catch (JSONException e) { + log.error("Failed to find route ", e); //$NON-NLS-1$ } } return new RouteCalculationResult(null); @@ -1204,6 +1211,35 @@ public class RouteProvider { return exporter.exportRoute(); } + private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException { + OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper(); + String stringKey = params.mode.getRoutingProfile(); + List route = helper.calculateRouteOnline(helper.getEngineByKey(stringKey), getFullPathFromParams(params)); + if (!route.isEmpty()) { + List res = new ArrayList<>(); + for (LatLon pt : route) { + WptPt wpt = new WptPt(); + wpt.lat = pt.getLatitude(); + wpt.lon = pt.getLongitude(); + res.add(createLocation(wpt)); + } + params.intermediates = null; + return new RouteCalculationResult(res, null, params, null, true); + } else { + return new RouteCalculationResult("Route is empty"); + } + } + + private static List getFullPathFromParams(RouteCalculationParams params) { + List points = new ArrayList<>(); + points.add(new LatLon(params.start.getLatitude(), params.start.getLongitude())); + if (Algorithms.isEmpty(params.intermediates)) { + points.addAll(params.intermediates); + } + points.add(params.end); + return points; + } + private void appendOSRMLoc(StringBuilder uri, LatLon il) { uri.append(";").append(il.getLongitude()); uri.append(",").append(il.getLatitude()); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index efaaff576b..836a1fc7f8 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -48,7 +48,6 @@ import net.osmand.plus.helpers.enums.TracksSortByMode; import net.osmand.plus.mapillary.MapillaryPlugin; import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format; import net.osmand.plus.mapmarkers.MapMarkersMode; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.profiles.LocationIcon; import net.osmand.plus.profiles.NavigationIcon; import net.osmand.plus.profiles.ProfileIconColors; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java index fdd5508352..665374c003 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java @@ -35,7 +35,7 @@ import java.util.List; import java.util.Set; import static net.osmand.plus.importfiles.ImportHelper.ImportType.SETTINGS; -import static net.osmand.plus.profiles.SelectProfileBottomSheet.IS_PROFILE_IMPORTED_ARG; +import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG; public class MainSettingsFragment extends BaseSettingsFragment implements OnSelectProfileCallback{ @@ -229,7 +229,7 @@ public class MainSettingsFragment extends BaseSettingsFragment implements OnSele FragmentManager fragmentManager = activity.getSupportFragmentManager(); if (fragmentManager != null) { String profileKey = args.getString(PROFILE_KEY_ARG); - boolean imported = args.getBoolean(IS_PROFILE_IMPORTED_ARG); + boolean imported = args.getBoolean(PROFILES_LIST_UPDATED_ARG); ProfileAppearanceFragment.showInstance(activity, SettingsScreenType.PROFILE_APPEARANCE, profileKey, imported); } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java index de8481f222..c6556459b5 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java @@ -10,13 +10,14 @@ import androidx.preference.Preference; import androidx.preference.SwitchPreferenceCompat; import net.osmand.plus.measurementtool.MeasurementToolFragment; +import net.osmand.plus.profiles.ProfileDataObject; import net.osmand.plus.profiles.ProfileDataUtils; import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet; import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DialogMode; +import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.profiles.RoutingProfileDataObject; import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources; import net.osmand.plus.profiles.SelectProfileBottomSheet; import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; @@ -26,7 +27,8 @@ import net.osmand.util.Algorithms; import java.util.Map; -import static net.osmand.plus.profiles.SelectProfileBottomSheet.IS_PROFILE_IMPORTED_ARG; +import static net.osmand.plus.onlinerouting.OnlineRoutingEngine.ONLINE_ROUTING_ENGINE_PREFIX; +import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG; import static net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DIALOG_MODE_KEY; @@ -35,13 +37,13 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect public static final String TAG = NavigationFragment.class.getSimpleName(); public static final String NAVIGATION_TYPE = "navigation_type"; - private Map routingProfileDataObjects; + private Map routingProfileDataObjects; private Preference navigationType; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - routingProfileDataObjects = ProfileDataUtils.getRoutingProfiles(app); + updateRoutingProfilesDataObjects(); setupOnBackPressedCallback(); } @@ -90,7 +92,7 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect private void setupNavigationTypePref() { String routingProfileKey = getSelectedAppMode().getRoutingProfile(); if (!Algorithms.isEmpty(routingProfileKey)) { - RoutingProfileDataObject routingProfileDataObject = routingProfileDataObjects.get(routingProfileKey); + ProfileDataObject routingProfileDataObject = routingProfileDataObjects.get(routingProfileKey); if (routingProfileDataObject != null) { navigationType.setSummary(routingProfileDataObject.getName()); navigationType.setIcon(getActiveIcon(routingProfileDataObject.getIconRes())); @@ -132,12 +134,16 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect return false; } + private void updateRoutingProfilesDataObjects() { + routingProfileDataObjects = ProfileDataUtils.getRoutingProfiles(app); + } + void updateRoutingProfile(String profileKey) { - RoutingProfileDataObject selectedRoutingProfileDataObject = routingProfileDataObjects.get(profileKey); + ProfileDataObject selectedRoutingProfileDataObject = routingProfileDataObjects.get(profileKey); if (profileKey == null || selectedRoutingProfileDataObject == null) { return; } - for (Map.Entry rp : routingProfileDataObjects.entrySet()) { + for (Map.Entry rp : routingProfileDataObjects.entrySet()) { boolean selected = profileKey.equals(rp.getKey()); rp.getValue().setSelected(selected); } @@ -152,6 +158,8 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect routeService = RouteProvider.RouteService.DIRECT_TO; } else if (profileKey.equals(RoutingProfilesResources.BROUTER_MODE.name())) { routeService = RouteProvider.RouteService.BROUTER; + } else if (profileKey.startsWith(ONLINE_ROUTING_ENGINE_PREFIX)) { + routeService = RouteService.ONLINE; } else { routeService = RouteProvider.RouteService.OSMAND; } @@ -174,8 +182,8 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect @Override public void onProfileSelected(Bundle args) { - if (args.getBoolean(IS_PROFILE_IMPORTED_ARG)) { - routingProfileDataObjects = ProfileDataUtils.getRoutingProfiles(app); + if (args.getBoolean(PROFILES_LIST_UPDATED_ARG)) { + updateRoutingProfilesDataObjects(); } updateRoutingProfile(args.getString(PROFILE_KEY_ARG)); } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java index 7a42818745..7e1277ca18 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java @@ -66,7 +66,7 @@ import java.util.ArrayList; import java.util.Collections; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID; -import static net.osmand.plus.profiles.SelectProfileBottomSheet.IS_PROFILE_IMPORTED_ARG; +import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG; public class ProfileAppearanceFragment extends BaseSettingsFragment implements OnSelectProfileCallback { @@ -934,7 +934,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O @Override public void onProfileSelected(Bundle args) { String profileKey = args.getString(PROFILE_KEY_ARG); - boolean imported = args.getBoolean(IS_PROFILE_IMPORTED_ARG); + boolean imported = args.getBoolean(PROFILES_LIST_UPDATED_ARG); updateParentProfile(profileKey, imported); } From d6bfe960146e88f29a00fc924060511b15547081 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sun, 10 Jan 2021 23:51:02 +0200 Subject: [PATCH 30/67] remove outdated OSRM code and small refactoring --- .../onlinerouting/OnlineRoutingEngine.java | 2 +- .../plus/onlinerouting/type/EngineType.java | 6 +- .../onlinerouting/type/GraphhoperEngine.java | 3 +- .../plus/onlinerouting/type/OsrmEngine.java | 3 +- .../osmand/plus/routing/RouteProvider.java | 64 ------------------- 5 files changed, 6 insertions(+), 72 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java index cf078f8b87..7b2b499e78 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java @@ -25,7 +25,6 @@ public class OnlineRoutingEngine { private String stringKey; private EngineType type; - private String customUrl; private String vehicleKey; private Map params = new HashMap<>(); @@ -61,6 +60,7 @@ public class OnlineRoutingEngine { } public String getBaseUrl() { + String customUrl = getParameter(EngineParameter.CUSTOM_URL); if (Algorithms.isEmpty(customUrl)) { return type.getStandardUrl(); } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java index bf8eaac493..2ef77e2c43 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java @@ -29,11 +29,7 @@ public abstract class EngineType { OnlineRoutingEngine engine, List path); - public List parseResponse(@NonNull String content) throws JSONException { - return parseResponse(new JSONObject(content), content); - } - - protected abstract List parseResponse(JSONObject obj, @NonNull String content) throws JSONException; + public abstract List parseResponse(@NonNull String content) throws JSONException; public static EngineType[] values() { EngineType[] types = new EngineType[] { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java index ea9288e564..a315eb457b 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java @@ -51,7 +51,8 @@ public class GraphhoperEngine extends EngineType { } @Override - protected List parseResponse(JSONObject obj, @NonNull String content) throws JSONException { + public List parseResponse(@NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); return GeoPolylineParserUtil.parse( obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), GeoPolylineParserUtil.PRECISION_5); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java index 003425809d..20cf6f00b4 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java @@ -43,7 +43,8 @@ public class OsrmEngine extends EngineType { } @Override - protected List parseResponse(@NonNull JSONObject obj, @NonNull String content) throws JSONException { + public List parseResponse(@NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); return GeoPolylineParserUtil.parse( obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), GeoPolylineParserUtil.PRECISION_5); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 0ba23f118a..89c17f1c2b 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -368,10 +368,6 @@ public class RouteProvider { res = findBROUTERRoute(params); } else if (params.mode.getRouteService() == RouteService.ONLINE) { res = findOnlineRoute(params); -// } else if (params.type == RouteService.ORS) { -// res = findORSRoute(params); -// } else if (params.type == RouteService.OSRM) { -// res = findOSRMRoute(params); } else if (params.mode.getRouteService() == RouteService.STRAIGHT || params.mode.getRouteService() == RouteService.DIRECT_TO) { res = findStraightRoute(params); @@ -1240,66 +1236,6 @@ public class RouteProvider { return points; } - private void appendOSRMLoc(StringBuilder uri, LatLon il) { - uri.append(";").append(il.getLongitude()); - uri.append(",").append(il.getLatitude()); - } - - protected RouteCalculationResult findOSRMRoute(RouteCalculationParams params) - throws MalformedURLException, IOException, JSONException { - // http://router.project-osrm.org/route/v1/driving/4.83,52.28;4.95,52.28 - List res = new ArrayList(); - StringBuilder uri = new StringBuilder(); - // possibly hide that API key because it is privacy of osmand - // A6421860EBB04234AB5EF2D049F2CD8F key is compromised - String scheme = ""; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { - scheme = "https"; - } else { - scheme = "http"; - } - uri.append(scheme + "://router.project-osrm.org/route/v1/driving/"); //$NON-NLS-1$ - uri.append(String.valueOf(params.start.getLongitude())); - uri.append(",").append(String.valueOf(params.start.getLatitude())); - if(params.intermediates != null && params.intermediates.size() > 0) { - for(LatLon il : params.intermediates) { - appendOSRMLoc(uri, il); - } - } - appendOSRMLoc(uri, params.end); -// to get more waypoints, add overview=full option -// uri.append("?overview=full") - - log.info("URL route " + uri); - - URLConnection connection = NetworkUtils.getHttpURLConnection(uri.toString()); - connection.setRequestProperty("User-Agent", Version.getFullVersion(params.ctx)); - StringBuilder content = new StringBuilder(); - BufferedReader rs = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String s; - while((s = rs.readLine()) != null) { - content.append(s); - } - JSONObject obj = new JSONObject(content.toString()); - try { - rs.close(); - } catch(IOException e){ - } - List route = GeoPolylineParserUtil.parse(obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), - GeoPolylineParserUtil.PRECISION_5); - if (route.isEmpty()) { - return new RouteCalculationResult("Route is empty"); - } - for (LatLon pt : route) { - WptPt wpt = new WptPt(); - wpt.lat = pt.getLatitude(); - wpt.lon = pt.getLongitude(); - res.add(createLocation(wpt)); - } - params.intermediates = null; - return new RouteCalculationResult(res, null, params, null, true); - } - protected RouteCalculationResult findBROUTERRoute(RouteCalculationParams params) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { int numpoints = 2 + (params.intermediates != null ? params.intermediates.size() : 0); From b11a264a42bbd67e08f59f044f78d48dd32fcc9e Mon Sep 17 00:00:00 2001 From: Joaquin Gonzalez Date: Sun, 10 Jan 2021 23:34:43 +0000 Subject: [PATCH 31/67] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 2b3d261317..58cbf94c92 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -4049,4 +4049,6 @@ Automóvil Error, vuelve a comprobar los parámetros Copiar dirección + Motor de ruta en línea + Motores de ruta en línea \ No newline at end of file From 21591f3276e369e17a5efc869526349f6f8fe587 Mon Sep 17 00:00:00 2001 From: Hakuchi Date: Sun, 10 Jan 2021 12:36:17 +0000 Subject: [PATCH 32/67] Translated using Weblate (German) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 95433700a5..35f7fb8f0a 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -738,7 +738,7 @@ OpenStreetMap-Bearbeitung Weitere Einstellungen Einstellungen - Karte aktualisieren + Aktualisieren Kartenteile aktualisieren Ziel Zu \'Favoriten\' hinzufügen From 0f8211d3de468e83cc84389d787735d67a790ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Sun, 10 Jan 2021 17:04:58 +0000 Subject: [PATCH 33/67] Translated using Weblate (Czech) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-cs/strings.xml | 177 ++++++++++++++++++------------- 1 file changed, 101 insertions(+), 76 deletions(-) diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 3159e5591a..20a7355927 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -275,7 +275,7 @@ Nastavte průhlednost (0 - průhledný, 255 - neprůhledný) Podkladová mapa… Podkresová mapa - Vyberte podkladovou mapu. + Vyberte podkladovou mapu Překryvná mapa… Žádná Překryvná mapa @@ -309,7 +309,9 @@ Sdílet polohu GPX bod na trase \'\'{0}\'\' byl přidán Přidat bod na zaznamenávanou GPX trasu - Off-line navigace je experimentální a funguje jen pro větší vzdálenosti než 20 km. Navigace je dočasně přepnuta na on-line CloudMade. + Off-line navigace je experimentální a funguje jen pro větší vzdálenosti než 20 km. +\n +\nNavigace je dočasně přepnuta na online službu CloudMade. Nepodařilo se najít zadaný adresář. Adresář pro data Aplikace pro zobrazení stavu GPS není nainstalovaná. Hledat v obchodě? @@ -440,7 +442,7 @@ Na šířku Orientace obrazovky Orientace obrazovky: na výšku, na šířku, podle zařízení. - Formát otevírací doby nemůže být změněn + Formát otevírací doby nemůže být změněn. Přidat nové pravidlo Cesty Zastávka @@ -459,8 +461,8 @@ Zobrazit zastávky Navigační aplikace OsmAnd Data POI byla aktualizována ({0} načteno) - Nelze aktualizovat lokální seznam POI - Nelze načíst data ze serveru + Nepodařilo se aktualizovat lokální seznam POI. + Nepodařilo se načíst data ze serveru. Pro tuto oblast nejsou dostupné žádné off-line POI Větší přiblížení vám umožní aktualizovat POI Aktualizovat POI @@ -482,11 +484,11 @@ Hledání off-line Hledat on-line Maximální zvětšení - Nelze procházet dlaždice online map pro přiblížení nad tuto úroveň. + Nepoužívat online mapy pro přiblížení nad tuto úroveň. Celková vzdálenost %1$s, doba cesty %2$d h %3$d min. - Vyberte online nebo offline navigační službu. + Online nebo offline navigační služba. Navigace - Úložný datový adresář na paměťové kartě není dostupný! + Úložný adresář na paměťové kartě není dostupný! Stáhnout {0} - {1} ? Offline data pro {0} již existují ({1}). Aktualizovat je ({2})\? Adresa @@ -500,7 +502,7 @@ Pouze zobrazit Spustit navádění Způsob dopravy: - Prosím zadejte nejprve cíl + Prosím nejprve zadejte cíl Navigace Otevírací doba Otevírání sady změn… @@ -515,14 +517,14 @@ Načítání ulic… Načítání měst… POI - Nelze uložit soubor GPX - Nelze vypočítat trasu - Nelze vypočítat trasu - Vypočtená trasa je prázdná + Nepodařilo se uložit soubor GPX. + Nepodařilo se vypočítat trasu. + Nepodařilo se vypočítat trasu. + Vypočítaná trasa je prázdná. Vypočtena nová trasa, vzdálenost - Dorazili jste do cíle + Dorazili jste do cíle. Neplatné souřadnice - Vrátit se k mapě OsmAnd + Vrátit se k mapě Zavřít Načítání dat… Načítání místních dat… @@ -559,15 +561,15 @@ Zorné pole Zapnout 3D pohled na mapu. 3D Mapa - Zobrazit naposledy vybrané POI jako vrstvu na mapě. + Zobrazit naposledy použité POI jako vrstvu. Zobrazit vrstvu POI - Zvolte zdroj on-line dlaždic nebo dlaždic v mezipaměti. + Zvolte zdroj online mapových dlaždic nebo dlaždic v mezipaměti. Zdroj rastrových map Zdroj map Používat Internet Zobrazit mou polohu Zobrazit GPS souřadnice na mapě - Stahovat chybějící části mapy z internetu + Stáhnout chybějící mapové dlaždice Navigační aplikace Konec Hledat @@ -586,11 +588,11 @@ Chůze Uprostřed Dole - Zadejte zem. šířku a délku ve vybraném formátu (D - stupně, M - minuty, S - vteřiny) + Zadejte zeměpisnou šířku a délku ve vybraném formátu (D - stupně, M - minuty, S - vteřiny) Šířka Délka Zobrazit na mapě - Zvolit adresu + Adresa Oblast Město Ulice @@ -621,7 +623,7 @@ Vymazat {0} (komentář) \? Vymazat POI Vymazat - POI byl vymazán + Smazáno Přidání Změna Akce {0} provedena. @@ -636,9 +638,9 @@ Vyčistit Filtr Uložit jako - Smazat vybraný filtr? - Filtr %1$s byl smazán - Filtr %1$s byl vytvořen + Smazat tento filtr\? + Filtr \'%1$s\' byl smazán + Filtr \'%1$s\' byl vytvořen Off-line navigace OsmAnd je dočasně nedostupná. Levostranný provoz Pro země, kde se jezdí po levé straně cesty. @@ -672,8 +674,8 @@ Kategorie Správce mapových souborů. DDD.DDDDD - DDD MM.MMMMM - DDD MM SS.SSSSS + DDD MM.MMM + DDD MM SS.S Navigační data Formát Hledat body zájmu (POI) @@ -1022,15 +1024,15 @@ Dopravní varování Heslo OSM (volitelné) Typ ostření fotoaparátu - Zvolte způsob ostření vestavěného fotoaparátu. + Režim zaostřování fotoaparátu: Automatické ostření Fix-focus Fix-focus - Ostření na nekonečno + Ostření je nastaveno na nekonečno Makro Kamera ostří souvisle Přehrát zvuk závěrky - Zvolte zda při vyfotografování snímku má být přehrán zvuk závěrky. + Nastavit zvuk či ticho při pořízení snímku. Mezicíle jsou již nastaveny. Navigovat sem Navigovat odsud @@ -1229,8 +1231,7 @@ Uložit jako skupinu Oblíbených Určete cíle Překryvné popisky bodů - - On-line OSM klasifikace map s obrázky. + On-line OSM klasifikace map s obrázky. Zobrazit tlačítka lupy během navigace. Zobrazit tlačítka lupy Třídit podle vzdálenosti @@ -1287,7 +1288,7 @@ Později V posledních metrech Velikost fotografie - Vyberte velikost obrázku interního fotoaparátu. + Nastavte velikost obrázku fotoaparátu Více… Standardní Automobil @@ -1442,12 +1443,12 @@ Exportovat Povolit Zakázat - Pro instalaci tohoto modulu je potřeba internetové připojení. + Pro instalaci tohoto modulu musíte být online. Získat Body cesty Simulovat polohu Šířka %1$s -Délka %2$s +\nDélka %2$s Nastavení navigace Všeobecná nastavení @@ -1589,11 +1590,11 @@ Délka %2$s Přidat otevírací dobu Kontaktní informace Máte rádi OsmAnd? - Záleží nám na vašem názoru, zpětná vazba je pro nás důležitá. + Oceníme váš názor a zpětnou vazbu. Ohodnoťte tuto aplikaci Ohodnoťte prosím aplikaci OsmAnd na Google Play Řekněte nám proč. - Sdělte nám prosím, co byste chtěli v této aplikaci změnit. + Sdělte nám prosím své návrhy. Přeskočit OsmAnd Moduly @@ -1612,7 +1613,7 @@ Délka %2$s Karta byla skryta Zpět Off-line mapy -& navigace +\n& navigace Odeslat POI Základní Rozšířené @@ -1836,7 +1837,7 @@ Délka %2$s Jednou týdně Ráno V noci - Vyberte měsíc a krajinu + Měsíc a země: Odstranit Ikony POI Vybrat @@ -1918,7 +1919,7 @@ Délka %2$s Doporučujeme vypnout vykreslování polygonů. Zobrazit trasy pro horská kola Aplikace nyní smí zapisovat na externí úložiště, ale je potřeba její restart. - Název souboru obsahuje nepovolené znaky + Nepovolený znak v názvu souboru Modul usnadnění: Cíl není nastaven Magnetické směrování Relativní směrování @@ -2112,20 +2113,20 @@ Délka %2$s Opravdu chcete odstranit akci \"%s\"? Zobrazit dialog Oblíbených Přednastavení názvu - Klepnutím na tlačítko akce se přidá mapová značka do středu obrazovky. - Klepnutím na tlačítko akce se přidá GPX bod trasy na místo ve středu obrazovky. - Klepnutím na tlačítko akce se přidá audio záznam na místo ve středu obrazovky. - Klepnutím na tlačítko akce se přidá video záznam na místo ve středu obrazovky. - Klepnutím na tlačítko akce se přidá foto záznam na místo ve středu obrazovky. - Klepnutím na tlačítko akce se přidá OSM poznámka na místo ve středu obrazovky. - Klepnutím na tlačítko akce se přidá POI na místo ve středu obrazovky. - Klepnutím na tlačítko akce se vypnou nebo zapnou hlasové pokyny během navigace. - Klepnutím na tlačítko akce se přidá parkovací místo do středu obrazovky. + Tlačítko pro přidání mapové značky do středu obrazovky. + Tlačítko pro přidání bodu GPX trasy do středu obrazovky. + Tlačítko pro přidání zvukové poznámky do středu obrazovky. + Tlačítko pro přidání video poznámky do středu obrazovky. + Tlačítko pro přidání foto poznámky do středu obrazovky. + Tlačítko pro přidání OSM poznámky do středu obrazovky. + Tlačítko pro přidání bodu zájmu do středu obrazovky. + Tlačítko pro vypnutí nebo zapnutí hlasových pokynů během navigace. + Tlačítko pro přidání místa zaparkování do středu obrazovky. Místo - Zadaný název rychlé akce je již použit a byl změněn na %1$s z důvodu duplicity. + Rychlá akce byla přejmenována na %1$s z důvodu duplicity. Duplicitní název rychlé akce - Klepnutím na tlačítko akce se zobrazí nebo skryjí Oblíbená místa na mapě. - Klepnutím na tlačítko akce se zobrazí nebo skryjí POI na mapě. + Tlačítko pro zobrazení nebo skrytí Oblíbených míst na mapě. + Tlačítko pro zobrazení nebo skrytí bodů zájmu na mapě. Zobrazit/skrýt Oblíbená místa Zobrazit oblíbená místa Skrýt Oblíbená místa @@ -2139,7 +2140,7 @@ Délka %2$s Ponecháte-li prázdné, bude použita adresa nebo název místa. Tato zpráva je zahrnuta v poli komentáře. Zpráva - Vyberte kategorii pro uložení Oblíbeného místa. + Kategorie pro uložení Oblíbeného místa: Vyberte volitelnou kategorii. Seznam POI Přidat jednu nebo více kategorií POI pro zobrazení na mapě. @@ -2155,23 +2156,23 @@ Délka %2$s Změnit zdroj mapy Mapové zdroje Přidat zdroj mapy - Zdroj mapy se změnil na \"%s\". + Zdroj mapy změněn na \"%s\". Změnit polohu tlačítka Podržení a potáhnutí tlačítka změní jeho umístění na obrazovce. Název akce Neplatný OLC - +\n Krátké OLC -Prosím uveďte úplný kód +\nProsím zadejte úplný kód Platné plné OLC -Zobrazená oblast: %1$s x %2$s - " je uložen do " - Překryvná mapa se změnila na \"%s\". - Mapa podkladu se změnila na \"%s\". +\nOdpovídá oblasti: %1$s x %2$s + " uložený do " + Překryvná mapa změněna na \"%s\". + Podkladová mapa změněna na \"%s\". Při pauze automaticky rozdělovat nahrávky Začít nový úsek po 6minutové pauze, novou trasu po 2hodinové pauze nebo nový soubor po delší pauze, pokud se změnilo datum. Zobrazit dočasné okno - Aktivace tlačítka akce posune seznam na další stranu. + Tlačítko pro posunutí seznamu na další stranu. Zobrazit hloubkové vrstevnice a body. Námořní hloubkové vrstevnice Open Location Code (OLC) @@ -2337,10 +2338,10 @@ Zobrazená oblast: %1$s x %2$s Měřit vzdálenost Časový zásobník pro online sledování Zadejte čas pro podržení pozic k odeslání, pokud není připojení - Pro zobrazení fotografií z Mapillary potřebujete internetové připojení. + Fotografie z Mapillary jsou dostupné pouze online. Zkusit znovu Přidat trasový bod - Uložit trasový bod GPX + Uložit bod GPX trasy Uložit bod trasy Trasový bod 1 Bod trasy 1 @@ -2564,7 +2565,8 @@ Zobrazená oblast: %1$s x %2$s \n• Svoji polohu můžete sdílet se svými přáteli \n• Důležitá místa si můžete uložit do složky \'Moje místa\' \n• Můžete si vybrat, jak se na mapě budou zobrazovat názvy: V angličtině, v místním jazyce nebo ve fonetickém přepisu -\n• Zobrazuje specializované online dlaždice, satelitní mapy (z Bingu), různé překryvné informace jako navigační GPX trasy a další vrstvy s volitelnou průhledností +\n• Zobrazuje specializované online dlaždice, satelitní mapy (z Bingu), různé překryvné informace jako navigační GPX trasy a další vrstvy s volitelnou průhledností +\n Lyžování \nOsmAnd plugin Lyžařský mapový pohled zobrazuje lyžařské trasy podle stupně obtížnosti a také další informace jako polohy vleků a dalších zařízení. Cyklistika @@ -2578,11 +2580,13 @@ Zobrazená oblast: %1$s x %2$s \n• Wikipedie ve vašem zvoleném jazyce vám poskytne mnoho informací při procházce městem \n• Při pohybu v neznámém městě vám pomůže zobrazování názvů zastávek a tras veřejné dopravy (autobusy, tramvaje, vlaky) \n• GPS navigace v režimu Pěší vytvoří trasu cest vhodných pro chodce -\n• Můžete otevřít GPX trasu a následovat ji nebo zaznamenat a sdílet svou vlastní +\n• Můžete otevřít GPX trasu a následovat ji nebo zaznamenat a sdílet svou vlastní +\n Přispějte do OSM \n• Hlaste chyby v datech \n•Nahrávejte GPX trasy do OSM přímo z aplikace -\n• Přidávejte body zájmu a rovnou je nahrávejte do OSM (nebo později, pokud jste zrovna offline) +\n• Přidávejte body zájmu a rovnou je nahrávejte do OSM (nebo později, pokud jste zrovna offline) +\n OsmAnd je aktivně vyvíjený open source software. Do aplikace může každý přispět hlášením chyb, vylepšováním překladů nebo programováním nových funkcí. Projekt je také závislý na finančních příspěvcích pro vývoj a testování nových funkcí. \n Přibližné pokrytí a kvalita map: \n • Západní Evropa: **** @@ -2609,7 +2613,8 @@ Zobrazená oblast: %1$s x %2$s \n• Volitelné navádění do jízdních pruhů, zobrazení názvů ulic a předpokládaného čas příjezdu \n• Podporuje mezicíle v itineráři \n• Automatické přepočítání trasy při odchýlení -\n• Hledání míst podle adresy, typu (např. restaurace, hotel, čerpací stanice, muzeum) či podle geografických souřadnic +\n• Hledání míst podle adresy, typu (např. restaurace, hotel, čerpací stanice, muzeum) či podle geografických souřadnic +\n Prohlížení mapy \n • Zobrazení vaší pozice a orientace \n • Volitelné otáčení podle směru vašeho pohybu (nebo podle kompasu) @@ -2630,7 +2635,8 @@ Zobrazená oblast: %1$s x %2$s \n• Volitelné automatické přepínání denního a nočního režimu \n• Volitelné zobrazení rychlostních limitů s upozorněním při překročení \n• Volitelné přiblížení mapy v závislosti na rychlosti -\n• Sdílení polohy s přáteli +\n• Sdílení polohy s přáteli +\n Funkce pro cyklisty a pěší \n• Zobrazení pěších, turistických a cyklistických tras, skvělé pro venkovní aktivity \n• Speciální navigační režim a zobrazení pro cyklisty a chodce @@ -2784,7 +2790,7 @@ Zobrazená oblast: %1$s x %2$s Průvodce Wikivoyage Vám ukáže nejzajímavější místa planety, přímo v aplikaci OsmAnd a bez nutnosti připojení k internetu. Čas příjezdu do mezicíle Do průjezdního bodu - Klepněte na tlačítko pro vyslechnutí odpovídajícího hlasového pokynu, aby jste zjistili chybné nebo chybějící pokyny. + Klepněte na tlačítko pro vyslechnutí odpovídajícího hlasového pokynu, abyste zjistili, zda chybí nebo je chybný Pro námořní navigaci. Obsahuje bóje, majáky, plavební cesty, mořské cesty a značky, přístavy, námořní služby a hloubkové vrstevnice. Pro lyžování. Obsahuje sjezdovky, lyžařské vleky, běžkařské trasy atd. Nedůležité objekty jsou na mapě méně výrazné. Vítejte v otevřené beta verzi @@ -2843,7 +2849,7 @@ Zobrazená oblast: %1$s x %2$s Používáte mapu {0}, která běží na aplikaci OsmAnd. Chcete spustit plnou verzi OsmAnd\? Spustit OsmAnd\? Guaranština - Klepnutím na tlačítko akce se přepíná mezi denním a nočním režimem OsmAnd + Tlačítko pro přepínání mezi denním a nočním režimem v OsmAnd. Denní režim Noční režim Přepnout denní/noční režim @@ -2886,7 +2892,7 @@ Zobrazená oblast: %1$s x %2$s Výjezd na Vyměnit Zobrazit/skrýt stopy - Tlačítko pro zobrazení nebo skrytí vybraných stop na mapě + Tlačítko pro zobrazení nebo skrytí vybraných stop na mapě. Skrýt stopy Zobrazit stopy %1$d přenosů @@ -2965,8 +2971,8 @@ Zobrazená oblast: %1$s x %2$s \n \n • Odstraněné analytické moduly Facebook a Firebase z verze zdarma (OsmAnd+ je neobsahoval) \n " - Vyhnout se kostkám - Vyhnout se kočičím hlavám a dlažebním kostkám + Žádné dlažební kostky + Vyhne se dlažebním kostkám Stupně Miliradiány Úhlová jednotka @@ -3068,10 +3074,10 @@ Zobrazená oblast: %1$s x %2$s Zvolte profily, které mají být viditelné v aplikaci. Profily aplikace Použít WunderLINQ pro ovládání - Musíte přidat alespoň jednu položku v nastavení Rychlé akce - Alpské/sjezdové lyžování + Přidejte alespoň jednu položku do seznamu \'Rychlá akce\' + Alpské a sjezdové lyžování Svahy pro alpské nebo sjezdové lyžování a přístup k lyžařským vlekům. - Běžecké a severské lyžování + Běžecké a klasické lyžování Trasy pro severské nebo běžecké lyžování. Lyžařské okruhy Trasy pro lyžařské okruhy. @@ -3556,7 +3562,7 @@ Zobrazená oblast: %1$s x %2$s Stopy Stopy Stopy - "Ukládat trasu do GPX souboru" + Ukládat trasu do GPX souboru Trasa ze stopy Přidat soubory stop Zjednodušená trasa @@ -4014,4 +4020,23 @@ Zobrazená oblast: %1$s x %2$s Povolit říčky a stoky Povolit občasné vodní cesty Povolit občasné vodní cesty + Časy hlasových pokynů + Přidat online navigační službu + Upravit online navigační službu + Podtyp + Vozidlo + API klíč + URL serveru + Zadejte parametr + Pokud ne, nechte prázdné + Adresa se všemi parametry bude vypadat takto: + Vyzkoušet výpočet trasy + Řízení vozidla + Chůze + Kolo + Auto + Chyba, zkontrolujte parametry + Kopírovat adresu + Online navigační služba + Online navigační služby \ No newline at end of file From 93488e51a05ad493aa9deeff8a628a21cd8940e0 Mon Sep 17 00:00:00 2001 From: syl Date: Sun, 10 Jan 2021 09:23:29 +0000 Subject: [PATCH 34/67] Translated using Weblate (French) Currently translated at 100.0% (3881 of 3881 strings) --- OsmAnd/res/values-fr/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fr/phrases.xml b/OsmAnd/res/values-fr/phrases.xml index 83c34749e1..e2b1ca9638 100644 --- a/OsmAnd/res/values-fr/phrases.xml +++ b/OsmAnd/res/values-fr/phrases.xml @@ -512,7 +512,7 @@ Football canadien Cyclisme Tir - Psychothérapeute + Kinésithérapeute Ergothérapeute Ferme Jardins familiaux From da3473b838b42ab6f8474d24ef0d140e0a6cc888 Mon Sep 17 00:00:00 2001 From: Franco Date: Mon, 11 Jan 2021 00:01:26 +0000 Subject: [PATCH 35/67] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 58cbf94c92..3b49991789 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -4050,5 +4050,5 @@ Error, vuelve a comprobar los parámetros Copiar dirección Motor de ruta en línea - Motores de ruta en línea + Motores de navegación en línea \ No newline at end of file From 7a1517fc3d5296d7954daa857ef62fcf794ab7ce Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 02:22:24 +0200 Subject: [PATCH 36/67] Fix #10068 --- OsmAnd/res/values/strings.xml | 3 + .../AddNewTrackFolderBottomSheet.java | 158 ++++++++++++++++++ .../plus/myplaces/AvailableGPXFragment.java | 153 +++-------------- .../plus/myplaces/MoveGpxFileBottomSheet.java | 151 +++++++++++++++++ .../ElevationDateBottomSheet.java | 3 +- 5 files changed, 336 insertions(+), 132 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java create mode 100644 OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 47645eb555..765b81de75 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,9 @@ --> + Select folder or add new one + Select folder + Folders Online routing engines Online routing engine Copy address diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java b/OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java new file mode 100644 index 0000000000..584ba75339 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java @@ -0,0 +1,158 @@ +package net.osmand.plus.myplaces; + +import android.content.res.ColorStateList; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; + +import net.osmand.AndroidUtils; +import net.osmand.IndexConstants; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; + +import java.io.File; + +import static net.osmand.FileUtils.ILLEGAL_PATH_NAME_CHARACTERS; + +public class AddNewTrackFolderBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = AddNewTrackFolderBottomSheet.class.getName(); + private static final Log LOG = PlatformUtil.getLog(AddNewTrackFolderBottomSheet.class); + private static final String FOLDER_NAME_KEY = "folder_name_key"; + + private OsmandApplication app; + + private TextInputEditText editText; + private TextInputLayout nameTextBox; + + private String folderName; + private boolean rightButtonEnabled = true; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + if (savedInstanceState != null) { + folderName = savedInstanceState.getString(FOLDER_NAME_KEY); + } else if (Algorithms.isEmpty(folderName)) { + folderName = app.getAppPath(IndexConstants.GPX_INDEX_DIR).getName(); + } + items.add(new TitleItem(getString(R.string.add_new_folder))); + + View view = UiUtilities.getInflater(app, nightMode).inflate(R.layout.track_name_edit_text, null); + nameTextBox = view.findViewById(R.id.name_text_box); + nameTextBox.setBoxBackgroundColorResource(nightMode ? R.color.list_background_color_dark : R.color.activity_background_color_light); + nameTextBox.setHint(AndroidUtils.addColon(app, R.string.shared_string_name)); + ColorStateList colorStateList = ColorStateList.valueOf(ContextCompat + .getColor(app, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light)); + nameTextBox.setDefaultHintTextColor(colorStateList); + TextInputEditText nameText = view.findViewById(R.id.name_edit_text); + nameText.setText(folderName); + nameText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + updateFileNameFromEditText(s.toString()); + } + }); + BaseBottomSheetItem editFolderName = new BaseBottomSheetItem.Builder() + .setCustomView(view) + .create(); + items.add(editFolderName); + } + + @Override + protected boolean isRightBottomButtonEnabled() { + return rightButtonEnabled; + } + + private void updateFileNameFromEditText(String name) { + rightButtonEnabled = false; + if (ILLEGAL_PATH_NAME_CHARACTERS.matcher(name).find()) { + nameTextBox.setError(getString(R.string.file_name_containes_illegal_char)); + } else if (Algorithms.isEmpty(name.trim())) { + nameTextBox.setError(getString(R.string.empty_filename)); + } else { + File destFolder = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), name); + if (destFolder.exists()) { + nameTextBox.setError(getString(R.string.file_with_name_already_exist)); + } else { + nameTextBox.setError(null); + folderName = name; + rightButtonEnabled = true; + } + } + updateBottomButtons(); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putString(FOLDER_NAME_KEY, folderName); + super.onSaveInstanceState(outState); + } + + @Override + protected void onRightBottomButtonClick() { + AndroidUtils.hideSoftKeyboard(requireActivity(), editText); + Fragment fragment = getTargetFragment(); + if (fragment instanceof OnTrackFolderAddListener) { + OnTrackFolderAddListener listener = (OnTrackFolderAddListener) fragment; + listener.onTrackFolderAdd(folderName); + } + dismiss(); + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected int getRightBottomButtonTextId() { + return R.string.shared_string_add; + } + + public interface OnTrackFolderAddListener { + + void onTrackFolderAdd(String folderName); + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @Nullable Fragment target, + @NonNull String folderName, boolean usedOnMap) { + try { + if (!fragmentManager.isStateSaved() && fragmentManager.findFragmentByTag(AddNewTrackFolderBottomSheet.TAG) == null) { + AddNewTrackFolderBottomSheet fragment = new AddNewTrackFolderBottomSheet(); + fragment.folderName = folderName; + fragment.setUsedOnMap(usedOnMap); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, AddNewTrackFolderBottomSheet.TAG); + } + } catch (RuntimeException e) { + LOG.error("showInstance", e); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 9e4ac656a4..4fc2e309fc 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -13,8 +13,6 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.text.Editable; -import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -27,7 +25,6 @@ import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; -import android.widget.EditText; import android.widget.ExpandableListView; import android.widget.Filter; import android.widget.Filterable; @@ -42,6 +39,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ActionMode; import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.Collator; @@ -81,11 +79,12 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; import net.osmand.plus.helpers.enums.TracksSortByMode; import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; +import net.osmand.plus.myplaces.MoveGpxFileBottomSheet.OnTrackFileMoveListener; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.oauth.OsmOAuthHelper.OsmAuthorizationListener; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.widgets.popup.PopUpMenuItem; import net.osmand.plus.widgets.popup.PopUpMenuHelper; +import net.osmand.plus.widgets.popup.PopUpMenuItem; import java.io.File; import java.text.DateFormat; @@ -101,21 +100,18 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.regex.Pattern; import static net.osmand.plus.GpxSelectionHelper.CURRENT_TRACK; import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; import static net.osmand.util.Algorithms.capitalizeFirstLetter; -import static net.osmand.util.Algorithms.collectDirs; import static net.osmand.util.Algorithms.formatDuration; import static net.osmand.util.Algorithms.objectEquals; import static net.osmand.util.Algorithms.removeAllFiles; public class AvailableGPXFragment extends OsmandExpandableListFragment implements - FavoritesFragmentStateHolder, OsmAuthorizationListener { + FavoritesFragmentStateHolder, OsmAuthorizationListener, OnTrackFileMoveListener { - public static final Pattern ILLEGAL_PATH_NAME_CHARACTERS = Pattern.compile("[?:\"*|<>]"); public static final int SEARCH_ID = -1; // public static final int ACTION_ID = 0; // protected static final int DELETE_ACTION_ID = 1; @@ -790,129 +786,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } private void moveGpx(final GpxInfo info) { - - final ContextMenuAdapter menuAdapter = new ContextMenuAdapter(app); - ContextMenuItem.ItemBuilder itemBuilder = new ContextMenuItem.ItemBuilder(); - - final List dirs = new ArrayList<>(); - collectDirs(app.getAppPath(IndexConstants.GPX_INDEX_DIR), dirs, info.file.getParentFile()); - if (!info.file.getParentFile().equals(app.getAppPath(IndexConstants.GPX_INDEX_DIR))) { - dirs.add(0, app.getAppPath(IndexConstants.GPX_INDEX_DIR)); + FragmentActivity activity = getActivity(); + if (activity != null) { + MoveGpxFileBottomSheet.showInstance(activity.getSupportFragmentManager(), this, info.file.getAbsolutePath(), false); } - String gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR).getPath(); - int i = 0; - for (File dir : dirs) { - String dirName = dir.getPath(); - if (dirName.startsWith(gpxDir)) { - if (dirName.length() == gpxDir.length()) { - dirName = dir.getName(); - } else { - dirName = dirName.substring(gpxDir.length() + 1); - } - } - menuAdapter.addItem(itemBuilder.setTitle(capitalizeFirstLetter(dirName)) - .setIcon(R.drawable.ic_action_folder_stroke).setTag(i).createItem()); - i++; - } - menuAdapter.addItem(itemBuilder.setTitleId(R.string.add_new_folder, app) - .setIcon(R.drawable.ic_zoom_in).setTag(-1).createItem()); - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - final ArrayAdapter listAdapter = - menuAdapter.createListAdapter(getActivity(), app.getSettings().isLightContent()); - builder.setTitle(R.string.select_gpx_folder); - builder.setAdapter(listAdapter, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - ContextMenuItem item = menuAdapter.getItem(which); - int index = item.getTag(); - if (index == -1) { - Activity a = getActivity(); - AlertDialog.Builder b = new AlertDialog.Builder(a); - b.setTitle(R.string.add_new_folder); - final EditText editText = new EditText(a); - editText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - Editable text = editText.getText(); - if (text.length() >= 1) { - if (ILLEGAL_PATH_NAME_CHARACTERS.matcher(text).find()) { - editText.setError(app.getString(R.string.file_name_containes_illegal_char)); - } - } - } - }); - int leftPadding = AndroidUtils.dpToPx(a, 24f); - int topPadding = AndroidUtils.dpToPx(a, 4f); - b.setView(editText, leftPadding, topPadding, leftPadding, topPadding); - // Behaviour will be overwritten later; - b.setPositiveButton(R.string.shared_string_ok, null); - b.setNegativeButton(R.string.shared_string_cancel, null); - final AlertDialog alertDialog = b.create(); - alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { - @Override - public void onShow(DialogInterface dialog) { - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - String newName = editText.getText().toString(); - if (ILLEGAL_PATH_NAME_CHARACTERS.matcher(newName).find()) { - Toast.makeText(app, R.string.file_name_containes_illegal_char, - Toast.LENGTH_LONG).show(); - return; - } - File destFolder = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), newName); - if (destFolder.exists()) { - Toast.makeText(app, R.string.file_with_name_already_exists, - Toast.LENGTH_LONG).show(); - return; - } else if (destFolder.mkdirs()) { - File dest = new File(destFolder, info.fileName); - if (info.file.renameTo(dest)) { - app.getGpxDbHelper().rename(info.file, dest); - asyncLoader = new LoadGpxTask(); - asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity()); - } else { - Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); - } - - } else { - Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); - } - alertDialog.dismiss(); - } - }); - } - }); - alertDialog.show(); - } else { - File dir = dirs.get(index); - File dest = new File(dir, info.file.getName()); - if (dest.exists()) { - Toast.makeText(app, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show(); - } else { - if (info.file.renameTo(dest)) { - app.getGpxDbHelper().rename(info.file, dest); - asyncLoader = new LoadGpxTask(); - asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity()); - } else { - Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); - } - } - } - } - }); - builder.setNegativeButton(R.string.shared_string_cancel, null); - builder.create().show(); } @Override @@ -938,6 +815,22 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement app.startActivity(intent); } + @Override + public void onFileMove(@NonNull File src, @NonNull File dest) { + File destFolder = dest.getParentFile(); + if (destFolder != null && !destFolder.exists() && !destFolder.mkdirs()) { + app.showToastMessage(R.string.file_can_not_be_moved); + } else if (dest.exists()) { + app.showToastMessage(R.string.file_with_name_already_exists); + } else if (src.renameTo(dest)) { + app.getGpxDbHelper().rename(src, dest); + asyncLoader = new LoadGpxTask(); + asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity()); + } else { + app.showToastMessage(R.string.file_can_not_be_moved); + } + } + public class LoadGpxTask extends AsyncTask> { private List result; diff --git a/OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java new file mode 100644 index 0000000000..50450ad19c --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java @@ -0,0 +1,151 @@ +package net.osmand.plus.myplaces; + +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + +import net.osmand.IndexConstants; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.SubtitleItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; +import net.osmand.plus.myplaces.AddNewTrackFolderBottomSheet.OnTrackFolderAddListener; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.util.Algorithms.capitalizeFirstLetter; +import static net.osmand.util.Algorithms.collectDirs; + +public class MoveGpxFileBottomSheet extends MenuBottomSheetDialogFragment implements OnTrackFolderAddListener { + + public static final String TAG = MoveGpxFileBottomSheet.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(MoveGpxFileBottomSheet.class); + private static final String FILE_PATH_KEY = "file_path_key"; + + private OsmandApplication app; + private String filePath; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + if (savedInstanceState != null) { + filePath = savedInstanceState.getString(FILE_PATH_KEY); + } + if (filePath == null) { + return; + } + final File file = new File(filePath); + final File fileDir = file.getParentFile(); + + items.add(new TitleItem(getString(R.string.shared_string_folders))); + items.add(new SubtitleItem(getString(R.string.select_folder_descr))); + + BaseBottomSheetItem addNewFolderItem = new SimpleBottomSheetItem.Builder() + .setTitle(getString(R.string.add_new_folder)) + .setIcon(getActiveIcon(R.drawable.ic_action_folder_add)) + .setLayoutId(R.layout.bottom_sheet_item_simple) + .setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity activity = getActivity(); + if (activity != null) { + AddNewTrackFolderBottomSheet.showInstance(activity.getSupportFragmentManager(), + MoveGpxFileBottomSheet.this, fileDir.getName(), usedOnMap); + } + } + }) + .create(); + items.add(addNewFolderItem); + items.add(new DividerItem(app)); + + final List dirs = new ArrayList<>(); + collectDirs(app.getAppPath(IndexConstants.GPX_INDEX_DIR), dirs, fileDir); + if (!Algorithms.objectEquals(fileDir, app.getAppPath(IndexConstants.GPX_INDEX_DIR))) { + dirs.add(0, app.getAppPath(IndexConstants.GPX_INDEX_DIR)); + } + String gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR).getPath(); + for (final File dir : dirs) { + String dirName = dir.getPath(); + if (dirName.startsWith(gpxDir)) { + if (dirName.length() == gpxDir.length()) { + dirName = dir.getName(); + } else { + dirName = dirName.substring(gpxDir.length() + 1); + } + } + + final BaseBottomSheetItem[] folderItem = new BaseBottomSheetItem[1]; + folderItem[0] = new SimpleBottomSheetItem.Builder() + .setTitle(capitalizeFirstLetter(dirName)) + .setIcon(getActiveIcon(R.drawable.ic_action_folder)) + .setLayoutId(R.layout.bottom_sheet_item_simple) + .setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + Fragment fragment = getTargetFragment(); + if (fragment instanceof OnTrackFileMoveListener) { + OnTrackFileMoveListener listener = (OnTrackFileMoveListener) fragment; + listener.onFileMove(file, new File(dir, file.getName())); + } + dismiss(); + } + }) + .setTag(dir) + .create(); + items.add(folderItem[0]); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(FILE_PATH_KEY, filePath); + } + + @Override + public void onTrackFolderAdd(String folderName) { + Fragment fragment = getTargetFragment(); + if (fragment instanceof OnTrackFileMoveListener) { + File file = new File(filePath); + File destFolder = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), folderName); + OnTrackFileMoveListener listener = (OnTrackFileMoveListener) fragment; + listener.onFileMove(file, new File(destFolder, file.getName())); + } + dismiss(); + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @Nullable Fragment target, + @NonNull String filePath, boolean usedOnMap) { + try { + if (!fragmentManager.isStateSaved() && fragmentManager.findFragmentByTag(MoveGpxFileBottomSheet.TAG) == null) { + MoveGpxFileBottomSheet fragment = new MoveGpxFileBottomSheet(); + fragment.filePath = filePath; + fragment.setUsedOnMap(usedOnMap); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, MoveGpxFileBottomSheet.TAG); + } + } catch (RuntimeException e) { + LOG.error("showInstance", e); + } + } + + public interface OnTrackFileMoveListener { + void onFileMove(@NonNull File src, @NonNull File dest); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java index 0d5d990eaf..427bda7521 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java @@ -2,7 +2,6 @@ package net.osmand.plus.settings.bottomsheets; import android.content.Context; import android.os.Bundle; -import android.os.Handler; import android.view.View; import android.widget.TextView; @@ -255,7 +254,7 @@ public class ElevationDateBottomSheet extends MenuBottomSheetDialogFragment { fragment.appMode = appMode; fragment.setUsedOnMap(usedOnMap); fragment.setTargetFragment(target, 0); - fragment.show(fm, ScreenTimeoutBottomSheet.TAG); + fragment.show(fm, ElevationDateBottomSheet.TAG); } } catch (RuntimeException e) { LOG.error("showInstance", e); From ee1bfd928e699e41a83fff4ebd90194caeaeee5e Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 11 Jan 2021 02:58:18 +0200 Subject: [PATCH 37/67] fix conflicts, refactoring, add Openroute Service support --- .../osmand/plus/onlinerouting/EngineType.java | 24 +++++ .../onlinerouting/OnlineRoutingEngine.java | 19 ---- .../OnlineRoutingEngineFragment.java | 21 +++-- .../onlinerouting/OnlineRoutingHelper.java | 90 ++++++++++++++++++- .../plus/onlinerouting/type/EngineType.java | 51 ----------- .../onlinerouting/type/GraphhoperEngine.java | 61 ------------- .../plus/onlinerouting/type/OsrmEngine.java | 53 ----------- .../backup/OnlineRoutingSettingsItem.java | 6 +- 8 files changed, 123 insertions(+), 202 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java new file mode 100644 index 0000000000..3362a4e499 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java @@ -0,0 +1,24 @@ +package net.osmand.plus.onlinerouting; + +public enum EngineType { + + GRAPHHOPER("Graphhoper", "https://graphhopper.com/api/1/route"), + OSRM("OSRM", "https://router.project-osrm.org/route/v1/"), + ORS("Openroute Service", "https://api.openrouteservice.org/v2/directions/"); + + private String title; + private String standardUrl; + + EngineType(String title, String standardUrl) { + this.title = title; + this.standardUrl = standardUrl; + } + + public String getTitle() { + return title; + } + + public String getStandardUrl() { + return standardUrl; + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java index 29fbf82711..3193d86d09 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java @@ -5,13 +5,10 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.data.LatLon; import net.osmand.plus.R; -import net.osmand.plus.onlinerouting.type.EngineType; import net.osmand.util.Algorithms; import java.util.HashMap; -import java.util.List; import java.util.Map; public class OnlineRoutingEngine { @@ -29,8 +26,6 @@ public class OnlineRoutingEngine { private String vehicleKey; private Map params = new HashMap<>(); - private OnlineRoutingEngine() {}; - public OnlineRoutingEngine(@NonNull String stringKey, @NonNull EngineType type, @NonNull String vehicleKey, @@ -44,12 +39,7 @@ public class OnlineRoutingEngine { public OnlineRoutingEngine(@NonNull String stringKey, @NonNull EngineType type, @NonNull String vehicleKey) { - this(type, vehicleKey); this.stringKey = stringKey; - } - - private OnlineRoutingEngine(@NonNull EngineType type, - @NonNull String vehicleKey) { this.type = type; this.vehicleKey = vehicleKey; } @@ -95,10 +85,6 @@ public class OnlineRoutingEngine { } } - public String createFullUrl(@NonNull List path) { - return type.createFullUrl(this, path); - } - private String getStandardName(@NonNull Context ctx) { return getStandardName(ctx, type, vehicleKey); } @@ -117,11 +103,6 @@ public class OnlineRoutingEngine { return new OnlineRoutingEngine(generateKey(), type, vehicleKey, params); } - public static OnlineRoutingEngine createTmpEngine(@NonNull EngineType type, - @NonNull String vehicleKey) { - return new OnlineRoutingEngine(type, vehicleKey); - } - private static String generateKey() { return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index ba6c4ceb75..cb70a8ca48 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -31,9 +31,6 @@ import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; import net.osmand.plus.onlinerouting.OnlineRoutingCard.OnTextChangedListener; import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; -import net.osmand.plus.onlinerouting.type.EngineType; -import net.osmand.plus.onlinerouting.type.GraphhoperEngine; -import net.osmand.plus.onlinerouting.type.OsrmEngine; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; @@ -190,7 +187,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { @Override public boolean processResult(HorizontalSelectionItem result) { EngineType type = (EngineType) result.getObject(); - if (!Algorithms.objectEquals(engine.type.getStringKey(), type.getStringKey())) { + if (engine.type != type) { engine.type = type; updateCardViews(nameCard, typeCard, exampleCard); return true; @@ -358,7 +355,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } else if (typeCard.equals(card)) { typeCard.setHeaderSubtitle(engine.type.getTitle()); typeCard.setEditedText(engine.getBaseUrl()); - if (engine.type instanceof GraphhoperEngine) { + if (engine.type == EngineType.GRAPHHOPER || engine.type == EngineType.ORS) { apiKeyCard.show(); } else { apiKeyCard.hide(); @@ -417,7 +414,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { engineToSave.putParameter(EngineParameter.CUSTOM_NAME, engine.customName); engineToSave.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); - if (engine.type instanceof GraphhoperEngine) { + if (engine.type == EngineType.GRAPHHOPER || engine.type == EngineType.ORS) { engineToSave.putParameter(EngineParameter.API_KEY, engine.apiKey); } @@ -433,10 +430,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { path.add(selectedLocation.getCityCenterLatLon()); path.add(selectedLocation.getCityAirportLatLon()); OnlineRoutingEngine tmpEngine = - OnlineRoutingEngine.createTmpEngine(engine.type, engine.getVehicleKey()); + OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey(), null); tmpEngine.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); tmpEngine.putParameter(EngineParameter.API_KEY, engine.apiKey); - return tmpEngine.createFullUrl(path); + return helper.createFullUrl(tmpEngine, path); } private void testEngineWork() { @@ -451,10 +448,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { try { JSONObject obj = new JSONObject(response); - if (type instanceof GraphhoperEngine) { + if (type == EngineType.GRAPHHOPER) { resultOk = obj.has("paths"); - } else if (type instanceof OsrmEngine) { + } else if (type == EngineType.OSRM) { resultOk = obj.has("routes"); + } else if (type == EngineType.ORS) { + resultOk = obj.has("features"); } } catch (JSONException e) { @@ -492,7 +491,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void saveState(Bundle outState) { outState.putString(ENGINE_NAME_KEY, engine.customName); - outState.putString(ENGINE_SERVER_KEY, engine.type.getStringKey()); + outState.putString(ENGINE_SERVER_KEY, engine.type.name()); outState.putString(ENGINE_SERVER_URL_KEY, engine.customServerUrl); outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 81f177d4f3..70226a0e25 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -10,9 +10,10 @@ import net.osmand.data.LatLon; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.Version; -import net.osmand.plus.onlinerouting.type.EngineType; +import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; +import net.osmand.util.GeoPolylineParserUtil; import org.apache.commons.logging.Log; import org.json.JSONArray; @@ -55,9 +56,90 @@ public class OnlineRoutingHelper { public List calculateRouteOnline(@NonNull OnlineRoutingEngine engine, @NonNull List path) throws IOException, JSONException { - String fullUrl = engine.createFullUrl(path); + String fullUrl = createFullUrl(engine, path); String content = makeRequest(fullUrl); - return engine.getType().parseResponse(content); + return parseResponse(engine, content); + } + + public String createFullUrl(OnlineRoutingEngine engine, List path) { + StringBuilder sb = new StringBuilder(engine.getBaseUrl()); + String vehicle = engine.getVehicleKey(); + String apiKey = engine.getParameter(EngineParameter.API_KEY); + switch (engine.getType()) { + + case GRAPHHOPER: + sb.append("?"); + for (LatLon point : path) { + sb.append("point=") + .append(point.getLatitude()) + .append(',') + .append(point.getLongitude()) + .append('&'); + } + sb.append("vehicle=").append(vehicle); + + if (!Algorithms.isEmpty(apiKey)) { + sb.append('&').append("key=").append(apiKey); + } + break; + + case OSRM: + sb.append(vehicle).append('/'); + for (int i = 0; i < path.size(); i++) { + LatLon point = path.get(i); + sb.append(point.getLongitude()).append(',').append(point.getLatitude()); + if (i < path.size() - 1) { + sb.append(';'); + } + } + break; + + case ORS: + if (path.size() > 1) { + sb.append("driving-car").append('?'); // todo only for testing + if (!Algorithms.isEmpty(apiKey)) { + sb.append("api_key=").append(apiKey); + } + LatLon start = path.get(0); + LatLon end = path.get(path.size() - 1); + sb.append('&').append("start=") + .append(start.getLatitude()).append(',').append(start.getLongitude()); + sb.append('&').append("end=") + .append(end.getLatitude()).append(',').append(end.getLongitude()); + } + break; + + } + return sb.toString(); + } + + private List parseResponse(OnlineRoutingEngine engine, String content) throws JSONException { + JSONObject obj = new JSONObject(content); + + switch (engine.getType()) { + case GRAPHHOPER: + return GeoPolylineParserUtil.parse( + obj.getJSONArray("paths").getJSONObject(0).getString("points"), + GeoPolylineParserUtil.PRECISION_5); + + case OSRM: + return GeoPolylineParserUtil.parse( + obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), + GeoPolylineParserUtil.PRECISION_5); + + case ORS: + JSONArray array = obj.getJSONArray("features").getJSONObject(0) + .getJSONObject("geometry").getJSONArray("coordinates"); + List track = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + JSONArray point = array.getJSONArray(i); + double lat = Double.parseDouble(point.getString(0)); + double lon = Double.parseDouble(point.getString(1)); + track.add(new LatLon(lat, lon)); + } + return track; + } + return new ArrayList<>(); } private String makeRequest(String url) throws IOException { @@ -161,7 +243,7 @@ public class OnlineRoutingHelper { for (OnlineRoutingEngine engine : engines) { JSONObject jsonObject = new JSONObject(); jsonObject.put("key", engine.getStringKey()); - jsonObject.put("type", engine.getType().getStringKey()); + jsonObject.put("type", engine.getType().name()); jsonObject.put("vehicle", engine.getVehicleKey()); jsonObject.put("params", gson.toJson(engine.getParams(), type)); jsonArray.put(jsonObject); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java deleted file mode 100644 index 2ef77e2c43..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/type/EngineType.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.osmand.plus.onlinerouting.type; - -import androidx.annotation.NonNull; - -import net.osmand.data.LatLon; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine; -import net.osmand.util.Algorithms; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.List; - -public abstract class EngineType { - - public abstract String getStringKey(); - - public abstract String getTitle(); - - public abstract String getStandardUrl(); - - public String createFullUrl(OnlineRoutingEngine engine, List path) { - StringBuilder sb = new StringBuilder(engine.getBaseUrl()); - createFullUrl(sb, engine, path); - return sb.toString(); - } - - protected abstract void createFullUrl(StringBuilder sb, - OnlineRoutingEngine engine, - List path); - - public abstract List parseResponse(@NonNull String content) throws JSONException; - - public static EngineType[] values() { - EngineType[] types = new EngineType[] { - new GraphhoperEngine(), - new OsrmEngine() - }; - return types; - } - - public static EngineType valueOf(String key) { - EngineType[] values = values(); - for (EngineType type : values) { - if (Algorithms.objectEquals(type.getStringKey(), key)) { - return type; - } - } - return values[0]; - } -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java deleted file mode 100644 index a315eb457b..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/type/GraphhoperEngine.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.osmand.plus.onlinerouting.type; - -import androidx.annotation.NonNull; - -import net.osmand.data.LatLon; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; -import net.osmand.util.Algorithms; -import net.osmand.util.GeoPolylineParserUtil; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.List; - -public class GraphhoperEngine extends EngineType { - - @Override - public String getStringKey() { - return "graphhoper"; - } - - @Override - public String getTitle() { - return "Graphhoper"; - } - - @Override - public String getStandardUrl() { - return "https://graphhopper.com/api/1/route"; - } - - @Override - protected void createFullUrl(StringBuilder sb, - OnlineRoutingEngine engine, - List path) { - sb.append("?"); - for (LatLon point : path) { - sb.append("point=") - .append(point.getLatitude()) - .append(',') - .append(point.getLongitude()) - .append('&'); - } - sb.append("vehicle=").append(engine.getVehicleKey()); - - String apiKey = engine.getParameter(EngineParameter.API_KEY); - if (!Algorithms.isEmpty(apiKey)) { - sb.append('&').append("key=").append(apiKey); - } - } - - @Override - public List parseResponse(@NonNull String content) throws JSONException { - JSONObject obj = new JSONObject(content); - return GeoPolylineParserUtil.parse( - obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), - GeoPolylineParserUtil.PRECISION_5); - } - -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java deleted file mode 100644 index 20cf6f00b4..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/type/OsrmEngine.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.osmand.plus.onlinerouting.type; - -import androidx.annotation.NonNull; - -import net.osmand.data.LatLon; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine; -import net.osmand.util.GeoPolylineParserUtil; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.List; - -public class OsrmEngine extends EngineType { - - @Override - public String getStringKey() { - return "osrm"; - } - - @Override - public String getTitle() { - return "OSRM"; - } - - @Override - public String getStandardUrl() { - return "https://router.project-osrm.org/route/v1/"; - } - - @Override - protected void createFullUrl(StringBuilder sb, - OnlineRoutingEngine engine, - List path) { - sb.append(engine.getVehicleKey()).append('/'); - for (int i = 0; i < path.size(); i++) { - LatLon point = path.get(i); - sb.append(point.getLongitude()).append(',').append(point.getLatitude()); - if (i < path.size() - 1) { - sb.append(';'); - } - } - } - - @Override - public List parseResponse(@NonNull String content) throws JSONException { - JSONObject obj = new JSONObject(content); - return GeoPolylineParserUtil.parse( - obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), - GeoPolylineParserUtil.PRECISION_5); - } - -} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java index e5ae306cf0..779a97d1df 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java @@ -8,7 +8,7 @@ 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.OnlineRoutingEngine.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import org.json.JSONException; @@ -93,8 +93,8 @@ public class OnlineRoutingSettingsItem extends CollectionSettingsItem Date: Mon, 11 Jan 2021 02:59:26 +0200 Subject: [PATCH 38/67] small refactoring --- .../src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 70226a0e25..6e61c3d444 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -117,6 +117,7 @@ public class OnlineRoutingHelper { JSONObject obj = new JSONObject(content); switch (engine.getType()) { + case GRAPHHOPER: return GeoPolylineParserUtil.parse( obj.getJSONArray("paths").getJSONObject(0).getString("points"), From f2f2d57a61bc5fe4e904194faa04442ecd374a52 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 04:16:22 +0200 Subject: [PATCH 39/67] Move gpx UI polishing --- ...ttom_sheet_item_title_with_description.xml | 44 ++++++++++ OsmAnd/res/layout/select_folder_row.xml | 44 ++++++++++ OsmAnd/res/values/strings.xml | 1 + ...veAsNewTrackBottomSheetDialogFragment.java | 84 ++++++++++++++++--- .../adapter/FolderListAdapter.java | 24 ++---- .../plus/myplaces/MoveGpxFileBottomSheet.java | 50 +++++++++-- 6 files changed, 210 insertions(+), 37 deletions(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_item_title_with_description.xml create mode 100644 OsmAnd/res/layout/select_folder_row.xml diff --git a/OsmAnd/res/layout/bottom_sheet_item_title_with_description.xml b/OsmAnd/res/layout/bottom_sheet_item_title_with_description.xml new file mode 100644 index 0000000000..9ffaa2e9dd --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_item_title_with_description.xml @@ -0,0 +1,44 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/select_folder_row.xml b/OsmAnd/res/layout/select_folder_row.xml new file mode 100644 index 0000000000..d9340cc5f2 --- /dev/null +++ b/OsmAnd/res/layout/select_folder_row.xml @@ -0,0 +1,44 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 765b81de75..c499d54b5c 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + Empty Select folder or add new one Select folder Folders diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java index 5b4058f339..90cbd1446e 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveAsNewTrackBottomSheetDialogFragment.java @@ -8,6 +8,7 @@ import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.View; +import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.Toast; @@ -16,13 +17,16 @@ import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; @@ -35,12 +39,17 @@ import net.osmand.plus.base.bottomsheetmenu.HorizontalRecyclerBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.measurementtool.adapter.FolderListAdapter; +import net.osmand.plus.myplaces.MoveGpxFileBottomSheet; +import net.osmand.plus.myplaces.MoveGpxFileBottomSheet.OnTrackFileMoveListener; +import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; import java.io.File; +import java.util.ArrayList; +import java.util.List; -public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { +public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDialogFragment implements OnTrackFileMoveListener { public static final String TAG = SaveAsNewTrackBottomSheetDialogFragment.class.getSimpleName(); private static final Log LOG = PlatformUtil.getLog(SaveAsNewTrackBottomSheetDialogFragment.class); @@ -52,19 +61,24 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial public static final String SOURCE_FOLDER_NAME_KEY = "source_folder_name_key"; public static final String SHOW_SIMPLIFIED_BUTTON_KEY = "show_simplified_button_key"; - private boolean showOnMap; - private boolean simplifiedTrack; + private OsmandApplication app; + + private FolderListAdapter adapter; + private TextInputLayout nameTextBox; + private RecyclerView recyclerView; + private String fileName; private String sourceFileName; private String sourceFolderName; private String folderName; + private boolean showOnMap; + private boolean simplifiedTrack; private boolean rightButtonEnabled = true; private boolean showSimplifiedButton = true; - private TextInputLayout nameTextBox; @Override public void createMenuItems(Bundle savedInstanceState) { - OsmandApplication app = getMyApplication(); + app = getMyApplication(); if (app == null) { return; } @@ -118,12 +132,30 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial items.add(new DividerSpaceItem(app, contentPaddingSmall)); - FolderListAdapter adapter = new FolderListAdapter(app, nightMode, folderName); + View selectFolderView = View.inflate(UiUtilities.getThemedContext(app, nightMode), R.layout.select_folder_row, null); + selectFolderView.findViewById(R.id.select_folder_button).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity activity = getActivity(); + if (activity != null) { + File dest = getFile(app, folderName, fileName); + MoveGpxFileBottomSheet.showInstance(activity.getSupportFragmentManager(), + SaveAsNewTrackBottomSheetDialogFragment.this, dest.getAbsolutePath(), usedOnMap); + } + } + }); + BaseBottomSheetItem selectFolderItem = new BaseBottomSheetItem.Builder() + .setCustomView(selectFolderView) + .create(); + items.add(selectFolderItem); + + adapter = new FolderListAdapter(app, nightMode, folderName); + adapter.setFolders(getFolders()); if (adapter.getItemCount() > 0) { adapter.setListener(createFolderSelectListener()); View view = View.inflate(UiUtilities.getThemedContext(app, nightMode), R.layout.bottom_sheet_item_recyclerview, null); - View recyclerView = view.findViewById(R.id.recycler_view); + recyclerView = view.findViewById(R.id.recycler_view); recyclerView.setPadding(contentPaddingHalf, 0, contentPaddingHalf, 0); BaseBottomSheetItem scrollItem = new HorizontalRecyclerBottomSheetItem.Builder() .setAdapter(adapter) @@ -191,7 +223,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial GradientDrawable background = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline); if (background != null) { - int highlightColor = ContextCompat.getColor(app,nightMode ? + int highlightColor = ContextCompat.getColor(app, nightMode ? R.color.list_background_color_dark : R.color.activity_background_color_light); int strokedColor = AndroidUtils.getColorFromAttr(UiUtilities.getThemedContext(app, nightMode), R.attr.stroked_buttons_and_links_outline); @@ -234,7 +266,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial } public static void showInstance(@NonNull FragmentManager fm, @Nullable Fragment targetFragment, String folderName, - String fileName, boolean showSimplifiedButton, boolean showOnMap) { + String fileName, boolean showSimplifiedButton, boolean showOnMap) { try { if (!fm.isStateSaved()) { SaveAsNewTrackBottomSheetDialogFragment fragment = new SaveAsNewTrackBottomSheetDialogFragment(); @@ -284,7 +316,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial } } } - GPXUtilities.GPXFile gpxFile = GPXUtilities.loadGPXFile(dest); + GPXFile gpxFile = GPXUtilities.loadGPXFile(dest); if (gpxFile.error != null) { return; } @@ -331,6 +363,38 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends MenuBottomSheetDial return false; } + private List getFolders() { + List dirs = new ArrayList<>(); + File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); + dirs.add(gpxDir); + Algorithms.collectDirs(gpxDir, dirs); + List dirItems = new ArrayList<>(); + for (File dir : dirs) { + dirItems.add(dir.getName()); + } + return dirItems; + } + + @Override + public void onFileMove(@NonNull File src, @NonNull File dest) { + File destFolder = dest.getParentFile(); + if (destFolder != null) { + folderName = destFolder.getName(); + boolean newFolder = destFolder.mkdirs(); + List folders = getFolders(); + if (newFolder) { + adapter.setFolders(folders); + } + adapter.setSelectedFolderName(folderName); + adapter.notifyDataSetChanged(); + + int position = folders.indexOf(folderName); + if (position != -1) { + recyclerView.scrollToPosition(position); + } + } + } + @Override protected int getBgColorId() { return nightMode ? R.color.activity_background_color_dark : R.color.list_background_color_light; diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java b/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java index b383a4bef6..30b85910ad 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/adapter/FolderListAdapter.java @@ -15,14 +15,11 @@ import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; import net.osmand.AndroidUtils; -import net.osmand.IndexConstants; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.util.Algorithms; -import java.io.File; import java.util.ArrayList; -import java.util.Collection; import java.util.List; public class FolderListAdapter extends RecyclerView.Adapter { @@ -38,24 +35,15 @@ public class FolderListAdapter extends RecyclerView.Adapter folders) { items.clear(); - items.addAll(getFolders()); - } - - private Collection getFolders() { - List dirs = new ArrayList<>(); - File gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); - dirs.add(gpxDir); - Algorithms.collectDirs(gpxDir, dirs); - List dirItems = new ArrayList<>(); - for (File dir : dirs) { - dirItems.add(dir.getName()); - } - return dirItems; + items.addAll(folders); } @NonNull diff --git a/OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java index 50450ad19c..c00e360d7d 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/MoveGpxFileBottomSheet.java @@ -14,12 +14,13 @@ import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; -import net.osmand.plus.base.bottomsheetmenu.simpleitems.SubtitleItem; -import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; +import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.myplaces.AddNewTrackFolderBottomSheet.OnTrackFolderAddListener; import net.osmand.util.Algorithms; @@ -53,13 +54,20 @@ public class MoveGpxFileBottomSheet extends MenuBottomSheetDialogFragment implem final File file = new File(filePath); final File fileDir = file.getParentFile(); - items.add(new TitleItem(getString(R.string.shared_string_folders))); - items.add(new SubtitleItem(getString(R.string.select_folder_descr))); + BaseBottomSheetItem titleItem = new BottomSheetItemWithDescription.Builder() + .setDescription(getString(R.string.select_folder_descr)) + .setTitle(getString(R.string.shared_string_folders)) + .setLayoutId(R.layout.bottom_sheet_item_title_with_description) + .create(); + items.add(titleItem); + View addNewFolderView = UiUtilities.getInflater(app, nightMode).inflate(R.layout.bottom_sheet_item_with_descr_64dp, null); + addNewFolderView.setMinimumHeight(getResources().getDimensionPixelSize(R.dimen.bottom_sheet_list_item_height)); + AndroidUiHelper.updateVisibility(addNewFolderView.findViewById(R.id.description), false); BaseBottomSheetItem addNewFolderItem = new SimpleBottomSheetItem.Builder() .setTitle(getString(R.string.add_new_folder)) .setIcon(getActiveIcon(R.drawable.ic_action_folder_add)) - .setLayoutId(R.layout.bottom_sheet_item_simple) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_64dp) .setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -70,9 +78,13 @@ public class MoveGpxFileBottomSheet extends MenuBottomSheetDialogFragment implem } } }) + .setCustomView(addNewFolderView) .create(); items.add(addNewFolderItem); - items.add(new DividerItem(app)); + + DividerItem dividerItem = new DividerItem(app); + dividerItem.setMargins(0, 0, 0, 0); + items.add(dividerItem); final List dirs = new ArrayList<>(); collectDirs(app.getAppPath(IndexConstants.GPX_INDEX_DIR), dirs, fileDir); @@ -89,12 +101,19 @@ public class MoveGpxFileBottomSheet extends MenuBottomSheetDialogFragment implem dirName = dirName.substring(gpxDir.length() + 1); } } - + String description; + List files = collectFiles(dir); + if (Algorithms.isEmpty(files)) { + description = getString(R.string.shared_string_empty); + } else { + description = String.valueOf(files.size()); + } final BaseBottomSheetItem[] folderItem = new BaseBottomSheetItem[1]; - folderItem[0] = new SimpleBottomSheetItem.Builder() + folderItem[0] = new BottomSheetItemWithDescription.Builder() + .setDescription(description) .setTitle(capitalizeFirstLetter(dirName)) .setIcon(getActiveIcon(R.drawable.ic_action_folder)) - .setLayoutId(R.layout.bottom_sheet_item_simple) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_64dp) .setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -130,6 +149,19 @@ public class MoveGpxFileBottomSheet extends MenuBottomSheetDialogFragment implem dismiss(); } + public List collectFiles(File parentDir) { + List files = new ArrayList<>(); + File[] listFiles = parentDir.listFiles(); + if (listFiles != null) { + for (File file : listFiles) { + if (!file.isDirectory()) { + files.add(file); + } + } + } + return files; + } + public static void showInstance(@NonNull FragmentManager fragmentManager, @Nullable Fragment target, @NonNull String filePath, boolean usedOnMap) { try { From 6188343341cbb5cb83ebbe145e094b80d525b1ff Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 05:36:06 +0200 Subject: [PATCH 40/67] Add a delete button to TrackSegmentFragment --- .../plus/myplaces/AvailableGPXFragment.java | 24 ++++++----------- .../plus/myplaces/FavoritesActivity.java | 10 +++++++ .../plus/myplaces/TrackSegmentFragment.java | 27 +++++++++++++++++-- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 9e4ac656a4..6327e3eda1 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -84,8 +84,8 @@ import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.oauth.OsmOAuthHelper.OsmAuthorizationListener; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.widgets.popup.PopUpMenuItem; import net.osmand.plus.widgets.popup.PopUpMenuHelper; +import net.osmand.plus.widgets.popup.PopUpMenuItem; import java.io.File; import java.text.DateFormat; @@ -105,6 +105,7 @@ import java.util.regex.Pattern; import static net.osmand.plus.GpxSelectionHelper.CURRENT_TRACK; import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB; +import static net.osmand.plus.myplaces.FavoritesActivity.OPEN_GPX_REQUEST; import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; import static net.osmand.util.Algorithms.capitalizeFirstLetter; import static net.osmand.util.Algorithms.collectDirs; @@ -426,7 +427,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, f.getAbsolutePath()); } newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - a.startActivity(newIntent); + a.startActivityForResult(newIntent, OPEN_GPX_REQUEST); } public void reloadTracks() { @@ -434,6 +435,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity()); } + public void resetTracksLoader() { + asyncLoader = null; + } + @Override public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) { menu.clear(); @@ -1711,20 +1716,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement GpxInfo item = allGpxAdapter.getChild(groupPosition, childPosition); if (!selectionMode) { - Intent newIntent = new Intent(getActivity(), getMyApplication().getAppCustomization().getTrackActivity()); - // causes wrong position caching: newIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - if (item.currentlyRecordingTrack) { - newIntent.putExtra(TrackActivity.CURRENT_RECORDING, true); - } else { - newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, item.file.getAbsolutePath()); - } - newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(newIntent); - // item.setExpanded(!item.isExpanded()); - // if (item.isExpanded()) { - // descriptionLoader = new LoadLocalIndexDescriptionTask(); - // descriptionLoader.execute(item); - // } + openTrack(getActivity(), item.file); } else { if (!selectedItems.contains(item)) { selectedItems.add(item); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java b/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java index 43e1e73cc8..c4e5cc8cee 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java @@ -42,6 +42,8 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; +import static net.osmand.plus.myplaces.TrackSegmentFragment.TRACK_DELETED_KEY; + /** * */ @@ -50,6 +52,7 @@ public class FavoritesActivity extends TabActivity { private static final int OPEN_GPX_DOCUMENT_REQUEST = 1006; private static final int IMPORT_FAVOURITES_REQUEST = 1007; + protected static final int OPEN_GPX_REQUEST = 1008; public static final String TAB_ID = "selected_tab_id"; @@ -152,6 +155,13 @@ public class FavoritesActivity extends TabActivity { if (data != null && data.getData() != null) { importHelper.handleGpxOrFavouritesImport(data.getData()); } + } else if (requestCode == OPEN_GPX_REQUEST && resultCode == Activity.RESULT_OK) { + if (data != null && data.getBooleanExtra(TRACK_DELETED_KEY, false)) { + AvailableGPXFragment gpxFragment = getGpxFragment(); + if (gpxFragment != null) { + gpxFragment.resetTracksLoader(); + } + } } else { super.onActivityResult(requestCode, resultCode, data); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java index 4541cf810a..259a1b59d2 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java @@ -1,6 +1,8 @@ package net.osmand.plus.myplaces; +import android.app.Activity; import android.content.DialogInterface; +import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.os.AsyncTask; @@ -23,6 +25,7 @@ import androidx.fragment.app.FragmentManager; import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; import net.osmand.AndroidUtils; +import net.osmand.FileUtils; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.TrkSegment; @@ -55,6 +58,8 @@ import java.util.List; public class TrackSegmentFragment extends OsmAndListFragment implements TrackBitmapDrawerListener, SegmentActionsListener { + public static final String TRACK_DELETED_KEY = "track_deleted_key"; + private OsmandApplication app; private TrackDisplayHelper displayHelper; private TrackActivityFragmentAdapter fragmentAdapter; @@ -134,8 +139,26 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit } }); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - } - if (gpxFile.showCurrentTrack) { + MenuItem deleteItem = menu.add(R.string.shared_string_delete) + .setIcon(app.getUIUtilities().getIcon((R.drawable.ic_action_delete_dark))) + .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + GPXFile gpx = displayHelper.getGpx(); + FragmentActivity activity = getActivity(); + if (activity != null && gpx != null) { + if (FileUtils.removeGpxFile(app, new File((gpx.path)))) { + Intent intent = new Intent(); + intent.putExtra(TRACK_DELETED_KEY, true); + activity.setResult(Activity.RESULT_OK, intent); + activity.onBackPressed(); + } + } + return true; + } + }); + deleteItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); + } else if (gpxFile.showCurrentTrack) { MenuItem item = menu.add(R.string.shared_string_refresh).setIcon(R.drawable.ic_action_refresh_dark) .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override From 643eaf3293105532bb0f1fd1034092774b7779b8 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 07:21:16 +0200 Subject: [PATCH 41/67] Add RenameFileBottomSheet --- OsmAnd/src/net/osmand/FileUtils.java | 82 +-------- .../osmand/plus/activities/TrackActivity.java | 37 +++- .../plus/dialogs/RenameFileBottomSheet.java | 164 ++++++++++++++++++ .../download/ui/LocalIndexesFragment.java | 31 ++-- .../plus/myplaces/AvailableGPXFragment.java | 25 +-- .../plus/myplaces/TrackSegmentFragment.java | 28 ++- 6 files changed, 262 insertions(+), 105 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java index 1f9a755be5..17e75e2fce 100644 --- a/OsmAnd/src/net/osmand/FileUtils.java +++ b/OsmAnd/src/net/osmand/FileUtils.java @@ -1,27 +1,22 @@ package net.osmand; -import android.app.Activity; -import android.content.DialogInterface; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.View; -import android.widget.EditText; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.SQLiteTileSource; +import net.osmand.plus.dialogs.RenameFileBottomSheet; import net.osmand.util.Algorithms; import java.io.File; import java.io.IOException; -import java.lang.ref.WeakReference; import java.util.regex.Pattern; public class FileUtils { @@ -29,70 +24,11 @@ public class FileUtils { public static final Pattern ILLEGAL_FILE_NAME_CHARACTERS = Pattern.compile("[?:\"*|/<>]"); public static final Pattern ILLEGAL_PATH_NAME_CHARACTERS = Pattern.compile("[?:\"*|<>]"); - public static void renameFile(Activity a, final File f, final RenameCallback callback) { - final WeakReference weakActivity = new WeakReference<>(a); - AlertDialog.Builder b = new AlertDialog.Builder(a); - if (f.exists()) { - int xt = f.getName().lastIndexOf('.'); - final String ext = xt == -1 ? "" : f.getName().substring(xt); - final String originalName = xt == -1 ? f.getName() : f.getName().substring(0, xt); - final EditText editText = new EditText(a); - editText.setText(originalName); - editText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - Editable text = editText.getText(); - if (text.length() >= 1) { - Activity activity = weakActivity.get(); - if (ILLEGAL_FILE_NAME_CHARACTERS.matcher(text).find() && activity != null) { - editText.setError(activity.getString(R.string.file_name_containes_illegal_char)); - } - } - } - }); - b.setTitle(R.string.shared_string_rename); - int leftPadding = AndroidUtils.dpToPx(a, 24f); - int topPadding = AndroidUtils.dpToPx(a, 4f); - b.setView(editText, leftPadding, topPadding, leftPadding, topPadding); - // Behaviour will be overwritten later; - b.setPositiveButton(R.string.shared_string_save, null); - b.setNegativeButton(R.string.shared_string_cancel, null); - final AlertDialog alertDialog = b.create(); - alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { - @Override - public void onShow(DialogInterface dialog) { - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - Activity activity = weakActivity.get(); - if (activity != null) { - OsmandApplication app = (OsmandApplication) activity.getApplication(); - if (ext.equals(SQLiteTileSource.EXT)) { - if (renameSQLiteFile(app, f, editText.getText().toString() + ext, - callback) != null) { - alertDialog.dismiss(); - } - } else { - if (renameGpxFile(app, f, editText.getText().toString() + ext, - false, callback) != null) { - alertDialog.dismiss(); - } - } - } - } - }); - } - }); - alertDialog.show(); + public static void renameFile(@NonNull FragmentActivity activity, @NonNull File file, + @Nullable Fragment target, boolean usedOnMap) { + if (file.exists()) { + FragmentManager fragmentManager = activity.getSupportFragmentManager(); + RenameFileBottomSheet.showInstance(fragmentManager, target, file, usedOnMap); } } diff --git a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java index 839823c369..e249fc2770 100644 --- a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.content.res.ColorStateList; import android.os.AsyncTask; import android.os.Bundle; +import android.os.PersistableBundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.MenuItem; @@ -45,6 +46,7 @@ import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.track.TrackDisplayHelper; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; +import net.osmand.util.Algorithms; import java.io.File; import java.lang.ref.WeakReference; @@ -83,10 +85,35 @@ public class TrackActivity extends TabActivity { return; } displayHelper = new TrackDisplayHelper(app); - if (intent.hasExtra(TRACK_FILE_NAME)) { + if (savedInstanceState != null) { + String path = savedInstanceState.getString(TRACK_FILE_NAME); + if (!Algorithms.isEmpty(path)) { + displayHelper.setFile(new File(path)); + } + } else if (intent.hasExtra(TRACK_FILE_NAME)) { displayHelper.setFile(new File(intent.getStringExtra(TRACK_FILE_NAME))); } + setupActionBar(); + if (intent.hasExtra(OPEN_POINTS_TAB) + || (savedInstanceState != null && savedInstanceState.getBoolean(OPEN_POINTS_TAB, false))) { + openPointsTab = true; + } + if (intent.hasExtra(OPEN_TRACKS_LIST)) { + openTracksList = true; + } + setContentView(R.layout.track_content); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) { + File file = getFile(); + outState.putString(TRACK_FILE_NAME, file != null ? file.getAbsolutePath() : null); + outState.putBoolean(CURRENT_RECORDING, file == null); + super.onSaveInstanceState(outState, outPersistentState); + } + + public void setupActionBar() { ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { if (getFile() != null) { @@ -97,14 +124,6 @@ public class TrackActivity extends TabActivity { } actionBar.setElevation(AndroidUtils.dpToPx(app, 4f)); } - if (intent.hasExtra(OPEN_POINTS_TAB) - || (savedInstanceState != null && savedInstanceState.getBoolean(OPEN_POINTS_TAB, false))) { - openPointsTab = true; - } - if (intent.hasExtra(OPEN_TRACKS_LIST)) { - openTracksList = true; - } - setContentView(R.layout.track_content); } public TrackDisplayHelper getDisplayHelper() { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java new file mode 100644 index 0000000000..a7d51add8e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java @@ -0,0 +1,164 @@ +package net.osmand.plus.dialogs; + +import android.content.res.ColorStateList; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; + +import net.osmand.AndroidUtils; +import net.osmand.FileUtils.RenameCallback; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.SQLiteTileSource; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; + +import java.io.File; + +import static net.osmand.FileUtils.ILLEGAL_FILE_NAME_CHARACTERS; +import static net.osmand.FileUtils.renameGpxFile; +import static net.osmand.FileUtils.renameSQLiteFile; + +public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment { + + private static final Log LOG = PlatformUtil.getLog(RenameFileBottomSheet.class); + private static final String TAG = RenameFileBottomSheet.class.getName(); + private static final String SOURCE_FILE_NAME_KEY = "source_file_name_key"; + private static final String SELECTED_FILE_NAME_KEY = "selected_file_name_key"; + + private OsmandApplication app; + + private TextInputEditText editText; + private TextInputLayout nameTextBox; + + private File file; + private String selectedFileName; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + if (savedInstanceState != null) { + String path = savedInstanceState.getString(SOURCE_FILE_NAME_KEY); + if (!Algorithms.isEmpty(path)) { + file = new File(path); + } + selectedFileName = savedInstanceState.getString(SELECTED_FILE_NAME_KEY); + } + items.add(new TitleItem(getString(R.string.shared_string_rename))); + + View view = UiUtilities.getInflater(app, nightMode).inflate(R.layout.track_name_edit_text, null); + nameTextBox = view.findViewById(R.id.name_text_box); + nameTextBox.setBoxBackgroundColorResource(nightMode ? R.color.list_background_color_dark : R.color.activity_background_color_light); + nameTextBox.setHint(AndroidUtils.addColon(app, R.string.shared_string_name)); + ColorStateList colorStateList = ColorStateList.valueOf(ContextCompat + .getColor(app, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light)); + nameTextBox.setDefaultHintTextColor(colorStateList); + + editText = view.findViewById(R.id.name_edit_text); + editText.setText(selectedFileName != null ? selectedFileName : Algorithms.getFileNameWithoutExtension(file)); + editText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + updateFileName(s.toString()); + } + }); + + BaseBottomSheetItem editFolderName = new BaseBottomSheetItem.Builder() + .setCustomView(view) + .create(); + items.add(editFolderName); + } + + private void updateFileName(String name) { + if (!Algorithms.isEmpty(name) && ILLEGAL_FILE_NAME_CHARACTERS.matcher(name).find()) { + nameTextBox.setError(getString(R.string.file_name_containes_illegal_char)); + } else { + selectedFileName = name; + nameTextBox.setError(null); + } + updateBottomButtons(); + } + + @Override + protected boolean isRightBottomButtonEnabled() { + return nameTextBox.getError() == null; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putString(SOURCE_FILE_NAME_KEY, file.getAbsolutePath()); + outState.putString(SELECTED_FILE_NAME_KEY, selectedFileName); + super.onSaveInstanceState(outState); + } + + @Override + protected void onRightBottomButtonClick() { + FragmentActivity activity = getActivity(); + if (activity != null) { + AndroidUtils.hideSoftKeyboard(activity, editText); + } + File dest; + int index = file.getName().lastIndexOf('.'); + String ext = index == -1 ? "" : file.getName().substring(index); + if (SQLiteTileSource.EXT.equals(ext)) { + dest = renameSQLiteFile(app, file, selectedFileName + ext, null); + } else { + dest = renameGpxFile(app, file, selectedFileName + ext, false, null); + } + if (dest != null) { + Fragment fragment = getTargetFragment(); + if (fragment instanceof RenameCallback) { + RenameCallback listener = (RenameCallback) fragment; + listener.renamedTo(dest); + } + dismiss(); + } + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected int getRightBottomButtonTextId() { + return R.string.shared_string_save; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @Nullable Fragment target, + @NonNull File file, boolean usedOnMap) { + if (file.exists() && !fragmentManager.isStateSaved() + && fragmentManager.findFragmentByTag(RenameFileBottomSheet.TAG) == null) { + RenameFileBottomSheet fragment = new RenameFileBottomSheet(); + fragment.file = file; + fragment.setUsedOnMap(usedOnMap); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, RenameFileBottomSheet.TAG); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java index 9160160973..3081c0680b 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java @@ -29,6 +29,7 @@ import androidx.appcompat.view.ActionMode; import androidx.appcompat.widget.PopupMenu; import androidx.core.content.ContextCompat; import androidx.core.view.MenuItemCompat; +import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.Collator; @@ -74,7 +75,7 @@ import java.util.Map; import java.util.Set; public class LocalIndexesFragment extends OsmandExpandableListFragment implements DownloadEvents, - OnMapSourceUpdateListener { + OnMapSourceUpdateListener, RenameCallback { private LoadLocalIndexTask asyncLoader; private Map filesToUpdate = new HashMap<>(); private LocalIndexesAdapter listAdapter; @@ -141,13 +142,11 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement private boolean performBasicOperation(int resId, final LocalIndexInfo info) { if (resId == R.string.shared_string_rename) { - FileUtils.renameFile(getActivity(), new File(info.getPathToData()), new RenameCallback() { - - @Override - public void renamedTo(File file) { - getDownloadActivity().reloadLocalIndexes(); - } - }); + FragmentActivity activity = getActivity(); + if (activity != null) { + File file = new File(info.getPathToData()); + FileUtils.renameFile(activity, file, this, false); + } } else if (resId == R.string.clear_tile_data) { AlertDialog.Builder confirm = new AlertDialog.Builder(getActivity()); confirm.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { @@ -188,7 +187,19 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement @Override public void onMapSourceUpdated() { - getDownloadActivity().reloadLocalIndexes(); + reloadLocalIndexes(); + } + + @Override + public void renamedTo(File file) { + reloadLocalIndexes(); + } + + private void reloadLocalIndexes() { + DownloadActivity activity = getDownloadActivity(); + if (activity != null) { + activity.reloadLocalIndexes(); + } } public class LoadLocalIndexTask extends AsyncTask> @@ -666,7 +677,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement public void localOptionsMenu(final int itemId) { if (itemId == R.string.shared_string_refresh) { - getDownloadActivity().reloadLocalIndexes(); + reloadLocalIndexes(); } else if (itemId == R.string.shared_string_delete) { openSelectionMode(itemId, R.drawable.ic_action_delete_dark, new DialogInterface.OnClickListener() { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 6327e3eda1..d17e9d8b67 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -42,6 +42,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ActionMode; import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.Collator; @@ -114,7 +115,7 @@ import static net.osmand.util.Algorithms.objectEquals; import static net.osmand.util.Algorithms.removeAllFiles; public class AvailableGPXFragment extends OsmandExpandableListFragment implements - FavoritesFragmentStateHolder, OsmAuthorizationListener { + FavoritesFragmentStateHolder, OsmAuthorizationListener, RenameCallback { public static final Pattern ILLEGAL_PATH_NAME_CHARACTERS = Pattern.compile("[?:\"*|<>]"); public static final int SEARCH_ID = -1; @@ -884,8 +885,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement File dest = new File(destFolder, info.fileName); if (info.file.renameTo(dest)) { app.getGpxDbHelper().rename(info.file, dest); - asyncLoader = new LoadGpxTask(); - asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity()); + reloadTracks(); } else { Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); } @@ -907,8 +907,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } else { if (info.file.renameTo(dest)) { app.getGpxDbHelper().rename(info.file, dest); - asyncLoader = new LoadGpxTask(); - asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity()); + reloadTracks(); } else { Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); } @@ -943,6 +942,11 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement app.startActivity(intent); } + @Override + public void renamedTo(File file) { + reloadTracks(); + } + public class LoadGpxTask extends AsyncTask> { private List result; @@ -1548,13 +1552,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - FileUtils.renameFile(getActivity(), gpxInfo.file, new RenameCallback() { - @Override - public void renamedTo(File file) { - asyncLoader = new LoadGpxTask(); - asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity()); - } - }); + FragmentActivity activity = getActivity(); + if (activity != null) { + FileUtils.renameFile(activity, gpxInfo.file, AvailableGPXFragment.this, false); + } } }) .create() diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java index 259a1b59d2..4a66e09d99 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java @@ -26,6 +26,7 @@ import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; import net.osmand.AndroidUtils; import net.osmand.FileUtils; +import net.osmand.FileUtils.RenameCallback; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.TrkSegment; @@ -56,7 +57,8 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -public class TrackSegmentFragment extends OsmAndListFragment implements TrackBitmapDrawerListener, SegmentActionsListener { +public class TrackSegmentFragment extends OsmAndListFragment implements TrackBitmapDrawerListener, + SegmentActionsListener, RenameCallback { public static final String TRACK_DELETED_KEY = "track_deleted_key"; @@ -139,6 +141,20 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit } }); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + MenuItem renameItem = menu.add(R.string.shared_string_rename) + .setIcon(app.getUIUtilities().getIcon((R.drawable.ic_action_edit_dark))) + .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + GPXFile gpx = displayHelper.getGpx(); + FragmentActivity activity = getActivity(); + if (activity != null && gpx != null) { + FileUtils.renameFile(activity, new File(gpx.path), TrackSegmentFragment.this, false); + } + return true; + } + }); + renameItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); MenuItem deleteItem = menu.add(R.string.shared_string_delete) .setIcon(app.getUIUtilities().getIcon((R.drawable.ic_action_delete_dark))) .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @@ -438,4 +454,14 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit } }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } + + @Override + public void renamedTo(File file) { + displayHelper.setFile(file); + TrackActivity activity = getTrackActivity(); + if (activity != null) { + activity.setupActionBar(); + activity.loadGpx(); + } + } } \ No newline at end of file From 0942b612aba1db5a53ea6ef969a52272dacf5759 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 07:22:40 +0200 Subject: [PATCH 42/67] Fix typo --- .../osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java b/OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java index 584ba75339..2a80de5b43 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AddNewTrackFolderBottomSheet.java @@ -63,9 +63,9 @@ public class AddNewTrackFolderBottomSheet extends MenuBottomSheetDialogFragment ColorStateList colorStateList = ColorStateList.valueOf(ContextCompat .getColor(app, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light)); nameTextBox.setDefaultHintTextColor(colorStateList); - TextInputEditText nameText = view.findViewById(R.id.name_edit_text); - nameText.setText(folderName); - nameText.addTextChangedListener(new TextWatcher() { + editText = view.findViewById(R.id.name_edit_text); + editText.setText(folderName); + editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } From 34837cb3d92bfb4f0c192b4e09ab1592e3394241 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 07:57:16 +0200 Subject: [PATCH 43/67] Add separate method for renaming files --- OsmAnd/src/net/osmand/FileUtils.java | 24 ++++++++++++++++++- .../plus/dialogs/RenameFileBottomSheet.java | 6 ++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/FileUtils.java b/OsmAnd/src/net/osmand/FileUtils.java index 17e75e2fce..fed5346212 100644 --- a/OsmAnd/src/net/osmand/FileUtils.java +++ b/OsmAnd/src/net/osmand/FileUtils.java @@ -8,6 +8,8 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.GPXUtilities.Metadata; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; @@ -42,7 +44,7 @@ public class FileUtils { dest.getParentFile().mkdirs(); } if (source.renameTo(dest)) { - final String[] suffixes = new String[]{"-journal", "-wal", "-shm"}; + final String[] suffixes = new String[] {"-journal", "-wal", "-shm"}; for (String s : suffixes) { File file = new File(ctx.getDatabasePath(source + s).toString()); if (file.exists()) { @@ -76,6 +78,26 @@ public class FileUtils { return res; } + public static File renameFile(@NonNull OsmandApplication app, @NonNull File source, + @NonNull String newName, boolean dirAllowed, RenameCallback callback) { + File dest = checkRenamePossibility(app, source, newName, dirAllowed); + if (dest == null) { + return null; + } + if (!dest.getParentFile().exists()) { + dest.getParentFile().mkdirs(); + } + File res = source.renameTo(dest) ? dest : null; + if (res != null) { + if (callback != null) { + callback.renamedTo(res); + } + } else { + Toast.makeText(app, R.string.file_can_not_be_renamed, Toast.LENGTH_LONG).show(); + } + return res; + } + public static File renameGpxFile(@NonNull OsmandApplication app, @NonNull File src, @NonNull File dest) { if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java index a7d51add8e..c6057b56de 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/RenameFileBottomSheet.java @@ -18,6 +18,7 @@ import com.google.android.material.textfield.TextInputLayout; import net.osmand.AndroidUtils; import net.osmand.FileUtils.RenameCallback; +import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -33,6 +34,7 @@ import org.apache.commons.logging.Log; import java.io.File; import static net.osmand.FileUtils.ILLEGAL_FILE_NAME_CHARACTERS; +import static net.osmand.FileUtils.renameFile; import static net.osmand.FileUtils.renameGpxFile; import static net.osmand.FileUtils.renameSQLiteFile; @@ -127,8 +129,10 @@ public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment { String ext = index == -1 ? "" : file.getName().substring(index); if (SQLiteTileSource.EXT.equals(ext)) { dest = renameSQLiteFile(app, file, selectedFileName + ext, null); - } else { + } else if (IndexConstants.GPX_FILE_EXT.equals(ext)) { dest = renameGpxFile(app, file, selectedFileName + ext, false, null); + } else { + dest = renameFile(app, file, selectedFileName + ext, false, null); } if (dest != null) { Fragment fragment = getTargetFragment(); From 60bf9843decd936290fc836253eb2a2ed13b73c1 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 11:42:59 +0200 Subject: [PATCH 44/67] Fix build --- .../plus/myplaces/AvailableGPXFragment.java | 104 +----------------- 1 file changed, 5 insertions(+), 99 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index a8bb5538b8..06a38d3ef2 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -13,6 +13,8 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.text.Editable; +import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -25,6 +27,7 @@ import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; +import android.widget.EditText; import android.widget.ExpandableListView; import android.widget.Filter; import android.widget.Filterable; @@ -100,19 +103,20 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import static net.osmand.plus.GpxSelectionHelper.CURRENT_TRACK; import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.OPEN_GPX_REQUEST; import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; import static net.osmand.util.Algorithms.capitalizeFirstLetter; +import static net.osmand.util.Algorithms.collectDirs; import static net.osmand.util.Algorithms.formatDuration; import static net.osmand.util.Algorithms.objectEquals; import static net.osmand.util.Algorithms.removeAllFiles; public class AvailableGPXFragment extends OsmandExpandableListFragment implements FavoritesFragmentStateHolder, OsmAuthorizationListener, OnTrackFileMoveListener, RenameCallback { - FavoritesFragmentStateHolder, OsmAuthorizationListener, RenameCallback { public static final int SEARCH_ID = -1; // public static final int ACTION_ID = 0; @@ -796,104 +800,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement if (activity != null) { MoveGpxFileBottomSheet.showInstance(activity.getSupportFragmentManager(), this, info.file.getAbsolutePath(), false); } - menuAdapter.addItem(itemBuilder.setTitleId(R.string.add_new_folder, app) - .setIcon(R.drawable.ic_zoom_in).setTag(-1).createItem()); - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - final ArrayAdapter listAdapter = - menuAdapter.createListAdapter(getActivity(), app.getSettings().isLightContent()); - builder.setTitle(R.string.select_gpx_folder); - builder.setAdapter(listAdapter, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - ContextMenuItem item = menuAdapter.getItem(which); - int index = item.getTag(); - if (index == -1) { - Activity a = getActivity(); - AlertDialog.Builder b = new AlertDialog.Builder(a); - b.setTitle(R.string.add_new_folder); - final EditText editText = new EditText(a); - editText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - Editable text = editText.getText(); - if (text.length() >= 1) { - if (ILLEGAL_PATH_NAME_CHARACTERS.matcher(text).find()) { - editText.setError(app.getString(R.string.file_name_containes_illegal_char)); - } - } - } - }); - int leftPadding = AndroidUtils.dpToPx(a, 24f); - int topPadding = AndroidUtils.dpToPx(a, 4f); - b.setView(editText, leftPadding, topPadding, leftPadding, topPadding); - // Behaviour will be overwritten later; - b.setPositiveButton(R.string.shared_string_ok, null); - b.setNegativeButton(R.string.shared_string_cancel, null); - final AlertDialog alertDialog = b.create(); - alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { - @Override - public void onShow(DialogInterface dialog) { - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - String newName = editText.getText().toString(); - if (ILLEGAL_PATH_NAME_CHARACTERS.matcher(newName).find()) { - Toast.makeText(app, R.string.file_name_containes_illegal_char, - Toast.LENGTH_LONG).show(); - return; - } - File destFolder = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), newName); - if (destFolder.exists()) { - Toast.makeText(app, R.string.file_with_name_already_exists, - Toast.LENGTH_LONG).show(); - return; - } else if (destFolder.mkdirs()) { - File dest = new File(destFolder, info.fileName); - if (info.file.renameTo(dest)) { - app.getGpxDbHelper().rename(info.file, dest); - reloadTracks(); - } else { - Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); - } - - } else { - Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); - } - alertDialog.dismiss(); - } - }); - } - }); - alertDialog.show(); - } else { - File dir = dirs.get(index); - File dest = new File(dir, info.file.getName()); - if (dest.exists()) { - Toast.makeText(app, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show(); - } else { - if (info.file.renameTo(dest)) { - app.getGpxDbHelper().rename(info.file, dest); - reloadTracks(); - } else { - Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show(); - } - } - } - } - }); - builder.setNegativeButton(R.string.shared_string_cancel, null); - builder.create().show(); - } @Override From 5297bfa9432d92ac31b3d6387822a1b981d8dc7f Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 11 Jan 2021 12:22:23 +0200 Subject: [PATCH 45/67] fix Graphhopper name --- OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java | 2 +- .../plus/onlinerouting/OnlineRoutingEngineFragment.java | 6 +++--- .../net/osmand/plus/onlinerouting/OnlineRoutingHelper.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java index 3362a4e499..fe5080f14c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java @@ -2,7 +2,7 @@ package net.osmand.plus.onlinerouting; public enum EngineType { - GRAPHHOPER("Graphhoper", "https://graphhopper.com/api/1/route"), + GRAPHHOPPER("Graphhopper", "https://graphhopper.com/api/1/route"), OSRM("OSRM", "https://router.project-osrm.org/route/v1/"), ORS("Openroute Service", "https://api.openrouteservice.org/v2/directions/"); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index cb70a8ca48..59df4ef698 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -355,7 +355,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } else if (typeCard.equals(card)) { typeCard.setHeaderSubtitle(engine.type.getTitle()); typeCard.setEditedText(engine.getBaseUrl()); - if (engine.type == EngineType.GRAPHHOPER || engine.type == EngineType.ORS) { + if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) { apiKeyCard.show(); } else { apiKeyCard.hide(); @@ -414,7 +414,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { engineToSave.putParameter(EngineParameter.CUSTOM_NAME, engine.customName); engineToSave.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); - if (engine.type == EngineType.GRAPHHOPER || engine.type == EngineType.ORS) { + if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) { engineToSave.putParameter(EngineParameter.API_KEY, engine.apiKey); } @@ -448,7 +448,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { try { JSONObject obj = new JSONObject(response); - if (type == EngineType.GRAPHHOPER) { + if (type == EngineType.GRAPHHOPPER) { resultOk = obj.has("paths"); } else if (type == EngineType.OSRM) { resultOk = obj.has("routes"); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 6e61c3d444..b54746ddd6 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -67,7 +67,7 @@ public class OnlineRoutingHelper { String apiKey = engine.getParameter(EngineParameter.API_KEY); switch (engine.getType()) { - case GRAPHHOPER: + case GRAPHHOPPER: sb.append("?"); for (LatLon point : path) { sb.append("point=") @@ -118,7 +118,7 @@ public class OnlineRoutingHelper { switch (engine.getType()) { - case GRAPHHOPER: + case GRAPHHOPPER: return GeoPolylineParserUtil.parse( obj.getJSONArray("paths").getJSONObject(0).getString("points"), GeoPolylineParserUtil.PRECISION_5); From b9f1f699347afee9b1c18cc92ca08018ecbf2894 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 11 Jan 2021 16:32:12 +0200 Subject: [PATCH 46/67] Fix build --- .../builders/AmenityMenuBuilder.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java index 524c862c47..0d097eabfb 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java @@ -15,6 +15,10 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.view.ContextThemeWrapper; +import androidx.core.content.ContextCompat; + import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.data.Amenity; @@ -63,10 +67,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import androidx.annotation.NonNull; -import androidx.appcompat.view.ContextThemeWrapper; -import androidx.core.content.ContextCompat; - public class AmenityMenuBuilder extends MenuBuilder { private static final String WIKI_LINK = ".wikipedia.org/w"; @@ -93,7 +93,7 @@ public class AmenityMenuBuilder extends MenuBuilder { 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, String socialMediaUrl, boolean collapsable, final CollapsableView collapsableView, int textColor, boolean isWiki, boolean isText, boolean needLinks, boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) { @@ -684,7 +684,8 @@ public class AmenityMenuBuilder extends MenuBuilder { if (processNearestWiki() && nearestWiki.size() > 0) { 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() + ")", + null, true, getCollapsableView(view.getContext(), true, nearestWiki), 0, false, false, false, 1000, null, false, false, false, 0); buildAmenityRow(view, wikiInfo); @@ -692,7 +693,8 @@ public class AmenityMenuBuilder extends MenuBuilder { if (processNearestPoi() && nearestPoi.size() > 0) { AmenityInfoRow poiInfo = new AmenityInfoRow( - "nearest_poi", AmenityMenuController.getRightIconId(amenity), null, app.getString(R.string.speak_poi) + " (" + nearestPoi.size() + ")", true, + "nearest_poi", AmenityMenuController.getRightIconId(amenity), null, app.getString(R.string.speak_poi) + " (" + nearestPoi.size() + ")", + null, true, getCollapsableView(view.getContext(), true, nearestPoi), 0, false, false, false, 1000, null, false, false, false, 0); buildAmenityRow(view, poiInfo); @@ -918,7 +920,7 @@ public class AmenityMenuBuilder extends MenuBuilder { if (sb.charAt(lastIdx) == '/') { sb.deleteCharAt(lastIdx); } - + // It cannot be username if (sb.indexOf("/") != -1) { return "https://" + value; From 9c7bacc3afeddfe1cb0a8cb820ce92c86873dadf Mon Sep 17 00:00:00 2001 From: max-klaus Date: Mon, 11 Jan 2021 20:04:51 +0300 Subject: [PATCH 47/67] Fix tracker backgound location issue --- OsmAnd-telegram/AndroidManifest.xml | 8 +- OsmAnd-telegram/build.gradle | 6 +- .../OnTelegramServiceAlarmReceiver.kt | 42 ------ .../osmand/telegram/TelegramApplication.kt | 23 +-- .../telegram/TelegramLocationProvider.kt | 2 +- .../net/osmand/telegram/TelegramService.kt | 139 ++++-------------- .../telegram/ui/MyLocationTabFragment.kt | 5 +- 7 files changed, 41 insertions(+), 184 deletions(-) delete mode 100644 OsmAnd-telegram/src/net/osmand/telegram/OnTelegramServiceAlarmReceiver.kt diff --git a/OsmAnd-telegram/AndroidManifest.xml b/OsmAnd-telegram/AndroidManifest.xml index 73e2e856ca..4e8ab332dc 100644 --- a/OsmAnd-telegram/AndroidManifest.xml +++ b/OsmAnd-telegram/AndroidManifest.xml @@ -19,7 +19,10 @@ android:launchMode="singleTask" android:screenOrientation="unspecified" android:supportsRtl="true" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + android:hasFragileUserData="true" + android:requestLegacyExternalStorage="true"> + - - service.serviceErrorInterval && handler != null) { - handler.postDelayed({ - // if lock is not anymore held - if (lock.isHeld) { - lock.release() - locationManager.removeUpdates(service) - } - }, service.serviceErrorInterval) - } - } catch (e: RuntimeException) { - e.printStackTrace() - } - } -} \ No newline at end of file diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt index b6927dc610..b9fcb3112d 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt @@ -8,12 +8,13 @@ import android.net.ConnectivityManager import android.net.NetworkInfo import android.os.Build import android.os.Handler +import androidx.core.content.ContextCompat import net.osmand.PlatformUtil -import net.osmand.telegram.ui.TrackerLogcatActivity import net.osmand.telegram.helpers.* import net.osmand.telegram.helpers.OsmandAidlHelper.OsmandHelperListener import net.osmand.telegram.helpers.OsmandAidlHelper.UpdatesListener import net.osmand.telegram.notifications.NotificationHelper +import net.osmand.telegram.ui.TrackerLogcatActivity import net.osmand.telegram.utils.AndroidUtils import net.osmand.telegram.utils.UiUtils import java.io.File @@ -146,35 +147,21 @@ class TelegramApplication : Application() { return internetConnectionAvailable } - private fun startTelegramService(intent: Int, serviceOffInterval: Long = 0) { + private fun startTelegramService(intent: Int) { var i = intent - var interval = serviceOffInterval val serviceIntent = Intent(this, TelegramService::class.java) - val telegramService = telegramService if (telegramService != null) { i = intent or telegramService.usedBy - interval = if (TelegramService.isOffIntervalDepended(intent)) { - Math.min(telegramService.serviceOffInterval, interval) - } else { - telegramService.serviceOffInterval - } telegramService.stopSelf() } - serviceIntent.putExtra(TelegramService.USAGE_INTENT, i) - serviceIntent.putExtra(TelegramService.USAGE_OFF_INTERVAL, interval) serviceIntent.putExtra(TelegramService.SEND_LOCATION_INTERVAL, settings.sendMyLocInterval) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(serviceIntent) - } else { - startService(serviceIntent) - } + ContextCompat.startForegroundService(this, serviceIntent) } fun startMyLocationService() { - val interval = settings.sendMyLocInterval - startTelegramService(TelegramService.USED_BY_MY_LOCATION, TelegramService.normalizeOffInterval(interval)) + startTelegramService(TelegramService.USED_BY_MY_LOCATION) } fun stopMyLocationService() { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt index d0f283df01..71611f7cf3 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt @@ -166,7 +166,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve registerOrUnregisterCompassListener(true) } - fun redownloadAGPS() { + private fun redownloadAGPS() { try { val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager service.sendExtraCommand(LocationManager.GPS_PROVIDER, "delete_aiding_data", null) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt index ee05034cb7..29503dfa27 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt @@ -1,16 +1,14 @@ package net.osmand.telegram import android.annotation.SuppressLint -import android.app.AlarmManager -import android.app.PendingIntent import android.app.Service import android.content.Context import android.content.Intent +import android.content.pm.ServiceInfo import android.location.Location import android.location.LocationListener import android.location.LocationManager import android.os.* -import android.util.Log import android.widget.Toast import net.osmand.PlatformUtil import net.osmand.telegram.TelegramSettings.ShareChatInfo @@ -26,7 +24,7 @@ private const val UPDATE_LIVE_MESSAGES_INTERVAL_MS = 10000L // 10 sec private const val UPDATE_LIVE_TRACKS_INTERVAL_MS = 30000L // 30 sec class TelegramService : Service(), LocationListener, TelegramIncomingMessagesListener, - TelegramOutgoingMessagesListener { + TelegramOutgoingMessagesListener { private val log = PlatformUtil.getLog(TelegramService::class.java) @@ -43,21 +41,14 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis private var updateWidgetHandler: Handler? = null private var updateWidgetThread = HandlerThread("WidgetUpdateServiceThread") - var handler: Handler? = null - private set var usedBy = 0 private set var serviceOffProvider: String = LocationManager.GPS_PROVIDER private set - var serviceOffInterval = 0L - private set - var serviceErrorInterval = 0L - private set var sendLocationInterval = 0L private set private var lastLocationSentTime = 0L - private var pendingIntent: PendingIntent? = null class LocationServiceBinder : Binder() @@ -71,7 +62,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis updateWidgetHandler = Handler(updateWidgetThread.looper) } - override fun onBind(intent: Intent): IBinder? { + override fun onBind(intent: Intent): IBinder { return binder } @@ -86,13 +77,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis ctx.stopService(serviceIntent) } isUsedByMyLocation(usedBy) -> { - val app = app() - if (app.settings.sendMyLocInterval >= OFF_INTERVAL_THRESHOLD && serviceOffInterval == 0L) { - serviceOffInterval = app.settings.sendMyLocInterval - setupServiceErrorInterval() - setupAlarm() - } - app.notificationHelper.refreshNotification(NotificationType.LOCATION) + app().notificationHelper.refreshNotification(NotificationType.LOCATION) } isUsedByUsersLocations(usedBy) -> removeLocationUpdates() } @@ -100,19 +85,21 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { val app = app() - handler = Handler() val usageIntent = intent.getIntExtra(USAGE_INTENT, 0) usedBy = usageIntent or usedBy - serviceOffInterval = intent.getLongExtra(USAGE_OFF_INTERVAL, 0) sendLocationInterval = intent.getLongExtra(SEND_LOCATION_INTERVAL, 0) - setupServiceErrorInterval() app.telegramHelper.addIncomingMessagesListener(this) app.telegramHelper.addOutgoingMessagesListener(this) app.telegramService = this + val locationNotification = app.notificationHelper.locationNotification + val notification = app.notificationHelper.buildNotification(locationNotification) + startForeground(locationNotification.telegramNotificationId, notification) + app.notificationHelper.refreshNotification(locationNotification.type) + if (isUsedByMyLocation(usedBy)) { initLocationUpdates() startShareInfoUpdates() @@ -124,21 +111,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis } app.shareLocationHelper.checkAndSendBufferMessages() - val locationNotification = app.notificationHelper.locationNotification - val notification = app.notificationHelper.buildNotification(locationNotification) - startForeground(locationNotification.telegramNotificationId, notification) - app.notificationHelper.refreshNotification(locationNotification.type) - return Service.START_REDELIVER_INTENT - } - - private fun setupServiceErrorInterval() { - serviceErrorInterval = serviceOffInterval / 5 - // 1. not more than 12 mins - serviceErrorInterval = Math.min(serviceErrorInterval, 12 * 60 * 1000) - // 2. not less than 30 seconds - serviceErrorInterval = Math.max(serviceErrorInterval, 30 * 1000) - // 3. not more than serviceOffInterval - serviceErrorInterval = Math.min(serviceErrorInterval, serviceOffInterval) + return START_REDELIVER_INTENT } override fun onDestroy() { @@ -158,13 +131,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis removeLocationUpdates() - if (!isContinuous()) { - val lock = getLock(this) - if (lock.isHeld) { - lock.release() - } - } - if (shouldCleanupResources) { app.cleanupResources() } @@ -176,7 +142,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis fun updateSendLocationInterval(newInterval: Long) { sendLocationInterval = newInterval } - + fun forceLocationUpdate() { val location = getFirstTimeRunDefaultLocation() app().shareLocationHelper.updateLocation(location) @@ -186,21 +152,16 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis val firstLocation = getFirstTimeRunDefaultLocation() app().shareLocationHelper.updateLocation(firstLocation) - // requesting - if (isContinuous()) { - // request location updates - val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager - try { - locationManager.requestLocationUpdates(serviceOffProvider, 0, 0f, this@TelegramService) - } catch (e: SecurityException) { - Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show() - Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$ - } catch (e: IllegalArgumentException) { - Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show() - Log.d(PlatformUtil.TAG, "GPS location provider not available") //$NON-NLS-1$ - } - } else { - setupAlarm() + // request location updates + val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + try { + locationManager.requestLocationUpdates(serviceOffProvider, 0, 0f, this@TelegramService) + } catch (e: SecurityException) { + Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show() + log.debug("Location service permission not granted") + } catch (e: IllegalArgumentException) { + Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show() + log.debug("GPS location provider not available") } } @@ -254,7 +215,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis startWidgetUpdates() }, UPDATE_WIDGET_INTERVAL_MS) } - + @SuppressLint("MissingPermission") private fun getFirstTimeRunDefaultLocation(): net.osmand.Location? { val app = app() @@ -282,43 +243,19 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis return location } - private fun setupAlarm() { - val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager - pendingIntent = PendingIntent.getBroadcast(this, 0, Intent(this, OnTelegramServiceAlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT) - alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent) - } - private fun removeLocationUpdates() { // remove updates val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager try { locationManager.removeUpdates(this) } catch (e: SecurityException) { - Log.d(PlatformUtil.TAG, "Location service permission not granted") + log.debug("Location service permission not granted") } } - private fun isContinuous(): Boolean { - return serviceOffInterval == 0L - } - override fun onLocationChanged(l: Location?) { val location = convertLocation(l) - if (!isContinuous()) { - // unregister listener and wait next time - val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager - try { - locationManager.removeUpdates(this) - } catch (e: Throwable) { - Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$ - } - - val lock = getLock(this) - if (lock.isHeld) { - lock.release() - } - app().shareLocationHelper.updateLocation(location) - } else if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) { + if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) { lastLocationSentTime = System.currentTimeMillis() app().shareLocationHelper.updateLocation(location) } @@ -373,7 +310,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis } override fun onSendLiveLocationError(code: Int, message: String, shareInfo: ShareChatInfo, messageType: Int) { - Log.d(PlatformUtil.TAG, "Send live location error: $code - $message") + log.debug("Send live location error: $code - $message") when (messageType) { TelegramHelper.MESSAGE_TYPE_TEXT -> shareInfo.pendingTdLibText-- TelegramHelper.MESSAGE_TYPE_MAP -> { @@ -388,26 +325,8 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis const val USED_BY_MY_LOCATION: Int = 1 const val USED_BY_USERS_LOCATIONS: Int = 2 const val USAGE_INTENT = "SERVICE_USED_BY" - const val USAGE_OFF_INTERVAL = "SERVICE_OFF_INTERVAL" const val SEND_LOCATION_INTERVAL = "SEND_LOCATION_INTERVAL" - const val OFF_INTERVAL_THRESHOLD: Long = 30000L - - private var lockStatic: PowerManager.WakeLock? = null - - @Synchronized - fun getLock(context: Context): PowerManager.WakeLock { - var lockStatic = lockStatic - return if (lockStatic == null) { - val mgr = context.getSystemService(Context.POWER_SERVICE) as PowerManager - lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "OsmandServiceLock") - this.lockStatic = lockStatic - lockStatic - } else { - lockStatic - } - } - fun isUsedByMyLocation(usedBy: Int): Boolean { return (usedBy and USED_BY_MY_LOCATION) > 0 } @@ -416,14 +335,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis return (usedBy and USED_BY_USERS_LOCATIONS) > 0 } - fun isOffIntervalDepended(usedBy: Int): Boolean { - return isUsedByMyLocation(usedBy) - } - - fun normalizeOffInterval(interval: Long): Long { - return if (interval < OFF_INTERVAL_THRESHOLD) 0 else interval - } - fun convertLocation(l: Location?): net.osmand.Location? { if (l == null) { return null diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt index fee5d83151..7d87ce3b1d 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt @@ -21,7 +21,6 @@ import android.widget.* import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import com.google.android.material.appbar.AppBarLayout import net.osmand.PlatformUtil import net.osmand.telegram.* @@ -42,7 +41,7 @@ private const val SUGGESTED = 2 private const val SHARE_LOCATION_CHAT = 1 private const val DEFAULT_CHAT = 0 -private const val ADAPTER_UPDATE_INTERVAL_MIL = 5 * 1000L // 5 sec +private const val ADAPTER_UPDATE_INTERVAL_MS = 5 * 1000L // 5 sec class MyLocationTabFragment : Fragment(), TelegramListener { @@ -380,7 +379,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { updateContent() startHandler() } - }, ADAPTER_UPDATE_INTERVAL_MIL) + }, ADAPTER_UPDATE_INTERVAL_MS) } private fun animateStartSharingBtn(show: Boolean) { From 7ac78fb9f4603f8f2bd05958c19bac4ea53fdcd1 Mon Sep 17 00:00:00 2001 From: Dmitriy Prodchenko Date: Mon, 11 Jan 2021 09:50:45 +0000 Subject: [PATCH 48/67] Translated using Weblate (Russian) Currently translated at 99.1% (3578 of 3609 strings) --- OsmAnd/res/values-ru/strings.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 59bc5514c9..4af14aab63 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -4005,4 +4005,14 @@ Последний раз использовалось Разрешить прерывистые водные пути Разрешить прерывистые водные пути + • Добавлена возможность экспорта и импорта всех данных, включая настройки, ресурсы, мои места. +\n +\n• Планирование маршрута: графики для сегментов трека с маршрутом, добавлена возможность создавать и редактировать несколько сегментов трека. +\n +\n• Добавлен OAuth метод аутентификации для OpenStreetMap, улучшен интерфейс диалоговых OSM. +\n +\n • Поддержка пользовательских цветов для избранного и путевых точек трека. +\n +\n + Скопировать адрес \ No newline at end of file From d326603d1df62beaa60f7dbeaac2657a60465b33 Mon Sep 17 00:00:00 2001 From: Franco Date: Mon, 11 Jan 2021 00:01:41 +0000 Subject: [PATCH 49/67] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3609 of 3609 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 3b49991789..610cf4435a 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -4049,6 +4049,6 @@ Automóvil Error, vuelve a comprobar los parámetros Copiar dirección - Motor de ruta en línea + Motor de navegación en línea Motores de navegación en línea \ No newline at end of file From 5661b344a7a471845bd63d8e4554fc08908aa372 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 12 Jan 2021 17:35:16 +0300 Subject: [PATCH 50/67] Drop location in tracker service (temp)' --- .../src/net/osmand/telegram/TelegramService.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt index 29503dfa27..c3dde54e76 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt @@ -153,6 +153,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis app().shareLocationHelper.updateLocation(firstLocation) // request location updates + /* val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager try { locationManager.requestLocationUpdates(serviceOffProvider, 0, 0f, this@TelegramService) @@ -163,6 +164,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show() log.debug("GPS location provider not available") } + */ } private fun startShareInfoUpdates() { @@ -222,6 +224,8 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis if (!AndroidUtils.isLocationPermissionAvailable(app)) { return null } + var location: net.osmand.Location? = null + /* val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager val ps = service.getProviders(true) ?: return null val providers = ArrayList(ps) @@ -233,24 +237,26 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis providers.add(0, providers.removeAt(passiveFirst)) } // find location - var location: net.osmand.Location? = null for (provider in providers) { val loc = convertLocation(service.getLastKnownLocation(provider)) if (loc != null && (location == null || loc.hasAccuracy() && loc.accuracy < location.accuracy)) { location = loc } } + */ return location } private fun removeLocationUpdates() { // remove updates + /* val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager try { locationManager.removeUpdates(this) } catch (e: SecurityException) { log.debug("Location service permission not granted") } + */ } override fun onLocationChanged(l: Location?) { From 9251a6bb4af017065cb7d2861baeae1df7f7b130 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 12 Jan 2021 18:33:43 +0100 Subject: [PATCH 51/67] Fix https://github.com/osmandapp/OsmAnd/issues/10454 --- .../java/net/osmand/search/core/SearchCoreFactory.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java index 5c2faf0b51..d00bf9ffb2 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java @@ -719,9 +719,10 @@ public class SearchCoreFactory { results.put(res.pt.getKeyName(), res); } } - if (nmAdditional != null) { - addAditonals(nmAdditional, results, types.getOtherMapCategory()); - } + // don't spam results with unsearchable additionals like 'description', 'email', ... + // if (nmAdditional != null) { + // addAditonals(nmAdditional, results, types.getOtherMapCategory()); + // } for (PoiCategory c : categories) { PoiTypeResult res = checkPoiType(nm, c); if(res != null) { From 6945aaa77bda11db52a8a031392419bb70995ed0 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Tue, 12 Jan 2021 21:16:23 +0300 Subject: [PATCH 52/67] Drop location in tracker service (temp) 2' --- OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index efdb35edf1..bece18b8f4 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -505,6 +505,8 @@ class TelegramSettings(private val app: TelegramApplication) { val currentTimeMillis = System.currentTimeMillis() val currentTime = currentTimeMillis / 1000 statusChangeTime = currentTimeMillis + val gpsEnabled = false + /* val lm = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager val gpsEnabled = try { if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { @@ -518,6 +520,7 @@ class TelegramSettings(private val app: TelegramApplication) { } catch (ex: Exception) { false } + */ var initializing = false var sendChatsErrors = false From 1720e5d24c9785b8fb26aa0a080d13d13338e3eb Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 12 Jan 2021 20:24:18 +0000 Subject: [PATCH 53/67] Translated using Weblate (Dutch) Currently translated at 94.3% (3410 of 3613 strings) --- OsmAnd/res/values-nl/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index b9061fecbf..733234b49f 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -3940,4 +3940,7 @@ Beken en sloten gebruiken Beken en sloten gebruiken Waterwegen die periodiek water voeren gebruiken + Selecteer een map + Selecteer een map of maak een nieuwe + Leeg \ No newline at end of file From 24ceac5d10539ae89b541f8f1f901ba39f65e961 Mon Sep 17 00:00:00 2001 From: Edgar Date: Tue, 12 Jan 2021 18:03:18 +0000 Subject: [PATCH 54/67] Translated using Weblate (Dutch) Currently translated at 94.3% (3410 of 3613 strings) --- OsmAnd/res/values-nl/strings.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index 733234b49f..46f2bdc5e8 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -3943,4 +3943,27 @@ Selecteer een map Selecteer een map of maak een nieuwe Leeg + Selecteer de groepen om deze te importeren. + Selecteer de items om deze te importeren. + Voeg toe aan Mapillary + Voeg toe aan OpenPlaceReviews + Gebruik dev.openstreetmap.org + Selecteer het profiel dat zal worden gebruikt bij het starten van de applicatie. + Online routeplanner toevoegen + Bewerk online routeplanner + Subtype + Voertuig + API-sleutel + Server-URL + De URL met alle parameters ziet er als volgt uit: + Test routeberekening + Rijden + Te voet + Fiets + Auto + Fout, controleer parameters opnieuw + Kopieer adres + Online navigatiesysteem + Online navigatiesystemen + Mappen \ No newline at end of file From 1a8516932e4934449c8990c6e7e7da85516f115d Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Tue, 12 Jan 2021 06:56:05 +0000 Subject: [PATCH 55/67] Translated using Weblate (French) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-fr/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index ce2956037a..ed159ba3d4 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4025,4 +4025,8 @@ Copier l\'adresse Moteur de routage en ligne Moteurs de routage en ligne + Dossiers + Sélectionnez le dossier + Sélectionnez un dossier ou créez-en un nouveau + Vide \ No newline at end of file From 5787564b1769d2d01d93068a22b3e2dfba90cbaf Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 11 Jan 2021 21:32:11 +0000 Subject: [PATCH 56/67] Translated using Weblate (German) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-de/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 35f7fb8f0a..786bc89b7b 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4050,4 +4050,8 @@ Fahren Online Navigationssystem Online Navigationssysteme + Ordner + Ordner auswählen + Ordner auswählen oder neuen hinzufügen + Leer \ No newline at end of file From 5e842ee036d9117abda783296ed0abe721cabf0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Mon, 11 Jan 2021 20:23:06 +0000 Subject: [PATCH 57/67] Translated using Weblate (Turkish) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-tr/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 6974f656ce..3633266c59 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -4001,4 +4001,8 @@ Adresi kopyala Çevrim içi yönlendirme motoru Çevrim içi yönlendirme motorları + Klasörler + Klasör seç + Klasör seçin veya yeni bir tane ekleyin + Boş \ No newline at end of file From ca38fdb838ac334430b3433df2bdfe883715a95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Mon, 11 Jan 2021 21:19:57 +0000 Subject: [PATCH 58/67] Translated using Weblate (Hungarian) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-hu/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index d764e136ea..4aa49b1705 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -4038,4 +4038,8 @@ Cím másolása Online útvonaltervező Online útvonaltervezők + Mappák + Mappa kijelölése + Mappa kijelölése vagy új hozzáadása + Üres \ No newline at end of file From 0f64e24d24e3395290dfce8fd62e9700ac53c06c Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 12 Jan 2021 11:31:07 +0000 Subject: [PATCH 59/67] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-uk/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index d40f3ce782..a78f27f55d 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4042,4 +4042,8 @@ Копіювати адресу Мережний рушій маршрутизації Мережні рушії маршрутизації + Теки + Вибрати теку + Виберіть теку або додайте нову + Порожньо \ No newline at end of file From d29c9608ef2d198b2dc59b08711d2cb138d8bf37 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 11 Jan 2021 22:30:17 +0000 Subject: [PATCH 60/67] Translated using Weblate (Hebrew) Currently translated at 99.9% (3612 of 3613 strings) --- OsmAnd/res/values-iw/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index e279d6d9b2..905fadb16d 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4050,4 +4050,8 @@ העתקת כתובת מנוע ניווט מקוון מנועי ניווט מקוונים + תיקיות + בחירת תקינה + נא לבחור תיקייה או להוסיף אחת חדשה + ריק \ No newline at end of file From aa585533bbb3379663ad0f804219b9dae7aaa9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Tue, 12 Jan 2021 20:04:30 +0000 Subject: [PATCH 61/67] Translated using Weblate (Czech) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-cs/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 20a7355927..593c4d3bc9 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -4039,4 +4039,8 @@ Kopírovat adresu Online navigační služba Online navigační služby + Složky + Zvolte složku + Zvolte složku nebo vytvořte novou + Prázdné \ No newline at end of file From 4d6dd1f27f293155bdf55f94f21705d48fb974ac Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Tue, 12 Jan 2021 17:38:36 +0000 Subject: [PATCH 62/67] Translated using Weblate (Sardinian) Currently translated at 99.8% (3606 of 3613 strings) --- OsmAnd/res/values-sc/strings.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index 4dea386d11..7982e1a5c7 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -4025,4 +4025,26 @@ Permite caminos de abba intermitentes Permite caminos de abba intermitentes Nùmeru de annùntzios vocales + Annanghe unu motore de càrculu de s\'àndala in lìnia + Modìfica su motore de càrculu de s\'àndala in lìnia + Suta-casta + Veìculu + Crae de s\'API + URL de su serbidore + Inserta su paràmetru + Si nono, mantene·lu bòidu + S\'URL cun totu sos paràmetros at a apàrrere gasi: + Proa a carculare un\'àndala + In vetura + A pee + Bitzicleta + Màchina + Errore, torra a verificare sos paràmetros + Còpia s\'indiritzu + Motore de càrculu in lìnia + Motores de càrculu in lìnia + Cartellas + Ischerta sa cartella + Ischerta una cartella o crea·nde una noa + Bòidu \ No newline at end of file From 6bb2d4b2eb0842f128f35dc13769f5690d9f4646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1ns?= Date: Tue, 12 Jan 2021 12:02:50 +0000 Subject: [PATCH 63/67] Translated using Weblate (Galician) Currently translated at 99.9% (3610 of 3613 strings) --- OsmAnd/res/values-gl/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml index d9d8d1142c..2b37db8ab3 100644 --- a/OsmAnd/res/values-gl/strings.xml +++ b/OsmAnd/res/values-gl/strings.xml @@ -3958,7 +3958,7 @@ Lon %2$s MGRS MGRS O OsmAnd emprega MGRS, que é semellante ó formato UTM NATO. - %1$s datos dispoñíbeis só nas estrada, necesitas calcular unha ruta empregando \"Ruta entre puntos\" para obtela. + Os datos de %1$s só dispoñíbeis nas estradas, calcula unha ruta empregando \"Ruta entre puntos\" para ver gráficas. O gráfico estará dispoñíbel após o recálculo da ruta. Mapas locais Salto @@ -4066,4 +4066,11 @@ Lon %2$s Coche Erro, verifica novamente os parámetros Copiar enderezo + Horarios dos avisos por voz + Motor de navegación en liña + Motores de navegación en liña + Cartafoles + Selecionar cartafol ou engadir un novo + Seleccionar cartafol + Baleiro \ No newline at end of file From f1d71b8a4b587b20f10fcb55e95b33d9fcf61ea5 Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Mon, 11 Jan 2021 23:28:00 +0000 Subject: [PATCH 64/67] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 20e2f1a64e..5348b7283d 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4041,4 +4041,8 @@ Copiar endereço Motor de encaminhamento online Mecanismos de roteamento online + Pastas + Selecione a pasta + Selecione a pasta ou adicione uma nova + Vazio \ No newline at end of file From 9049e680c6abbaeb8af52cb4c846b6393fc626d4 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Mon, 11 Jan 2021 23:16:47 +0000 Subject: [PATCH 65/67] Translated using Weblate (Esperanto) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-eo/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 933c81c0a8..0509e0d3fd 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -4046,4 +4046,8 @@ Kopii adreson Enreta navigilo Enretaj navigiloj + Dosierujoj + Elekti dosierujon + Elekti dosierujon aŭ krei novan + Malplena \ No newline at end of file From ae23549e8d83d788830e8038e9b0c5c36de7d642 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 12 Jan 2021 02:23:42 +0000 Subject: [PATCH 66/67] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3613 of 3613 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 4b5e87a853..74513f74f7 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -4041,4 +4041,8 @@ 複製地址 線上路線計算引擎 線上路線計算引擎 + 資料夾 + 選取資料夾 + 選取資料夾或新增 + \ No newline at end of file From d4ea5f62cc7431fc3fee0912aa71de79d9311e7b Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 12 Jan 2021 20:24:58 +0000 Subject: [PATCH 67/67] Translated using Weblate (Dutch) Currently translated at 94.4% (3412 of 3613 strings) --- OsmAnd/res/values-nl/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index 46f2bdc5e8..4313500cc9 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -3963,7 +3963,7 @@ Auto Fout, controleer parameters opnieuw Kopieer adres - Online navigatiesysteem - Online navigatiesystemen + Online routeplanningssysteem + Online routeplanningssystemen Mappen \ No newline at end of file