Update poi search

This commit is contained in:
Victor Shcherb 2015-04-08 16:04:32 +02:00
parent 79d1493439
commit 2bb1d40f41
20 changed files with 501 additions and 622 deletions

View file

@ -735,7 +735,11 @@ public class BinaryInspector {
@Override @Override
public int compare(MapStatKey o1, MapStatKey o2) { 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);
} }
}); });
@ -1009,6 +1013,11 @@ public class BinaryInspector {
return true; return true;
} }
@Override
public boolean isEmpty() {
return false;
}
}, },
new ResultMatcher<Amenity>() { new ResultMatcher<Amenity>() {
@Override @Override

View file

@ -1539,6 +1539,7 @@ public class BinaryMapIndexReader {
public boolean accept(PoiCategory type, String subcategory); public boolean accept(PoiCategory type, String subcategory);
public boolean isEmpty();
} }
public static class MapObjectStat { public static class MapObjectStat {
@ -1992,6 +1993,11 @@ public class BinaryMapIndexReader {
return false; return false;
} }
@Override
public boolean isEmpty() {
return false;
}
}, null); }, null);
req.zoom = -1; req.zoom = -1;
List<Amenity> results = reader.searchPoi(req); List<Amenity> results = reader.searchPoi(req);
@ -2104,6 +2110,11 @@ public class BinaryMapIndexReader {
return true; return true;
} }
@Override
public boolean isEmpty() {
return false;
}
}, null); }, null);
List<Amenity> results = reader.searchPoi(req); List<Amenity> results = reader.searchPoi(req);
for (Amenity a : results) { for (Amenity a : results) {

View file

@ -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 PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="agps_info">A-GPS info</string> <string name="agps_info">A-GPS info</string>
<string name="shared_string_places">Places</string>
<string name="shared_string_search">Search</string> <string name="shared_string_search">Search</string>
<string name="shared_string_show_description">Show description</string> <string name="shared_string_show_description">Show description</string>
<string name="shared_string_message">Message</string> <string name="shared_string_message">Message</string>

View file

@ -738,7 +738,7 @@ public class OsmandSettings {
public static final String TRANSPORT_STOPS_OVER_MAP = "transportStops"; public static final String TRANSPORT_STOPS_OVER_MAP = "transportStops";
public final OsmandPreference<String> MAP_PREFERRED_LOCALE = new StringPreference("map_preferred_locale", "").makeGlobal(); public final OsmandPreference<String> MAP_PREFERRED_LOCALE = new StringPreference("map_preferred_locale", "").makeGlobal().cache();
public boolean usingEnglishNames() { public boolean usingEnglishNames() {
return MAP_PREFERRED_LOCALE.get().equals("en"); return MAP_PREFERRED_LOCALE.get().equals("en");

View file

@ -168,7 +168,9 @@ public class EditPOIFilterActivity extends OsmandListActivity {
builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
PoiLegacyFilter nFilter = new PoiLegacyFilter(editText.getText().toString(), null, filter.getAcceptedTypes(), (OsmandApplication) getApplication()); PoiLegacyFilter nFilter = new PoiLegacyFilter(editText.getText().toString(),
null,
filter.getAcceptedTypes(), (OsmandApplication) getApplication());
if (helper.createPoiFilter(nFilter)) { if (helper.createPoiFilter(nFilter)) {
AccessibleToast.makeText( AccessibleToast.makeText(
EditPOIFilterActivity.this, EditPOIFilterActivity.this,

View file

@ -282,7 +282,7 @@ public class MapActivityLayers {
getApplication().getSettings().setPoiFilterForMap(filterId); getApplication().getSettings().setPoiFilterForMap(filterId);
pf = poiFilters.getFilterById(filterId); pf = poiFilters.getFilterById(filterId);
if (pf != null && pf.isStandardFilter()) { if (pf != null && pf.isStandardFilter()) {
pf.clearNameFilter(); pf.setFilterByName(null);
} }
poiMapLayer.setFilter(pf); poiMapLayer.setFilter(pf);
mapView.refreshMap(); mapView.refreshMap();
@ -303,7 +303,7 @@ public class MapActivityLayers {
if (RenderingIcons.containsBigIcon(f.getSimplifiedId())) { if (RenderingIcons.containsBigIcon(f.getSimplifiedId())) {
it.icon(RenderingIcons.getBigIconResourceId(f.getSimplifiedId())); it.icon(RenderingIcons.getBigIconResourceId(f.getSimplifiedId()));
} else { } else {
it.icon(RenderingIcons.getBigIconResourceId("user_defined")); it.icon(R.drawable.mx_user_defined);
} }
it.reg(); it.reg();
} }

View file

@ -162,7 +162,8 @@ public class SearchActivity extends TabActivity implements OsmAndLocationListene
if(tab == POI_TAB_INDEX) { if(tab == POI_TAB_INDEX) {
return SearchPoiFilterFragment.class; return SearchPoiFilterFragment.class;
} else if(tab == ADDRESS_TAB_INDEX) { } 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) { } else if(tab == LOCATION_TAB_INDEX) {
return NavigatePointFragment.class; return NavigatePointFragment.class;
} else if(tab == HISTORY_TAB_INDEX) { } else if(tab == HISTORY_TAB_INDEX) {
@ -358,15 +359,6 @@ public class SearchActivity extends TabActivity implements OsmAndLocationListene
} }
public void setAddressSpecContent() { 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(); Intent intent = getIntent();
finish(); finish();
startActivity(intent); startActivity(intent);

View file

@ -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 String SELECT_ADDRESS_POINT_INTENT_KEY = "SELECT_ADDRESS_POINT_INTENT_KEY";
public static final int SELECT_ADDRESS_POINT_RESULT_OK = 1; 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_LAT = "SELECT_ADDRESS_POINT_LAT";
public static final String SELECT_ADDRESS_POINT_LON = "SELECT_ADDRESS_POINT_LON"; public static final String SELECT_ADDRESS_POINT_LON = "SELECT_ADDRESS_POINT_LON";
private static final int NAVIGATE_TO = 0; private static final int NAVIGATE_TO = 0;
@ -152,6 +153,7 @@ public class SearchAddressFragment extends Fragment {
return true; return true;
} }
}); });
if (ENABLE_ONLINE_ADDRESS) {
menuItem = menu.add(0, ONLINE_SEARCH, 0, R.string.search_online_address); menuItem = menu.add(0, ONLINE_SEARCH, 0, R.string.search_online_address);
MenuItemCompat.setShowAsAction(menuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); MenuItemCompat.setShowAsAction(menuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
menuItem = menuItem.setIcon(R.drawable.ic_world_globe_dark); menuItem = menuItem.setIcon(R.drawable.ic_world_globe_dark);
@ -163,6 +165,7 @@ public class SearchAddressFragment extends Fragment {
} }
}); });
} }
}
} }

View file

@ -9,18 +9,15 @@ import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.osmand.Location;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.access.AccessibleToast; import net.osmand.access.AccessibleToast;
import net.osmand.access.NavigationInfo; import net.osmand.access.NavigationInfo;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.osm.PoiCategory;
import net.osmand.osm.PoiType; import net.osmand.osm.PoiType;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
@ -29,14 +26,12 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.R.color; import net.osmand.plus.R.color;
import net.osmand.plus.activities.EditPOIFilterActivity;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.OsmandListActivity; import net.osmand.plus.activities.OsmandListActivity;
import net.osmand.plus.dashboard.DashLocationFragment; import net.osmand.plus.dashboard.DashLocationFragment;
import net.osmand.plus.dialogs.DirectionsDialogs; 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.PoiLegacyFilter;
import net.osmand.plus.poi.SearchByNameFilter;
import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.views.DirectionDrawable; import net.osmand.plus.views.DirectionDrawable;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -46,8 +41,6 @@ import net.osmand.util.OpeningHoursParser.OpeningHours;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.AsyncTask.Status; import android.os.AsyncTask.Status;
@ -89,7 +82,6 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
private static final int SHOW_ON_MAP = 1; private static final int SHOW_ON_MAP = 1;
private static final int FILTER = 2; private static final int FILTER = 2;
private PoiLegacyFilter filter; private PoiLegacyFilter filter;
private AmenityAdapter amenityAdapter; private AmenityAdapter amenityAdapter;
private EditText searchFilter; private EditText searchFilter;
@ -99,13 +91,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
private net.osmand.Location location = null; private net.osmand.Location location = null;
private Float heading = null; private Float heading = null;
private OsmandSettings settings; private SearchAmenityTask currentSearchTask = null;
private float width = 24;
private float height = 24;
// never null represents current running task or last finished
private SearchAmenityTask currentSearchTask = new SearchAmenityTask(null);
private OsmandApplication app; private OsmandApplication app;
private MenuItem showFilterItem; private MenuItem showFilterItem;
private MenuItem showOnMapItem; private MenuItem showOnMapItem;
@ -119,13 +105,10 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
searchPOILevel.setOnMenuItemClickListener(new OnMenuItemClickListener() { searchPOILevel.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
return searchMore(); return searchMore();
} }
}); });
updateSearchPoiTextButton(false);
showFilterItem = menu.add(0, FILTER, 0, R.string.search_poi_filter); showFilterItem = menu.add(0, FILTER, 0, R.string.search_poi_filter);
MenuItemCompat.setShowAsAction(showFilterItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); MenuItemCompat.setShowAsAction(showFilterItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
showFilterItem = showFilterItem.setIcon(getMyApplication().getIconsCache().getActionBarIcon( showFilterItem = showFilterItem.setIcon(getMyApplication().getIconsCache().getActionBarIcon(
@ -133,29 +116,18 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
showFilterItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { showFilterItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { 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);
} else {
if (searchFilterLayout.getVisibility() == View.GONE) { if (searchFilterLayout.getVisibility() == View.GONE) {
searchFilterLayout.setVisibility(View.VISIBLE); searchFilterLayout.setVisibility(View.VISIBLE);
} else { } else {
searchFilter.setText(""); //$NON-NLS-1$ if(filter != null) {
searchFilterLayout.setVisibility(View.GONE); searchFilter.setText(filter.getSavedFilterByName() == null ? "" :
filter.getSavedFilterByName());
} }
searchFilterLayout.setVisibility(View.GONE);
} }
return true; return true;
} }
}); });
updateShowFilterItem();
if (isSearchByNameFilter() || isNameFinderFilter()) {
showFilterItem.setVisible(false);
}
showOnMapItem = menu.add(0, SHOW_ON_MAP, 0, R.string.shared_string_show_on_map); showOnMapItem = menu.add(0, SHOW_ON_MAP, 0, R.string.shared_string_show_on_map);
MenuItemCompat.setShowAsAction(showOnMapItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); MenuItemCompat.setShowAsAction(showOnMapItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
@ -164,9 +136,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
showOnMapItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { showOnMapItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
if (searchFilter.getVisibility() == View.VISIBLE) { OsmandSettings settings = app.getSettings();
filter.setNameFilter(searchFilter.getText().toString());
}
settings.setPoiFilterForMap(filter.getFilterId()); settings.setPoiFilterForMap(filter.getFilterId());
settings.SHOW_POI_OVER_MAP.set(true); settings.SHOW_POI_OVER_MAP.set(true);
if (location != null) { if (location != null) {
@ -177,6 +147,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
} }
}); });
updateButtonState();
return true; return true;
} }
@ -190,23 +161,17 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
private boolean searchMore() { private boolean searchMore() {
String query = searchFilter.getText().toString().trim(); 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) AccessibleToast.makeText(SearchPOIActivity.this, R.string.poi_namefinder_query_empty, Toast.LENGTH_LONG)
.show(); .show();
return true; return true;
} }
if (isNameFinderFilter() && !Algorithms.objectEquals(((NameFinderPoiFilter) filter).getQuery(), query)) { if (isNameSearch() && !Algorithms.objectEquals(filter.getFilterByName(), query)) {
filter.clearPreviousZoom(); filter.clearPreviousZoom();
((NameFinderPoiFilter) filter).setQuery(query); filter.setFilterByName(query);
runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT)); runNewSearchQuery(location, 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));
} else { } else {
runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.SEARCH_FURTHER)); runNewSearchQuery(location, SEARCH_FURTHER);
} }
return true; return true;
} }
@ -221,23 +186,12 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
setSupportProgressBarIndeterminateVisibility(false); setSupportProgressBarIndeterminateVisibility(false);
app = (OsmandApplication) getApplication(); app = (OsmandApplication) getApplication();
searchFilter = (EditText) findViewById(R.id.edit);
searchFilterLayout = findViewById(R.id.SearchFilterLayout); searchFilterLayout = findViewById(R.id.SearchFilterLayout);
searchFilter = (EditText) findViewById(R.id.edit);
settings = ((OsmandApplication) getApplication()).getSettings();
searchFilter.addTextChangedListener(new TextWatcher() { searchFilter.addTextChangedListener(new TextWatcher() {
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
if (!isNameFinderFilter() && !isSearchByNameFilter()) { changeFilter(s);
amenityAdapter.getFilter().filter(s);
} else {
if (searchPOILevel != null) {
searchPOILevel.setEnabled(true);
searchPOILevel.setTitle(R.string.search_button);
}
}
} }
@Override @Override
@ -258,15 +212,9 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
}); });
amenityAdapter = new AmenityAdapter(new ArrayList<Amenity>()); amenityAdapter = new AmenityAdapter(new ArrayList<Amenity>());
setListAdapter(amenityAdapter); 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 @Override
protected void onResume() { protected void onResume() {
@ -289,18 +237,12 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
if (filter != null) { if (filter != null) {
filter.clearPreviousZoom(); filter.clearPreviousZoom();
} else { } else {
amenityAdapter.setNewModel(Collections.<Amenity> emptyList(), ""); amenityAdapter.setNewModel(Collections.<Amenity> emptyList());
} }
// run query again // run query again
clearSearchQuery(); runNewSearchQuery(location, NEW_SEARCH_INIT);
} }
if (filter != null) { updateButtonState();
filter.clearNameFilter();
}
updateSubtitle();
updateSearchPoiTextButton(false);
updateShowFilterItem();
if (filter != null) { if (filter != null) {
if (searchNearBy) { if (searchNearBy) {
app.getLocationProvider().addLocationListener(this); app.getLocationProvider().addLocationListener(this);
@ -309,143 +251,93 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
} }
updateLocation(location); updateLocation(location);
} }
if (isNameFinderFilter()) { if (isNameSearch()) {
searchFilterLayout.setVisibility(View.VISIBLE);
} else if (isSearchByNameFilter()) {
searchFilterLayout.setVisibility(View.VISIBLE); searchFilterLayout.setVisibility(View.VISIBLE);
} }
if(searchFilterLayout.getVisibility() == View.VISIBLE) {
searchFilter.requestFocus();
}
if(filter != null) {
searchFilter.setText(filter.getFilterByName() != null ? filter.getFilterByName() : "");
}
// Freeze the direction arrows (reference is constant north) when Accessibility mode = ON, so screen can be read // Freeze the direction arrows (reference is constant north) when Accessibility mode = ON, so screen can be read
// aloud without continuous updates // aloud without continuous updates
if (!app.accessibilityEnabled()) { if (!app.accessibilityEnabled()) {
app.getLocationProvider().addCompassListener(this); app.getLocationProvider().addCompassListener(this);
app.getLocationProvider().registerOrUnregisterCompassListener(true); app.getLocationProvider().registerOrUnregisterCompassListener(true);
} }
if(searchFilterLayout.getVisibility() == View.VISIBLE) {
searchFilter.requestFocus();
}
} }
private void updateShowFilterItem() { private void changeFilter(CharSequence s) {
// if (!isNameSearch() ) {
amenityAdapter.getFilter().filter(s);
if (filter != null && !isNameSearch()) {
filter.setFilterByName(s.toString());
}
updateButtonState();
}
private void updateButtonState() {
if (showFilterItem != null) { if (showFilterItem != null) {
showFilterItem.setVisible(filter != null); showFilterItem.setVisible(filter != null && !isNameSearch());
} }
}
private void updateSubtitle() {
if (filter != null) { if (filter != null) {
getSupportActionBar().setSubtitle(filter.getName() + " " + filter.getSearchArea()); String name = filter.getName();
} if(filter instanceof NominatimPoiFilter && !((NominatimPoiFilter) filter).isPlacesQuery()) {
} // nothing to add
private void showPoiCategoriesByNameFilter(String query, net.osmand.Location loc) {
OsmandApplication app = (OsmandApplication) getApplication();
if (loc != null) {
Map<PoiCategory, List<String>> 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();
}
}
}
private String typesToString(Map<PoiCategory, List<String>> map) {
StringBuilder b = new StringBuilder();
int count = 0;
Iterator<Entry<PoiCategory, List<String>>> iterator = map.entrySet().iterator();
while (iterator.hasNext() && count < 4) {
Entry<PoiCategory, List<String>> e = iterator.next();
b.append("\n").append(e.getKey().getTranslation()).append(" - ");
if (e.getValue() == null) {
b.append("...");
} else { } else {
for (int j = 0; j < e.getValue().size() && j < 3; j++) { name += " " + filter.getSearchArea();
if (j > 0) {
b.append(", ");
} }
b.append(e.getValue().get(j)); getSupportActionBar().setSubtitle(name);
}
}
}
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();
} }
if (searchPOILevel != null) { 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())) {
searchPOILevel.setEnabled(true);
searchPOILevel.setTitle(R.string.search_button);
}
searchPOILevel.setEnabled(enabled); searchPOILevel.setEnabled(enabled);
searchPOILevel.setTitle(title); searchPOILevel.setTitle(title);
} }
} }
private net.osmand.Location getSearchedLocation() { private synchronized void runNewSearchQuery(net.osmand.Location location, int requestType) {
return currentSearchTask.getSearchedLocation(); if (currentSearchTask == null || currentSearchTask.getStatus() == Status.FINISHED ) {
} currentSearchTask = new SearchAmenityTask(location, requestType);
private synchronized void runNewSearchQuery(SearchAmenityRequest request) {
if (currentSearchTask.getStatus() == Status.FINISHED || currentSearchTask.getSearchedLocation() == null) {
currentSearchTask = new SearchAmenityTask(request);
currentSearchTask.execute(); currentSearchTask.execute();
} }
} }
private synchronized void clearSearchQuery() { public boolean isNominatimFilter() {
if (currentSearchTask.getStatus() == Status.FINISHED || currentSearchTask.getSearchedLocation() == null) { return filter instanceof NominatimPoiFilter;
currentSearchTask = new SearchAmenityTask(null);
}
} }
public boolean isNameFinderFilter() { public boolean isOfflineSearchByNameFilter() {
return filter instanceof NameFinderPoiFilter;
}
public boolean isSearchByNameFilter() {
return filter != null && PoiLegacyFilter.BY_NAME_FILTER_ID.equals(filter.getFilterId()); return filter != null && PoiLegacyFilter.BY_NAME_FILTER_ID.equals(filter.getFilterId());
} }
public boolean isNameSearch() {
return isNominatimFilter() || isOfflineSearchByNameFilter();
}
@Override @Override
public void updateLocation(net.osmand.Location location) { public void updateLocation(net.osmand.Location location) {
boolean handled = false; boolean handled = false;
if (location != null && filter != null) { if (location != null && filter != null) {
net.osmand.Location searchedLocation = getSearchedLocation(); net.osmand.Location searchedLocation = currentSearchTask == null ? null : currentSearchTask.getSearchedLocation();
if (searchedLocation == null) { if (searchedLocation == null) {
searchedLocation = location; if (!isNameSearch()) {
if (!isNameFinderFilter() && !isSearchByNameFilter()) { runNewSearchQuery(location, NEW_SEARCH_INIT);
runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT));
} }
handled = true; handled = true;
} else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) { } else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) {
searchedLocation = location; searchedLocation = location;
runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.SEARCH_AGAIN)); runNewSearchQuery(location, SEARCH_AGAIN);
handled = true; handled = true;
} else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_REFRESH) { } else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_REFRESH) {
handled = true; handled = true;
@ -457,16 +349,8 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
} }
if (handled) { if (handled) {
this.location = location; this.location = location;
updateSearchPoiTextButton(false); amenityAdapter.notifyDataSetChanged();
// Get the top position from the first visible element updateButtonState();
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);
} }
} }
@ -510,6 +394,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
@Override @Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) { public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
final Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position); final Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position);
final OsmandSettings settings = app.getSettings();
String poiSimpleFormat = OsmAndFormatter.getPoiStringWithoutType(amenity, String poiSimpleFormat = OsmAndFormatter.getPoiStringWithoutType(amenity,
settings.usingEnglishNames()); settings.usingEnglishNames());
PointDescription name = new PointDescription(PointDescription.POINT_TYPE_POI, poiSimpleFormat); PointDescription name = new PointDescription(PointDescription.POINT_TYPE_POI, poiSimpleFormat);
@ -561,35 +446,26 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
optionsMenu.show(); optionsMenu.show();
} }
static class SearchAmenityRequest {
private static final int SEARCH_AGAIN = 1; private static final int SEARCH_AGAIN = 1;
private static final int NEW_SEARCH_INIT = 2; private static final int NEW_SEARCH_INIT = 2;
private static final int SEARCH_FURTHER = 3; 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;
}
}
class SearchAmenityTask extends AsyncTask<Void, Amenity, List<Amenity>> implements ResultMatcher<Amenity> { class SearchAmenityTask extends AsyncTask<Void, Amenity, List<Amenity>> implements ResultMatcher<Amenity> {
private SearchAmenityRequest request; private int requestType;
private TLongHashSet existingObjects = null; private TLongHashSet existingObjects = null;
private TLongHashSet updateExisting; private TLongHashSet updateExisting;
private Location location;
public SearchAmenityTask(SearchAmenityRequest request) { public SearchAmenityTask(net.osmand.Location location, int requestType) {
this.request = request; this.location = location;
this.requestType = requestType;
} }
net.osmand.Location getSearchedLocation() { net.osmand.Location getSearchedLocation() {
return request != null ? request.location : null; return location ;
} }
@Override @Override
@ -600,9 +476,9 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
} }
existingObjects = new TLongHashSet(); existingObjects = new TLongHashSet();
updateExisting = new TLongHashSet(); updateExisting = new TLongHashSet();
if (request.type == SearchAmenityRequest.NEW_SEARCH_INIT) { if (requestType == NEW_SEARCH_INIT) {
amenityAdapter.clear(); amenityAdapter.clear();
} else if (request.type == SearchAmenityRequest.SEARCH_FURTHER) { } else if (requestType == SEARCH_FURTHER) {
List<Amenity> list = amenityAdapter.getOriginalAmenityList(); List<Amenity> list = amenityAdapter.getOriginalAmenityList();
for (Amenity a : list) { for (Amenity a : list) {
updateExisting.add(getAmenityId(a)); updateExisting.add(getAmenityId(a));
@ -617,21 +493,19 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
@Override @Override
protected void onPostExecute(List<Amenity> result) { protected void onPostExecute(List<Amenity> result) {
// getSherlock().setProgressBarIndeterminateVisibility(false); // getSherlock().setProgressBarIndeterminateVisibility(false);
updateSearchPoiTextButton(true); currentSearchTask = null;
if (isNameFinderFilter()) { updateButtonState();
if (!Algorithms.isEmpty(((NameFinderPoiFilter) filter).getLastError())) { if (isNameSearch()) {
AccessibleToast.makeText(SearchPOIActivity.this, ((NameFinderPoiFilter) filter).getLastError(), if (isNominatimFilter() && !Algorithms.isEmpty(((NominatimPoiFilter) filter).getLastError())) {
AccessibleToast.makeText(SearchPOIActivity.this, ((NominatimPoiFilter) filter).getLastError(),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
} }
amenityAdapter.setNewModel(result, ""); amenityAdapter.setNewModel(result);
showOnMapItem.setEnabled(amenityAdapter.getCount() > 0); showOnMapItem.setEnabled(amenityAdapter.getCount() > 0);
} else if (isSearchByNameFilter()) {
showOnMapItem.setEnabled(amenityAdapter.getCount() > 0);
amenityAdapter.setNewModel(result, "");
} else { } else {
amenityAdapter.setNewModel(result, searchFilter.getText().toString()); amenityAdapter.setNewModel(result);
} }
updateSubtitle();
} }
@Override @Override
@ -643,14 +517,14 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
@Override @Override
protected List<Amenity> doInBackground(Void... params) { protected List<Amenity> doInBackground(Void... params) {
if (request.location != null) { if (location != null) {
if (request.type == SearchAmenityRequest.NEW_SEARCH_INIT) { if (requestType == NEW_SEARCH_INIT) {
return filter.initializeNewSearch(request.location.getLatitude(), request.location.getLongitude(), return filter.initializeNewSearch(location.getLatitude(), location.getLongitude(),
-1, this); -1, this);
} else if (request.type == SearchAmenityRequest.SEARCH_FURTHER) { } else if (requestType == SEARCH_FURTHER) {
return filter.searchFurther(request.location.getLatitude(), request.location.getLongitude(), this); return filter.searchFurther(location.getLatitude(), location.getLongitude(), this);
} else if (request.type == SearchAmenityRequest.SEARCH_AGAIN) { } else if (requestType == SEARCH_AGAIN) {
return filter.searchAgain(request.location.getLatitude(), request.location.getLongitude()); return filter.searchAgain(location.getLatitude(), location.getLongitude());
} }
} }
return Collections.emptyList(); return Collections.emptyList();
@ -661,9 +535,9 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
long id = getAmenityId(object); long id = getAmenityId(object);
if (existingObjects != null && !existingObjects.contains(id)) { if (existingObjects != null && !existingObjects.contains(id)) {
existingObjects.add(id); existingObjects.add(id);
if (request.type == SearchAmenityRequest.NEW_SEARCH_INIT) { if (requestType == NEW_SEARCH_INIT) {
publishProgress(object); publishProgress(object);
} else if (request.type == SearchAmenityRequest.SEARCH_FURTHER) { } else if (requestType == SEARCH_FURTHER) {
if (!updateExisting.contains(id)) { if (!updateExisting.contains(id)) {
publishProgress(object); publishProgress(object);
} }
@ -690,7 +564,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
return originalAmenityList; return originalAmenityList;
} }
public void setNewModel(List<Amenity> amenityList, String filter) { public void setNewModel(List<Amenity> amenityList) {
setNotifyOnChange(false); setNotifyOnChange(false);
screenOrientation = DashLocationFragment.getScreenOrientation(SearchPOIActivity.this); screenOrientation = DashLocationFragment.getScreenOrientation(SearchPOIActivity.this);
originalAmenityList = new ArrayList<Amenity>(amenityList); originalAmenityList = new ArrayList<Amenity>(amenityList);
@ -698,10 +572,8 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
for (Amenity obj : amenityList) { for (Amenity obj : amenityList) {
add(obj); add(obj);
} }
getFilter().filter(filter);
setNotifyOnChange(true); setNotifyOnChange(true);
this.notifyDataSetChanged(); this.notifyDataSetInvalidated();
} }
@Override @Override
@ -744,7 +616,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
if (dd instanceof DirectionDrawable) { if (dd instanceof DirectionDrawable) {
draw = (DirectionDrawable) dd; draw = (DirectionDrawable) dd;
} else { } 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); R.drawable.ic_destination_arrow_white, R.color.color_distance);
direction.setImageDrawable(draw); direction.setImageDrawable(draw);
} }
@ -780,7 +652,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
if (mes != null) { if (mes != null) {
distance = " " + OsmAndFormatter.getFormattedDistance((int) mes[0], getMyApplication()) + " "; //$NON-NLS-1$ 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); label.setText(poiType);
distanceText.setText(distance); distanceText.setText(distance);
return (row); return (row);
@ -800,21 +672,20 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
protected FilterResults performFiltering(CharSequence constraint) { protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults(); FilterResults results = new FilterResults();
List<Amenity> listToFilter = originalAmenityList; List<Amenity> listToFilter = originalAmenityList;
if (constraint == null || constraint.length() == 0) { if (constraint == null || constraint.length() == 0 || filter == null) {
results.values = listToFilter; results.values = listToFilter;
results.count = listToFilter.size(); results.count = listToFilter.size();
} else { } else {
boolean en = app.getSettings().usingEnglishNames();
String lowerCase = constraint.toString().toLowerCase(); String lowerCase = constraint.toString().toLowerCase();
List<Amenity> filter = new ArrayList<Amenity>(); List<Amenity> res = new ArrayList<Amenity>();
for (Amenity item : listToFilter) { for (Amenity item : listToFilter) {
String lower = OsmAndFormatter.getPoiStringWithoutType(item, settings.usingEnglishNames()) if (filter.checkNameFilter(item, lowerCase, en)) {
.toLowerCase(); res.add(item);
if (lower.indexOf(lowerCase) != -1) {
filter.add(item);
} }
} }
results.values = filter; results.values = res;
results.count = filter.size(); results.count = res.size();
} }
return results; return results;
} }

View file

@ -15,13 +15,14 @@ import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.PoiType; import net.osmand.osm.PoiType;
import net.osmand.plus.IconsCache; import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.EditPOIFilterActivity; import net.osmand.plus.activities.EditPOIFilterActivity;
import net.osmand.plus.activities.search.SearchActivity.SearchActivityChild; 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.PoiFiltersHelper;
import net.osmand.plus.poi.PoiLegacyFilter; 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.render.RenderingIcons;
import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.resources.ResourceManager;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -125,6 +126,11 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv
for(AbstractPoiType p : res.values()) { for(AbstractPoiType p : res.values()) {
filters.add(p); filters.add(p);
} }
filters.add(poiFilters.getSearchByNamePOIFilter());
if(OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class) != null) {
filters.add(poiFilters.getNominatimPOIFilter());
filters.add(poiFilters.getNominatimAddressFilter());
}
} }
return filters; return filters;
} }
@ -175,7 +181,14 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv
return; return;
} }
if (item instanceof PoiLegacyFilter) { 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 if(model.isStandardFilter()) {
model.setFilterByName(null);
}
showFilterActivity(model.getFilterId());
} else { } else {
showFilterActivity(PoiLegacyFilter.STD_PREFIX + ((AbstractPoiType) item).getKeyName()); showFilterActivity(PoiLegacyFilter.STD_PREFIX + ((AbstractPoiType) item).getKeyName());
} }
@ -237,6 +250,9 @@ public class SearchPoiFilterFragment extends ListFragment implements SearchActiv
final PoiLegacyFilter model = (PoiLegacyFilter) item; final PoiLegacyFilter model = (PoiLegacyFilter) item;
if (RenderingIcons.containsBigIcon(model.getSimplifiedId())) { if (RenderingIcons.containsBigIcon(model.getSimplifiedId())) {
icon.setImageDrawable(RenderingIcons.getBigIcon(getActivity(), 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 { } else {
icon.setImageResource(R.drawable.mx_user_defined); icon.setImageResource(R.drawable.mx_user_defined);
} }

View file

@ -527,19 +527,7 @@ public class WaypointHelper {
PoiLegacyFilter pf = getPoiFilter(); PoiLegacyFilter pf = getPoiFilter();
if (pf != null) { if (pf != null) {
final List<Location> locs = route.getImmutableAllLocations(); final List<Location> locs = route.getImmutableAllLocations();
List<Amenity> amenities = app.getResourceManager().searchAmenitiesOnThePath(locs, poiSearchDeviationRadius, List<Amenity> amenities = pf.searchAmenitiesOnThePath(locs, poiSearchDeviationRadius);
pf, new ResultMatcher<Amenity>() {
@Override
public boolean publish(Amenity object) {
return true;
}
@Override
public boolean isCancelled() {
return false;
}
});
for (Amenity a : amenities) { for (Amenity a : amenities) {
AmenityRoutePoint rp = a.getRoutePoint(); AmenityRoutePoint rp = a.getRoutePoint();
int i = locs.indexOf(rp.pointA); int i = locs.indexOf(rp.pointA);

View file

@ -6,6 +6,7 @@ import java.net.URLConnection;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
@ -22,66 +23,71 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; 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 String FILTER_ID = "name_finder"; //$NON-NLS-1$
private static final Log log = PlatformUtil.getLog(NameFinderPoiFilter.class); private static final Log log = PlatformUtil.getLog(NominatimPoiFilter.class);
private static final int LIMIT = 300; private static final int LIMIT = 300;
List<Amenity> searchedAmenities = new ArrayList<Amenity>();
private String query = ""; //$NON-NLS-1$
private String lastError = ""; //$NON-NLS-1$ private String lastError = ""; //$NON-NLS-1$
private boolean addressQuery;
public NameFinderPoiFilter(OsmandApplication application) { public NominatimPoiFilter(OsmandApplication application, boolean addressQuery) {
super(null, application); super(application);
this.name = application.getString(R.string.poi_filter_nominatim); //$NON-NLS-1$ 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.distanceToSearchValues = new double[] {1, 2, 5, 10, 20, 50, 100, 200, 500 };
this.filterId = FILTER_ID; }
this.filterId = FILTER_ID + (addressQuery ? "_address" : "_places");
}
public boolean isPlacesQuery() {
return !addressQuery;
} }
@Override @Override
public List<Amenity> searchAgain(double lat, double lon) { public boolean isAutomaticallyIncreaseSearch() {
MapUtils.sortListOfMapObject(searchedAmenities, lat, lon); return false;
return searchedAmenities;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
} }
@Override @Override
protected List<Amenity> searchAmenities(double lat, double lon, double topLatitude, protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, ResultMatcher<Amenity> matcher) { double bottomLatitude, double leftLongitude, double rightLongitude, ResultMatcher<Amenity> matcher) {
final int deviceApiVersion = android.os.Build.VERSION.SDK_INT; final int deviceApiVersion = android.os.Build.VERSION.SDK_INT;
String NOMINATIM_API; String NOMINATIM_API;
if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {
NOMINATIM_API = "https://nominatim.openstreetmap.org/search/"; NOMINATIM_API = "https://nominatim.openstreetmap.org/search/";
} } else {
else {
NOMINATIM_API = "http://nominatim.openstreetmap.org/search/"; NOMINATIM_API = "http://nominatim.openstreetmap.org/search/";
} }
currentSearchResult = new ArrayList<Amenity>();
searchedAmenities.clear();
String viewbox = "viewboxlbrt="+((float) leftLongitude)+","+((float) bottomLatitude)+","+((float) rightLongitude)+","+((float) topLatitude); String viewbox = "viewboxlbrt="+((float) leftLongitude)+","+((float) bottomLatitude)+","+((float) rightLongitude)+","+((float) topLatitude);
try { try {
lastError = ""; 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); log.info(urlq);
URLConnection connection = NetworkUtils.getHttpURLConnection(urlq); //$NON-NLS-1$ URLConnection connection = NetworkUtils.getHttpURLConnection(urlq); //$NON-NLS-1$
InputStream stream = connection.getInputStream(); InputStream stream = connection.getInputStream();
XmlPullParser parser = PlatformUtil.newXMLPullParser(); XmlPullParser parser = PlatformUtil.newXMLPullParser();
parser.setInput(stream, "UTF-8"); //$NON-NLS-1$ parser.setInput(stream, "UTF-8"); //$NON-NLS-1$
int eventType; int eventType;
int namedDepth= 0; int namedDepth = 0;
Amenity a = null; Amenity a = null;
MapPoiTypes poiTypes = ((OsmandApplication) getApplication()).getPoiTypes(); MapPoiTypes poiTypes = ((OsmandApplication) getApplication()).getPoiTypes();
while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) { while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
@ -91,7 +97,7 @@ public class NameFinderPoiFilter extends PoiLegacyFilter {
if (err != null && err.length() > 0) { if (err != null && err.length() > 0) {
lastError = err; lastError = err;
stream.close(); stream.close();
return searchedAmenities; return currentSearchResult;
} }
} }
if (parser.getName().equals("place")) { //$NON-NLS-1$ if (parser.getName().equals("place")) { //$NON-NLS-1$
@ -108,7 +114,7 @@ public class NameFinderPoiFilter extends PoiLegacyFilter {
a.setType(poiTypes.getOtherPoiCategory()); 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)) { if (matcher == null || matcher.publish(a)) {
searchedAmenities.add(a); currentSearchResult.add(a);
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
log.info("Invalid attributes", e); //$NON-NLS-1$ log.info("Invalid attributes", e); //$NON-NLS-1$
@ -126,7 +132,7 @@ public class NameFinderPoiFilter extends PoiLegacyFilter {
} else if (eventType == XmlPullParser.END_TAG) { } else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("place")) { //$NON-NLS-1$ if (parser.getName().equals("place")) { //$NON-NLS-1$
namedDepth--; namedDepth--;
if(namedDepth == 0){ if (namedDepth == 0) {
a = null; a = null;
} }
} }
@ -140,18 +146,13 @@ public class NameFinderPoiFilter extends PoiLegacyFilter {
log.error("Error parsing name finder poi", e); //$NON-NLS-1$ log.error("Error parsing name finder poi", e); //$NON-NLS-1$
lastError = getApplication().getString(R.string.shared_string_io_error); //$NON-NLS-1$ lastError = getApplication().getString(R.string.shared_string_io_error); //$NON-NLS-1$
} }
MapUtils.sortListOfMapObject(searchedAmenities, lat, lon); MapUtils.sortListOfMapObject(currentSearchResult, lat, lon);
return searchedAmenities; return currentSearchResult;
} }
public String getLastError() { public String getLastError() {
return lastError; return lastError;
} }
public List<Amenity> getSearchedAmenities() {
return searchedAmenities;
}
} }

View file

@ -23,7 +23,9 @@ import net.osmand.plus.api.SQLiteAPI.SQLiteStatement;
public class PoiFiltersHelper { public class PoiFiltersHelper {
private final OsmandApplication application; private final OsmandApplication application;
private NameFinderPoiFilter nameFinderPOIFilter; private NominatimPoiFilter nominatimPOIFilter;
private NominatimPoiFilter nominatimAddresFilter;
private PoiLegacyFilter searchByNamePOIFilter; private PoiLegacyFilter searchByNamePOIFilter;
private PoiLegacyFilter customPOIFilter; private PoiLegacyFilter customPOIFilter;
private PoiLegacyFilter showAllPOIFilter; private PoiLegacyFilter showAllPOIFilter;
@ -49,11 +51,18 @@ public class PoiFiltersHelper {
this.application = application; this.application = application;
} }
public NameFinderPoiFilter getNameFinderPOIFilter() { public NominatimPoiFilter getNominatimPOIFilter() {
if(nameFinderPOIFilter == null){ if(nominatimPOIFilter == null){
nameFinderPOIFilter = new NameFinderPoiFilter(application); 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() { public PoiLegacyFilter getSearchByNamePOIFilter() {
@ -104,7 +113,7 @@ public class PoiFiltersHelper {
} }
} }
PoiLegacyFilter ff = getFilterById(filterId, getCustomPOIFilter(), getSearchByNamePOIFilter(), PoiLegacyFilter ff = getFilterById(filterId, getCustomPOIFilter(), getSearchByNamePOIFilter(),
getShowAllPOIFilter(), getNameFinderPOIFilter()); getShowAllPOIFilter(), getNominatimPOIFilter(), getNominatimAddressFilter());
if (ff != null) { if (ff != null) {
return ff; return ff;
} }
@ -139,28 +148,9 @@ public class PoiFiltersHelper {
public void sortListOfFilters(List<PoiLegacyFilter> list) { public void sortListOfFilters(List<PoiLegacyFilter> list) {
final Collator instance = Collator.getInstance(); final Collator instance = Collator.getInstance();
Collections.sort(list, new Comparator<PoiLegacyFilter>() { Collections.sort(list, new Comparator<PoiLegacyFilter>() {
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 @Override
public int compare(PoiLegacyFilter lhs, PoiLegacyFilter rhs) { 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()); return instance.compare(lhs.getName(), rhs.getName());
} }
}); });
@ -383,7 +373,7 @@ public class PoiFiltersHelper {
if(map.containsKey(filterId)){ if(map.containsKey(filterId)){
PoiLegacyFilter filter = new PoiLegacyFilter(query.getString(1), filterId, PoiLegacyFilter filter = new PoiLegacyFilter(query.getString(1), filterId,
map.get(filterId), application); map.get(filterId), application);
filter.setFilterByName(query.getString(2)); filter.setSavedFilterByName(query.getString(2));
list.add(filter); list.add(filter);
} }
} while(query.moveToNext()); } while(query.moveToNext());

View file

@ -1,42 +1,44 @@
package net.osmand.plus.poi; package net.osmand.plus.poi;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; 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.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.osm.AbstractPoiType; import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.MapPoiTypes; import net.osmand.osm.MapPoiTypes;
import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiCategory;
import net.osmand.osm.PoiFilter;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import android.content.Context; 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 STD_PREFIX = "std_"; //$NON-NLS-1$
public final static String USER_PREFIX = "user_"; //$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 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 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<PoiCategory, LinkedHashSet<String>> acceptedTypes = new LinkedHashMap<PoiCategory, private Map<PoiCategory, LinkedHashSet<String>> acceptedTypes = new LinkedHashMap<PoiCategory,
LinkedHashSet<String>>(); LinkedHashSet<String>>();
private String filterByName = null;
protected String filterId; protected String filterId;
protected String name; protected String name;
protected String nameFilter;
protected boolean isStandardFilter; protected boolean isStandardFilter;
protected final OsmandApplication app; protected final OsmandApplication app;
@ -44,8 +46,13 @@ public class PoiLegacyFilter {
protected int distanceInd = 1; protected int distanceInd = 1;
// in kilometers // in kilometers
protected double[] distanceToSearchValues = new double[] {1, 2, 5, 10, 20, 50, 100, 200, 500 }; protected double[] distanceToSearchValues = new double[] {1, 2, 5, 10, 20, 50, 100, 200, 500 };
private final MapPoiTypes poiTypes; private final MapPoiTypes poiTypes;
protected String filterByName = null;
protected String savedFilterByName = null;
protected List<Amenity> currentSearchResult = null;
private Collator collator;
// constructor for standard filters // constructor for standard filters
public PoiLegacyFilter(AbstractPoiType type, OsmandApplication application) { public PoiLegacyFilter(AbstractPoiType type, OsmandApplication application) {
@ -61,10 +68,17 @@ public class PoiLegacyFilter {
} }
} }
// 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 // constructor for user defined filters
public PoiLegacyFilter(String name, String filterId, Map<PoiCategory, LinkedHashSet<String>> acceptedTypes, OsmandApplication app){ public PoiLegacyFilter(String name, String filterId,
Map<PoiCategory, LinkedHashSet<String>> acceptedTypes, OsmandApplication app){
this.app = app; this.app = app;
isStandardFilter = false; isStandardFilter = false;
poiTypes = app.getPoiTypes(); poiTypes = app.getPoiTypes();
@ -80,20 +94,47 @@ public class PoiLegacyFilter {
} }
} }
public void setNameFilter(String nameFilter) { public String getFilterByName() {
if(nameFilter != null) { return filterByName;
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<Amenity> getCurrentSearchResult() {
return currentSearchResult;
}
public List<Amenity> searchAgain(double lat, double lon) {
List<Amenity> amenityList ;
if(currentSearchResult != null) {
amenityList = currentSearchResult;
} else { } else {
clearNameFilter(); amenityList = searchAmenities(lat, lon, null);
} }
MapUtils.sortListOfMapObject(amenityList, lat, lon);
return amenityList;
} }
public String getNameFilter() {
return nameFilter;
}
public void clearNameFilter(){ public List<Amenity> searchFurther(double latitude, double longitude, ResultMatcher<Amenity> matcher){
nameFilter = null; if(distanceInd < distanceToSearchValues.length - 1){
distanceInd ++;
}
List<Amenity> amenityList = searchAmenities( latitude, longitude, matcher);
MapUtils.sortListOfMapObject(amenityList, latitude, longitude);
return amenityList;
} }
private void initSearchAll(){ private void initSearchAll(){
@ -109,15 +150,7 @@ public class PoiLegacyFilter {
} }
public List<Amenity> searchFurther(double latitude, double longitude, ResultMatcher<Amenity> matcher){
if(distanceInd < distanceToSearchValues.length - 1){
distanceInd ++;
}
List<Amenity> amenityList = searchAmenities( latitude, longitude, matcher);
MapUtils.sortListOfMapObject(amenityList, latitude, longitude);
return amenityList;
}
public String getSearchArea(){ public String getSearchArea(){
double val = distanceToSearchValues[distanceInd]; double val = distanceToSearchValues[distanceInd];
@ -141,56 +174,99 @@ public class PoiLegacyFilter {
amenityList.remove(amenityList.size() - 1); 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; return amenityList;
} }
public boolean isAutomaticallyIncreaseSearch() {
return true;
}
private List<Amenity> searchAmenities(double lat, double lon, ResultMatcher<Amenity> matcher) { private List<Amenity> searchAmenities(double lat, double lon, ResultMatcher<Amenity> matcher) {
double baseDistY = MapUtils.getDistance(lat, lon, lat - 1, lon); double baseDistY = MapUtils.getDistance(lat, lon, lat - 1, lon);
double baseDistX = MapUtils.getDistance(lat, lon, lat, lon - 1); double baseDistX = MapUtils.getDistance(lat, lon, lat, lon - 1);
double distance = distanceToSearchValues[distanceInd] * 1000; double distance = distanceToSearchValues[distanceInd] * 1000;
double topLatitude = Math.min(lat + (distance/ baseDistY ), 84.); double topLatitude = Math.min(lat + (distance/ baseDistY ), 84.);
double bottomLatitude = Math.max(lat - (distance/ baseDistY ), -84.); double bottomLatitude = Math.max(lat - (distance/ baseDistY ), -84.);
double leftLongitude = Math.max(lon - (distance / baseDistX), -180); double leftLongitude = Math.max(lon - (distance / baseDistX), -180);
double rightLongitude = Math.min(lon + (distance/ baseDistX), 180); double rightLongitude = Math.min(lon + (distance/ baseDistX), 180);
return searchAmenitiesInternal(lat, lon, topLatitude, bottomLatitude, leftLongitude, rightLongitude, matcher);
return searchAmenities(lat, lon, topLatitude, bottomLatitude, leftLongitude, rightLongitude, matcher);
} }
public ResultMatcher<Amenity> getResultMatcher(final ResultMatcher<Amenity> matcher){ public List<Amenity> searchAmenities(double top, double left, double bottom, double right, int zoom,
final String filter = nameFilter; ResultMatcher<Amenity> matcher) {
if(filter != null) { List<Amenity> results = new ArrayList<Amenity>();
List<Amenity> 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);
}
}
}
}
List<Amenity> amenities = app.getResourceManager().searchAmenities(this, top, left, bottom, right, zoom,
wrapResultMatcher(matcher));
results.addAll(amenities);
return results;
}
public List<Amenity> searchAmenitiesOnThePath(List<Location> locs, int poiSearchDeviationRadius) {
return app.getResourceManager().searchAmenitiesOnThePath(locs, poiSearchDeviationRadius, this, wrapResultMatcher(null));
}
protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher<Amenity> matcher) {
return app.getResourceManager().searchAmenities(this,
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;
}
private Collator getCollator() {
if (collator == null) {
collator = OsmAndCollator.primaryCollator();
}
return collator;
}
private ResultMatcher<Amenity> wrapResultMatcher(final ResultMatcher<Amenity> matcher) {
final boolean en = app.getSettings().usingEnglishNames(); final boolean en = app.getSettings().usingEnglishNames();
return new ResultMatcher<Amenity>() { return new ResultMatcher<Amenity>() {
@Override @Override
public boolean publish(Amenity object) { public boolean publish(Amenity a) {
if(!OsmAndFormatter.getPoiStringWithoutType(object, en).toLowerCase().contains(filter) || if (checkNameFilter(a, filterByName, en)) {
(matcher != null && !matcher.publish(object))) { if (matcher == null || matcher.publish(a)) {
return false;
}
return true; return true;
} }
}
return false;
}
@Override @Override
public boolean isCancelled() { public boolean isCancelled() {
return (matcher != null && matcher.isCancelled()); return matcher != null && matcher.isCancelled();
} }
}; };
} }
return matcher;
}
protected List<Amenity> searchAmenities(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher<Amenity> matcher) {
return app.getResourceManager().searchAmenities(this,
topLatitude, leftLongitude, bottomLatitude, rightLongitude, -1, matcher);
}
public List<Amenity> searchAgain(double lat, double lon) {
List<Amenity> amenityList = searchAmenities(lat, lon, null);
MapUtils.sortListOfMapObject(amenityList, lat, lon);
return amenityList;
}
public String getName(){ public String getName(){
return name; return name;
@ -211,24 +287,7 @@ public class PoiLegacyFilter {
return acceptedTypes.containsKey(t); return acceptedTypes.containsKey(t);
} }
public boolean acceptTypeSubtype(PoiCategory t, String subtype){ public void clearFilter() {
if(t == null) {
return true;
}
if(!poiTypes.isRegisteredType(t)) {
t = poiTypes.getOtherPoiCategory();
}
if(!acceptedTypes.containsKey(t)){
return false;
}
LinkedHashSet<String> set = acceptedTypes.get(t);
if(set == null){
return true;
}
return set.contains(subtype);
}
public void clearFilter(){
acceptedTypes = new LinkedHashMap<PoiCategory, LinkedHashSet<String>>(); acceptedTypes = new LinkedHashMap<PoiCategory, LinkedHashSet<String>>();
} }
@ -253,20 +312,6 @@ public class PoiLegacyFilter {
} }
} }
public void setMapToAccept(Map<PoiCategory, List<String>> newMap) {
Iterator<Entry<PoiCategory, List<String>>> iterator = newMap.entrySet().iterator();
acceptedTypes.clear();
while(iterator.hasNext()){
Entry<PoiCategory, List<String>> e = iterator.next();
if(e.getValue() == null){
acceptedTypes.put(e.getKey(), null);
} else {
acceptedTypes.put(e.getKey(), new LinkedHashSet<String>(e.getValue()));
}
}
}
public Map<PoiCategory, LinkedHashSet<String>> getAcceptedTypes(){ public Map<PoiCategory, LinkedHashSet<String>> getAcceptedTypes(){
return new LinkedHashMap<PoiCategory, LinkedHashSet<String>>(acceptedTypes); return new LinkedHashMap<PoiCategory, LinkedHashSet<String>>(acceptedTypes);
@ -289,15 +334,6 @@ public class PoiLegacyFilter {
return filterId; return filterId;
} }
public String getFilterByName() {
return filterByName;
}
public void setFilterByName(String filterByName) {
this.filterByName = filterByName;
}
public boolean isStandardFilter() { public boolean isStandardFilter() {
return isStandardFilter; return isStandardFilter;
} }
@ -310,4 +346,27 @@ public class PoiLegacyFilter {
return app; 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<String> set = acceptedTypes.get(type);
if(set == null){
return true;
}
return set.contains(subtype);
}
@Override
public boolean isEmpty() {
return acceptedTypes.isEmpty();
}
} }

View file

@ -16,46 +16,33 @@ public class SearchByNameFilter extends PoiLegacyFilter {
public static final String FILTER_ID = PoiLegacyFilter.BY_NAME_FILTER_ID; //$NON-NLS-1$ public static final String FILTER_ID = PoiLegacyFilter.BY_NAME_FILTER_ID; //$NON-NLS-1$
List<Amenity> searchedAmenities = new ArrayList<Amenity>();
private String query = ""; //$NON-NLS-1$
public SearchByNameFilter(OsmandApplication application) { public SearchByNameFilter(OsmandApplication application) {
super(application.getString(R.string.poi_filter_by_name), FILTER_ID, new LinkedHashMap<PoiCategory, LinkedHashSet<String>>(), 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.distanceToSearchValues = new double[] {100, 1000, 5000};
this.isStandardFilter = true;
} }
@Override @Override
public List<Amenity> searchAgain(double lat, double lon) { public boolean isAutomaticallyIncreaseSearch() {
MapUtils.sortListOfMapObject(searchedAmenities, lat, lon); return false;
return searchedAmenities;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
} }
@Override @Override
protected List<Amenity> searchAmenities(double lat, double lon, double topLatitude, protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher<Amenity> matcher) { double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher<Amenity> matcher) {
searchedAmenities.clear(); currentSearchResult = new ArrayList<Amenity>();
final int limit = distanceInd == 0 ? 500 : -1; final int limit = distanceInd == 0 ? 500 : -1;
List<Amenity> result = app.getResourceManager().searchAmenitiesByName(getFilterByName(),
List<Amenity> result = app.getResourceManager().searchAmenitiesByName(query,
topLatitude, leftLongitude, bottomLatitude, rightLongitude, lat, lon, new ResultMatcher<Amenity>() { topLatitude, leftLongitude, bottomLatitude, rightLongitude, lat, lon, new ResultMatcher<Amenity>() {
boolean elimit = false; boolean elimit = false;
@Override @Override
public boolean publish(Amenity object) { public boolean publish(Amenity object) {
if(limit != -1 && searchedAmenities.size() > limit) { if (limit != -1 && currentSearchResult.size() > limit) {
elimit = true; elimit = true;
} }
if(matcher.publish(object)) { if (matcher.publish(object)) {
searchedAmenities.add(object); currentSearchResult.add(object);
return true; return true;
} }
return false; return false;
@ -67,15 +54,8 @@ public class SearchByNameFilter extends PoiLegacyFilter {
} }
}); });
MapUtils.sortListOfMapObject(result, lat, lon); MapUtils.sortListOfMapObject(result, lat, lon);
searchedAmenities = result; currentSearchResult = result;
return searchedAmenities; return currentSearchResult;
} }
public List<Amenity> getSearchedAmenities() {
return searchedAmenities;
}
} }

View file

@ -4,8 +4,8 @@ import java.util.List;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.plus.poi.PoiLegacyFilter;
public interface AmenityIndexRepository { public interface AmenityIndexRepository {
@ -18,10 +18,11 @@ public interface AmenityIndexRepository {
/** /**
* Search amenities in the specified box doesn't cache results * Search amenities in the specified box doesn't cache results
*/ */
public List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, PoiLegacyFilter filter, List<Amenity> amenities, List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, SearchPoiTypeFilter filter,
ResultMatcher<Amenity> matcher); ResultMatcher<Amenity> matcher);
public List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, PoiLegacyFilter filter, ResultMatcher<Amenity> matcher); List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, SearchPoiTypeFilter filter,
ResultMatcher<Amenity> matcher);
} }

View file

@ -83,42 +83,29 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
@Override @Override
public synchronized List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, public synchronized List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom,
final PoiLegacyFilter filter, final List<Amenity> amenities, ResultMatcher<Amenity> matcher) { final SearchPoiTypeFilter filter, ResultMatcher<Amenity> matcher) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
SearchPoiTypeFilter poiTypeFilter = new SearchPoiTypeFilter(){
@Override
public boolean accept(PoiCategory type, String subcategory) {
return filter.acceptTypeSubtype(type, subcategory);
}
};
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(sleft, sright, stop, sbottom, zoom, SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(sleft, sright, stop, sbottom, zoom,
poiTypeFilter, filter == null ? matcher : filter.getResultMatcher(matcher)); filter, matcher);
List<Amenity> result = null;
try { try {
List<Amenity> result = index.searchPoi(req); result = index.searchPoi(req);
amenities.addAll(result);
} catch (IOException e) { } catch (IOException e) {
log.error("Error searching amenities", e); //$NON-NLS-1$ 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$ 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 @Override
public synchronized List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, final PoiLegacyFilter filter, ResultMatcher<Amenity> matcher) { public synchronized List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, final SearchPoiTypeFilter filter, ResultMatcher<Amenity> matcher) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
SearchPoiTypeFilter poiTypeFilter = new SearchPoiTypeFilter(){
@Override
public boolean accept(PoiCategory type, String subcategory) {
return filter.acceptTypeSubtype(type, subcategory);
}
};
List<Amenity> result = null; List<Amenity> result = null;
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(locations, radius, SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(locations, radius,
poiTypeFilter, filter == null ? matcher : filter.getResultMatcher(matcher)); filter, matcher );
try { try {
result = index.searchPoi(req); result = index.searchPoi(req);
} catch (IOException e) { } catch (IOException e) {

View file

@ -25,9 +25,9 @@ import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter;
import net.osmand.binary.CachedOsmandIndexes; import net.osmand.binary.CachedOsmandIndexes;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.data.TransportStop; import net.osmand.data.TransportStop;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
@ -38,15 +38,11 @@ import net.osmand.osm.PoiCategory;
import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.AppInitializer.InitEvents;
import net.osmand.plus.BusyIndicator; import net.osmand.plus.BusyIndicator;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.Version; 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.MapRenderRepositories;
import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.resources.AsyncLoadingThread.MapLoadRequest; import net.osmand.plus.resources.AsyncLoadingThread.MapLoadRequest;
@ -710,60 +706,21 @@ public class ResourceManager {
} }
////////////////////////////////////////////// Working with amenities //////////////////////////////////////////////// ////////////////////////////////////////////// Working with amenities ////////////////////////////////////////////////
public boolean checkNameFilter(Amenity object, String filterByName) { public List<Amenity> searchAmenities(SearchPoiTypeFilter filter,
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<Amenity> searchAmenities(PoiLegacyFilter filter,
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) { double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) {
final List<Amenity> amenities = new ArrayList<Amenity>(); final List<Amenity> amenities = new ArrayList<Amenity>();
searchAmenitiesInProgress = true; searchAmenitiesInProgress = true;
try { try {
if (filter instanceof NameFinderPoiFilter || filter instanceof SearchByNameFilter) { if (!filter.isEmpty()) {
List<Amenity> 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();
for (AmenityIndexRepository index : amenityRepositories) { for (AmenityIndexRepository index : amenityRepositories) {
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
index.searchAmenities(MapUtils.get31TileNumberY(topLatitude), List<Amenity> r = index.searchAmenities(MapUtils.get31TileNumberY(topLatitude),
MapUtils.get31TileNumberX(leftLongitude), MapUtils.get31TileNumberY(bottomLatitude), MapUtils.get31TileNumberX(leftLongitude), MapUtils.get31TileNumberY(bottomLatitude),
MapUtils.get31TileNumberX(rightLongitude), zoom, filter, amenities, MapUtils.get31TileNumberX(rightLongitude), zoom, filter, matcher);
new ResultMatcher<Amenity>() { if(r != null) {
amenities.addAll(r);
@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();
}
});
}
} }
} }
} finally { } finally {
@ -772,6 +729,46 @@ public class ResourceManager {
return amenities; return amenities;
} }
public List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, SearchPoiTypeFilter filter,
ResultMatcher<Amenity> matcher) {
searchAmenitiesInProgress = true;
final List<Amenity> amenities = new ArrayList<Amenity>();
try {
if (locations != null && locations.size() > 0) {
List<AmenityIndexRepository> repos = new ArrayList<AmenityIndexRepository>();
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<Amenity> res = r.searchAmenitiesOnThePath(locations, radius, filter, matcher);
if(res != null) {
amenities.addAll(res);
}
}
}
}
}
} finally {
searchAmenitiesInProgress = false;
}
return amenities;
}
public boolean containsAmenityRepositoryToSearch(boolean searchByName){ public boolean containsAmenityRepositoryToSearch(boolean searchByName){
for (AmenityIndexRepository index : amenityRepositories) { for (AmenityIndexRepository index : amenityRepositories) {
if(searchByName){ if(searchByName){
@ -828,41 +825,6 @@ public class ResourceManager {
return map; return map;
} }
public List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, PoiLegacyFilter filter, ResultMatcher<Amenity> matcher) {
searchAmenitiesInProgress = true;
final List<Amenity> amenities = new ArrayList<Amenity>();
try {
if (locations != null && locations.size() > 0) {
List<AmenityIndexRepository> repos = new ArrayList<AmenityIndexRepository>();
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<Amenity> res = r.searchAmenitiesOnThePath(locations, radius, filter, matcher);
if (res != null) {
amenities.addAll(res);
}
}
}
}
}finally {
searchAmenitiesInProgress = false;
}
return amenities;
}
////////////////////////////////////////////// Working with address /////////////////////////////////////////// ////////////////////////////////////////////// Working with address ///////////////////////////////////////////

View file

@ -1,13 +1,18 @@
package net.osmand.plus.views; 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.IconsCache;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; 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 * Created by Denis
@ -29,6 +34,16 @@ public class DirectionDrawable extends Drawable {
this.resourceId = resourceId; 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) { public void setImage(int resourceId, int clrId) {
IconsCache iconsCache = ((OsmandApplication) ctx.getApplicationContext()).getIconsCache(); IconsCache iconsCache = ((OsmandApplication) ctx.getApplicationContext()).getIconsCache();
arrowImage = iconsCache.getIcon(resourceId, clrId); arrowImage = iconsCache.getIcon(resourceId, clrId);
@ -43,15 +58,6 @@ public class DirectionDrawable extends Drawable {
onBoundsChange(getBounds()); 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) { public void setColorId(int clrId) {
// R.color.color_ok, R.color.color_unknown, R.color.color_warning // R.color.color_ok, R.color.color_unknown, R.color.color_warning

View file

@ -84,7 +84,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
if (filter == null) { if (filter == null) {
return new ArrayList<Amenity>(); return new ArrayList<Amenity>();
} }
return resourceManager.searchAmenities(filter, latLonBounds.top, latLonBounds.left, return filter.searchAmenities(latLonBounds.top, latLonBounds.left,
latLonBounds.bottom, latLonBounds.right, tileBox.getZoom(), new ResultMatcher<Amenity>() { latLonBounds.bottom, latLonBounds.right, tileBox.getZoom(), new ResultMatcher<Amenity>() {
@Override @Override