refactor poi cache db
This commit is contained in:
parent
ccc98d8c87
commit
3a800d2520
11 changed files with 221 additions and 372 deletions
|
@ -1421,7 +1421,7 @@ public class BinaryMapIndexReader {
|
|||
return addressIndexes;
|
||||
}
|
||||
|
||||
protected List<PoiRegion> getPoiIndexes() {
|
||||
public List<PoiRegion> getPoiIndexes() {
|
||||
return poiIndexes;
|
||||
}
|
||||
|
||||
|
|
|
@ -229,17 +229,7 @@ public class BinaryMapPoiReaderAdapter {
|
|||
region.subcategories.add(new ArrayList<String>());
|
||||
break;
|
||||
case OsmandOdb.OsmAndCategoryTable.SUBCATEGORIES_FIELD_NUMBER:
|
||||
String subCat = codedIS.readString().intern();
|
||||
PoiCategory lastCat = poiTypes.getPoiCategoryByName(region.categories.get(region.categories.size() - 1));
|
||||
PoiType poiType = new PoiType(MapPoiTypes.getDefault(), lastCat, null, subCat);
|
||||
List<String> filters = new ArrayList<>();
|
||||
for (PoiType poi : lastCat.getPoiTypes()) {
|
||||
filters.add(poi.getKeyName());
|
||||
}
|
||||
if (!filters.contains(subCat)) {
|
||||
lastCat.getPoiTypes().add(poiType);
|
||||
}
|
||||
region.subcategories.get(region.subcategories.size() - 1).add(subCat);
|
||||
region.subcategories.get(region.subcategories.size() - 1).add(codedIS.readString().intern());
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
|
|
|
@ -33,7 +33,6 @@ 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;
|
||||
|
||||
|
@ -300,7 +299,6 @@ public class MapPoiTypes {
|
|||
lastCategory.setTopVisible(true);
|
||||
}
|
||||
categories.add(lastCategory);
|
||||
createdCategories.add(lastCategory);
|
||||
return lastCategory;
|
||||
}
|
||||
return otherCategory;
|
||||
|
@ -920,12 +918,4 @@ public class MapPoiTypes {
|
|||
return pat.isText();
|
||||
}
|
||||
}
|
||||
|
||||
public List<PoiCategory> getCreatedCategories() {
|
||||
return createdCategories;
|
||||
}
|
||||
|
||||
public void clearCreatedCategories(){
|
||||
createdCategories.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,5 +69,12 @@ public class PoiFilter extends AbstractPoiType {
|
|||
public List<PoiType> getPoiTypes() {
|
||||
return poiTypes;
|
||||
}
|
||||
|
||||
|
||||
public List<String> getPoiTypesKeys() {
|
||||
List<String> filters = new ArrayList<>();
|
||||
for (PoiType p : poiTypes) {
|
||||
filters.add(p.keyName);
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ 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;
|
||||
|
@ -547,7 +546,6 @@ 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();
|
||||
|
|
|
@ -62,7 +62,6 @@ 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;
|
||||
|
@ -148,7 +147,6 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
SettingsHelper settingsHelper;
|
||||
GpxDbHelper gpxDbHelper;
|
||||
QuickActionRegistry quickActionRegistry;
|
||||
PoiHelper poiHelper;
|
||||
|
||||
private Resources localizedResources;
|
||||
|
||||
|
@ -335,10 +333,6 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
return poiFilters;
|
||||
}
|
||||
|
||||
public PoiHelper getPoiHelper() {
|
||||
return poiHelper;
|
||||
}
|
||||
|
||||
public GpxSelectionHelper getSelectedGpxHelper() {
|
||||
return selectedGpxHelper;
|
||||
}
|
||||
|
|
|
@ -632,7 +632,6 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
|
|||
} else {
|
||||
a.newDownloadIndexes();
|
||||
}
|
||||
getMyApplication().getPoiHelper().readPoiTypesFromMapAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,10 @@ package net.osmand.plus.poi;
|
|||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
|
@ -12,12 +15,18 @@ import net.osmand.plus.ApplicationMode;
|
|||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.api.SQLiteAPI;
|
||||
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
|
||||
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
|
||||
import net.osmand.plus.api.SQLiteAPI.SQLiteStatement;
|
||||
import net.osmand.plus.wikipedia.WikipediaPoiMenu;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -36,6 +45,7 @@ import static net.osmand.osm.MapPoiTypes.WIKI_PLACE;
|
|||
|
||||
public class PoiFiltersHelper {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(PoiFiltersHelper.class);
|
||||
private final OsmandApplication application;
|
||||
|
||||
private NominatimPoiFilter nominatimPOIFilter;
|
||||
|
@ -625,6 +635,33 @@ public class PoiFiltersHelper {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Pair<Long, Map<String, List<String>>> getCacheByResourceName(String fileName) {
|
||||
Pair<Long, Map<String, List<String>>> cache = null;
|
||||
PoiFilterDbHelper helper = openDbHelper();
|
||||
if (helper != null) {
|
||||
cache = helper.getCacheByResourceName(helper.getReadableDatabase(), fileName);
|
||||
helper.close();
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
public void updateCacheForResource(String fileName, long lastModified, Map<String, List<String>> categories) {
|
||||
PoiFilterDbHelper helper = openDbHelper();
|
||||
if (helper != null) {
|
||||
helper.updateCacheForResource(helper.getReadableDatabase(), fileName, lastModified, categories);
|
||||
helper.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void insertCacheForResource(String fileName, long lastModified, Map<String, List<String>> categories) {
|
||||
PoiFilterDbHelper helper = openDbHelper();
|
||||
if (helper != null) {
|
||||
helper.insertCacheForResource(helper.getReadableDatabase(), fileName, lastModified, categories);
|
||||
helper.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveSelectedPoiFilters() {
|
||||
Set<String> filters = new HashSet<>();
|
||||
for (Set<PoiUIFilter> template : selectedPoiFilters.values()) {
|
||||
|
@ -641,7 +678,7 @@ public class PoiFiltersHelper {
|
|||
private static final int FALSE_INT = 0;
|
||||
|
||||
public static final String DATABASE_NAME = "poi_filters";
|
||||
private static final int DATABASE_VERSION = 6;
|
||||
private static final int DATABASE_VERSION = 7;
|
||||
|
||||
private static final String FILTER_NAME = "poi_filters";
|
||||
private static final String FILTER_COL_NAME = "name";
|
||||
|
@ -669,6 +706,20 @@ public class PoiFiltersHelper {
|
|||
CATEGORIES_COL_CATEGORY + ", " +
|
||||
CATEGORIES_COL_SUBCATEGORY + ");";
|
||||
|
||||
private static final String POI_TYPES_CACHE_NAME = "poi_types_cache";
|
||||
private static final String MAP_FILE_NAME = "map_name";
|
||||
private static final String MAP_FILE_DATE = "map_date";
|
||||
private static final String CACHED_POI_CATEGORIES = "cached_categories";
|
||||
|
||||
private static final String POI_CACHE_TABLE_CREATE = "CREATE TABLE " +
|
||||
POI_TYPES_CACHE_NAME + " (" +
|
||||
MAP_FILE_NAME + ", " +
|
||||
MAP_FILE_DATE + ", " +
|
||||
CACHED_POI_CATEGORIES + ");";
|
||||
|
||||
private static final String CATEGORY_KEY = "category";
|
||||
private static final String SUB_CATEGORIES_KEY = "sub_categories";
|
||||
|
||||
private OsmandApplication context;
|
||||
private SQLiteConnection conn;
|
||||
private MapPoiTypes mapPoiTypes;
|
||||
|
@ -714,6 +765,7 @@ public class PoiFiltersHelper {
|
|||
public void onCreate(SQLiteConnection conn) {
|
||||
conn.execSQL(FILTER_TABLE_CREATE);
|
||||
conn.execSQL(CATEGORIES_TABLE_CREATE);
|
||||
conn.execSQL(POI_CACHE_TABLE_CREATE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -725,6 +777,9 @@ public class PoiFiltersHelper {
|
|||
conn.execSQL("ALTER TABLE " + FILTER_NAME + " ADD " + FILTER_COL_HISTORY + " int DEFAULT " + FALSE_INT);
|
||||
conn.execSQL("ALTER TABLE " + FILTER_NAME + " ADD " + FILTER_COL_DELETED + " int DEFAULT " + FALSE_INT);
|
||||
}
|
||||
if (oldVersion < 7) {
|
||||
conn.execSQL(POI_CACHE_TABLE_CREATE);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteOldFilters(SQLiteConnection conn) {
|
||||
|
@ -887,5 +942,89 @@ public class PoiFiltersHelper {
|
|||
db.execSQL("DELETE FROM " + FILTER_NAME + " WHERE " + FILTER_COL_ID + " = ?", new Object[]{key});
|
||||
db.execSQL("DELETE FROM " + CATEGORIES_NAME + " WHERE " + CATEGORIES_FILTER_ID + " = ?", new Object[]{key});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Pair<Long, Map<String, List<String>>> getCacheByResourceName(SQLiteConnection db, String fileName) {
|
||||
Pair<Long, Map<String, List<String>>> cache = null;
|
||||
if (db != null) {
|
||||
SQLiteAPI.SQLiteCursor query = db.rawQuery("SELECT " +
|
||||
MAP_FILE_DATE + ", " +
|
||||
CACHED_POI_CATEGORIES +
|
||||
" FROM " +
|
||||
POI_TYPES_CACHE_NAME +
|
||||
" WHERE " + MAP_FILE_NAME + " = ?", new String[]{fileName});
|
||||
if (query != null && query.moveToFirst()) {
|
||||
long lastModified = query.getLong(0);
|
||||
Map<String, List<String>> categories = getCategories(query.getString(1));
|
||||
cache = new Pair<>(lastModified, categories);
|
||||
}
|
||||
if (query != null) {
|
||||
query.close();
|
||||
}
|
||||
db.close();
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getCategories(String json) {
|
||||
Map<String, List<String>> categories = new HashMap<>();
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray(json);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||
String category = jsonObject.optString(CATEGORY_KEY);
|
||||
List<String> subCategories = getSubCategories(jsonObject.optString(SUB_CATEGORIES_KEY));
|
||||
categories.put(category, subCategories);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Error parsing categories: " + e);
|
||||
}
|
||||
return categories;
|
||||
}
|
||||
|
||||
protected void updateCacheForResource(SQLiteConnection db, String fileName, long lastModified, Map<String, List<String>> categories) {
|
||||
try {
|
||||
db.execSQL("UPDATE " + POI_TYPES_CACHE_NAME + " SET " +
|
||||
MAP_FILE_DATE + " = ?, " +
|
||||
CACHED_POI_CATEGORIES + " = ? " +
|
||||
"WHERE " + MAP_FILE_NAME + " = ?",
|
||||
new Object[]{lastModified, getCategoriesJson(categories), fileName});
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Error converting category to json: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void insertCacheForResource(SQLiteConnection db, String fileName, long lastModified, Map<String, List<String>> categories) {
|
||||
try {
|
||||
db.execSQL("INSERT INTO " + POI_TYPES_CACHE_NAME + " VALUES(?,?,?)",
|
||||
new Object[]{fileName, lastModified, getCategoriesJson(categories)});
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Error converting category to json: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getCategoriesJson(Map<String, List<String>> categories) throws JSONException {
|
||||
JSONArray json = new JSONArray();
|
||||
for (Map.Entry<String, List<String>> entry : categories.entrySet()) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
JSONArray subCategories = new JSONArray();
|
||||
for (String subCategory : entry.getValue()) {
|
||||
subCategories.put(subCategory);
|
||||
}
|
||||
jsonObject.put(CATEGORY_KEY, entry.getKey());
|
||||
jsonObject.put(SUB_CATEGORIES_KEY, subCategories);
|
||||
json.put(jsonObject);
|
||||
}
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
private List<String> getSubCategories(@NonNull String json) throws JSONException {
|
||||
List<String> subCategories = new ArrayList<>();
|
||||
JSONArray jsonArray = new JSONArray(json);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
subCategories.add(jsonArray.optString(i));
|
||||
}
|
||||
return subCategories;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,321 +0,0 @@
|
|||
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 = helper.getFiles();
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getCategories() {
|
||||
if (categories == null) {
|
||||
categories = helper.getCategories();
|
||||
}
|
||||
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) {
|
||||
files.clear();
|
||||
helper.deleteFilesTable();
|
||||
for (LocalIndexInfo info : localMapsIndexes) {
|
||||
File f = new File(info.getPathToData());
|
||||
helper.addFile(f);
|
||||
files.put(f.getName(), f.lastModified());
|
||||
}
|
||||
helper.close();
|
||||
}
|
||||
|
||||
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) {
|
||||
categories.clear();
|
||||
helper.deletePoiTypesTable();
|
||||
for (PoiCategory category : poiCategories) {
|
||||
helper.addCategory(category);
|
||||
categories.put(category.getKeyName(), getSubCategoriesFilters(category.getPoiTypes()));
|
||||
}
|
||||
helper.close();
|
||||
}
|
||||
|
||||
private List<String> getSubCategoriesFilters(List<PoiType> poiTypeList) {
|
||||
List<String> filters = new ArrayList<>();
|
||||
for (PoiType poiType : poiTypeList) {
|
||||
filters.add(poiType.getKeyName());
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
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 = getReadableDatabase();
|
||||
if (db != null) {
|
||||
db.execSQL("INSERT INTO " + FILES_TABLE_NAME + " VALUES (?, ?)",
|
||||
new Object[]{f.getName(), f.lastModified()});
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteFilesTable() {
|
||||
SQLiteAPI.SQLiteConnection db = getReadableDatabase();
|
||||
if (db != null) {
|
||||
db.execSQL("DELETE FROM " + FILES_TABLE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deletePoiTypesTable() {
|
||||
SQLiteAPI.SQLiteConnection db = getReadableDatabase();
|
||||
if (db != null) {
|
||||
db.execSQL("DELETE FROM " + POI_TYPES_TABLE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addCategory(PoiCategory poiCategory) {
|
||||
SQLiteAPI.SQLiteConnection db = getReadableDatabase();
|
||||
if (db != null) {
|
||||
db.execSQL("INSERT INTO " + POI_TYPES_TABLE_NAME + " VALUES (?, ?)",
|
||||
new Object[]{poiCategory.getKeyName(), getSubCategoriesJson(poiCategory.getPoiTypes())});
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Long> getFiles() {
|
||||
Map<String, Long> files = new HashMap<>();
|
||||
SQLiteAPI.SQLiteConnection conn = getReadableDatabase();
|
||||
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();
|
||||
}
|
||||
}
|
||||
close();
|
||||
return files;
|
||||
}
|
||||
|
||||
protected Map<String, List<String>> getCategories() {
|
||||
Map<String, List<String>> categories = new HashMap<>();
|
||||
SQLiteAPI.SQLiteConnection conn = getReadableDatabase();
|
||||
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();
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.plus.resources;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -9,8 +10,12 @@ import net.osmand.binary.BinaryMapIndexReader;
|
|||
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.BinaryMapPoiReaderAdapter;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.poi.PoiFiltersHelper;
|
||||
import net.osmand.plus.resources.ResourceManager.BinaryMapReaderResource;
|
||||
import net.osmand.plus.resources.ResourceManager.BinaryMapReaderResourceType;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
@ -18,18 +23,66 @@ import net.osmand.util.MapUtils;
|
|||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
|
||||
|
||||
private final static Log log = PlatformUtil.getLog(AmenityIndexRepositoryBinary.class);
|
||||
private BinaryMapReaderResource resource;
|
||||
private MapPoiTypes poiTypes;
|
||||
private Map<String, List<String>> poiCategories = new HashMap<>();
|
||||
|
||||
public AmenityIndexRepositoryBinary(BinaryMapReaderResource resource) {
|
||||
public AmenityIndexRepositoryBinary(BinaryMapReaderResource resource, OsmandApplication app) {
|
||||
this.resource = resource;
|
||||
poiTypes = app.getPoiTypes();
|
||||
checkCachedCategories(app.getPoiFilters());
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getPoiCategories() {
|
||||
return poiCategories;
|
||||
}
|
||||
|
||||
private void checkCachedCategories(PoiFiltersHelper poiFiltersHelper) {
|
||||
String fileName = resource.getFileName();
|
||||
long lastModified = resource.getFileLastModified();
|
||||
Pair<Long, Map<String, List<String>>> cache = poiFiltersHelper.getCacheByResourceName(fileName);
|
||||
if (cache == null || cache.first != null && cache.first != lastModified) {
|
||||
try {
|
||||
BinaryMapIndexReader reader = getOpenFile();
|
||||
if (reader != null) {
|
||||
reader.initCategories();
|
||||
List<BinaryMapPoiReaderAdapter.PoiRegion> regions = reader.getPoiIndexes();
|
||||
for (BinaryMapPoiReaderAdapter.PoiRegion region : regions) {
|
||||
List<String> categories = region.getCategories();
|
||||
List<List<String>> subCategories = region.getSubcategories();
|
||||
for (int i = 0; i < categories.size(); i++) {
|
||||
PoiCategory poiCategory = poiTypes.getPoiCategoryByName(categories.get(i));
|
||||
Set<String> filters = new HashSet<>(subCategories.get(i));
|
||||
List<String> keys = poiCategory.getPoiTypesKeys();
|
||||
filters.removeAll(keys);
|
||||
if (!filters.isEmpty()) {
|
||||
poiCategories.put(categories.get(i), new ArrayList<>(filters));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cache == null) {
|
||||
poiFiltersHelper.insertCacheForResource(fileName, lastModified, poiCategories);
|
||||
} else {
|
||||
poiFiltersHelper.updateCacheForResource(fileName, lastModified, poiCategories);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Error initializing categories ", e);
|
||||
}
|
||||
} else if (cache.second != null) {
|
||||
poiCategories = cache.second;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -32,6 +32,7 @@ import net.osmand.map.MapTileDownloader.DownloadRequest;
|
|||
import net.osmand.map.OsmandRegions;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.plus.AppInitializer;
|
||||
import net.osmand.plus.AppInitializer.InitEvents;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
@ -152,6 +153,10 @@ public class ResourceManager {
|
|||
return filename.getName();
|
||||
}
|
||||
|
||||
public long getFileLastModified() {
|
||||
return filename.lastModified();
|
||||
}
|
||||
|
||||
// should not use methods to read from file!
|
||||
@Nullable
|
||||
public BinaryMapIndexReader getShallowReader() {
|
||||
|
@ -735,7 +740,7 @@ public class ResourceManager {
|
|||
resource.setUseForPublicTransport(true);
|
||||
}
|
||||
if (mapReader.containsPoiData()) {
|
||||
amenityRepositories.put(f.getName(), new AmenityIndexRepositoryBinary(resource));
|
||||
amenityRepositories.put(f.getName(), new AmenityIndexRepositoryBinary(resource, context));
|
||||
}
|
||||
}
|
||||
} catch (SQLiteException e) {
|
||||
|
@ -746,6 +751,17 @@ public class ResourceManager {
|
|||
warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_big_for_memory), f.getName()));
|
||||
}
|
||||
}
|
||||
for (AmenityIndexRepository repo : amenityRepositories.values()) {
|
||||
Map<String, List<String>> categories = ((AmenityIndexRepositoryBinary) repo).getPoiCategories();
|
||||
if (!categories.isEmpty()) {
|
||||
for (Map.Entry<String, List<String>> entry : categories.entrySet()) {
|
||||
PoiCategory poiCategory = context.getPoiTypes().getPoiCategoryByName(entry.getKey(), true);
|
||||
for (String s : entry.getValue()) {
|
||||
poiCategory.addPoiType(new PoiType(MapPoiTypes.getDefault(), poiCategory, null, s));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.debug("All map files initialized " + (System.currentTimeMillis() - val) + " ms");
|
||||
if (files.size() > 0 && (!indCache.exists() || indCache.canWrite())) {
|
||||
try {
|
||||
|
@ -757,7 +773,6 @@ public class ResourceManager {
|
|||
for (ResourceListener l : resourceListeners) {
|
||||
l.onMapsIndexed();
|
||||
}
|
||||
context.getPoiHelper().readPoiTypesFromMap();
|
||||
return warnings;
|
||||
}
|
||||
|
||||
|
@ -1123,21 +1138,6 @@ public class ResourceManager {
|
|||
return readers.toArray(new BinaryMapIndexReader[readers.size()]);
|
||||
}
|
||||
|
||||
public BinaryMapIndexReader[] getPoiSearchFiles() {
|
||||
Collection<BinaryMapReaderResource> fileReaders = getFileReaders();
|
||||
List<BinaryMapIndexReader> readers = new ArrayList<>(fileReaders.size());
|
||||
for (BinaryMapReaderResource r : fileReaders) {
|
||||
BinaryMapIndexReader shallowReader = r.getShallowReader();
|
||||
if (shallowReader != null && shallowReader.containsPoiData()) {
|
||||
BinaryMapIndexReader reader = r.getReader(BinaryMapReaderResourceType.POI);
|
||||
if (reader != null) {
|
||||
readers.add(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
return readers.toArray(new BinaryMapIndexReader[readers.size()]);
|
||||
}
|
||||
|
||||
public Map<String, String> getIndexFileNames() {
|
||||
return new LinkedHashMap<String, String>(indexFileNames);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue