custom poi types cache db
This commit is contained in:
parent
203d25c5e4
commit
c02a7820fa
7 changed files with 328 additions and 18 deletions
|
@ -33,6 +33,7 @@ public class MapPoiTypes {
|
|||
private static final Log log = PlatformUtil.getLog(MapRenderingTypes.class);
|
||||
private String resourceName;
|
||||
private List<PoiCategory> categories = new ArrayList<PoiCategory>();
|
||||
private List<PoiCategory> createdCategories = new ArrayList<PoiCategory>();
|
||||
private PoiCategory otherCategory;
|
||||
private PoiCategory otherMapCategory;
|
||||
|
||||
|
@ -299,6 +300,7 @@ public class MapPoiTypes {
|
|||
lastCategory.setTopVisible(true);
|
||||
}
|
||||
categories.add(lastCategory);
|
||||
createdCategories.add(lastCategory);
|
||||
return lastCategory;
|
||||
}
|
||||
return otherCategory;
|
||||
|
@ -919,10 +921,11 @@ public class MapPoiTypes {
|
|||
}
|
||||
}
|
||||
|
||||
public List<PoiCategory> getCreatedCategories() {
|
||||
return createdCategories;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void clearCreatedCategories(){
|
||||
createdCategories.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import net.osmand.IProgress;
|
|||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.aidl.OsmandAidlApi;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.map.OsmandRegions;
|
||||
import net.osmand.map.OsmandRegions.RegionTranslation;
|
||||
import net.osmand.map.WorldRegion;
|
||||
|
@ -43,6 +42,7 @@ import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
|
|||
import net.osmand.plus.monitoring.LiveMonitoringHelper;
|
||||
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
|
||||
import net.osmand.plus.poi.PoiFiltersHelper;
|
||||
import net.osmand.plus.poi.PoiHelper;
|
||||
import net.osmand.plus.quickaction.QuickActionRegistry;
|
||||
import net.osmand.plus.render.MapRenderRepositories;
|
||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||
|
@ -482,17 +482,6 @@ public class AppInitializer implements IProgress {
|
|||
});
|
||||
}
|
||||
|
||||
private void readPoiTypesFromMap() {
|
||||
final BinaryMapIndexReader[] currentFile = app.resourceManager.getPoiSearchFiles();
|
||||
for (BinaryMapIndexReader r : currentFile) {
|
||||
try {
|
||||
r.initCategories();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error while read poi types from map " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onCreateApplication() {
|
||||
// always update application mode to default
|
||||
OsmandSettings osmandSettings = app.getSettings();
|
||||
|
@ -550,6 +539,7 @@ public class AppInitializer implements IProgress {
|
|||
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);
|
||||
app.poiHelper = startupInit(new PoiHelper(app), PoiHelper.class);
|
||||
|
||||
|
||||
initOpeningHoursParser();
|
||||
|
@ -741,7 +731,6 @@ public class AppInitializer implements IProgress {
|
|||
initPoiTypes();
|
||||
notifyEvent(InitEvents.POI_TYPES_INITIALIZED);
|
||||
app.resourceManager.reloadIndexesOnStart(this, warnings);
|
||||
readPoiTypesFromMap();
|
||||
|
||||
// native depends on renderers
|
||||
initNativeCore();
|
||||
|
|
|
@ -61,6 +61,7 @@ import net.osmand.plus.inapp.InAppPurchaseHelper;
|
|||
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
|
||||
import net.osmand.plus.monitoring.LiveMonitoringHelper;
|
||||
import net.osmand.plus.poi.PoiFiltersHelper;
|
||||
import net.osmand.plus.poi.PoiHelper;
|
||||
import net.osmand.plus.quickaction.QuickActionRegistry;
|
||||
import net.osmand.plus.render.RendererRegistry;
|
||||
import net.osmand.plus.resources.ResourceManager;
|
||||
|
@ -146,6 +147,7 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
SettingsHelper settingsHelper;
|
||||
GpxDbHelper gpxDbHelper;
|
||||
QuickActionRegistry quickActionRegistry;
|
||||
PoiHelper poiHelper;
|
||||
|
||||
private Resources localizedResources;
|
||||
|
||||
|
@ -331,6 +333,9 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
return poiFilters;
|
||||
}
|
||||
|
||||
public PoiHelper getPoiHelper() {
|
||||
return poiHelper;
|
||||
}
|
||||
|
||||
public GpxSelectionHelper getSelectedGpxHelper() {
|
||||
return selectedGpxHelper;
|
||||
|
|
|
@ -632,6 +632,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
|
|||
} else {
|
||||
a.newDownloadIndexes();
|
||||
}
|
||||
getMyApplication().getPoiHelper().readPoiTypesFromMapAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
303
OsmAnd/src/net/osmand/plus/poi/PoiHelper.java
Normal file
303
OsmAnd/src/net/osmand/plus/poi/PoiHelper.java
Normal file
|
@ -0,0 +1,303 @@
|
|||
package net.osmand.plus.poi;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.activities.LocalIndexHelper;
|
||||
import net.osmand.plus.activities.LocalIndexInfo;
|
||||
import net.osmand.plus.api.SQLiteAPI;
|
||||
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PoiHelper {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(PoiHelper.class);
|
||||
private OsmandApplication app;
|
||||
private PoiDbHelper helper;
|
||||
private Map<String, Long> files;
|
||||
private Map<String, List<String>> categories;
|
||||
|
||||
public PoiHelper(OsmandApplication app) {
|
||||
this.app = app;
|
||||
helper = new PoiDbHelper(app);
|
||||
}
|
||||
|
||||
public Map<String, Long> getFiles() {
|
||||
if (files == null) {
|
||||
files = new HashMap<>();
|
||||
files = helper.getFiles(helper.getReadableDatabase());
|
||||
helper.close();
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getCategories() {
|
||||
if (categories == null) {
|
||||
categories = new HashMap<>();
|
||||
categories = helper.getCategories(helper.getReadableDatabase());
|
||||
helper.close();
|
||||
}
|
||||
return categories;
|
||||
}
|
||||
|
||||
public void readPoiTypesFromMap() {
|
||||
LocalIndexHelper localIndexHelper = new LocalIndexHelper(app);
|
||||
List<LocalIndexInfo> localMapsIndexes = localIndexHelper.getLocalFullMaps(new AbstractLoadLocalIndexTask() {
|
||||
@Override
|
||||
public void loadFile(LocalIndexInfo... loaded) {
|
||||
}
|
||||
});
|
||||
Map<String, Long> savedFiles = getFiles();
|
||||
if (savedFiles.size() == localMapsIndexes.size()) {
|
||||
for (LocalIndexInfo info : localMapsIndexes) {
|
||||
File f = new File(info.getPathToData());
|
||||
String name = f.getName();
|
||||
long date = f.lastModified();
|
||||
if (!savedFiles.containsKey(name) || savedFiles.get(name) != date) {
|
||||
initCategoriesFromFiles();
|
||||
replaceSavedFiles(localMapsIndexes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
initCategoriesFromFiles();
|
||||
replaceSavedFiles(localMapsIndexes);
|
||||
return;
|
||||
}
|
||||
readCategoriesFromDb();
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public void readPoiTypesFromMapAsync() {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
app.getPoiTypes().init();
|
||||
readPoiTypesFromMap();
|
||||
return null;
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void readCategoriesFromDb() {
|
||||
for (Map.Entry<String, List<String>> entry : getCategories().entrySet()) {
|
||||
PoiCategory poiCategory = app.getPoiTypes().getPoiCategoryByName(entry.getKey(), true);
|
||||
for (String s : entry.getValue()) {
|
||||
PoiType poiType = new PoiType(MapPoiTypes.getDefault(), poiCategory, null, s);
|
||||
List<String> filters = new ArrayList<>();
|
||||
for (PoiType poi : poiCategory.getPoiTypes()) {
|
||||
filters.add(poi.getKeyName());
|
||||
}
|
||||
if (!filters.contains(s)) {
|
||||
poiCategory.getPoiTypes().add(poiType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void replaceSavedFiles(List<LocalIndexInfo> localMapsIndexes) {
|
||||
helper.deleteFilesTable(helper.getWritableDatabase());
|
||||
for (LocalIndexInfo info : localMapsIndexes) {
|
||||
File f = new File(info.getPathToData());
|
||||
helper.addFile(f, helper.getWritableDatabase());
|
||||
}
|
||||
}
|
||||
|
||||
private void initCategoriesFromFiles() {
|
||||
app.getPoiTypes().clearCreatedCategories();
|
||||
final BinaryMapIndexReader[] currentFile = app.getResourceManager().getPoiSearchFiles();
|
||||
for (BinaryMapIndexReader r : currentFile) {
|
||||
try {
|
||||
r.initCategories();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error while read poi types from map " + e);
|
||||
}
|
||||
}
|
||||
replaceSavedCategories(app.getPoiTypes().getCreatedCategories());
|
||||
}
|
||||
|
||||
private void replaceSavedCategories(List<PoiCategory> poiCategories) {
|
||||
helper.deletePoiTypesTable(helper.getWritableDatabase());
|
||||
for (PoiCategory category : poiCategories) {
|
||||
helper.addCategory(category, helper.getWritableDatabase());
|
||||
}
|
||||
}
|
||||
|
||||
public class PoiDbHelper {
|
||||
|
||||
private static final String DATABASE_NAME = "poi_types_cache";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
private static final String FILES_TABLE_NAME = "files";
|
||||
private static final String FILE_NAME = "name";
|
||||
private static final String FILE_DATE = "date";
|
||||
|
||||
private static final String FILES_TABLE_CREATE = "CREATE TABLE " +
|
||||
FILES_TABLE_NAME + " (" +
|
||||
FILE_NAME + ", " +
|
||||
FILE_DATE + ");";
|
||||
|
||||
private static final String POI_TYPES_TABLE_NAME = "poi_types";
|
||||
private static final String POI_CATEGORY = "category";
|
||||
private static final String POI_SUBCATEGORIES = "subcategories";
|
||||
|
||||
private static final String POI_TYPES_TABLE_CREATE = "CREATE TABLE " +
|
||||
POI_TYPES_TABLE_NAME + " (" +
|
||||
POI_CATEGORY + ", " +
|
||||
POI_SUBCATEGORIES + ");";
|
||||
|
||||
private OsmandApplication context;
|
||||
private SQLiteAPI.SQLiteConnection conn;
|
||||
|
||||
PoiDbHelper(OsmandApplication context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public SQLiteAPI.SQLiteConnection getWritableDatabase() {
|
||||
return openConnection(false);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (conn != null) {
|
||||
conn.close();
|
||||
conn = null;
|
||||
}
|
||||
}
|
||||
|
||||
public SQLiteAPI.SQLiteConnection getReadableDatabase() {
|
||||
return openConnection(true);
|
||||
}
|
||||
|
||||
private SQLiteAPI.SQLiteConnection openConnection(boolean readonly) {
|
||||
conn = context.getSQLiteAPI().getOrCreateDatabase(DATABASE_NAME, readonly);
|
||||
if (conn.getVersion() < DATABASE_VERSION) {
|
||||
if (readonly) {
|
||||
conn.close();
|
||||
conn = context.getSQLiteAPI().getOrCreateDatabase(DATABASE_NAME, false);
|
||||
}
|
||||
int version = conn.getVersion();
|
||||
conn.setVersion(DATABASE_VERSION);
|
||||
if (version == 0) {
|
||||
onCreate(conn);
|
||||
}
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
public void onCreate(SQLiteAPI.SQLiteConnection conn) {
|
||||
conn.execSQL(FILES_TABLE_CREATE);
|
||||
conn.execSQL(POI_TYPES_TABLE_CREATE);
|
||||
}
|
||||
|
||||
protected void addFile(File f, SQLiteAPI.SQLiteConnection db) {
|
||||
if (db != null) {
|
||||
db.execSQL("INSERT INTO " + FILES_TABLE_NAME + " VALUES (?, ?)",
|
||||
new Object[]{f.getName(), f.lastModified()});
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteFilesTable(SQLiteAPI.SQLiteConnection db) {
|
||||
if (db != null) {
|
||||
db.execSQL("DELETE FROM " + FILES_TABLE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deletePoiTypesTable(SQLiteAPI.SQLiteConnection db) {
|
||||
if (db != null) {
|
||||
db.execSQL("DELETE FROM " + POI_TYPES_TABLE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addCategory(PoiCategory poiCategory, SQLiteAPI.SQLiteConnection db) {
|
||||
if (db != null) {
|
||||
db.execSQL("INSERT INTO " + POI_TYPES_TABLE_NAME + " VALUES (?, ?)",
|
||||
new Object[]{poiCategory.getKeyName(), getSubCategoriesJson(poiCategory.getPoiTypes())});
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Long> getFiles(SQLiteAPI.SQLiteConnection conn) {
|
||||
Map<String, Long> files = new HashMap<>();
|
||||
if (conn != null) {
|
||||
SQLiteAPI.SQLiteCursor query = conn.rawQuery("SELECT " +
|
||||
FILE_NAME + ", " +
|
||||
FILE_DATE +
|
||||
" FROM " +
|
||||
FILES_TABLE_NAME, null);
|
||||
if (query != null && query.moveToFirst()) {
|
||||
do {
|
||||
String fileName = query.getString(0);
|
||||
Long date = query.getLong(1);
|
||||
files.put(fileName, date);
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
if (query != null) {
|
||||
query.close();
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
protected Map<String, List<String>> getCategories(SQLiteAPI.SQLiteConnection conn) {
|
||||
Map<String, List<String>> categories = new HashMap<>();
|
||||
if (conn != null) {
|
||||
SQLiteAPI.SQLiteCursor query = conn.rawQuery("SELECT " +
|
||||
POI_CATEGORY + ", " +
|
||||
POI_SUBCATEGORIES +
|
||||
" FROM " +
|
||||
POI_TYPES_TABLE_NAME, null);
|
||||
if (query != null && query.moveToFirst()) {
|
||||
do {
|
||||
String categoryName = query.getString(0);
|
||||
List<String> subCategories = getSubCategories(query.getString(1));
|
||||
categories.put(categoryName, subCategories);
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
if (query != null) {
|
||||
query.close();
|
||||
}
|
||||
}
|
||||
return categories;
|
||||
}
|
||||
|
||||
private List<String> getSubCategories(@NonNull String json) {
|
||||
List<String> subCategories = new ArrayList<>();
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray(json);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
subCategories.add(jsonArray.optString(i));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Error parsing subCategories json: " + e);
|
||||
}
|
||||
return subCategories;
|
||||
}
|
||||
|
||||
private String getSubCategoriesJson(@NonNull List<PoiType> poiTypes) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (PoiType subCategory : poiTypes) {
|
||||
jsonArray.put(subCategory.getKeyName());
|
||||
}
|
||||
return jsonArray.toString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -757,6 +757,7 @@ public class ResourceManager {
|
|||
for (ResourceListener l : resourceListeners) {
|
||||
l.onMapsIndexed();
|
||||
}
|
||||
context.getPoiHelper().readPoiTypesFromMap();
|
||||
return warnings;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ import net.osmand.plus.render.RenderingIcons;
|
|||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
@ -90,6 +92,12 @@ public class QuickSearchCustomPoiFragment extends DialogFragment {
|
|||
this.nightMode = app.getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_DARK_THEME;
|
||||
setStyle(STYLE_NO_FRAME, nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme);
|
||||
poiCategoryList = app.getPoiTypes().getCategories(false);
|
||||
Collections.sort(poiCategoryList, new Comparator<PoiCategory>() {
|
||||
@Override
|
||||
public int compare(PoiCategory poiCategory, PoiCategory t1) {
|
||||
return poiCategory.getTranslation().compareTo(t1.getTranslation());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue