package net.osmand.plus; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import net.osmand.data.AmenityType; import net.osmand.plus.activities.OsmandApplication; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; public class PoiFiltersHelper { private final OsmandApplication application; private NameFinderPoiFilter nameFinderPOIFilter; private List<PoiFilter> cacheUserDefinedFilters; private List<PoiFilter> cacheOsmDefinedFilters; public PoiFiltersHelper(OsmandApplication application){ this.application = application; } public NameFinderPoiFilter getNameFinderPOIFilter() { if(nameFinderPOIFilter == null){ nameFinderPOIFilter = new NameFinderPoiFilter(application); } return nameFinderPOIFilter; } public PoiFilter getFilterById(String filterId){ if(filterId == null){ return null; } if(filterId.equals(NameFinderPoiFilter.FILTER_ID)){ return getNameFinderPOIFilter(); } if(filterId.startsWith(PoiFilter.USER_PREFIX)){ List<PoiFilter> filters = getUserDefinedPoiFilters(); for(PoiFilter f : filters){ if(f.getFilterId().equals(filterId)){ return f; } } } else if(filterId.startsWith(PoiFilter.STD_PREFIX)){ List<PoiFilter> filters = getOsmDefinedPoiFilters(); for(PoiFilter f : filters){ if(f.getFilterId().equals(filterId)){ return f; } } } return null; } private List<PoiFilter> getUserDefinedDefaultFilters(){ List<PoiFilter> filters = new ArrayList<PoiFilter>(); Map<AmenityType, LinkedHashSet<String>> types = new LinkedHashMap<AmenityType, LinkedHashSet<String>>(); LinkedHashSet<String> list = new LinkedHashSet<String>(); list.add("fuel"); //$NON-NLS-1$ list.add("car_wash"); //$NON-NLS-1$ list.add("car_repair"); //$NON-NLS-1$ types.put(AmenityType.TRANSPORTATION, list); list = new LinkedHashSet<String>(); list.add("car"); //$NON-NLS-1$ list.add("car_repair"); //$NON-NLS-1$ types.put(AmenityType.SHOP, list); filters.add(new PoiFilter(application.getString(R.string.poi_filter_car_aid), null, types, application)); //$NON-NLS-1$ types.clear(); types.put(AmenityType.HISTORIC, null); types.put(AmenityType.TOURISM, null); list = new LinkedHashSet<String>(); list.add("place_of_worship"); //$NON-NLS-1$ list.add("internet_access"); //$NON-NLS-1$ list.add("bench"); //$NON-NLS-1$ list.add("embassy"); //$NON-NLS-1$ list.add("emergency_phone"); //$NON-NLS-1$ list.add("marketplace"); //$NON-NLS-1$ list.add("post_office"); //$NON-NLS-1$ list.add("recycling"); //$NON-NLS-1$ list.add("telephone"); //$NON-NLS-1$ list.add("toilets"); //$NON-NLS-1$ list.add("waste_basket"); //$NON-NLS-1$ list.add("waste_disposal"); //$NON-NLS-1$ types.put(AmenityType.OTHER, list); filters.add(new PoiFilter(application.getString(R.string.poi_filter_for_tourists), null, types, application)); //$NON-NLS-1$ types.clear(); list = new LinkedHashSet<String>(); list.add("fuel"); //$NON-NLS-1$ types.put(AmenityType.TRANSPORTATION, list); filters.add(new PoiFilter(application.getString(R.string.poi_filter_fuel), null, types, application)); //$NON-NLS-1$ types.clear(); list = new LinkedHashSet<String>(); list.add("alcohol"); //$NON-NLS-1$ list.add("bakery"); //$NON-NLS-1$ list.add("beverages"); //$NON-NLS-1$ list.add("butcher"); //$NON-NLS-1$ list.add("convenience"); //$NON-NLS-1$ list.add("department_store"); //$NON-NLS-1$ list.add("convenience"); //$NON-NLS-1$ list.add("farm"); //$NON-NLS-1$ list.add("general"); //$NON-NLS-1$ list.add("ice_cream"); //$NON-NLS-1$ list.add("kiosk"); //$NON-NLS-1$ list.add("supermarket"); //$NON-NLS-1$ list.add("variety_store"); //$NON-NLS-1$ types.put(AmenityType.SHOP, list); filters.add(new PoiFilter(application.getString(R.string.poi_filter_food_shop), null, types, application)); //$NON-NLS-1$ types.clear(); return filters; } public List<PoiFilter> getUserDefinedPoiFilters(){ if(cacheUserDefinedFilters == null){ ////ctx.deleteDatabase(PoiFilterDbHelper.DATABASE_NAME); cacheUserDefinedFilters = new ArrayList<PoiFilter>(); PoiFilter filter = new PoiFilter(application.getString(R.string.poi_filter_custom_filter), PoiFilter.CUSTOM_FILTER_ID, new LinkedHashMap<AmenityType, LinkedHashSet<String>>(), application); //$NON-NLS-1$ cacheUserDefinedFilters.add(filter); PoiFilterDbHelper helper = openDbHelper(); cacheUserDefinedFilters.addAll(helper.getFilters()); helper.close(); } return Collections.unmodifiableList(cacheUserDefinedFilters); } public static String getOsmDefinedFilterId(AmenityType t){ return PoiFilter.STD_PREFIX + t; } public List<PoiFilter> getOsmDefinedPoiFilters(){ if(cacheOsmDefinedFilters == null){ cacheOsmDefinedFilters = new ArrayList<PoiFilter>(); cacheOsmDefinedFilters.add(new PoiFilter(null, application)); for(AmenityType t : AmenityType.values()){ cacheOsmDefinedFilters.add(new PoiFilter(t, application)); } } return Collections.unmodifiableList(cacheOsmDefinedFilters); } private PoiFilterDbHelper openDbHelper(){ return new PoiFilterDbHelper(application.getApplicationContext()); } public boolean removePoiFilter(PoiFilter filter){ if(filter.getFilterId().equals(PoiFilter.CUSTOM_FILTER_ID)){ return false; } PoiFilterDbHelper helper = openDbHelper(); if(helper == null){ return false; } boolean res = helper.deleteFilter(filter); if(res){ cacheUserDefinedFilters.remove(filter); } helper.close(); return res; } public boolean createPoiFilter(PoiFilter filter){ PoiFilterDbHelper helper = openDbHelper(); if(helper == null){ return false; } boolean res = helper.addFilter(filter, helper.getWritableDatabase(), false); if(res){ cacheUserDefinedFilters.add(filter); } helper.close(); return res; } public boolean editPoiFilter(PoiFilter filter) { if (filter.getFilterId().equals(PoiFilter.CUSTOM_FILTER_ID)) { return false; } PoiFilterDbHelper helper = openDbHelper(); if (helper != null) { boolean res = helper.editFilter(filter); helper.close(); return res; } return false; } public class PoiFilterDbHelper extends SQLiteOpenHelper { public static final String DATABASE_NAME = "poi_filters"; //$NON-NLS-1$ private static final int DATABASE_VERSION = 1; private static final String FILTER_NAME = "poi_filters"; //$NON-NLS-1$ private static final String FILTER_COL_NAME = "name"; //$NON-NLS-1$ private static final String FILTER_COL_ID = "id"; //$NON-NLS-1$ private static final String FILTER_COL_FILTERBYNAME = "filterbyname"; //$NON-NLS-1$ private static final String FILTER_TABLE_CREATE = "CREATE TABLE " + FILTER_NAME + " (" + //$NON-NLS-1$ //$NON-NLS-2$ FILTER_COL_NAME + ", " + FILTER_COL_ID + ", " + FILTER_COL_FILTERBYNAME + ");"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ private static final String CATEGORIES_NAME = "categories"; //$NON-NLS-1$ private static final String CATEGORIES_FILTER_ID = "filter_id"; //$NON-NLS-1$ private static final String CATEGORIES_COL_CATEGORY = "category"; //$NON-NLS-1$ private static final String CATEGORIES_COL_SUBCATEGORY = "subcategory"; //$NON-NLS-1$ private static final String CATEGORIES_TABLE_CREATE = "CREATE TABLE " + CATEGORIES_NAME + " (" + //$NON-NLS-1$ //$NON-NLS-2$ CATEGORIES_FILTER_ID + ", " + CATEGORIES_COL_CATEGORY + ", " + CATEGORIES_COL_SUBCATEGORY + ");"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ PoiFilterDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(FILTER_TABLE_CREATE); db.execSQL(CATEGORIES_TABLE_CREATE); List<PoiFilter> filters = getUserDefinedDefaultFilters(); for(PoiFilter f : filters){ addFilter(f, db,false); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } protected boolean addFilter(PoiFilter p, SQLiteDatabase db, boolean addOnlyCategories){ if(db != null){ if(!addOnlyCategories){ db.execSQL("INSERT INTO " + FILTER_NAME + " VALUES (?, ?, ?)",new Object[]{p.getName(), p.getFilterId(), p.getFilterByName()}); //$NON-NLS-1$ //$NON-NLS-2$ } Map<AmenityType, LinkedHashSet<String>> types = p.getAcceptedTypes(); SQLiteStatement insertCategories = db.compileStatement("INSERT INTO " + CATEGORIES_NAME + " VALUES (?, ?, ?)"); //$NON-NLS-1$ //$NON-NLS-2$ for(AmenityType a : types.keySet()){ if(types.get(a) == null){ insertCategories.bindString(1, p.getFilterId()); insertCategories.bindString(2, AmenityType.valueToString(a)); insertCategories.bindNull(3); insertCategories.execute(); } else { for(String s : types.get(a)){ insertCategories.bindString(1, p.getFilterId()); insertCategories.bindString(2, AmenityType.valueToString(a)); insertCategories.bindString(3, s); insertCategories.execute(); } } } insertCategories.close(); return true; } return false; } protected List<PoiFilter> getFilters(){ SQLiteDatabase db = getReadableDatabase(); ArrayList<PoiFilter> list = new ArrayList<PoiFilter>(); if(db != null){ Cursor query = db.rawQuery("SELECT " + CATEGORIES_FILTER_ID +", " + CATEGORIES_COL_CATEGORY +"," + CATEGORIES_COL_SUBCATEGORY +" FROM " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ CATEGORIES_NAME, null); Map<String, Map<AmenityType, LinkedHashSet<String>>> map = new LinkedHashMap<String, Map<AmenityType,LinkedHashSet<String>>>(); if(query.moveToFirst()){ do { String filterId = query.getString(0); if(!map.containsKey(filterId)){ map.put(filterId, new LinkedHashMap<AmenityType, LinkedHashSet<String>>()); } Map<AmenityType, LinkedHashSet<String>> m = map.get(filterId); AmenityType a = AmenityType.fromString(query.getString(1)); String subCategory = query.getString(2); if(subCategory == null){ m.put(a, null); } else { if(m.get(a) == null){ m.put(a, new LinkedHashSet<String>()); } m.get(a).add(subCategory); } } while(query.moveToNext()); } query.close(); query = db.rawQuery("SELECT " + FILTER_COL_ID +", " + FILTER_COL_NAME +"," + FILTER_COL_FILTERBYNAME +" FROM " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ FILTER_NAME, null); if(query.moveToFirst()){ do { String filterId = query.getString(0); if(map.containsKey(filterId)){ PoiFilter filter = new PoiFilter(query.getString(1), filterId, map.get(filterId), application); filter.setFilterByName(query.getString(2)); list.add(filter); } } while(query.moveToNext()); } query.close(); } return list; } protected boolean editFilter(PoiFilter filter) { SQLiteDatabase db = getWritableDatabase(); if (db != null) { db.execSQL("DELETE FROM " + CATEGORIES_NAME + " WHERE " + CATEGORIES_FILTER_ID + " = ?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ new Object[] { filter.getFilterId() }); addFilter(filter, db, true); db.execSQL("UPDATE " + FILTER_NAME + " SET " + FILTER_COL_FILTERBYNAME + " = ?, " + FILTER_COL_NAME + " = ? " + " WHERE " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + FILTER_COL_ID + "= ?", new Object[] { filter.getFilterByName(), filter.getName(), filter.getFilterId() }); //$NON-NLS-1$ return true; } return false; } protected boolean deleteFilter(PoiFilter p){ SQLiteDatabase db = getWritableDatabase(); if(db != null){ db.execSQL("DELETE FROM " + FILTER_NAME + " WHERE " +FILTER_COL_ID + " = ?",new Object[]{p.getFilterId()}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ db.execSQL("DELETE FROM " + CATEGORIES_NAME + " WHERE " +CATEGORIES_FILTER_ID + " = ?", new Object[]{p.getFilterId()}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ return true; } return false; } } }