Implement search by name poi categories/subcategories

This commit is contained in:
Victor Shcherb 2011-10-01 12:54:46 +02:00
parent 7f0ef99d11
commit 76d60428f1
9 changed files with 113 additions and 15 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -40,7 +40,6 @@ import android.widget.TextView;
import android.widget.Toast;
/**
* @author Frolov
*
*/
public class EditPOIFilterActivity extends ListActivity {

View file

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

View file

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