Core search in progress
This commit is contained in:
parent
44eeb3f7cc
commit
1a455885fa
22 changed files with 875 additions and 190 deletions
|
@ -4,6 +4,10 @@ android {
|
|||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.3"
|
||||
|
||||
dexOptions {
|
||||
jumboMode true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 23
|
||||
|
|
|
@ -23,12 +23,10 @@ import android.widget.ListView;
|
|||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.core.android.AtlasMapRendererView;
|
||||
import net.osmand.core.android.NativeCore;
|
||||
import net.osmand.core.jni.AreaI;
|
||||
import net.osmand.core.jni.IMapLayerProvider;
|
||||
import net.osmand.core.jni.IMapStylesCollection;
|
||||
import net.osmand.core.jni.LatLon;
|
||||
import net.osmand.core.jni.LogSeverityLevel;
|
||||
import net.osmand.core.jni.Logger;
|
||||
import net.osmand.core.jni.MapObjectsSymbolsProvider;
|
||||
import net.osmand.core.jni.MapPresentationEnvironment;
|
||||
|
@ -45,12 +43,12 @@ import net.osmand.core.jni.Utilities;
|
|||
import net.osmand.core.samples.android.sample1.MultiTouchSupport.MultiTouchZoomListener;
|
||||
import net.osmand.core.samples.android.sample1.adapters.SearchListAdapter;
|
||||
import net.osmand.core.samples.android.sample1.adapters.SearchListItem;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchAPICallback;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback;
|
||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -86,7 +84,8 @@ public class MainActivity extends Activity {
|
|||
private SearchAPI searchAPI;
|
||||
private ListView searchListView;
|
||||
private SearchListAdapter adapter;
|
||||
private final static int MAX_SEARCH_RESULTS = 50;
|
||||
private final static int MAX_SEARCH_RESULTS_CORE = 500;
|
||||
private final static int MAX_SEARCH_RESULTS_IU = 50;
|
||||
|
||||
// Germany
|
||||
private final static float INIT_LAT = 49.353953f;
|
||||
|
@ -402,41 +401,50 @@ public class MainActivity extends Activity {
|
|||
private void runSearch(AreaI bounds31, String keyword) {
|
||||
|
||||
searchAPI.setObfAreaFilter(bounds31);
|
||||
searchAPI.startSearch(keyword, MAX_SEARCH_RESULTS, new SearchAPICallback() {
|
||||
@Override
|
||||
public void onSearchFinished(List<SearchItem> searchItems, boolean cancelled) {
|
||||
if (searchItems != null && !cancelled) {
|
||||
LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
List<SearchListItem> rows = new ArrayList<>();
|
||||
for (SearchItem item : searchItems) {
|
||||
SearchListItem row =
|
||||
SearchListItem.buildListItem((SampleApplication)getApplication(), item);
|
||||
rows.add(row);
|
||||
searchAPI.startSearch(keyword, MAX_SEARCH_RESULTS_CORE,
|
||||
// Intermediate search callback
|
||||
new SearchCallback() {
|
||||
@Override
|
||||
public void onSearchFinished(List<SearchItem> searchItems) {
|
||||
processSearchResult(searchItems);
|
||||
}
|
||||
|
||||
adapter.clear();
|
||||
adapter.addAll(rows);
|
||||
adapter.updateDistance(latLon.getLatitude(), latLon.getLongitude());
|
||||
adapter.sort(new Comparator<SearchListItem>() {
|
||||
@Override
|
||||
public int compare(SearchListItem lhs, SearchListItem rhs) {
|
||||
int res = Double.compare(lhs.getDistance(), rhs.getDistance());
|
||||
if (res == 0) {
|
||||
return lhs.getName().compareToIgnoreCase(rhs.getName());
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
});
|
||||
adapter.notifyDataSetChanged();
|
||||
if (adapter.getCount() > 0) {
|
||||
searchListView.setSelection(0);
|
||||
},
|
||||
// Core search callback
|
||||
new SearchCallback() {
|
||||
@Override
|
||||
public void onSearchFinished(List<SearchItem> searchItems) {
|
||||
processSearchResult(searchItems);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
showSearchList();
|
||||
private void processSearchResult(List<SearchItem> searchItems) {
|
||||
if (searchItems != null) {
|
||||
LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
double latitude = latLon.getLatitude();
|
||||
double longitude = latLon.getLongitude();
|
||||
List<SearchListItem> rows = new ArrayList<>();
|
||||
for (SearchItem item : searchItems) {
|
||||
SearchListItem listItem =
|
||||
SearchListItem.buildListItem((SampleApplication)getApplication(), item);
|
||||
if (listItem != null) {
|
||||
rows.add(listItem);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (rows.size() > MAX_SEARCH_RESULTS_IU) {
|
||||
rows = rows.subList(0, MAX_SEARCH_RESULTS_IU);
|
||||
}
|
||||
|
||||
adapter.clear();
|
||||
adapter.addAll(rows);
|
||||
adapter.notifyDataSetChanged();
|
||||
if (adapter.getCount() > 0) {
|
||||
searchListView.setSelection(0);
|
||||
}
|
||||
|
||||
showSearchList();
|
||||
}
|
||||
}
|
||||
|
||||
private class MapViewOnGestureListener extends SimpleOnGestureListener {
|
||||
|
|
|
@ -2,7 +2,7 @@ package net.osmand.core.samples.android.sample1.adapters;
|
|||
|
||||
import net.osmand.core.samples.android.sample1.MapUtils;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.AddressSearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class AddressSearchListItem extends SearchListItem {
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.graphics.drawable.Drawable;
|
|||
|
||||
import net.osmand.core.samples.android.sample1.MapUtils;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.AmenitySearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
|
|
|
@ -26,8 +26,7 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
|||
for (int i = 0; i < getCount(); i++) {
|
||||
SearchListItem item = getItem(i);
|
||||
item.setDistance(Utilities.distance(
|
||||
longitude, latitude,
|
||||
item.getLongitude(), item.getLatitude()));
|
||||
longitude, latitude, item.getLongitude(), item.getLatitude()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,15 +3,14 @@ package net.osmand.core.samples.android.sample1.adapters;
|
|||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.AddressSearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.AmenitySearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
||||
|
||||
public class SearchListItem {
|
||||
|
||||
protected SampleApplication app;
|
||||
private SearchItem searchItem;
|
||||
private double distance;
|
||||
|
||||
public SearchListItem(SampleApplication app, SearchItem searchItem) {
|
||||
this.app = app;
|
||||
|
@ -45,11 +44,11 @@ public class SearchListItem {
|
|||
}
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
return searchItem.getDistance();
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
searchItem.setDistance(distance);
|
||||
}
|
||||
|
||||
public Drawable getIcon() {
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import net.osmand.core.jni.Address;
|
||||
import net.osmand.core.jni.AddressesByNameSearch;
|
||||
import net.osmand.core.jni.AmenitiesByNameSearch;
|
||||
import net.osmand.core.jni.Amenity;
|
||||
import net.osmand.core.jni.AreaI;
|
||||
import net.osmand.core.jni.IQueryController;
|
||||
import net.osmand.core.jni.ISearch;
|
||||
import net.osmand.core.jni.ISearch.INewResultEntryCallback;
|
||||
import net.osmand.core.jni.NullableAreaI;
|
||||
import net.osmand.core.jni.ObfsCollection;
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.requests.CoreSearchRequest;
|
||||
import net.osmand.core.samples.android.sample1.search.requests.IntermediateSearchRequest;
|
||||
import net.osmand.core.samples.android.sample1.search.requests.SearchRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchAPI {
|
||||
|
@ -21,15 +17,23 @@ public class SearchAPI {
|
|||
private ObfsCollection obfsCollection;
|
||||
private AreaI searchableArea;
|
||||
private AreaI obfAreaFilter;
|
||||
private SearchRequestExecutor executor;
|
||||
private PointI searchLocation;
|
||||
private double searchRadius;
|
||||
|
||||
public interface SearchAPICallback {
|
||||
void onSearchFinished(List<SearchItem> searchItems, boolean cancelled);
|
||||
private SearchRequestExecutor executor;
|
||||
private SearchString searchString;
|
||||
private SearchScope searchScope;
|
||||
private List<SearchItem> searchItems;
|
||||
|
||||
public interface SearchCallback {
|
||||
void onSearchFinished(List<SearchItem> searchItems);
|
||||
}
|
||||
|
||||
public SearchAPI(ObfsCollection obfsCollection) {
|
||||
public SearchAPI(@NonNull ObfsCollection obfsCollection) {
|
||||
this.obfsCollection = obfsCollection;
|
||||
executor = new SearchRequestExecutor();
|
||||
this.executor = new SearchRequestExecutor();
|
||||
this.searchString = new SearchString();
|
||||
this.searchScope = new SearchScope(this);
|
||||
}
|
||||
|
||||
public AreaI getSearchableArea() {
|
||||
|
@ -48,8 +52,55 @@ public class SearchAPI {
|
|||
this.obfAreaFilter = obfAreaFilter;
|
||||
}
|
||||
|
||||
public void startSearch(String keyword, int maxSearchResults, SearchAPICallback apiCallback) {
|
||||
executor.run(new SearchRequest(keyword, maxSearchResults, apiCallback), true);
|
||||
public PointI getSearchLocation() {
|
||||
return searchLocation;
|
||||
}
|
||||
|
||||
public void setSearchLocation(PointI searchLocation) {
|
||||
this.searchLocation = searchLocation;
|
||||
}
|
||||
|
||||
public double getSearchRadius() {
|
||||
return searchRadius;
|
||||
}
|
||||
|
||||
public void setSearchRadius(double searchRadius) {
|
||||
this.searchRadius = searchRadius;
|
||||
}
|
||||
|
||||
public ObfsCollection getObfsCollection() {
|
||||
return obfsCollection;
|
||||
}
|
||||
|
||||
public SearchString getSearchString() {
|
||||
return searchString;
|
||||
}
|
||||
|
||||
public SearchScope getSearchScope() {
|
||||
return searchScope;
|
||||
}
|
||||
|
||||
public List<SearchItem> getSearchItems() {
|
||||
return searchItems;
|
||||
}
|
||||
|
||||
public void setSearchItems(List<SearchItem> searchItems) {
|
||||
this.searchItems = searchItems;
|
||||
}
|
||||
|
||||
public void startSearch(String query, int maxSearchResults,
|
||||
SearchCallback intermediateSearchCallback,
|
||||
SearchCallback coreSearchCallback) {
|
||||
|
||||
searchString.setQueryText(query);
|
||||
searchScope.updateScope();
|
||||
IntermediateSearchRequest intermediateSearchRequest = null;
|
||||
if (searchItems != null && !searchItems.isEmpty()) {
|
||||
intermediateSearchRequest =
|
||||
new IntermediateSearchRequest(this, maxSearchResults, intermediateSearchCallback);
|
||||
}
|
||||
executor.run(new CoreSearchRequest(intermediateSearchRequest, this,
|
||||
maxSearchResults, coreSearchCallback), true);
|
||||
}
|
||||
|
||||
public void cancelSearch() {
|
||||
|
@ -97,127 +148,4 @@ public class SearchAPI {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SearchRequest {
|
||||
private String keyword;
|
||||
private int maxSearchResults;
|
||||
private Runnable onFinished;
|
||||
private SearchAPICallback apiCallback;
|
||||
|
||||
private boolean cancelled;
|
||||
private int amenityResultsCounter;
|
||||
private int addressResultsCounter;
|
||||
|
||||
public SearchRequest(String keyword, int maxSearchResults, SearchAPICallback apiCallback) {
|
||||
this.keyword = keyword;
|
||||
this.maxSearchResults = maxSearchResults;
|
||||
this.apiCallback = apiCallback;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
new AsyncTask<String, Void, List<SearchItem>>() {
|
||||
@Override
|
||||
protected List<SearchItem> doInBackground(String... params) {
|
||||
return doSearch(params[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<SearchItem> searchItems) {
|
||||
|
||||
if (onFinished != null) {
|
||||
onFinished.run();
|
||||
}
|
||||
|
||||
if (apiCallback != null) {
|
||||
apiCallback.onSearchFinished(searchItems, cancelled);
|
||||
}
|
||||
}
|
||||
}.execute(keyword);
|
||||
}
|
||||
|
||||
private List<SearchItem> doSearch(String keyword) {
|
||||
System.out.println("=== Start search");
|
||||
amenityResultsCounter = 0;
|
||||
addressResultsCounter = 0;
|
||||
|
||||
final List<SearchItem> searchItems = new ArrayList<>();
|
||||
|
||||
// Setup Amenities by name search
|
||||
AmenitiesByNameSearch amByNameSearch = new AmenitiesByNameSearch(obfsCollection);
|
||||
AmenitiesByNameSearch.Criteria amByNameCriteria = new AmenitiesByNameSearch.Criteria();
|
||||
amByNameCriteria.setName(keyword);
|
||||
if (obfAreaFilter != null) {
|
||||
amByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(obfAreaFilter));
|
||||
}
|
||||
INewResultEntryCallback amByNameResultCallback = new ISearch.INewResultEntryCallback() {
|
||||
@Override
|
||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||
Amenity amenity = new AmenityResultEntry(resultEntry).getAmenity();
|
||||
AmenitySearchItem amenitySearchItem = new AmenitySearchItem(amenity);
|
||||
searchItems.add(amenitySearchItem);
|
||||
System.out.println("Poi found === " + amenitySearchItem.toString());
|
||||
amenityResultsCounter++;
|
||||
}
|
||||
};
|
||||
|
||||
// Setup Addresses by name search
|
||||
AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(obfsCollection);
|
||||
AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria();
|
||||
addrByNameCriteria.setName(keyword);
|
||||
if (obfAreaFilter != null) {
|
||||
addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(obfAreaFilter));
|
||||
}
|
||||
INewResultEntryCallback addrByNameResultCallback = new ISearch.INewResultEntryCallback() {
|
||||
@Override
|
||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||
Address address = new AddressResultEntry(resultEntry).getAddress();
|
||||
AddressSearchItem addrSearchItem = new AddressSearchItem(address);
|
||||
searchItems.add(addrSearchItem);
|
||||
System.out.println("Address found === " + addrSearchItem.toString());
|
||||
addressResultsCounter++;
|
||||
}
|
||||
};
|
||||
|
||||
amByNameSearch.performSearch(amByNameCriteria, amByNameResultCallback.getBinding(), new IQueryController() {
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return amenityResultsCounter >= maxSearchResults || cancelled;
|
||||
}
|
||||
});
|
||||
|
||||
if (!cancelled) {
|
||||
addrByNameSearch.performSearch(addrByNameCriteria, addrByNameResultCallback.getBinding(), new IQueryController() {
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return addressResultsCounter >= maxSearchResults || cancelled;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
System.out.println("=== Finish search");
|
||||
|
||||
return searchItems;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
public void setOnFinishedCallback(Runnable onFinished) {
|
||||
this.onFinished = onFinished;
|
||||
}
|
||||
}
|
||||
|
||||
private static class AmenityResultEntry extends AmenitiesByNameSearch.ResultEntry {
|
||||
protected AmenityResultEntry(ISearch.IResultEntry resultEntry) {
|
||||
super(ISearch.IResultEntry.getCPtr(resultEntry), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class AddressResultEntry extends AddressesByNameSearch.ResultEntry {
|
||||
protected AddressResultEntry(ISearch.IResultEntry resultEntry) {
|
||||
super(ISearch.IResultEntry.getCPtr(resultEntry), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import net.osmand.core.jni.AddressesByNameSearch;
|
||||
import net.osmand.core.jni.AmenitiesByNameSearch;
|
||||
import net.osmand.core.jni.LatLon;
|
||||
import net.osmand.core.jni.QStringList;
|
||||
import net.osmand.core.jni.QStringStringListHash;
|
||||
import net.osmand.core.jni.Utilities;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.CitySearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.PoiTypeSearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.PostcodeSearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken.TokenType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SearchScope {
|
||||
|
||||
private SearchAPI searchAPI;
|
||||
private Map<TokenType, SearchToken> resolvedTokens;
|
||||
private double searchLat;
|
||||
private double searchLon;
|
||||
private double searchRadius;
|
||||
|
||||
public SearchScope(SearchAPI searchAPI) {
|
||||
this.searchAPI = searchAPI;
|
||||
}
|
||||
|
||||
public void updateScope() {
|
||||
resolvedTokens = searchAPI.getSearchString().getResolvedTokens();
|
||||
LatLon latLon = Utilities.convert31ToLatLon(searchAPI.getSearchLocation());
|
||||
searchLat = latLon.getLatitude();
|
||||
searchLon = latLon.getLongitude();
|
||||
searchRadius = searchAPI.getSearchRadius();
|
||||
}
|
||||
|
||||
public void setupAmenitySearchCriteria(AmenitiesByNameSearch.Criteria criteria) {
|
||||
String categoryName = null;
|
||||
String typeName = null;
|
||||
if (resolvedTokens.containsKey(TokenType.POI_TYPE)) {
|
||||
PoiTypeSearchToken token = (PoiTypeSearchToken)resolvedTokens.get(TokenType.POI_TYPE);
|
||||
categoryName = token.getPoiType().getCategory().getKeyName();
|
||||
typeName = token.getName();
|
||||
} else if (resolvedTokens.containsKey(TokenType.POI_FILTER)) {
|
||||
SearchToken token = resolvedTokens.get(TokenType.POI_FILTER);
|
||||
categoryName = token.getName();
|
||||
} else if (resolvedTokens.containsKey(TokenType.POI_CATEGORY)) {
|
||||
SearchToken token = resolvedTokens.get(TokenType.POI_CATEGORY);
|
||||
categoryName = token.getName();
|
||||
}
|
||||
if (!Algorithms.isEmpty(categoryName) && !Algorithms.isEmpty(typeName)) {
|
||||
QStringStringListHash list = new QStringStringListHash();
|
||||
QStringList stringList = new QStringList();
|
||||
//todo list.set(categoryName, stringList);
|
||||
criteria.setCategoriesFilter(list);
|
||||
} else if (!Algorithms.isEmpty(categoryName)) {
|
||||
QStringStringListHash list = new QStringStringListHash();
|
||||
//todo list.set(categoryName, new QStringList());
|
||||
criteria.setCategoriesFilter(list);
|
||||
}
|
||||
}
|
||||
|
||||
public void setupAddressSearchCriteria(AddressesByNameSearch.Criteria criteria) {
|
||||
//not implemented
|
||||
}
|
||||
|
||||
public boolean processAmenitySearchItem(AmenitySearchItem item) {
|
||||
boolean res = true;
|
||||
updateDistance(item);
|
||||
if (searchRadius > 0) {
|
||||
res = item.getDistance() < searchRadius;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean processAddressSearchItem(AddressSearchItem item) {
|
||||
boolean res = true;
|
||||
if (resolvedTokens.containsKey(TokenType.CITY) && item.getParentCityObfId() != null) {
|
||||
CitySearchToken token = (CitySearchToken)resolvedTokens.get(TokenType.CITY);
|
||||
res = token.getObfId().equals(item.getParentCityObfId());
|
||||
} else if (resolvedTokens.containsKey(TokenType.POSTCODE) && item.getParentPostcodeObfId() != null) {
|
||||
PostcodeSearchToken token = (PostcodeSearchToken)resolvedTokens.get(TokenType.CITY);
|
||||
res = token.getObfId().equals(item.getParentPostcodeObfId());
|
||||
}
|
||||
if (res) {
|
||||
updateDistance(item);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void processSearchResult(List<SearchItem> searchItems) {
|
||||
/*
|
||||
Collections.sort(searchItems, new Comparator<SearchItem>() {
|
||||
@Override
|
||||
public int compare(SearchItem lhs, SearchItem rhs) {
|
||||
int res = Double.compare(lhs.getDistance(), rhs.getDistance());
|
||||
if (res == 0) {
|
||||
return lhs.getName().compareToIgnoreCase(rhs.getName());
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
//todo
|
||||
}
|
||||
|
||||
private void updateDistance(SearchItem item) {
|
||||
item.setDistance(Utilities.distance(
|
||||
searchLon, searchLat, item.getLongitude(), item.getLatitude()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.NameFilterSearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken.TokenType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SearchString {
|
||||
|
||||
private String queryText = "";
|
||||
private List<SearchToken> tokens = new ArrayList<>();
|
||||
|
||||
public SearchString() {
|
||||
}
|
||||
|
||||
public String getQueryText() {
|
||||
return queryText;
|
||||
}
|
||||
|
||||
public synchronized void setQueryText(String queryText) {
|
||||
int newTextLength = queryText.length();
|
||||
int currTextLength = this.queryText.length();
|
||||
boolean isNewText = currTextLength == 0
|
||||
|| newTextLength == 0
|
||||
|| !this.queryText.regionMatches(0, queryText, 0,
|
||||
newTextLength > currTextLength ? currTextLength : newTextLength);
|
||||
|
||||
int lastKnownTokenIndex = -1;
|
||||
if (isNewText) {
|
||||
tokens.clear();
|
||||
} else {
|
||||
int brokenTokenIndex = -1;
|
||||
for (int i = 0; i < tokens.size(); i++) {
|
||||
SearchToken token = tokens.get(i);
|
||||
int lastTokenIndex = token.getLastIndex();
|
||||
if (lastTokenIndex > newTextLength - 1
|
||||
|| (lastTokenIndex < newTextLength - 1 && !startWithDelimiter(queryText.substring(lastTokenIndex + 1)))) {
|
||||
brokenTokenIndex = i;
|
||||
break;
|
||||
}
|
||||
lastKnownTokenIndex = token.getLastIndex();
|
||||
}
|
||||
|
||||
if (brokenTokenIndex != -1) {
|
||||
if (brokenTokenIndex == 0) {
|
||||
tokens.clear();
|
||||
} else {
|
||||
for (int i = tokens.size() - 1; i >= brokenTokenIndex; i--) {
|
||||
tokens.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newTextLength - 1 > lastKnownTokenIndex) {
|
||||
int firstWordIndex = lastKnownTokenIndex + 1;
|
||||
for (int i = lastKnownTokenIndex + 1; i < newTextLength; i++) {
|
||||
char c = queryText.charAt(i);
|
||||
if (isDelimiterChar(c)) {
|
||||
if (i == firstWordIndex) {
|
||||
firstWordIndex++;
|
||||
} else {
|
||||
SearchToken token = new NameFilterSearchToken(firstWordIndex, queryText.substring(firstWordIndex, i));
|
||||
tokens.add(token);
|
||||
firstWordIndex = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (firstWordIndex <= newTextLength - 1) {
|
||||
SearchToken token = new NameFilterSearchToken(firstWordIndex, queryText.substring(firstWordIndex));
|
||||
tokens.add(token);
|
||||
}
|
||||
}
|
||||
|
||||
this.queryText = queryText;
|
||||
}
|
||||
|
||||
private boolean startWithDelimiter(String text) {
|
||||
char firstChar = text.charAt(0);
|
||||
return isDelimiterChar(firstChar);
|
||||
}
|
||||
|
||||
private boolean isDelimiterChar(char c) {
|
||||
return c == ',' || c == ' ';
|
||||
}
|
||||
|
||||
public synchronized SearchToken getNextNameFilterToken() {
|
||||
SearchToken res = null;
|
||||
if (!tokens.isEmpty()) {
|
||||
for (int i = tokens.size() - 1; i >= 0; i--) {
|
||||
SearchToken token = tokens.get(i);
|
||||
if (token.getType() == TokenType.NAME_FILTER) {
|
||||
res = token;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public synchronized SearchToken getLastToken() {
|
||||
if (!tokens.isEmpty()) {
|
||||
return tokens.get(tokens.size() - 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized boolean hasNameFilterTokens() {
|
||||
return getNextNameFilterToken() != null;
|
||||
}
|
||||
|
||||
public synchronized boolean replaceToken(SearchToken oldToken, SearchToken newToken) {
|
||||
int index = tokens.indexOf(oldToken);
|
||||
if (index != -1) {
|
||||
tokens.set(index, newToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized Map<TokenType, SearchToken> getResolvedTokens() {
|
||||
Map<TokenType, SearchToken> map = new HashMap<>();
|
||||
for (SearchToken token : tokens) {
|
||||
if (token.getType() != SearchToken.TokenType.NAME_FILTER) {
|
||||
map.put(token.getType(), token);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
//test
|
||||
SearchString searchString = new SearchString();
|
||||
searchString.setQueryText("cit");
|
||||
searchString.setQueryText("city");
|
||||
searchString.setQueryText("city ");
|
||||
searchString.setQueryText("city s");
|
||||
searchString.setQueryText("city st");
|
||||
searchString.setQueryText("city street ");
|
||||
searchString.setQueryText("city street 8");
|
||||
searchString.setQueryText("new");
|
||||
}
|
||||
}
|
|
@ -1,17 +1,23 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
package net.osmand.core.samples.android.sample1.search.items;
|
||||
|
||||
import net.osmand.core.jni.Address;
|
||||
import net.osmand.core.jni.ObfAddressStreetGroupSubtype;
|
||||
import net.osmand.core.jni.ObfAddressStreetGroupType;
|
||||
import net.osmand.core.jni.Street;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class AddressSearchItem extends SearchItem {
|
||||
|
||||
private String namePrefix;
|
||||
private String nameSuffix;
|
||||
private String typeStr;
|
||||
|
||||
private BigInteger parentCityObfId;
|
||||
private BigInteger parentPostcodeObfId;
|
||||
|
||||
public AddressSearchItem(Address address) {
|
||||
super();
|
||||
|
||||
|
@ -22,8 +28,14 @@ public class AddressSearchItem extends SearchItem {
|
|||
setNativeName(street.getNativeName());
|
||||
addLocalizedNames(street.getLocalizedNames());
|
||||
if (street.getStreetGroup() != null) {
|
||||
StreetGroup streetGroup = street.getStreetGroup();
|
||||
nameSuffix = "st.";
|
||||
typeStr = street.getStreetGroup().getNativeName() + " — " + getTypeStr(street.getStreetGroup());
|
||||
typeStr = streetGroup.getNativeName() + " — " + getTypeStr(streetGroup);
|
||||
if (streetGroup.getType() == ObfAddressStreetGroupType.Postcode) {
|
||||
parentPostcodeObfId = streetGroup.getId().getId();
|
||||
} else {
|
||||
parentCityObfId = streetGroup.getId().getId();
|
||||
}
|
||||
} else {
|
||||
typeStr = "Street";
|
||||
}
|
||||
|
@ -77,6 +89,14 @@ public class AddressSearchItem extends SearchItem {
|
|||
return typeStr;
|
||||
}
|
||||
|
||||
public BigInteger getParentCityObfId() {
|
||||
return parentCityObfId;
|
||||
}
|
||||
|
||||
public BigInteger getParentPostcodeObfId() {
|
||||
return parentPostcodeObfId;
|
||||
}
|
||||
|
||||
private class StreetInternal extends Street {
|
||||
public StreetInternal(Address address) {
|
||||
super(Address.getCPtr(address), false);
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
package net.osmand.core.samples.android.sample1.search.items;
|
||||
|
||||
import net.osmand.core.jni.Amenity;
|
||||
import net.osmand.core.jni.DecodedCategoryList;
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
package net.osmand.core.samples.android.sample1.search.items;
|
||||
|
||||
import net.osmand.core.jni.LatLon;
|
||||
import net.osmand.core.jni.PointI;
|
||||
|
@ -16,6 +16,9 @@ public abstract class SearchItem {
|
|||
protected String nativeName;
|
||||
protected Map<String, String> localizedNames = new HashMap<>();
|
||||
|
||||
private double distance;
|
||||
private float priority;
|
||||
|
||||
protected SearchItem() {
|
||||
}
|
||||
|
||||
|
@ -71,6 +74,22 @@ public abstract class SearchItem {
|
|||
}
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
public float getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void setPriority(float priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + " (" + getType() + ") {lat:" + getLatitude() + " lon: " + getLongitude() + "}";
|
|
@ -0,0 +1,175 @@
|
|||
package net.osmand.core.samples.android.sample1.search.requests;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.osmand.core.jni.Address;
|
||||
import net.osmand.core.jni.AddressesByNameSearch;
|
||||
import net.osmand.core.jni.AmenitiesByNameSearch;
|
||||
import net.osmand.core.jni.Amenity;
|
||||
import net.osmand.core.jni.IQueryController;
|
||||
import net.osmand.core.jni.ISearch;
|
||||
import net.osmand.core.jni.NullableAreaI;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CoreSearchRequest extends SearchRequest {
|
||||
|
||||
private IntermediateSearchRequest intermediateSearchRequest;
|
||||
private boolean intermediateSearchDone;
|
||||
|
||||
private int amenityResultsCounter;
|
||||
private int addressResultsCounter;
|
||||
|
||||
public CoreSearchRequest(@Nullable IntermediateSearchRequest intermediateSearchRequest,
|
||||
@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) {
|
||||
super(searchAPI, maxSearchResults, searchCallback);
|
||||
this.intermediateSearchRequest = intermediateSearchRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (intermediateSearchRequest != null) {
|
||||
intermediateSearchRequest.setOnFinishedCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
intermediateSearchDone = true;
|
||||
}
|
||||
});
|
||||
intermediateSearchRequest.run();
|
||||
}
|
||||
|
||||
super.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSearchRequestPostExecute(List<SearchItem> searchItems) {
|
||||
if (intermediateSearchRequest != null && !intermediateSearchDone) {
|
||||
intermediateSearchRequest.cancel();
|
||||
}
|
||||
searchAPI.setSearchItems(searchItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (intermediateSearchRequest != null) {
|
||||
intermediateSearchRequest.cancel();
|
||||
}
|
||||
super.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SearchItem> doSearch() {
|
||||
|
||||
List<SearchItem> res = new ArrayList<>();
|
||||
|
||||
SearchToken token = searchString.getNextNameFilterToken();
|
||||
while (token != null && !cancelled) {
|
||||
if (token.getType() == SearchToken.TokenType.NAME_FILTER) {
|
||||
List<SearchItem> searchItems = doCoreSearch(token);
|
||||
res.clear();
|
||||
res.addAll(searchItems);
|
||||
}
|
||||
token = searchString.getNextNameFilterToken();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private List<SearchItem> doCoreSearch(@NonNull SearchToken token) {
|
||||
System.out.println("=== Start search");
|
||||
amenityResultsCounter = 0;
|
||||
addressResultsCounter = 0;
|
||||
|
||||
String keyword = token.getQueryText();
|
||||
final List<SearchItem> searchItems = new ArrayList<>();
|
||||
|
||||
// Setup Amenities by name search
|
||||
AmenitiesByNameSearch amByNameSearch = new AmenitiesByNameSearch(searchAPI.getObfsCollection());
|
||||
AmenitiesByNameSearch.Criteria amenityByNameCriteria = new AmenitiesByNameSearch.Criteria();
|
||||
amenityByNameCriteria.setName(keyword);
|
||||
if (searchAPI.getObfAreaFilter() != null) {
|
||||
amenityByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchAPI.getObfAreaFilter()));
|
||||
}
|
||||
searchScope.setupAmenitySearchCriteria(amenityByNameCriteria);
|
||||
|
||||
ISearch.INewResultEntryCallback amenityByNameResultCallback = new ISearch.INewResultEntryCallback() {
|
||||
@Override
|
||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||
Amenity amenity = new AmenityResultEntry(resultEntry).getAmenity();
|
||||
AmenitySearchItem amenitySearchItem = new AmenitySearchItem(amenity);
|
||||
if (searchScope.processAmenitySearchItem(amenitySearchItem)) {
|
||||
searchItems.add(amenitySearchItem);
|
||||
}
|
||||
System.out.println("Poi found === " + amenitySearchItem.toString());
|
||||
amenityResultsCounter++;
|
||||
}
|
||||
};
|
||||
|
||||
// Setup Addresses by name search
|
||||
AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(searchAPI.getObfsCollection());
|
||||
AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria();
|
||||
addrByNameCriteria.setName(keyword);
|
||||
if (searchAPI.getObfAreaFilter() != null) {
|
||||
addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchAPI.getObfAreaFilter()));
|
||||
}
|
||||
searchScope.setupAddressSearchCriteria(addrByNameCriteria);
|
||||
|
||||
ISearch.INewResultEntryCallback addrByNameResultCallback = new ISearch.INewResultEntryCallback() {
|
||||
@Override
|
||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||
Address address = new AddressResultEntry(resultEntry).getAddress();
|
||||
AddressSearchItem addrSearchItem = new AddressSearchItem(address);
|
||||
if (searchScope.processAddressSearchItem(addrSearchItem)) {
|
||||
searchItems.add(addrSearchItem);
|
||||
}
|
||||
System.out.println("Address found === " + addrSearchItem.toString());
|
||||
addressResultsCounter++;
|
||||
}
|
||||
};
|
||||
|
||||
amByNameSearch.performSearch(amenityByNameCriteria, amenityByNameResultCallback.getBinding(), new IQueryController() {
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return amenityResultsCounter >= maxSearchResults || cancelled;
|
||||
}
|
||||
});
|
||||
|
||||
if (!cancelled) {
|
||||
addrByNameSearch.performSearch(addrByNameCriteria, addrByNameResultCallback.getBinding(), new IQueryController() {
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return addressResultsCounter >= maxSearchResults || cancelled;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!cancelled) {
|
||||
searchScope.processSearchResult(searchItems);
|
||||
}
|
||||
|
||||
System.out.println("=== Finish search");
|
||||
|
||||
return searchItems;
|
||||
}
|
||||
|
||||
private class AmenityResultEntry extends AmenitiesByNameSearch.ResultEntry {
|
||||
protected AmenityResultEntry(ISearch.IResultEntry resultEntry) {
|
||||
super(ISearch.IResultEntry.getCPtr(resultEntry), false);
|
||||
}
|
||||
}
|
||||
|
||||
private class AddressResultEntry extends AddressesByNameSearch.ResultEntry {
|
||||
protected AddressResultEntry(ISearch.IResultEntry resultEntry) {
|
||||
super(ISearch.IResultEntry.getCPtr(resultEntry), false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package net.osmand.core.samples.android.sample1.search.requests;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback;
|
||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
||||
import net.osmand.core.samples.android.sample1.search.requests.SearchRequest;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IntermediateSearchRequest extends SearchRequest {
|
||||
|
||||
private List<SearchItem> searchItems;
|
||||
protected String keyword = "";
|
||||
|
||||
public IntermediateSearchRequest(@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) {
|
||||
super(searchAPI, maxSearchResults, searchCallback);
|
||||
this.searchItems = new ArrayList<>(searchAPI.getSearchItems());
|
||||
|
||||
SearchToken token = searchString.getLastToken();
|
||||
if (token != null && token.getType() == SearchToken.TokenType.NAME_FILTER) {
|
||||
keyword = token.getQueryText();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SearchItem> doSearch() {
|
||||
List<SearchItem> res = new ArrayList<>();
|
||||
for (SearchItem item : searchItems) {
|
||||
if (cancelled) {
|
||||
break;
|
||||
}
|
||||
if (keyword.isEmpty() || item.getName().contains(keyword)) {
|
||||
res.add(item);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package net.osmand.core.samples.android.sample1.search.requests;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchScope;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchString;
|
||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SearchRequest {
|
||||
protected SearchAPI searchAPI;
|
||||
protected SearchString searchString;
|
||||
protected SearchScope searchScope;
|
||||
|
||||
protected int maxSearchResults;
|
||||
protected Runnable onFinished;
|
||||
protected SearchCallback searchCallback;
|
||||
|
||||
protected boolean cancelled;
|
||||
|
||||
public SearchRequest(@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) {
|
||||
this.searchAPI = searchAPI;
|
||||
this.searchString = searchAPI.getSearchString();
|
||||
this.searchScope= searchAPI.getSearchScope();
|
||||
this.maxSearchResults = maxSearchResults;
|
||||
this.searchCallback = searchCallback;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
new AsyncTask<Void, Void, List<SearchItem>>() {
|
||||
|
||||
@Override
|
||||
protected List<SearchItem> doInBackground(Void... params) {
|
||||
return doSearch();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<SearchItem> searchItems) {
|
||||
|
||||
onSearchRequestPostExecute(searchItems);
|
||||
|
||||
if (onFinished != null) {
|
||||
onFinished.run();
|
||||
}
|
||||
|
||||
if (searchCallback != null && !cancelled) {
|
||||
searchCallback.onSearchFinished(searchItems);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
protected void onSearchRequestPostExecute(List<SearchItem> searchItems) {
|
||||
}
|
||||
|
||||
protected abstract List<SearchItem> doSearch();
|
||||
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
public void setOnFinishedCallback(@Nullable Runnable onFinished) {
|
||||
this.onFinished = onFinished;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class CitySearchToken extends SearchToken {
|
||||
|
||||
private BigInteger obfId;
|
||||
|
||||
public CitySearchToken(BigInteger obfId, int startIndex, String queryText, String name) {
|
||||
super(TokenType.CITY, startIndex, queryText, name);
|
||||
this.obfId = obfId;
|
||||
}
|
||||
|
||||
public BigInteger getObfId() {
|
||||
return obfId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
public class NameFilterSearchToken extends SearchToken {
|
||||
|
||||
public NameFilterSearchToken(int startIndex, String queryText) {
|
||||
super(TokenType.NAME_FILTER, startIndex, queryText, queryText);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import net.osmand.osm.PoiCategory;
|
||||
|
||||
public class PoiCategorySearchToken extends SearchToken {
|
||||
private PoiCategory poiCategory;
|
||||
|
||||
public PoiCategorySearchToken(@NonNull PoiCategory poiCategory, int startIndex, String queryText) {
|
||||
super(TokenType.POI_CATEGORY, startIndex, queryText, poiCategory.getKeyName());
|
||||
this.poiCategory = poiCategory;
|
||||
}
|
||||
|
||||
public PoiCategory getPoiCategory() {
|
||||
return poiCategory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
|
||||
public class PoiFilterSearchToken extends SearchToken {
|
||||
private PoiFilter poiFilter;
|
||||
|
||||
public PoiFilterSearchToken(@NonNull PoiFilter poiFilter, int startIndex, String queryText) {
|
||||
super(TokenType.POI_FILTER, startIndex, queryText, poiFilter.getKeyName());
|
||||
this.poiFilter = poiFilter;
|
||||
}
|
||||
|
||||
public PoiFilter getPoiFilter() {
|
||||
return poiFilter;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
|
||||
public class PoiTypeSearchToken extends SearchToken {
|
||||
private PoiType poiType;
|
||||
|
||||
public PoiTypeSearchToken(@NonNull PoiType poiType, int startIndex, String queryText) {
|
||||
super(TokenType.POI_TYPE, startIndex, queryText, poiType.getKeyName());
|
||||
this.poiType = poiType;
|
||||
}
|
||||
|
||||
public PoiType getPoiType() {
|
||||
return poiType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class PostcodeSearchToken extends SearchToken {
|
||||
private BigInteger obfId;
|
||||
|
||||
public PostcodeSearchToken(BigInteger obfId, int startIndex, String queryText, String name) {
|
||||
super(TokenType.POSTCODE, startIndex, queryText, name);
|
||||
this.obfId = obfId;
|
||||
}
|
||||
|
||||
public BigInteger getObfId() {
|
||||
return obfId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
public abstract class SearchToken {
|
||||
|
||||
public enum TokenType {
|
||||
CITY,
|
||||
POSTCODE,
|
||||
STREET,
|
||||
BUILDING,
|
||||
POI_CATEGORY,
|
||||
POI_FILTER,
|
||||
POI_TYPE,
|
||||
LOCATION,
|
||||
NAME_FILTER
|
||||
}
|
||||
|
||||
private TokenType type;
|
||||
private int startIndex;
|
||||
protected String queryText;
|
||||
protected String name;
|
||||
|
||||
public SearchToken(TokenType type, int startIndex, String queryText, String name) {
|
||||
this.type = type;
|
||||
this.startIndex = startIndex;
|
||||
this.queryText = queryText;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TokenType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getStartIndex() {
|
||||
return startIndex;
|
||||
}
|
||||
|
||||
public void setStartIndex(int startIndex) {
|
||||
this.startIndex = startIndex;
|
||||
}
|
||||
|
||||
public String getQueryText() {
|
||||
return queryText;
|
||||
}
|
||||
|
||||
public int getLastIndex() {
|
||||
return startIndex + queryText.length() - 1;
|
||||
}
|
||||
|
||||
public int getQueryTextLenght() {
|
||||
return queryText.length();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue