diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java b/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java index afd4821d88..3fc4439314 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java @@ -735,8 +735,12 @@ public class BinaryInspector { @Override public int compare(MapStatKey o1, MapStatKey o2) { - return -Long.compare(o1.statObjectSize, o2.statObjectSize); + return compare(o1.statObjectSize, o2.statObjectSize); } + + public int compare(long x, long y) { + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } }); for(MapStatKey s : stats) { @@ -1008,6 +1012,11 @@ public class BinaryInspector { public boolean accept(PoiCategory type, String subcategory) { return true; } + + @Override + public boolean isEmpty() { + return false; + } }, new ResultMatcher() { diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java index 064e6aa31f..12b4cd4837 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java @@ -1539,6 +1539,7 @@ public class BinaryMapIndexReader { public boolean accept(PoiCategory type, String subcategory); + public boolean isEmpty(); } public static class MapObjectStat { @@ -1992,6 +1993,11 @@ public class BinaryMapIndexReader { return false; } + @Override + public boolean isEmpty() { + return false; + } + }, null); req.zoom = -1; List results = reader.searchPoi(req); @@ -2104,6 +2110,11 @@ public class BinaryMapIndexReader { return true; } + @Override + public boolean isEmpty() { + return false; + } + }, null); List results = reader.searchPoi(req); for (Amenity a : results) { diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml index 18e3d115a1..eb7a4ddaa3 100644 --- a/OsmAnd/res/values-be/strings.xml +++ b/OsmAnd/res/values-be/strings.xml @@ -1946,4 +1946,5 @@ Адрас Паказаць апісаньне Пошук + Месцы diff --git a/OsmAnd/res/values-da/strings.xml b/OsmAnd/res/values-da/strings.xml index 4ad220aae1..c9d4d0f8ce 100644 --- a/OsmAnd/res/values-da/strings.xml +++ b/OsmAnd/res/values-da/strings.xml @@ -1992,4 +1992,5 @@ Adresse Vis beskrivelse Søg + Steder diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index dae1fb0a0c..7a87dffa6c 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -2011,4 +2011,5 @@ Afghanistan, Albanie, Algérie, Allemagne, Andorre, Angola, Anguilla, Antigua-et Adresse Afficher la description Rechercher + Lieux diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 400b8e719b..4128badaff 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -2143,4 +2143,6 @@ Afganistan, Albánsko, Alžírsko, Andora, Angola, Anguilla, Antigua a Barbuda, Nepoužívať Adresa Zobraziť popis + Miesta + Hľadať diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 4b7668a0c7..65fd9e5104 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -10,6 +10,7 @@ PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> A-GPS info + Places Search Show description Message diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 52448732f5..57317b4e96 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -738,7 +738,7 @@ public class OsmandSettings { public static final String TRANSPORT_STOPS_OVER_MAP = "transportStops"; - public final OsmandPreference MAP_PREFERRED_LOCALE = new StringPreference("map_preferred_locale", "").makeGlobal(); + public final OsmandPreference MAP_PREFERRED_LOCALE = new StringPreference("map_preferred_locale", "").makeGlobal().cache(); public boolean usingEnglishNames() { return MAP_PREFERRED_LOCALE.get().equals("en"); diff --git a/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java b/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java index da41741d1e..e414429d5d 100644 --- a/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java @@ -4,6 +4,25 @@ package net.osmand.plus.activities; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import net.osmand.data.LatLon; +import net.osmand.osm.PoiCategory; +import net.osmand.osm.PoiType; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.activities.search.SearchActivity; +import net.osmand.plus.activities.search.SearchPOIActivity; +import net.osmand.plus.poi.PoiFiltersHelper; +import net.osmand.plus.poi.PoiLegacyFilter; +import net.osmand.util.Algorithms; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.DialogInterface; @@ -19,35 +38,9 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.LinearLayout.LayoutParams; import android.widget.ListView; import android.widget.ScrollView; import android.widget.TextView; -import android.widget.Toast; - -import net.osmand.access.AccessibleToast; -import net.osmand.data.LatLon; -import net.osmand.osm.PoiCategory; -import net.osmand.osm.PoiType; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.activities.search.SearchActivity; -import net.osmand.plus.activities.search.SearchPOIActivity; -import net.osmand.plus.poi.PoiFiltersHelper; -import net.osmand.plus.poi.PoiLegacyFilter; -import net.osmand.util.Algorithms; - -import java.text.Collator; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; /** * @@ -59,8 +52,6 @@ public class EditPOIFilterActivity extends OsmandListActivity { public static final String SEARCH_LAT = SearchActivity.SEARCH_LAT; //$NON-NLS-1$ public static final String SEARCH_LON = SearchActivity.SEARCH_LON; //$NON-NLS-1$ private static final int FILTER = 2; - private static final int DELETE_FILTER = 3; - private static final int SAVE_FILTER = 4; @Override @@ -90,33 +81,20 @@ public class EditPOIFilterActivity extends OsmandListActivity { if (item.getItemId() == FILTER) { filterPOI(); return true; - } else if (item.getItemId() == DELETE_FILTER) { - removePoiFilter(); - return true; - } else if (item.getItemId() == SAVE_FILTER) { - savePoiFilter(); - return true; } return super.onOptionsItemSelected(item); } + @Override public boolean onCreateOptionsMenu(Menu menu) { if(filter == null) { return super.onCreateOptionsMenu(menu); } - createMenuItem(menu, SAVE_FILTER, R.string.edit_filter_save_as_menu_item, - R.drawable.ic_action_gsave_dark , - MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); createMenuItem(menu, FILTER, R.string.filter_current_poiButton, - 0, + R.drawable.ic_action_done, //R.drawable.a_1_navigation_accept_light, R.drawable.a_1_navigation_accept_dark, MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT | MenuItemCompat.SHOW_AS_ACTION_ALWAYS); - if(!filter.isStandardFilter()){ - createMenuItem(menu, DELETE_FILTER, R.string.shared_string_delete, - R.drawable.ic_action_delete_dark, - MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); - } return super.onCreateOptionsMenu(menu); } @@ -156,53 +134,9 @@ public class EditPOIFilterActivity extends OsmandListActivity { } } - public void savePoiFilter() { - Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.edit_filter_save_as_menu_item); - final EditText editText = new EditText(this); - LinearLayout ll = new LinearLayout(this); - ll.setPadding(5, 3, 5, 0); - ll.addView(editText, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - builder.setView(ll); - builder.setNegativeButton(R.string.shared_string_cancel, null); - builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - PoiLegacyFilter nFilter = new PoiLegacyFilter(editText.getText().toString(), null, filter.getAcceptedTypes(), (OsmandApplication) getApplication()); - if (helper.createPoiFilter(nFilter)) { - AccessibleToast.makeText( - EditPOIFilterActivity.this, - MessageFormat.format(EditPOIFilterActivity.this.getText(R.string.edit_filter_create_message).toString(), - editText.getText().toString()), Toast.LENGTH_SHORT).show(); - } - EditPOIFilterActivity.this.finish(); - } - }); - builder.create().show(); - - } - private void removePoiFilter() { - Builder builder = new AlertDialog.Builder(this); - builder.setMessage(R.string.edit_filter_delete_dialog_title); - builder.setNegativeButton(R.string.shared_string_no, null); - builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (helper.removePoiFilter(filter)) { - AccessibleToast.makeText( - EditPOIFilterActivity.this, - MessageFormat.format(EditPOIFilterActivity.this.getText(R.string.edit_filter_delete_message).toString(), - filter.getName()), Toast.LENGTH_SHORT).show(); - EditPOIFilterActivity.this.finish(); - } - - } - }); - builder.create().show(); - } private void showDialog(final PoiCategory poiCategory) { ListView lv = EditPOIFilterActivity.this.getListView(); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index 52265e2e51..5351bed783 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -281,8 +281,8 @@ public class MapActivityLayers { } else { getApplication().getSettings().setPoiFilterForMap(filterId); pf = poiFilters.getFilterById(filterId); - if (pf != null && pf.isStandardFilter()) { - pf.clearNameFilter(); + if (pf != null) { + pf.setFilterByName(pf.getSavedFilterByName()); } poiMapLayer.setFilter(pf); mapView.refreshMap(); @@ -303,7 +303,7 @@ public class MapActivityLayers { if (RenderingIcons.containsBigIcon(f.getSimplifiedId())) { it.icon(RenderingIcons.getBigIconResourceId(f.getSimplifiedId())); } else { - it.icon(RenderingIcons.getBigIconResourceId("user_defined")); + it.icon(R.drawable.mx_user_defined); } it.reg(); } diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java index 9126d08351..895a7534d9 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java @@ -162,7 +162,8 @@ public class SearchActivity extends TabActivity implements OsmAndLocationListene if(tab == POI_TAB_INDEX) { return SearchPoiFilterFragment.class; } else if(tab == ADDRESS_TAB_INDEX) { - return searchOnLine ? SearchAddressOnlineFragment.class : SearchAddressFragment.class; +// return searchOnLine ? SearchAddressOnlineFragment.class : SearchAddressFragment.class; + return SearchAddressFragment.class; } else if(tab == LOCATION_TAB_INDEX) { return NavigatePointFragment.class; } else if(tab == HISTORY_TAB_INDEX) { @@ -358,15 +359,6 @@ public class SearchActivity extends TabActivity implements OsmAndLocationListene } public void setAddressSpecContent() { -// mTabsAdapter.mViewPager.setCurrentItem(0); -// mTabsAdapter.mTabHost.setCurrentTab(0); -// if (searchOnLine) { -// mTabsAdapter.mTabs.get(1).clss = SearchAddressOnlineFragment.class; -// } else { -// mTabsAdapter.mTabs.get(1).clss = SearchAddressFragment.class; -// } -// mTabsAdapter.notifyDataSetChanged(); -// mTabsAdapter.mViewPager.invalidate(); Intent intent = getIntent(); finish(); startActivity(intent); diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchAddressFragment.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchAddressFragment.java index 94f51ee2da..e7dc79ad6b 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchAddressFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchAddressFragment.java @@ -36,6 +36,7 @@ public class SearchAddressFragment extends Fragment { public static final String SELECT_ADDRESS_POINT_INTENT_KEY = "SELECT_ADDRESS_POINT_INTENT_KEY"; public static final int SELECT_ADDRESS_POINT_RESULT_OK = 1; + private static final boolean ENABLE_ONLINE_ADDRESS = false; // disabled moved to poi search public static final String SELECT_ADDRESS_POINT_LAT = "SELECT_ADDRESS_POINT_LAT"; public static final String SELECT_ADDRESS_POINT_LON = "SELECT_ADDRESS_POINT_LON"; private static final int NAVIGATE_TO = 0; @@ -152,16 +153,18 @@ public class SearchAddressFragment extends Fragment { return true; } }); - menuItem = menu.add(0, ONLINE_SEARCH, 0, R.string.search_online_address); - MenuItemCompat.setShowAsAction(menuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); - menuItem = menuItem.setIcon(R.drawable.ic_world_globe_dark); - menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - ((SearchActivity) getActivity()).startSearchAddressOnline(); - return true; - } - }); + if (ENABLE_ONLINE_ADDRESS) { + menuItem = menu.add(0, ONLINE_SEARCH, 0, R.string.search_online_address); + MenuItemCompat.setShowAsAction(menuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); + menuItem = menuItem.setIcon(R.drawable.ic_world_globe_dark); + menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + ((SearchActivity) getActivity()).startSearchAddressOnline(); + return true; + } + }); + } } } diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java index e310ec4a45..6fafb86f46 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java @@ -5,22 +5,20 @@ package net.osmand.plus.activities.search; import gnu.trove.set.hash.TLongHashSet; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; +import net.osmand.Location; import net.osmand.ResultMatcher; import net.osmand.access.AccessibleToast; import net.osmand.access.NavigationInfo; import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; -import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; @@ -29,14 +27,12 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.R.color; -import net.osmand.plus.activities.EditPOIFilterActivity; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandListActivity; import net.osmand.plus.dashboard.DashLocationFragment; import net.osmand.plus.dialogs.DirectionsDialogs; -import net.osmand.plus.poi.NameFinderPoiFilter; +import net.osmand.plus.poi.NominatimPoiFilter; import net.osmand.plus.poi.PoiLegacyFilter; -import net.osmand.plus.poi.SearchByNameFilter; import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.views.DirectionDrawable; import net.osmand.util.Algorithms; @@ -45,9 +41,8 @@ import net.osmand.util.OpeningHoursParser; import net.osmand.util.OpeningHoursParser.OpeningHours; import android.app.AlertDialog; import android.app.AlertDialog.Builder; +import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; -import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.AsyncTask.Status; @@ -67,11 +62,14 @@ import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Filter; import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; import android.widget.Toast; @@ -88,7 +86,11 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa private static final int SEARCH_MORE = 0; private static final int SHOW_ON_MAP = 1; private static final int FILTER = 2; - + + private static final int EDIT_FILTER = 4; + private static final int DELETE_FILTER = 5; + private static final int SAVE_FILTER = 6; + private PoiLegacyFilter filter; private AmenityAdapter amenityAdapter; @@ -99,33 +101,24 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa private net.osmand.Location location = null; private Float heading = null; - private OsmandSettings settings; - - private float width = 24; - private float height = 24; - - // never null represents current running task or last finished - private SearchAmenityTask currentSearchTask = new SearchAmenityTask(null); + private SearchAmenityTask currentSearchTask = null; private OsmandApplication app; private MenuItem showFilterItem; private MenuItem showOnMapItem; private MenuItem searchPOILevel; @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu = getClearToolbar(true).getMenu(); + public boolean onCreateOptionsMenu(Menu omenu) { + Menu menu = getClearToolbar(true).getMenu(); searchPOILevel = menu.add(0, SEARCH_MORE, 0, R.string.search_POI_level_btn); MenuItemCompat.setShowAsAction(searchPOILevel, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); searchPOILevel.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - - return searchMore(); + return search(); } }); - updateSearchPoiTextButton(false); - showFilterItem = menu.add(0, FILTER, 0, R.string.search_poi_filter); MenuItemCompat.setShowAsAction(showFilterItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); showFilterItem = showFilterItem.setIcon(getMyApplication().getIconsCache().getActionBarIcon( @@ -133,30 +126,22 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa showFilterItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - if (isSearchByNameFilter()) { - Intent newIntent = new Intent(SearchPOIActivity.this, EditPOIFilterActivity.class); - newIntent.putExtra(EditPOIFilterActivity.AMENITY_FILTER, PoiLegacyFilter.CUSTOM_FILTER_ID); - if (location != null) { - newIntent.putExtra(EditPOIFilterActivity.SEARCH_LAT, location.getLatitude()); - newIntent.putExtra(EditPOIFilterActivity.SEARCH_LON, location.getLongitude()); - } - startActivity(newIntent); + if (searchFilterLayout.getVisibility() == View.GONE) { + searchFilterLayout.setVisibility(View.VISIBLE); + searchFilter.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(searchFilter, InputMethodManager.SHOW_IMPLICIT); } else { - if (searchFilterLayout.getVisibility() == View.GONE) { - searchFilterLayout.setVisibility(View.VISIBLE); - } else { - searchFilter.setText(""); //$NON-NLS-1$ - searchFilterLayout.setVisibility(View.GONE); + if(filter != null) { + searchFilter.setText(filter.getSavedFilterByName() == null ? "" : + filter.getSavedFilterByName()); } + searchFilterLayout.setVisibility(View.GONE); } return true; } }); - updateShowFilterItem(); - if (isSearchByNameFilter() || isNameFinderFilter()) { - showFilterItem.setVisible(false); - } - + showOnMapItem = menu.add(0, SHOW_ON_MAP, 0, R.string.shared_string_show_on_map); MenuItemCompat.setShowAsAction(showOnMapItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); showOnMapItem = showOnMapItem.setIcon(getMyApplication().getIconsCache().getActionBarIcon( @@ -164,9 +149,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa showOnMapItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - if (searchFilter.getVisibility() == View.VISIBLE) { - filter.setNameFilter(searchFilter.getText().toString()); - } + OsmandSettings settings = app.getSettings(); settings.setPoiFilterForMap(filter.getFilterId()); settings.SHOW_POI_OVER_MAP.set(true); if (location != null) { @@ -177,6 +160,15 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa } }); + if (filter != null && !isNameSearch()) { + createMenuItem(omenu, SAVE_FILTER, R.string.edit_filter_save_as_menu_item, R.drawable.ic_action_gsave_dark, + MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); + if (!filter.isStandardFilter()) { + createMenuItem(omenu, DELETE_FILTER, R.string.shared_string_delete, R.drawable.ic_action_delete_dark, + MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); + } + } + updateButtonState(); return true; } @@ -188,25 +180,20 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa return tb; } - private boolean searchMore() { + private boolean search() { String query = searchFilter.getText().toString().trim(); - if (query.length() < 2 && (isNameFinderFilter() || isSearchByNameFilter())) { + if (query.length() < 2 && isNameSearch()) { AccessibleToast.makeText(SearchPOIActivity.this, R.string.poi_namefinder_query_empty, Toast.LENGTH_LONG) .show(); return true; } - if (isNameFinderFilter() && !Algorithms.objectEquals(((NameFinderPoiFilter) filter).getQuery(), query)) { + if (isNameSearch() && !Algorithms.objectEquals(filter.getFilterByName(), query)) { filter.clearPreviousZoom(); - ((NameFinderPoiFilter) filter).setQuery(query); - runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT)); - } else if (isSearchByNameFilter() && !Algorithms.objectEquals(((SearchByNameFilter) filter).getQuery(), query)) { - showFilterItem.setVisible(false); - filter.clearPreviousZoom(); - showPoiCategoriesByNameFilter(query, location); - ((SearchByNameFilter) filter).setQuery(query); - runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT)); + filter.setFilterByName(query); + runNewSearchQuery(location, NEW_SEARCH_INIT); } else { - runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.SEARCH_FURTHER)); + filter.setFilterByName(query); + runNewSearchQuery(location, SEARCH_FURTHER); } return true; } @@ -221,23 +208,14 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa setSupportProgressBarIndeterminateVisibility(false); app = (OsmandApplication) getApplication(); - - searchFilter = (EditText) findViewById(R.id.edit); + amenityAdapter = new AmenityAdapter(new ArrayList()); + setListAdapter(amenityAdapter); searchFilterLayout = findViewById(R.id.SearchFilterLayout); - - settings = ((OsmandApplication) getApplication()).getSettings(); - + searchFilter = (EditText) findViewById(R.id.edit); searchFilter.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { - if (!isNameFinderFilter() && !isSearchByNameFilter()) { - amenityAdapter.getFilter().filter(s); - } else { - if (searchPOILevel != null) { - searchPOILevel.setEnabled(true); - searchPOILevel.setTitle(R.string.search_button); - } - } + changeFilter(s); } @Override @@ -256,17 +234,10 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa } } }); - amenityAdapter = new AmenityAdapter(new ArrayList()); - setListAdapter(amenityAdapter); - - boolean light = getMyApplication().getSettings().isLightContent(); - Drawable arrowImage = getResources().getDrawable(R.drawable.ic_destination_arrow_white); - if (light) { - arrowImage.setColorFilter(getResources().getColor(R.color.color_distance), PorterDuff.Mode.MULTIPLY); - } else { - arrowImage.setColorFilter(getResources().getColor(R.color.color_distance), PorterDuff.Mode.MULTIPLY); - } + } + + @Override protected void onResume() { @@ -289,18 +260,17 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa if (filter != null) { filter.clearPreviousZoom(); } else { - amenityAdapter.setNewModel(Collections. emptyList(), ""); + amenityAdapter.setNewModel(Collections. emptyList()); } // run query again - clearSearchQuery(); + runNewSearchQuery(location, NEW_SEARCH_INIT); } + updateButtonState(); if (filter != null) { - filter.clearNameFilter(); + String text = filter.getFilterByName() != null ? filter.getFilterByName() : ""; + searchFilter.setText(text); + searchFilterLayout.setVisibility(text.length() > 0 || isNameSearch() ? View.VISIBLE : View.GONE); } - - updateSubtitle(); - updateSearchPoiTextButton(false); - updateShowFilterItem(); if (filter != null) { if (searchNearBy) { app.getLocationProvider().addLocationListener(this); @@ -309,143 +279,91 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa } updateLocation(location); } - if (isNameFinderFilter()) { - searchFilterLayout.setVisibility(View.VISIBLE); - } else if (isSearchByNameFilter()) { - searchFilterLayout.setVisibility(View.VISIBLE); - } + // Freeze the direction arrows (reference is constant north) when Accessibility mode = ON, so screen can be read // aloud without continuous updates if (!app.accessibilityEnabled()) { app.getLocationProvider().addCompassListener(this); app.getLocationProvider().registerOrUnregisterCompassListener(true); } - if(searchFilterLayout.getVisibility() == View.VISIBLE) { - searchFilter.requestFocus(); + + } + + private void changeFilter(CharSequence s) { + // if (!isNameSearch() ) { + amenityAdapter.getFilter().filter(s); + String cfilter = filter == null || filter.getFilterByName() == null ? "" : + filter.getFilterByName().toLowerCase(); + if(!isNameSearch() && !s.toString().toLowerCase().startsWith(cfilter)) { + filter.setFilterByName(s.toString()); + runNewSearchQuery(location, SEARCH_AGAIN); } + updateButtonState(); } - private void updateShowFilterItem() { + private void updateButtonState() { if (showFilterItem != null) { - showFilterItem.setVisible(filter != null); + showFilterItem.setVisible(filter != null && !isNameSearch()); } - } - - private void updateSubtitle() { if (filter != null) { - getSupportActionBar().setSubtitle(filter.getName() + " " + filter.getSearchArea()); - } - } - - private void showPoiCategoriesByNameFilter(String query, net.osmand.Location loc) { - OsmandApplication app = (OsmandApplication) getApplication(); - if (loc != null) { - Map> map = app.getResourceManager().searchAmenityCategoriesByName(query, - loc.getLatitude(), loc.getLongitude()); - if (!map.isEmpty()) { - PoiLegacyFilter filter = ((OsmandApplication) getApplication()).getPoiFilters().getFilterById( - PoiLegacyFilter.CUSTOM_FILTER_ID); - if (filter != null) { - showFilterItem.setVisible(true); - filter.setMapToAccept(map); - } - - String s = typesToString(map); - AccessibleToast.makeText(this, getString(R.string.poi_query_by_name_matches_categories) + s, - Toast.LENGTH_LONG).show(); + int maxLength = 24; + String name = filter.getGeneratedName(maxLength); + if(name.length() >= maxLength) { + name = name.substring(0, maxLength) + getString(R.string.shared_string_ellipsis); } - } - } - - private String typesToString(Map> map) { - StringBuilder b = new StringBuilder(); - int count = 0; - Iterator>> iterator = map.entrySet().iterator(); - while (iterator.hasNext() && count < 4) { - Entry> e = iterator.next(); - b.append("\n").append(e.getKey().getTranslation()).append(" - "); - if (e.getValue() == null) { - b.append("..."); + if(filter instanceof NominatimPoiFilter && !((NominatimPoiFilter) filter).isPlacesQuery()) { + // nothing to add } else { - for (int j = 0; j < e.getValue().size() && j < 3; j++) { - if (j > 0) { - b.append(", "); - } - b.append(e.getValue().get(j)); - } + name += " " + filter.getSearchArea(); } - } - if (iterator.hasNext()) { - b.append("\n..."); - } - return b.toString(); - } - - private void updateSearchPoiTextButton(boolean taskAlreadyFinished) { - boolean enabled = false; - int title = R.string.search_POI_level_btn; - - if (location == null) { - title = R.string.search_poi_location; - enabled = false; - } else if (filter != null && !isNameFinderFilter() && !isSearchByNameFilter()) { - title = R.string.search_POI_level_btn; - enabled = (taskAlreadyFinished || currentSearchTask.getStatus() != Status.RUNNING) - && filter.isSearchFurtherAvailable(); - } else if (filter != null) { - // TODO: for search-by-name case, as long as filter text field is empty, we could disable the search button - // (with title search_button) until at least 2 characters are typed - // title = R.string.search_button; - // The following is needed as it indicates that search radius can be extended in search-by-name case - title = R.string.search_POI_level_btn; - enabled = (taskAlreadyFinished || currentSearchTask.getStatus() != Status.RUNNING) - && filter.isSearchFurtherAvailable(); + getSupportActionBar().setTitle(name); } if (searchPOILevel != null) { + int title = location == null ? R.string.search_poi_location : R.string.search_POI_level_btn; + boolean taskAlreadyFinished = currentSearchTask == null || currentSearchTask.getStatus() != Status.RUNNING; + boolean enabled = taskAlreadyFinished && location != null && + filter != null && filter.isSearchFurtherAvailable(); + if(isNameSearch() && !Algorithms.objectEquals(searchFilter.getText().toString(), filter.getFilterByName())) { + enabled = true; + title = R.string.search_button; + } searchPOILevel.setEnabled(enabled); searchPOILevel.setTitle(title); } } - private net.osmand.Location getSearchedLocation() { - return currentSearchTask.getSearchedLocation(); - } - - private synchronized void runNewSearchQuery(SearchAmenityRequest request) { - if (currentSearchTask.getStatus() == Status.FINISHED || currentSearchTask.getSearchedLocation() == null) { - currentSearchTask = new SearchAmenityTask(request); + private synchronized void runNewSearchQuery(net.osmand.Location location, int requestType) { + if (currentSearchTask == null || currentSearchTask.getStatus() == Status.FINISHED ) { + currentSearchTask = new SearchAmenityTask(location, requestType); currentSearchTask.execute(); } } - private synchronized void clearSearchQuery() { - if (currentSearchTask.getStatus() == Status.FINISHED || currentSearchTask.getSearchedLocation() == null) { - currentSearchTask = new SearchAmenityTask(null); - } + public boolean isNominatimFilter() { + return filter instanceof NominatimPoiFilter; } - public boolean isNameFinderFilter() { - return filter instanceof NameFinderPoiFilter; - } - - public boolean isSearchByNameFilter() { + public boolean isOfflineSearchByNameFilter() { return filter != null && PoiLegacyFilter.BY_NAME_FILTER_ID.equals(filter.getFilterId()); } + + public boolean isNameSearch() { + return isNominatimFilter() || isOfflineSearchByNameFilter(); + } @Override public void updateLocation(net.osmand.Location location) { boolean handled = false; if (location != null && filter != null) { - net.osmand.Location searchedLocation = getSearchedLocation(); + net.osmand.Location searchedLocation = currentSearchTask == null ? null : currentSearchTask.getSearchedLocation(); if (searchedLocation == null) { - searchedLocation = location; - if (!isNameFinderFilter() && !isSearchByNameFilter()) { - runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT)); + if (!isNameSearch()) { + runNewSearchQuery(location, NEW_SEARCH_INIT); } handled = true; } else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) { searchedLocation = location; - runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.SEARCH_AGAIN)); + runNewSearchQuery(location, SEARCH_AGAIN); handled = true; } else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_REFRESH) { handled = true; @@ -457,16 +375,8 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa } if (handled) { this.location = location; - updateSearchPoiTextButton(false); - // Get the top position from the first visible element - int idx = getListView().getFirstVisiblePosition(); - View vfirst = getListView().getChildAt(0); - int pos = 0; - if (vfirst != null) - pos = vfirst.getTop(); - amenityAdapter.notifyDataSetInvalidated(); - // Restore the position - getListView().setSelectionFromTop(idx, pos); + amenityAdapter.notifyDataSetChanged(); + updateButtonState(); } } @@ -510,6 +420,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa @Override public void onItemClick(AdapterView parent, final View view, int position, long id) { final Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position); + final OsmandSettings settings = app.getSettings(); String poiSimpleFormat = OsmAndFormatter.getPoiStringWithoutType(amenity, settings.usingEnglishNames()); PointDescription name = new PointDescription(PointDescription.POINT_TYPE_POI, poiSimpleFormat); @@ -561,48 +472,39 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa optionsMenu.show(); } - static class SearchAmenityRequest { - private static final int SEARCH_AGAIN = 1; - private static final int NEW_SEARCH_INIT = 2; - private static final int SEARCH_FURTHER = 3; - private int type; - private net.osmand.Location location; - - public static SearchAmenityRequest buildRequest(net.osmand.Location l, int type) { - SearchAmenityRequest req = new SearchAmenityRequest(); - req.type = type; - req.location = l; - return req; - - } - } + + private static final int SEARCH_AGAIN = 1; + private static final int NEW_SEARCH_INIT = 2; + private static final int SEARCH_FURTHER = 3; class SearchAmenityTask extends AsyncTask> implements ResultMatcher { - private SearchAmenityRequest request; + private int requestType; private TLongHashSet existingObjects = null; private TLongHashSet updateExisting; + private Location location; - public SearchAmenityTask(SearchAmenityRequest request) { - this.request = request; + public SearchAmenityTask(net.osmand.Location location, int requestType) { + this.location = location; + this.requestType = requestType; } net.osmand.Location getSearchedLocation() { - return request != null ? request.location : null; + return location ; } @Override protected void onPreExecute() { - // getSherlock().setProgressBarIndeterminateVisibility(true); + setSupportProgressBarIndeterminateVisibility(true); if (searchPOILevel != null) { searchPOILevel.setEnabled(false); } existingObjects = new TLongHashSet(); updateExisting = new TLongHashSet(); - if (request.type == SearchAmenityRequest.NEW_SEARCH_INIT) { + if (requestType == NEW_SEARCH_INIT) { amenityAdapter.clear(); - } else if (request.type == SearchAmenityRequest.SEARCH_FURTHER) { + } else if (requestType == SEARCH_FURTHER) { List list = amenityAdapter.getOriginalAmenityList(); for (Amenity a : list) { updateExisting.add(getAmenityId(a)); @@ -616,22 +518,20 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa @Override protected void onPostExecute(List result) { - // getSherlock().setProgressBarIndeterminateVisibility(false); - updateSearchPoiTextButton(true); - if (isNameFinderFilter()) { - if (!Algorithms.isEmpty(((NameFinderPoiFilter) filter).getLastError())) { - AccessibleToast.makeText(SearchPOIActivity.this, ((NameFinderPoiFilter) filter).getLastError(), + setSupportProgressBarIndeterminateVisibility(false); + currentSearchTask = null; + updateButtonState(); + if (isNameSearch()) { + if (isNominatimFilter() && !Algorithms.isEmpty(((NominatimPoiFilter) filter).getLastError())) { + AccessibleToast.makeText(SearchPOIActivity.this, ((NominatimPoiFilter) filter).getLastError(), Toast.LENGTH_LONG).show(); } - amenityAdapter.setNewModel(result, ""); + amenityAdapter.setNewModel(result); showOnMapItem.setEnabled(amenityAdapter.getCount() > 0); - } else if (isSearchByNameFilter()) { - showOnMapItem.setEnabled(amenityAdapter.getCount() > 0); - amenityAdapter.setNewModel(result, ""); } else { - amenityAdapter.setNewModel(result, searchFilter.getText().toString()); + amenityAdapter.setNewModel(result); } - updateSubtitle(); + } @Override @@ -643,14 +543,14 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa @Override protected List doInBackground(Void... params) { - if (request.location != null) { - if (request.type == SearchAmenityRequest.NEW_SEARCH_INIT) { - return filter.initializeNewSearch(request.location.getLatitude(), request.location.getLongitude(), + if (location != null) { + if (requestType == NEW_SEARCH_INIT) { + return filter.initializeNewSearch(location.getLatitude(), location.getLongitude(), -1, this); - } else if (request.type == SearchAmenityRequest.SEARCH_FURTHER) { - return filter.searchFurther(request.location.getLatitude(), request.location.getLongitude(), this); - } else if (request.type == SearchAmenityRequest.SEARCH_AGAIN) { - return filter.searchAgain(request.location.getLatitude(), request.location.getLongitude()); + } else if (requestType == SEARCH_FURTHER) { + return filter.searchFurther(location.getLatitude(), location.getLongitude(), this); + } else if (requestType == SEARCH_AGAIN) { + return filter.searchAgain(location.getLatitude(), location.getLongitude()); } } return Collections.emptyList(); @@ -661,9 +561,9 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa long id = getAmenityId(object); if (existingObjects != null && !existingObjects.contains(id)) { existingObjects.add(id); - if (request.type == SearchAmenityRequest.NEW_SEARCH_INIT) { + if (requestType == NEW_SEARCH_INIT) { publishProgress(object); - } else if (request.type == SearchAmenityRequest.SEARCH_FURTHER) { + } else if (requestType == SEARCH_FURTHER) { if (!updateExisting.contains(id)) { publishProgress(object); } @@ -690,7 +590,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa return originalAmenityList; } - public void setNewModel(List amenityList, String filter) { + public void setNewModel(List amenityList) { setNotifyOnChange(false); screenOrientation = DashLocationFragment.getScreenOrientation(SearchPOIActivity.this); originalAmenityList = new ArrayList(amenityList); @@ -698,10 +598,8 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa for (Amenity obj : amenityList) { add(obj); } - getFilter().filter(filter); setNotifyOnChange(true); - this.notifyDataSetChanged(); - + this.notifyDataSetInvalidated(); } @Override @@ -744,7 +642,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa if (dd instanceof DirectionDrawable) { draw = (DirectionDrawable) dd; } else { - draw = new DirectionDrawable(SearchPOIActivity.this, width, height, + draw = new DirectionDrawable(SearchPOIActivity.this, 24, 24, R.drawable.ic_destination_arrow_white, R.color.color_distance); direction.setImageDrawable(draw); } @@ -780,7 +678,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa if (mes != null) { distance = " " + OsmAndFormatter.getFormattedDistance((int) mes[0], getMyApplication()) + " "; //$NON-NLS-1$ } - String poiType = OsmAndFormatter.getPoiStringWithoutType(amenity, settings.usingEnglishNames()); + String poiType = OsmAndFormatter.getPoiStringWithoutType(amenity, app.getSettings().usingEnglishNames()); label.setText(poiType); distanceText.setText(distance); return (row); @@ -800,21 +698,20 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); List listToFilter = originalAmenityList; - if (constraint == null || constraint.length() == 0) { + if (constraint == null || constraint.length() == 0 || filter == null) { results.values = listToFilter; results.count = listToFilter.size(); } else { + boolean en = app.getSettings().usingEnglishNames(); String lowerCase = constraint.toString().toLowerCase(); - List filter = new ArrayList(); + List res = new ArrayList(); for (Amenity item : listToFilter) { - String lower = OsmAndFormatter.getPoiStringWithoutType(item, settings.usingEnglishNames()) - .toLowerCase(); - if (lower.indexOf(lowerCase) != -1) { - filter.add(item); + if (filter.checkNameFilter(item, lowerCase, en)) { + res.add(item); } } - results.values = filter; - results.count = filter.size(); + results.values = res; + results.count = res.size(); } return results; } @@ -859,5 +756,69 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa }); b.show(); } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == DELETE_FILTER) { + removePoiFilter(); + return true; + } else if (item.getItemId() == SAVE_FILTER) { + savePoiFilter(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void removePoiFilter() { + Builder builder = new AlertDialog.Builder(this); + builder.setMessage(R.string.edit_filter_delete_dialog_title); + builder.setNegativeButton(R.string.shared_string_no, null); + builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + if (app.getPoiFilters().removePoiFilter(filter)) { + AccessibleToast.makeText( + SearchPOIActivity.this, + MessageFormat.format(SearchPOIActivity.this.getText(R.string.edit_filter_delete_message).toString(), + filter.getName()), Toast.LENGTH_SHORT).show(); + SearchPOIActivity.this.finish(); + } + + } + }); + builder.create().show(); + } + + public void savePoiFilter() { + Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.edit_filter_save_as_menu_item); + final EditText editText = new EditText(this); + LinearLayout ll = new LinearLayout(this); + ll.setPadding(5, 3, 5, 0); + ll.addView(editText, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + builder.setView(ll); + builder.setNegativeButton(R.string.shared_string_cancel, null); + builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + PoiLegacyFilter nFilter = new PoiLegacyFilter(editText.getText().toString(), + null, + filter.getAcceptedTypes(), (OsmandApplication) getApplication()); + if(searchFilter.getText().toString().length() > 0) { + nFilter.setSavedFilterByName(searchFilter.getText().toString()); + } + if (app.getPoiFilters().createPoiFilter(nFilter)) { + AccessibleToast.makeText( + SearchPOIActivity.this, + MessageFormat.format(SearchPOIActivity.this.getText(R.string.edit_filter_create_message).toString(), + editText.getText().toString()), Toast.LENGTH_SHORT).show(); + } + SearchPOIActivity.this.finish(); + } + }); + builder.create().show(); + + } } diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterFragment.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterFragment.java index ae37b21289..4f1844980b 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterFragment.java @@ -15,13 +15,14 @@ import net.osmand.osm.AbstractPoiType; import net.osmand.osm.PoiType; import net.osmand.plus.IconsCache; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.EditPOIFilterActivity; import net.osmand.plus.activities.search.SearchActivity.SearchActivityChild; -import net.osmand.plus.poi.NameFinderPoiFilter; +import net.osmand.plus.poi.NominatimPoiFilter; import net.osmand.plus.poi.PoiFiltersHelper; import net.osmand.plus.poi.PoiLegacyFilter; -import net.osmand.plus.poi.SearchByNameFilter; +import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.resources.ResourceManager; import net.osmand.util.Algorithms; @@ -107,6 +108,12 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv setListAdapter(poiFitlersAdapter); setHasOptionsMenu(true); } + + @Override + public void onResume() { + super.onResume(); + poiFitlersAdapter.setResult(getFilters(searchEditText == null ? "" : searchEditText.getText().toString())); + } public List getFilters(String s) { List filters = new ArrayList() ; @@ -116,7 +123,7 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv } else { PoiFiltersHelper poiFilters = getApp().getPoiFilters(); for(PoiLegacyFilter pf : poiFilters.getTopDefinedPoiFilters()) { - if(!pf.isStandardFilter()) { + if(!pf.isStandardFilter() && pf.getName().toLowerCase().startsWith(s.toLowerCase())) { filters.add(pf); } } @@ -125,6 +132,11 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv for(AbstractPoiType p : res.values()) { filters.add(p); } + filters.add(poiFilters.getSearchByNamePOIFilter()); + if(OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class) != null) { + filters.add(poiFilters.getNominatimPOIFilter()); + filters.add(poiFilters.getNominatimAddressFilter()); + } } return filters; } @@ -156,16 +168,9 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv // folder selected newIntent.putExtra(EditPOIFilterActivity.AMENITY_FILTER, poi.getFilterId()); updateIntentToLaunch(newIntent); - startActivityForResult(newIntent, REQUEST_POI_EDIT); + startActivity(newIntent); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if(requestCode == REQUEST_POI_EDIT) { - poiFitlersAdapter.setResult(getFilters(searchEditText == null ? "" : searchEditText.getText().toString())); - } - } - @Override public void onListItemClick(ListView listView, View v, int position, long id) { final Object item = ((PoiFiltersAdapter) getListAdapter()).getItem(position); @@ -175,9 +180,21 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv return; } if (item instanceof PoiLegacyFilter) { - showFilterActivity(((PoiLegacyFilter) item).getFilterId()); + PoiLegacyFilter model = ((PoiLegacyFilter) item); + if (PoiLegacyFilter.BY_NAME_FILTER_ID.equals(model.getFilterId()) + || model instanceof NominatimPoiFilter) { + model.setFilterByName(searchEditText.getText().toString()); + } else { + model.setFilterByName(model.getSavedFilterByName()); + } + showFilterActivity(model.getFilterId()); } else { - showFilterActivity(PoiLegacyFilter.STD_PREFIX + ((AbstractPoiType) item).getKeyName()); + PoiLegacyFilter custom = getApp().getPoiFilters().getFilterById(PoiLegacyFilter.STD_PREFIX + ((AbstractPoiType) item).getKeyName()); + if(custom != null) { + custom.setFilterByName(null); + custom.updateTypesToAccept(((AbstractPoiType) item)); + showFilterActivity(custom.getFilterId()); + } } } @@ -237,6 +254,9 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv final PoiLegacyFilter model = (PoiLegacyFilter) item; if (RenderingIcons.containsBigIcon(model.getSimplifiedId())) { icon.setImageDrawable(RenderingIcons.getBigIcon(getActivity(), model.getSimplifiedId())); + } else if(PoiLegacyFilter.BY_NAME_FILTER_ID.equals(model.getFilterId()) || + model instanceof NominatimPoiFilter){ + icon.setImageResource(R.drawable.mx_name_finder); } else { icon.setImageResource(R.drawable.mx_user_defined); } diff --git a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java index 500642dbb7..1f6f9427cf 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java @@ -527,19 +527,7 @@ public class WaypointHelper { PoiLegacyFilter pf = getPoiFilter(); if (pf != null) { final List locs = route.getImmutableAllLocations(); - List amenities = app.getResourceManager().searchAmenitiesOnThePath(locs, poiSearchDeviationRadius, - pf, new ResultMatcher() { - - @Override - public boolean publish(Amenity object) { - return true; - } - - @Override - public boolean isCancelled() { - return false; - } - }); + List amenities = pf.searchAmenitiesOnThePath(locs, poiSearchDeviationRadius); for (Amenity a : amenities) { AmenityRoutePoint rp = a.getRoutePoint(); int i = locs.indexOf(rp.pointA); diff --git a/OsmAnd/src/net/osmand/plus/poi/NameFinderPoiFilter.java b/OsmAnd/src/net/osmand/plus/poi/NominatimPoiFilter.java similarity index 66% rename from OsmAnd/src/net/osmand/plus/poi/NameFinderPoiFilter.java rename to OsmAnd/src/net/osmand/plus/poi/NominatimPoiFilter.java index e03c8ff206..effdde0f9a 100644 --- a/OsmAnd/src/net/osmand/plus/poi/NameFinderPoiFilter.java +++ b/OsmAnd/src/net/osmand/plus/poi/NominatimPoiFilter.java @@ -6,6 +6,7 @@ import java.net.URLConnection; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; @@ -22,66 +23,71 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -public class NameFinderPoiFilter extends PoiLegacyFilter { +public class NominatimPoiFilter extends PoiLegacyFilter { - public static final String FILTER_ID = NAME_FINDER_FILTER_ID; //$NON-NLS-1$ - private static final Log log = PlatformUtil.getLog(NameFinderPoiFilter.class); + private static final String FILTER_ID = "name_finder"; //$NON-NLS-1$ + private static final Log log = PlatformUtil.getLog(NominatimPoiFilter.class); private static final int LIMIT = 300; - List searchedAmenities = new ArrayList(); - - private String query = ""; //$NON-NLS-1$ private String lastError = ""; //$NON-NLS-1$ + private boolean addressQuery; - public NameFinderPoiFilter(OsmandApplication application) { - super(null, application); - this.name = application.getString(R.string.poi_filter_nominatim); //$NON-NLS-1$ - this.distanceToSearchValues = new double[] {1, 2, 5, 10, 20, 50, 100, 200, 500 }; - this.filterId = FILTER_ID; + public NominatimPoiFilter(OsmandApplication application, boolean addressQuery) { + super(application); + this.addressQuery = addressQuery; + this.name = + application.getString(R.string.poi_filter_nominatim); //$NON-NLS-1$ + if(addressQuery) { + this.name += " - " + application.getString(R.string.shared_string_address); + } else { + this.name += " - " + application.getString(R.string.shared_string_places); + } + if(addressQuery) { + this.distanceToSearchValues = new double[] {500}; + } else { + this.distanceToSearchValues = new double[] {1, 2, 5, 10, 20, 50, 100, 200, 500 }; + } + this.filterId = FILTER_ID + (addressQuery ? "_address" : "_places"); + } + + public boolean isPlacesQuery() { + return !addressQuery; } @Override - public List searchAgain(double lat, double lon) { - MapUtils.sortListOfMapObject(searchedAmenities, lat, lon); - return searchedAmenities; - } - - public String getQuery() { - return query; - } - - public void setQuery(String query) { - this.query = query; + public boolean isAutomaticallyIncreaseSearch() { + return false; } @Override - protected List searchAmenities(double lat, double lon, double topLatitude, + protected List searchAmenitiesInternal(double lat, double lon, double topLatitude, double bottomLatitude, double leftLongitude, double rightLongitude, ResultMatcher matcher) { - final int deviceApiVersion = android.os.Build.VERSION.SDK_INT; - String NOMINATIM_API; - if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { NOMINATIM_API = "https://nominatim.openstreetmap.org/search/"; - } - else { + } else { NOMINATIM_API = "http://nominatim.openstreetmap.org/search/"; } - - searchedAmenities.clear(); - + currentSearchResult = new ArrayList(); String viewbox = "viewboxlbrt="+((float) leftLongitude)+","+((float) bottomLatitude)+","+((float) rightLongitude)+","+((float) topLatitude); try { lastError = ""; - String urlq = NOMINATIM_API + URLEncoder.encode(query)+ "?format=xml&addressdetails=1&limit="+LIMIT+"&bounded=1&"+viewbox; + String urlq ; + if(addressQuery) { + urlq = NOMINATIM_API + "?format=xml&addressdetails=0&accept-language="+ Locale.getDefault().getLanguage() + + "&q=" + URLEncoder.encode(getFilterByName()); + } else { + urlq = NOMINATIM_API + URLEncoder.encode(getFilterByName()) + "?format=xml&addressdetails=1&limit=" + LIMIT + + "&bounded=1&" + viewbox; + } log.info(urlq); URLConnection connection = NetworkUtils.getHttpURLConnection(urlq); //$NON-NLS-1$ InputStream stream = connection.getInputStream(); XmlPullParser parser = PlatformUtil.newXMLPullParser(); parser.setInput(stream, "UTF-8"); //$NON-NLS-1$ int eventType; - int namedDepth= 0; + int namedDepth = 0; Amenity a = null; MapPoiTypes poiTypes = ((OsmandApplication) getApplication()).getPoiTypes(); while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) { @@ -91,7 +97,7 @@ public class NameFinderPoiFilter extends PoiLegacyFilter { if (err != null && err.length() > 0) { lastError = err; stream.close(); - return searchedAmenities; + return currentSearchResult; } } if (parser.getName().equals("place")) { //$NON-NLS-1$ @@ -102,13 +108,13 @@ public class NameFinderPoiFilter extends PoiLegacyFilter { a.setLocation(Double.parseDouble(parser.getAttributeValue("", "lat")), //$NON-NLS-1$//$NON-NLS-2$ Double.parseDouble(parser.getAttributeValue("", "lon"))); //$NON-NLS-1$//$NON-NLS-2$ a.setId(Long.parseLong(parser.getAttributeValue("", "place_id"))); //$NON-NLS-1$ //$NON-NLS-2$ - String name = parser.getAttributeValue("", "display_name"); //$NON-NLS-1$//$NON-NLS-2$ + String name = parser.getAttributeValue("", "display_name"); //$NON-NLS-1$//$NON-NLS-2$ a.setName(name); a.setEnName(Junidecode.unidecode(name)); a.setType(poiTypes.getOtherPoiCategory()); - a.setSubType(parser.getAttributeValue("", "type")); //$NON-NLS-1$//$NON-NLS-2$ + a.setSubType(parser.getAttributeValue("", "type")); //$NON-NLS-1$//$NON-NLS-2$ if (matcher == null || matcher.publish(a)) { - searchedAmenities.add(a); + currentSearchResult.add(a); } } catch (NumberFormatException e) { log.info("Invalid attributes", e); //$NON-NLS-1$ @@ -126,7 +132,7 @@ public class NameFinderPoiFilter extends PoiLegacyFilter { } else if (eventType == XmlPullParser.END_TAG) { if (parser.getName().equals("place")) { //$NON-NLS-1$ namedDepth--; - if(namedDepth == 0){ + if (namedDepth == 0) { a = null; } } @@ -140,18 +146,13 @@ public class NameFinderPoiFilter extends PoiLegacyFilter { log.error("Error parsing name finder poi", e); //$NON-NLS-1$ lastError = getApplication().getString(R.string.shared_string_io_error); //$NON-NLS-1$ } - MapUtils.sortListOfMapObject(searchedAmenities, lat, lon); - return searchedAmenities; + MapUtils.sortListOfMapObject(currentSearchResult, lat, lon); + return currentSearchResult; } public String getLastError() { return lastError; } - public List getSearchedAmenities() { - return searchedAmenities; - } - - } diff --git a/OsmAnd/src/net/osmand/plus/poi/PoiFiltersHelper.java b/OsmAnd/src/net/osmand/plus/poi/PoiFiltersHelper.java index 31943898d0..6eaee977b7 100644 --- a/OsmAnd/src/net/osmand/plus/poi/PoiFiltersHelper.java +++ b/OsmAnd/src/net/osmand/plus/poi/PoiFiltersHelper.java @@ -10,11 +10,14 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import net.osmand.access.AccessibilityPlugin; +import net.osmand.osm.AbstractPoiType; import net.osmand.osm.MapPoiTypes; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiFilter; import net.osmand.osm.PoiType; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; @@ -23,7 +26,9 @@ import net.osmand.plus.api.SQLiteAPI.SQLiteStatement; public class PoiFiltersHelper { private final OsmandApplication application; - private NameFinderPoiFilter nameFinderPOIFilter; + private NominatimPoiFilter nominatimPOIFilter; + private NominatimPoiFilter nominatimAddresFilter; + private PoiLegacyFilter searchByNamePOIFilter; private PoiLegacyFilter customPOIFilter; private PoiLegacyFilter showAllPOIFilter; @@ -49,11 +54,18 @@ public class PoiFiltersHelper { this.application = application; } - public NameFinderPoiFilter getNameFinderPOIFilter() { - if(nameFinderPOIFilter == null){ - nameFinderPOIFilter = new NameFinderPoiFilter(application); + public NominatimPoiFilter getNominatimPOIFilter() { + if(nominatimPOIFilter == null){ + nominatimPOIFilter = new NominatimPoiFilter(application, false); } - return nameFinderPOIFilter; + return nominatimPOIFilter; + } + + public NominatimPoiFilter getNominatimAddressFilter() { + if(nominatimAddresFilter == null){ + nominatimAddresFilter = new NominatimPoiFilter(application, true); + } + return nominatimAddresFilter; } public PoiLegacyFilter getSearchByNamePOIFilter() { @@ -104,7 +116,7 @@ public class PoiFiltersHelper { } } PoiLegacyFilter ff = getFilterById(filterId, getCustomPOIFilter(), getSearchByNamePOIFilter(), - getShowAllPOIFilter(), getNameFinderPOIFilter()); + getShowAllPOIFilter(), getNominatimPOIFilter(), getNominatimAddressFilter()); if (ff != null) { return ff; } @@ -112,7 +124,10 @@ public class PoiFiltersHelper { String typeId = filterId.substring(PoiLegacyFilter.STD_PREFIX.length()); PoiType tp = application.getPoiTypes().getPoiTypeByKey(typeId); if(tp != null) { - return new PoiLegacyFilter(tp, application); + PoiLegacyFilter lf = new PoiLegacyFilter(tp, application); + cacheTopStandardFilters.add(lf); + sortListOfFilters(cacheTopStandardFilters); + return lf; } } return null; @@ -121,6 +136,8 @@ public class PoiFiltersHelper { public void reloadAllPoiFilters() { cacheTopStandardFilters = null; + showAllPOIFilter = null; + getShowAllPOIFilter(); getTopDefinedPoiFilters(); } @@ -139,28 +156,9 @@ public class PoiFiltersHelper { public void sortListOfFilters(List list) { final Collator instance = Collator.getInstance(); Collections.sort(list, new Comparator() { - private int getRank(PoiLegacyFilter lf) { - if(PoiLegacyFilter.BY_NAME_FILTER_ID.equals(lf.getFilterId())) { - return 0; - } else if(lf.areAllTypesAccepted()) { - return 3; - } else if(PoiLegacyFilter.CUSTOM_FILTER_ID.equals(lf.getFilterId())) { - return 4; - } else if(PoiLegacyFilter.NAME_FINDER_FILTER_ID.equals(lf.getFilterId())) { - return 5; - } else if(lf.isStandardFilter()) { - return 2; - } - return 1; - } @Override public int compare(PoiLegacyFilter lhs, PoiLegacyFilter rhs) { - int lr = getRank(lhs); - int rr = getRank(rhs); - if(lr != rr) { - return lr < rr ? -1 : 1; - } return instance.compare(lhs.getName(), rhs.getName()); } }); @@ -180,7 +178,9 @@ public class PoiFiltersHelper { sortListOfFilters(cacheTopStandardFilters); } List result = new ArrayList(); - result.add(getShowAllPOIFilter()); + if(OsmandPlugin.getEnabledPlugin(AccessibilityPlugin.class) != null) { + result.add(getShowAllPOIFilter()); + } result.addAll(cacheTopStandardFilters); return result; } @@ -383,7 +383,7 @@ public class PoiFiltersHelper { if(map.containsKey(filterId)){ PoiLegacyFilter filter = new PoiLegacyFilter(query.getString(1), filterId, map.get(filterId), application); - filter.setFilterByName(query.getString(2)); + filter.setSavedFilterByName(query.getString(2)); list.add(filter); } } while(query.moveToNext()); @@ -428,4 +428,5 @@ public class PoiFiltersHelper { } + } diff --git a/OsmAnd/src/net/osmand/plus/poi/PoiLegacyFilter.java b/OsmAnd/src/net/osmand/plus/poi/PoiLegacyFilter.java index 4e15577924..48b542fac4 100644 --- a/OsmAnd/src/net/osmand/plus/poi/PoiLegacyFilter.java +++ b/OsmAnd/src/net/osmand/plus/poi/PoiLegacyFilter.java @@ -1,42 +1,45 @@ package net.osmand.plus.poi; +import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; +import net.osmand.Collator; +import net.osmand.CollatorStringMatcher; +import net.osmand.Location; +import net.osmand.OsmAndCollator; import net.osmand.ResultMatcher; +import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter; import net.osmand.data.Amenity; +import net.osmand.data.LatLon; import net.osmand.osm.AbstractPoiType; import net.osmand.osm.MapPoiTypes; import net.osmand.osm.PoiCategory; -import net.osmand.osm.PoiFilter; +import net.osmand.osm.PoiType; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import android.content.Context; -public class PoiLegacyFilter { +public class PoiLegacyFilter implements SearchPoiTypeFilter { public final static String STD_PREFIX = "std_"; //$NON-NLS-1$ public final static String USER_PREFIX = "user_"; //$NON-NLS-1$ public final static String CUSTOM_FILTER_ID = USER_PREFIX + "custom_id"; //$NON-NLS-1$ public final static String BY_NAME_FILTER_ID = USER_PREFIX + "by_name"; //$NON-NLS-1$ - public static final String NAME_FINDER_FILTER_ID = "name_finder"; private Map> acceptedTypes = new LinkedHashMap>(); - private String filterByName = null; protected String filterId; protected String name; - protected String nameFilter; protected boolean isStandardFilter; protected final OsmandApplication app; @@ -44,8 +47,13 @@ public class PoiLegacyFilter { protected int distanceInd = 1; // in kilometers protected double[] distanceToSearchValues = new double[] {1, 2, 5, 10, 20, 50, 100, 200, 500 }; + private final MapPoiTypes poiTypes; + protected String filterByName = null; + protected String savedFilterByName = null; + protected List currentSearchResult = null; + private Collator collator; // constructor for standard filters public PoiLegacyFilter(AbstractPoiType type, OsmandApplication application) { @@ -60,11 +68,18 @@ public class PoiLegacyFilter { type.putTypes(acceptedTypes); } } + + // search by name standard + protected PoiLegacyFilter(OsmandApplication application) { + this.app = application; + isStandardFilter = true; + filterId = STD_PREFIX; // overridden + poiTypes = application.getPoiTypes(); + } - - // constructor for user defined filters - public PoiLegacyFilter(String name, String filterId, Map> acceptedTypes, OsmandApplication app){ + public PoiLegacyFilter(String name, String filterId, + Map> acceptedTypes, OsmandApplication app){ this.app = app; isStandardFilter = false; poiTypes = app.getPoiTypes(); @@ -79,21 +94,48 @@ public class PoiLegacyFilter { this.acceptedTypes.putAll(acceptedTypes); } } + + public String getFilterByName() { + return filterByName; + } - public void setNameFilter(String nameFilter) { - if(nameFilter != null) { - this.nameFilter = nameFilter.toLowerCase(); + public void setFilterByName(String filterByName) { + this.filterByName = filterByName; + } + + public void setSavedFilterByName(String filterByName) { + this.filterByName = filterByName; + this.savedFilterByName = filterByName; + } + + public String getSavedFilterByName() { + return savedFilterByName; + } + + public List getCurrentSearchResult() { + return currentSearchResult; + } + + + public List searchAgain(double lat, double lon) { + List amenityList ; + if(currentSearchResult != null) { + amenityList = currentSearchResult; } else { - clearNameFilter(); + amenityList = searchAmenities(lat, lon, null); } + MapUtils.sortListOfMapObject(amenityList, lat, lon); + return amenityList; } - public String getNameFilter() { - return nameFilter; - } - - public void clearNameFilter(){ - nameFilter = null; + + public List searchFurther(double latitude, double longitude, ResultMatcher matcher){ + if(distanceInd < distanceToSearchValues.length - 1){ + distanceInd ++; + } + List amenityList = searchAmenities( latitude, longitude, matcher); + MapUtils.sortListOfMapObject(amenityList, latitude, longitude); + return amenityList; } private void initSearchAll(){ @@ -109,15 +151,7 @@ public class PoiLegacyFilter { } - public List searchFurther(double latitude, double longitude, ResultMatcher matcher){ - if(distanceInd < distanceToSearchValues.length - 1){ - distanceInd ++; - } - List amenityList = searchAmenities( latitude, longitude, matcher); - MapUtils.sortListOfMapObject(amenityList, latitude, longitude); - - return amenityList; - } + public String getSearchArea(){ double val = distanceToSearchValues[distanceInd]; @@ -141,61 +175,142 @@ public class PoiLegacyFilter { amenityList.remove(amenityList.size() - 1); } } + if (amenityList.size() == 0 && isAutomaticallyIncreaseSearch()) { + int step = 5; + while (amenityList.size() == 0 && step-- > 0 && isSearchFurtherAvailable()) { + amenityList = searchFurther(lat, lon, matcher); + } + } return amenityList; } + public boolean isAutomaticallyIncreaseSearch() { + return true; + } + private List searchAmenities(double lat, double lon, ResultMatcher matcher) { double baseDistY = MapUtils.getDistance(lat, lon, lat - 1, lon); double baseDistX = MapUtils.getDistance(lat, lon, lat, lon - 1); double distance = distanceToSearchValues[distanceInd] * 1000; - double topLatitude = Math.min(lat + (distance/ baseDistY ), 84.); double bottomLatitude = Math.max(lat - (distance/ baseDistY ), -84.); double leftLongitude = Math.max(lon - (distance / baseDistX), -180); double rightLongitude = Math.min(lon + (distance/ baseDistX), 180); - - return searchAmenities(lat, lon, topLatitude, bottomLatitude, leftLongitude, rightLongitude, matcher); + return searchAmenitiesInternal(lat, lon, topLatitude, bottomLatitude, leftLongitude, rightLongitude, matcher); } - public ResultMatcher getResultMatcher(final ResultMatcher matcher){ - final String filter = nameFilter; - if(filter != null) { - final boolean en = app.getSettings().usingEnglishNames(); - return new ResultMatcher() { - @Override - public boolean publish(Amenity object) { - if(!OsmAndFormatter.getPoiStringWithoutType(object, en).toLowerCase().contains(filter) || - (matcher != null && !matcher.publish(object))) { - return false; + public List searchAmenities(double top, double left, double bottom, double right, int zoom, + ResultMatcher matcher) { + List results = new ArrayList(); + List tempResults = currentSearchResult; + if (tempResults != null) { + for (Amenity a : tempResults) { + LatLon l = a.getLocation(); + if (l != null && l.getLatitude() <= top && l.getLatitude() >= bottom && l.getLongitude() >= left + && l.getLongitude() <= right) { + if (matcher == null || matcher.publish(a)) { + results.add(a); } - return true; } - - @Override - public boolean isCancelled() { - return (matcher != null && matcher.isCancelled()); - } - }; + } } - return matcher; + List amenities = app.getResourceManager().searchAmenities(this, top, left, bottom, right, zoom, + wrapResultMatcher(matcher)); + results.addAll(amenities); + return results; } - - protected List searchAmenities(double lat, double lon, double topLatitude, + + public List searchAmenitiesOnThePath(List locs, int poiSearchDeviationRadius) { + return app.getResourceManager().searchAmenitiesOnThePath(locs, poiSearchDeviationRadius, this, wrapResultMatcher(null)); + } + + protected List searchAmenitiesInternal(double lat, double lon, double topLatitude, double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher matcher) { return app.getResourceManager().searchAmenities(this, - topLatitude, leftLongitude, bottomLatitude, rightLongitude, -1, matcher); + topLatitude, leftLongitude, bottomLatitude, rightLongitude, -1, wrapResultMatcher(matcher)); + } + + public boolean checkNameFilter(Amenity object, String filter, boolean en) { + boolean publish = false; + if (Algorithms.isEmpty(filter)) { + publish = true; + } else { + String lower = OsmAndFormatter.getPoiStringWithoutType(object, en); + publish = CollatorStringMatcher.ccontains(getCollator(), lower, filter); + } + return publish; } - public List searchAgain(double lat, double lon) { - List amenityList = searchAmenities(lat, lon, null); - MapUtils.sortListOfMapObject(amenityList, lat, lon); - return amenityList; + private Collator getCollator() { + if (collator == null) { + collator = OsmAndCollator.primaryCollator(); + } + return collator; + } + + private ResultMatcher wrapResultMatcher(final ResultMatcher matcher) { + final boolean en = app.getSettings().usingEnglishNames(); + return new ResultMatcher() { + + @Override + public boolean publish(Amenity a) { + if (checkNameFilter(a, filterByName, en)) { + if (matcher == null || matcher.publish(a)) { + return true; + } + } + return false; + } + + @Override + public boolean isCancelled() { + return matcher != null && matcher.isCancelled(); + } + }; } public String getName(){ return name; } + public String getGeneratedName(int chars) { + if (!filterId.equals(CUSTOM_FILTER_ID) || + areAllTypesAccepted() || acceptedTypes.isEmpty()) { + return getName(); + } + StringBuilder res = new StringBuilder(); + for (PoiCategory p : acceptedTypes.keySet()) { + LinkedHashSet set = acceptedTypes.get(p); + if (set == null) { + if (res.length() > 0) { + res.append(", "); + } + res.append(p.getTranslation()); + } + if (res.length() > chars) { + return res.toString(); + } + } + for (PoiCategory p : acceptedTypes.keySet()) { + LinkedHashSet set = acceptedTypes.get(p); + if (set != null) { + for (String st : set) { + if (res.length() > 0) { + res.append(", "); + } + PoiType pt = poiTypes.getPoiTypeByKey(st); + if (pt != null) { + res.append(pt.getTranslation()); + if (res.length() > chars) { + return res.toString(); + } + } + } + } + } + return res.toString(); + } + /** * @param type * @return null if all subtypes are accepted/ empty list if type is not accepted at all @@ -211,24 +326,7 @@ public class PoiLegacyFilter { return acceptedTypes.containsKey(t); } - public boolean acceptTypeSubtype(PoiCategory t, String subtype){ - if(t == null) { - return true; - } - if(!poiTypes.isRegisteredType(t)) { - t = poiTypes.getOtherPoiCategory(); - } - if(!acceptedTypes.containsKey(t)){ - return false; - } - LinkedHashSet set = acceptedTypes.get(t); - if(set == null){ - return true; - } - return set.contains(subtype); - } - - public void clearFilter(){ + public void clearFilter() { acceptedTypes = new LinkedHashMap>(); } @@ -253,21 +351,12 @@ public class PoiLegacyFilter { } } - public void setMapToAccept(Map> newMap) { - Iterator>> iterator = newMap.entrySet().iterator(); + public void updateTypesToAccept(AbstractPoiType pt) { acceptedTypes.clear(); - while(iterator.hasNext()){ - Entry> e = iterator.next(); - if(e.getValue() == null){ - acceptedTypes.put(e.getKey(), null); - } else { - acceptedTypes.put(e.getKey(), new LinkedHashSet(e.getValue())); - } - } + pt.putTypes(acceptedTypes); } - public Map> getAcceptedTypes(){ return new LinkedHashMap>(acceptedTypes); } @@ -289,15 +378,6 @@ public class PoiLegacyFilter { return filterId; } - - public String getFilterByName() { - return filterByName; - } - - public void setFilterByName(String filterByName) { - this.filterByName = filterByName; - } - public boolean isStandardFilter() { return isStandardFilter; } @@ -310,4 +390,27 @@ public class PoiLegacyFilter { return app; } + @Override + public boolean accept(PoiCategory type, String subtype) { + if(type == null) { + return true; + } + if(!poiTypes.isRegisteredType(type)) { + type = poiTypes.getOtherPoiCategory(); + } + if(!acceptedTypes.containsKey(type)){ + return false; + } + LinkedHashSet set = acceptedTypes.get(type); + if(set == null){ + return true; + } + return set.contains(subtype); + } + + @Override + public boolean isEmpty() { + return acceptedTypes.isEmpty(); + } + } diff --git a/OsmAnd/src/net/osmand/plus/poi/SearchByNameFilter.java b/OsmAnd/src/net/osmand/plus/poi/SearchByNameFilter.java index 5e5dbb4ec9..ffd6a5062d 100644 --- a/OsmAnd/src/net/osmand/plus/poi/SearchByNameFilter.java +++ b/OsmAnd/src/net/osmand/plus/poi/SearchByNameFilter.java @@ -16,46 +16,33 @@ public class SearchByNameFilter extends PoiLegacyFilter { public static final String FILTER_ID = PoiLegacyFilter.BY_NAME_FILTER_ID; //$NON-NLS-1$ - List searchedAmenities = new ArrayList(); - - private String query = ""; //$NON-NLS-1$ - public SearchByNameFilter(OsmandApplication application) { - super(application.getString(R.string.poi_filter_by_name), FILTER_ID, new LinkedHashMap>(), application); + super(application); + this.name = application.getString(R.string.poi_filter_by_name); + this.filterId = FILTER_ID; this.distanceToSearchValues = new double[] {100, 1000, 5000}; - this.isStandardFilter = true; } @Override - public List searchAgain(double lat, double lon) { - MapUtils.sortListOfMapObject(searchedAmenities, lat, lon); - return searchedAmenities; - } - - public String getQuery() { - return query; - } - - public void setQuery(String query) { - this.query = query; + public boolean isAutomaticallyIncreaseSearch() { + return false; } @Override - protected List searchAmenities(double lat, double lon, double topLatitude, + protected List searchAmenitiesInternal(double lat, double lon, double topLatitude, double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher matcher) { - searchedAmenities.clear(); + currentSearchResult = new ArrayList(); final int limit = distanceInd == 0 ? 500 : -1; - - List result = app.getResourceManager().searchAmenitiesByName(query, + List result = app.getResourceManager().searchAmenitiesByName(getFilterByName(), topLatitude, leftLongitude, bottomLatitude, rightLongitude, lat, lon, new ResultMatcher() { boolean elimit = false; @Override public boolean publish(Amenity object) { - if(limit != -1 && searchedAmenities.size() > limit) { + if (limit != -1 && currentSearchResult.size() > limit) { elimit = true; } - if(matcher.publish(object)) { - searchedAmenities.add(object); + if (matcher.publish(object)) { + currentSearchResult.add(object); return true; } return false; @@ -67,15 +54,8 @@ public class SearchByNameFilter extends PoiLegacyFilter { } }); MapUtils.sortListOfMapObject(result, lat, lon); - searchedAmenities = result; - return searchedAmenities; + currentSearchResult = result; + return currentSearchResult; } - - - public List getSearchedAmenities() { - return searchedAmenities; - } - - } diff --git a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java index 0378df1ddc..52a8072cef 100644 --- a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java +++ b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepository.java @@ -4,8 +4,8 @@ import java.util.List; import net.osmand.Location; import net.osmand.ResultMatcher; +import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter; import net.osmand.data.Amenity; -import net.osmand.plus.poi.PoiLegacyFilter; public interface AmenityIndexRepository { @@ -18,10 +18,11 @@ public interface AmenityIndexRepository { /** * Search amenities in the specified box doesn't cache results */ - public List searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, PoiLegacyFilter filter, List amenities, - ResultMatcher matcher); + List searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, SearchPoiTypeFilter filter, + ResultMatcher matcher); - public List searchAmenitiesOnThePath(List locations, double radius, PoiLegacyFilter filter, ResultMatcher matcher); + List searchAmenitiesOnThePath(List locations, double radius, SearchPoiTypeFilter filter, + ResultMatcher matcher); } diff --git a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java index 688965138e..746b8e0360 100644 --- a/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/resources/AmenityIndexRepositoryBinary.java @@ -83,42 +83,29 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository { @Override public synchronized List searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, - final PoiLegacyFilter filter, final List amenities, ResultMatcher matcher) { + final SearchPoiTypeFilter filter, ResultMatcher matcher) { long now = System.currentTimeMillis(); - SearchPoiTypeFilter poiTypeFilter = new SearchPoiTypeFilter(){ - @Override - public boolean accept(PoiCategory type, String subcategory) { - return filter.acceptTypeSubtype(type, subcategory); - } - }; SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest(sleft, sright, stop, sbottom, zoom, - poiTypeFilter, filter == null ? matcher : filter.getResultMatcher(matcher)); + filter, matcher); + List result = null; try { - List result = index.searchPoi(req); - amenities.addAll(result); + result = index.searchPoi(req); } catch (IOException e) { log.error("Error searching amenities", e); //$NON-NLS-1$ - return amenities; } - if (log.isDebugEnabled()) { + if (log.isDebugEnabled() && result != null) { log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$ - MapUtils.get31LatitudeY(stop) + " " + MapUtils.get31LongitudeX(sleft), System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$ + MapUtils.get31LatitudeY(stop) + " " + MapUtils.get31LongitudeX(sleft), System.currentTimeMillis() - now, result.size())); //$NON-NLS-1$ } - return amenities; + return result; } @Override - public synchronized List searchAmenitiesOnThePath(List locations, double radius, final PoiLegacyFilter filter, ResultMatcher matcher) { + public synchronized List searchAmenitiesOnThePath(List locations, double radius, final SearchPoiTypeFilter filter, ResultMatcher matcher) { long now = System.currentTimeMillis(); - SearchPoiTypeFilter poiTypeFilter = new SearchPoiTypeFilter(){ - @Override - public boolean accept(PoiCategory type, String subcategory) { - return filter.acceptTypeSubtype(type, subcategory); - } - }; List result = null; SearchRequest req = BinaryMapIndexReader.buildSearchPoiRequest(locations, radius, - poiTypeFilter, filter == null ? matcher : filter.getResultMatcher(matcher)); + filter, matcher ); try { result = index.searchPoi(req); } catch (IOException e) { diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index c4ca2dc6b8..0b80c4a23d 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -25,9 +25,9 @@ import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter; import net.osmand.binary.CachedOsmandIndexes; import net.osmand.data.Amenity; -import net.osmand.data.LatLon; import net.osmand.data.RotatedTileBox; import net.osmand.data.TransportStop; import net.osmand.map.ITileSource; @@ -38,15 +38,11 @@ import net.osmand.osm.PoiCategory; import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.BusyIndicator; -import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.Version; -import net.osmand.plus.poi.NameFinderPoiFilter; -import net.osmand.plus.poi.PoiLegacyFilter; -import net.osmand.plus.poi.SearchByNameFilter; import net.osmand.plus.render.MapRenderRepositories; import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.resources.AsyncLoadingThread.MapLoadRequest; @@ -710,59 +706,20 @@ public class ResourceManager { } ////////////////////////////////////////////// Working with amenities //////////////////////////////////////////////// - public boolean checkNameFilter(Amenity object, String filterByName) { - boolean publish = false; - if (filterByName == null || filterByName.length() == 0) { - publish = true; - } else { - String lower = OsmAndFormatter.getPoiStringWithoutType(object, context.getSettings().usingEnglishNames()) - .toLowerCase(); - publish = lower.indexOf(filterByName) != -1; - } - return publish; - } - - public List searchAmenities(PoiLegacyFilter filter, + public List searchAmenities(SearchPoiTypeFilter filter, double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, final ResultMatcher matcher) { final List amenities = new ArrayList(); searchAmenitiesInProgress = true; try { - if (filter instanceof NameFinderPoiFilter || filter instanceof SearchByNameFilter) { - List tempResults = filter instanceof NameFinderPoiFilter ? ((NameFinderPoiFilter) filter) - .getSearchedAmenities() : ((SearchByNameFilter) filter).getSearchedAmenities(); - for (Amenity a : tempResults) { - LatLon l = a.getLocation(); - if (l != null && l.getLatitude() <= topLatitude && l.getLatitude() >= bottomLatitude - && l.getLongitude() >= leftLongitude && l.getLongitude() <= rightLongitude) { - if (matcher == null || matcher.publish(a)) { - amenities.add(a); - } - } - } - } else { - final String filterByName = filter.getFilterByName(); + if (!filter.isEmpty()) { for (AmenityIndexRepository index : amenityRepositories) { if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { - index.searchAmenities(MapUtils.get31TileNumberY(topLatitude), + List r = index.searchAmenities(MapUtils.get31TileNumberY(topLatitude), MapUtils.get31TileNumberX(leftLongitude), MapUtils.get31TileNumberY(bottomLatitude), - MapUtils.get31TileNumberX(rightLongitude), zoom, filter, amenities, - new ResultMatcher() { - - @Override - public boolean publish(Amenity a) { - if (checkNameFilter(a, filterByName)) { - if (matcher == null || matcher.publish(a)) { - amenities.add(a); - } - } - return false; - } - - @Override - public boolean isCancelled() { - return matcher != null && matcher.isCancelled(); - } - }); + MapUtils.get31TileNumberX(rightLongitude), zoom, filter, matcher); + if(r != null) { + amenities.addAll(r); + } } } } @@ -772,6 +729,46 @@ public class ResourceManager { return amenities; } + public List searchAmenitiesOnThePath(List locations, double radius, SearchPoiTypeFilter filter, + ResultMatcher matcher) { + searchAmenitiesInProgress = true; + final List amenities = new ArrayList(); + try { + if (locations != null && locations.size() > 0) { + List repos = new ArrayList(); + double topLatitude = locations.get(0).getLatitude(); + double bottomLatitude = locations.get(0).getLatitude(); + double leftLongitude = locations.get(0).getLongitude(); + double rightLongitude = locations.get(0).getLongitude(); + for (Location l : locations) { + topLatitude = Math.max(topLatitude, l.getLatitude()); + bottomLatitude = Math.min(bottomLatitude, l.getLatitude()); + leftLongitude = Math.min(leftLongitude, l.getLongitude()); + rightLongitude = Math.max(rightLongitude, l.getLongitude()); + } + if (!filter.isEmpty()) { + for (AmenityIndexRepository index : amenityRepositories) { + if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { + repos.add(index); + } + } + if (!repos.isEmpty()) { + for (AmenityIndexRepository r : repos) { + List res = r.searchAmenitiesOnThePath(locations, radius, filter, matcher); + if(res != null) { + amenities.addAll(res); + } + } + } + } + } + } finally { + searchAmenitiesInProgress = false; + } + return amenities; + } + + public boolean containsAmenityRepositoryToSearch(boolean searchByName){ for (AmenityIndexRepository index : amenityRepositories) { if(searchByName){ @@ -828,41 +825,6 @@ public class ResourceManager { return map; } - public List searchAmenitiesOnThePath(List locations, double radius, PoiLegacyFilter filter, ResultMatcher matcher) { - searchAmenitiesInProgress = true; - final List amenities = new ArrayList(); - try { - if (locations != null && locations.size() > 0) { - List repos = new ArrayList(); - double topLatitude = locations.get(0).getLatitude(); - double bottomLatitude = locations.get(0).getLatitude(); - double leftLongitude = locations.get(0).getLongitude(); - double rightLongitude = locations.get(0).getLongitude(); - for (Location l : locations) { - topLatitude = Math.max(topLatitude, l.getLatitude()); - bottomLatitude = Math.min(bottomLatitude, l.getLatitude()); - leftLongitude = Math.min(leftLongitude, l.getLongitude()); - rightLongitude = Math.max(rightLongitude, l.getLongitude()); - } - for (AmenityIndexRepository index : amenityRepositories) { - if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { - repos.add(index); - } - } - if (!repos.isEmpty()) { - for (AmenityIndexRepository r : repos) { - List res = r.searchAmenitiesOnThePath(locations, radius, filter, matcher); - if (res != null) { - amenities.addAll(res); - } - } - } - } - }finally { - searchAmenitiesInProgress = false; - } - return amenities; - } ////////////////////////////////////////////// Working with address /////////////////////////////////////////// diff --git a/OsmAnd/src/net/osmand/plus/views/DirectionDrawable.java b/OsmAnd/src/net/osmand/plus/views/DirectionDrawable.java index ce997e3c70..0d88d93aae 100644 --- a/OsmAnd/src/net/osmand/plus/views/DirectionDrawable.java +++ b/OsmAnd/src/net/osmand/plus/views/DirectionDrawable.java @@ -1,13 +1,18 @@ package net.osmand.plus.views; -import android.content.Context; -import android.graphics.*; -import android.graphics.drawable.Drawable; -import android.util.DisplayMetrics; -import android.view.WindowManager; import net.osmand.plus.IconsCache; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.DisplayMetrics; +import android.view.WindowManager; /** * Created by Denis @@ -29,6 +34,16 @@ public class DirectionDrawable extends Drawable { this.resourceId = resourceId; } + public DirectionDrawable(Context ctx, float width, float height) { + this.ctx = ctx; + this.width = width; + this.height = height; + paintRouteDirection = new Paint(); + paintRouteDirection.setStyle(Paint.Style.FILL_AND_STROKE); + paintRouteDirection.setColor(ctx.getResources().getColor(R.color.color_unknown)); + paintRouteDirection.setAntiAlias(true); + } + public void setImage(int resourceId, int clrId) { IconsCache iconsCache = ((OsmandApplication) ctx.getApplicationContext()).getIconsCache(); arrowImage = iconsCache.getIcon(resourceId, clrId); @@ -43,16 +58,7 @@ public class DirectionDrawable extends Drawable { onBoundsChange(getBounds()); } - public DirectionDrawable(Context ctx, float width, float height) { - this.ctx = ctx; - this.width = width; - this.height = height; - paintRouteDirection = new Paint(); - paintRouteDirection.setStyle(Paint.Style.FILL_AND_STROKE); - paintRouteDirection.setColor(ctx.getResources().getColor(R.color.color_unknown)); - paintRouteDirection.setAntiAlias(true); - } - + public void setColorId(int clrId) { // R.color.color_ok, R.color.color_unknown, R.color.color_warning if(arrowImage != null) { diff --git a/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java b/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java index 60e7ad9605..7fa8ace503 100644 --- a/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java @@ -12,7 +12,6 @@ import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; -import net.osmand.osm.MapPoiTypes; import net.osmand.osm.PoiType; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; @@ -84,19 +83,19 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon if (filter == null) { return new ArrayList(); } - return resourceManager.searchAmenities(filter, latLonBounds.top, latLonBounds.left, + return filter.searchAmenities(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, tileBox.getZoom(), new ResultMatcher() { - @Override - public boolean publish(Amenity object) { - return true; - } + @Override + public boolean publish(Amenity object) { + return true; + } - @Override - public boolean isCancelled() { - return isInterrupted(); - } - }); + @Override + public boolean isCancelled() { + return isInterrupted(); + } + }); } }; } @@ -198,7 +197,6 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon data.queryNewData(tileBox); objects = data.getResults(); if (objects != null) { - MapPoiTypes poiTypes = view.getApplication().getPoiTypes(); int r = getRadiusPoi(tileBox); for (Amenity o : objects) { int x = (int) tileBox.getPixXFromLatLon(o.getLocation().getLatitude(), o.getLocation() @@ -214,8 +212,6 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon id = st.getKeyName(); } else if (RenderingIcons.containsIcon(st.getOsmTag() + "_" + st.getOsmValue())) { id = st.getOsmTag() + "_" + st.getOsmValue(); - } else if (RenderingIcons.containsIcon(st.getOsmValue())) { - id = st.getOsmValue(); } } if (id != null) {