custom poi types cache db

This commit is contained in:
veliymolfar 2020-05-08 11:29:36 +03:00
parent 203d25c5e4
commit c02a7820fa
7 changed files with 328 additions and 18 deletions

View file

@ -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();
}
}

View file

@ -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();

View file

@ -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;

View file

@ -632,6 +632,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
} else {
a.newDownloadIndexes();
}
getMyApplication().getPoiHelper().readPoiTypesFromMapAsync();
}
}

View 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();
}
}
}

View file

@ -757,6 +757,7 @@ public class ResourceManager {
for (ResourceListener l : resourceListeners) {
l.onMapsIndexed();
}
context.getPoiHelper().readPoiTypesFromMap();
return warnings;
}

View file

@ -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