From 95ee4645787d3f37bf0a326db718a56c7e6bbee3 Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Tue, 28 Jun 2016 23:31:20 +0300 Subject: [PATCH] [Core sample] poi types in progress --- .../res/layout/activity_main.xml | 1 + .../samples/android/sample1/IconsCache.java | 2 +- .../samples/android/sample1/MainActivity.java | 148 +++++++++++++++--- .../android/sample1/PoiTypesHelper.java | 104 ++++++++++++ .../android/sample1/SampleApplication.java | 6 + .../sample1/adapters/PoiSearchListItem.java | 2 +- .../adapters/PoiTypeSearchListItem.java | 60 +++++++ .../sample1/adapters/SearchListAdapter.java | 15 ++ .../sample1/adapters/SearchListItem.java | 3 + .../adapters/SearchListPositionItem.java | 2 - .../android/sample1/search/SearchAPI.java | 5 + .../android/sample1/search/SearchScope.java | 15 +- .../android/sample1/search/SearchString.java | 19 ++- .../search/objects/PoiTypeSearchObject.java | 47 ++++++ .../sample1/search/objects/SearchObject.java | 1 - .../search/requests/CoreSearchRequest.java | 46 +++++- 16 files changed, 442 insertions(+), 34 deletions(-) create mode 100644 OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/PoiTypesHelper.java create mode 100644 OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiTypeSearchListItem.java create mode 100644 OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PoiTypeSearchObject.java diff --git a/OsmAndCore-sample/res/layout/activity_main.xml b/OsmAndCore-sample/res/layout/activity_main.xml index 4eacd6551b..e146d1473a 100755 --- a/OsmAndCore-sample/res/layout/activity_main.xml +++ b/OsmAndCore-sample/res/layout/activity_main.xml @@ -9,6 +9,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" + android:focusableInTouchMode="true" android:orientation="vertical"> fetchExternalObjects(String keyword, @Nullable List completeObjects) { + return null; + } + @Override public void onSearchFinished(List searchObjects) { processSearchResult(searchObjects); @@ -125,9 +143,96 @@ public class MainActivity extends Activity { }; private SearchApiCallback coreSearchCallback = new SearchApiCallback() { + + @Override + @Nullable + public List fetchExternalObjects(String keyword, @Nullable List completeObjects) { + List 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 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() { + @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() { + @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 searchObjects) { + processSearchResult(searchObjects); + StringBuilder sb = new StringBuilder(); Map 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 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 listItems) { + adapter.setListItems(listItems); + if (adapter.getCount() > 0) { + searchListView.setSelection(0); + } + } + private class MapViewOnGestureListener extends SimpleOnGestureListener { @Override diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/PoiTypesHelper.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/PoiTypesHelper.java new file mode 100644 index 0000000000..f53964d533 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/PoiTypesHelper.java @@ -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 findPoiTypes(String s) { + List poiTypes = new ArrayList<>(); + if (Algorithms.isEmpty(s)) { + poiTypes.addAll(app.getPoiTypes().getTopVisibleFilters()); + } else { + List res = app.getPoiTypes().getAllTypesTranslatedNames( + new CollatorStringMatcher(s, CollatorStringMatcher.StringMatcherMode.CHECK_STARTS_FROM_SPACE)); + final Collator inst = Collator.getInstance(); + Collections.sort(res, new Comparator() { + @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 getPoiCategoryTypesTranslatedNames(PoiCategory pc, StringMatcher matcher) { + List tm = new ArrayList(); + 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 getPoiFilterTypesTranslatedNames(PoiFilter pf, StringMatcher matcher) { + List tm = new ArrayList(); + for (PoiType pt : pf.getPoiTypes()) { + if (pt.isReference()) { + continue; + } + addIf(tm, pt, matcher); + } + + return tm; + } + + private void addIf(List tm, AbstractPoiType pc, StringMatcher matcher) { + if (matcher.matches(pc.getTranslation()) || matcher.matches(pc.getKeyName().replace('_', ' '))) { + tm.add(pc); + } + List additionals = pc.getPoiAdditionals(); + if (additionals != null) { + for (PoiType a : additionals) { + addIf(tm, a, matcher); + } + } + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java index 72ecab508a..6dd63331c5 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleApplication.java @@ -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; } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiSearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiSearchListItem.java index e596bfaa72..3b1ce0b921 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiSearchListItem.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiSearchListItem.java @@ -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; } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiTypeSearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiTypeSearchListItem.java new file mode 100644 index 0000000000..ba4c09aacd --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiTypeSearchListItem.java @@ -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; + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListAdapter.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListAdapter.java index 2b1a3ef47a..8c55c02cd9 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListAdapter.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListAdapter.java @@ -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 { private Context ctx; @@ -22,6 +24,19 @@ public class SearchListAdapter extends ArrayAdapter { this.ctx = ctx; } + public void setListItems(List 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); diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java index 9a0b3132ac..cae18ac37b 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java @@ -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: diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListPositionItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListPositionItem.java index 34034cbe23..00d12f4df6 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListPositionItem.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListPositionItem.java @@ -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(); diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java index ef034e7ad5..f65b1daa18 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java @@ -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 fetchExternalObjects(String keyword, @Nullable List completeObjects); + void onSearchFinished(List searchObjects); } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchScope.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchScope.java index 2e31d91232..2ab2509c5b 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchScope.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchScope.java @@ -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; diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchString.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchString.java index 8212aa1e4d..f533ff89b2 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchString.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchString.java @@ -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 getCompleteObjects() { + List 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); diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PoiTypeSearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PoiTypeSearchObject.java new file mode 100644 index 0000000000..8099828d57 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PoiTypeSearchObject.java @@ -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; + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObject.java index 9eb7f76715..c392dd9f40 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObject.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObject.java @@ -12,7 +12,6 @@ public abstract class SearchObject { STREET_INTERSECTION, BUILDING, POI_TYPE, - POI_FILTER, POI, COORDINATES } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/CoreSearchRequest.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/CoreSearchRequest.java index 249dcdfe16..5a781fdd17 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/CoreSearchRequest.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/CoreSearchRequest.java @@ -89,6 +89,10 @@ public class CoreSearchRequest extends SearchRequest { while (token != null && !cancelled) { if (!token.hasEmptyQuery()) { res = doCoreSearch(token); + List 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 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 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; + } } }