From f1569fd5fb8c05939869df897fed5cae435389fb Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Sun, 24 Jan 2021 23:48:41 +0200 Subject: [PATCH 01/28] Travel GPX card --- .../main/java/net/osmand/data/Amenity.java | 4 + .../res/layout/wikivoyage_travel_gpx_card.xml | 242 ++++++++++++++++++ .../plus/wikivoyage/data/TravelGpx.java | 8 + .../wikivoyage/explore/ExploreRvAdapter.java | 13 +- .../explore/ExploreTabFragment.java | 8 +- .../explore/travelcards/TravelGpxCard.java | 120 +++++++++ 6 files changed, 392 insertions(+), 3 deletions(-) create mode 100644 OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml create mode 100644 OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java create mode 100644 OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java diff --git a/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java b/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java index 3ef6a54652..959669a665 100644 --- a/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java +++ b/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java @@ -273,6 +273,10 @@ public class Amenity extends MapObject { return null; } + public String getTagContent(String tag) { + return getTagContent(tag, null); + } + public String getTagContent(String tag, String lang) { if (lang != null) { String translateName = getAdditionalInfo(tag + ":" + lang); diff --git a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml new file mode 100644 index 0000000000..eb97f02c0b --- /dev/null +++ b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java new file mode 100644 index 0000000000..8393ec98a6 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java @@ -0,0 +1,8 @@ +package net.osmand.plus.wikivoyage.data; + +public class TravelGpx extends TravelArticle { + public String user; + public float totalDistance = 0; + public double diffElevationUp = 0; + public double diffElevationDown = 0; +} diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java index a95614bdb8..5341edcb9d 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java @@ -20,6 +20,8 @@ import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard.StartEditingTravelVH; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard.DownloadUpdateVH; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.TravelGpxVH; import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard.NeededMapsVH; @@ -48,6 +50,9 @@ public class ExploreRvAdapter extends RecyclerView.Adapter 0; i--) { BaseTravelCard o = items.get(i); - if (o instanceof ArticleTravelCard) { + if (o instanceof ArticleTravelCard || o instanceof TravelGpxCard) { return i; } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index c53027fb7a..ae6b0cace7 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -28,6 +28,7 @@ import net.osmand.plus.download.DownloadResources; import net.osmand.plus.download.DownloadValidationManager; import net.osmand.plus.download.IndexItem; import net.osmand.plus.wikivoyage.data.TravelArticle; +import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import net.osmand.plus.wikivoyage.explore.travelcards.ArticleTravelCard; @@ -36,6 +37,7 @@ import net.osmand.plus.wikivoyage.explore.travelcards.HeaderTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard; import java.io.IOException; @@ -183,7 +185,11 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv List popularArticles = app.getTravelHelper().getPopularArticles(); for (TravelArticle article : popularArticles) { - items.add(new ArticleTravelCard(app, nightMode, article, fm)); + if (article instanceof TravelGpx) { + items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, fm)); + } else { + items.add(new ArticleTravelCard(app, nightMode, article, fm)); + } } } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java new file mode 100644 index 0000000000..32790cc094 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -0,0 +1,120 @@ +package net.osmand.plus.wikivoyage.explore.travelcards; + +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.wikipedia.WikiArticleHelper; +import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; +import net.osmand.plus.wikivoyage.data.TravelGpx; +import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; + +public class TravelGpxCard extends BaseTravelCard { + + public static final int TYPE = 3; + + private final TravelGpx article; + private final Drawable readIcon; + private final FragmentManager fragmentManager; + private boolean isLastItem; + + public TravelGpxCard(@NonNull OsmandApplication app, boolean nightMode, @NonNull TravelGpx article, + @NonNull FragmentManager fragmentManager) { + super(app, nightMode); + this.article = article; + readIcon = getActiveIcon(R.drawable.ic_action_read_article); + this.fragmentManager = fragmentManager; + } + + @Override + public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof TravelGpxVH) { + final TravelGpxVH holder = (TravelGpxVH) viewHolder; + holder.title.setText(article.getTitle()); + holder.content.setText(WikiArticleHelper.getPartialContent(article.getContent())); + holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance,app)); + holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp,app)); + holder.diffElevationDown.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationDown,app)); + holder.leftButton.setText(app.getString(R.string.shared_string_view)); + View.OnClickListener readClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fragmentManager != null) { + WikivoyageArticleDialogFragment.showInstance(app, fragmentManager, + article.generateIdentifier(), article.getLang()); + } + } + }; + holder.leftButton.setOnClickListener(readClickListener); + holder.itemView.setOnClickListener(readClickListener); + holder.leftButton.setCompoundDrawablesWithIntrinsicBounds(readIcon, null, null, null); + updateSaveButton(holder); + holder.divider.setVisibility(isLastItem ? View.GONE : View.VISIBLE); + holder.shadow.setVisibility(isLastItem ? View.VISIBLE : View.GONE); + } + } + + private void updateSaveButton(final TravelGpxVH holder) { + if (article != null) { + final TravelLocalDataHelper helper = app.getTravelHelper().getBookmarksHelper(); + final boolean saved = helper.isArticleSaved(article); + Drawable icon = getActiveIcon(saved ? R.drawable.ic_action_read_later_fill : R.drawable.ic_action_read_later); + holder.rightButton.setText(saved ? R.string.shared_string_remove : R.string.shared_string_save); + holder.rightButton.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null); + holder.rightButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (saved) { + helper.removeArticleFromSaved(article); + } else { + app.getTravelHelper().createGpxFile(article); + helper.addArticleToSaved(article); + } + updateSaveButton(holder); + } + }); + } + } + + public static class TravelGpxVH extends RecyclerView.ViewHolder { + + final TextView title; + final TextView content; + final TextView distance; + final TextView diffElevationUp; + final TextView diffElevationDown; + final TextView leftButton; + final TextView rightButton; + final View divider; + final View shadow; + + public TravelGpxVH(final View itemView) { + super(itemView); + title = itemView.findViewById(R.id.title); + content = itemView.findViewById(R.id.content); + distance = itemView.findViewById(R.id.distance); + diffElevationUp = itemView.findViewById(R.id.diff_ele_up); + diffElevationDown = itemView.findViewById(R.id.diff_ele_down); + leftButton = itemView.findViewById(R.id.left_button); + rightButton = itemView.findViewById(R.id.right_button); + divider = itemView.findViewById(R.id.divider); + shadow = itemView.findViewById(R.id.shadow); + } + } + + public void setLastItem(boolean lastItem) { + isLastItem = lastItem; + } + + @Override + public int getCardType() { + return TYPE; + } +} From a914efaa286353dbbfd9cb920de442773590de3f Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 25 Jan 2021 23:30:43 +0200 Subject: [PATCH 02/28] Sort travel GPX card and travel article, UI --- .../res/layout/wikivoyage_travel_gpx_card.xml | 78 +++++++--- .../plus/wikivoyage/data/TravelObfHelper.java | 143 ++++++++++++------ .../explore/ExploreTabFragment.java | 27 ++-- .../explore/travelcards/TravelGpxCard.java | 22 +-- 4 files changed, 184 insertions(+), 86 deletions(-) diff --git a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml index eb97f02c0b..44077a0dcd 100644 --- a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml +++ b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml @@ -10,17 +10,13 @@ android:id="@+id/background_view" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/content_padding_small" - android:layout_marginStart="@dimen/content_padding" - android:layout_marginEnd="@dimen/content_padding" - android:background="?attr/wikivoyage_travel_card_bg"> + android:background="?attr/wikivoyage_card_bg_color"> + + + + - + android:orientation="vertical" + android:paddingTop="@dimen/content_padding_half" + android:paddingBottom="@dimen/content_padding_small"> + + + + + + android:layout_height="wrap_content" + android:paddingTop="@dimen/content_padding_small_half" + android:paddingBottom="@dimen/content_padding_small_half"> loadPopularArticles() { String lang = app.getLanguage(); List popularArticles = new ArrayList<>(); - for (BinaryMapIndexReader reader : getReaders()) { + final List> amenities = new ArrayList<>(); + final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); + for (final BinaryMapIndexReader reader : getReaders()) { try { - final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); - SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest( - location, POPULAR_ARTICLES_SEARCH_RADIUS, -1, getSearchFilter(false), null); - List amenities = reader.searchPoi(req); - if (amenities.size() > 0) { - for (Amenity amenity : amenities) { - if (!Algorithms.isEmpty(amenity.getName(lang))) { - TravelArticle article = cacheTravelArticles(reader.getFile(), amenity, lang, false); - if (article != null) { - popularArticles.add(article); - if (popularArticles.size() >= MAX_POPULAR_ARTICLES_COUNT) { - break; - } - } - } - } - Collections.sort(popularArticles, new Comparator() { - @Override - public int compare(TravelArticle article1, TravelArticle article2) { - int d1 = (int) (MapUtils.getDistance(article1.getLat(), article1.getLon(), - location.getLatitude(), location.getLongitude())); - int d2 = (int) (MapUtils.getDistance(article2.getLat(), article2.getLon(), - location.getLatitude(), location.getLongitude())); - return d1 < d2 ? -1 : (d1 == d2 ? 0 : 1); - } - }); - } + searchAmenity(amenities, location, reader, POPULAR_ARTICLES_SEARCH_RADIUS, -1, ROUTE_ARTICLE); + searchAmenity(amenities, location, reader, GPX_TRACKS_SEARCH_RADIUS, 15, ROUTE_TRACK); } catch (Exception e) { LOG.error(e.getMessage(), e); } } + + if (amenities.size() > 0) { + Collections.sort(amenities, new Comparator>() { + @Override + public int compare(Pair article1, Pair article2) { + int d1 = (int) (MapUtils.getDistance(((Amenity) article1.second).getLocation(), location)); + int d2 = (int) (MapUtils.getDistance(((Amenity) article2.second).getLocation(), location)); + return d1 < d2 ? -1 : (d1 == d2 ? 0 : 1); + } + }); + for (Pair amenity : amenities) { + if (!Algorithms.isEmpty(amenity.second.getName(lang))) { + TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false); + if (article != null) { + popularArticles.add(article); + if (popularArticles.size() >= MAX_POPULAR_ARTICLES_COUNT) { + break; + } + } + } + } + } this.popularArticles = popularArticles; return popularArticles; } + private void searchAmenity(final List> amenitiesList, LatLon location, + final BinaryMapIndexReader reader, int searchRadius, int zoom, + String searchFilter) throws IOException { + reader.searchPoi(BinaryMapIndexReader.buildSearchPoiRequest( + location, searchRadius, zoom, getSearchFilter(searchFilter), new ResultMatcher() { + @Override + public boolean publish(Amenity object) { + amenitiesList.add(new Pair<>(reader.getFile(), object)); + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + })); + } + @Nullable private TravelArticle cacheTravelArticles(File file, Amenity amenity, String lang, boolean readPoints) { TravelArticle article = null; - Map articles = readArticles(file, amenity, false); + Map articles; + if (amenity.getSubType().equals(ROUTE_TRACK)) { + articles = readRoutePoint(file, amenity); + } else { + articles = readArticles(file, amenity, false); + } if (!Algorithms.isEmpty(articles)) { TravelArticleIdentifier newArticleId = articles.values().iterator().next().generateIdentifier(); cachedArticles.put(newArticleId, articles); @@ -139,12 +165,38 @@ public class TravelObfHelper implements TravelHelper { return article; } - @NonNull - private SearchPoiTypeFilter getSearchFilter(final boolean articlePoints) { - return new SearchPoiTypeFilter() { + private Map readRoutePoint(File file, Amenity amenity) { + Map articles = new HashMap<>(); + TravelGpx res = new TravelGpx(); + String title = amenity.getName("en"); + res.title = capitalizeFirstLetter(getGpxTitle(Algorithms.isEmpty(title) ? amenity.getName() : title)); + res.routeId = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID)); + try { + res.totalDistance = Float.parseFloat(Algorithms.emptyIfNull(amenity.getTagContent("distance"))); + } catch (NumberFormatException e) { + LOG.debug(e.getMessage(), e); + } + try { + res.diffElevationUp = Double.parseDouble(Algorithms.emptyIfNull(amenity.getTagContent("diff_ele_up"))); + } catch (NumberFormatException e) { + LOG.debug(e.getMessage(), e); + } + try { + res.diffElevationDown = Double.parseDouble(Algorithms.emptyIfNull(amenity.getTagContent("diff_ele_down"))); + } catch (NumberFormatException e) { + LOG.debug(e.getMessage(), e); + } + res.user = Algorithms.emptyIfNull(amenity.getTagContent("user")); + articles.put("en", res); + return articles; + } + + + private BinaryMapIndexReader.SearchPoiTypeFilter getSearchFilter(final String filterSubcategory) { + return new BinaryMapIndexReader.SearchPoiTypeFilter() { @Override public boolean accept(PoiCategory type, String subcategory) { - return subcategory.equals(articlePoints ? ROUTE_ARTICLE_POINT : ROUTE_ARTICLE); + return subcategory.equals(filterSubcategory); } @Override @@ -175,9 +227,9 @@ public class TravelObfHelper implements TravelHelper { res.isParentOf = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.IS_PARENT_OF, lang)); res.lat = amenity.getLocation().getLatitude(); res.lon = amenity.getLocation().getLongitude(); - res.imageTitle = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.IMAGE_TITLE, null)); - res.routeId = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null)); - res.routeSource = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null)); + res.imageTitle = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.IMAGE_TITLE)); + res.routeId = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID)); + res.routeSource = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE)); res.originalId = 0; res.lang = lang; res.contentsJson = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.CONTENT_JSON, lang)); @@ -214,14 +266,14 @@ public class TravelObfHelper implements TravelHelper { } SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, Algorithms.emptyIfNull(article.title), 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, - getSearchFilter(true), new ResultMatcher() { + getSearchFilter(ROUTE_ARTICLE_POINT), new ResultMatcher() { @Override public boolean publish(Amenity amenity) { String amenityLang = amenity.getTagSuffix(Amenity.LANG_YES + ":"); if (Algorithms.stringsEqual(lang, amenityLang) && Algorithms.stringsEqual(article.routeId, - Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null)))) { + Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID)))) { pointList.add(amenity); } return false; @@ -263,7 +315,7 @@ public class TravelObfHelper implements TravelHelper { } String category = amenity.getTagSuffix("category_"); if (category != null) { - wptPt.category = Algorithms.capitalizeFirstLetter(category); + wptPt.category = capitalizeFirstLetter(category); } return wptPt; } @@ -283,7 +335,7 @@ public class TravelObfHelper implements TravelHelper { for (BinaryMapIndexReader reader : getReaders()) { try { SearchRequest searchRequest = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, searchQuery, - 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchFilter(false), new ResultMatcher() { + 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchFilter(ROUTE_ARTICLE), new ResultMatcher() { @Override public boolean publish(Amenity object) { List otherNames = object.getAllNames(false); @@ -458,7 +510,7 @@ public class TravelObfHelper implements TravelHelper { for (BinaryMapIndexReader reader : getReaders()) { try { SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest( - 0, 0, title, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchFilter(false), + 0, 0, title, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchFilter(ROUTE_ARTICLE), new ResultMatcher() { boolean done = false; @@ -531,12 +583,13 @@ public class TravelObfHelper implements TravelHelper { } SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, Algorithms.emptyIfNull(articleId.title), 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, - getSearchFilter(false), new ResultMatcher() { + getSearchFilter(ROUTE_ARTICLE), new ResultMatcher() { boolean done = false; @Override public boolean publish(Amenity amenity) { - if (Algorithms.stringsEqual(articleId.routeId, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null))) || isDbArticle) { + if (Algorithms.stringsEqual(articleId.routeId, + Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID))) || isDbArticle) { amenities.add(amenity); done = true; } @@ -604,7 +657,7 @@ public class TravelObfHelper implements TravelHelper { for (BinaryMapIndexReader reader : getReaders()) { try { SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest( - x, y, title, left, right, top, bottom, getSearchFilter(false), + x, y, title, left, right, top, bottom, getSearchFilter(ROUTE_ARTICLE), new ResultMatcher() { boolean done = false; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index e520487740..ce6f4475af 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -180,20 +180,21 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv List popularArticles = app.getTravelHelper().getPopularArticles(); for (TravelArticle article : popularArticles) { - if (article instanceof TravelGpx) { - items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, fm)); - } else { - items.add(new ArticleTravelCard(app, nightMode, article, activity.getSupportFragmentManager())); + if (article instanceof TravelGpx) { + items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, activity.getSupportFragmentManager())); + } else { + items.add(new ArticleTravelCard(app, nightMode, article, activity.getSupportFragmentManager())); + } + } + items.add(new StartEditingTravelCard(activity, nightMode)); + adapter.setItems(items); + final DownloadIndexesThread downloadThread = app.getDownloadThread(); + if (!downloadThread.getIndexes().isDownloadedFromInternet) { + waitForIndexes = true; + downloadThread.runReloadIndexFilesSilent(); + } else { + checkDownloadIndexes(); } - } - items.add(new StartEditingTravelCard(activity, nightMode)); - adapter.setItems(items); - final DownloadIndexesThread downloadThread = app.getDownloadThread(); - if (!downloadThread.getIndexes().isDownloadedFromInternet) { - waitForIndexes = true; - downloadThread.runReloadIndexFilesSilent(); - } else { - checkDownloadIndexes(); } } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index 32790cc094..608b0b812f 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -8,11 +8,11 @@ import androidx.annotation.NonNull; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.RecyclerView; +import net.osmand.AndroidUtils; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.wikipedia.WikiArticleHelper; -import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; @@ -38,17 +38,21 @@ public class TravelGpxCard extends BaseTravelCard { if (viewHolder instanceof TravelGpxVH) { final TravelGpxVH holder = (TravelGpxVH) viewHolder; holder.title.setText(article.getTitle()); - holder.content.setText(WikiArticleHelper.getPartialContent(article.getContent())); - holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance,app)); - holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp,app)); - holder.diffElevationDown.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationDown,app)); + Drawable icon = getActiveIcon(R.drawable.ic_action_user_account_16); + holder.user.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); + holder.user.setText(WikiArticleHelper.getPartialContent(article.user)); + AndroidUtils.setBackground(app, holder.user, nightMode, R.drawable.btn_border_bg_light, R.drawable.btn_border_bg_dark); + holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance, app)); + holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp, app)); + holder.diffElevationDown.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationDown, app)); holder.leftButton.setText(app.getString(R.string.shared_string_view)); View.OnClickListener readClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (fragmentManager != null) { - WikivoyageArticleDialogFragment.showInstance(app, fragmentManager, - article.generateIdentifier(), article.getLang()); +// WikivoyageArticleDialogFragment.showInstance(app, fragmentManager, +// article.generateIdentifier(), article.getLang()); + app.getTravelHelper().createGpxFile(article); } } }; @@ -86,7 +90,7 @@ public class TravelGpxCard extends BaseTravelCard { public static class TravelGpxVH extends RecyclerView.ViewHolder { final TextView title; - final TextView content; + final TextView user; final TextView distance; final TextView diffElevationUp; final TextView diffElevationDown; @@ -98,7 +102,7 @@ public class TravelGpxCard extends BaseTravelCard { public TravelGpxVH(final View itemView) { super(itemView); title = itemView.findViewById(R.id.title); - content = itemView.findViewById(R.id.content); + user = itemView.findViewById(R.id.user_name); distance = itemView.findViewById(R.id.distance); diffElevationUp = itemView.findViewById(R.id.diff_ele_up); diffElevationDown = itemView.findViewById(R.id.diff_ele_down); From fea90fd37e6395feb960ff8e1c30c508ff7f20b4 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 26 Jan 2021 23:41:44 +0200 Subject: [PATCH 03/28] Add to bookmarks, build gpx track --- .../plus/wikivoyage/data/TravelGpx.java | 6 ++ .../data/TravelLocalDataHelper.java | 33 +++++-- .../plus/wikivoyage/data/TravelObfHelper.java | 82 +++++++++++++++- .../explore/SavedArticlesRvAdapter.java | 93 ++++++++++++++++--- .../explore/travelcards/TravelGpxCard.java | 18 ++-- 5 files changed, 198 insertions(+), 34 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java index 8393ec98a6..185fdc922c 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java @@ -1,6 +1,12 @@ package net.osmand.plus.wikivoyage.data; public class TravelGpx extends TravelArticle { + + public static final String DISTANCE = "distance"; + public static final String DIFF_ELE_UP = "diff_ele_up"; + public static final String DIFF_ELE_DOWN = "diff_ele_down"; + public static final String USER = "user"; + public String user; public float totalDistance = 0; public double diffElevationUp = 0; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index 2c59c16ed2..748800a611 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -143,6 +143,9 @@ public class TravelLocalDataHelper { @Nullable private TravelArticle getArticle(String title, String lang) { for (TravelArticle article : savedArticles) { + if (article.lang == null && lang == null && article.title != null && article.title.equals(title)) { + return article; + } if (article.title != null && article.title.equals(title) && article.lang != null && article.lang.equals(lang)) { return article; } @@ -477,12 +480,23 @@ public class TravelLocalDataHelper { SQLiteConnection conn = openConnection(false); if (conn != null) { try { - conn.execSQL("DELETE FROM " + BOOKMARKS_TABLE_NAME + - " WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" + - " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + - " AND " + BOOKMARKS_COL_LANG + " = ?" + - " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?", - new Object[]{article.title, article.routeId, article.lang, travelBook}); + String query; + Object[] parameters; + if (article.lang == null) { + query = "DELETE FROM " + BOOKMARKS_TABLE_NAME + + " WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" + + " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + + " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?"; + parameters = new Object[]{article.title, article.routeId, travelBook}; + } else { + query = "DELETE FROM " + BOOKMARKS_TABLE_NAME + + " WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" + + " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + + " AND " + BOOKMARKS_COL_LANG + " = ?" + + " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?"; + parameters = new Object[]{article.title, article.routeId, article.lang, travelBook}; + } + conn.execSQL(query, parameters); } finally { conn.close(); } @@ -537,7 +551,12 @@ public class TravelLocalDataHelper { @NonNull private TravelArticle readSavedArticle(SQLiteCursor cursor) { - TravelArticle res = new TravelArticle(); + TravelArticle res; + if (cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_LANG)) == null) { + res = new TravelGpx(); + } else { + res = new TravelArticle(); + } res.title = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_ARTICLE_TITLE)); res.lang = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_LANG)); res.aggregatedPartOf = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_IS_PART_OF)); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 0f76eb775e..13c4fffa49 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -8,11 +8,13 @@ import androidx.annotation.Nullable; import net.osmand.Collator; import net.osmand.CollatorStringMatcher.StringMatcherMode; +import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.IndexConstants; import net.osmand.OsmAndCollator; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; +import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.data.Amenity; @@ -48,6 +50,10 @@ import java.util.concurrent.ConcurrentHashMap; import static net.osmand.GPXUtilities.WptPt; import static net.osmand.GPXUtilities.writeGpxFile; import static net.osmand.plus.helpers.GpxUiHelper.getGpxTitle; +import static net.osmand.plus.wikivoyage.data.TravelGpx.DIFF_ELE_DOWN; +import static net.osmand.plus.wikivoyage.data.TravelGpx.DIFF_ELE_UP; +import static net.osmand.plus.wikivoyage.data.TravelGpx.DISTANCE; +import static net.osmand.plus.wikivoyage.data.TravelGpx.USER; import static net.osmand.util.Algorithms.capitalizeFirstLetter; public class TravelObfHelper implements TravelHelper { @@ -168,25 +174,26 @@ public class TravelObfHelper implements TravelHelper { private Map readRoutePoint(File file, Amenity amenity) { Map articles = new HashMap<>(); TravelGpx res = new TravelGpx(); + res.file = file; String title = amenity.getName("en"); res.title = capitalizeFirstLetter(getGpxTitle(Algorithms.isEmpty(title) ? amenity.getName() : title)); res.routeId = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID)); try { - res.totalDistance = Float.parseFloat(Algorithms.emptyIfNull(amenity.getTagContent("distance"))); + res.totalDistance = Float.parseFloat(Algorithms.emptyIfNull(amenity.getTagContent(DISTANCE))); } catch (NumberFormatException e) { LOG.debug(e.getMessage(), e); } try { - res.diffElevationUp = Double.parseDouble(Algorithms.emptyIfNull(amenity.getTagContent("diff_ele_up"))); + res.diffElevationUp = Double.parseDouble(Algorithms.emptyIfNull(amenity.getTagContent(DIFF_ELE_UP))); } catch (NumberFormatException e) { LOG.debug(e.getMessage(), e); } try { - res.diffElevationDown = Double.parseDouble(Algorithms.emptyIfNull(amenity.getTagContent("diff_ele_down"))); + res.diffElevationDown = Double.parseDouble(Algorithms.emptyIfNull(amenity.getTagContent(DIFF_ELE_DOWN))); } catch (NumberFormatException e) { LOG.debug(e.getMessage(), e); } - res.user = Algorithms.emptyIfNull(amenity.getTagContent("user")); + res.user = Algorithms.emptyIfNull(amenity.getTagContent(USER)); articles.put("en", res); return articles; } @@ -255,6 +262,66 @@ public class TravelObfHelper implements TravelHelper { return gpxFile; } + @Nullable + private GPXFile buildTravelGpxFile(@NonNull final TravelGpx article) { + String routeId = article.getRouteId(); + final String ref = routeId.substring(routeId.length() - 3); + final List segmentList = new ArrayList<>(); + + for (BinaryMapIndexReader reader : getReaders()) { + try { + if (article.file != null && !article.file.equals(reader.getFile())) { + continue; + } + BinaryMapIndexReader.SearchRequest sr = BinaryMapIndexReader.buildSearchRequest( + 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, 15, null, + new ResultMatcher() { + @Override + public boolean publish(BinaryMapDataObject object) { + if (object.getPointsLength() > 1) { + if (object.getObjectNames().get(2).equals(ref) + && capitalizeFirstLetter(getGpxTitle(object.getObjectNames().get(1))).equals(article.title)) { + segmentList.add(object); + } + } + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + }); + reader.searchMapIndex(sr); + if (!Algorithms.isEmpty(segmentList)) { + break; + } + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + GPXFile gpxFile = null; + if (!segmentList.isEmpty()) { + GPXUtilities.Track track = new GPXUtilities.Track(); + for (BinaryMapDataObject segment : segmentList) { + List pointList = new ArrayList<>(); + GPXUtilities.TrkSegment trkSegment = new GPXUtilities.TrkSegment(); + for (int i = 0; i < segment.getPointsLength(); i++) { + WptPt point = new WptPt(); + point.lat = MapUtils.get31LatitudeY(segment.getPoint31YTile(i)); + point.lon = MapUtils.get31LongitudeX(segment.getPoint31XTile(i)); + pointList.add(point); + } + trkSegment.points = pointList; + track.segments.add(trkSegment); + } + gpxFile = new GPXFile(article.getTitle(), article.getLang(), ""); + gpxFile.tracks = new ArrayList<>(); + gpxFile.tracks.add(track); + } + return gpxFile; + } + @NonNull private List getPointList(@NonNull final TravelArticle article) { final List pointList = new ArrayList<>(); @@ -744,7 +811,12 @@ public class TravelObfHelper implements TravelHelper { @NonNull @Override public File createGpxFile(@NonNull final TravelArticle article) { - final GPXFile gpx = article.getGpxFile(); + final GPXFile gpx; + if (article instanceof TravelGpx) { + gpx = buildTravelGpxFile((TravelGpx) article); + } else { + gpx = article.getGpxFile(); + } File file = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article)); writeGpxFile(file, gpx); return file; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java index 8996e4d375..89fc06ed37 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java @@ -7,6 +7,8 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.DrawableRes; +import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; @@ -16,16 +18,20 @@ import com.squareup.picasso.Callback; import com.squareup.picasso.Picasso; import com.squareup.picasso.RequestCreator; +import net.osmand.AndroidUtils; import net.osmand.PicassoUtils; +import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.widgets.tools.CropCircleTransformation; import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.WikivoyageUtils; import net.osmand.plus.wikivoyage.data.TravelArticle; +import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; import java.util.ArrayList; import java.util.List; @@ -33,7 +39,8 @@ import java.util.List; public class SavedArticlesRvAdapter extends RecyclerView.Adapter { private static final int HEADER_TYPE = 0; - private static final int ITEM_TYPE = 1; + private static final int ARTICLE_TYPE = 1; + private static final int GPX_TYPE = 2; private final OsmandApplication app; private final OsmandSettings settings; @@ -45,6 +52,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter Date: Wed, 27 Jan 2021 10:20:55 +0200 Subject: [PATCH 04/28] Open mapActivity --- .../plus/wikivoyage/data/TravelObfHelper.java | 3 +++ .../explore/ExploreTabFragment.java | 2 +- .../explore/travelcards/TravelGpxCard.java | 21 ++++++++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 13c4fffa49..a44b131a66 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -177,6 +177,8 @@ public class TravelObfHelper implements TravelHelper { res.file = file; String title = amenity.getName("en"); res.title = capitalizeFirstLetter(getGpxTitle(Algorithms.isEmpty(title) ? amenity.getName() : title)); + res.lat = amenity.getLocation().getLatitude(); + res.lon = amenity.getLocation().getLongitude(); res.routeId = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID)); try { res.totalDistance = Float.parseFloat(Algorithms.emptyIfNull(amenity.getTagContent(DISTANCE))); @@ -319,6 +321,7 @@ public class TravelObfHelper implements TravelHelper { gpxFile.tracks = new ArrayList<>(); gpxFile.tracks.add(track); } + article.gpxFile = gpxFile; return gpxFile; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index ce6f4475af..9055acd4ed 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -181,7 +181,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv List popularArticles = app.getTravelHelper().getPopularArticles(); for (TravelArticle article : popularArticles) { if (article instanceof TravelGpx) { - items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, activity.getSupportFragmentManager())); + items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, getActivity())); } else { items.add(new ArticleTravelCard(app, nightMode, article, activity.getSupportFragmentManager())); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index ded096a260..3cfbc91c04 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -5,13 +5,15 @@ import android.view.View; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; import net.osmand.AndroidUtils; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; @@ -22,15 +24,15 @@ public class TravelGpxCard extends BaseTravelCard { private final TravelGpx article; private final Drawable readIcon; - private final FragmentManager fragmentManager; + private final FragmentActivity activity; private boolean isLastItem; public TravelGpxCard(@NonNull OsmandApplication app, boolean nightMode, @NonNull TravelGpx article, - @NonNull FragmentManager fragmentManager) { + @NonNull FragmentActivity activity) { super(app, nightMode); this.article = article; readIcon = getActiveIcon(R.drawable.ic_action_read_article); - this.fragmentManager = fragmentManager; + this.activity = activity; } @Override @@ -49,10 +51,15 @@ public class TravelGpxCard extends BaseTravelCard { View.OnClickListener readClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - if (fragmentManager != null) { -// WikivoyageArticleDialogFragment.showInstance(app, fragmentManager, -// article.generateIdentifier(), article.getLang()); + if (activity != null) { app.getTravelHelper().createGpxFile(article); + final OsmandSettings settings = app.getSettings(); + settings.setMapLocationToShow(article.getLat(), article.getLon(), + settings.getLastKnownMapZoom(), + null, + false, + article.getGpxFile()); + MapActivity.launchMapActivityMoveToTop(activity); } } }; From 048f6035cbf1a00ed8140c68f05f2250b883d547 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 27 Jan 2021 12:02:57 +0200 Subject: [PATCH 05/28] open TrackMenuFragment --- .../explore/SavedArticlesRvAdapter.java | 9 +++++++-- .../explore/SavedArticlesTabFragment.java | 20 +++++++++++++++---- .../explore/travelcards/TravelGpxCard.java | 15 +++++--------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java index 89fc06ed37..bbc0cb6da7 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java @@ -11,6 +11,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.snackbar.Snackbar; @@ -25,6 +26,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.widgets.tools.CropCircleTransformation; import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.WikivoyageUtils; @@ -33,6 +35,7 @@ import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; +import java.io.File; import java.util.ArrayList; import java.util.List; @@ -58,7 +61,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter Date: Wed, 27 Jan 2021 16:33:49 +0200 Subject: [PATCH 06/28] Minor code cleanup --- .../data/TravelLocalDataHelper.java | 23 +++++-------------- .../plus/wikivoyage/data/TravelObfHelper.java | 23 +++++++++++-------- .../explore/SavedArticlesRvAdapter.java | 5 +--- .../explore/SavedArticlesTabFragment.java | 2 +- 4 files changed, 22 insertions(+), 31 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index e27b3363b6..ae1c22b587 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -480,23 +480,12 @@ public class TravelLocalDataHelper { SQLiteConnection conn = openConnection(false); if (conn != null) { try { - String query; - Object[] parameters; - if (article.lang == null) { - query = "DELETE FROM " + BOOKMARKS_TABLE_NAME + - " WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" + - " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + - " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?"; - parameters = new Object[]{article.title, article.routeId, travelBook}; - } else { - query = "DELETE FROM " + BOOKMARKS_TABLE_NAME + - " WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" + - " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + - " AND " + BOOKMARKS_COL_LANG + " = ?" + - " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?"; - parameters = new Object[]{article.title, article.routeId, article.lang, travelBook}; - } - conn.execSQL(query, parameters); + String query = "DELETE FROM " + BOOKMARKS_TABLE_NAME + + " WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" + + " AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" + + " AND " + BOOKMARKS_COL_LANG + ((article.lang != null) ? " = '" + article.lang + "'" : " IS NULL") + + " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?"; + conn.execSQL(query, new Object[]{article.title, article.routeId, travelBook}); } finally { conn.close(); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 17dd2c71c0..69c1506b9b 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -9,7 +9,6 @@ import androidx.annotation.Nullable; import net.osmand.Collator; import net.osmand.CollatorStringMatcher.StringMatcherMode; -import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.IndexConstants; import net.osmand.OsmAndCollator; @@ -49,6 +48,8 @@ import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import static net.osmand.GPXUtilities.Track; +import static net.osmand.GPXUtilities.TrkSegment; import static net.osmand.GPXUtilities.WptPt; import static net.osmand.GPXUtilities.writeGpxFile; import static net.osmand.plus.helpers.GpxUiHelper.getGpxTitle; @@ -69,6 +70,8 @@ public class TravelObfHelper implements TravelHelper { public static final int ARTICLE_SEARCH_RADIUS = 50000; public static final int GPX_TRACKS_SEARCH_RADIUS = 10000; public static final int MAX_POPULAR_ARTICLES_COUNT = 30; + public static final int REF_KEY = 2; + public static final int NAME_KEY = 1; private final OsmandApplication app; private final Collator collator; @@ -178,7 +181,7 @@ public class TravelObfHelper implements TravelHelper { TravelGpx res = new TravelGpx(); res.file = file; String title = amenity.getName("en"); - res.title = capitalizeFirstLetter(getGpxTitle(Algorithms.isEmpty(title) ? amenity.getName() : title)); + res.title = createTitle(Algorithms.isEmpty(title) ? amenity.getName() : title); res.lat = amenity.getLocation().getLatitude(); res.lon = amenity.getLocation().getLongitude(); res.routeId = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID)); @@ -265,8 +268,8 @@ public class TravelObfHelper implements TravelHelper { @Override public boolean publish(BinaryMapDataObject object) { if (object.getPointsLength() > 1) { - if (object.getObjectNames().get(2).equals(ref) - && capitalizeFirstLetter(getGpxTitle(object.getObjectNames().get(1))).equals(article.title)) { + if (object.getObjectNames().get(REF_KEY).equals(ref) + && createTitle(object.getObjectNames().get(NAME_KEY)).equals(article.title)) { segmentList.add(object); } } @@ -288,17 +291,15 @@ public class TravelObfHelper implements TravelHelper { } GPXFile gpxFile = null; if (!segmentList.isEmpty()) { - GPXUtilities.Track track = new GPXUtilities.Track(); + Track track = new Track(); for (BinaryMapDataObject segment : segmentList) { - List pointList = new ArrayList<>(); - GPXUtilities.TrkSegment trkSegment = new GPXUtilities.TrkSegment(); + TrkSegment trkSegment = new TrkSegment(); for (int i = 0; i < segment.getPointsLength(); i++) { WptPt point = new WptPt(); point.lat = MapUtils.get31LatitudeY(segment.getPoint31YTile(i)); point.lon = MapUtils.get31LongitudeX(segment.getPoint31XTile(i)); - pointList.add(point); + trkSegment.points.add(point); } - trkSegment.points = pointList; track.segments.add(trkSegment); } gpxFile = new GPXFile(article.getTitle(), article.getLang(), ""); @@ -309,6 +310,10 @@ public class TravelObfHelper implements TravelHelper { return gpxFile; } + private String createTitle(String name) { + return capitalizeFirstLetter(getGpxTitle(name)); + } + @NonNull private synchronized List getPointList(@NonNull final TravelArticle article) { final List pointList = new ArrayList<>(); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java index bbc0cb6da7..a01de6e6cb 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java @@ -11,7 +11,6 @@ import androidx.annotation.DrawableRes; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.snackbar.Snackbar; @@ -26,7 +25,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.widgets.tools.CropCircleTransformation; import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.WikivoyageUtils; @@ -35,7 +33,6 @@ import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; -import java.io.File; import java.util.ArrayList; import java.util.List; @@ -61,7 +58,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter Date: Wed, 27 Jan 2021 19:27:00 +0200 Subject: [PATCH 07/28] Add default height states for gpx menu tabs --- .../osmand/plus/base/ContextMenuFragment.java | 8 +++++ .../osmand/plus/track/TrackMenuFragment.java | 31 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java index 4cc90afd96..4b625e9515 100644 --- a/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/ContextMenuFragment.java @@ -946,6 +946,11 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment @TargetApi(Build.VERSION_CODES.JELLY_BEAN) protected void runLayoutListener() { + runLayoutListener(null); + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + protected void runLayoutListener(final Runnable runnable) { if (view != null) { ViewTreeObserver vto = view.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @@ -974,6 +979,9 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment int menuState = getCurrentMenuState(); listener.onContextMenuStateChanged(ContextMenuFragment.this, menuState, menuState); } + if (runnable != null) { + runnable.run(); + } } } }); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index a551ba2330..6c9857e11e 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -270,7 +270,18 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card setupToolbar(); updateHeader(); setupButtons(view); - runLayoutListener(); + runLayoutListener(new Runnable() { + @Override + public void run() { + if (menuType == TrackMenuType.OPTIONS) { + openMenuFullScreen(); + } else if (menuType == TrackMenuType.OVERVIEW) { + openMenuHeaderOnly(); + } else { + openMenuHalfScreen(); + } + } + }); } return view; } @@ -837,6 +848,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card menuType = type; setupCards(); updateHeader(); + updateMenuState(); break; } } @@ -845,6 +857,23 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card }); } + + private void updateMenuState() { + runLayoutListener(new Runnable() { + + @Override + public void run() { + if (menuType == TrackMenuType.OPTIONS) { + openMenuFullScreen(); + } else if (menuType == TrackMenuType.OVERVIEW) { + openMenuHeaderOnly(); + } else { + openMenuHalfScreen(); + } + } + }); + } + @Override public void updateContent() { if (segmentsCard != null) { From cc7ec8e0d9fc52ecd588ee0ba37ab116a390dd25 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 09:38:00 +0200 Subject: [PATCH 08/28] Add group to markers in gpx menu --- .../EditTrackGroupDialogFragment.java | 68 +++++++++++++++---- .../osmand/plus/track/TrackMenuFragment.java | 30 ++++---- 2 files changed, 68 insertions(+), 30 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java index 19c398685c..fa7bff99ed 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java @@ -30,6 +30,7 @@ import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; import net.osmand.data.FavouritePoint; import net.osmand.plus.FavouritesDbHelper; +import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; @@ -70,19 +71,32 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment public static final String TAG = EditTrackGroupDialogFragment.class.getSimpleName(); private OsmandApplication app; + private GpxSelectionHelper selectedGpxHelper; + private MapMarkersHelper mapMarkersHelper; private GpxDisplayGroup group; @Override public void createMenuItems(Bundle savedInstanceState) { - app = requiredMyApplication(); if (group == null) { return; } + app = requiredMyApplication(); + selectedGpxHelper = app.getSelectedGpxHelper(); + mapMarkersHelper = app.getMapMarkersHelper(); items.add(new TitleItem(getCategoryName(app, group.getName()))); + GPXFile gpxFile = group.getGpx(); + + boolean currentTrack = group.getGpx().showCurrentTrack; + + SelectedGpxFile selectedGpxFile; + if (currentTrack) { + selectedGpxFile = selectedGpxHelper.getSelectedCurrentRecordingTrack(); + } else { + selectedGpxFile = selectedGpxHelper.getSelectedFileByPath(gpxFile.path); + } boolean trackPoints = group.getType() == GpxDisplayItemType.TRACK_POINTS; - SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(group.getGpx().path); if (trackPoints && selectedGpxFile != null) { items.add(createShowOnMapItem(selectedGpxFile)); } @@ -92,7 +106,9 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment } items.add(new OptionsDividerItem(app)); -// items.add(createCopyToMarkersItem()); + if (!currentTrack) { + items.add(createCopyToMarkersItem(gpxFile)); + } items.add(createCopyToFavoritesItem()); items.add(new OptionsDividerItem(app)); @@ -175,27 +191,51 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment .create(); } - private BaseBottomSheetItem createCopyToMarkersItem() { + private BaseBottomSheetItem createCopyToMarkersItem(final GPXFile gpxFile) { + final MapMarkersGroup markersGroup = getOrCreateMarkersGroup(gpxFile); + final Set categories = markersGroup.getWptCategories(); + final boolean synced = categories != null && categories.contains(group.getName()); + return new SimpleBottomSheetItem.Builder() - .setIcon(getContentIcon(R.drawable.ic_action_copy)) - .setTitle(getString(R.string.copy_to_map_markers)) - .setLayoutId(R.layout.bottom_sheet_item_simple) + .setIcon(getContentIcon(synced ? R.drawable.ic_action_delete_dark : R.drawable.ic_action_copy)) + .setTitle(getString(synced ? R.string.remove_from_map_markers : R.string.copy_to_map_markers)) .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp) .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { -// MapMarkersHelper markersHelper = app.getMapMarkersHelper(); -// MapMarkersGroup markersGroup = markersHelper.getMarkersGroup(group); -// if (markersGroup != null) { -// markersHelper.removeMarkersGroup(markersGroup); -// } else { -// markersHelper.addOrEnableGroup(group); -// } + updateGroupWptCategory(gpxFile, markersGroup, categories, synced); + dismiss(); } }) .create(); } + private void updateGroupWptCategory(GPXFile gpxFile, MapMarkersGroup markersGroup, Set categories, boolean synced) { + SelectedGpxFile selectedGpxFile = selectedGpxHelper.getSelectedFileByPath(gpxFile.path); + if (selectedGpxFile == null) { + selectedGpxHelper.selectGpxFile(gpxFile, true, false, false, false, false); + } + Set selectedCategories = new HashSet<>(); + if (categories != null) { + selectedCategories.addAll(categories); + } + if (synced) { + selectedCategories.remove(group.getName()); + } else { + selectedCategories.add(group.getName()); + } + mapMarkersHelper.updateGroupWptCategories(markersGroup, selectedCategories); + mapMarkersHelper.runSynchronization(markersGroup); + } + + private MapMarkersGroup getOrCreateMarkersGroup(GPXFile gpxFile) { + MapMarkersGroup markersGroup = mapMarkersHelper.getMarkersGroup(gpxFile); + if (markersGroup == null) { + markersGroup = mapMarkersHelper.addOrEnableGroup(gpxFile); + } + return markersGroup; + } + private BaseBottomSheetItem createCopyToFavoritesItem() { return new SimpleBottomSheetItem.Builder() .setIcon(getContentIcon(R.drawable.ic_action_copy)) diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index 6c9857e11e..dd2ca7f465 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -808,7 +808,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card @Override protected void onHeaderClick() { - adjustMapPosition(getViewY()); + updateMenuState(); } private void adjustMapPosition(int y) { @@ -848,7 +848,12 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card menuType = type; setupCards(); updateHeader(); - updateMenuState(); + runLayoutListener(new Runnable() { + @Override + public void run() { + updateMenuState(); + } + }); break; } } @@ -857,21 +862,14 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card }); } - private void updateMenuState() { - runLayoutListener(new Runnable() { - - @Override - public void run() { - if (menuType == TrackMenuType.OPTIONS) { - openMenuFullScreen(); - } else if (menuType == TrackMenuType.OVERVIEW) { - openMenuHeaderOnly(); - } else { - openMenuHalfScreen(); - } - } - }); + if (menuType == TrackMenuType.OPTIONS) { + openMenuFullScreen(); + } else if (menuType == TrackMenuType.OVERVIEW) { + openMenuHeaderOnly(); + } else { + openMenuHalfScreen(); + } } @Override From e28246975000dbeb230209653e6a0e2282182ec9 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 10:49:44 +0200 Subject: [PATCH 09/28] Remove unnecessary code --- OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index dd2ca7f465..cfc6610b5b 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -273,13 +273,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card runLayoutListener(new Runnable() { @Override public void run() { - if (menuType == TrackMenuType.OPTIONS) { - openMenuFullScreen(); - } else if (menuType == TrackMenuType.OVERVIEW) { - openMenuHeaderOnly(); - } else { - openMenuHalfScreen(); - } + updateMenuState(); } }); } From 08621d17fdadcc19ce80aba303b637f66c5b6f53 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 11:35:23 +0200 Subject: [PATCH 10/28] Add new method for updating menu state after layout calculation --- .../osmand/plus/track/TrackMenuFragment.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index cfc6610b5b..7f3fef69ed 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -270,12 +270,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card setupToolbar(); updateHeader(); setupButtons(view); - runLayoutListener(new Runnable() { - @Override - public void run() { - updateMenuState(); - } - }); + calculateLayoutAndUpdateMenuState(); } return view; } @@ -842,12 +837,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card menuType = type; setupCards(); updateHeader(); - runLayoutListener(new Runnable() { - @Override - public void run() { - updateMenuState(); - } - }); + calculateLayoutAndUpdateMenuState(); break; } } @@ -856,6 +846,15 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card }); } + private void calculateLayoutAndUpdateMenuState() { + runLayoutListener(new Runnable() { + @Override + public void run() { + updateMenuState(); + } + }); + } + private void updateMenuState() { if (menuType == TrackMenuType.OPTIONS) { openMenuFullScreen(); From 1b1ed6e02f69a9b8d671ee46fa0f4257af4602a0 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 13:00:51 +0200 Subject: [PATCH 11/28] Show my location button and change header height for overview tab --- OsmAnd/res/layout/track_menu.xml | 7 +++++++ OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/layout/track_menu.xml b/OsmAnd/res/layout/track_menu.xml index 671a9332f1..db0f8a47f9 100644 --- a/OsmAnd/res/layout/track_menu.xml +++ b/OsmAnd/res/layout/track_menu.xml @@ -91,6 +91,13 @@ + + Date: Thu, 28 Jan 2021 14:33:31 +0200 Subject: [PATCH 12/28] Fix back to context menu from gpx menu --- .../controllers/SelectedGpxMenuController.java | 4 +--- .../src/net/osmand/plus/track/TrackMenuFragment.java | 12 ++++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java index 427e0cce35..acdce38b90 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java @@ -42,9 +42,7 @@ public class SelectedGpxMenuController extends MenuController { leftTitleButtonController = new TitleButtonController() { @Override public void buttonPressed() { - SelectedGpxFile selectedGpxFile = selectedGpxPoint.getSelectedGpxFile(); - mapActivity.getContextMenu().hide(false); - TrackMenuFragment.showInstance(mapActivity, selectedGpxFile.getGpxFile().path, selectedGpxFile.isShowCurrentTrack()); + TrackMenuFragment.showInstance(mapActivity, selectedGpxPoint.getSelectedGpxFile()); } }; leftTitleButtonController.caption = mapActivity.getString(R.string.shared_string_open_track); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index 533268fd62..b145fc903d 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -227,11 +227,15 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card FragmentActivity activity = requireMyActivity(); activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { public void handleOnBackPressed() { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - mapActivity.launchPrevActivityIntent(); + if (getCurrentMenuState() != MenuState.HEADER_ONLY && isPortrait()) { + openMenuHeaderOnly(); + } else { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null && mapActivity.getSupportFragmentManager().getBackStackEntryCount() == 1) { + mapActivity.launchPrevActivityIntent(); + } + dismiss(); } - dismiss(); } }); } From c0727f658fc2eeff3e5a37acded82e4bbc27cc7f Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 15:04:41 +0200 Subject: [PATCH 13/28] Fix back from track appearance screen to trip recording dialog --- .../osmand/plus/activities/MapActivity.java | 2 +- .../monitoring/TripRecordingBottomSheet.java | 2 +- .../plus/track/TrackAppearanceFragment.java | 26 ++++++++++--------- .../osmand/plus/track/TrackMenuFragment.java | 2 +- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 0de562fa2b..12f66f8c49 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -1200,7 +1200,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFile.path); } - TrackAppearanceFragment.showInstance(this, selectedGpxFile); + TrackAppearanceFragment.showInstance(this, selectedGpxFile, null); } else if (toShow instanceof QuadRect) { QuadRect qr = (QuadRect) toShow; mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 789fc0aeb0..178e662176 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -90,7 +90,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { if (mapActivity != null) { hide(); SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); - TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile); + TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile, TripRecordingBottomSheet.this); } } }); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index ddc102adc9..522103ac02 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -19,6 +19,7 @@ import androidx.activity.OnBackPressedCallback; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -37,6 +38,7 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.ContextMenuFragment; import net.osmand.plus.base.ContextMenuScrollFragment; import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem; @@ -165,16 +167,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { public void handleOnBackPressed() { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - TripRecordingBottomSheet fragment = mapActivity.getTripRecordingBottomSheet(); - if (fragment != null) { - fragment.show(); - } else { - mapActivity.launchPrevActivityIntent(); - } - dismissImmediate(); - } + dismiss(); } }); } @@ -385,6 +378,14 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement return y; } + @Override + public void onContextMenuDismiss(@NonNull ContextMenuFragment fragment) { + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingBottomSheet) { + ((TripRecordingBottomSheet) target).show(); + } + } + private void updateAppearanceIcon() { Drawable icon = getTrackIcon(app, trackDrawInfo.getWidth(), trackDrawInfo.isShowArrows(), trackDrawInfo.getColor()); trackIcon.setImageDrawable(icon); @@ -725,11 +726,12 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement return totalScreenHeight - frameTotalHeight; } - public static boolean showInstance(@NonNull MapActivity mapActivity, @NonNull SelectedGpxFile selectedGpxFile) { + public static boolean showInstance(@NonNull MapActivity mapActivity, @NonNull SelectedGpxFile selectedGpxFile, Fragment target) { try { TrackAppearanceFragment fragment = new TrackAppearanceFragment(); - fragment.setSelectedGpxFile(selectedGpxFile); fragment.setRetainInstance(true); + fragment.setSelectedGpxFile(selectedGpxFile); + fragment.setTargetFragment(target, 0); mapActivity.getSupportFragmentManager() .beginTransaction() diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index b145fc903d..597dc4c485 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -663,7 +663,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card app.getSelectedGpxHelper().selectGpxFile(gpxFile, gpxFileSelected, false); mapActivity.refreshMap(); } else if (buttonIndex == APPEARANCE_BUTTON_INDEX) { - TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile); + TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile, this); } else if (buttonIndex == DIRECTIONS_BUTTON_INDEX) { MapActivityActions mapActions = mapActivity.getMapActions(); if (app.getRoutingHelper().isFollowingMode()) { From 2bd2839f495cde38c94748553dad521a4e9c5d05 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 15:32:21 +0200 Subject: [PATCH 14/28] Fix context menu visibility --- .../controllers/SelectedGpxMenuController.java | 1 + .../net/osmand/plus/track/TrackMenuFragment.java | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java index acdce38b90..5ea0766469 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java @@ -42,6 +42,7 @@ public class SelectedGpxMenuController extends MenuController { leftTitleButtonController = new TitleButtonController() { @Override public void buttonPressed() { + mapContextMenu.hide(false); TrackMenuFragment.showInstance(mapActivity, selectedGpxPoint.getSelectedGpxFile()); } }; diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index 597dc4c485..0c7c88b7a3 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -230,11 +230,18 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card if (getCurrentMenuState() != MenuState.HEADER_ONLY && isPortrait()) { openMenuHeaderOnly(); } else { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null && mapActivity.getSupportFragmentManager().getBackStackEntryCount() == 1) { - mapActivity.launchPrevActivityIntent(); - } dismiss(); + + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + MapContextMenu contextMenu = mapActivity.getContextMenu(); + if (contextMenu.isActive() && contextMenu.getPointDescription() != null + && contextMenu.getPointDescription().isGpxPoint()) { + contextMenu.show(); + } else { + mapActivity.launchPrevActivityIntent(); + } + } } } }); From 593657475a93ac040d97a6454edfebd8d2e240c1 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 16:06:10 +0200 Subject: [PATCH 15/28] Fix menu drag under toolbar --- OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index 0c7c88b7a3..492ac2ff3d 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -193,6 +193,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card return 0.5f; } + public int getMinY() { + return getFullScreenTopPosY(); + } + @Override public int getSupportedMenuStatesPortrait() { return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN; From a9761c1a39fa36b34b313e487aed7ed7aeaf9dca Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 16:30:29 +0200 Subject: [PATCH 16/28] UI improvements --- .../net/osmand/plus/track/TrackMenuFragment.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index 492ac2ff3d..9147de6de9 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -186,7 +186,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card @Override public int getToolbarHeight() { - return toolbarHeightPx; + return isPortrait() ? toolbarHeightPx : 0; } public float getMiddleStateKoef() { @@ -286,6 +286,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card setupToolbar(); updateHeader(); setupButtons(view); + updateCardsLayout(); calculateLayoutAndUpdateMenuState(); } return view; @@ -443,6 +444,17 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card } } + private void updateCardsLayout() { + FrameLayout bottomContainer = getBottomContainer(); + if (menuType == TrackMenuType.OPTIONS) { + AndroidUtils.setBackground(app, bottomContainer, isNightMode(), + R.color.list_background_color_light, R.color.list_background_color_dark); + } else { + AndroidUtils.setBackground(app, bottomContainer, isNightMode(), + R.color.activity_background_color_light, R.color.activity_background_color_dark); + } + } + @Override protected void calculateLayout(View view, boolean initLayout) { menuTitleHeight = routeMenuTopShadowAll.getHeight() @@ -852,6 +864,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card menuType = type; setupCards(); updateHeader(); + updateCardsLayout(); calculateLayoutAndUpdateMenuState(); break; } From cbebccb12374ee1ac61ec5a24954e901425da97f Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 28 Jan 2021 16:42:08 +0200 Subject: [PATCH 17/28] Small refactoring --- .../data/TravelLocalDataHelper.java | 6 ++--- .../plus/wikivoyage/data/TravelObfHelper.java | 25 +++++++++++++++---- .../explore/travelcards/TravelGpxCard.java | 3 +-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index ae1c22b587..a95438a77e 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -143,10 +143,8 @@ public class TravelLocalDataHelper { @Nullable private TravelArticle getArticle(String title, String lang) { for (TravelArticle article : savedArticles) { - if (article.lang == null && lang == null && article.title != null && article.title.equals(title)) { - return article; - } - if (article.title != null && article.title.equals(title) && article.lang != null && article.lang.equals(lang)) { + if (article.title != null && article.title.equals(title) + && (article.lang != null && article.lang.equals(lang) || article.lang == null && lang == null)) { return article; } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 69c1506b9b..ab9e926c10 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -48,6 +48,8 @@ import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import gnu.trove.iterator.TIntObjectIterator; + import static net.osmand.GPXUtilities.Track; import static net.osmand.GPXUtilities.TrkSegment; import static net.osmand.GPXUtilities.WptPt; @@ -70,8 +72,8 @@ public class TravelObfHelper implements TravelHelper { public static final int ARTICLE_SEARCH_RADIUS = 50000; public static final int GPX_TRACKS_SEARCH_RADIUS = 10000; public static final int MAX_POPULAR_ARTICLES_COUNT = 30; - public static final int REF_KEY = 2; - public static final int NAME_KEY = 1; + public static final String REF_TAG = "ref"; + public static final String NAME_TAG = "name"; private final OsmandApplication app; private final Collator collator; @@ -163,7 +165,7 @@ public class TravelObfHelper implements TravelHelper { private TravelArticle cacheTravelArticles(File file, Amenity amenity, String lang, boolean readPoints, @Nullable GpxReadCallback callback) { TravelArticle article = null; Map articles; - if (amenity.getSubType().equals(ROUTE_TRACK)) { + if (Algorithms.objectEquals(amenity.getSubType(), ROUTE_TRACK)) { articles = readRoutePoint(file, amenity); } else { articles = readArticles(file, amenity); @@ -268,8 +270,8 @@ public class TravelObfHelper implements TravelHelper { @Override public boolean publish(BinaryMapDataObject object) { if (object.getPointsLength() > 1) { - if (object.getObjectNames().get(REF_KEY).equals(ref) - && createTitle(object.getObjectNames().get(NAME_KEY)).equals(article.title)) { + if (getTagValue(object, REF_TAG).equals(ref) + && createTitle(getTagValue(object, NAME_TAG)).equals(article.title)) { segmentList.add(object); } } @@ -310,6 +312,19 @@ public class TravelObfHelper implements TravelHelper { return gpxFile; } + private String getTagValue(BinaryMapDataObject object, String tag) { + BinaryMapIndexReader.MapIndex mi = object.getMapIndex(); + TIntObjectIterator it = object.getObjectNames().iterator(); + while (it.hasNext()) { + it.advance(); + BinaryMapIndexReader.TagValuePair tp = mi.decodeType(it.key()); + if (tp.tag.equals(tag)) { + return it.value(); + } + } + return ""; + } + private String createTitle(String name) { return capitalizeFirstLetter(getGpxTitle(name)); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index 515a5f5b06..1bc2409621 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -13,7 +13,6 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.track.TrackMenuFragment; -import net.osmand.plus.wikipedia.WikiArticleHelper; import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; @@ -43,7 +42,7 @@ public class TravelGpxCard extends BaseTravelCard { holder.title.setText(article.getTitle()); Drawable icon = getActiveIcon(R.drawable.ic_action_user_account_16); holder.user.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); - holder.user.setText(WikiArticleHelper.getPartialContent(article.user)); + holder.user.setText(article.user); AndroidUtils.setBackground(app, holder.user, nightMode, R.drawable.btn_border_bg_light, R.drawable.btn_border_bg_dark); holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance, app)); holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp, app)); From 25f7a2a8b309a0bfdbfa1c44a2a90613027ce14a Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 28 Jan 2021 16:00:47 +0100 Subject: [PATCH 18/28] Moved to docs --- GPX.md | 157 --------------------------------------------------------- 1 file changed, 157 deletions(-) delete mode 100644 GPX.md diff --git a/GPX.md b/GPX.md deleted file mode 100644 index b3f1e441e4..0000000000 --- a/GPX.md +++ /dev/null @@ -1,157 +0,0 @@ -The OsmAnd's GPX file format conforms to the GPX 1.1 specification with additional data written as extensions. There are several sections of such data: - -## Track appearance -The following parameters are used to customize the appearance of a track on the map. They are used inside the "gpx" tag and apply to all tracks contained in the gpx. -#### Parameters -* **show_arrows** [*true, false*] - show / hide arrows along the path line. -* **width** [*thin, medium, bold, 1-24*] - width of the track line on the map. The thin, medium, and bold are style depended values (should be defined as currentTrackWidth attribute). -* **color** [*#AARRGGBB, #RRGGBB*] - color of a track line on the map. Hex value. -* **split_type** [*no_split, distance, time*] - split type for a track. -* **split_interval** [*double*] - split interval for a track. Distance (meters), time (seconds). - -#### Example: -```xml - -... - - true - #4e4eff - distance - 2000.0 - bold - - -``` -## Details of a track point (trkpt) -Written to a gpx file while recording a track. -* **speed** (meters per second) -* **heading** (0-359 degrees) - -#### Example: -```xml - - 203 - - 3 - - 273 - 5.02 - - -``` - -## Calculated route(s) -This data contains all details of a route built with **OsmAnd** (route segments, turns, road names, road types, restrictions, etc.). The route can be completely restored as if just built, even in the absence of the respective offline maps. - -A gpx file may contain several routes. Each of them is contained in a specific segment under **trkseg** / **extensions**. A gpx file is saved in this form when exporting a constructed route or when saving a track that consists of several separate segments via the **Plan a route** functionality. -**Plan a route** also adds one (or several, in accordance with the number of contained separate segments / tracks) **rte** blocks to the gpx file, containing route key points (**rtept**). -#### Gpx structure: -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - ... - - ... - - - -``` - -#### Example: -```xml - - - Fri 06 Nov 2020 - - - Fri 06 Nov 2020 - - - 0.801 - - - 0.998 - - - 1 - - - 0.963 - - - 0.899 - - - .... - - - - - - - - ... - - - - - - - - ... - - - - - - - - - pedestrian - 0 - - - - - pedestrian - 24 - - - - - pedestrian - 89 - - - - - pedestrian - 121 - - - - -``` From f4c5685ff5ce15d51ee0ecf0086a9d06a49494e2 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 28 Jan 2021 16:03:32 +0100 Subject: [PATCH 19/28] Update no_translate.xml --- OsmAnd/no_translate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/no_translate.xml b/OsmAnd/no_translate.xml index 92d3a4034f..d5ecc7c149 100644 --- a/OsmAnd/no_translate.xml +++ b/OsmAnd/no_translate.xml @@ -40,7 +40,7 @@ items modified OsmAnd Unlimited Markers - https://test.openplacereviews.org/ + https://openplacereviews.org/ https://test.openplacereviews.org/ v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J From 0f994e2da6133d79a12cf8ae43b34e2c0df05421 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 28 Jan 2021 17:21:32 +0200 Subject: [PATCH 20/28] Small refactoring --- .../osmand/plus/wikivoyage/data/TravelLocalDataHelper.java | 4 ++-- .../src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index a95438a77e..c2ccc442c3 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -143,8 +143,8 @@ public class TravelLocalDataHelper { @Nullable private TravelArticle getArticle(String title, String lang) { for (TravelArticle article : savedArticles) { - if (article.title != null && article.title.equals(title) - && (article.lang != null && article.lang.equals(lang) || article.lang == null && lang == null)) { + if (Algorithms.stringsEqual(article.title, title) + && Algorithms.stringsEqual(article.lang, lang)) { return article; } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index ab9e926c10..294cf2cd13 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -165,7 +165,7 @@ public class TravelObfHelper implements TravelHelper { private TravelArticle cacheTravelArticles(File file, Amenity amenity, String lang, boolean readPoints, @Nullable GpxReadCallback callback) { TravelArticle article = null; Map articles; - if (Algorithms.objectEquals(amenity.getSubType(), ROUTE_TRACK)) { + if (ROUTE_TRACK.equals(amenity.getSubType())) { articles = readRoutePoint(file, amenity); } else { articles = readArticles(file, amenity); From f87592c4adf0ff4acc883c700cebf7950026edf6 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 28 Jan 2021 19:04:14 +0300 Subject: [PATCH 21/28] Travel fixes --- .../net/osmand/plus/OsmandApplication.java | 13 ++++++++++ .../plus/activities/MapActivityActions.java | 2 +- .../data/TravelLocalDataHelper.java | 26 +++++++++++++++++++ .../plus/wikivoyage/data/TravelObfHelper.java | 14 +++++----- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 842a36237e..6b9aa4d0a4 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -210,6 +210,8 @@ public class OsmandApplication extends MultiDexApplication { File mapillaryVectorTilesPath = new File(tilesPath, TileSourceManager.getMapillaryVectorSource().getName()); Algorithms.removeAllFiles(mapillaryRasterTilesPath); Algorithms.removeAllFiles(mapillaryVectorTilesPath); + // Remove travel sqlite db files + removeSqliteDbTravelFiles(); } checkPreferredLocale(); @@ -234,6 +236,17 @@ public class OsmandApplication extends MultiDexApplication { return externalStorageDirectoryReadOnly; } + private void removeSqliteDbTravelFiles() { + File[] files = getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).listFiles(); + if (files != null) { + for (File file : files) { + if (file.getName().endsWith(IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT)) { + file.delete(); + } + } + } + } + @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index b5dd0dc3ea..258ed7be38 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -928,7 +928,7 @@ public class MapActivityActions implements DialogProvider { MapActivity.clearPrevActivityIntent(); TravelHelper travelHelper = getMyApplication().getTravelHelper(); travelHelper.initializeDataOnAppStartup(); - if (!travelHelper.isAnyTravelBookPresent()) { + if (!travelHelper.isAnyTravelBookPresent() && !travelHelper.getBookmarksHelper().hasSavedArticles()) { WikivoyageWelcomeDialogFragment.showInstance(mapActivity.getSupportFragmentManager()); } else { Intent intent = new Intent(mapActivity, WikivoyageExploreActivity.class); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index 02ee5a32c8..151a0ef424 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -1,6 +1,9 @@ package net.osmand.plus.wikivoyage.data; +import android.database.DatabaseUtils; +import android.database.sqlite.SQLiteDatabase; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -100,6 +103,10 @@ public class TravelLocalDataHelper { } } + public boolean hasSavedArticles() { + return !savedArticles.isEmpty() || dbHelper.hasSavedArticles(); + } + @NonNull public List getSavedArticles() { return new ArrayList<>(savedArticles); @@ -438,6 +445,25 @@ public class TravelLocalDataHelper { return res; } + boolean hasSavedArticles() { + int count = 0; + SQLiteConnection conn = openConnection(true); + if (conn != null) { + try { + SQLiteCursor cursor = conn.rawQuery("SELECT COUNT(*) FROM " + BOOKMARKS_TABLE_NAME, null); + if (cursor != null) { + if (cursor.moveToFirst()) { + count = cursor.getInt(0); + } + cursor.close(); + } + } finally { + conn.close(); + } + } + return count > 0; + } + void addSavedArticle(@NonNull TravelArticle article) { String travelBook = article.getTravelBook(context); if (travelBook == null) { diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 0f14896a94..1336dcc2f6 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -485,7 +485,7 @@ public class TravelObfHelper implements TravelHelper { @Nullable private TravelArticle getCachedArticle(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, - boolean forceReadPoints, @Nullable GpxReadCallback callback) { + boolean readGpx, @Nullable GpxReadCallback callback) { TravelArticle article = null; Map articles = cachedArticles.get(articleId); if (articles != null) { @@ -502,9 +502,9 @@ public class TravelObfHelper implements TravelHelper { } } if (article == null && articles == null) { - article = findArticleById(articleId, lang, callback); + article = findArticleById(articleId, lang, readGpx, callback); } - if (article != null && forceReadPoints && !Algorithms.isEmpty(lang)) { + if (article != null && readGpx && !Algorithms.isEmpty(lang)) { readGpxFile(article, callback); } return article; @@ -518,8 +518,8 @@ public class TravelObfHelper implements TravelHelper { } } - private TravelArticle findArticleById(@NonNull final TravelArticleIdentifier articleId, - final String lang, @Nullable GpxReadCallback callback) { + private synchronized TravelArticle findArticleById(@NonNull final TravelArticleIdentifier articleId, + final String lang, boolean readGpx, @Nullable GpxReadCallback callback) { TravelArticle article = null; final boolean isDbArticle = articleId.file != null && articleId.file.getName().endsWith(IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT); final List amenities = new ArrayList<>(); @@ -562,7 +562,7 @@ public class TravelObfHelper implements TravelHelper { LOG.error(e.getMessage()); } if (!Algorithms.isEmpty(amenities)) { - article = cacheTravelArticles(reader.getFile(), amenities.get(0), lang, true, callback); + article = cacheTravelArticles(reader.getFile(), amenities.get(0), lang, readGpx, callback); } } return article; @@ -585,7 +585,7 @@ public class TravelObfHelper implements TravelHelper { @Nullable @Override - public TravelArticle getArticleByTitle(@NonNull final String title, @NonNull QuadRect rect, + public synchronized TravelArticle getArticleByTitle(@NonNull final String title, @NonNull QuadRect rect, @NonNull final String lang, boolean readGpx, @Nullable GpxReadCallback callback) { TravelArticle article = null; final List amenities = new ArrayList<>(); From 8098f5d92c32c4bfcc6f85bdc8304a5bd0fee348 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 28 Jan 2021 19:17:25 +0300 Subject: [PATCH 22/28] Fix npe --- .../WikivoyageArticleDialogFragment.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index 4ee8099c26..cced9d45ad 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -1,6 +1,7 @@ package net.osmand.plus.wikivoyage.article; import android.annotation.SuppressLint; +import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; @@ -339,17 +340,20 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme } private void updateTrackButton(boolean processing, @Nullable GPXFile gpxFile) { - if (processing) { - trackButton.setVisibility(View.GONE); - gpxProgress.setVisibility(View.VISIBLE); - } else { - if (gpxFile != null && gpxFile.getPointsSize() > 0) { - trackButton.setVisibility(View.VISIBLE); - trackButton.setText(getString(R.string.shared_string_gpx_points) + " (" + gpxFile.getPointsSize() + ")"); - } else { + Context ctx = getContext(); + if (ctx != null) { + if (processing) { trackButton.setVisibility(View.GONE); + gpxProgress.setVisibility(View.VISIBLE); + } else { + if (gpxFile != null && gpxFile.getPointsSize() > 0) { + trackButton.setVisibility(View.VISIBLE); + trackButton.setText(ctx.getString(R.string.shared_string_gpx_points) + " (" + gpxFile.getPointsSize() + ")"); + } else { + trackButton.setVisibility(View.GONE); + } + gpxProgress.setVisibility(View.GONE); } - gpxProgress.setVisibility(View.GONE); } } From 1b30f1f428b3fbc7ea54693b389e41f5cc02d040 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 28 Jan 2021 19:53:34 +0300 Subject: [PATCH 23/28] Fix travel cards when no book --- .../explore/ExploreTabFragment.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index 9055acd4ed..c13c7fb22f 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -175,10 +175,9 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv if (!Version.isPaidVersion(app) && !OpenBetaTravelCard.isClosed()) { items.add(new OpenBetaTravelCard(activity, nightMode)); } - if (app.getTravelHelper().isAnyTravelBookPresent()) { + List popularArticles = app.getTravelHelper().getPopularArticles(); + if (!popularArticles.isEmpty()) { items.add(new HeaderTravelCard(app, nightMode, getString(R.string.popular_destinations))); - - List popularArticles = app.getTravelHelper().getPopularArticles(); for (TravelArticle article : popularArticles) { if (article instanceof TravelGpx) { items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, getActivity())); @@ -186,15 +185,15 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv items.add(new ArticleTravelCard(app, nightMode, article, activity.getSupportFragmentManager())); } } - items.add(new StartEditingTravelCard(activity, nightMode)); - adapter.setItems(items); - final DownloadIndexesThread downloadThread = app.getDownloadThread(); - if (!downloadThread.getIndexes().isDownloadedFromInternet) { - waitForIndexes = true; - downloadThread.runReloadIndexFilesSilent(); - } else { - checkDownloadIndexes(); - } + } + items.add(new StartEditingTravelCard(activity, nightMode)); + adapter.setItems(items); + final DownloadIndexesThread downloadThread = app.getDownloadThread(); + if (!downloadThread.getIndexes().isDownloadedFromInternet) { + waitForIndexes = true; + downloadThread.runReloadIndexFilesSilent(); + } else { + checkDownloadIndexes(); } } } From 44bcf483759a72aa40a36761b46e1b166acf53ba Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 18:54:45 +0200 Subject: [PATCH 24/28] Add opr blockchain name --- .../plus/mapcontextmenu/MenuBuilder.java | 2 +- .../mapcontextmenu/UploadPhotosAsyncTask.java | 6 ++-- .../osmand/plus/osmedit/opr/OpenDBAPI.java | 32 ++++++++++++++++--- .../plus/settings/backend/OsmandSettings.java | 3 ++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 183e41a84f..93f2bdf6b5 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -421,7 +421,7 @@ public class MenuBuilder { new Thread(new Runnable() { @Override public void run() { - if (openDBAPI.checkPrivateKeyValid(baseUrl, name, privateKey)) { + if (openDBAPI.checkPrivateKeyValid(app, baseUrl, name, privateKey)) { app.runInUIThread(new Runnable() { @Override public void run() { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java index 30932e8b42..1bb48ff1f0 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java @@ -131,12 +131,12 @@ public class UploadPhotosAsyncTask extends AsyncTask { try { StringBuilder error = new StringBuilder(); String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); - String username = app.getSettings().OPR_USERNAME.get(); + String name = app.getSettings().OPR_BLOCKCHAIN_NAME.get(); res = openDBAPI.uploadImage( placeId, baseUrl, privateKey, - username, + name, response, error); if (res != 200) { app.showToastMessage(error.toString()); @@ -170,7 +170,7 @@ public class UploadPhotosAsyncTask extends AsyncTask { String baseUrl = OPRConstants.getBaseUrl(app); String name = app.getSettings().OPR_USERNAME.get(); String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); - if (openDBAPI.checkPrivateKeyValid(baseUrl, name, privateKey)) { + if (openDBAPI.checkPrivateKeyValid(app, baseUrl, name, privateKey)) { app.showToastMessage(R.string.cannot_upload_image); } else { app.runInUIThread(new Runnable() { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java index a16361c8bd..14c0e97672 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java @@ -3,10 +3,15 @@ package net.osmand.plus.osmedit.opr; import android.net.TrafficStats; import android.os.Build; +import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; import net.osmand.PlatformUtil; import net.osmand.osm.io.NetworkUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -27,6 +32,7 @@ import java.security.KeyPair; import java.security.Security; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -40,7 +46,7 @@ public class OpenDBAPI { public static final String PURPOSE = "osmand-android"; private static final Log log = PlatformUtil.getLog(SecUtils.class); private static final String checkLoginEndpoint = "api/auth/user-check-loginkey?"; - private static final String LOGIN_SUCCESS_MESSAGE = "{\"result\":\"OK\"}"; + private static final String LOGIN_SUCCESS_MESSAGE = "\"result\":\"OK\""; private static final int THREAD_ID = 11200; /* @@ -51,7 +57,7 @@ public class OpenDBAPI { * Need to encode key * Do not call on mainThread */ - public boolean checkPrivateKeyValid(String baseUrl, String username, String privateKey) { + public boolean checkPrivateKeyValid(OsmandApplication app, String baseUrl, String username, String privateKey) { String url = null; try { String purposeParam = "purpose=" + PURPOSE; @@ -65,9 +71,27 @@ public class OpenDBAPI { } catch (UnsupportedEncodingException e) { return false; } + StringBuilder response = new StringBuilder(); - return (NetworkUtils.sendGetRequest(url,null,response) == null) && - response.toString().contains(LOGIN_SUCCESS_MESSAGE); + String error = NetworkUtils.sendGetRequest(url, null, response); + if (error == null) { + String responseStr = response.toString(); + try { + Map tagMap = new Gson().fromJson( + responseStr, new TypeToken>() { + }.getType() + ); + if (Algorithms.isEmpty(tagMap) && tagMap.containsKey("blockchain-name")) { + String blockchainName = tagMap.get("blockchain-name"); + app.getSettings().OPR_BLOCKCHAIN_NAME.set(blockchainName); + } + } catch (JsonSyntaxException e) { + return false; + } + return responseStr.contains(LOGIN_SUCCESS_MESSAGE); + } else { + return false; + } } public int uploadImage(String[] placeId, String baseUrl, String privateKey, String username, String image, StringBuilder sb) throws FailedVerificationException { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index dfaaea9468..0d3cddb136 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1171,6 +1171,9 @@ public class OsmandSettings { public final OsmandPreference OPR_USERNAME = new StringPreference(this, "opr_username_secret", "").makeGlobal(); + public final OsmandPreference OPR_BLOCKCHAIN_NAME = + new StringPreference(this, "opr_blockchain_name", "").makeGlobal(); + // this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition public final OsmandPreference OFFLINE_EDITION = new BooleanPreference(this, "offline_osm_editing", true).makeGlobal().makeShared(); public final OsmandPreference USE_DEV_URL = new BooleanPreference(this, "use_dev_url", false).makeGlobal().makeShared(); From ef899fad821229ecefb27c317d6ac907d90520ec Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 18:58:49 +0200 Subject: [PATCH 25/28] Small fix --- OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java index 14c0e97672..62612f2ffe 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java @@ -77,13 +77,15 @@ public class OpenDBAPI { if (error == null) { String responseStr = response.toString(); try { - Map tagMap = new Gson().fromJson( + Map map = new Gson().fromJson( responseStr, new TypeToken>() { }.getType() ); - if (Algorithms.isEmpty(tagMap) && tagMap.containsKey("blockchain-name")) { - String blockchainName = tagMap.get("blockchain-name"); + if (Algorithms.isEmpty(map) && map.containsKey("blockchain-name")) { + String blockchainName = map.get("blockchain-name"); app.getSettings().OPR_BLOCKCHAIN_NAME.set(blockchainName); + } else { + return false; } } catch (JsonSyntaxException e) { return false; From b43a4e46f370b1ba4549f538352a5435303c5b93 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 28 Jan 2021 18:00:25 +0100 Subject: [PATCH 26/28] Update no_translate.xml --- OsmAnd/no_translate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/no_translate.xml b/OsmAnd/no_translate.xml index d5ecc7c149..92d3a4034f 100644 --- a/OsmAnd/no_translate.xml +++ b/OsmAnd/no_translate.xml @@ -40,7 +40,7 @@ items modified OsmAnd Unlimited Markers - https://openplacereviews.org/ + https://test.openplacereviews.org/ https://test.openplacereviews.org/ v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J From 31dc53203d727fb00be67b5b0654833bdd8d5c7d Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 19:04:23 +0200 Subject: [PATCH 27/28] Fix typo --- OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java index 62612f2ffe..1fdeba64f0 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java @@ -81,7 +81,7 @@ public class OpenDBAPI { responseStr, new TypeToken>() { }.getType() ); - if (Algorithms.isEmpty(map) && map.containsKey("blockchain-name")) { + if (!Algorithms.isEmpty(map) && map.containsKey("blockchain-name")) { String blockchainName = map.get("blockchain-name"); app.getSettings().OPR_BLOCKCHAIN_NAME.set(blockchainName); } else { From 70c7e8a3676111ed088a0ab2d830d4139bbb11b8 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 28 Jan 2021 20:44:22 +0100 Subject: [PATCH 28/28] Update no_translate.xml --- OsmAnd/no_translate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/no_translate.xml b/OsmAnd/no_translate.xml index 92d3a4034f..d5ecc7c149 100644 --- a/OsmAnd/no_translate.xml +++ b/OsmAnd/no_translate.xml @@ -40,7 +40,7 @@ items modified OsmAnd Unlimited Markers - https://test.openplacereviews.org/ + https://openplacereviews.org/ https://test.openplacereviews.org/ v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J