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
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;
}
@Override
public boolean isEmpty() {
return false;
}
},
new ResultMatcher<Amenity>() {
@Override

View file

@ -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<Amenity> results = reader.searchPoi(req);
@ -2104,6 +2110,11 @@ public class BinaryMapIndexReader {
return true;
}
@Override
public boolean isEmpty() {
return false;
}
}, null);
List<Amenity> results = reader.searchPoi(req);
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
-->
<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_show_description">Show description</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 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() {
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() {
@Override
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)) {
AccessibleToast.makeText(
EditPOIFilterActivity.this,

View file

@ -282,7 +282,7 @@ public class MapActivityLayers {
getApplication().getSettings().setPoiFilterForMap(filterId);
pf = poiFilters.getFilterById(filterId);
if (pf != null && pf.isStandardFilter()) {
pf.clearNameFilter();
pf.setFilterByName(null);
}
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();
}

View file

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

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 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,6 +153,7 @@ public class SearchAddressFragment extends Fragment {
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);
@ -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.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 +26,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;
@ -46,8 +41,6 @@ import net.osmand.util.OpeningHoursParser.OpeningHours;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
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;
@ -89,7 +82,6 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
private static final int SHOW_ON_MAP = 1;
private static final int FILTER = 2;
private PoiLegacyFilter filter;
private AmenityAdapter amenityAdapter;
private EditText searchFilter;
@ -99,13 +91,7 @@ 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;
@ -119,13 +105,10 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
searchPOILevel.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return searchMore();
}
});
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,29 +116,18 @@ 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);
} 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);
@ -164,9 +136,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 +147,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
}
});
updateButtonState();
return true;
}
@ -190,23 +161,17 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
private boolean searchMore() {
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));
runNewSearchQuery(location, SEARCH_FURTHER);
}
return true;
}
@ -221,23 +186,12 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
setSupportProgressBarIndeterminateVisibility(false);
app = (OsmandApplication) getApplication();
searchFilter = (EditText) findViewById(R.id.edit);
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
@ -258,15 +212,9 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
});
amenityAdapter = new AmenityAdapter(new ArrayList<Amenity>());
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 +237,12 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
if (filter != null) {
filter.clearPreviousZoom();
} else {
amenityAdapter.setNewModel(Collections.<Amenity> emptyList(), "");
amenityAdapter.setNewModel(Collections.<Amenity> emptyList());
}
// run query again
clearSearchQuery();
runNewSearchQuery(location, NEW_SEARCH_INIT);
}
if (filter != null) {
filter.clearNameFilter();
}
updateSubtitle();
updateSearchPoiTextButton(false);
updateShowFilterItem();
updateButtonState();
if (filter != null) {
if (searchNearBy) {
app.getLocationProvider().addLocationListener(this);
@ -309,143 +251,93 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
}
updateLocation(location);
}
if (isNameFinderFilter()) {
searchFilterLayout.setVisibility(View.VISIBLE);
} else if (isSearchByNameFilter()) {
if (isNameSearch()) {
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
// aloud without continuous updates
if (!app.accessibilityEnabled()) {
app.getLocationProvider().addCompassListener(this);
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) {
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<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("...");
String name = filter.getName();
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(", ");
name += " " + filter.getSearchArea();
}
b.append(e.getValue().get(j));
}
}
}
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().setSubtitle(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())) {
searchPOILevel.setEnabled(true);
searchPOILevel.setTitle(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 +349,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 +394,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,35 +446,26 @@ 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;
}
}
class SearchAmenityTask extends AsyncTask<Void, Amenity, List<Amenity>> implements ResultMatcher<Amenity> {
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
@ -600,9 +476,9 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
}
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<Amenity> list = amenityAdapter.getOriginalAmenityList();
for (Amenity a : list) {
updateExisting.add(getAmenityId(a));
@ -617,21 +493,19 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
@Override
protected void onPostExecute(List<Amenity> result) {
// getSherlock().setProgressBarIndeterminateVisibility(false);
updateSearchPoiTextButton(true);
if (isNameFinderFilter()) {
if (!Algorithms.isEmpty(((NameFinderPoiFilter) filter).getLastError())) {
AccessibleToast.makeText(SearchPOIActivity.this, ((NameFinderPoiFilter) filter).getLastError(),
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 +517,14 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
@Override
protected List<Amenity> 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 +535,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 +564,7 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
return originalAmenityList;
}
public void setNewModel(List<Amenity> amenityList, String filter) {
public void setNewModel(List<Amenity> amenityList) {
setNotifyOnChange(false);
screenOrientation = DashLocationFragment.getScreenOrientation(SearchPOIActivity.this);
originalAmenityList = new ArrayList<Amenity>(amenityList);
@ -698,10 +572,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 +616,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 +652,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 +672,20 @@ public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompa
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<Amenity> 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<Amenity> filter = new ArrayList<Amenity>();
List<Amenity> res = new ArrayList<Amenity>();
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;
}

View file

@ -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;
@ -125,6 +126,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;
}
@ -175,7 +181,14 @@ 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 if(model.isStandardFilter()) {
model.setFilterByName(null);
}
showFilterActivity(model.getFilterId());
} else {
showFilterActivity(PoiLegacyFilter.STD_PREFIX + ((AbstractPoiType) item).getKeyName());
}
@ -237,6 +250,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);
}

View file

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

View file

@ -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<Amenity> searchedAmenities = new ArrayList<Amenity>();
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$
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;
}
this.filterId = FILTER_ID + (addressQuery ? "_address" : "_places");
}
public boolean isPlacesQuery() {
return !addressQuery;
}
@Override
public List<Amenity> 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<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) {
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<Amenity>();
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$
@ -108,7 +114,7 @@ public class NameFinderPoiFilter extends PoiLegacyFilter {
a.setType(poiTypes.getOtherPoiCategory());
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<Amenity> getSearchedAmenities() {
return searchedAmenities;
}
}

View file

@ -23,7 +23,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 +51,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 +113,7 @@ public class PoiFiltersHelper {
}
}
PoiLegacyFilter ff = getFilterById(filterId, getCustomPOIFilter(), getSearchByNamePOIFilter(),
getShowAllPOIFilter(), getNameFinderPOIFilter());
getShowAllPOIFilter(), getNominatimPOIFilter(), getNominatimAddressFilter());
if (ff != null) {
return ff;
}
@ -139,28 +148,9 @@ public class PoiFiltersHelper {
public void sortListOfFilters(List<PoiLegacyFilter> list) {
final Collator instance = Collator.getInstance();
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
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());
}
});
@ -383,7 +373,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());

View file

@ -1,42 +1,44 @@
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.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<PoiCategory, LinkedHashSet<String>> acceptedTypes = new LinkedHashMap<PoiCategory,
LinkedHashSet<String>>();
private String filterByName = null;
protected String filterId;
protected String name;
protected String nameFilter;
protected boolean isStandardFilter;
protected final OsmandApplication app;
@ -44,8 +46,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<Amenity> currentSearchResult = null;
private Collator collator;
// constructor for standard filters
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
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;
isStandardFilter = false;
poiTypes = app.getPoiTypes();
@ -80,20 +94,47 @@ public class PoiLegacyFilter {
}
}
public void setNameFilter(String nameFilter) {
if(nameFilter != null) {
this.nameFilter = nameFilter.toLowerCase();
public String getFilterByName() {
return filterByName;
}
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 {
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<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;
}
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(){
double val = distanceToSearchValues[distanceInd];
@ -141,56 +174,99 @@ 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<Amenity> searchAmenities(double lat, double lon, ResultMatcher<Amenity> 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<Amenity> getResultMatcher(final ResultMatcher<Amenity> matcher){
final String filter = nameFilter;
if(filter != null) {
public List<Amenity> searchAmenities(double top, double left, double bottom, double right, int zoom,
ResultMatcher<Amenity> matcher) {
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();
return new ResultMatcher<Amenity>() {
@Override
public boolean publish(Amenity object) {
if(!OsmAndFormatter.getPoiStringWithoutType(object, en).toLowerCase().contains(filter) ||
(matcher != null && !matcher.publish(object))) {
return false;
}
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());
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(){
return name;
@ -211,24 +287,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<String> set = acceptedTypes.get(t);
if(set == null){
return true;
}
return set.contains(subtype);
}
public void clearFilter(){
public void clearFilter() {
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(){
return new LinkedHashMap<PoiCategory, LinkedHashSet<String>>(acceptedTypes);
@ -289,15 +334,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 +346,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<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$
List<Amenity> searchedAmenities = new ArrayList<Amenity>();
private String query = ""; //$NON-NLS-1$
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.isStandardFilter = true;
}
@Override
public List<Amenity> 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<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) {
searchedAmenities.clear();
currentSearchResult = new ArrayList<Amenity>();
final int limit = distanceInd == 0 ? 500 : -1;
List<Amenity> result = app.getResourceManager().searchAmenitiesByName(query,
List<Amenity> result = app.getResourceManager().searchAmenitiesByName(getFilterByName(),
topLatitude, leftLongitude, bottomLatitude, rightLongitude, lat, lon, new ResultMatcher<Amenity>() {
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<Amenity> getSearchedAmenities() {
return searchedAmenities;
}
}

View file

@ -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<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);
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
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();
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,
poiTypeFilter, filter == null ? matcher : filter.getResultMatcher(matcher));
filter, matcher);
List<Amenity> result = null;
try {
List<Amenity> 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<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();
SearchPoiTypeFilter poiTypeFilter = new SearchPoiTypeFilter(){
@Override
public boolean accept(PoiCategory type, String subcategory) {
return filter.acceptTypeSubtype(type, subcategory);
}
};
List<Amenity> result = null;
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(locations, radius,
poiTypeFilter, filter == null ? matcher : filter.getResultMatcher(matcher));
filter, matcher );
try {
result = index.searchPoi(req);
} catch (IOException e) {

View file

@ -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,60 +706,21 @@ 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<Amenity> searchAmenities(PoiLegacyFilter filter,
public List<Amenity> searchAmenities(SearchPoiTypeFilter filter,
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) {
final List<Amenity> amenities = new ArrayList<Amenity>();
searchAmenitiesInProgress = true;
try {
if (filter instanceof NameFinderPoiFilter || filter instanceof SearchByNameFilter) {
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();
if (!filter.isEmpty()) {
for (AmenityIndexRepository index : amenityRepositories) {
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(rightLongitude), zoom, filter, amenities,
new ResultMatcher<Amenity>() {
@Override
public boolean publish(Amenity a) {
if (checkNameFilter(a, filterByName)) {
if (matcher == null || matcher.publish(a)) {
amenities.add(a);
MapUtils.get31TileNumberX(rightLongitude), zoom, filter, matcher);
if(r != null) {
amenities.addAll(r);
}
}
return false;
}
@Override
public boolean isCancelled() {
return matcher != null && matcher.isCancelled();
}
});
}
}
}
} finally {
@ -772,6 +729,46 @@ public class ResourceManager {
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){
for (AmenityIndexRepository index : amenityRepositories) {
if(searchByName){
@ -828,41 +825,6 @@ public class ResourceManager {
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 ///////////////////////////////////////////

View file

@ -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,15 +58,6 @@ 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

View file

@ -84,7 +84,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
if (filter == null) {
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>() {
@Override