[Core sample] added new search engine
This commit is contained in:
parent
a967f56e05
commit
ec7c26ece9
40 changed files with 215 additions and 2424 deletions
|
@ -8,7 +8,6 @@ import android.graphics.PointF;
|
|||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.ViewPropertyAnimatorListener;
|
||||
import android.text.Editable;
|
||||
|
@ -28,14 +27,12 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.CollatorStringMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.core.android.AtlasMapRendererView;
|
||||
import net.osmand.core.jni.AreaI;
|
||||
import net.osmand.core.jni.IMapLayerProvider;
|
||||
import net.osmand.core.jni.IMapStylesCollection;
|
||||
import net.osmand.core.jni.IQueryController;
|
||||
import net.osmand.core.jni.ISearch;
|
||||
import net.osmand.core.jni.LatLon;
|
||||
import net.osmand.core.jni.Logger;
|
||||
import net.osmand.core.jni.MapObjectsSymbolsProvider;
|
||||
import net.osmand.core.jni.MapPresentationEnvironment;
|
||||
|
@ -56,26 +53,19 @@ 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.adapters.SearchListPositionItem;
|
||||
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.objects.PoiTypeObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiTypeSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiTypeSearchObject.ObjectType;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject.SearchObjectType;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.ObjectSearchToken;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.example.SearchUICore;
|
||||
import net.osmand.search.example.SearchUICore.SearchResultCollection;
|
||||
import net.osmand.search.example.core.ObjectType;
|
||||
import net.osmand.search.example.core.SearchResult;
|
||||
import net.osmand.search.example.core.SearchSettings;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Locale;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
private static final String TAG = "OsmAndCoreSample";
|
||||
|
@ -93,7 +83,6 @@ public class MainActivity extends Activity {
|
|||
private MapPrimitivesProvider mapPrimitivesProvider;
|
||||
private MapObjectsSymbolsProvider mapObjectsSymbolsProvider;
|
||||
private IMapLayerProvider mapLayerProvider0;
|
||||
private IMapLayerProvider mapLayerProvider1;
|
||||
private QIODeviceLogSink fileLogSink;
|
||||
|
||||
private AtlasMapRendererView mapView;
|
||||
|
@ -107,7 +96,7 @@ public class MainActivity extends Activity {
|
|||
private float elevationAngle;
|
||||
private MultiTouchSupport multiTouchSupport;
|
||||
|
||||
private SearchAPI searchAPI;
|
||||
private SearchUICore searchUICore;
|
||||
|
||||
private EditText searchEditText;
|
||||
private TextView searchDetailsText;
|
||||
|
@ -138,135 +127,15 @@ public class MainActivity extends Activity {
|
|||
private static final String PREF_MAP_ZOOM = "MAP_ZOOM";
|
||||
private static final String PREF_MAP_ELEVATION_ANGLE = "MAP_ELEVATION_ANGLE";
|
||||
|
||||
private SearchApiCallback intermediateSearchCallback = new SearchApiCallback() {
|
||||
public static final String LANGUAGE;
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<SearchObject> fetchExternalObjects(String keyword, @Nullable List<SearchObject> completeObjects) {
|
||||
return null;
|
||||
static {
|
||||
String langCode = Locale.getDefault().getLanguage();
|
||||
if (langCode.isEmpty()) {
|
||||
langCode = "en";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchFinished(List<SearchObject> searchObjects) {
|
||||
processSearchResult(searchObjects);
|
||||
LANGUAGE = langCode;
|
||||
}
|
||||
};
|
||||
|
||||
private SearchApiCallback coreSearchCallback = new SearchApiCallback() {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<SearchObject> fetchExternalObjects(String keyword, @Nullable List<SearchObject> completeObjects) {
|
||||
List<SearchObject> result = new ArrayList<>();
|
||||
boolean poiTypeSelected = false;
|
||||
PoiCategory selectedPoiCategory = null;
|
||||
PoiFilter selectedPoiFilter = null;
|
||||
if (completeObjects != null) {
|
||||
for (SearchObject searchObject : completeObjects) {
|
||||
if (searchObject.getType() == SearchObjectType.POI_TYPE) {
|
||||
PoiTypeSearchObject ptObj = (PoiTypeSearchObject) searchObject;
|
||||
switch (ptObj.getObjectType()) {
|
||||
case CATEGORY:
|
||||
selectedPoiCategory = getSampleApplication().getPoiTypes().getPoiCategoryByName(ptObj.getKeyName());
|
||||
break;
|
||||
case FILTER:
|
||||
PoiCategory category = getSampleApplication().getPoiTypes().getPoiCategoryByName(ptObj.getCategoryKeyName());
|
||||
for (PoiFilter filter : category.getPoiFilters()) {
|
||||
if (filter.getKeyName().equalsIgnoreCase(ptObj.getKeyName())) {
|
||||
selectedPoiFilter = filter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE:
|
||||
poiTypeSelected = true;
|
||||
break;
|
||||
}
|
||||
if (poiTypeSelected || selectedPoiCategory != null || selectedPoiFilter != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (poiTypeSelected) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
PoiTypesHelper poiTypesHelper = getSampleApplication().getPoiTypesHelper();
|
||||
List<AbstractPoiType> res;
|
||||
if (selectedPoiCategory != null) {
|
||||
res = poiTypesHelper.getPoiCategoryTypesTranslatedNames(selectedPoiCategory,
|
||||
new CollatorStringMatcher(keyword, CollatorStringMatcher.StringMatcherMode.CHECK_STARTS_FROM_SPACE));
|
||||
final Collator inst = Collator.getInstance();
|
||||
Collections.sort(res, new Comparator<AbstractPoiType>() {
|
||||
@Override
|
||||
public int compare(AbstractPoiType lhs, AbstractPoiType rhs) {
|
||||
return inst.compare(lhs.getTranslation(), rhs.getTranslation());
|
||||
}
|
||||
});
|
||||
} else if (selectedPoiFilter != null) {
|
||||
res = poiTypesHelper.getPoiFilterTypesTranslatedNames(selectedPoiFilter,
|
||||
new CollatorStringMatcher(keyword, CollatorStringMatcher.StringMatcherMode.CHECK_STARTS_FROM_SPACE));
|
||||
final Collator inst = Collator.getInstance();
|
||||
Collections.sort(res, new Comparator<AbstractPoiType>() {
|
||||
@Override
|
||||
public int compare(AbstractPoiType lhs, AbstractPoiType rhs) {
|
||||
return inst.compare(lhs.getTranslation(), rhs.getTranslation());
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
res = poiTypesHelper.findPoiTypes(keyword);
|
||||
}
|
||||
|
||||
for (AbstractPoiType pt : res) {
|
||||
if (pt instanceof PoiCategory) {
|
||||
result.add(new PoiTypeSearchObject(ObjectType.CATEGORY,
|
||||
new PoiTypeObject(pt.getTranslation(), pt.getKeyName(), null)));
|
||||
} else if (pt instanceof PoiFilter) {
|
||||
PoiFilter poiFilter = (PoiFilter) pt;
|
||||
result.add(new PoiTypeSearchObject(ObjectType.FILTER,
|
||||
new PoiTypeObject(poiFilter.getTranslation(), poiFilter.getKeyName(), poiFilter.getPoiCategory().getKeyName())));
|
||||
} else if (pt instanceof PoiType) {
|
||||
PoiType poiType = (PoiType) pt;
|
||||
result.add(new PoiTypeSearchObject(ObjectType.TYPE,
|
||||
new PoiTypeObject(poiType.getTranslation(), poiType.getKeyName(), poiType.getCategory().getKeyName())));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchFinished(List<SearchObject> searchObjects) {
|
||||
|
||||
processSearchResult(searchObjects);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Map<SearchObjectType, ObjectSearchToken> objectTokensMap = searchAPI.getObjectTokens();
|
||||
ObjectSearchToken lastObjectToken = searchAPI.getLastObjectToken();
|
||||
for (ObjectSearchToken token : objectTokensMap.values()) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(" • ");
|
||||
}
|
||||
sb.append(token.getSearchObject().getName(MapUtils.LANGUAGE));
|
||||
}
|
||||
if (lastObjectToken != null && lastObjectToken.isSuggestion()) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(" • ");
|
||||
}
|
||||
sb.append(lastObjectToken.getSearchObject().getName(MapUtils.LANGUAGE));
|
||||
}
|
||||
if (sb.length() == 0) {
|
||||
searchDetailsText.setVisibility(View.GONE);
|
||||
} else {
|
||||
searchDetailsText.setText(sb.toString());
|
||||
searchDetailsText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
hideProgressBar();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -342,7 +211,7 @@ public class MainActivity extends Activity {
|
|||
displayDensityFactor,
|
||||
1.0f,
|
||||
1.0f,
|
||||
MapUtils.LANGUAGE);
|
||||
LANGUAGE);
|
||||
//mapPresentationEnvironment->setSettings(configuration.styleSettings);
|
||||
mapPrimitiviser = new MapPrimitiviser(
|
||||
mapPresentationEnvironment);
|
||||
|
@ -366,8 +235,7 @@ public class MainActivity extends Activity {
|
|||
|
||||
app.getIconsCache().setDisplayDensityFactor(displayDensityFactor);
|
||||
|
||||
//Setup search
|
||||
searchAPI = new SearchAPI(obfsCollection, MapUtils.LANGUAGE);
|
||||
setupSearch();
|
||||
|
||||
searchEditText = (EditText) findViewById(R.id.searchEditText);
|
||||
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||
|
@ -392,10 +260,18 @@ public class MainActivity extends Activity {
|
|||
searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus && isSearchListHidden()) {
|
||||
if (hasFocus) {
|
||||
net.osmand.core.jni.LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings().setOriginalLocation(
|
||||
new LatLon(latLon.getLatitude(), latLon.getLongitude()));
|
||||
settings = settings.setLang(LANGUAGE);
|
||||
searchUICore.updateSettings(settings);
|
||||
|
||||
adapter.setLocation(new LatLon(latLon.getLatitude(), latLon.getLongitude()));
|
||||
|
||||
if (isSearchListHidden()) {
|
||||
showSearchList();
|
||||
if (adapter.getCount() > 0) {
|
||||
LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
adapter.updateDistance(latLon.getLatitude(), latLon.getLongitude());
|
||||
adapter.notifyDataSetChanged();
|
||||
} else {
|
||||
|
@ -403,6 +279,7 @@ public class MainActivity extends Activity {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
searchDetailsText = (TextView) findViewById(R.id.searchDetailsText);
|
||||
|
@ -427,24 +304,58 @@ public class MainActivity extends Activity {
|
|||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
SearchListItem item = adapter.getItem(position);
|
||||
SearchObject searchObject = item.getSearchObject();
|
||||
SearchResult sr = item.getSearchResult();
|
||||
|
||||
if (sr.objectType == ObjectType.POI
|
||||
|| sr.objectType == ObjectType.LOCATION
|
||||
|| sr.objectType == ObjectType.HOUSE
|
||||
|| sr.objectType == ObjectType.FAVORITE
|
||||
|| sr.objectType == ObjectType.RECENT_OBJ
|
||||
|| sr.objectType == ObjectType.WPT
|
||||
|| sr.objectType == ObjectType.STREET_INTERSECTION) {
|
||||
|
||||
if (searchObject.getType() == SearchObjectType.POI
|
||||
|| searchObject.getType() == SearchObjectType.BUILDING
|
||||
|| searchObject.getType() == SearchObjectType.COORDINATES) {
|
||||
// show on map
|
||||
hideSearchList();
|
||||
mapView.requestFocus();
|
||||
showOnMap((SearchListPositionItem) item);
|
||||
} else {
|
||||
// complete search query with selected object
|
||||
completeQueryWithObject(item.getSearchObject());
|
||||
}
|
||||
completeQueryWithObject(item.getSearchResult());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void setupSearch() {
|
||||
final SampleApplication app = getSampleApplication();
|
||||
List<BinaryMapIndexReader> files = new ArrayList<>();
|
||||
File file = new File(app.getAbsoluteAppPath());
|
||||
if (file.exists() && file.listFiles() != null) {
|
||||
for (File obf : file.listFiles()) {
|
||||
if (!obf.isDirectory() && obf.getName().endsWith(".obf")) {
|
||||
try {
|
||||
BinaryMapIndexReader bmir = new BinaryMapIndexReader(new RandomAccessFile(obf, "r"), obf);
|
||||
files.add(bmir);
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchUICore = new SearchUICore(app.getPoiTypes(), LANGUAGE, files.toArray(new BinaryMapIndexReader[files.size()]));
|
||||
|
||||
searchUICore.setOnResultsComplete(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hideProgressBar();
|
||||
updateSearchResult(searchUICore.getCurrentSearchResult(), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
@ -471,11 +382,13 @@ public class MainActivity extends Activity {
|
|||
return (SampleApplication) getApplication();
|
||||
}
|
||||
|
||||
private void showOnMap(SearchListPositionItem positionItem) {
|
||||
private void showOnMap(LatLon latLon, int zoom) {
|
||||
if (latLon != null) {
|
||||
PointI target = Utilities.convertLatLonTo31(
|
||||
new LatLon(positionItem.getLatitude(), positionItem.getLongitude()));
|
||||
new net.osmand.core.jni.LatLon(latLon.getLatitude(), latLon.getLongitude()));
|
||||
setTarget(target);
|
||||
setZoom(17f);
|
||||
setZoom(zoom);
|
||||
}
|
||||
}
|
||||
|
||||
private PointI getScreenCenter31() {
|
||||
|
@ -484,14 +397,6 @@ public class MainActivity extends Activity {
|
|||
return point;
|
||||
}
|
||||
|
||||
private AreaI getScreenBounds31() {
|
||||
PointI topLeftPoint = new PointI();
|
||||
PointI bottomRightPoint = new PointI();
|
||||
mapView.getLocationFromScreenPoint(new PointI(0, 0), topLeftPoint);
|
||||
mapView.getLocationFromScreenPoint(new PointI(mapView.getWidth(), mapView.getHeight()), bottomRightPoint);
|
||||
return new AreaI(topLeftPoint, bottomRightPoint);
|
||||
}
|
||||
|
||||
private void showProgressBar() {
|
||||
searchIcon.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
@ -536,7 +441,7 @@ public class MainActivity extends Activity {
|
|||
public void saveMapState() {
|
||||
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
|
||||
Editor edit = prefs.edit();
|
||||
LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
net.osmand.core.jni.LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
edit.putFloat(PREF_MAP_CENTER_LAT, (float) latLon.getLatitude());
|
||||
edit.putFloat(PREF_MAP_CENTER_LON, (float) latLon.getLongitude());
|
||||
edit.putFloat(PREF_MAP_AZIMUTH, azimuth);
|
||||
|
@ -555,7 +460,7 @@ public class MainActivity extends Activity {
|
|||
|
||||
setAzimuth(prefAzimuth);
|
||||
setElevationAngle(prefElevationAngle);
|
||||
setTarget(Utilities.convertLatLonTo31(new LatLon(prefLat, prefLon)));
|
||||
setTarget(Utilities.convertLatLonTo31(new net.osmand.core.jni.LatLon(prefLat, prefLon)));
|
||||
setZoom(prefZoom);
|
||||
}
|
||||
|
||||
|
@ -604,37 +509,80 @@ public class MainActivity extends Activity {
|
|||
}
|
||||
|
||||
private void runSearch() {
|
||||
runSearch(getScreenCenter31(), getScreenBounds31(), queryText);
|
||||
runSearch(queryText);
|
||||
}
|
||||
|
||||
private void runSearch(PointI position31, AreaI bounds31, String keyword) {
|
||||
private void runSearch(String text) {
|
||||
|
||||
searchAPI.setSearchLocation31(position31);
|
||||
searchAPI.setObfAreaFilter(bounds31);
|
||||
searchAPI.startSearch(keyword, MAX_SEARCH_RESULTS_CORE,
|
||||
intermediateSearchCallback, coreSearchCallback);
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
if(settings.getRadiusLevel() != 1){
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(1));
|
||||
}
|
||||
searchUICore.search(text, null);
|
||||
SearchResultCollection c = searchUICore.search(text, null);
|
||||
updateSearchResult(c, false);
|
||||
}
|
||||
|
||||
private void completeQueryWithObject(SearchObject searchObject) {
|
||||
queryText = searchAPI.completeSearch(searchObject, MAX_SEARCH_RESULTS_CORE,
|
||||
intermediateSearchCallback, coreSearchCallback);
|
||||
searchEditText.setText(queryText);
|
||||
searchEditText.setSelection(queryText.length());
|
||||
private void completeQueryWithObject(SearchResult sr) {
|
||||
|
||||
if (sr.location != null) {
|
||||
showOnMap(sr.location, sr.preferredZoom);
|
||||
}
|
||||
searchUICore.selectSearchResult(sr);
|
||||
String txt = searchUICore.getPhrase().getText(true);
|
||||
queryText = txt;
|
||||
searchEditText.setText(txt);
|
||||
searchEditText.setSelection(txt.length());
|
||||
|
||||
searchUICore.search(txt, null);
|
||||
}
|
||||
|
||||
private void processSearchResult(List<SearchObject> searchObjects) {
|
||||
if (searchObjects != null) {
|
||||
private void updateSearchResult(SearchResultCollection res, boolean addMore) {
|
||||
|
||||
SampleApplication app = getSampleApplication();
|
||||
|
||||
if (res.getCurrentSearchResults().size() > 0) {
|
||||
List<SearchListItem> rows = new ArrayList<>();
|
||||
for (SearchObject item : searchObjects) {
|
||||
SearchListItem listItem =
|
||||
SearchListItem.buildListItem(getSampleApplication(), item);
|
||||
if (listItem != null) {
|
||||
for (final SearchResult sr : res.getCurrentSearchResults()) {
|
||||
|
||||
int count = 30;
|
||||
/*
|
||||
if(addMore) {
|
||||
JMenuItem mi = new JMenuItem();
|
||||
mi.setText("Results " + res.getCurrentSearchResults().size() + ", radius " + res.getPhrase().getRadiusLevel()+
|
||||
" (show more...)");
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(settings.getRadiusLevel() + 1));
|
||||
searchUICore.search(statusField.getText(), null);
|
||||
updateSearchResult(statusField, new SearchResultCollection(), false);
|
||||
}
|
||||
});
|
||||
popup.add(mi);
|
||||
}
|
||||
*/
|
||||
|
||||
count--;
|
||||
if (count == 0) {
|
||||
// break;
|
||||
}
|
||||
//LatLon location = res.getPhrase().getLastTokenLocation();
|
||||
//String locationString = "";
|
||||
//if (sr.location != null) {
|
||||
// locationString = ((int) MapUtils.getDistance(location, sr.location)) + " m";
|
||||
//}
|
||||
//mi.setText(sr.localeName + " [" + sr.objectType + "] " + locationString);
|
||||
|
||||
SearchListItem listItem = new SearchListItem(app, sr);
|
||||
if (sr.location != null) {
|
||||
LatLon location = res.getPhrase().getLastTokenLocation();
|
||||
listItem.setDistance(MapUtils.getDistance(location, sr.location));
|
||||
}
|
||||
rows.add(listItem);
|
||||
}
|
||||
}
|
||||
if (rows.size() > MAX_SEARCH_RESULTS_IU) {
|
||||
rows = rows.subList(0, MAX_SEARCH_RESULTS_IU);
|
||||
}
|
||||
updateListAdapter(rows);
|
||||
showSearchList();
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class MapUtils {
|
||||
|
||||
public static final String LANGUAGE;
|
||||
|
||||
static {
|
||||
LANGUAGE = getLanguage();
|
||||
}
|
||||
|
||||
public static float unifyRotationTo360(float rotate) {
|
||||
while (rotate < -180) {
|
||||
rotate += 360;
|
||||
}
|
||||
while (rotate > +180) {
|
||||
rotate -= 360;
|
||||
}
|
||||
return rotate;
|
||||
}
|
||||
|
||||
private static String getLanguage() {
|
||||
String langCode = Locale.getDefault().getLanguage();
|
||||
if (langCode.isEmpty()) {
|
||||
langCode = "en";
|
||||
}
|
||||
return langCode;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import android.graphics.PointF;
|
|||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class MultiTouchSupport {
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import net.osmand.CollatorStringMatcher;
|
||||
import net.osmand.StringMatcher;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiTypeSearchObject;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class PoiTypesHelper {
|
||||
|
||||
private SampleApplication app;
|
||||
|
||||
public PoiTypesHelper(SampleApplication app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public List<AbstractPoiType> findPoiTypes(String s) {
|
||||
List<AbstractPoiType> poiTypes = new ArrayList<>();
|
||||
if (Algorithms.isEmpty(s)) {
|
||||
poiTypes.addAll(app.getPoiTypes().getTopVisibleFilters());
|
||||
} else {
|
||||
List<AbstractPoiType> res = app.getPoiTypes().getAllTypesTranslatedNames(
|
||||
new CollatorStringMatcher(s, CollatorStringMatcher.StringMatcherMode.CHECK_STARTS_FROM_SPACE));
|
||||
final Collator inst = Collator.getInstance();
|
||||
Collections.sort(res, new Comparator<AbstractPoiType>() {
|
||||
@Override
|
||||
public int compare(AbstractPoiType lhs, AbstractPoiType rhs) {
|
||||
return inst.compare(lhs.getTranslation(), rhs.getTranslation());
|
||||
}
|
||||
|
||||
});
|
||||
for (AbstractPoiType p : res) {
|
||||
poiTypes.add(p);
|
||||
}
|
||||
}
|
||||
return poiTypes;
|
||||
}
|
||||
|
||||
public AbstractPoiType fetchPoiType(PoiTypeSearchObject poiTypeObject) {
|
||||
switch (poiTypeObject.getObjectType()) {
|
||||
case CATEGORY:
|
||||
return app.getPoiTypes().getPoiCategoryByName(poiTypeObject.getKeyName());
|
||||
case FILTER:
|
||||
PoiCategory category = app.getPoiTypes().getPoiCategoryByName(poiTypeObject.getCategoryKeyName());
|
||||
for (PoiFilter filter : category.getPoiFilters()) {
|
||||
if (filter.getKeyName().equalsIgnoreCase(poiTypeObject.getKeyName())) {
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE:
|
||||
AbstractPoiType p = app.getPoiTypes().getPoiTypeByKey(poiTypeObject.getKeyName());
|
||||
if(p == null) {
|
||||
return app.getPoiTypes().getAnyPoiAdditionalTypeByKey(poiTypeObject.getKeyName());
|
||||
}
|
||||
return p;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<AbstractPoiType> getPoiCategoryTypesTranslatedNames(PoiCategory pc, StringMatcher matcher) {
|
||||
List<AbstractPoiType> tm = new ArrayList<AbstractPoiType>();
|
||||
for (PoiFilter pt : pc.getPoiFilters()) {
|
||||
addIf(tm, pt, matcher);
|
||||
}
|
||||
for (PoiType pt : pc.getPoiTypes()) {
|
||||
if (pt.isReference()) {
|
||||
continue;
|
||||
}
|
||||
addIf(tm, pt, matcher);
|
||||
}
|
||||
|
||||
return tm;
|
||||
}
|
||||
|
||||
public List<AbstractPoiType> getPoiFilterTypesTranslatedNames(PoiFilter pf, StringMatcher matcher) {
|
||||
List<AbstractPoiType> tm = new ArrayList<AbstractPoiType>();
|
||||
for (PoiType pt : pf.getPoiTypes()) {
|
||||
if (pt.isReference()) {
|
||||
continue;
|
||||
}
|
||||
addIf(tm, pt, matcher);
|
||||
}
|
||||
|
||||
return tm;
|
||||
}
|
||||
|
||||
private void addIf(List<AbstractPoiType> tm, AbstractPoiType pc, StringMatcher matcher) {
|
||||
if (matcher.matches(pc.getTranslation()) || matcher.matches(pc.getKeyName().replace('_', ' '))) {
|
||||
tm.add(pc);
|
||||
}
|
||||
List<PoiType> additionals = pc.getPoiAdditionals();
|
||||
if (additionals != null) {
|
||||
for (PoiType a : additionals) {
|
||||
addIf(tm, a, matcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ package net.osmand.core.samples.android.sample1;
|
|||
|
||||
import android.app.Application;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
||||
import net.osmand.core.android.CoreResourcesFromAndroidAssets;
|
||||
import net.osmand.core.android.NativeCore;
|
||||
|
@ -17,16 +19,16 @@ public class SampleApplication extends Application
|
|||
{
|
||||
private CoreResourcesFromAndroidAssets assetsCustom;
|
||||
private MapPoiTypes poiTypes;
|
||||
private PoiTypesHelper poiTypesHelper;
|
||||
private IconsCache iconsCache;
|
||||
Handler uiHandler;
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
uiHandler = new Handler();
|
||||
|
||||
initPoiTypes();
|
||||
poiTypesHelper = new PoiTypesHelper(this);
|
||||
|
||||
// Initialize native core
|
||||
if (NativeCore.isAvailable() && !NativeCore.isLoaded()) {
|
||||
|
@ -42,10 +44,6 @@ public class SampleApplication extends Application
|
|||
return poiTypes;
|
||||
}
|
||||
|
||||
public PoiTypesHelper getPoiTypesHelper() {
|
||||
return poiTypesHelper;
|
||||
}
|
||||
|
||||
public IconsCache getIconsCache() {
|
||||
return iconsCache;
|
||||
}
|
||||
|
@ -97,4 +95,12 @@ public class SampleApplication extends Application
|
|||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public void runInUIThread(Runnable run) {
|
||||
uiHandler.post(run);
|
||||
}
|
||||
|
||||
public void runInUIThread(Runnable run, long delay) {
|
||||
uiHandler.postDelayed(run, delay);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static String getFormattedDistance(double meters) {
|
||||
double mainUnitInMeters = 1000;
|
||||
String mainUnitStr = "km";
|
||||
if (meters >= 100 * mainUnitInMeters) {
|
||||
return (int) (meters / mainUnitInMeters + 0.5) + " " + mainUnitStr;
|
||||
} else if (meters > 9.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.#} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else if (meters > 0.999f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.##} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else {
|
||||
return ((int) (meters + 0.5)) + " m";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.adapters;
|
||||
|
||||
import net.osmand.core.jni.Building;
|
||||
import net.osmand.core.jni.Street;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
import net.osmand.core.samples.android.sample1.MapUtils;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.BuildingSearchObject;
|
||||
|
||||
public class BuildingSearchListItem extends SearchListPositionItem {
|
||||
private String nameStr;
|
||||
private String typeStr;
|
||||
|
||||
public BuildingSearchListItem(SampleApplication app, BuildingSearchObject buildingObject) {
|
||||
super(app, buildingObject);
|
||||
|
||||
nameStr = buildingObject.getName(MapUtils.LANGUAGE);
|
||||
|
||||
Building building = buildingObject.getBaseObject();
|
||||
|
||||
Street street = building.getStreet();
|
||||
if (street != null) {
|
||||
StreetGroup streetGroup = street.getStreetGroup();
|
||||
if (streetGroup != null) {
|
||||
typeStr = streetGroup.getNativeName() + ", " + street.getNativeName();
|
||||
} else {
|
||||
typeStr = street.getNativeName();
|
||||
}
|
||||
} else {
|
||||
typeStr = "Building";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return nameStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeStr;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
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.objects.CitySearchObject;
|
||||
|
||||
public class CitySearchListItem extends SearchListPositionItem{
|
||||
|
||||
private String nameStr;
|
||||
private String typeStr;
|
||||
|
||||
public CitySearchListItem(SampleApplication app, CitySearchObject cityObject) {
|
||||
super(app, cityObject);
|
||||
|
||||
nameStr = cityObject.getName(MapUtils.LANGUAGE);
|
||||
typeStr = "City";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return nameStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeStr;
|
||||
}
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.adapters;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.core.jni.Amenity.DecodedCategory;
|
||||
import net.osmand.core.jni.Amenity.DecodedValue;
|
||||
import net.osmand.core.jni.DecodedCategoryList;
|
||||
import net.osmand.core.jni.DecodedValueList;
|
||||
import net.osmand.core.jni.QStringList;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
import net.osmand.core.samples.android.sample1.MapUtils;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiSearchObject;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PoiSearchListItem extends SearchListPositionItem {
|
||||
|
||||
private Amenity amenity;
|
||||
private String nameStr;
|
||||
private String typeStr;
|
||||
|
||||
public PoiSearchListItem(SampleApplication app, PoiSearchObject poiObject) {
|
||||
super(app, poiObject);
|
||||
amenity = parseAmenity(poiObject);
|
||||
nameStr = amenity.getName(MapUtils.LANGUAGE);
|
||||
typeStr = getTypeStr();
|
||||
}
|
||||
|
||||
private Amenity parseAmenity(PoiSearchObject poiObject) {
|
||||
|
||||
String categoryName = "";
|
||||
String subcategoryName = "";
|
||||
Map<String, String> values = new HashMap<>();
|
||||
|
||||
net.osmand.core.jni.Amenity coreAmenity = poiObject.getBaseObject();
|
||||
DecodedCategoryList catList = coreAmenity.getDecodedCategories();
|
||||
if (catList.size() > 0) {
|
||||
DecodedCategory decodedCategory = catList.get(0);
|
||||
categoryName = decodedCategory.getCategory();
|
||||
subcategoryName = decodedCategory.getSubcategory();
|
||||
}
|
||||
|
||||
DecodedValueList decodedValueList = coreAmenity.getDecodedValues();
|
||||
if (decodedValueList.size() > 0) {
|
||||
for (int i = 0; i < decodedValueList.size(); i++) {
|
||||
DecodedValue decodedValue = decodedValueList.get(i);
|
||||
String tag = decodedValue.getDeclaration().getTagName();
|
||||
String value = decodedValue.getValue();
|
||||
values.put(tag, value);
|
||||
}
|
||||
}
|
||||
|
||||
MapPoiTypes poiTypes = app.getPoiTypes();
|
||||
|
||||
Amenity a = new Amenity();
|
||||
PoiCategory category = poiTypes.getPoiCategoryByName(categoryName);
|
||||
a.setType(category);
|
||||
a.setSubType(subcategoryName);
|
||||
a.setName(poiObject.getNativeName());
|
||||
|
||||
QStringStringHash localizedNamesMap = coreAmenity.getLocalizedNames();
|
||||
QStringList locNamesKeys = localizedNamesMap.keys();
|
||||
for (int i = 0; i < locNamesKeys.size(); i++) {
|
||||
String key = locNamesKeys.get(i);
|
||||
String val = localizedNamesMap.get(key);
|
||||
a.setName(key, val);
|
||||
}
|
||||
|
||||
a.setAdditionalInfo(values);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
public Amenity getAmenity() {
|
||||
return amenity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return nameStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeStr;
|
||||
}
|
||||
|
||||
private String getTypeStr() {
|
||||
/*
|
||||
PoiCategory pc = amenity.getTypeName();
|
||||
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
|
||||
String typeStr = amenity.getSubType();
|
||||
if (pt != null) {
|
||||
typeStr = pt.getTranslation();
|
||||
} else if (typeStr != null) {
|
||||
typeStr = Algorithms.capitalizeFirstLetterAndLowercase(typeStr.replace('_', ' '));
|
||||
}
|
||||
return typeStr;
|
||||
*/
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(amenity.getSubType().replace('_', ' '));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
Drawable drawable = null;
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
drawable = app.getIconsCache().getMapIcon(st.getOsmTag() + "_" + st.getOsmValue());
|
||||
}
|
||||
return drawable;
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
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.objects.PoiTypeSearchObject;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
|
||||
public class PoiTypeSearchListItem extends SearchListItem {
|
||||
|
||||
private AbstractPoiType poiType;
|
||||
private String typeName;
|
||||
|
||||
public PoiTypeSearchListItem(SampleApplication app, PoiTypeSearchObject poiTypeObject) {
|
||||
super(app, poiTypeObject);
|
||||
|
||||
poiType = app.getPoiTypesHelper().fetchPoiType(poiTypeObject);
|
||||
if (poiType != null) {
|
||||
if (poiType instanceof PoiCategory) {
|
||||
typeName = "Category";
|
||||
} else if (poiType instanceof PoiFilter) {
|
||||
PoiFilter filter = (PoiFilter) poiType;
|
||||
if (filter.getPoiCategory() != null) {
|
||||
typeName = ((PoiFilter) poiType).getPoiCategory().getTranslation();
|
||||
} else {
|
||||
typeName = "Filter";
|
||||
}
|
||||
} else if (poiType instanceof PoiType) {
|
||||
PoiType type = (PoiType) poiType;
|
||||
if (type.getCategory() != null) {
|
||||
typeName = type.getCategory().getTranslation();
|
||||
} else if (type.getParentType() != null) {
|
||||
typeName = type.getTranslation();
|
||||
}
|
||||
} else {
|
||||
typeName = "Poi type";
|
||||
}
|
||||
} else {
|
||||
typeName = poiTypeObject.getObjectType().name();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return poiType != null ? poiType.getTranslation() : "Unresolved";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
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.objects.CitySearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PostcodeSearchObject;
|
||||
|
||||
public class PostcodeSearchListItem extends SearchListPositionItem {
|
||||
|
||||
private String nameStr;
|
||||
private String typeStr;
|
||||
|
||||
public PostcodeSearchListItem(SampleApplication app, PostcodeSearchObject postcodeObject) {
|
||||
super(app, postcodeObject);
|
||||
|
||||
nameStr = postcodeObject.getNativeName();
|
||||
typeStr = "Postcode";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return nameStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeStr;
|
||||
}
|
||||
}
|
|
@ -9,15 +9,17 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.core.jni.Utilities;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.Utils;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.example.core.SearchResult;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
||||
|
||||
private Context ctx;
|
||||
private LatLon location;
|
||||
|
||||
public SearchListAdapter(Context ctx) {
|
||||
super(ctx, R.layout.search_list_item);
|
||||
|
@ -32,12 +34,21 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
|||
notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
public LatLon getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(LatLon location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchListItem getItem(int position) {
|
||||
return super.getItem(position);
|
||||
}
|
||||
|
||||
public void updateDistance(double latitude, double longitude) {
|
||||
/*
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
SearchListItem item = getItem(i);
|
||||
if (item instanceof SearchListPositionItem) {
|
||||
|
@ -46,6 +57,7 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
|||
longitude, latitude, positionItem.getLongitude(), positionItem.getLatitude()));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,12 +82,12 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
|||
imageView.setImageDrawable(listItem.getIcon());
|
||||
title.setText(listItem.getName());
|
||||
subtitle.setText(listItem.getTypeName());
|
||||
if (listItem instanceof SearchListPositionItem) {
|
||||
SearchListPositionItem positionItem = (SearchListPositionItem) listItem;
|
||||
if (positionItem.getDistance() == 0) {
|
||||
if (location != null && listItem.getSearchResult().location != null) {
|
||||
double dist = listItem.getDistance();
|
||||
if (dist == 0) {
|
||||
distance.setText("");
|
||||
} else {
|
||||
distance.setText(Utils.getFormattedDistance(positionItem.getDistance()));
|
||||
distance.setText(getFormattedDistance(dist));
|
||||
}
|
||||
distance.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
|
@ -84,4 +96,17 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
|||
return view;
|
||||
}
|
||||
|
||||
public static String getFormattedDistance(double meters) {
|
||||
double mainUnitInMeters = 1000;
|
||||
String mainUnitStr = "km";
|
||||
if (meters >= 100 * mainUnitInMeters) {
|
||||
return (int) (meters / mainUnitInMeters + 0.5) + " " + mainUnitStr;
|
||||
} else if (meters > 9.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.#} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else if (meters > 0.999f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.##} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else {
|
||||
return ((int) (meters + 0.5)) + " m";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,62 +3,40 @@ 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.objects.BuildingSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.CitySearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiTypeSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PostcodeSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetIntersectionSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.VillageSearchObject;
|
||||
import net.osmand.search.example.core.SearchResult;
|
||||
|
||||
public class SearchListItem {
|
||||
|
||||
protected SampleApplication app;
|
||||
private SearchObject searchObject;
|
||||
private SearchResult searchResult;
|
||||
private double distance;
|
||||
|
||||
public SearchListItem(SampleApplication app, SearchObject searchObject) {
|
||||
public SearchListItem(SampleApplication app, SearchResult searchResult) {
|
||||
this.app = app;
|
||||
this.searchObject = searchObject;
|
||||
this.searchResult = searchResult;
|
||||
}
|
||||
|
||||
public static SearchListItem buildListItem(SampleApplication app, SearchObject searchObject) {
|
||||
switch (searchObject.getType()) {
|
||||
case POI_TYPE:
|
||||
return new PoiTypeSearchListItem(app, (PoiTypeSearchObject) searchObject);
|
||||
case POI:
|
||||
return new PoiSearchListItem(app, (PoiSearchObject) searchObject);
|
||||
case BUILDING:
|
||||
return new BuildingSearchListItem(app, (BuildingSearchObject) searchObject);
|
||||
case STREET_INTERSECTION:
|
||||
return new StreetIntersectionSearchListItem(app, (StreetIntersectionSearchObject) searchObject);
|
||||
case STREET:
|
||||
return new StreetSearchListItem(app, (StreetSearchObject) searchObject);
|
||||
case CITY:
|
||||
return new CitySearchListItem(app, (CitySearchObject) searchObject);
|
||||
case VILLAGE:
|
||||
return new VillageSearchListItem(app, (VillageSearchObject) searchObject);
|
||||
case POSTCODE:
|
||||
return new PostcodeSearchListItem(app, (PostcodeSearchObject) searchObject);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public SearchObject getSearchObject() {
|
||||
return searchObject;
|
||||
public SearchResult getSearchResult() {
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return searchObject.getNativeName();
|
||||
return searchResult.localeName;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return searchObject.getType().name();
|
||||
return searchResult.objectType.name();
|
||||
}
|
||||
|
||||
public Drawable getIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.adapters;
|
||||
|
||||
import net.osmand.core.jni.LatLon;
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.Utilities;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchPositionObject;
|
||||
|
||||
public class SearchListPositionItem extends SearchListItem {
|
||||
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
|
||||
public SearchListPositionItem(SampleApplication app, SearchPositionObject positionObject) {
|
||||
super(app, positionObject);
|
||||
PointI position31 = positionObject.getPosition31();
|
||||
LatLon latLon = Utilities.convert31ToLatLon(position31);
|
||||
latitude = latLon.getLatitude();
|
||||
longitude = latLon.getLongitude();
|
||||
}
|
||||
|
||||
public SearchPositionObject getSearchPositionObject() {
|
||||
return (SearchPositionObject) getSearchObject();
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return getSearchPositionObject().getDistance();
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
getSearchPositionObject().setDistance(distance);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.adapters;
|
||||
|
||||
import net.osmand.core.jni.Street;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
import net.osmand.core.jni.StreetIntersection;
|
||||
import net.osmand.core.samples.android.sample1.MapUtils;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetIntersectionSearchObject;
|
||||
|
||||
public class StreetIntersectionSearchListItem extends SearchListPositionItem {
|
||||
private String nameStr;
|
||||
private String typeStr;
|
||||
|
||||
public StreetIntersectionSearchListItem(SampleApplication app, StreetIntersectionSearchObject intersectionObject) {
|
||||
super(app, intersectionObject);
|
||||
|
||||
nameStr = intersectionObject.getName(MapUtils.LANGUAGE);
|
||||
|
||||
StreetIntersection streetIntersection = intersectionObject.getBaseObject();
|
||||
|
||||
Street street = streetIntersection.getStreet();
|
||||
if (street != null) {
|
||||
StreetGroup streetGroup = street.getStreetGroup();
|
||||
if (streetGroup != null) {
|
||||
typeStr = streetGroup.getNativeName() + ", " + street.getNativeName();
|
||||
} else {
|
||||
typeStr = street.getNativeName();
|
||||
}
|
||||
} else {
|
||||
typeStr = "Street intersection";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return nameStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeStr;
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.adapters;
|
||||
|
||||
import net.osmand.core.jni.ObfAddressStreetGroupSubtype;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
import net.osmand.core.samples.android.sample1.MapUtils;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetSearchObject;
|
||||
|
||||
public class StreetSearchListItem extends SearchListPositionItem {
|
||||
private String nameStr;
|
||||
private String typeStr;
|
||||
|
||||
public StreetSearchListItem(SampleApplication app, StreetSearchObject streetObject) {
|
||||
super(app, streetObject);
|
||||
|
||||
nameStr = streetObject.getName(MapUtils.LANGUAGE);
|
||||
|
||||
StreetGroup streetGroup = streetObject.getBaseObject().getStreetGroup();
|
||||
if (streetGroup != null) {
|
||||
typeStr = streetGroup.getNativeName() + " — " + getTypeStr(streetGroup);
|
||||
} else {
|
||||
typeStr = "Street";
|
||||
}
|
||||
}
|
||||
|
||||
private String getTypeStr(StreetGroup streetGroup) {
|
||||
String typeStr;
|
||||
if (streetGroup.getSubtype() != ObfAddressStreetGroupSubtype.Unknown) {
|
||||
typeStr = streetGroup.getSubtype().name();
|
||||
} else {
|
||||
typeStr = streetGroup.getType().name();
|
||||
}
|
||||
return typeStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return nameStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeStr;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
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.objects.VillageSearchObject;
|
||||
|
||||
public class VillageSearchListItem extends SearchListPositionItem{
|
||||
|
||||
private String nameStr;
|
||||
private String typeStr;
|
||||
|
||||
public VillageSearchListItem(SampleApplication app, VillageSearchObject villageObject) {
|
||||
super(app, villageObject);
|
||||
|
||||
nameStr = villageObject.getName(MapUtils.LANGUAGE);
|
||||
typeStr = "Village";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return nameStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return typeStr;
|
||||
}
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.osmand.core.jni.AreaI;
|
||||
import net.osmand.core.jni.ObfsCollection;
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject.SearchObjectType;
|
||||
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 net.osmand.core.samples.android.sample1.search.tokens.ObjectSearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SearchAPI {
|
||||
|
||||
private ObfsCollection obfsCollection;
|
||||
private AreaI searchableArea;
|
||||
private AreaI obfAreaFilter;
|
||||
private PointI searchLocation31;
|
||||
private double searchRadius;
|
||||
private String lang;
|
||||
|
||||
private SearchRequestExecutor executor;
|
||||
private SearchString searchString;
|
||||
private List<SearchObject> searchObjects;
|
||||
|
||||
private SearchCallbackInternal internalCallback = new SearchCallbackInternal() {
|
||||
@Override
|
||||
public void onSearchObjectsFound(List<SearchObject> searchObjects) {
|
||||
setSearchObjects(searchObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewTokenFound(SearchToken oldToken, SearchToken newToken) {
|
||||
searchString.replaceToken(oldToken, newToken);
|
||||
}
|
||||
};
|
||||
|
||||
public interface SearchApiCallback {
|
||||
|
||||
@Nullable
|
||||
List<SearchObject> fetchExternalObjects(String keyword, @Nullable List<SearchObject> completeObjects);
|
||||
|
||||
void onSearchFinished(List<SearchObject> searchObjects);
|
||||
}
|
||||
|
||||
public interface SearchCallbackInternal {
|
||||
void onSearchObjectsFound(List<SearchObject> searchObjects);
|
||||
void onNewTokenFound(SearchToken oldToken, SearchToken newToken);
|
||||
}
|
||||
|
||||
public SearchAPI(@NonNull ObfsCollection obfsCollection, String lang) {
|
||||
this.obfsCollection = obfsCollection;
|
||||
this.executor = new SearchRequestExecutor();
|
||||
this.searchString = new SearchString(lang);
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public AreaI getSearchableArea() {
|
||||
return searchableArea;
|
||||
}
|
||||
|
||||
public void setSearchableArea(AreaI searchableArea) {
|
||||
this.searchableArea = searchableArea;
|
||||
}
|
||||
|
||||
public AreaI getObfAreaFilter() {
|
||||
return obfAreaFilter;
|
||||
}
|
||||
|
||||
public void setObfAreaFilter(AreaI obfAreaFilter) {
|
||||
this.obfAreaFilter = obfAreaFilter;
|
||||
}
|
||||
|
||||
public PointI getSearchLocation31() {
|
||||
return searchLocation31;
|
||||
}
|
||||
|
||||
public void setSearchLocation31(PointI position31) {
|
||||
this.searchLocation31 = position31;
|
||||
}
|
||||
|
||||
public double getSearchRadius() {
|
||||
return searchRadius;
|
||||
}
|
||||
|
||||
public void setSearchRadius(double searchRadius) {
|
||||
this.searchRadius = searchRadius;
|
||||
}
|
||||
|
||||
public ObfsCollection getObfsCollection() {
|
||||
return obfsCollection;
|
||||
}
|
||||
|
||||
public SearchString getSearchStringCopy() {
|
||||
return searchString.copy();
|
||||
}
|
||||
|
||||
public List<SearchObject> getSearchObjects() {
|
||||
return searchObjects;
|
||||
}
|
||||
|
||||
public void setSearchObjects(List<SearchObject> searchObjects) {
|
||||
this.searchObjects = searchObjects;
|
||||
}
|
||||
|
||||
public Map<SearchObjectType, ObjectSearchToken> getObjectTokens() {
|
||||
return searchString.getCompleteObjectTokens();
|
||||
}
|
||||
|
||||
public ObjectSearchToken getLastObjectToken() {
|
||||
return searchString.getLastObjectToken();
|
||||
}
|
||||
|
||||
public void startSearch(String query, int maxSearchResults,
|
||||
SearchApiCallback intermediateSearchCallback,
|
||||
SearchApiCallback coreSearchCallback) {
|
||||
|
||||
searchString.setPlainText(query);
|
||||
startSearchInternal(maxSearchResults, intermediateSearchCallback, coreSearchCallback);
|
||||
}
|
||||
|
||||
public String completeSearch(SearchObject searchObject, int maxSearchResults,
|
||||
SearchApiCallback intermediateSearchCallback,
|
||||
SearchApiCallback coreSearchCallback) {
|
||||
|
||||
searchString.completeQuery(searchObject);
|
||||
startSearchInternal(maxSearchResults, intermediateSearchCallback, coreSearchCallback);
|
||||
return searchString.getPlainText();
|
||||
}
|
||||
|
||||
private void startSearchInternal(int maxSearchResults,
|
||||
SearchApiCallback intermediateSearchCallback,
|
||||
SearchApiCallback coreSearchCallback) {
|
||||
|
||||
SearchScope searchScope = new SearchScope(this);
|
||||
IntermediateSearchRequest intermediateSearchRequest = null;
|
||||
if (searchObjects != null && !searchObjects.isEmpty()) {
|
||||
intermediateSearchRequest =
|
||||
new IntermediateSearchRequest(searchScope, new ArrayList<>(searchObjects),
|
||||
maxSearchResults, intermediateSearchCallback);
|
||||
}
|
||||
executor.run(new CoreSearchRequest(intermediateSearchRequest, searchScope,
|
||||
maxSearchResults, coreSearchCallback, internalCallback), true);
|
||||
}
|
||||
|
||||
public void cancelSearch() {
|
||||
executor.cancel();
|
||||
}
|
||||
|
||||
|
||||
public class SearchRequestExecutor {
|
||||
|
||||
private SearchRequest ongoingSearchRequest;
|
||||
private SearchRequest nextSearchRequest;
|
||||
|
||||
public void run(SearchRequest searchRequest, boolean cancelCurrentRequest) {
|
||||
if (ongoingSearchRequest != null) {
|
||||
nextSearchRequest = searchRequest;
|
||||
if (cancelCurrentRequest) {
|
||||
ongoingSearchRequest.cancel();
|
||||
}
|
||||
} else {
|
||||
ongoingSearchRequest = searchRequest;
|
||||
nextSearchRequest = null;
|
||||
searchRequest.setOnFinishedCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
operationFinished();
|
||||
}
|
||||
});
|
||||
searchRequest.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (nextSearchRequest != null) {
|
||||
nextSearchRequest = null;
|
||||
}
|
||||
if (ongoingSearchRequest != null) {
|
||||
ongoingSearchRequest.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void operationFinished() {
|
||||
ongoingSearchRequest = null;
|
||||
if (nextSearchRequest != null) {
|
||||
run(nextSearchRequest, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import net.osmand.core.jni.Address;
|
||||
import net.osmand.core.jni.Building;
|
||||
import net.osmand.core.jni.OsmAndCoreJNI;
|
||||
import net.osmand.core.jni.Street;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
import net.osmand.core.jni.StreetIntersection;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.BuildingSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.CitySearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PostcodeSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchPositionObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetIntersectionSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.VillageSearchObject;
|
||||
|
||||
public class SearchObjectsHelper {
|
||||
|
||||
public static SearchPositionObject getAddressObject(Address address) {
|
||||
|
||||
switch (address.getAddressType()) {
|
||||
case Building:
|
||||
BuildingInternal building = new BuildingInternal(address);
|
||||
return new BuildingSearchObject(building);
|
||||
|
||||
case StreetIntersection:
|
||||
StreetIntercestionInternal streetIntersection = new StreetIntercestionInternal(address);
|
||||
return new StreetIntersectionSearchObject(streetIntersection);
|
||||
|
||||
case Street:
|
||||
StreetInternal street = new StreetInternal(address);
|
||||
return new StreetSearchObject(street);
|
||||
|
||||
case StreetGroup:
|
||||
StreetGroupInternal streetGroup = new StreetGroupInternal(address);
|
||||
switch (streetGroup.getType()) {
|
||||
case CityOrTown:
|
||||
return new CitySearchObject(streetGroup);
|
||||
case Village:
|
||||
return new VillageSearchObject(streetGroup);
|
||||
case Postcode:
|
||||
return new PostcodeSearchObject(streetGroup);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class BuildingInternal extends Building {
|
||||
public BuildingInternal(Address address) {
|
||||
super(OsmAndCoreJNI.Street_SWIGSmartPtrUpcast(Address.getCPtr(address)), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StreetIntercestionInternal extends StreetIntersection {
|
||||
public StreetIntercestionInternal(Address address) {
|
||||
super(OsmAndCoreJNI.Street_SWIGSmartPtrUpcast(Address.getCPtr(address)), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StreetInternal extends Street {
|
||||
public StreetInternal(Address address) {
|
||||
super(OsmAndCoreJNI.Street_SWIGSmartPtrUpcast(Address.getCPtr(address)), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StreetGroupInternal extends StreetGroup {
|
||||
public StreetGroupInternal(Address address) {
|
||||
super(OsmAndCoreJNI.StreetGroup_SWIGSmartPtrUpcast(Address.getCPtr(address)), false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,276 +0,0 @@
|
|||
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.AreaI;
|
||||
import net.osmand.core.jni.ObfAddressStreetGroupSubtype;
|
||||
import net.osmand.core.jni.ObfAddressStreetGroupType;
|
||||
import net.osmand.core.jni.ObfsCollection;
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringListHash;
|
||||
import net.osmand.core.jni.Street;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
import net.osmand.core.jni.Utilities;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PoiTypeSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.PostcodeSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject.SearchObjectType;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchPositionObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetGroupSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.StreetSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.ObjectSearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SearchScope {
|
||||
|
||||
private ObfsCollection obfsCollection;
|
||||
private SearchString searchString;
|
||||
private String lang;
|
||||
private Map<SearchObjectType, ObjectSearchToken> objectTokens;
|
||||
private PointI searchLocation31;
|
||||
private AreaI searchableArea;
|
||||
private AreaI obfAreaFilter;
|
||||
private double searchRadius;
|
||||
boolean citySelected;
|
||||
boolean poiTypeSelected;
|
||||
|
||||
private int resultLimitPoiByName = 25;
|
||||
private int poiByNameCounter = 0;
|
||||
private int resultLimitCityByName = 25;
|
||||
private int cityByNameCounter = 0;
|
||||
private int resultLimitStreetByName = 50;
|
||||
private int streetByNameCounter = 0;
|
||||
|
||||
public SearchScope(SearchAPI searchAPI) {
|
||||
obfsCollection = searchAPI.getObfsCollection();
|
||||
lang = searchAPI.getLang();
|
||||
searchString = searchAPI.getSearchStringCopy();
|
||||
searchLocation31 = searchAPI.getSearchLocation31();
|
||||
searchableArea = searchAPI.getSearchableArea();
|
||||
obfAreaFilter = searchAPI.getObfAreaFilter();
|
||||
searchRadius = searchAPI.getSearchRadius();
|
||||
updateScope();
|
||||
}
|
||||
|
||||
public void updateScope() {
|
||||
objectTokens = searchString.getCompleteObjectTokens();
|
||||
citySelected = objectTokens.containsKey(SearchObjectType.CITY)
|
||||
|| objectTokens.containsKey(SearchObjectType.VILLAGE)
|
||||
|| objectTokens.containsKey(SearchObjectType.POSTCODE)
|
||||
|| objectTokens.containsKey(SearchObjectType.STREET);
|
||||
poiTypeSelected = objectTokens.containsKey(SearchObjectType.POI_TYPE);
|
||||
}
|
||||
|
||||
public ObfsCollection getObfsCollection() {
|
||||
return obfsCollection;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public SearchString getSearchString() {
|
||||
return searchString;
|
||||
}
|
||||
|
||||
public PointI getSearchLocation31() {
|
||||
return searchLocation31;
|
||||
}
|
||||
|
||||
public AreaI getSearchableArea() {
|
||||
return searchableArea;
|
||||
}
|
||||
|
||||
public AreaI getObfAreaFilter() {
|
||||
return obfAreaFilter;
|
||||
}
|
||||
|
||||
public double getSearchRadius() {
|
||||
return searchRadius;
|
||||
}
|
||||
|
||||
public void setupAmenitySearchCriteria(AmenitiesByNameSearch.Criteria criteria) {
|
||||
if (objectTokens.containsKey(SearchObjectType.POI_TYPE)) {
|
||||
PoiTypeSearchObject searchObject =
|
||||
(PoiTypeSearchObject) objectTokens.get(SearchObjectType.POI_TYPE).getSearchObject();
|
||||
QStringStringListHash filter = new QStringStringListHash();
|
||||
// todo SWIG!!! filter.set(searchObject.getCategoryKeyName(), new QStringList(searchObject.getKeyName()));
|
||||
criteria.setCategoriesFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
public void setupAddressSearchCriteria(AddressesByNameSearch.Criteria criteria) {
|
||||
if (objectTokens.containsKey(SearchObjectType.STREET)) {
|
||||
StreetSearchObject streetSearchObject =
|
||||
(StreetSearchObject) objectTokens.get(SearchObjectType.STREET).getSearchObject();
|
||||
criteria.setAddressFilter(streetSearchObject.getBaseObject());
|
||||
if (objectTokens.containsKey(SearchObjectType.POSTCODE)) {
|
||||
PostcodeSearchObject postcodeSearchObject =
|
||||
(PostcodeSearchObject) objectTokens.get(SearchObjectType.POSTCODE).getSearchObject();
|
||||
criteria.setPostcode(postcodeSearchObject.getNativeName());
|
||||
}
|
||||
} else if (objectTokens.containsKey(SearchObjectType.CITY)) {
|
||||
criteria.setAddressFilter(((StreetGroupSearchObject) objectTokens.get(SearchObjectType.CITY)
|
||||
.getSearchObject()).getBaseObject());
|
||||
} else if (objectTokens.containsKey(SearchObjectType.VILLAGE)) {
|
||||
criteria.setAddressFilter(((StreetGroupSearchObject) objectTokens.get(SearchObjectType.VILLAGE)
|
||||
.getSearchObject()).getBaseObject());
|
||||
} else if (objectTokens.containsKey(SearchObjectType.POSTCODE)) {
|
||||
criteria.setAddressFilter(((StreetGroupSearchObject) objectTokens.get(SearchObjectType.POSTCODE)
|
||||
.getSearchObject()).getBaseObject());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean processPoiSearchObject(PoiSearchObject poiSearchObject) {
|
||||
updateDistance(poiSearchObject);
|
||||
return processSearchObject(poiSearchObject);
|
||||
}
|
||||
|
||||
public boolean processAddressSearchObject(SearchPositionObject addressSearchObject) {
|
||||
updateDistance(addressSearchObject);
|
||||
return processSearchObject(addressSearchObject);
|
||||
}
|
||||
|
||||
public SearchToken processSearchResult(SearchToken token, List<SearchObject> searchObjects) {
|
||||
|
||||
SearchToken newToken = null;
|
||||
if (searchObjects.size() > 0) {
|
||||
Collections.sort(searchObjects, new Comparator<SearchObject>() {
|
||||
@Override
|
||||
public int compare(SearchObject lhs, SearchObject rhs) {
|
||||
int res = Double.compare(lhs.getPriority(), rhs.getPriority());
|
||||
if (res == 0) {
|
||||
return lhs.getName(lang).compareToIgnoreCase(rhs.getName(lang));
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Iterator<SearchObject> it = searchObjects.iterator();
|
||||
while (it.hasNext()) {
|
||||
SearchObject searchObject = it.next();
|
||||
boolean accept;
|
||||
switch (searchObject.getType()) {
|
||||
case POI:
|
||||
accept = poiByNameCounter < resultLimitPoiByName;
|
||||
if (accept) {
|
||||
poiByNameCounter++;
|
||||
}
|
||||
break;
|
||||
case CITY:
|
||||
case VILLAGE:
|
||||
case POSTCODE:
|
||||
accept = cityByNameCounter < resultLimitCityByName;
|
||||
if (accept) {
|
||||
cityByNameCounter++;
|
||||
}
|
||||
break;
|
||||
|
||||
case STREET:
|
||||
accept = streetByNameCounter < resultLimitStreetByName;
|
||||
if (accept) {
|
||||
streetByNameCounter++;
|
||||
}
|
||||
default:
|
||||
accept = true;
|
||||
break;
|
||||
}
|
||||
if (!accept) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (token.getType() == SearchToken.TokenType.NAME_FILTER
|
||||
&& !token.hasEmptyQuery()) {
|
||||
boolean suggeston = token == searchString.getLastToken();
|
||||
newToken = new ObjectSearchToken(token, searchObjects.get(0), suggeston);
|
||||
searchString.replaceToken(token, newToken);
|
||||
}
|
||||
}
|
||||
return newToken;
|
||||
}
|
||||
|
||||
private boolean processSearchObject(SearchObject searchObject) {
|
||||
double priority = 0.0;
|
||||
switch (searchObject.getType()) {
|
||||
case BUILDING:
|
||||
priority = 3.0;
|
||||
break;
|
||||
case POI_TYPE:
|
||||
priority = poiTypeSelected ? 10.0 : 9.0;
|
||||
break;
|
||||
case POI:
|
||||
priority = getPriorityByDistance(10.0, ((PoiSearchObject) searchObject).getDistance());
|
||||
break;
|
||||
case CITY:
|
||||
case VILLAGE:
|
||||
case POSTCODE:
|
||||
double cityType = getCityType((StreetGroupSearchObject) searchObject);
|
||||
priority = (getPriorityByDistance(citySelected
|
||||
? 20.0 : 7.0 + cityType, ((StreetGroupSearchObject) searchObject).getDistance()));
|
||||
break;
|
||||
|
||||
case STREET:
|
||||
StreetSearchObject streetSearchObject = (StreetSearchObject) searchObject;
|
||||
Street street = streetSearchObject.getBaseObject();
|
||||
if (!citySelected) {
|
||||
priority = getPriorityByDistance(9.0, streetSearchObject.getDistance());
|
||||
} else {
|
||||
boolean streetFromSelectedCity = false;
|
||||
for (ObjectSearchToken st : objectTokens.values()) {
|
||||
if (st.getSearchObject() instanceof StreetGroupSearchObject) {
|
||||
StreetGroup streetGroup =
|
||||
((StreetGroupSearchObject) st.getSearchObject()).getBaseObject();
|
||||
if (streetGroup.getId().getId().equals(street.getStreetGroup().getId().getId())) {
|
||||
streetFromSelectedCity = true;
|
||||
break;
|
||||
}
|
||||
} else if (st.getSearchObject() instanceof StreetSearchObject) {
|
||||
StreetGroup streetGroup =
|
||||
((StreetSearchObject) st.getSearchObject()).getBaseObject().getStreetGroup();
|
||||
if (streetGroup.getId().getId().equals(street.getStreetGroup().getId().getId())) {
|
||||
streetFromSelectedCity = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (streetFromSelectedCity) {
|
||||
priority = 3.0;
|
||||
} else {
|
||||
priority = getPriorityByDistance(9.0, streetSearchObject.getDistance());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
searchObject.setPriority(priority);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private double getCityType(StreetGroupSearchObject searchObject) {
|
||||
if (searchObject.getBaseObject().getType() == ObfAddressStreetGroupType.CityOrTown) {
|
||||
if (searchObject.getBaseObject().getSubtype() == ObfAddressStreetGroupSubtype.City) {
|
||||
return 1.0;
|
||||
} else if (searchObject.getBaseObject().getSubtype() == ObfAddressStreetGroupSubtype.Town) {
|
||||
return 1.5;
|
||||
}
|
||||
}
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
private double getPriorityByDistance(double priority, double distance) {
|
||||
return priority + 1.0 - (1.0 / (1.0 + distance));
|
||||
}
|
||||
|
||||
private void updateDistance(SearchPositionObject item) {
|
||||
item.setDistance(Utilities.distance31(searchLocation31, item.getPosition31()));
|
||||
}
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MapUtils;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject.SearchObjectType;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.NameFilterSearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.ObjectSearchToken;
|
||||
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.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SearchString {
|
||||
|
||||
private String plainText = "";
|
||||
private List<SearchToken> tokens = new ArrayList<>();
|
||||
private String lang;
|
||||
|
||||
public SearchString(String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
public SearchString copy() {
|
||||
SearchString res = new SearchString(lang);
|
||||
res.plainText = plainText;
|
||||
res.tokens = new ArrayList<>(tokens);
|
||||
return res;
|
||||
}
|
||||
|
||||
public String getPlainText() {
|
||||
return plainText;
|
||||
}
|
||||
|
||||
public void setPlainText(String plainText) {
|
||||
int newTextLength = plainText.length();
|
||||
int currTextLength = this.plainText.length();
|
||||
boolean isNewText = currTextLength == 0
|
||||
|| newTextLength == 0
|
||||
|| !this.plainText.regionMatches(0, plainText, 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
|
||||
|| token.hasEmptyQuery()
|
||||
|| (lastTokenIndex < newTextLength - 1 && !startWithDelimiter(plainText.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 = plainText.charAt(i);
|
||||
if (isDelimiterChar(c)) {
|
||||
if (i == firstWordIndex) {
|
||||
firstWordIndex++;
|
||||
} else {
|
||||
SearchToken token = new NameFilterSearchToken(firstWordIndex, plainText.substring(firstWordIndex, i));
|
||||
tokens.add(token);
|
||||
firstWordIndex = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (firstWordIndex <= newTextLength - 1) {
|
||||
SearchToken token = new NameFilterSearchToken(firstWordIndex, plainText.substring(firstWordIndex));
|
||||
tokens.add(token);
|
||||
} else if (endWithDelimeter(plainText)) {
|
||||
SearchToken lastToken = getLastToken();
|
||||
if (lastToken.getType() == TokenType.OBJECT) {
|
||||
((ObjectSearchToken) lastToken).applySuggestion();
|
||||
}
|
||||
SearchToken token = new NameFilterSearchToken(firstWordIndex, "");
|
||||
tokens.add(token);
|
||||
}
|
||||
}
|
||||
|
||||
this.plainText = plainText;
|
||||
}
|
||||
|
||||
public void completeQuery(@NonNull SearchObject searchObject) {
|
||||
String text;
|
||||
String objectName = searchObject.getName(lang);
|
||||
int startIndex;
|
||||
SearchToken lastToken = getLastToken();
|
||||
if (lastToken == null || lastToken.hasEmptyQuery()) {
|
||||
startIndex = plainText.length();
|
||||
text = plainText + objectName + " ";
|
||||
} else {
|
||||
startIndex = lastToken.getStartIndex();
|
||||
text = plainText.substring(0, startIndex) + objectName + " ";
|
||||
}
|
||||
ObjectSearchToken token = new ObjectSearchToken(startIndex, objectName, searchObject, false);
|
||||
if (lastToken == null) {
|
||||
tokens.add(token);
|
||||
} else {
|
||||
tokens.set(tokens.size() - 1, token);
|
||||
}
|
||||
tokens.add(new NameFilterSearchToken(text.length(), ""));
|
||||
plainText = text;
|
||||
}
|
||||
|
||||
private boolean endWithDelimeter(String text) {
|
||||
return !Algorithms.isEmpty(text) && isDelimiterChar(text.charAt(text.length() - 1));
|
||||
}
|
||||
|
||||
private boolean startWithDelimiter(String text) {
|
||||
char firstChar = text.charAt(0);
|
||||
return isDelimiterChar(firstChar);
|
||||
}
|
||||
|
||||
private boolean isDelimiterChar(char c) {
|
||||
return c == ',' || c == ' ';
|
||||
}
|
||||
|
||||
public NameFilterSearchToken getNextNameFilterToken() {
|
||||
NameFilterSearchToken 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 = (NameFilterSearchToken) token;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public SearchToken getLastToken() {
|
||||
if (!tokens.isEmpty()) {
|
||||
return tokens.get(tokens.size() - 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ObjectSearchToken getLastObjectToken() {
|
||||
ObjectSearchToken res = null;
|
||||
if (!tokens.isEmpty()) {
|
||||
for (int i = tokens.size() - 1; i >= 0; i--) {
|
||||
SearchToken token = tokens.get(i);
|
||||
if (token.getType() == TokenType.OBJECT) {
|
||||
res = (ObjectSearchToken) token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean replaceToken(SearchToken oldToken, SearchToken newToken) {
|
||||
int index = tokens.indexOf(oldToken);
|
||||
if (index != -1) {
|
||||
tokens.set(index, newToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<SearchObjectType, ObjectSearchToken> getCompleteObjectTokens() {
|
||||
Map<SearchObjectType, ObjectSearchToken> map = new LinkedHashMap<>();
|
||||
for (SearchToken token : tokens) {
|
||||
if (token.getType() == TokenType.OBJECT && !((ObjectSearchToken)token).isSuggestion()) {
|
||||
map.put(((ObjectSearchToken)token).getSearchObject().getType(), (ObjectSearchToken)token);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public List<SearchObject> getCompleteObjects() {
|
||||
List<SearchObject> list = new ArrayList<>();
|
||||
for (SearchToken token : tokens) {
|
||||
if (token.getType() == TokenType.OBJECT && !((ObjectSearchToken)token).isSuggestion()) {
|
||||
list.add(((ObjectSearchToken)token).getSearchObject());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
//test
|
||||
SearchString searchString = new SearchString(MapUtils.LANGUAGE);
|
||||
searchString.setPlainText("cit");
|
||||
searchString.setPlainText("city");
|
||||
searchString.setPlainText("city ");
|
||||
searchString.setPlainText("city s");
|
||||
searchString.setPlainText("city st");
|
||||
searchString.setPlainText("city street ");
|
||||
searchString.setPlainText("city street 8");
|
||||
searchString.setPlainText("new");
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.Building;
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
|
||||
public class BuildingSearchObject extends SearchPositionObject<Building> {
|
||||
|
||||
public BuildingSearchObject(Building building) {
|
||||
super(SearchObjectType.BUILDING, building);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointI getPosition31() {
|
||||
return getBaseObject().getPosition31();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return getBaseObject().getNativeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return getBaseObject().getLocalizedNames();
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
|
||||
public class CitySearchObject extends StreetGroupSearchObject {
|
||||
|
||||
public CitySearchObject(StreetGroup streetGroup) {
|
||||
super(SearchObjectType.CITY, streetGroup);
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
|
||||
public class CoordinatesSearchObject extends SearchPositionObject<PointI> {
|
||||
|
||||
public CoordinatesSearchObject(PointI position31) {
|
||||
super(SearchObjectType.COORDINATES, position31);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointI getPosition31() {
|
||||
return getBaseObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.Amenity;
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
|
||||
public class PoiSearchObject extends SearchPositionObject<Amenity> {
|
||||
|
||||
public PoiSearchObject(Amenity amenity) {
|
||||
super(SearchObjectType.POI, amenity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointI getPosition31() {
|
||||
return getBaseObject().getPosition31();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return getBaseObject().getNativeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return getBaseObject().getLocalizedNames();
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
public class PoiTypeObject {
|
||||
|
||||
private String name;
|
||||
private String keyName;
|
||||
private String categoryKeyName;
|
||||
|
||||
public PoiTypeObject(String name, String keyName, String categoryKeyName) {
|
||||
this.name = name;
|
||||
this.keyName = keyName;
|
||||
this.categoryKeyName = categoryKeyName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getKeyName() {
|
||||
return keyName;
|
||||
}
|
||||
|
||||
public String getCategoryKeyName() {
|
||||
return categoryKeyName;
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
|
||||
public class PoiTypeSearchObject extends SearchObject<PoiTypeObject> {
|
||||
|
||||
private ObjectType objectType;
|
||||
|
||||
public enum ObjectType {
|
||||
CATEGORY,
|
||||
FILTER,
|
||||
TYPE
|
||||
}
|
||||
|
||||
public PoiTypeSearchObject(ObjectType objectType, PoiTypeObject poiTypeObject) {
|
||||
super(SearchObjectType.POI_TYPE, poiTypeObject);
|
||||
this.objectType = objectType;
|
||||
}
|
||||
|
||||
public ObjectType getObjectType() {
|
||||
return objectType;
|
||||
}
|
||||
|
||||
public String getKeyName() {
|
||||
return getBaseObject().getKeyName();
|
||||
}
|
||||
|
||||
public String getCategoryKeyName() {
|
||||
return getBaseObject().getCategoryKeyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return getBaseObject().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
|
||||
public class PostcodeSearchObject extends StreetGroupSearchObject {
|
||||
|
||||
public PostcodeSearchObject(StreetGroup streetGroup) {
|
||||
super(SearchObjectType.POSTCODE, streetGroup);
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
|
||||
public abstract class SearchObject<T> {
|
||||
|
||||
public enum SearchObjectType {
|
||||
CITY,
|
||||
VILLAGE,
|
||||
POSTCODE,
|
||||
STREET,
|
||||
STREET_INTERSECTION,
|
||||
BUILDING,
|
||||
POI_TYPE,
|
||||
POI,
|
||||
COORDINATES
|
||||
}
|
||||
|
||||
private SearchObjectType type;
|
||||
private T baseObject;
|
||||
|
||||
private double priority;
|
||||
|
||||
protected SearchObject(SearchObjectType type, T baseObject) {
|
||||
this.type = type;
|
||||
this.baseObject = baseObject;
|
||||
}
|
||||
|
||||
public SearchObjectType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public T getBaseObject() {
|
||||
return baseObject;
|
||||
}
|
||||
|
||||
public abstract String getNativeName();
|
||||
|
||||
public String getName(String lang) {
|
||||
QStringStringHash locNames = getLocalizedNames();
|
||||
if (locNames != null && lang != null) {
|
||||
String locName = null;
|
||||
if (locNames.has_key(lang)) {
|
||||
locName = locNames.get(lang);
|
||||
}
|
||||
return locName == null ? getNativeName() : locName;
|
||||
} else {
|
||||
return getNativeName();
|
||||
}
|
||||
}
|
||||
|
||||
public String getNameEn() {
|
||||
QStringStringHash locNames = getLocalizedNames();
|
||||
if (locNames != null && locNames.has_key("en")) {
|
||||
return locNames.get("en");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public double getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void setPriority(double priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
protected abstract QStringStringHash getLocalizedNames();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SearchObject: " + getNativeName();
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.PointI;
|
||||
|
||||
public abstract class SearchPositionObject<T> extends SearchObject<T> {
|
||||
|
||||
private double distance;
|
||||
|
||||
public SearchPositionObject(SearchObjectType type, T object) {
|
||||
super(type, object);
|
||||
}
|
||||
|
||||
public abstract PointI getPosition31();
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SearchPositionObject: " + getNativeName()
|
||||
+ " {x31:" + getPosition31().getX() + " y31: " + getPosition31().getY() + "}";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
|
||||
public abstract class StreetGroupSearchObject extends SearchPositionObject<StreetGroup> {
|
||||
|
||||
public StreetGroupSearchObject(SearchObjectType type, StreetGroup streetGroup) {
|
||||
super(type, streetGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointI getPosition31() {
|
||||
return getBaseObject().getPosition31();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return getBaseObject().getNativeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return getBaseObject().getLocalizedNames();
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
import net.osmand.core.jni.StreetIntersection;
|
||||
|
||||
public class StreetIntersectionSearchObject extends SearchPositionObject<StreetIntersection> {
|
||||
|
||||
public StreetIntersectionSearchObject(StreetIntersection streetIntersection) {
|
||||
super(SearchObjectType.STREET_INTERSECTION, streetIntersection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointI getPosition31() {
|
||||
return getBaseObject().getPosition31();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return getBaseObject().getNativeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return getBaseObject().getLocalizedNames();
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
import net.osmand.core.jni.Street;
|
||||
|
||||
public class StreetSearchObject extends SearchPositionObject<Street> {
|
||||
|
||||
public StreetSearchObject(Street street) {
|
||||
super(SearchObjectType.STREET, street);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointI getPosition31() {
|
||||
return getBaseObject().getPosition31();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return getBaseObject().getNativeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return getBaseObject().getLocalizedNames();
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
import net.osmand.core.jni.StreetGroup;
|
||||
|
||||
public class VillageSearchObject extends StreetGroupSearchObject {
|
||||
|
||||
public VillageSearchObject(StreetGroup streetGroup) {
|
||||
super(SearchObjectType.VILLAGE, streetGroup);
|
||||
}
|
||||
}
|
|
@ -1,245 +0,0 @@
|
|||
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.jni.OsmAndCoreJNI;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchApiCallback;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallbackInternal;
|
||||
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.objects.PoiSearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchObjectsHelper;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchPositionObject;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.NameFilterSearchToken;
|
||||
import net.osmand.core.samples.android.sample1.search.tokens.ObjectSearchToken;
|
||||
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 SearchCallbackInternal internalCallback;
|
||||
|
||||
private int amenityResultsCounter;
|
||||
private int addressResultsCounter;
|
||||
|
||||
public CoreSearchRequest(@Nullable IntermediateSearchRequest intermediateSearchRequest,
|
||||
@NonNull SearchScope searchScope, int maxSearchResults,
|
||||
@Nullable SearchApiCallback searchCallback,
|
||||
@Nullable SearchCallbackInternal internalCallback) {
|
||||
super(searchScope, maxSearchResults, searchCallback);
|
||||
this.intermediateSearchRequest = intermediateSearchRequest;
|
||||
this.internalCallback = internalCallback;
|
||||
}
|
||||
|
||||
@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<SearchObject> searchObjects) {
|
||||
if (intermediateSearchRequest != null && !intermediateSearchDone) {
|
||||
intermediateSearchRequest.cancel();
|
||||
}
|
||||
if (internalCallback != null) {
|
||||
internalCallback.onSearchObjectsFound(searchObjects);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (intermediateSearchRequest != null) {
|
||||
intermediateSearchRequest.cancel();
|
||||
}
|
||||
super.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SearchObject> doSearch() {
|
||||
|
||||
List<SearchObject> res = new ArrayList<>();
|
||||
|
||||
SearchString searchString = searchScope.getSearchString();
|
||||
SearchToken lastToken = searchString.getLastToken();
|
||||
NameFilterSearchToken token = searchString.getNextNameFilterToken();
|
||||
while (token != null && !cancelled) {
|
||||
if (!token.hasEmptyQuery()) {
|
||||
res = doCoreSearch(token);
|
||||
List<SearchObject> externalObjects = searchCallback.fetchExternalObjects(token.getPlainText(), searchString.getCompleteObjects());
|
||||
if (externalObjects != null) {
|
||||
res.addAll(externalObjects);
|
||||
}
|
||||
}
|
||||
if (token != lastToken) {
|
||||
searchScope.updateScope();
|
||||
token = searchString.getNextNameFilterToken();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastToken == null || lastToken.hasEmptyQuery()) {
|
||||
// 2.4 Search considered to be complete if there no NF in the end (not finished or not regonized objects)
|
||||
ObjectSearchToken lastObjectToken = searchString.getLastObjectToken();
|
||||
if (lastObjectToken == null) {
|
||||
// Last object = [] - none. We display list of poi categories (recents separate tab)
|
||||
List<SearchObject> externalObjects = searchCallback.fetchExternalObjects("", null);
|
||||
if (externalObjects != null) {
|
||||
res = externalObjects;
|
||||
}
|
||||
} else {
|
||||
SearchObject searchObject = lastObjectToken.getSearchObject();
|
||||
switch (searchObject.getType()) {
|
||||
case POI_TYPE:
|
||||
// Last object - poi category/poi filter/poi type. Display: poi filters (if it is poi category & pois around location (if it is specified in query by any previous object) + Search more radius
|
||||
// For example: Leiden ice hockey, we display all ice hockey around Leiden
|
||||
List<SearchObject> externalObjects = searchCallback.fetchExternalObjects("", searchString.getCompleteObjects());
|
||||
if (externalObjects != null) {
|
||||
res = externalObjects;
|
||||
}
|
||||
break;
|
||||
case CITY:
|
||||
// Last object - City. Display (list of streets could be quite long)
|
||||
res = doCoreSearch(new NameFilterSearchToken(0, ""));
|
||||
break;
|
||||
case STREET:
|
||||
// Last object - Street. Display building and intersetcting street
|
||||
res = doCoreSearch(new NameFilterSearchToken(0, ""));
|
||||
break;
|
||||
case POSTCODE:
|
||||
// Last object - Postcode. Display building and streets
|
||||
res = doCoreSearch(new NameFilterSearchToken(0, ""));
|
||||
break;
|
||||
case BUILDING:
|
||||
// Last object - Building - object is found
|
||||
break;
|
||||
case POI:
|
||||
// Last object - POI - object is found
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private List<SearchObject> doCoreSearch(@NonNull SearchToken token) {
|
||||
amenityResultsCounter = 0;
|
||||
addressResultsCounter = 0;
|
||||
|
||||
String keyword = token.getPlainText();
|
||||
final List<SearchObject> searchObjects = new ArrayList<>();
|
||||
|
||||
AmenitiesByNameSearch amByNameSearch = null;
|
||||
AmenitiesByNameSearch.Criteria amenityByNameCriteria = null;
|
||||
ISearch.INewResultEntryCallback amenityByNameResultCallback = null;
|
||||
if (!keyword.isEmpty()) {
|
||||
// Setup Amenities by name search
|
||||
amByNameSearch = new AmenitiesByNameSearch(searchScope.getObfsCollection());
|
||||
amenityByNameCriteria = new AmenitiesByNameSearch.Criteria();
|
||||
amenityByNameCriteria.setName(keyword);
|
||||
if (searchScope.getObfAreaFilter() != null) {
|
||||
amenityByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchScope.getObfAreaFilter()));
|
||||
}
|
||||
searchScope.setupAmenitySearchCriteria(amenityByNameCriteria);
|
||||
|
||||
amenityByNameResultCallback = new ISearch.INewResultEntryCallback() {
|
||||
@Override
|
||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||
Amenity amenity = new AmenityResultEntry(resultEntry).getAmenity();
|
||||
PoiSearchObject amenitySearchItem = new PoiSearchObject(amenity);
|
||||
if (searchScope.processPoiSearchObject(amenitySearchItem)) {
|
||||
searchObjects.add(amenitySearchItem);
|
||||
}
|
||||
amenityResultsCounter++;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Setup Addresses by name search
|
||||
AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(searchScope.getObfsCollection());
|
||||
final AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria();
|
||||
addrByNameCriteria.setName(keyword);
|
||||
if (searchScope.getObfAreaFilter() != null) {
|
||||
addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchScope.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();
|
||||
SearchPositionObject addressSearchObject = SearchObjectsHelper.getAddressObject(address);
|
||||
if (addressSearchObject != null) {
|
||||
if (searchScope.processAddressSearchObject(addressSearchObject)) {
|
||||
searchObjects.add(addressSearchObject);
|
||||
}
|
||||
addressResultsCounter++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (amByNameSearch != null) {
|
||||
amByNameSearch.performSearch(amenityByNameCriteria, amenityByNameResultCallback.getBinding(), new IQueryController() {
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return (maxSearchResults > 0 && amenityResultsCounter >= maxSearchResults) || cancelled;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!cancelled) {
|
||||
addrByNameSearch.performSearch(addrByNameCriteria, addrByNameResultCallback.getBinding(), new IQueryController() {
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return (maxSearchResults > 0 && addressResultsCounter >= maxSearchResults) || cancelled;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!cancelled) {
|
||||
SearchToken newToken = searchScope.processSearchResult(token, searchObjects);
|
||||
if (newToken != null && internalCallback != null) {
|
||||
internalCallback.onNewTokenFound(token, newToken);
|
||||
}
|
||||
}
|
||||
|
||||
return searchObjects;
|
||||
}
|
||||
|
||||
private class AmenityResultEntry extends AmenitiesByNameSearch.ResultEntry {
|
||||
protected AmenityResultEntry(ISearch.IResultEntry resultEntry) {
|
||||
super(OsmAndCoreJNI.AmenitiesByNameSearch_ResultEntry_SWIGUpcast(ISearch.IResultEntry.getCPtr(resultEntry)), false);
|
||||
}
|
||||
}
|
||||
|
||||
private class AddressResultEntry extends AddressesByNameSearch.ResultEntry {
|
||||
protected AddressResultEntry(ISearch.IResultEntry resultEntry) {
|
||||
super(OsmAndCoreJNI.AddressesByNameSearch_ResultEntry_SWIGUpcast(ISearch.IResultEntry.getCPtr(resultEntry)), false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
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.SearchApiCallback;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchScope;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
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<SearchObject> searchObjects;
|
||||
protected String keyword = "";
|
||||
|
||||
public IntermediateSearchRequest(@NonNull SearchScope searchScope, List<SearchObject> searchObjects,
|
||||
int maxSearchResults, @Nullable SearchApiCallback searchCallback) {
|
||||
super(searchScope, maxSearchResults, searchCallback);
|
||||
this.searchObjects = searchObjects;
|
||||
|
||||
SearchToken token = searchScope.getSearchString().getLastToken();
|
||||
if (token != null && token.getType() == SearchToken.TokenType.NAME_FILTER) {
|
||||
keyword = token.getPlainText().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SearchObject> doSearch() {
|
||||
List<SearchObject> res = new ArrayList<>();
|
||||
for (SearchObject item : searchObjects) {
|
||||
if (cancelled) {
|
||||
break;
|
||||
}
|
||||
if (keyword.isEmpty() || item.getName(searchScope.getLang()).toLowerCase().contains(keyword)
|
||||
|| item.getNativeName().toLowerCase().contains(keyword)) {
|
||||
res.add(item);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
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.SearchApiCallback;
|
||||
import net.osmand.core.samples.android.sample1.search.SearchScope;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SearchRequest {
|
||||
protected SearchScope searchScope;
|
||||
|
||||
protected int maxSearchResults;
|
||||
protected Runnable onFinished;
|
||||
protected SearchApiCallback searchCallback;
|
||||
|
||||
protected boolean cancelled;
|
||||
|
||||
public SearchRequest(@NonNull SearchScope searchScope, int maxSearchResults,
|
||||
@Nullable SearchApiCallback searchCallback) {
|
||||
this.searchScope = searchScope;
|
||||
this.maxSearchResults = maxSearchResults;
|
||||
this.searchCallback = searchCallback;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
new AsyncTask<Void, Void, List<SearchObject>>() {
|
||||
|
||||
@Override
|
||||
protected List<SearchObject> doInBackground(Void... params) {
|
||||
return doSearch();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<SearchObject> searchObjects) {
|
||||
|
||||
onSearchRequestPostExecute(searchObjects);
|
||||
|
||||
if (onFinished != null) {
|
||||
onFinished.run();
|
||||
}
|
||||
|
||||
if (searchCallback != null && !cancelled) {
|
||||
searchCallback.onSearchFinished(searchObjects);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
protected void onSearchRequestPostExecute(List<SearchObject> searchObjects) {
|
||||
}
|
||||
|
||||
protected abstract List<SearchObject> doSearch();
|
||||
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
public void setOnFinishedCallback(@Nullable Runnable onFinished) {
|
||||
this.onFinished = onFinished;
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
public class NameFilterSearchToken extends SearchToken {
|
||||
|
||||
public NameFilterSearchToken(int startIndex, String plainText) {
|
||||
super(TokenType.NAME_FILTER, startIndex, plainText);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||
|
||||
public class ObjectSearchToken extends SearchToken {
|
||||
|
||||
private SearchObject searchObject;
|
||||
private boolean suggestion = true;
|
||||
|
||||
public ObjectSearchToken(SearchToken searchToken, SearchObject searchObject, boolean suggestion) {
|
||||
super(TokenType.OBJECT, searchToken.getStartIndex(), searchToken.getPlainText());
|
||||
this.searchObject = searchObject;
|
||||
this.suggestion = suggestion;
|
||||
}
|
||||
|
||||
public ObjectSearchToken(int startIndex, String plainText, SearchObject searchObject, boolean suggestion) {
|
||||
super(TokenType.OBJECT, startIndex, plainText);
|
||||
this.searchObject = searchObject;
|
||||
this.suggestion = suggestion;
|
||||
}
|
||||
|
||||
public SearchObject getSearchObject() {
|
||||
return searchObject;
|
||||
}
|
||||
|
||||
public boolean isSuggestion() {
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
public void applySuggestion() {
|
||||
this.suggestion = false;
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public abstract class SearchToken {
|
||||
|
||||
public enum TokenType {
|
||||
OBJECT,
|
||||
NAME_FILTER
|
||||
}
|
||||
|
||||
private TokenType type;
|
||||
private int startIndex;
|
||||
protected String plainText;
|
||||
|
||||
public SearchToken(TokenType type, int startIndex, String plainText) {
|
||||
this.type = type;
|
||||
this.startIndex = startIndex;
|
||||
this.plainText = plainText;
|
||||
}
|
||||
|
||||
public TokenType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getStartIndex() {
|
||||
return startIndex;
|
||||
}
|
||||
|
||||
public String getPlainText() {
|
||||
return plainText;
|
||||
}
|
||||
|
||||
public int getLastIndex() {
|
||||
return startIndex + plainText.length() - 1;
|
||||
}
|
||||
|
||||
public boolean hasEmptyQuery() {
|
||||
return Algorithms.isEmpty(plainText);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue