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 4af1596c2c..f7be034cbe 100644 --- a/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java +++ b/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java @@ -39,6 +39,11 @@ public class Amenity extends MapObject { public static final String REF = "ref"; public static final String OSM_DELETE_VALUE = "delete"; public static final String OSM_DELETE_TAG = "osmand_change"; + public static final String IMAGE_TITLE = "image_title"; + public static final String IS_PART = "is_part"; + public static final String IS_AGGR_PART = "is_aggr_part"; + public static final String CONTENT_JSON = "content_json"; + private String subType; private PoiCategory type; diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index a862182014..8f13681d69 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -66,6 +66,8 @@ import net.osmand.plus.voice.JSTTSCommandPlayerImpl; import net.osmand.plus.voice.MediaCommandPlayerImpl; import net.osmand.plus.voice.TTSCommandPlayerImpl; import net.osmand.plus.wikivoyage.data.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; +import net.osmand.plus.wikivoyage.data.TravelObfHelper; import net.osmand.render.RenderingRulesStorage; import net.osmand.router.RoutingConfiguration; import net.osmand.util.Algorithms; @@ -85,7 +87,6 @@ import java.util.Locale; import java.util.Map; import java.util.Random; -import btools.routingapp.BRouterServiceConnection; import btools.routingapp.IBRouterService; import static net.osmand.plus.AppVersionUpgradeOnInit.LAST_APP_VERSION; @@ -457,11 +458,14 @@ public class AppInitializer implements IProgress { app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class); app.searchUICore = startupInit(new QuickSearchHelper(app), QuickSearchHelper.class); app.mapViewTrackingUtilities = startupInit(new MapViewTrackingUtilities(app), MapViewTrackingUtilities.class); - app.travelDbHelper = new TravelDbHelper(app); + + //TODO cleanup after Travel migration complete + app.travelHelper = TravelObfHelper.checkIfObfFileExists(app) ? new TravelObfHelper(app) : new TravelDbHelper(app); if (app.getSettings().SELECTED_TRAVEL_BOOK.get() != null) { - app.travelDbHelper.initTravelBooks(); + app.travelHelper.initTravelBooks(); } - app.travelDbHelper = startupInit(app.travelDbHelper, TravelDbHelper.class); + app.travelHelper = startupInit(app.travelHelper, TravelHelper.class); + app.lockHelper = startupInit(new LockHelper(app), LockHelper.class); app.settingsHelper = startupInit(new SettingsHelper(app), SettingsHelper.class); app.quickActionRegistry = startupInit(new QuickActionRegistry(app.getSettings()), QuickActionRegistry.class); diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 00bdd97e2d..bbe45aab51 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -79,7 +79,7 @@ import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.backup.SettingsHelper; import net.osmand.plus.voice.CommandPlayer; -import net.osmand.plus.wikivoyage.data.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.router.GeneralRouter; import net.osmand.router.RoutingConfiguration; import net.osmand.router.RoutingConfiguration.Builder; @@ -148,7 +148,7 @@ public class OsmandApplication extends MultiDexApplication { OsmandRegions regions; GeocodingLookupService geocodingLookupService; QuickSearchHelper searchUICore; - TravelDbHelper travelDbHelper; + TravelHelper travelHelper; InAppPurchaseHelper inAppPurchaseHelper; MapViewTrackingUtilities mapViewTrackingUtilities; LockHelper lockHelper; @@ -481,8 +481,8 @@ public class OsmandApplication extends MultiDexApplication { return searchUICore; } - public TravelDbHelper getTravelDbHelper() { - return travelDbHelper; + public TravelHelper getTravelHelper() { + return travelHelper; } public InAppPurchaseHelper getInAppPurchaseHelper() { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 5a6a7560a5..00bd656b63 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -76,6 +76,7 @@ import net.osmand.plus.views.layers.MapControlsLayer; import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.plus.wikivoyage.WikivoyageWelcomeDialogFragment; import net.osmand.plus.wikivoyage.data.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity; import net.osmand.router.GeneralRouter; import net.osmand.util.Algorithms; @@ -924,9 +925,9 @@ public class MapActivityActions implements DialogProvider { @Override public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { MapActivity.clearPrevActivityIntent(); - TravelDbHelper travelDbHelper = getMyApplication().getTravelDbHelper(); - travelDbHelper.initTravelBooks(); - if (travelDbHelper.getSelectedTravelBook() == null) { + TravelHelper travelHelper = getMyApplication().getTravelHelper(); + travelHelper.initTravelBooks(); + if (travelHelper.getSelectedTravelBook() == null) { WikivoyageWelcomeDialogFragment.showInstance(mapActivity.getSupportFragmentManager()); } else { Intent intent = new Intent(mapActivity, WikivoyageExploreActivity.class); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java index 3650f6d820..74797620f9 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java @@ -27,6 +27,7 @@ import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; @@ -567,11 +568,11 @@ public class MapMarkersHelper { @NonNull public List getGroupsForSavedArticlesTravelBook() { List res = new ArrayList<>(); - TravelDbHelper travelDbHelper = ctx.getTravelDbHelper(); - if (travelDbHelper.getSelectedTravelBook() != null) { - List savedArticles = travelDbHelper.getLocalDataHelper().getSavedArticles(); + TravelHelper travelHelper = ctx.getTravelHelper(); + if (travelHelper.getSelectedTravelBook() != null) { + List savedArticles = travelHelper.getLocalDataHelper().getSavedArticles(); for (TravelArticle art : savedArticles) { - String gpxName = travelDbHelper.getGPXName(art); + String gpxName = travelHelper.getGPXName(art); File path = ctx.getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName); LOG.debug("Article group " + path.getAbsolutePath() + " " + path.exists()); MapMarkersGroup search = getMapMarkerGroupById(getMarkerGroupId(path), MapMarkersGroup.GPX_TYPE); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 30639c768b..4cb0b9f690 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -37,6 +37,7 @@ import net.osmand.plus.mapmarkers.SelectWptCategoriesBottomSheetDialogFragment; import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; import java.io.File; import java.text.SimpleDateFormat; @@ -163,11 +164,11 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter savedArticles = travelDbHelper.getLocalDataHelper().getSavedArticles(); + TravelHelper travelHelper = mapActivity.getMyApplication().getTravelHelper(); + if (travelHelper.getSelectedTravelBook() != null) { + List savedArticles = travelHelper.getLocalDataHelper().getSavedArticles(); for (TravelArticle art : savedArticles) { - String gpxName = travelDbHelper.getGPXName(art); + String gpxName = travelHelper.getGPXName(art); File path = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName); if (path.getAbsolutePath().equals(group.getGpxPath())) { group.setWikivoyageArticle(art); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java index 7612583067..d27ceba057 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackActivityFragmentAdapter.java @@ -486,7 +486,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener { String title = metadata.getArticleTitle(); String lang = metadata.getArticleLang(); if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(lang)) { - return app.getTravelDbHelper().getArticle(title, lang); + return app.getTravelHelper().getArticle(title, lang); } return null; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java index fe47a8f370..7886ff2a7e 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java @@ -67,7 +67,7 @@ public class WikivoyageWebViewClient extends WebViewClient { if (url.contains(WIKIVOAYAGE_DOMAIN) && isWebPage) { String lang = WikiArticleHelper.getLang(url); String articleName = WikiArticleHelper.getArticleNameFromUrl(url, lang); - long articleId = app.getTravelDbHelper().getArticleId(articleName, lang); + long articleId = app.getTravelHelper().getArticleId(articleName, lang); if (articleId != 0) { WikivoyageArticleDialogFragment.showInstance(app, fragmentManager, articleId, lang); } else { @@ -116,7 +116,7 @@ public class WikivoyageWebViewClient extends WebViewClient { fragmentManager.popBackStackImmediate(); - File path = app.getTravelDbHelper().createGpxFile(article); + File path = app.getTravelHelper().createGpxFile(article); GPXUtilities.GPXFile gpxFile = article.getGpxFile(); gpxFile.path = path.getAbsolutePath(); app.getSelectedGpxHelper().setGpxFileToDisplay(gpxFile); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index fa704688a0..d23200f40b 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -42,6 +42,7 @@ import net.osmand.plus.wikivoyage.WikivoyageShowPicturesDialogFragment; import net.osmand.plus.wikivoyage.WikivoyageWebViewClient; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import net.osmand.util.Algorithms; @@ -148,8 +149,8 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme if (article == null || activity == null || fm == null) { return; } - TravelDbHelper dbHelper = getMyApplication().getTravelDbHelper(); - File path = dbHelper.createGpxFile(article); + TravelHelper travelHelper = getMyApplication().getTravelHelper(); + File path = travelHelper.createGpxFile(article); Intent newIntent = new Intent(activity, getMyApplication().getAppCustomization().getTrackActivity()); newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, path.getAbsolutePath()); newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -234,7 +235,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme private void updateSaveButton() { if (article != null) { - final TravelLocalDataHelper helper = getMyApplication().getTravelDbHelper().getLocalDataHelper(); + final TravelLocalDataHelper helper = getMyApplication().getTravelHelper().getLocalDataHelper(); final boolean saved = helper.isArticleSaved(article); Drawable icon = getActiveIcon(saved ? R.drawable.ic_action_read_later_fill : R.drawable.ic_action_read_later); saveBtn.setText(getString(saved ? R.string.shared_string_remove : R.string.shared_string_bookmark)); @@ -246,7 +247,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme if (saved) { helper.removeArticleFromSaved(article); } else { - getMyApplication().getTravelDbHelper().createGpxFile(article); + getMyApplication().getTravelHelper().createGpxFile(article); helper.addArticleToSaved(article); } updateSaveButton(); @@ -301,7 +302,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme selectedLang = langs.get(0); } articleToolbarText.setText(""); - article = getMyApplication().getTravelDbHelper().getArticle(tripId, selectedLang); + article = getMyApplication().getTravelHelper().getArticle(tripId, selectedLang); if (article == null) { return; } @@ -314,7 +315,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme trackButton.setVisibility(View.GONE); } - TravelLocalDataHelper ldh = getMyApplication().getTravelDbHelper().getLocalDataHelper(); + TravelLocalDataHelper ldh = getMyApplication().getTravelHelper().getLocalDataHelper(); ldh.addToHistory(article); updateSaveButton(); @@ -370,7 +371,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme @NonNull FragmentManager fm, @NonNull String title, @NonNull String lang) { - long cityId = app.getTravelDbHelper().getArticleId(title, lang); + long cityId = app.getTravelHelper().getArticleId(title, lang); return showInstance(app, fm, cityId, lang); } @@ -378,7 +379,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme @NonNull FragmentManager fm, long cityId, @Nullable String selectedLang) { - ArrayList langs = app.getTravelDbHelper().getArticleLangs(cityId); + ArrayList langs = app.getTravelHelper().getArticleLangs(cityId); return showInstance(fm, cityId, langs, selectedLang); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleNavigationFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleNavigationFragment.java index 886e128d04..11ca183c50 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleNavigationFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleNavigationFragment.java @@ -73,13 +73,13 @@ public class WikivoyageArticleNavigationFragment extends MenuBottomSheetDialogFr return; } - article = getMyApplication().getTravelDbHelper().getArticle(cityId, selectedLang); + article = getMyApplication().getTravelHelper().getArticle(cityId, selectedLang); if (article == null) { return; } parentsList = new ArrayList<>(Arrays.asList(article.getAggregatedPartOf().split(","))); - LinkedHashMap> navigationMap = getMyApplication().getTravelDbHelper().getNavigationMap(article); + LinkedHashMap> navigationMap = getMyApplication().getTravelHelper().getNavigationMap(article); items.add(new TitleItem(getString(R.string.shared_string_navigation))); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java index df591f4020..0ca212164d 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java @@ -14,6 +14,7 @@ import net.osmand.IndexConstants; import net.osmand.Location; import net.osmand.OsmAndCollator; import net.osmand.PlatformUtil; +import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -43,7 +44,7 @@ import java.util.Set; import gnu.trove.map.hash.TLongObjectHashMap; -public class TravelDbHelper { +public class TravelDbHelper implements TravelHelper { private static final Log LOG = PlatformUtil.getLog(TravelDbHelper.class); @@ -646,7 +647,7 @@ public class TravelDbHelper { return file; } - private static class PopularArticle { + protected static class PopularArticle { long tripId; String title; String lang; @@ -654,11 +655,11 @@ public class TravelDbHelper { int order; double lat; double lon; - + public boolean isLocationSpecified() { return !Double.isNaN(lat) && !Double.isNaN(lon); } - + public static PopularArticle readArticle(SQLiteCursor cursor) { PopularArticle res = new PopularArticle(); res.title = cursor.getString(0); @@ -670,5 +671,17 @@ public class TravelDbHelper { res.popIndex = cursor.isNull(6) ? 0 : cursor.getInt(6); return res; } + + public static PopularArticle readArticleFromAmenity(Amenity a, String lang) { + PopularArticle res = new PopularArticle(); + res.title = a.getName(lang); + res.lat = a.getLocation().getLatitude(); + res.lon = a.getLocation().getLongitude(); + res.tripId = a.getId(); + res.lang = lang; + res.order = -1; + res.popIndex = 0; + return res; + } } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java new file mode 100644 index 0000000000..065aff9e3f --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java @@ -0,0 +1,53 @@ +package net.osmand.plus.wikivoyage.data; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.plus.OsmandApplication; + +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public interface TravelHelper { + + TravelLocalDataHelper getLocalDataHelper(); + + void initTravelBooks(); + + void loadDataForSelectedTravelBook(); + + File getSelectedTravelBook(); + + List getExistingTravelBooks(); + + void selectTravelBook(File f); + + @NonNull + List search(final String searchQuery); + + @NonNull + List getPopularArticles(); + + @NonNull + List loadPopularArticles(); + + LinkedHashMap> getNavigationMap( + final TravelArticle article); + + TravelArticle getArticle(long cityId, String lang); + + TravelArticle getArticle(String title, String lang); + + long getArticleId(String title, String lang); + + ArrayList getArticleLangs(long cityId); + + String formatTravelBookName(File tb); + + String getGPXName(TravelArticle article); + + File createGpxFile(TravelArticle article); +} diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java index 6127c3e5d5..68f2f7cc2c 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelLocalDataHelper.java @@ -260,7 +260,7 @@ public class TravelLocalDataHelper { if (oldVersion < 3) { conn.execSQL("ALTER TABLE " + HISTORY_TABLE_NAME + " ADD " + HISTORY_COL_TRAVEL_BOOK + " TEXT"); conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_TRAVEL_BOOK + " TEXT"); - File selectedTravelBook = context.getTravelDbHelper().getSelectedTravelBook(); + File selectedTravelBook = context.getTravelHelper().getSelectedTravelBook(); if (selectedTravelBook != null) { Object[] args = new Object[]{selectedTravelBook.getName()}; conn.execSQL("UPDATE " + HISTORY_TABLE_NAME + " SET " + HISTORY_COL_TRAVEL_BOOK + " = ?", args); @@ -452,7 +452,7 @@ public class TravelLocalDataHelper { @Nullable private String getSelectedTravelBookName() { - File selectedTravelBook = context.getTravelDbHelper().getSelectedTravelBook(); + File selectedTravelBook = context.getTravelHelper().getSelectedTravelBook(); if (selectedTravelBook != null) { return selectedTravelBook.getName(); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java new file mode 100644 index 0000000000..3f6b27129e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -0,0 +1,301 @@ +package net.osmand.plus.wikivoyage.data; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.Collator; +import net.osmand.GPXUtilities; +import net.osmand.IndexConstants; +import net.osmand.OsmAndCollator; +import net.osmand.PlatformUtil; +import net.osmand.ResultMatcher; +import net.osmand.binary.BinaryIndexPart; +import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.binary.BinaryMapPoiReaderAdapter; +import net.osmand.data.Amenity; +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.util.Algorithms; +import net.osmand.util.MapUtils; + +import org.apache.commons.logging.Log; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + + + +public class TravelObfHelper implements TravelHelper{ + + private static final Log LOG = PlatformUtil.getLog(TravelObfHelper.class); + + private static final String WIKIVOYAGE_OBF = "Wikivoyage.obf"; + public static final String ROUTE_ARTICLE = "route_article"; + + private final OsmandApplication application; + private Collator collator; + private TravelLocalDataHelper localDataHelper; + + private File selectedTravelBook = null; + private List existingTravelBooks = new ArrayList<>(); + private List popularArticles = new ArrayList(); + + private BinaryMapIndexReader index = null; + + + public TravelObfHelper(OsmandApplication application) { + this.application = application; + collator = OsmAndCollator.primaryCollator(); + localDataHelper = new TravelLocalDataHelper(application); + } + + public static boolean checkIfObfFileExists(OsmandApplication app) { + File[] files = app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).listFiles(); + if (files != null) { + for (File f : files) { + if (f.getName().equals(WIKIVOYAGE_OBF)) { + return true; + } + } + } + return false; + } + + @Override + public TravelLocalDataHelper getLocalDataHelper() { + return localDataHelper; + } + + /** TODO + * 1. implement regional travelbooks + * 2. check settings for default? + */ + public void initTravelBooks() { + List files = getPossibleFiles(); + String travelBook = application.getSettings().SELECTED_TRAVEL_BOOK.get(); + existingTravelBooks.clear(); + if (files != null && !files.isEmpty()) { + for (File f : files) { + existingTravelBooks.add(f); + if (selectedTravelBook == null) { + selectedTravelBook = f; + } else if (Algorithms.objectEquals(travelBook, f.getName())) { + selectedTravelBook = f; + } + } + selectedTravelBook = files.get(0); + } else { + selectedTravelBook = null; + } + + } + + /** + * todo: get all obf files from folder, may be we should add some suffix like 'wikivoyage' + * to filenames to distinguish from other maps? Or add some checks right there. + */ + @Nullable + private List getPossibleFiles() { + File[] files = application.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).listFiles(); + if (files != null) { + List res = new ArrayList<>(); + for (File file : files) { + if (file.getName().equals("Wikivoyage.obf")) { + res.add(file); + LOG.debug(String.format("FIle name: %s", file.getAbsolutePath())); + } + } + return res; + } + return null; + } + + public void loadDataForSelectedTravelBook() { + localDataHelper.refreshCachedData(); + loadPopularArticles(); + } + + @Override + public File getSelectedTravelBook() { + return selectedTravelBook; + } + + @Override + public List getExistingTravelBooks() { + return existingTravelBooks; + } + + @Override + public void selectTravelBook(File f) { + //todo + } + + @NonNull + @Override + public List search(String searchQuery) { + return null; + } + + @NonNull + public List getPopularArticles() { + return popularArticles; + } + + //TODO for now it reads any articles, since we didn't have popular articles in the obf + @NonNull + public List loadPopularArticles() { + String language = application.getLanguage(); + final List articles = new ArrayList<>(); + try { + BinaryMapIndexReader bookIndexReader = getBookBinaryIndex(); + if (bookIndexReader == null) { + popularArticles = new ArrayList<>(); + return popularArticles; + } + LatLon ll = application.getMapViewTrackingUtilities().getMapLocation(); + float coeff = 2; + BinaryMapIndexReader.SearchRequest req = + BinaryMapIndexReader.buildSearchPoiRequest( + MapUtils.get31TileNumberX(ll.getLongitude() - coeff), + MapUtils.get31TileNumberX(ll.getLongitude() + coeff), + MapUtils.get31TileNumberY(ll.getLatitude() + coeff), + MapUtils.get31TileNumberY(ll.getLatitude() - coeff), + -1, + BinaryMapIndexReader.ACCEPT_ALL_POI_TYPE_FILTER, + new ResultMatcher() { + int count = 0; + + @Override + public boolean publish(Amenity object) { + //TODO need more logical way to filter results + if (object.getSubType().equals(ROUTE_ARTICLE)) { + articles.add(object); + } + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + }); + + bookIndexReader.searchPoi(req); + bookIndexReader.close(); + + if (articles.size() > 0) { + Iterator it = articles.iterator(); + while (it.hasNext()) { + Amenity a = it.next(); + if (!a.getName(language).equals("")) { + popularArticles.add(readArticle(a, language)); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return popularArticles; + } + + + private TravelArticle readArticle(Amenity amenity, String lang) { + TravelArticle res = new TravelArticle(); + + res.title = amenity.getName(lang).equals("") ? amenity.getName() : amenity.getName(lang); + res.content = amenity.getDescription(lang); + res.isPartOf = amenity.getTagContent(Amenity.IS_PART, lang) == null ? "" : amenity.getTagContent(Amenity.IS_PART, lang); + res.lat = amenity.getLocation().getLatitude(); + res.lon = amenity.getLocation().getLongitude(); + res.imageTitle = amenity.getTagContent(Amenity.IMAGE_TITLE, lang) == null ? "" : amenity.getTagContent(Amenity.IMAGE_TITLE, lang); + res.tripId = amenity.getId(); //? + res.originalId = 0; //? + res.lang = lang; + res.contentsJson = amenity.getTagContent(Amenity.CONTENT_JSON, lang) == null ? "" : amenity.getTagContent(Amenity.CONTENT_JSON, lang); + res.aggregatedPartOf = amenity.getTagContent(Amenity.IS_AGGR_PART, lang) == null ? "" : amenity.getTagContent(Amenity.IS_AGGR_PART, lang); + +// crash in some places, need to fix it +// try { +// String gpxContent = amenity.getAdditionalInfo("gpx_info"); +// res.gpxFile = GPXUtilities.loadGPXFile(new ByteArrayInputStream(gpxContent.getBytes("UTF-8"))); +// } catch (IOException e) { +// LOG.error(e.getMessage(), e); +// } + + return res; + } + + private BinaryMapIndexReader getBookBinaryIndex() throws IOException { + application.getSettings().SELECTED_TRAVEL_BOOK.set(selectedTravelBook.getName()); + try { + RandomAccessFile r = new RandomAccessFile(selectedTravelBook.getAbsolutePath(), "r"); + BinaryMapIndexReader index = new BinaryMapIndexReader(r, selectedTravelBook); + for (BinaryIndexPart p : index.getIndexes()) { + if (p instanceof BinaryMapPoiReaderAdapter.PoiRegion) { + return index; + } + } + } catch (IOException e) { + System.err.println("File doesn't have valid structure : " + selectedTravelBook.getName() + " " + e.getMessage()); + throw e; + } + return null; + } + + @Override + public LinkedHashMap> getNavigationMap(TravelArticle article) { + return null; + } + + @Override + public TravelArticle getArticle(long cityId, String lang) { + return null; + } + + @Override + public TravelArticle getArticle(String title, String lang) { + return null; + } + + @Override + public long getArticleId(String title, String lang) { + return 0; + } + + @Override + public ArrayList getArticleLangs(long cityId) { + return null; + } + + @Override + public String formatTravelBookName(File tb) { + if (tb == null) { + return application.getString(R.string.shared_string_none); + } + String nm = tb.getName(); + return nm.substring(0, nm.indexOf('.')).replace('_', ' '); + } + + @Override + public String getGPXName(TravelArticle article) { + return article.getTitle().replace('/', '_').replace('\'', '_') + .replace('\"', '_') + IndexConstants.GPX_FILE_EXT; + } + + @Override + public File createGpxFile(TravelArticle article) { + final GPXUtilities.GPXFile gpx = article.getGpxFile(); + File file = application.getAppPath(IndexConstants.GPX_TRAVEL_DIR + getGPXName(article)); + if (!file.exists()) { + GPXUtilities.writeGpxFile(file, gpx); + } + return file; + } +} diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index 88e814773b..2419f02636 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -29,6 +29,7 @@ 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.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import net.osmand.plus.wikivoyage.explore.travelcards.ArticleTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.BaseTravelCard; @@ -92,7 +93,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv super.onResume(); OsmandApplication app = getMyApplication(); if (app != null) { - app.getTravelDbHelper().getLocalDataHelper().addListener(this); + app.getTravelHelper().getLocalDataHelper().addListener(this); } WikivoyageExploreActivity exploreActivity = getExploreActivity(); if (exploreActivity != null) { @@ -105,7 +106,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv super.onPause(); OsmandApplication app = getMyApplication(); if (app != null) { - app.getTravelDbHelper().getLocalDataHelper().removeListener(this); + app.getTravelHelper().getLocalDataHelper().removeListener(this); } } @@ -135,9 +136,9 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv public void downloadHasFinished() { OsmandApplication app = getMyApplication(); if (app != null) { - TravelDbHelper travelDbHelper = app.getTravelDbHelper(); - if (travelDbHelper.getSelectedTravelBook() == null) { - app.getTravelDbHelper().initTravelBooks(); + TravelHelper travelHelper = app.getTravelHelper(); + if (travelHelper.getSelectedTravelBook() == null) { + app.getTravelHelper().initTravelBooks(); WikivoyageExploreActivity exploreActivity = getExploreActivity(); if (exploreActivity != null) { exploreActivity.populateData(); @@ -181,10 +182,10 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv if (!Version.isPaidVersion(app)) { items.add(new OpenBetaTravelCard(app, nightMode, fm)); } - if (app.getTravelDbHelper().getSelectedTravelBook() != null) { + if (app.getTravelHelper().getSelectedTravelBook() != null) { items.add(new HeaderTravelCard(app, nightMode, getString(R.string.popular_destinations))); - List popularArticles = app.getTravelDbHelper().getPopularArticles(); + List popularArticles = app.getTravelHelper().getPopularArticles(); for (TravelArticle article : popularArticles) { items.add(new ArticleTravelCard(app, nightMode, article, fm)); } @@ -238,7 +239,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv boolean outdated = mainIndexItem != null && mainIndexItem.isOutdated(); boolean needsDownloading = mainIndexItem != null && !mainIndexItem.isDownloaded(); - File selectedTravelBook = app.getTravelDbHelper().getSelectedTravelBook(); + File selectedTravelBook = app.getTravelHelper().getSelectedTravelBook(); if (selectedTravelBook == null || needsDownloading || (outdated && SHOW_TRAVEL_UPDATE_CARD)) { boolean showOtherMaps = false; @@ -389,7 +390,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv IndexItem mainItem = app.getDownloadThread().getIndexes().getWikivoyageItem(fileName); List neededItems = new ArrayList<>(); - for (TravelArticle article : app.getTravelDbHelper().getLocalDataHelper().getSavedArticles()) { + for (TravelArticle article : app.getTravelHelper().getLocalDataHelper().getSavedArticles()) { LatLon latLon = new LatLon(article.getLat(), article.getLon()); try { for (DownloadActivityType type : types) { diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java index bc8025cba9..6a4864d147 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java @@ -195,7 +195,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter { private WeakReference activityRef; - private TravelDbHelper travelDbHelper; + private TravelHelper travelHelper; LoadWikivoyageData(WikivoyageExploreActivity activity) { - travelDbHelper = activity.getMyApplication().getTravelDbHelper(); + travelHelper = activity.getMyApplication().getTravelHelper(); activityRef = new WeakReference<>(activity); } @Override protected Void doInBackground(Void... params) { - travelDbHelper.loadDataForSelectedTravelBook(); + travelHelper.loadDataForSelectedTravelBook(); return null; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java index 988598c359..fe3021ba51 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageOptionsBottomSheetDialogFragment.java @@ -25,6 +25,7 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.wikivoyage.data.TravelDbHelper; +import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import java.io.File; @@ -45,13 +46,13 @@ public class WikivoyageOptionsBottomSheetDialogFragment extends MenuBottomSheetD return; } final CommonPreference showImagesPref = app.getSettings().WIKI_ARTICLE_SHOW_IMAGES; - final TravelDbHelper dbHelper = app.getTravelDbHelper(); + final TravelHelper travelHelper = app.getTravelHelper(); items.add(new TitleItem(getString(R.string.shared_string_options))); - if (dbHelper.getExistingTravelBooks().size() > 1) { + if (travelHelper.getExistingTravelBooks().size() > 1) { BaseBottomSheetItem selectTravelBook = new BottomSheetItemWithDescription.Builder() - .setDescription(dbHelper.formatTravelBookName(dbHelper.getSelectedTravelBook())) + .setDescription(travelHelper.formatTravelBookName(travelHelper.getSelectedTravelBook())) .setDescriptionColorId(nightMode ? R.color.wikivoyage_active_dark : R.color.wikivoyage_active_light) .setIcon(getContentIcon(R.drawable.ic_action_travel)) .setTitle(getString(R.string.shared_string_travel_book)) @@ -125,7 +126,7 @@ public class WikivoyageOptionsBottomSheetDialogFragment extends MenuBottomSheetD public void onClick(View v) { OsmandApplication app = getMyApplication(); if (app != null) { - TravelLocalDataHelper ldh = app.getTravelDbHelper().getLocalDataHelper(); + TravelLocalDataHelper ldh = app.getTravelHelper().getLocalDataHelper(); ldh.clearHistory(); } dismiss(); @@ -149,11 +150,11 @@ public class WikivoyageOptionsBottomSheetDialogFragment extends MenuBottomSheetD return; } - final TravelDbHelper dbHelper = app.getTravelDbHelper(); - final List list = dbHelper.getExistingTravelBooks(); + final TravelHelper travelHelper = app.getTravelHelper(); + final List list = travelHelper.getExistingTravelBooks(); String[] ls = new String[list.size()]; for (int i = 0; i < ls.length; i++) { - ls[i] = dbHelper.formatTravelBookName(list.get(i)); + ls[i] = travelHelper.formatTravelBookName(list.get(i)); } new AlertDialog.Builder(ctx) @@ -161,7 +162,7 @@ public class WikivoyageOptionsBottomSheetDialogFragment extends MenuBottomSheetD .setItems(ls, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - dbHelper.selectTravelBook(list.get(which)); + travelHelper.selectTravelBook(list.get(which)); sendResult(TRAVEL_BOOK_CHANGED); } }) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/ArticleTravelCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/ArticleTravelCard.java index 5b782c5757..084209674a 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/ArticleTravelCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/ArticleTravelCard.java @@ -91,7 +91,7 @@ public class ArticleTravelCard extends BaseTravelCard { private void updateSaveButton(final ArticleTravelVH holder) { if (article != null) { - final TravelLocalDataHelper helper = app.getTravelDbHelper().getLocalDataHelper(); + final TravelLocalDataHelper helper = app.getTravelHelper().getLocalDataHelper(); 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_bookmark); @@ -103,7 +103,7 @@ public class ArticleTravelCard extends BaseTravelCard { if (saved) { helper.removeArticleFromSaved(article); } else { - app.getTravelDbHelper().createGpxFile(article); + app.getTravelHelper().createGpxFile(article); helper.addArticleToSaved(article); } updateSaveButton(holder); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/menu/WikivoyageWptPtMenuController.java b/OsmAnd/src/net/osmand/plus/wikivoyage/menu/WikivoyageWptPtMenuController.java index 1ea04be8b4..9ad66116cb 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/menu/WikivoyageWptPtMenuController.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/menu/WikivoyageWptPtMenuController.java @@ -42,7 +42,7 @@ public class WikivoyageWptPtMenuController extends WptPtMenuController { String title = metadata != null ? metadata.getArticleTitle() : null; String lang = metadata != null ? metadata.getArticleLang() : null; if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(lang)) { - return mapActivity.getMyApplication().getTravelDbHelper().getArticle(title, lang); + return mapActivity.getMyApplication().getTravelHelper().getArticle(title, lang); } return null; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchDialogFragment.java index 826d938562..f0aafde679 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchDialogFragment.java @@ -151,7 +151,7 @@ public class WikivoyageSearchDialogFragment extends WikiBaseDialogFragment { private void setAdapterItems(@Nullable List items) { if (items == null || items.isEmpty()) { - TravelLocalDataHelper ldh = getMyApplication().getTravelDbHelper().getLocalDataHelper(); + TravelLocalDataHelper ldh = getMyApplication().getTravelHelper().getLocalDataHelper(); adapter.setHistoryItems(ldh.getAllHistory()); } else { adapter.setItems(items); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchHelper.java index 147cfbd91e..e25feedfc1 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchHelper.java @@ -42,7 +42,7 @@ public class WikivoyageSearchHelper { } if (!isCancelled()) { - List results = application.getTravelDbHelper().search(query); + List results = application.getTravelHelper().search(query); if (!isCancelled()) { rm.publish(results); }