Implement search by name poi categories/subcategories
This commit is contained in:
parent
7f0ef99d11
commit
76d60428f1
9 changed files with 113 additions and 15 deletions
|
@ -936,9 +936,8 @@ public class BinaryMapIndexReader {
|
|||
return req.getSearchResults();
|
||||
}
|
||||
|
||||
public Map<AmenityType, List<String>> searchPoiCategoriesByName(SearchRequest<Amenity> req, Map<AmenityType, List<String>> map)
|
||||
throws IOException {
|
||||
if (req.nameQuery == null || req.nameQuery.length() == 0) {
|
||||
public Map<AmenityType, List<String>> searchPoiCategoriesByName(String query, Map<AmenityType, List<String>> map) {
|
||||
if (query == null || query.length() == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
Collator collator = Collator.getInstance();
|
||||
|
@ -947,12 +946,12 @@ public class BinaryMapIndexReader {
|
|||
for(int i= 0; i< poiIndex.categories.size(); i++){
|
||||
String cat = poiIndex.categories.get(i);
|
||||
AmenityType catType = poiIndex.categoriesType.get(i);
|
||||
if(CollatorStringMatcher.cmatches(collator, cat, req.nameQuery, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){
|
||||
if(CollatorStringMatcher.cmatches(collator, cat, query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){
|
||||
map.put(catType, null);
|
||||
} else {
|
||||
List<String> subcats = poiIndex.subcategories.get(i);
|
||||
for(int j=0; j< subcats.size(); j++){
|
||||
if(CollatorStringMatcher.cmatches(collator, subcats.get(j), req.nameQuery, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){
|
||||
if(CollatorStringMatcher.cmatches(collator, subcats.get(j), query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){
|
||||
if(!map.containsKey(catType)){
|
||||
map.put(catType, new ArrayList<String>());
|
||||
}
|
||||
|
|
|
@ -555,7 +555,6 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
|
|||
|
||||
public static void main(String[] args) throws SQLException, FileNotFoundException, IOException {
|
||||
// TODO support cancelling poi search request! Do it in another thread (Check is cancelled()!!!)
|
||||
// TODO implement UI to show matching by name subcategories
|
||||
long time = System.currentTimeMillis();
|
||||
IndexPoiCreator poiCreator = new IndexPoiCreator();
|
||||
// String fileSqlte = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.odb";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<resources>
|
||||
<string name="poi_query_by_name_matches_categories">Some poi categories matching to the query were found :</string>
|
||||
<string name="data_to_search_poi_not_available">Local data to search POI is not present.</string>
|
||||
<string name="poi_filter_by_name">Search by name</string>
|
||||
<string name="old_poi_file_should_be_deleted">The poi data file \'%1$s\' is deprecated and can be deleted.</string>
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.LogUtil;
|
||||
|
@ -49,6 +50,11 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
|
|||
}
|
||||
|
||||
|
||||
public Map<AmenityType, List<String>> searchAmenityCategoriesByName(String query, Map<AmenityType, List<String>> map) {
|
||||
return index.searchPoiCategoriesByName(query, map);
|
||||
}
|
||||
|
||||
|
||||
public List<Amenity> searchAmenitiesByName(int x, int y, String query, ResultMatcher<Amenity> resulMatcher) {
|
||||
long now = System.currentTimeMillis();
|
||||
List<Amenity> amenities = Collections.emptyList();
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
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.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.osmand.OsmAndFormatter;
|
||||
import net.osmand.ResultMatcher;
|
||||
|
@ -168,6 +170,10 @@ public class PoiFilter {
|
|||
return set.contains(subtype);
|
||||
}
|
||||
|
||||
public void clearFilter(){
|
||||
acceptedTypes = new LinkedHashMap<AmenityType, LinkedHashSet<String>>();
|
||||
}
|
||||
|
||||
public boolean areAllTypesAccepted(){
|
||||
if(AmenityType.values().length == acceptedTypes.size()){
|
||||
for(AmenityType a : acceptedTypes.keySet()){
|
||||
|
@ -189,6 +195,19 @@ public class PoiFilter {
|
|||
}
|
||||
}
|
||||
|
||||
public void setMapToAccept(Map<AmenityType, List<String>> newMap) {
|
||||
Iterator<Entry<AmenityType, List<String>>> iterator = newMap.entrySet().iterator();
|
||||
acceptedTypes.clear();
|
||||
while(iterator.hasNext()){
|
||||
Entry<AmenityType, 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 String buildSqlWhereFilter(){
|
||||
if(areAllTypesAccepted()){
|
||||
return null;
|
||||
|
|
|
@ -25,6 +25,7 @@ import net.osmand.ResultMatcher;
|
|||
import net.osmand.Version;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.data.IndexConstants;
|
||||
import net.osmand.data.MapTileDownloader;
|
||||
import net.osmand.data.TransportStop;
|
||||
|
@ -645,6 +646,18 @@ public class ResourceManager {
|
|||
return amenities;
|
||||
}
|
||||
|
||||
public Map<AmenityType, List<String>> searchAmenityCategoriesByName(String searchQuery, double lat, double lon) {
|
||||
Map<AmenityType, List<String>> map = new LinkedHashMap<AmenityType, List<String>>();
|
||||
for (AmenityIndexRepository index : amenityRepositories) {
|
||||
if (index instanceof AmenityIndexRepositoryBinary) {
|
||||
if (index.checkContains(lat, lon)) {
|
||||
((AmenityIndexRepositoryBinary) index).searchAmenityCategoriesByName(searchQuery, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public void searchAmenitiesAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter, List<Amenity> toFill){
|
||||
if(filter instanceof NameFinderPoiFilter){
|
||||
List<Amenity> amenities = ((NameFinderPoiFilter) filter).getSearchedAmenities();
|
||||
|
|
|
@ -40,7 +40,6 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* @author Frolov
|
||||
*
|
||||
*/
|
||||
public class EditPOIFilterActivity extends ListActivity {
|
||||
|
|
|
@ -3,19 +3,24 @@
|
|||
*/
|
||||
package net.osmand.plus.activities.search;
|
||||
|
||||
|
||||
import gnu.trove.set.hash.TLongHashSet;
|
||||
|
||||
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.Algoritms;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.OsmAndFormatter;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.OpeningHoursParser;
|
||||
import net.osmand.osm.OpeningHoursParser.OpeningHoursRule;
|
||||
|
@ -24,11 +29,13 @@ import net.osmand.plus.OsmandSettings;
|
|||
import net.osmand.plus.PoiFilter;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.SearchByNameFilter;
|
||||
import net.osmand.plus.activities.EditPOIFilterActivity;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ListActivity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
|
@ -70,8 +77,7 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* @author Maxim Frolov
|
||||
*
|
||||
* Search poi activity
|
||||
*/
|
||||
public class SearchPOIActivity extends ListActivity implements SensorEventListener {
|
||||
|
||||
|
@ -137,7 +143,9 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
|
|||
runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT));
|
||||
} else if(isSearchByNameFilter() &&
|
||||
!Algoritms.objectEquals(((SearchByNameFilter) filter).getQuery(), query)){
|
||||
showFilter.setVisibility(View.INVISIBLE);
|
||||
filter.clearPreviousZoom();
|
||||
showPoiCategoriesByNameFilter(query, location);
|
||||
((SearchByNameFilter) filter).setQuery(query);
|
||||
runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT));
|
||||
} else {
|
||||
|
@ -149,11 +157,21 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
|
|||
showFilter.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (searchFilterLayout.getVisibility() == View.GONE) {
|
||||
searchFilterLayout.setVisibility(View.VISIBLE);
|
||||
if(isSearchByNameFilter()){
|
||||
Intent newIntent = new Intent(SearchPOIActivity.this, EditPOIFilterActivity.class);
|
||||
newIntent.putExtra(EditPOIFilterActivity.AMENITY_FILTER, PoiFilter.CUSTOM_FILTER_ID);
|
||||
if(location != null) {
|
||||
newIntent.putExtra(EditPOIFilterActivity.SEARCH_LAT, location.getLatitude());
|
||||
newIntent.putExtra(EditPOIFilterActivity.SEARCH_LON, location.getLongitude());
|
||||
}
|
||||
startActivity(newIntent);
|
||||
} else {
|
||||
searchFilter.setText(""); //$NON-NLS-1$
|
||||
searchFilterLayout.setVisibility(View.GONE);
|
||||
if (searchFilterLayout.getVisibility() == View.GONE) {
|
||||
searchFilterLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
searchFilter.setText(""); //$NON-NLS-1$
|
||||
searchFilterLayout.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -233,14 +251,17 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
|
|||
clearSearchQuery();
|
||||
}
|
||||
|
||||
if(isNameFinderFilter() || isSearchByNameFilter() ){
|
||||
if(isNameFinderFilter()){
|
||||
showFilter.setVisibility(View.GONE);
|
||||
searchFilterLayout.setVisibility(View.VISIBLE);
|
||||
} else if(isSearchByNameFilter() ){
|
||||
showFilter.setVisibility(View.INVISIBLE);
|
||||
searchFilterLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
showFilter.setVisibility(View.VISIBLE);
|
||||
showOnMap.setEnabled(filter != null);
|
||||
}
|
||||
showOnMap.setVisibility(isSearchByNameFilter() ? View.INVISIBLE : View.VISIBLE);
|
||||
showOnMap.setVisibility(isSearchByNameFilter() ? View.GONE : View.VISIBLE);
|
||||
|
||||
if (filter != null) {
|
||||
searchArea.setText(filter.getSearchArea());
|
||||
|
@ -261,7 +282,47 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
|
|||
}
|
||||
}
|
||||
|
||||
private void showPoiCategoriesByNameFilter(String query, Location loc){
|
||||
OsmandApplication app = (OsmandApplication) getApplication();
|
||||
if(loc != null){
|
||||
Map<AmenityType, List<String>> map = app.getResourceManager().searchAmenityCategoriesByName(query, loc.getLatitude(), loc.getLongitude());
|
||||
if(!map.isEmpty()){
|
||||
PoiFilter filter = ((OsmandApplication)getApplication()).getPoiFilters().getFilterById(PoiFilter.CUSTOM_FILTER_ID);
|
||||
if(filter != null){
|
||||
showFilter.setVisibility(View.VISIBLE);
|
||||
filter.setMapToAccept(map);
|
||||
}
|
||||
|
||||
String s = typesToString(map);
|
||||
Toast.makeText(this, getString(R.string.poi_query_by_name_matches_categories) + s, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String typesToString(Map<AmenityType, List<String>> map) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int count = 0;
|
||||
Iterator<Entry<AmenityType, List<String>>> iterator = map.entrySet().iterator();
|
||||
while(iterator.hasNext() && count < 4){
|
||||
Entry<AmenityType, List<String>> e = iterator.next();
|
||||
b.append("\n").append(OsmAndFormatter.toPublicString(e.getKey(), this)).append(" - ");
|
||||
if(e.getValue() == null){
|
||||
b.append("...");
|
||||
} else {
|
||||
for(int j=0; j<e.getValue().size() && j < 3; j++){
|
||||
if(j > 0){
|
||||
b.append(", ");
|
||||
}
|
||||
b.append(e.getValue().get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(iterator.hasNext()){
|
||||
b.append("\n...");
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private void updateSearchPoiTextButton(){
|
||||
if(location == null){
|
||||
searchPOILevel.setText(R.string.search_poi_location);
|
||||
|
|
|
@ -110,6 +110,7 @@ public class SearchPoiFilterActivity extends ListActivity {
|
|||
public void onListItemClick(ListView parent, View v, int position, long id) {
|
||||
final PoiFilter filter = ((AmenityAdapter) getListAdapter()).getItem(position);
|
||||
if (filter.getFilterId().equals(PoiFilter.CUSTOM_FILTER_ID)) {
|
||||
filter.clearFilter();
|
||||
showEditActivity(filter);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue