[Core sample] poi types in progress
This commit is contained in:
parent
38affee113
commit
95ee464578
16 changed files with 442 additions and 34 deletions
|
@ -9,6 +9,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorPrimary"
|
||||
android:focusableInTouchMode="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -21,7 +21,7 @@ public class IconsCache {
|
|||
this.displayDensityFactor = displayDensityFactor;
|
||||
}
|
||||
|
||||
public Drawable getIcon(String name) {
|
||||
public Drawable getMapIcon(String name) {
|
||||
return assets.getIcon("map/icons/" + name + ".png", displayDensityFactor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.content.SharedPreferences;
|
|||
import android.content.SharedPreferences.Editor;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.ViewPropertyAnimatorListener;
|
||||
import android.text.Editable;
|
||||
|
@ -24,6 +25,7 @@ import android.widget.ListView;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.CollatorStringMatcher;
|
||||
import net.osmand.core.android.AtlasMapRendererView;
|
||||
import net.osmand.core.jni.AreaI;
|
||||
import net.osmand.core.jni.IMapLayerProvider;
|
||||
|
@ -48,12 +50,21 @@ 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.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.core.samples.android.sample1.search.tokens.SearchToken;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -93,11 +104,11 @@ public class MainActivity extends Activity {
|
|||
private ImageView searchIcon;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
private final static int MAX_SEARCH_RESULTS_CORE = 0;
|
||||
private final static int MAX_SEARCH_RESULTS_IU = 150;
|
||||
private ListView searchListView;
|
||||
private SearchListAdapter adapter;
|
||||
private String queryText = "";
|
||||
private final static int MAX_SEARCH_RESULTS_CORE = 0;
|
||||
private final static int MAX_SEARCH_RESULTS_IU = 150;
|
||||
|
||||
// Germany
|
||||
private final static float INIT_LAT = 49.353953f;
|
||||
|
@ -118,6 +129,13 @@ public class MainActivity extends Activity {
|
|||
private static final String PREF_MAP_ELEVATION_ANGLE = "MAP_ELEVATION_ANGLE";
|
||||
|
||||
private SearchApiCallback intermediateSearchCallback = new SearchApiCallback() {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<SearchObject> fetchExternalObjects(String keyword, @Nullable List<SearchObject> completeObjects) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchFinished(List<SearchObject> searchObjects) {
|
||||
processSearchResult(searchObjects);
|
||||
|
@ -125,9 +143,96 @@ public class MainActivity extends Activity {
|
|||
};
|
||||
|
||||
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,
|
||||
pt.getTranslation(), pt.getKeyName(), null));
|
||||
} else if (pt instanceof PoiFilter) {
|
||||
PoiFilter poiFilter = (PoiFilter) pt;
|
||||
result.add(new PoiTypeSearchObject(ObjectType.FILTER,
|
||||
poiFilter.getTranslation(), poiFilter.getKeyName(), poiFilter.getPoiCategory().getKeyName()));
|
||||
} else if (pt instanceof PoiType) {
|
||||
PoiType poiType = (PoiType) pt;
|
||||
result.add(new PoiTypeSearchObject(ObjectType.TYPE,
|
||||
poiType.getTranslation(), poiType.getKeyName(), poiType.getCategory().getKeyName()));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchFinished(List<SearchObject> searchObjects) {
|
||||
|
||||
processSearchResult(searchObjects);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Map<SearchObjectType, SearchToken> objectTokensMap = searchAPI.getObjectTokens();
|
||||
ObjectSearchToken lastObjectToken = searchAPI.getLastObjectToken();
|
||||
|
@ -251,7 +356,6 @@ public class MainActivity extends Activity {
|
|||
app.getIconsCache().setDisplayDensityFactor(displayDensityFactor);
|
||||
|
||||
//Setup search
|
||||
|
||||
searchAPI = new SearchAPI(obfsCollection, MapUtils.LANGUAGE);
|
||||
|
||||
searchEditText = (EditText) findViewById(R.id.searchEditText);
|
||||
|
@ -270,18 +374,22 @@ public class MainActivity extends Activity {
|
|||
if (!queryText.equalsIgnoreCase(newQueryText)) {
|
||||
queryText = newQueryText;
|
||||
showProgressBar();
|
||||
runSearch(getScreenCenter31(), getScreenBounds31(), queryText);
|
||||
runSearch();
|
||||
}
|
||||
}
|
||||
});
|
||||
searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus && adapter.getCount() > 0 && isSearchListHidden()) {
|
||||
if (hasFocus && isSearchListHidden()) {
|
||||
showSearchList();
|
||||
LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
adapter.updateDistance(latLon.getLatitude(), latLon.getLongitude());
|
||||
adapter.notifyDataSetChanged();
|
||||
if (adapter.getCount() > 0) {
|
||||
LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
adapter.updateDistance(latLon.getLatitude(), latLon.getLongitude());
|
||||
adapter.notifyDataSetChanged();
|
||||
} else {
|
||||
runSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -309,6 +417,7 @@ public class MainActivity extends Activity {
|
|||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
SearchListItem item = adapter.getItem(position);
|
||||
SearchObject searchObject = item.getSearchObject();
|
||||
|
||||
if (searchObject.getType() == SearchObjectType.POI
|
||||
|| searchObject.getType() == SearchObjectType.BUILDING
|
||||
|| searchObject.getType() == SearchObjectType.COORDINATES) {
|
||||
|
@ -483,6 +592,10 @@ public class MainActivity extends Activity {
|
|||
|| gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
|
||||
private void runSearch() {
|
||||
runSearch(getScreenCenter31(), getScreenBounds31(), queryText);
|
||||
}
|
||||
|
||||
private void runSearch(PointI position31, AreaI bounds31, String keyword) {
|
||||
|
||||
searchAPI.setSearchLocation31(position31);
|
||||
|
@ -503,27 +616,26 @@ public class MainActivity extends Activity {
|
|||
List<SearchListItem> rows = new ArrayList<>();
|
||||
for (SearchObject item : searchObjects) {
|
||||
SearchListItem listItem =
|
||||
SearchListItem.buildListItem((SampleApplication)getApplication(), item);
|
||||
SearchListItem.buildListItem(getSampleApplication(), item);
|
||||
if (listItem != null) {
|
||||
rows.add(listItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (rows.size() > MAX_SEARCH_RESULTS_IU) {
|
||||
rows = rows.subList(0, MAX_SEARCH_RESULTS_IU);
|
||||
}
|
||||
|
||||
adapter.clear();
|
||||
adapter.addAll(rows);
|
||||
adapter.notifyDataSetChanged();
|
||||
if (adapter.getCount() > 0) {
|
||||
searchListView.setSelection(0);
|
||||
}
|
||||
|
||||
updateListAdapter(rows);
|
||||
showSearchList();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateListAdapter(List<SearchListItem> listItems) {
|
||||
adapter.setListItems(listItems);
|
||||
if (adapter.getCount() > 0) {
|
||||
searchListView.setSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
private class MapViewOnGestureListener extends SimpleOnGestureListener {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
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:
|
||||
return app.getPoiTypes().getPoiTypeByKey(poiTypeObject.getKeyName());
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ public class SampleApplication extends Application
|
|||
{
|
||||
private CoreResourcesFromAndroidAssets assetsCustom;
|
||||
private MapPoiTypes poiTypes;
|
||||
private PoiTypesHelper poiTypesHelper;
|
||||
private IconsCache iconsCache;
|
||||
|
||||
@Override
|
||||
|
@ -25,6 +26,7 @@ public class SampleApplication extends Application
|
|||
super.onCreate();
|
||||
|
||||
initPoiTypes();
|
||||
poiTypesHelper = new PoiTypesHelper(this);
|
||||
|
||||
// Initialize native core
|
||||
if (NativeCore.isAvailable() && !NativeCore.isLoaded()) {
|
||||
|
@ -40,6 +42,10 @@ public class SampleApplication extends Application
|
|||
return poiTypes;
|
||||
}
|
||||
|
||||
public PoiTypesHelper getPoiTypesHelper() {
|
||||
return poiTypesHelper;
|
||||
}
|
||||
|
||||
public IconsCache getIconsCache() {
|
||||
return iconsCache;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public class PoiSearchListItem extends SearchListPositionItem {
|
|||
Drawable drawable = null;
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
drawable = app.getIconsCache().getIcon(st.getOsmTag() + "_" + st.getOsmValue());
|
||||
drawable = app.getIconsCache().getMapIcon(st.getOsmTag() + "_" + st.getOsmValue());
|
||||
}
|
||||
return drawable;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
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;
|
||||
}
|
||||
}
|
|
@ -13,6 +13,8 @@ import net.osmand.core.jni.Utilities;
|
|||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
||||
|
||||
private Context ctx;
|
||||
|
@ -22,6 +24,19 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
|||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public void setListItems(List<SearchListItem> items) {
|
||||
setNotifyOnChange(false);
|
||||
clear();
|
||||
addAll(items);
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
@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);
|
||||
|
|
|
@ -6,6 +6,7 @@ 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;
|
||||
|
@ -24,6 +25,8 @@ public class SearchListItem {
|
|||
|
||||
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:
|
||||
|
|
|
@ -4,7 +4,6 @@ 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.SearchObject;
|
||||
import net.osmand.core.samples.android.sample1.search.objects.SearchPositionObject;
|
||||
|
||||
public class SearchListPositionItem extends SearchListItem {
|
||||
|
@ -12,7 +11,6 @@ public class SearchListPositionItem extends SearchListItem {
|
|||
private double latitude;
|
||||
private double longitude;
|
||||
|
||||
|
||||
public SearchListPositionItem(SampleApplication app, SearchPositionObject searchObject) {
|
||||
super(app, searchObject);
|
||||
PointI position31 = searchObject.getPosition31();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
@ -43,6 +44,10 @@ public class SearchAPI {
|
|||
};
|
||||
|
||||
public interface SearchApiCallback {
|
||||
|
||||
@Nullable
|
||||
List<SearchObject> fetchExternalObjects(String keyword, @Nullable List<SearchObject> completeObjects);
|
||||
|
||||
void onSearchFinished(List<SearchObject> searchObjects);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,12 @@ 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;
|
||||
|
@ -37,6 +39,7 @@ public class SearchScope {
|
|||
private AreaI obfAreaFilter;
|
||||
private double searchRadius;
|
||||
boolean citySelected;
|
||||
boolean poiTypeSelected;
|
||||
|
||||
private int resultLimitPoiByName = 25;
|
||||
private int poiByNameCounter = 0;
|
||||
|
@ -62,6 +65,7 @@ public class SearchScope {
|
|||
|| objectTokens.containsKey(SearchObjectType.VILLAGE)
|
||||
|| objectTokens.containsKey(SearchObjectType.POSTCODE)
|
||||
|| objectTokens.containsKey(SearchObjectType.STREET);
|
||||
poiTypeSelected = objectTokens.containsKey(SearchObjectType.POI_TYPE);
|
||||
}
|
||||
|
||||
public ObfsCollection getObfsCollection() {
|
||||
|
@ -93,7 +97,13 @@ public class SearchScope {
|
|||
}
|
||||
|
||||
public void setupAmenitySearchCriteria(AmenitiesByNameSearch.Criteria criteria) {
|
||||
//todo criteria.setCategoriesFilter() if needed;
|
||||
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) {
|
||||
|
@ -194,6 +204,9 @@ public class SearchScope {
|
|||
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;
|
||||
|
|
|
@ -108,7 +108,7 @@ public class SearchString {
|
|||
String objectName = searchObject.getName(lang);
|
||||
int startIndex;
|
||||
SearchToken lastToken = getLastToken();
|
||||
if (lastToken.hasEmptyQuery()) {
|
||||
if (lastToken == null || lastToken.hasEmptyQuery()) {
|
||||
startIndex = queryText.length();
|
||||
newQueryText = queryText + objectName + " ";
|
||||
} else {
|
||||
|
@ -116,7 +116,12 @@ public class SearchString {
|
|||
newQueryText = queryText.substring(0, startIndex) + objectName + " ";
|
||||
}
|
||||
ObjectSearchToken token = new ObjectSearchToken(startIndex, objectName, searchObject, false);
|
||||
tokens.set(tokens.size() - 1, token);
|
||||
if (lastToken == null) {
|
||||
tokens.add(token);
|
||||
} else {
|
||||
tokens.set(tokens.size() - 1, token);
|
||||
}
|
||||
tokens.add(new NameFilterSearchToken(newQueryText.length(), ""));
|
||||
queryText = newQueryText;
|
||||
}
|
||||
|
||||
|
@ -188,6 +193,16 @@ public class SearchString {
|
|||
return map;
|
||||
}
|
||||
|
||||
public List<SearchObject> getCompleteObjects() {
|
||||
List<SearchObject> list = new ArrayList<>();
|
||||
for (SearchToken token : tokens) {
|
||||
if (token.getType() == TokenType.SEARCH_OBJECT && !((ObjectSearchToken)token).isSuggestion()) {
|
||||
list.add(token.getSearchObject());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
//test
|
||||
SearchString searchString = new SearchString(MapUtils.LANGUAGE);
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package net.osmand.core.samples.android.sample1.search.objects;
|
||||
|
||||
import net.osmand.core.jni.QStringStringHash;
|
||||
|
||||
public class PoiTypeSearchObject extends SearchObject {
|
||||
|
||||
private ObjectType objectType;
|
||||
private String name;
|
||||
private String keyName;
|
||||
private String categoryKeyName;
|
||||
|
||||
public enum ObjectType {
|
||||
CATEGORY,
|
||||
FILTER,
|
||||
TYPE
|
||||
}
|
||||
|
||||
public PoiTypeSearchObject(ObjectType objectType, String name, String keyName, String categoryKeyName) {
|
||||
super(SearchObjectType.POI_TYPE, null);
|
||||
this.objectType = objectType;
|
||||
this.name = name;
|
||||
this.keyName = keyName;
|
||||
this.categoryKeyName = categoryKeyName;
|
||||
}
|
||||
|
||||
public ObjectType getObjectType() {
|
||||
return objectType;
|
||||
}
|
||||
|
||||
public String getKeyName() {
|
||||
return keyName;
|
||||
}
|
||||
|
||||
public String getCategoryKeyName() {
|
||||
return categoryKeyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QStringStringHash getLocalizedNames() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ public abstract class SearchObject {
|
|||
STREET_INTERSECTION,
|
||||
BUILDING,
|
||||
POI_TYPE,
|
||||
POI_FILTER,
|
||||
POI,
|
||||
COORDINATES
|
||||
}
|
||||
|
|
|
@ -89,6 +89,10 @@ public class CoreSearchRequest extends SearchRequest {
|
|||
while (token != null && !cancelled) {
|
||||
if (!token.hasEmptyQuery()) {
|
||||
res = doCoreSearch(token);
|
||||
List<SearchObject> externalObjects = searchCallback.fetchExternalObjects(token.getQueryText(), searchString.getCompleteObjects());
|
||||
if (externalObjects != null) {
|
||||
res.addAll(externalObjects);
|
||||
}
|
||||
}
|
||||
if (token != lastToken) {
|
||||
searchScope.updateScope();
|
||||
|
@ -99,18 +103,44 @@ public class CoreSearchRequest extends SearchRequest {
|
|||
}
|
||||
|
||||
if (lastToken == null || lastToken.hasEmptyQuery()) {
|
||||
// todo 2.4
|
||||
// 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)
|
||||
// Last object = [] - none. We display list of poi categories (recents separate tab)
|
||||
List<SearchObject> externalObjects = searchCallback.fetchExternalObjects("", null);
|
||||
if (externalObjects != null) {
|
||||
res = externalObjects;
|
||||
}
|
||||
} else {
|
||||
// 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
|
||||
// Last object - City. Display (list of streets could be quite long)
|
||||
// Last object - Street. Display building and intersetcting street
|
||||
// Last object - Postcode. Display building and streets
|
||||
// Last object - Building/POI - object is found
|
||||
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:
|
||||
// todo - no SWIG
|
||||
// Last object - City. Display (list of streets could be quite long)
|
||||
break;
|
||||
case STREET:
|
||||
// todo - no SWIG
|
||||
// Last object - Street. Display building and intersetcting street
|
||||
break;
|
||||
case POSTCODE:
|
||||
// todo - no SWIG
|
||||
// Last object - Postcode. Display building and streets
|
||||
break;
|
||||
case BUILDING:
|
||||
// Last object - Building - object is found
|
||||
break;
|
||||
case POI:
|
||||
// Last object - POI - object is found
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue