Fix travel bugs show 30 articles, gpx bookmark
This commit is contained in:
vshcherb 2021-02-15 16:00:36 +01:00 committed by GitHub
commit ec493acbea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 157 additions and 102 deletions

View file

@ -3,13 +3,19 @@ package net.osmand.plus.wikivoyage.data;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.osmand.GPXUtilities;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -23,6 +29,8 @@ import java.util.Set;
public class TravelLocalDataHelper { public class TravelLocalDataHelper {
private static final Log LOG = PlatformUtil.getLog(TravelLocalDataHelper.class);
private static final int HISTORY_ITEMS_LIMIT = 300; private static final int HISTORY_ITEMS_LIMIT = 300;
private final WikivoyageLocalDataDbHelper dbHelper; private final WikivoyageLocalDataDbHelper dbHelper;
@ -185,7 +193,7 @@ public class TravelLocalDataHelper {
private static class WikivoyageLocalDataDbHelper { private static class WikivoyageLocalDataDbHelper {
private static final int DB_VERSION = 7; private static final int DB_VERSION = 8;
private static final String DB_NAME = "wikivoyage_local_data"; private static final String DB_NAME = "wikivoyage_local_data";
private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history"; private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history";
@ -223,6 +231,7 @@ public class TravelLocalDataHelper {
private static final String BOOKMARKS_COL_CONTENT_JSON = "content_json"; private static final String BOOKMARKS_COL_CONTENT_JSON = "content_json";
private static final String BOOKMARKS_COL_CONTENT = "content"; private static final String BOOKMARKS_COL_CONTENT = "content";
private static final String BOOKMARKS_COL_LAST_MODIFIED = "last_modified"; private static final String BOOKMARKS_COL_LAST_MODIFIED = "last_modified";
private static final String BOOKMARKS_COL_GPX_GZ = "gpx_gz";
private static final String BOOKMARKS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " + private static final String BOOKMARKS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
BOOKMARKS_TABLE_NAME + " (" + BOOKMARKS_TABLE_NAME + " (" +
@ -236,7 +245,8 @@ public class TravelLocalDataHelper {
BOOKMARKS_COL_ROUTE_ID + " TEXT, " + BOOKMARKS_COL_ROUTE_ID + " TEXT, " +
BOOKMARKS_COL_CONTENT_JSON + " TEXT, " + BOOKMARKS_COL_CONTENT_JSON + " TEXT, " +
BOOKMARKS_COL_CONTENT + " TEXT, " + BOOKMARKS_COL_CONTENT + " TEXT, " +
BOOKMARKS_COL_LAST_MODIFIED + " long" + ");"; BOOKMARKS_COL_LAST_MODIFIED + " long, " +
BOOKMARKS_COL_GPX_GZ + " blob" + ");";
private static final String BOOKMARKS_TABLE_SELECT = "SELECT " + private static final String BOOKMARKS_TABLE_SELECT = "SELECT " +
BOOKMARKS_COL_ARTICLE_TITLE + ", " + BOOKMARKS_COL_ARTICLE_TITLE + ", " +
@ -249,7 +259,8 @@ public class TravelLocalDataHelper {
BOOKMARKS_COL_ROUTE_ID + ", " + BOOKMARKS_COL_ROUTE_ID + ", " +
BOOKMARKS_COL_CONTENT_JSON + ", " + BOOKMARKS_COL_CONTENT_JSON + ", " +
BOOKMARKS_COL_CONTENT + ", " + BOOKMARKS_COL_CONTENT + ", " +
BOOKMARKS_COL_LAST_MODIFIED + BOOKMARKS_COL_LAST_MODIFIED + ", " +
BOOKMARKS_COL_GPX_GZ +
" FROM " + BOOKMARKS_TABLE_NAME; " FROM " + BOOKMARKS_TABLE_NAME;
private final OsmandApplication context; private final OsmandApplication context;
@ -318,6 +329,9 @@ public class TravelLocalDataHelper {
conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME + conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME +
" SET " + BOOKMARKS_COL_PARTIAL_CONTENT + " = null"); " SET " + BOOKMARKS_COL_PARTIAL_CONTENT + " = null");
} }
if (oldVersion < 8) {
conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_GPX_GZ + " blob");
}
} }
@NonNull @NonNull
@ -461,35 +475,48 @@ public class TravelLocalDataHelper {
return count > 0; return count > 0;
} }
void addSavedArticle(@NonNull TravelArticle article) { void addSavedArticle(@NonNull final TravelArticle article) {
String travelBook = article.getTravelBook(context); final String travelBook = article.getTravelBook(context);
if (travelBook == null) { if (travelBook == null) {
return; return;
} }
SQLiteConnection conn = openConnection(false); context.getTravelHelper().getArticleById(article.generateIdentifier(), article.lang, true,
if (conn != null) { new TravelHelper.GpxReadCallback() {
try { @Override
String query = "INSERT INTO " + BOOKMARKS_TABLE_NAME + " (" + public void onGpxFileReading() {
BOOKMARKS_COL_ARTICLE_TITLE + ", " +
BOOKMARKS_COL_LANG + ", " + }
BOOKMARKS_COL_IS_PART_OF + ", " +
BOOKMARKS_COL_IMAGE_TITLE + ", " + @Override
BOOKMARKS_COL_TRAVEL_BOOK + ", " + public void onGpxFileRead(@Nullable GPXUtilities.GPXFile gpxFile) {
BOOKMARKS_COL_LAT + ", " + SQLiteConnection conn = openConnection(false);
BOOKMARKS_COL_LON + ", " + if (conn != null) {
BOOKMARKS_COL_ROUTE_ID + ", " + try {
BOOKMARKS_COL_CONTENT_JSON + ", " + String query = "INSERT INTO " + BOOKMARKS_TABLE_NAME + " (" +
BOOKMARKS_COL_CONTENT + ", " + BOOKMARKS_COL_ARTICLE_TITLE + ", " +
BOOKMARKS_COL_LAST_MODIFIED + BOOKMARKS_COL_LANG + ", " +
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; BOOKMARKS_COL_IS_PART_OF + ", " +
conn.execSQL(query, new Object[]{article.title, article.lang, BOOKMARKS_COL_IMAGE_TITLE + ", " +
article.aggregatedPartOf, article.imageTitle, BOOKMARKS_COL_TRAVEL_BOOK + ", " +
travelBook, article.lat, article.lon, article.routeId, article.contentsJson, BOOKMARKS_COL_LAT + ", " +
article.content, article.getFile().lastModified()}); BOOKMARKS_COL_LON + ", " +
} finally { BOOKMARKS_COL_ROUTE_ID + ", " +
conn.close(); BOOKMARKS_COL_CONTENT_JSON + ", " +
} BOOKMARKS_COL_CONTENT + ", " +
} BOOKMARKS_COL_LAST_MODIFIED + ", " +
BOOKMARKS_COL_GPX_GZ +
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
conn.execSQL(query, new Object[]{article.title, article.lang,
article.aggregatedPartOf, article.imageTitle,
travelBook, article.lat, article.lon, article.routeId, article.contentsJson,
article.content, article.getFile().lastModified(),
Algorithms.stringToGzip(GPXUtilities.asString(article.gpxFile))});
} finally {
conn.close();
}
}
}
});
} }
void removeSavedArticle(@NonNull TravelArticle article) { void removeSavedArticle(@NonNull TravelArticle article) {
@ -580,6 +607,15 @@ public class TravelLocalDataHelper {
res.file = context.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR + travelBook); res.file = context.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR + travelBook);
res.lastModified = cursor.getLong(cursor.getColumnIndex(BOOKMARKS_COL_LAST_MODIFIED)); res.lastModified = cursor.getLong(cursor.getColumnIndex(BOOKMARKS_COL_LAST_MODIFIED));
} }
try {
byte[] blob = cursor.getBlob(cursor.getColumnIndex(BOOKMARKS_COL_GPX_GZ));
if (blob != null) {
String gpxContent = Algorithms.gzipToString(blob);
res.gpxFile = GPXUtilities.loadGPXFile(new ByteArrayInputStream(gpxContent.getBytes("UTF-8")));
}
} catch (IOException e) {
LOG.error(e.getMessage(), e);
}
return res; return res;
} }
} }

View file

@ -116,46 +116,50 @@ public class TravelObfHelper implements TravelHelper {
public synchronized List<TravelArticle> loadPopularArticles() { public synchronized List<TravelArticle> loadPopularArticles() {
String lang = app.getLanguage(); String lang = app.getLanguage();
List<TravelArticle> popularArticles = new ArrayList<>(this.popularArticles); List<TravelArticle> popularArticles = new ArrayList<>(this.popularArticles);
if (foundAmenities.size() - foundAmenitiesIndex < MAX_POPULAR_ARTICLES_COUNT) { int pagesCount;
final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); if (isAnyTravelBookPresent()) {
for (final BinaryMapIndexReader reader : getReaders()) { do {
try { if (foundAmenities.size() - foundAmenitiesIndex < MAX_POPULAR_ARTICLES_COUNT) {
searchAmenity(foundAmenities, location, reader, searchRadius, -1, ROUTE_ARTICLE); final LatLon location = app.getMapViewTrackingUtilities().getMapLocation();
searchAmenity(foundAmenities, location, reader, searchRadius / 5, 15, ROUTE_TRACK); for (final BinaryMapIndexReader reader : getReaders()) {
} catch (Exception e) { try {
LOG.error(e.getMessage(), e); searchAmenity(foundAmenities, location, reader, searchRadius, -1, ROUTE_ARTICLE);
} searchAmenity(foundAmenities, location, reader, searchRadius / 5, 15, ROUTE_TRACK);
} } catch (Exception e) {
if (foundAmenities.size() > 0) { LOG.error(e.getMessage(), e);
Collections.sort(foundAmenities, new Comparator<Pair<File, Amenity>>() { }
@Override
public int compare(Pair article1, Pair article2) {
Amenity amenity1 = (Amenity) article1.second;
double d1 = MapUtils.getDistance(amenity1.getLocation(), location)
/ (ROUTE_ARTICLE.equals(amenity1.getSubType()) ? 5 : 1);
Amenity amenity2 = (Amenity) article2.second;
double d2 = MapUtils.getDistance(amenity2.getLocation(), location)
/ (ROUTE_ARTICLE.equals(amenity2.getSubType()) ? 5 : 1);
return Double.compare(d1, d2);
} }
}); if (foundAmenities.size() > 0) {
} Collections.sort(foundAmenities, new Comparator<Pair<File, Amenity>>() {
searchRadius *= 2; @Override
} public int compare(Pair article1, Pair article2) {
Amenity amenity1 = (Amenity) article1.second;
int pagesCount = popularArticles.size() / MAX_POPULAR_ARTICLES_COUNT; double d1 = MapUtils.getDistance(amenity1.getLocation(), location)
while (foundAmenitiesIndex < foundAmenities.size() - 1) { / (ROUTE_ARTICLE.equals(amenity1.getSubType()) ? 5 : 1);
Pair<File, Amenity> amenity = foundAmenities.get(foundAmenitiesIndex); Amenity amenity2 = (Amenity) article2.second;
if (!Algorithms.isEmpty(amenity.second.getName(lang))) { double d2 = MapUtils.getDistance(amenity2.getLocation(), location)
TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null); / (ROUTE_ARTICLE.equals(amenity2.getSubType()) ? 5 : 1);
if (article != null && !popularArticles.contains(article)) { return Double.compare(d1, d2);
popularArticles.add(article); }
if (popularArticles.size() >= (pagesCount + 1) * MAX_POPULAR_ARTICLES_COUNT) { });
break;
} }
searchRadius *= 2;
} }
} pagesCount = popularArticles.size() / MAX_POPULAR_ARTICLES_COUNT;
foundAmenitiesIndex++; while (foundAmenitiesIndex < foundAmenities.size() - 1) {
Pair<File, Amenity> amenity = foundAmenities.get(foundAmenitiesIndex);
if (!Algorithms.isEmpty(amenity.second.getName(lang))) {
TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null);
if (article != null && !popularArticles.contains(article)) {
popularArticles.add(article);
if (popularArticles.size() >= (pagesCount + 1) * MAX_POPULAR_ARTICLES_COUNT) {
break;
}
}
}
foundAmenitiesIndex++;
}
} while (popularArticles.size() < (pagesCount + 1) * MAX_POPULAR_ARTICLES_COUNT);
} }
this.popularArticles = popularArticles; this.popularArticles = popularArticles;
return popularArticles; return popularArticles;
@ -669,7 +673,7 @@ public class TravelObfHelper implements TravelHelper {
if (article == null && articles == null) { if (article == null && articles == null) {
article = findArticleById(articleId, lang, readGpx, callback); article = findArticleById(articleId, lang, readGpx, callback);
} }
if (article != null && readGpx && !Algorithms.isEmpty(lang)) { if (article != null && readGpx && (!Algorithms.isEmpty(lang) || article instanceof TravelGpx)) {
readGpxFile(article, callback); readGpxFile(article, callback);
} }
return article; return article;
@ -1003,11 +1007,7 @@ public class TravelObfHelper implements TravelHelper {
@Override @Override
public File createGpxFile(@NonNull TravelArticle article) { public File createGpxFile(@NonNull TravelArticle article) {
final GPXFile gpx; final GPXFile gpx;
if (article instanceof TravelGpx) { gpx = article.getGpxFile();
gpx = buildTravelGpxFile((TravelGpx) article);
} else {
gpx = article.getGpxFile();
}
File file = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article)); File file = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article));
writeGpxFile(file, gpx); writeGpxFile(file, gpx);
return file; return file;
@ -1043,13 +1043,17 @@ public class TravelObfHelper implements TravelHelper {
@Override @Override
protected GPXFile doInBackground(Void... voids) { protected GPXFile doInBackground(Void... voids) {
GPXFile gpxFile = null; GPXFile gpxFile = null;
List<Amenity> pointList = getPointList(article); if (article instanceof TravelGpx) {
if (!Algorithms.isEmpty(pointList)) { gpxFile = buildTravelGpxFile((TravelGpx) article);
gpxFile = new GPXFile(article.getTitle(), article.getLang(), article.getContent()); } else {
gpxFile.metadata.link = TravelArticle.getImageUrl(article.getImageTitle(), false); List<Amenity> pointList = getPointList(article);
for (Amenity amenity : pointList) { if (!Algorithms.isEmpty(pointList)) {
WptPt wptPt = createWptPt(amenity, article.getLang()); gpxFile = new GPXFile(article.getTitle(), article.getLang(), article.getContent());
gpxFile.addPoint(wptPt); gpxFile.metadata.link = TravelArticle.getImageUrl(article.getImageTitle(), false);
for (Amenity amenity : pointList) {
WptPt wptPt = createWptPt(amenity, article.getLang());
gpxFile.addPoint(wptPt);
}
} }
} }
return gpxFile; return gpxFile;

View file

@ -186,28 +186,28 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
} }
} }
if (app.getTravelHelper().isAnyTravelBookPresent()) {
TravelButtonCard travelButtonCard = new TravelButtonCard(app, nightMode); TravelButtonCard travelButtonCard = new TravelButtonCard(app, nightMode);
travelButtonCard.setListener(new TravelNeededMapsCard.CardListener() { travelButtonCard.setListener(new TravelNeededMapsCard.CardListener() {
@Override @Override
public void onPrimaryButtonClick() { public void onPrimaryButtonClick() {
if (activity instanceof WikivoyageExploreActivity) { if (activity instanceof WikivoyageExploreActivity) {
new LoadWikivoyageData((WikivoyageExploreActivity) activity,false).execute(); new LoadWikivoyageData((WikivoyageExploreActivity) activity, false).execute();
}
} }
}
@Override @Override
public void onSecondaryButtonClick() { public void onSecondaryButtonClick() {
} }
@Override @Override
public void onIndexItemClick(IndexItem item) { public void onIndexItemClick(IndexItem item) {
}
});
items.add(travelButtonCard);
}
});
items.add(travelButtonCard);
}
items.add(new StartEditingTravelCard(activity, nightMode)); items.add(new StartEditingTravelCard(activity, nightMode));
adapter.setItems(items); adapter.setItems(items);
final DownloadIndexesThread downloadThread = app.getDownloadThread(); final DownloadIndexesThread downloadThread = app.getDownloadThread();
@ -248,11 +248,14 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
private void addIndexItemCards(List<IndexItem> mainIndexItem, List<IndexItem> neededIndexItems) { private void addIndexItemCards(List<IndexItem> mainIndexItem, List<IndexItem> neededIndexItems) {
this.mainIndexItems.clear(); final OsmandApplication app = getMyApplication();
this.mainIndexItems.addAll(mainIndexItem); if (app != null && !app.getTravelHelper().isAnyTravelBookPresent()) {
this.mainIndexItems.clear();
this.mainIndexItems.addAll(mainIndexItem);
addDownloadUpdateCard();
}
this.neededIndexItems.clear(); this.neededIndexItems.clear();
this.neededIndexItems.addAll(neededIndexItems); this.neededIndexItems.addAll(neededIndexItems);
addDownloadUpdateCard();
addNeededMapsCard(); addNeededMapsCard();
} }

View file

@ -7,16 +7,19 @@ import android.widget.TextView;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities;
import net.osmand.osm.RouteActivityType; import net.osmand.osm.RouteActivityType;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.track.TrackMenuFragment;
import net.osmand.plus.wikivoyage.data.TravelGpx; 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.data.TravelLocalDataHelper;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -64,8 +67,18 @@ public class TravelGpxCard extends BaseTravelCard {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (activity != null) { if (activity != null) {
File file = app.getTravelHelper().createGpxFile(article); app.getTravelHelper().getArticleById(article.generateIdentifier(), null, true,
TrackMenuFragment.openTrack(activity, file, null); new TravelHelper.GpxReadCallback() {
@Override
public void onGpxFileReading() {
}
@Override
public void onGpxFileRead(@Nullable GPXUtilities.GPXFile gpxFile) {
File file = app.getTravelHelper().createGpxFile(article);
TrackMenuFragment.openTrack(activity, file, null);
}
});
} }
} }
}; };
@ -102,7 +115,6 @@ public class TravelGpxCard extends BaseTravelCard {
if (saved) { if (saved) {
helper.removeArticleFromSaved(article); helper.removeArticleFromSaved(article);
} else { } else {
app.getTravelHelper().createGpxFile(article);
helper.addArticleToSaved(article); helper.addArticleToSaved(article);
} }
updateSaveButton(holder); updateSaveButton(holder);