Merge pull request #10544 from osmandapp/travel_obf_gpx

Travel obf gpx
This commit is contained in:
alex-osm 2021-01-14 18:07:29 +03:00 committed by GitHub
commit 2b9da9d83d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 165 additions and 48 deletions

View file

@ -1769,6 +1769,10 @@ public class BinaryMapIndexReader {
return limit != -1 && searchResults.size() > limit; return limit != -1 && searchResults.size() > limit;
} }
public void setLimit(int limit) {
this.limit = limit;
}
public boolean isCancelled() { public boolean isCancelled() {
if (this.interrupted) { if (this.interrupted) {
return interrupted; return interrupted;

View file

@ -45,6 +45,9 @@ public class Amenity extends MapObject {
public static final String CONTENT_JSON = "content_json"; public static final String CONTENT_JSON = "content_json";
public static final String ROUTE_ID = "route_id"; public static final String ROUTE_ID = "route_id";
public static final String ROUTE_SOURCE = "route_source"; public static final String ROUTE_SOURCE = "route_source";
public static final String COLOR = "color";
public static final String LANG_YES = "lang_yes";
public static final String GPX_ICON = "gpx_icon";
private String subType; private String subType;
@ -201,6 +204,15 @@ public class Amenity extends MapObject {
setAdditionalInfo(PHONE, phone); setAdditionalInfo(PHONE, phone);
} }
public String getColor() {
return getAdditionalInfo(COLOR);
}
public String getGpxIcon() {
return getAdditionalInfo(GPX_ICON);
}
public String getContentLanguage(String tag, String lang, String defLang) { public String getContentLanguage(String tag, String lang, String defLang) {
if (lang != null) { if (lang != null) {
String translateName = getAdditionalInfo(tag + ":" + lang); String translateName = getAdditionalInfo(tag + ":" + lang);
@ -250,6 +262,17 @@ public class Amenity extends MapObject {
return l; return l;
} }
public String getTagSuffix(String tagPrefix) {
for (String infoTag : getAdditionalInfoKeys()) {
if (infoTag.startsWith(tagPrefix)) {
if (infoTag.length() > tagPrefix.length()) {
return infoTag.substring(tagPrefix.length());
}
}
}
return null;
}
public String getTagContent(String tag, String lang) { public String getTagContent(String tag, String lang) {
if (lang != null) { if (lang != null) {
String translateName = getAdditionalInfo(tag + ":" + lang); String translateName = getAdditionalInfo(tag + ":" + lang);
@ -381,6 +404,4 @@ public class Amenity extends MapObject {
} }
return a; return a;
} }
}
}

View file

@ -14,6 +14,7 @@ import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
@ -119,7 +120,7 @@ public class WikivoyageWebViewClient extends WebViewClient {
fragmentManager.popBackStackImmediate(); fragmentManager.popBackStackImmediate();
File path = app.getTravelHelper().createGpxFile(article); File path = app.getTravelHelper().createGpxFile(article);
GPXUtilities.GPXFile gpxFile = article.getGpxFile(); GPXFile gpxFile = article.getGpxFile();
gpxFile.path = path.getAbsolutePath(); gpxFile.path = path.getAbsolutePath();
app.getSelectedGpxHelper().setGpxFileToDisplay(gpxFile); app.getSelectedGpxHelper().setGpxFileToDisplay(gpxFile);
MapActivity.launchMapActivityMoveToTop(activity); MapActivity.launchMapActivityMoveToTop(activity);

View file

@ -27,6 +27,8 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentManager.BackStackEntry; import androidx.fragment.app.FragmentManager.BackStackEntry;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
@ -309,9 +311,10 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme
} }
webViewClient.setArticle(article); webViewClient.setArticle(article);
articleToolbarText.setText(article.getTitle()); articleToolbarText.setText(article.getTitle());
if (article.getGpxFile() != null && article.getGpxFile().getPointsSize() > 0) { GPXFile gpxFile = article.getGpxFile();
if (gpxFile != null && gpxFile.getPointsSize() > 0) {
trackButton.setVisibility(View.VISIBLE); trackButton.setVisibility(View.VISIBLE);
trackButton.setText(getString(R.string.shared_string_gpx_points) + " (" + article.getGpxFile().getPointsSize() + ")"); trackButton.setText(getString(R.string.shared_string_gpx_points) + " (" + gpxFile.getPointsSize() + ")");
} else { } else {
trackButton.setVisibility(View.GONE); trackButton.setVisibility(View.GONE);
} }

View file

@ -43,6 +43,7 @@ public class TravelArticle {
String aggregatedPartOf; String aggregatedPartOf;
long lastModified; long lastModified;
boolean gpxFileRead;
@NonNull @NonNull
public TravelArticleIdentifier generateIdentifier() { public TravelArticleIdentifier generateIdentifier() {
@ -237,14 +238,13 @@ public class TravelArticle {
TravelArticleIdentifier that = (TravelArticleIdentifier) o; TravelArticleIdentifier that = (TravelArticleIdentifier) o;
return areLatLonEqual(that.lat, that.lon, lat, lon) && return areLatLonEqual(that.lat, that.lon, lat, lon) &&
Algorithms.objectEquals(file, that.file) && Algorithms.objectEquals(file, that.file) &&
Algorithms.stringsEqual(title, that.title) &&
Algorithms.stringsEqual(routeId, that.routeId) && Algorithms.stringsEqual(routeId, that.routeId) &&
Algorithms.stringsEqual(routeSource, that.routeSource); Algorithms.stringsEqual(routeSource, that.routeSource);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Algorithms.hash(file, lat, lon, title, routeId, routeSource); return Algorithms.hash(file, lat, lon, routeId, routeSource);
} }
private static boolean areLatLonEqual(double lat1, double lon1, double lat2, double lon2) { private static boolean areLatLonEqual(double lat1, double lon1, double lat2, double lon2) {

View file

@ -514,8 +514,9 @@ public class TravelLocalDataHelper {
" AND " + BOOKMARKS_COL_LANG + " = ?" + " AND " + BOOKMARKS_COL_LANG + " = ?" +
" AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?", " AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?",
new Object[]{newArticle.title, newArticle.lang, newArticle.aggregatedPartOf, new Object[]{newArticle.title, newArticle.lang, newArticle.aggregatedPartOf,
newArticle.imageTitle, travelBook, newArticle.lat, newArticle.lon, newArticle.imageTitle, newArticle.getTravelBook(context), newArticle.lat,
newArticle.routeId, newArticle.content, newArticle.contentsJson, newArticle.lon, newArticle.routeId, newArticle.contentsJson, newArticle.content,
newArticle.getLastModified(),
odlArticle.title, odlArticle.routeId, odlArticle.lang, travelBook}); odlArticle.title, odlArticle.routeId, odlArticle.lang, travelBook});
} finally { } finally {

View file

@ -7,7 +7,6 @@ import androidx.annotation.Nullable;
import net.osmand.Collator; import net.osmand.Collator;
import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.OsmAndCollator; import net.osmand.OsmAndCollator;
@ -21,6 +20,7 @@ import net.osmand.data.LatLon;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiCategory;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.wikivoyage.data.TravelArticle.TravelArticleIdentifier; import net.osmand.plus.wikivoyage.data.TravelArticle.TravelArticleIdentifier;
import net.osmand.search.core.SearchPhrase.NameStringMatcher; import net.osmand.search.core.SearchPhrase.NameStringMatcher;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -45,11 +45,15 @@ import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static net.osmand.GPXUtilities.WptPt;
import static net.osmand.GPXUtilities.writeGpxFile;
public class TravelObfHelper implements TravelHelper { public class TravelObfHelper implements TravelHelper {
private static final Log LOG = PlatformUtil.getLog(TravelObfHelper.class); private static final Log LOG = PlatformUtil.getLog(TravelObfHelper.class);
private static final String WORLD_WIKIVOYAGE_FILE_NAME = "World_wikivoyage.travel.obf"; private static final String WORLD_WIKIVOYAGE_FILE_NAME = "World_wikivoyage.travel.obf";
public static final String ROUTE_ARTICLE = "route_article"; public static final String ROUTE_ARTICLE = "route_article";
public static final String ROUTE_ARTICLE_POINT = "route_article_point";
public static final int POPULAR_ARTICLES_SEARCH_RADIUS = 100000; public static final int POPULAR_ARTICLES_SEARCH_RADIUS = 100000;
public static final int ARTICLE_SEARCH_RADIUS = 50000; public static final int ARTICLE_SEARCH_RADIUS = 50000;
public static final int MAX_POPULAR_ARTICLES_COUNT = 100; public static final int MAX_POPULAR_ARTICLES_COUNT = 100;
@ -58,7 +62,7 @@ public class TravelObfHelper implements TravelHelper {
private final Collator collator; private final Collator collator;
private List<TravelArticle> popularArticles = new ArrayList<>(); private List<TravelArticle> popularArticles = new ArrayList<>();
private Map<TravelArticleIdentifier, Map<String, TravelArticle>> cachedArticles = new ConcurrentHashMap<>(); private final Map<TravelArticleIdentifier, Map<String, TravelArticle>> cachedArticles = new ConcurrentHashMap<>();
private final TravelLocalDataHelper localDataHelper; private final TravelLocalDataHelper localDataHelper;
public TravelObfHelper(OsmandApplication app) { public TravelObfHelper(OsmandApplication app) {
@ -90,12 +94,12 @@ public class TravelObfHelper implements TravelHelper {
try { try {
final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); final LatLon location = app.getMapViewTrackingUtilities().getMapLocation();
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest( SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(
location, POPULAR_ARTICLES_SEARCH_RADIUS, -1, getSearchRouteArticleFilter(), null); location, POPULAR_ARTICLES_SEARCH_RADIUS, -1, getSearchFilter(false), null);
List<Amenity> amenities = reader.searchPoi(req); List<Amenity> amenities = reader.searchPoi(req);
if (amenities.size() > 0) { if (amenities.size() > 0) {
for (Amenity amenity : amenities) { for (Amenity amenity : amenities) {
if (!Algorithms.isEmpty(amenity.getName(lang))) { if (!Algorithms.isEmpty(amenity.getName(lang))) {
TravelArticle article = cacheTravelArticles(reader.getFile(), amenity, lang); TravelArticle article = cacheTravelArticles(reader.getFile(), amenity, lang, false);
if (article != null) { if (article != null) {
popularArticles.add(article); popularArticles.add(article);
if (popularArticles.size() >= MAX_POPULAR_ARTICLES_COUNT) { if (popularArticles.size() >= MAX_POPULAR_ARTICLES_COUNT) {
@ -124,22 +128,23 @@ public class TravelObfHelper implements TravelHelper {
} }
@Nullable @Nullable
private TravelArticle cacheTravelArticles(File file, Amenity amenity, String lang) { private TravelArticle cacheTravelArticles(File file, Amenity amenity, String lang, boolean readPoints) {
TravelArticle article = null; TravelArticle article = null;
Map<String, TravelArticle> articles = readArticles(file, amenity); Map<String, TravelArticle> articles = readArticles(file, amenity, readPoints);
if (!Algorithms.isEmpty(articles)) { if (!Algorithms.isEmpty(articles)) {
TravelArticleIdentifier newArticleId = articles.values().iterator().next().generateIdentifier(); TravelArticleIdentifier newArticleId = articles.values().iterator().next().generateIdentifier();
cachedArticles.put(newArticleId, articles); cachedArticles.put(newArticleId, articles);
article = getCachedArticle(newArticleId, lang); article = getCachedArticle(newArticleId, lang, readPoints);
} }
return article; return article;
} }
SearchPoiTypeFilter getSearchRouteArticleFilter() { @NonNull
private SearchPoiTypeFilter getSearchFilter(final boolean articlePoints) {
return new SearchPoiTypeFilter() { return new SearchPoiTypeFilter() {
@Override @Override
public boolean accept(PoiCategory type, String subcategory) { public boolean accept(PoiCategory type, String subcategory) {
return subcategory.equals(ROUTE_ARTICLE); return subcategory.equals(articlePoints ? ROUTE_ARTICLE_POINT : ROUTE_ARTICLE);
} }
@Override @Override
@ -150,37 +155,115 @@ public class TravelObfHelper implements TravelHelper {
} }
@NonNull @NonNull
private Map<String, TravelArticle> readArticles(@NonNull File file, @NonNull Amenity amenity) { private Map<String, TravelArticle> readArticles(@NonNull File file, @NonNull Amenity amenity, boolean readPoints) {
Map<String, TravelArticle> articles = new HashMap<>(); Map<String, TravelArticle> articles = new HashMap<>();
Set<String> langs = getLanguages(amenity); Set<String> langs = getLanguages(amenity);
for (String lang : langs) { for (String lang : langs) {
articles.put(lang, readArticle(file, amenity, lang)); articles.put(lang, readArticle(file, amenity, lang, readPoints));
} }
return articles; return articles;
} }
@NonNull @NonNull
private TravelArticle readArticle(@NonNull File file, @NonNull Amenity amenity, @Nullable String lang) { private TravelArticle readArticle(@NonNull File file, @NonNull Amenity amenity, @NonNull String lang, boolean readPoints) {
TravelArticle res = new TravelArticle(); TravelArticle res = new TravelArticle();
res.file = file; res.file = file;
String title = amenity.getName(lang); String title = amenity.getName(lang);
res.title = Algorithms.isEmpty(title) ? amenity.getName() : title; res.title = Algorithms.isEmpty(title) ? amenity.getName() : title;
res.content = amenity.getDescription(lang); res.content = amenity.getDescription(lang);
res.isPartOf = emptyIfNull(amenity.getTagContent(Amenity.IS_PART, lang)); res.isPartOf = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.IS_PART, lang));
res.lat = amenity.getLocation().getLatitude(); res.lat = amenity.getLocation().getLatitude();
res.lon = amenity.getLocation().getLongitude(); res.lon = amenity.getLocation().getLongitude();
res.imageTitle = emptyIfNull(amenity.getTagContent(Amenity.IMAGE_TITLE, null)); res.imageTitle = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.IMAGE_TITLE, null));
res.routeId = emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null)); res.routeId = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null));
res.routeSource = emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null)); res.routeSource = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null));
res.originalId = 0; res.originalId = 0;
res.lang = lang; res.lang = lang;
res.contentsJson = emptyIfNull(amenity.getTagContent(Amenity.CONTENT_JSON, lang)); res.contentsJson = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.CONTENT_JSON, lang));
res.aggregatedPartOf = emptyIfNull(amenity.getTagContent(Amenity.IS_AGGR_PART, lang)); res.aggregatedPartOf = Algorithms.emptyIfNull(amenity.getTagContent(Amenity.IS_AGGR_PART, lang));
if (readPoints) {
res.gpxFile = buildGpxFile(res);
res.gpxFileRead = true;
}
return res; return res;
} }
private String emptyIfNull(String text) { private GPXFile buildGpxFile(@NonNull TravelArticle article) {
return text == null ? "" : text; GPXFile gpxFile = null;
List<Amenity> pointList = getPointList(article);
if (!Algorithms.isEmpty(pointList)) {
gpxFile = new GPXFile(article.getTitle(), article.getLang(), "");
for (Amenity amenity : pointList) {
WptPt wptPt = createWptPt(amenity, article.getLang());
gpxFile.addPoint(wptPt);
}
}
return gpxFile;
}
@NonNull
private List<Amenity> getPointList(@NonNull final TravelArticle article) {
final List<Amenity> pointList = new ArrayList<>();
final String lang = article.getLang();
for (BinaryMapIndexReader reader : getReaders()) {
try {
if (article.file != null && !article.file.equals(reader.getFile())) {
continue;
}
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(0, 0,
Algorithms.emptyIfNull(article.title), 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE,
getSearchFilter(true), new ResultMatcher<Amenity>() {
@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)))) {
pointList.add(amenity);
}
return false;
}
@Override
public boolean isCancelled() {
return false;
}
}, null);
if (!Algorithms.isEmpty(article.title)) {
reader.searchPoiByName(req);
} else {
reader.searchPoi(req);
}
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
return pointList;
}
@NonNull
private WptPt createWptPt(@NonNull Amenity amenity, @Nullable String lang) {
WptPt wptPt = new WptPt();
wptPt.name = amenity.getName();
wptPt.lat = amenity.getLocation().getLatitude();
wptPt.lon = amenity.getLocation().getLongitude();
wptPt.desc = amenity.getDescription(lang);
wptPt.link = amenity.getSite();
String color = amenity.getColor();
if (color != null) {
wptPt.setColor(ColorDialogs.getColorByTag(color));
}
String iconName = amenity.getGpxIcon();
if (iconName != null) {
wptPt.setIconName(iconName);
}
String category = amenity.getTagSuffix("category_");
if (category != null) {
wptPt.category = Algorithms.capitalizeFirstLetter(category);
}
return wptPt;
} }
@Override @Override
@ -198,7 +281,7 @@ public class TravelObfHelper implements TravelHelper {
for (BinaryMapIndexReader reader : getReaders()) { for (BinaryMapIndexReader reader : getReaders()) {
try { try {
SearchRequest<Amenity> searchRequest = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, searchQuery, SearchRequest<Amenity> searchRequest = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, searchQuery,
0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchRouteArticleFilter(), new ResultMatcher<Amenity>() { 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, getSearchFilter(false), new ResultMatcher<Amenity>() {
@Override @Override
public boolean publish(Amenity object) { public boolean publish(Amenity object) {
List<String> otherNames = object.getAllNames(false); List<String> otherNames = object.getAllNames(false);
@ -227,7 +310,7 @@ public class TravelObfHelper implements TravelHelper {
for (Amenity amenity : entry.getValue()) { for (Amenity amenity : entry.getValue()) {
Set<String> nameLangs = getLanguages(amenity); Set<String> nameLangs = getLanguages(amenity);
if (nameLangs.contains(appLang)) { if (nameLangs.contains(appLang)) {
TravelArticle article = readArticle(file, amenity, appLang); TravelArticle article = readArticle(file, amenity, appLang, false);
ArrayList<String> langs = new ArrayList<>(nameLangs); ArrayList<String> langs = new ArrayList<>(nameLangs);
Collections.sort(langs, new Comparator<String>() { Collections.sort(langs, new Comparator<String>() {
@Override @Override
@ -281,7 +364,7 @@ public class TravelObfHelper implements TravelHelper {
Collections.sort(list, new Comparator<WikivoyageSearchResult>() { Collections.sort(list, new Comparator<WikivoyageSearchResult>() {
@Override @Override
public int compare(WikivoyageSearchResult res1, WikivoyageSearchResult res2) { public int compare(WikivoyageSearchResult res1, WikivoyageSearchResult res2) {
return collator.compare(res1.articleId.title, res2.articleId.title); return collator.compare(res1.getArticleTitle(), res2.getArticleTitle());
} }
}); });
} }
@ -321,7 +404,7 @@ public class TravelObfHelper implements TravelHelper {
for (BinaryMapIndexReader reader : getReaders()) { for (BinaryMapIndexReader reader : getReaders()) {
try { try {
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(0, SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(0,
Integer.MAX_VALUE, 0, Integer.MAX_VALUE, -1, getSearchRouteArticleFilter(), new ResultMatcher<Amenity>() { Integer.MAX_VALUE, 0, Integer.MAX_VALUE, -1, getSearchFilter(false), new ResultMatcher<Amenity>() {
@Override @Override
public boolean publish(Amenity amenity) { public boolean publish(Amenity amenity) {
@ -364,7 +447,7 @@ public class TravelObfHelper implements TravelHelper {
for (Amenity amenity : entry.getValue()) { for (Amenity amenity : entry.getValue()) {
Set<String> nameLangs = getLanguages(amenity); Set<String> nameLangs = getLanguages(amenity);
if (nameLangs.contains(lang)) { if (nameLangs.contains(lang)) {
TravelArticle a = readArticle(file, amenity, lang); TravelArticle a = readArticle(file, amenity, lang, false);
WikivoyageSearchResult rs = new WikivoyageSearchResult(a, new ArrayList<>(nameLangs)); WikivoyageSearchResult rs = new WikivoyageSearchResult(a, new ArrayList<>(nameLangs));
List<WikivoyageSearchResult> l = navMap.get(rs.isPartOf); List<WikivoyageSearchResult> l = navMap.get(rs.isPartOf);
if (l == null) { if (l == null) {
@ -401,12 +484,12 @@ public class TravelObfHelper implements TravelHelper {
@Override @Override
public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang) { public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang) {
TravelArticle article = getCachedArticle(articleId, lang); TravelArticle article = getCachedArticle(articleId, lang, true);
return article == null ? localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang) : article; return article == null ? localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang) : article;
} }
@Nullable @Nullable
private TravelArticle getCachedArticle(@NonNull TravelArticleIdentifier articleId, @NonNull String lang) { private TravelArticle getCachedArticle(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, boolean forceReadPoints) {
TravelArticle article = null; TravelArticle article = null;
Map<String, TravelArticle> articles = cachedArticles.get(articleId); Map<String, TravelArticle> articles = cachedArticles.get(articleId);
if (articles != null) { if (articles != null) {
@ -422,7 +505,14 @@ public class TravelObfHelper implements TravelHelper {
} }
} }
} }
return article == null ? findArticleById(articleId, lang) : article; if (article == null) {
article = findArticleById(articleId, lang);
}
if (article != null && !article.gpxFileRead && forceReadPoints) {
article.gpxFile = buildGpxFile(article);
article.gpxFileRead = true;
}
return article;
} }
private TravelArticle findArticleById(@NonNull final TravelArticleIdentifier articleId, final String lang) { private TravelArticle findArticleById(@NonNull final TravelArticleIdentifier articleId, final String lang) {
@ -436,7 +526,7 @@ public class TravelObfHelper implements TravelHelper {
} }
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(0, 0, SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(0, 0,
Algorithms.emptyIfNull(articleId.title), 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, Algorithms.emptyIfNull(articleId.title), 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE,
getSearchRouteArticleFilter(), new ResultMatcher<Amenity>() { getSearchFilter(false), new ResultMatcher<Amenity>() {
boolean done = false; boolean done = false;
@Override @Override
@ -457,7 +547,7 @@ public class TravelObfHelper implements TravelHelper {
if (!Double.isNaN(articleId.lat)) { if (!Double.isNaN(articleId.lat)) {
req.setBBoxRadius(articleId.lat, articleId.lon, ARTICLE_SEARCH_RADIUS); req.setBBoxRadius(articleId.lat, articleId.lon, ARTICLE_SEARCH_RADIUS);
if (!Algorithms.isEmpty(articleId.title)) { if (!Algorithms.isEmpty(articleId.routeId)) {
reader.searchPoiByName(req); reader.searchPoiByName(req);
} else { } else {
reader.searchPoi(req); reader.searchPoi(req);
@ -468,8 +558,8 @@ public class TravelObfHelper implements TravelHelper {
} catch (IOException e) { } catch (IOException e) {
LOG.error(e.getMessage()); LOG.error(e.getMessage());
} }
if (!amenities.isEmpty()) { if (!Algorithms.isEmpty(amenities)) {
article = cacheTravelArticles(reader.getFile(), amenities.get(0), lang); article = cacheTravelArticles(reader.getFile(), amenities.get(0), lang, true);
} }
} }
return article; return article;
@ -510,7 +600,7 @@ public class TravelObfHelper implements TravelHelper {
for (BinaryMapIndexReader reader : getReaders()) { for (BinaryMapIndexReader reader : getReaders()) {
try { try {
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest( SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(
x, y, title, left, right, top, bottom, getSearchRouteArticleFilter(), x, y, title, left, right, top, bottom, getSearchFilter(false),
new ResultMatcher<Amenity>() { new ResultMatcher<Amenity>() {
boolean done = false; boolean done = false;
@ -533,7 +623,7 @@ public class TravelObfHelper implements TravelHelper {
LOG.error(e.getMessage()); LOG.error(e.getMessage());
} }
if (!Algorithms.isEmpty(amenities)) { if (!Algorithms.isEmpty(amenities)) {
article = cacheTravelArticles(reader.getFile(), amenities.get(0), lang); article = cacheTravelArticles(reader.getFile(), amenities.get(0), lang, true);
} }
} }
return article; return article;
@ -599,9 +689,7 @@ public class TravelObfHelper implements TravelHelper {
public File createGpxFile(@NonNull final TravelArticle article) { public File createGpxFile(@NonNull final TravelArticle article) {
final GPXFile gpx = article.getGpxFile(); final GPXFile gpx = article.getGpxFile();
File file = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article)); File file = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article));
if (!file.exists()) { writeGpxFile(file, gpx);
GPXUtilities.writeGpxFile(file, gpx);
}
return file; return file;
} }

View file

@ -33,7 +33,6 @@ public class WikivoyageSearchResult {
TravelArticle article = new TravelArticle(); TravelArticle article = new TravelArticle();
article.routeId = routeId; article.routeId = routeId;
article.title = articleTitle; article.title = articleTitle;
this.articleId = article.generateIdentifier(); this.articleId = article.generateIdentifier();
this.imageTitle = imageTitle; this.imageTitle = imageTitle;
this.isPartOf = isPartOf; this.isPartOf = isPartOf;