diff --git a/OsmAndCore-sample/res/layout/search_list_item.xml b/OsmAndCore-sample/res/layout/search_list_item.xml index b8f7e2fd79..572a305e3c 100644 --- a/OsmAndCore-sample/res/layout/search_list_item.xml +++ b/OsmAndCore-sample/res/layout/search_list_item.xml @@ -15,7 +15,7 @@ android:layout_width="24dp" android:layout_height="24dp" android:layout_marginRight="8dp" - android:layout_gravity="center" + android:layout_gravity="top" android:scaleType="centerInside" android:visibility="visible"/> diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java index 4db9b56224..2ec47ff8e3 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java @@ -43,13 +43,12 @@ import net.osmand.core.jni.Utilities; import net.osmand.core.samples.android.sample1.MultiTouchSupport.MultiTouchZoomListener; import net.osmand.core.samples.android.sample1.adapters.SearchListAdapter; import net.osmand.core.samples.android.sample1.adapters.SearchListItem; +import net.osmand.core.samples.android.sample1.adapters.SearchListPositionItem; import net.osmand.core.samples.android.sample1.search.SearchAPI; -import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback; -import net.osmand.core.samples.android.sample1.search.items.SearchItem; +import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchApiCallback; +import net.osmand.core.samples.android.sample1.search.objects.SearchObject; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; public class MainActivity extends Activity { @@ -84,7 +83,7 @@ public class MainActivity extends Activity { private SearchAPI searchAPI; private ListView searchListView; private SearchListAdapter adapter; - private final static int MAX_SEARCH_RESULTS_CORE = 500; + private final static int MAX_SEARCH_RESULTS_CORE = 300; private final static int MAX_SEARCH_RESULTS_IU = 50; // Germany @@ -204,7 +203,7 @@ public class MainActivity extends Activity { //Setup search - searchAPI = new SearchAPI(obfsCollection); + searchAPI = new SearchAPI(obfsCollection, MapUtils.LANGUAGE); final EditText searchEditText = (EditText) findViewById(R.id.searchEditText); searchEditText.addTextChangedListener(new TextWatcher() { @@ -218,9 +217,7 @@ public class MainActivity extends Activity { @Override public void afterTextChanged(Editable s) { - if (s.length() > 2) { - runSearch(getScreenBounds31(), s.toString()); - } + runSearch(getScreenCenter31(), getScreenBounds31(), s.toString()); } }); searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @@ -255,9 +252,13 @@ public class MainActivity extends Activity { hideSearchList(); mapView.requestFocus(); SearchListItem item = adapter.getItem(position); - PointI target = Utilities.convertLatLonTo31(new LatLon(item.getLatitude(), item.getLongitude())); - setTarget(target); - setZoom(17f); + if (item instanceof SearchListPositionItem) { + SearchListPositionItem positionItem = (SearchListPositionItem) item; + PointI target = Utilities.convertLatLonTo31( + new LatLon(positionItem.getLatitude(), positionItem.getLongitude())); + setTarget(target); + setZoom(17f); + } } }); @@ -289,6 +290,12 @@ public class MainActivity extends Activity { return (SampleApplication) getApplication(); } + private PointI getScreenCenter31() { + PointI point = new PointI(); + mapView.getLocationFromScreenPoint(new PointI(mapView.getWidth() / 2, mapView.getHeight() / 2), point); + return point; + } + private AreaI getScreenBounds31() { PointI topLeftPoint = new PointI(); PointI bottomRightPoint = new PointI(); @@ -398,33 +405,31 @@ public class MainActivity extends Activity { || gestureDetector.onTouchEvent(event); } - private void runSearch(AreaI bounds31, String keyword) { + private void runSearch(PointI position31, AreaI bounds31, String keyword) { + searchAPI.setSearchLocation31(position31); searchAPI.setObfAreaFilter(bounds31); searchAPI.startSearch(keyword, MAX_SEARCH_RESULTS_CORE, // Intermediate search callback - new SearchCallback() { + new SearchApiCallback() { @Override - public void onSearchFinished(List searchItems) { - processSearchResult(searchItems); + public void onSearchFinished(List searchObjects) { + processSearchResult(searchObjects); } }, // Core search callback - new SearchCallback() { + new SearchApiCallback() { @Override - public void onSearchFinished(List searchItems) { - processSearchResult(searchItems); + public void onSearchFinished(List searchObjects) { + processSearchResult(searchObjects); } }); } - private void processSearchResult(List searchItems) { - if (searchItems != null) { - LatLon latLon = Utilities.convert31ToLatLon(target31); - double latitude = latLon.getLatitude(); - double longitude = latLon.getLongitude(); + private void processSearchResult(List searchObjects) { + if (searchObjects != null) { List rows = new ArrayList<>(); - for (SearchItem item : searchItems) { + for (SearchObject item : searchObjects) { SearchListItem listItem = SearchListItem.buildListItem((SampleApplication)getApplication(), item); if (listItem != null) { diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AddressSearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AddressSearchListItem.java deleted file mode 100644 index b2fe22ddf1..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AddressSearchListItem.java +++ /dev/null @@ -1,43 +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.items.AddressSearchItem; -import net.osmand.util.Algorithms; - -public class AddressSearchListItem extends SearchListItem { - private String nameStr; - private String typeStr; - - public AddressSearchListItem(SampleApplication app, AddressSearchItem searchItem) { - super(app, searchItem); - - StringBuilder sb = new StringBuilder(); - String localizedName = searchItem.getLocalizedNames().get(MapUtils.LANGUAGE); - if (Algorithms.isEmpty(localizedName)) { - localizedName = searchItem.getNativeName(); - } - if (!Algorithms.isEmpty(searchItem.getNamePrefix())) { - sb.append(searchItem.getNamePrefix()); - sb.append(" "); - } - sb.append(localizedName); - if (!Algorithms.isEmpty(searchItem.getNameSuffix())) { - sb.append(" "); - sb.append(searchItem.getNameSuffix()); - } - - nameStr = sb.toString(); - typeStr = searchItem.getType(); - } - - @Override - public String getName() { - return nameStr; - } - - @Override - public String getType() { - return typeStr; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AmenitySearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AmenitySearchListItem.java deleted file mode 100644 index bb51a8d5c3..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AmenitySearchListItem.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.osmand.core.samples.android.sample1.adapters; - -import android.graphics.drawable.Drawable; - -import net.osmand.core.samples.android.sample1.MapUtils; -import net.osmand.core.samples.android.sample1.SampleApplication; -import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem; -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.Map.Entry; - -public class AmenitySearchListItem extends SearchListItem { - - private Amenity amenity; - private String nameStr; - private String typeStr; - - public AmenitySearchListItem(SampleApplication app, AmenitySearchItem searchItem) { - super(app, searchItem); - amenity = parseAmenity(searchItem); - nameStr = amenity.getName(MapUtils.LANGUAGE); - typeStr = getTypeStr(); - } - - private Amenity parseAmenity(AmenitySearchItem searchItem) { - - MapPoiTypes poiTypes = app.getPoiTypes(); - - Amenity a = new Amenity(); - PoiCategory category = poiTypes.getPoiCategoryByName(searchItem.getCategory()); - a.setType(category); - a.setSubType(searchItem.getSubcategory()); - a.setName(searchItem.getNativeName()); - for (Entry entry : searchItem.getLocalizedNames().entrySet()) { - a.setName(entry.getKey(), entry.getValue()); - } - a.setAdditionalInfo(searchItem.getValues()); - - return a; - } - - public Amenity getAmenity() { - return amenity; - } - - @Override - public String getName() { - return nameStr; - } - - @Override - public String getType() { - return typeStr; - } - - private String getTypeStr() { - /* - PoiCategory pc = amenity.getType(); - 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().getIcon(st.getOsmTag() + "_" + st.getOsmValue()); - } - return drawable; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/CitySearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/CitySearchListItem.java new file mode 100644 index 0000000000..b87cc09685 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/CitySearchListItem.java @@ -0,0 +1,28 @@ +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 searchItem) { + super(app, searchItem); + + nameStr = searchItem.getName(MapUtils.LANGUAGE); + typeStr = "City"; + } + + @Override + public String getName() { + return nameStr; + } + + @Override + public String getTypeName() { + return typeStr; + } +} 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 new file mode 100644 index 0000000000..5b4da14450 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PoiSearchListItem.java @@ -0,0 +1,119 @@ +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 searchItem) { + super(app, searchItem); + amenity = parseAmenity(searchItem); + nameStr = amenity.getName(MapUtils.LANGUAGE); + typeStr = getTypeStr(); + } + + private Amenity parseAmenity(PoiSearchObject searchItem) { + + String categoryName = ""; + String subcategoryName = ""; + Map values = new HashMap<>(); + + net.osmand.core.jni.Amenity coreAmenity = searchItem.getAmenity(); + 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(searchItem.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().getIcon(st.getOsmTag() + "_" + st.getOsmValue()); + } + return drawable; + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PostcodeSearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PostcodeSearchListItem.java new file mode 100644 index 0000000000..dc94d8957b --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/PostcodeSearchListItem.java @@ -0,0 +1,29 @@ +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 searchItem) { + super(app, searchItem); + + nameStr = searchItem.getNativeName(); + typeStr = "Postcode"; + } + + @Override + public String getName() { + return nameStr; + } + + @Override + public String getTypeName() { + return typeStr; + } +} 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 df69def47a..2b1a3ef47a 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 @@ -25,8 +25,11 @@ public class SearchListAdapter extends ArrayAdapter { public void updateDistance(double latitude, double longitude) { for (int i = 0; i < getCount(); i++) { SearchListItem item = getItem(i); - item.setDistance(Utilities.distance( - longitude, latitude, item.getLongitude(), item.getLatitude())); + if (item instanceof SearchListPositionItem) { + SearchListPositionItem positionItem = (SearchListPositionItem) item; + positionItem.setDistance(Utilities.distance( + longitude, latitude, positionItem.getLongitude(), positionItem.getLatitude())); + } } } @@ -51,11 +54,17 @@ public class SearchListAdapter extends ArrayAdapter { imageView.setImageDrawable(listItem.getIcon()); title.setText(listItem.getName()); - subtitle.setText(listItem.getType()); - if (listItem.getDistance() == 0) { - distance.setText(""); + subtitle.setText(listItem.getTypeName()); + if (listItem instanceof SearchListPositionItem) { + SearchListPositionItem positionItem = (SearchListPositionItem) listItem; + if (positionItem.getDistance() == 0) { + distance.setText(""); + } else { + distance.setText(Utils.getFormattedDistance(positionItem.getDistance())); + } + distance.setVisibility(View.VISIBLE); } else { - distance.setText(Utils.getFormattedDistance(listItem.getDistance())); + distance.setVisibility(View.INVISIBLE); } return view; } 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 fbd5459389..251e2980b5 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 @@ -3,52 +3,49 @@ 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.items.AddressSearchItem; -import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem; -import net.osmand.core.samples.android.sample1.search.items.SearchItem; +import net.osmand.core.samples.android.sample1.search.objects.CitySearchObject; +import net.osmand.core.samples.android.sample1.search.objects.PoiSearchObject; +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.StreetSearchObject; +import net.osmand.core.samples.android.sample1.search.objects.VillageSearchObject; public class SearchListItem { protected SampleApplication app; - private SearchItem searchItem; + private SearchObject searchObject; - public SearchListItem(SampleApplication app, SearchItem searchItem) { + public SearchListItem(SampleApplication app, SearchObject searchObject) { this.app = app; - this.searchItem = searchItem; + this.searchObject = searchObject; } - public static SearchListItem buildListItem(SampleApplication app, SearchItem item) { - - if (item instanceof AmenitySearchItem) { - return new AmenitySearchListItem(app, (AmenitySearchItem) item); - } else if (item instanceof AddressSearchItem) { - return new AddressSearchListItem(app, (AddressSearchItem) item); + public static SearchListItem buildListItem(SampleApplication app, SearchObject item) { + switch (item.getType()) { + case POI: + return new PoiSearchListItem(app, (PoiSearchObject) item); + case STREET: + return new StreetSearchListItem(app, (StreetSearchObject) item); + case CITY: + return new CitySearchListItem(app, (CitySearchObject) item); + case VILLAGE: + return new VillageSearchListItem(app, (VillageSearchObject) item); + case POSTCODE: + return new PostcodeSearchListItem(app, (PostcodeSearchObject) item); } return null; } - public double getLatitude() { - return searchItem.getLatitude(); - } - - public double getLongitude() { - return searchItem.getLongitude(); + protected SearchObject getSearchObject() { + return searchObject; } public String getName() { - return searchItem.getName(); + return searchObject.getNativeName(); } - public String getType() { - return searchItem.getType(); - } - - public double getDistance() { - return searchItem.getDistance(); - } - - public void setDistance(double distance) { - searchItem.setDistance(distance); + public String getTypeName() { + return searchObject.getType().name(); } public Drawable getIcon() { 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 new file mode 100644 index 0000000000..34034cbe23 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListPositionItem.java @@ -0,0 +1,44 @@ +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.SearchObject; +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 searchObject) { + super(app, searchObject); + PointI position31 = searchObject.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); + } + +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/StreetSearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/StreetSearchListItem.java new file mode 100644 index 0000000000..565f803404 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/StreetSearchListItem.java @@ -0,0 +1,45 @@ +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 SearchListItem { + private String nameStr; + private String typeStr; + + public StreetSearchListItem(SampleApplication app, StreetSearchObject searchItem) { + super(app, searchItem); + + nameStr = searchItem.getName(MapUtils.LANGUAGE); + + StreetGroup streetGroup = searchItem.getStreet().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; + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/VillageSearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/VillageSearchListItem.java new file mode 100644 index 0000000000..f374ca2817 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/VillageSearchListItem.java @@ -0,0 +1,29 @@ +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.VillageSearchObject; + +public class VillageSearchListItem extends SearchListPositionItem{ + + private String nameStr; + private String typeStr; + + public VillageSearchListItem(SampleApplication app, VillageSearchObject searchItem) { + super(app, searchItem); + + nameStr = searchItem.getName(MapUtils.LANGUAGE); + typeStr = "Village"; + } + + @Override + public String getName() { + return nameStr; + } + + @Override + public String getTypeName() { + return typeStr; + } +} 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 fd8703e5d8..9223e9f618 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 @@ -5,11 +5,13 @@ import android.support.annotation.NonNull; 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.items.SearchItem; +import net.osmand.core.samples.android.sample1.search.objects.SearchObject; 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.SearchToken; +import java.util.ArrayList; import java.util.List; public class SearchAPI { @@ -17,23 +19,44 @@ public class SearchAPI { private ObfsCollection obfsCollection; private AreaI searchableArea; private AreaI obfAreaFilter; - private PointI searchLocation; + private PointI searchLocation31; private double searchRadius; + private String lang; private SearchRequestExecutor executor; private SearchString searchString; - private SearchScope searchScope; - private List searchItems; + private List searchObjects; - public interface SearchCallback { - void onSearchFinished(List searchItems); + private SearchCallbackInternal internalCallback = new SearchCallbackInternal() { + @Override + public void onSearchObjectsFound(List searchObjects) { + setSearchObjects(searchObjects); + } + + @Override + public void onNewTokenFound(SearchToken oldToken, SearchToken newToken) { + searchString.replaceToken(oldToken, newToken); + } + }; + + public interface SearchApiCallback { + void onSearchFinished(List searchObjects); } - public SearchAPI(@NonNull ObfsCollection obfsCollection) { + public interface SearchCallbackInternal { + void onSearchObjectsFound(List 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(); - this.searchScope = new SearchScope(this); + this.lang = lang; + } + + public String getLang() { + return lang; } public AreaI getSearchableArea() { @@ -52,12 +75,12 @@ public class SearchAPI { this.obfAreaFilter = obfAreaFilter; } - public PointI getSearchLocation() { - return searchLocation; + public PointI getSearchLocation31() { + return searchLocation31; } - public void setSearchLocation(PointI searchLocation) { - this.searchLocation = searchLocation; + public void setSearchLocation31(PointI position31) { + this.searchLocation31 = position31; } public double getSearchRadius() { @@ -72,35 +95,32 @@ public class SearchAPI { return obfsCollection; } - public SearchString getSearchString() { - return searchString; + public SearchString getSearchStringCopy() { + return searchString.copy(); } - public SearchScope getSearchScope() { - return searchScope; + public List getSearchObjects() { + return searchObjects; } - public List getSearchItems() { - return searchItems; - } - - public void setSearchItems(List searchItems) { - this.searchItems = searchItems; + public void setSearchObjects(List searchObjects) { + this.searchObjects = searchObjects; } public void startSearch(String query, int maxSearchResults, - SearchCallback intermediateSearchCallback, - SearchCallback coreSearchCallback) { + SearchApiCallback intermediateSearchCallback, + SearchApiCallback coreSearchCallback) { searchString.setQueryText(query); - searchScope.updateScope(); + SearchScope searchScope = new SearchScope(this); IntermediateSearchRequest intermediateSearchRequest = null; - if (searchItems != null && !searchItems.isEmpty()) { + if (searchObjects != null && !searchObjects.isEmpty()) { intermediateSearchRequest = - new IntermediateSearchRequest(this, maxSearchResults, intermediateSearchCallback); + new IntermediateSearchRequest(searchScope, new ArrayList<>(searchObjects), + maxSearchResults, intermediateSearchCallback); } - executor.run(new CoreSearchRequest(intermediateSearchRequest, this, - maxSearchResults, coreSearchCallback), true); + executor.run(new CoreSearchRequest(intermediateSearchRequest, searchScope, + maxSearchResults, coreSearchCallback, internalCallback), true); } public void cancelSearch() { 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 a5cbc3a25b..2cebb96d18 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 @@ -2,117 +2,190 @@ package net.osmand.core.samples.android.sample1.search; import net.osmand.core.jni.AddressesByNameSearch; import net.osmand.core.jni.AmenitiesByNameSearch; -import net.osmand.core.jni.LatLon; -import net.osmand.core.jni.QStringList; -import net.osmand.core.jni.QStringStringListHash; +import net.osmand.core.jni.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.Street; import net.osmand.core.jni.Utilities; -import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem; -import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem; -import net.osmand.core.samples.android.sample1.search.items.SearchItem; -import net.osmand.core.samples.android.sample1.search.tokens.CitySearchToken; -import net.osmand.core.samples.android.sample1.search.tokens.PoiTypeSearchToken; -import net.osmand.core.samples.android.sample1.search.tokens.PostcodeSearchToken; +import net.osmand.core.samples.android.sample1.search.objects.PoiSearchObject; +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 net.osmand.core.samples.android.sample1.search.tokens.SearchToken.TokenType; import net.osmand.util.Algorithms; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; public class SearchScope { - private SearchAPI searchAPI; - private Map resolvedTokens; - private double searchLat; - private double searchLon; + private ObfsCollection obfsCollection; + private SearchString searchString; + private String lang; + private Map objectTokens; + private PointI searchLocation31; + private AreaI searchableArea; + private AreaI obfAreaFilter; private double searchRadius; public SearchScope(SearchAPI searchAPI) { - this.searchAPI = searchAPI; - } - - public void updateScope() { - resolvedTokens = searchAPI.getSearchString().getResolvedTokens(); - LatLon latLon = Utilities.convert31ToLatLon(searchAPI.getSearchLocation()); - searchLat = latLon.getLatitude(); - searchLon = latLon.getLongitude(); + obfsCollection = searchAPI.getObfsCollection(); + lang = searchAPI.getLang(); + searchString = searchAPI.getSearchStringCopy(); + objectTokens = searchString.getObjectTokens(); + searchLocation31 = searchAPI.getSearchLocation31(); + searchableArea = searchAPI.getSearchableArea(); + obfAreaFilter = searchAPI.getObfAreaFilter(); searchRadius = searchAPI.getSearchRadius(); } + public ObfsCollection getObfsCollection() { + return obfsCollection; + } + + public String getLang() { + return lang; + } + + public SearchString getSearchString() { + return searchString; + } + + public Map getObjectTokens() { + return objectTokens; + } + + 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) { - String categoryName = null; - String typeName = null; - if (resolvedTokens.containsKey(TokenType.POI_TYPE)) { - PoiTypeSearchToken token = (PoiTypeSearchToken)resolvedTokens.get(TokenType.POI_TYPE); - categoryName = token.getPoiType().getCategory().getKeyName(); - typeName = token.getName(); - } else if (resolvedTokens.containsKey(TokenType.POI_FILTER)) { - SearchToken token = resolvedTokens.get(TokenType.POI_FILTER); - categoryName = token.getName(); - } else if (resolvedTokens.containsKey(TokenType.POI_CATEGORY)) { - SearchToken token = resolvedTokens.get(TokenType.POI_CATEGORY); - categoryName = token.getName(); - } - if (!Algorithms.isEmpty(categoryName) && !Algorithms.isEmpty(typeName)) { - QStringStringListHash list = new QStringStringListHash(); - QStringList stringList = new QStringList(); - //todo list.set(categoryName, stringList); - criteria.setCategoriesFilter(list); - } else if (!Algorithms.isEmpty(categoryName)) { - QStringStringListHash list = new QStringStringListHash(); - //todo list.set(categoryName, new QStringList()); - criteria.setCategoriesFilter(list); - } + //todo criteria.setCategoriesFilter() if needed; } public void setupAddressSearchCriteria(AddressesByNameSearch.Criteria criteria) { //not implemented } - public boolean processAmenitySearchItem(AmenitySearchItem item) { - boolean res = true; - updateDistance(item); - if (searchRadius > 0) { - res = item.getDistance() < searchRadius; - } - return res; + public boolean processPoiSearchObject(PoiSearchObject poiSearchObject) { + updateDistance(poiSearchObject); + return true; } - public boolean processAddressSearchItem(AddressSearchItem item) { - boolean res = true; - if (resolvedTokens.containsKey(TokenType.CITY) && item.getParentCityObfId() != null) { - CitySearchToken token = (CitySearchToken)resolvedTokens.get(TokenType.CITY); - res = token.getObfId().equals(item.getParentCityObfId()); - } else if (resolvedTokens.containsKey(TokenType.POSTCODE) && item.getParentPostcodeObfId() != null) { - PostcodeSearchToken token = (PostcodeSearchToken)resolvedTokens.get(TokenType.CITY); - res = token.getObfId().equals(item.getParentPostcodeObfId()); - } - if (res) { - updateDistance(item); - } - return res; + public boolean processAddressSearchObject(SearchPositionObject addressSearchObject) { + updateDistance(addressSearchObject); + return true; } - public void processSearchResult(List searchItems) { - /* - Collections.sort(searchItems, new Comparator() { - @Override - public int compare(SearchItem lhs, SearchItem rhs) { - int res = Double.compare(lhs.getDistance(), rhs.getDistance()); - if (res == 0) { - return lhs.getName().compareToIgnoreCase(rhs.getName()); - } else { - return res; - } + public SearchToken processSearchResult(SearchToken token, List searchObjects) { + + SearchToken newToken = null; + + boolean cityVillagePostcodeSelected = objectTokens.containsKey(SearchObjectType.CITY) + || objectTokens.containsKey(SearchObjectType.VILLAGE) + || objectTokens.containsKey(SearchObjectType.POSTCODE); + + for (SearchObject searchObject : searchObjects) { + float priority = 0f; + boolean sortByName = false; + switch (searchObject.getType()) { + case POI: + priority = getPriorityByDistance(10, ((PoiSearchObject) searchObject).getDistance()); + break; + case CITY: + case VILLAGE: + case POSTCODE: + float cityType = getCityType((StreetGroupSearchObject) searchObject); + priority = (getPriorityByDistance(cityVillagePostcodeSelected + ? 20f : 7f + cityType, ((StreetGroupSearchObject) searchObject).getDistance())); + break; + + case STREET: + StreetSearchObject streetSearchObject = (StreetSearchObject) searchObject; + Street street = streetSearchObject.getStreet(); + if (!cityVillagePostcodeSelected) { + priority = getPriorityByDistance(9f, streetSearchObject.getDistance()); + } else { + boolean streetFromSelectedCity = false; + for (SearchToken st : objectTokens.values()) { + if (st.getSearchObject() instanceof StreetGroupSearchObject) { + StreetGroupSearchObject streetGroupSearchObject = (StreetGroupSearchObject) st.getSearchObject(); + if (streetGroupSearchObject.getStreetGroup().getId().getId() + .equals(street.getStreetGroup().getId().getId())) { + streetFromSelectedCity = true; + break; + } + } + } + if (streetFromSelectedCity) { + priority = 3f; + sortByName = true; + } else { + priority = getPriorityByDistance(9f, streetSearchObject.getDistance()); + } + } + break; } - }); - */ + searchObject.setPriority(priority); + searchObject.setSortByName(sortByName); + } - //todo + if (searchObjects.size() > 0) { + Collections.sort(searchObjects, new Comparator() { + @Override + public int compare(SearchObject lhs, SearchObject rhs) { + int res = Double.compare(lhs.getPriority(), rhs.getPriority()); + if (res == 0 && lhs.isSortByName() && rhs.isSortByName()) { + return lhs.getName(lang).compareToIgnoreCase(rhs.getName(lang)); + } else { + return res; + } + } + }); + + if (token.getType() == SearchToken.TokenType.NAME_FILTER + && !Algorithms.isEmpty(token.getQueryText())) { + newToken = new ObjectSearchToken(token, searchObjects.get(0)); + } + } + return newToken; } - private void updateDistance(SearchItem item) { - item.setDistance(Utilities.distance( - searchLon, searchLat, item.getLongitude(), item.getLatitude())); + private float getCityType(StreetGroupSearchObject searchObject) { + if (searchObject.getStreetGroup().getType() == ObfAddressStreetGroupType.CityOrTown) { + if (searchObject.getStreetGroup().getSubtype() == ObfAddressStreetGroupSubtype.City) { + return 1f; + } else if (searchObject.getStreetGroup().getSubtype() == ObfAddressStreetGroupSubtype.Town) { + return 1.5f; + } + } + return 2.5f; + } + + private float getPriorityByDistance(float priority, double distance) { + return priority + (float)(1 / (1 + distance)); + } + + private void updateDistance(SearchPositionObject item) { + item.setDistance(Utilities.distance31(searchLocation31, item.getPosition31())); } } 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 f838a2a276..3a01cef4d8 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 @@ -1,8 +1,10 @@ package net.osmand.core.samples.android.sample1.search; +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.SearchToken; import net.osmand.core.samples.android.sample1.search.tokens.SearchToken.TokenType; +import net.osmand.util.Algorithms; import java.util.ArrayList; import java.util.HashMap; @@ -17,11 +19,18 @@ public class SearchString { public SearchString() { } + public SearchString copy() { + SearchString res = new SearchString(); + res.queryText = queryText; + res.tokens = new ArrayList<>(tokens); + return res; + } + public String getQueryText() { return queryText; } - public synchronized void setQueryText(String queryText) { + public void setQueryText(String queryText) { int newTextLength = queryText.length(); int currTextLength = this.queryText.length(); boolean isNewText = currTextLength == 0 @@ -73,12 +82,19 @@ public class SearchString { if (firstWordIndex <= newTextLength - 1) { SearchToken token = new NameFilterSearchToken(firstWordIndex, queryText.substring(firstWordIndex)); tokens.add(token); + } else if (endWithDelimeter(queryText)) { + SearchToken token = new NameFilterSearchToken(firstWordIndex, ""); + tokens.add(token); } } this.queryText = queryText; } + 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); @@ -88,7 +104,7 @@ public class SearchString { return c == ',' || c == ' '; } - public synchronized SearchToken getNextNameFilterToken() { + public SearchToken getNextNameFilterToken() { SearchToken res = null; if (!tokens.isEmpty()) { for (int i = tokens.size() - 1; i >= 0; i--) { @@ -103,18 +119,18 @@ public class SearchString { return res; } - public synchronized SearchToken getLastToken() { + public SearchToken getLastToken() { if (!tokens.isEmpty()) { return tokens.get(tokens.size() - 1); } return null; } - public synchronized boolean hasNameFilterTokens() { + public boolean hasNameFilterTokens() { return getNextNameFilterToken() != null; } - public synchronized boolean replaceToken(SearchToken oldToken, SearchToken newToken) { + public boolean replaceToken(SearchToken oldToken, SearchToken newToken) { int index = tokens.indexOf(oldToken); if (index != -1) { tokens.set(index, newToken); @@ -123,11 +139,11 @@ public class SearchString { return false; } - public synchronized Map getResolvedTokens() { - Map map = new HashMap<>(); + public Map getObjectTokens() { + Map map = new HashMap<>(); for (SearchToken token : tokens) { - if (token.getType() != SearchToken.TokenType.NAME_FILTER) { - map.put(token.getType(), token); + if (token.getType() == TokenType.SEARCH_OBJECT) { + map.put(token.getSearchObject().getType(), token); } } return map; diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/AddressSearchItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/AddressSearchItem.java deleted file mode 100644 index c1acab1981..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/AddressSearchItem.java +++ /dev/null @@ -1,111 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.items; - -import net.osmand.core.jni.Address; -import net.osmand.core.jni.ObfAddressStreetGroupSubtype; -import net.osmand.core.jni.ObfAddressStreetGroupType; -import net.osmand.core.jni.Street; -import net.osmand.core.jni.StreetGroup; -import net.osmand.util.Algorithms; - -import java.math.BigInteger; - -public class AddressSearchItem extends SearchItem { - - private String namePrefix; - private String nameSuffix; - private String typeStr; - - private BigInteger parentCityObfId; - private BigInteger parentPostcodeObfId; - - public AddressSearchItem(Address address) { - super(); - - switch (address.getAddressType()) { - case Street: - StreetInternal street = new StreetInternal(address); - setLocation(street.getPosition31()); - setNativeName(street.getNativeName()); - addLocalizedNames(street.getLocalizedNames()); - if (street.getStreetGroup() != null) { - StreetGroup streetGroup = street.getStreetGroup(); - nameSuffix = "st."; - typeStr = streetGroup.getNativeName() + " — " + getTypeStr(streetGroup); - if (streetGroup.getType() == ObfAddressStreetGroupType.Postcode) { - parentPostcodeObfId = streetGroup.getId().getId(); - } else { - parentCityObfId = streetGroup.getId().getId(); - } - } else { - typeStr = "Street"; - } - break; - - case StreetGroup: - StreetGroupInternal streetGroup = new StreetGroupInternal(address); - setLocation(streetGroup.getPosition31()); - setNativeName(streetGroup.getNativeName()); - addLocalizedNames(streetGroup.getLocalizedNames()); - typeStr = getTypeStr(streetGroup); - break; - } - } - - public String getNamePrefix() { - return namePrefix; - } - - public String getNameSuffix() { - return nameSuffix; - } - - @Override - public String getName() { - StringBuilder sb = new StringBuilder(); - if (!Algorithms.isEmpty(namePrefix)) { - sb.append(namePrefix); - sb.append(" "); - } - sb.append(super.getName()); - if (!Algorithms.isEmpty(nameSuffix)) { - sb.append(" "); - sb.append(nameSuffix); - } - return sb.toString(); - } - - @Override - public String getType() { - return typeStr; - } - - private String getTypeStr(StreetGroup streetGroup) { - String typeStr; - if (streetGroup.getSubtype() != ObfAddressStreetGroupSubtype.Unknown) { - typeStr = streetGroup.getSubtype().name(); - } else { - typeStr = streetGroup.getType().name(); - } - return typeStr; - } - - public BigInteger getParentCityObfId() { - return parentCityObfId; - } - - public BigInteger getParentPostcodeObfId() { - return parentPostcodeObfId; - } - - private class StreetInternal extends Street { - public StreetInternal(Address address) { - super(Address.getCPtr(address), false); - } - } - - private class StreetGroupInternal extends StreetGroup { - public StreetGroupInternal(Address address) { - super(Address.getCPtr(address), false); - } - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/AmenitySearchItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/AmenitySearchItem.java deleted file mode 100644 index 10c8ff83e4..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/AmenitySearchItem.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.items; - -import net.osmand.core.jni.Amenity; -import net.osmand.core.jni.DecodedCategoryList; -import net.osmand.core.jni.DecodedValueList; -import net.osmand.util.Algorithms; - -import java.util.HashMap; -import java.util.Map; - -public class AmenitySearchItem extends SearchItem { - - private String category; - private String subcategory; - private Map values = new HashMap<>(); - - public AmenitySearchItem(Amenity amenity) { - super(amenity.getPosition31()); - - setNativeName(amenity.getNativeName()); - addLocalizedNames(amenity.getLocalizedNames()); - - DecodedCategoryList catList = amenity.getDecodedCategories(); - if (catList.size() > 0) { - Amenity.DecodedCategory decodedCategory = catList.get(0); - category = decodedCategory.getCategory(); - subcategory = decodedCategory.getSubcategory(); - } - - DecodedValueList decodedValueList = amenity.getDecodedValues(); - if (decodedValueList.size() > 0) { - for (int i = 0; i < decodedValueList.size(); i++) { - Amenity.DecodedValue decodedValue = decodedValueList.get(i); - String tag = decodedValue.getDeclaration().getTagName(); - String value = decodedValue.getValue(); - values.put(tag, value); - } - } - } - - public String getCategory() { - return category; - } - - public String getSubcategory() { - return subcategory; - } - - public Map getValues() { - return values; - } - - @Override - public String getType() { - return Algorithms.capitalizeFirstLetterAndLowercase(subcategory); - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/SearchItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/SearchItem.java deleted file mode 100644 index 6ed64e9b9f..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/items/SearchItem.java +++ /dev/null @@ -1,97 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.items; - -import net.osmand.core.jni.LatLon; -import net.osmand.core.jni.PointI; -import net.osmand.core.jni.QStringList; -import net.osmand.core.jni.QStringStringHash; -import net.osmand.core.jni.Utilities; - -import java.util.HashMap; -import java.util.Map; - -public abstract class SearchItem { - - protected double latitude; - protected double longitude; - protected String nativeName; - protected Map localizedNames = new HashMap<>(); - - private double distance; - private float priority; - - protected SearchItem() { - } - - protected SearchItem(double latitude, double longitude) { - this.latitude = latitude; - this.longitude = longitude; - } - - protected SearchItem(PointI location31) { - LatLon latLon = Utilities.convert31ToLatLon(location31); - latitude = latLon.getLatitude(); - longitude = latLon.getLongitude(); - } - - public String getName() { - return nativeName; - } - - public abstract String getType(); - - public double getLatitude() { - return latitude; - } - - public double getLongitude() { - return longitude; - } - - public String getNativeName() { - return nativeName; - } - - public Map getLocalizedNames() { - return localizedNames; - } - - protected void setLocation(PointI location31) { - LatLon latLon = Utilities.convert31ToLatLon(location31); - latitude = latLon.getLatitude(); - longitude = latLon.getLongitude(); - } - - protected void setNativeName(String nativeName) { - this.nativeName = nativeName; - } - - protected void addLocalizedNames(QStringStringHash localizedNames) { - QStringList locNamesKeys = localizedNames.keys(); - for (int i = 0; i < locNamesKeys.size(); i++) { - String key = locNamesKeys.get(i); - String val = localizedNames.get(key); - this.localizedNames.put(key, val); - } - } - - public double getDistance() { - return distance; - } - - public void setDistance(double distance) { - this.distance = distance; - } - - public float getPriority() { - return priority; - } - - public void setPriority(float priority) { - this.priority = priority; - } - - @Override - public String toString() { - return getName() + " (" + getType() + ") {lat:" + getLatitude() + " lon: " + getLongitude() + "}"; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/CitySearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/CitySearchObject.java new file mode 100644 index 0000000000..adc1070a5e --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/CitySearchObject.java @@ -0,0 +1,10 @@ +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); + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/CoordinatesSearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/CoordinatesSearchObject.java new file mode 100644 index 0000000000..e5b7ef83d8 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/CoordinatesSearchObject.java @@ -0,0 +1,26 @@ +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 { + + public CoordinatesSearchObject(PointI position31) { + super(SearchObjectType.COORDINATES, position31); + } + + @Override + public PointI getPosition31() { + return (PointI) getInternalObject(); + } + + @Override + public String getNativeName() { + return null; + } + + @Override + protected QStringStringHash getLocalizedNames() { + return null; + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PoiSearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PoiSearchObject.java new file mode 100644 index 0000000000..8aa7589de5 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PoiSearchObject.java @@ -0,0 +1,31 @@ +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 { + + public PoiSearchObject(Amenity amenity) { + super(SearchObjectType.POI, amenity); + } + + public Amenity getAmenity() { + return (Amenity) getInternalObject(); + } + + @Override + public PointI getPosition31() { + return getAmenity().getPosition31(); + } + + @Override + public String getNativeName() { + return getAmenity().getNativeName(); + } + + @Override + protected QStringStringHash getLocalizedNames() { + return getAmenity().getLocalizedNames(); + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PostcodeSearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PostcodeSearchObject.java new file mode 100644 index 0000000000..8d2348b43b --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/PostcodeSearchObject.java @@ -0,0 +1,12 @@ +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); + } +} 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 new file mode 100644 index 0000000000..f2c07c44c6 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObject.java @@ -0,0 +1,84 @@ +package net.osmand.core.samples.android.sample1.search.objects; + +import net.osmand.core.jni.QStringStringHash; + +public abstract class SearchObject { + + public enum SearchObjectType { + CITY, + VILLAGE, + POSTCODE, + STREET, + BUILDING, + POI_TYPE, + POI_FILTER, + POI, + COORDINATES + } + + private SearchObjectType type; + private Object internalObject; + + private float priority; + private boolean sortByName; + + protected SearchObject(SearchObjectType type, Object internalObject) { + this.type = type; + this.internalObject = internalObject; + } + + public SearchObjectType getType() { + return type; + } + + protected Object getInternalObject() { + return internalObject; + } + + 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 float getPriority() { + return priority; + } + + public void setPriority(float priority) { + this.priority = priority; + } + + public boolean isSortByName() { + return sortByName; + } + + public void setSortByName(boolean sortByName) { + this.sortByName = sortByName; + } + + protected abstract QStringStringHash getLocalizedNames(); + + @Override + public String toString() { + return "SearchObject: " + getNativeName(); + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObjectsHelper.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObjectsHelper.java new file mode 100644 index 0000000000..03fad96f65 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchObjectsHelper.java @@ -0,0 +1,42 @@ +package net.osmand.core.samples.android.sample1.search.objects; + +import net.osmand.core.jni.Address; +import net.osmand.core.jni.Street; +import net.osmand.core.jni.StreetGroup; + +public class SearchObjectsHelper { + + public static SearchPositionObject getAddressObject(Address address) { + + switch (address.getAddressType()) { + 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 StreetInternal extends Street { + public StreetInternal(Address address) { + super(Address.getCPtr(address), false); + } + } + + private static class StreetGroupInternal extends StreetGroup { + public StreetGroupInternal(Address address) { + super(Address.getCPtr(address), false); + } + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchPositionObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchPositionObject.java new file mode 100644 index 0000000000..799040aef0 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/SearchPositionObject.java @@ -0,0 +1,29 @@ +package net.osmand.core.samples.android.sample1.search.objects; + +import net.osmand.core.jni.PointI; + +public abstract class SearchPositionObject extends SearchObject { + + private double distance; + + public SearchPositionObject(SearchObjectType type, Object internalObject) { + super(type, internalObject); + } + + 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() + "}"; + } + +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/StreetGroupSearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/StreetGroupSearchObject.java new file mode 100644 index 0000000000..39b093629d --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/StreetGroupSearchObject.java @@ -0,0 +1,31 @@ +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 { + + public StreetGroupSearchObject(SearchObjectType type, StreetGroup streetGroup) { + super(type, streetGroup); + } + + public StreetGroup getStreetGroup() { + return (StreetGroup) getInternalObject(); + } + + @Override + public PointI getPosition31() { + return getStreetGroup().getPosition31(); + } + + @Override + public String getNativeName() { + return getStreetGroup().getNativeName(); + } + + @Override + protected QStringStringHash getLocalizedNames() { + return getStreetGroup().getLocalizedNames(); + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/StreetSearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/StreetSearchObject.java new file mode 100644 index 0000000000..052860465f --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/StreetSearchObject.java @@ -0,0 +1,31 @@ +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 { + + public StreetSearchObject(Street street) { + super(SearchObjectType.STREET, street); + } + + public Street getStreet() { + return (Street) getInternalObject(); + } + + @Override + public PointI getPosition31() { + return getStreet().getPosition31(); + } + + @Override + public String getNativeName() { + return getStreet().getNativeName(); + } + + @Override + protected QStringStringHash getLocalizedNames() { + return getStreet().getLocalizedNames(); + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/VillageSearchObject.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/VillageSearchObject.java new file mode 100644 index 0000000000..f7c3da23d6 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/objects/VillageSearchObject.java @@ -0,0 +1,12 @@ +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); + } +} 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 ddb693bf22..16a48b8e97 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 @@ -10,12 +10,16 @@ import net.osmand.core.jni.Amenity; import net.osmand.core.jni.IQueryController; import net.osmand.core.jni.ISearch; import net.osmand.core.jni.NullableAreaI; -import net.osmand.core.samples.android.sample1.search.SearchAPI; -import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback; -import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem; -import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem; -import net.osmand.core.samples.android.sample1.search.items.SearchItem; +import net.osmand.core.samples.android.sample1.search.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.objects.SearchObjectsHelper; +import net.osmand.core.samples.android.sample1.search.objects.SearchPositionObject; import net.osmand.core.samples.android.sample1.search.tokens.SearchToken; +import net.osmand.util.Algorithms; import java.util.ArrayList; import java.util.List; @@ -24,14 +28,18 @@ 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 SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) { - super(searchAPI, maxSearchResults, searchCallback); + @NonNull SearchScope searchScope, int maxSearchResults, + @Nullable SearchApiCallback searchCallback, + @Nullable SearchCallbackInternal internalCallback) { + super(searchScope, maxSearchResults, searchCallback); this.intermediateSearchRequest = intermediateSearchRequest; + this.internalCallback = internalCallback; } @Override @@ -51,11 +59,13 @@ public class CoreSearchRequest extends SearchRequest { } @Override - protected void onSearchRequestPostExecute(List searchItems) { + protected void onSearchRequestPostExecute(List searchObjects) { if (intermediateSearchRequest != null && !intermediateSearchDone) { intermediateSearchRequest.cancel(); } - searchAPI.setSearchItems(searchItems); + if (internalCallback != null) { + internalCallback.onSearchObjectsFound(searchObjects); + } } @Override @@ -67,37 +77,42 @@ public class CoreSearchRequest extends SearchRequest { } @Override - protected List doSearch() { + protected List doSearch() { - List res = new ArrayList<>(); + List res = new ArrayList<>(); + SearchString searchString = searchScope.getSearchString(); + SearchToken lastToken = searchString.getLastToken(); SearchToken token = searchString.getNextNameFilterToken(); while (token != null && !cancelled) { - if (token.getType() == SearchToken.TokenType.NAME_FILTER) { - List searchItems = doCoreSearch(token); - res.clear(); - res.addAll(searchItems); + if (token.getType() == SearchToken.TokenType.NAME_FILTER + && !Algorithms.isEmpty(token.getQueryText())) { + res = doCoreSearch(token); + } + if (token != lastToken) { + token = searchString.getNextNameFilterToken(); + } else { + break; } - token = searchString.getNextNameFilterToken(); } return res; } - private List doCoreSearch(@NonNull SearchToken token) { + private List doCoreSearch(@NonNull SearchToken token) { System.out.println("=== Start search"); amenityResultsCounter = 0; addressResultsCounter = 0; String keyword = token.getQueryText(); - final List searchItems = new ArrayList<>(); + final List searchObjects = new ArrayList<>(); // Setup Amenities by name search - AmenitiesByNameSearch amByNameSearch = new AmenitiesByNameSearch(searchAPI.getObfsCollection()); + AmenitiesByNameSearch amByNameSearch = new AmenitiesByNameSearch(searchScope.getObfsCollection()); AmenitiesByNameSearch.Criteria amenityByNameCriteria = new AmenitiesByNameSearch.Criteria(); amenityByNameCriteria.setName(keyword); - if (searchAPI.getObfAreaFilter() != null) { - amenityByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchAPI.getObfAreaFilter())); + if (searchScope.getObfAreaFilter() != null) { + amenityByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchScope.getObfAreaFilter())); } searchScope.setupAmenitySearchCriteria(amenityByNameCriteria); @@ -105,9 +120,9 @@ public class CoreSearchRequest extends SearchRequest { @Override public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) { Amenity amenity = new AmenityResultEntry(resultEntry).getAmenity(); - AmenitySearchItem amenitySearchItem = new AmenitySearchItem(amenity); - if (searchScope.processAmenitySearchItem(amenitySearchItem)) { - searchItems.add(amenitySearchItem); + PoiSearchObject amenitySearchItem = new PoiSearchObject(amenity); + if (searchScope.processPoiSearchObject(amenitySearchItem)) { + searchObjects.add(amenitySearchItem); } System.out.println("Poi found === " + amenitySearchItem.toString()); amenityResultsCounter++; @@ -115,11 +130,11 @@ public class CoreSearchRequest extends SearchRequest { }; // Setup Addresses by name search - AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(searchAPI.getObfsCollection()); - AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria(); + AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(searchScope.getObfsCollection()); + final AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria(); addrByNameCriteria.setName(keyword); - if (searchAPI.getObfAreaFilter() != null) { - addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchAPI.getObfAreaFilter())); + if (searchScope.getObfAreaFilter() != null) { + addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchScope.getObfAreaFilter())); } searchScope.setupAddressSearchCriteria(addrByNameCriteria); @@ -127,12 +142,14 @@ public class CoreSearchRequest extends SearchRequest { @Override public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) { Address address = new AddressResultEntry(resultEntry).getAddress(); - AddressSearchItem addrSearchItem = new AddressSearchItem(address); - if (searchScope.processAddressSearchItem(addrSearchItem)) { - searchItems.add(addrSearchItem); + SearchPositionObject addressSearchObject = SearchObjectsHelper.getAddressObject(address); + if (addressSearchObject != null) { + if (searchScope.processAddressSearchObject(addressSearchObject)) { + searchObjects.add(addressSearchObject); + } + System.out.println("Address found === " + addressSearchObject.toString()); + addressResultsCounter++; } - System.out.println("Address found === " + addrSearchItem.toString()); - addressResultsCounter++; } }; @@ -153,12 +170,15 @@ public class CoreSearchRequest extends SearchRequest { } if (!cancelled) { - searchScope.processSearchResult(searchItems); + SearchToken newToken = searchScope.processSearchResult(token, searchObjects); + if (newToken != null && internalCallback != null) { + internalCallback.onNewTokenFound(token, newToken); + } } System.out.println("=== Finish search"); - return searchItems; + return searchObjects; } private class AmenityResultEntry extends AmenitiesByNameSearch.ResultEntry { diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/IntermediateSearchRequest.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/IntermediateSearchRequest.java index af968db2f9..12a14a74b3 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/IntermediateSearchRequest.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/IntermediateSearchRequest.java @@ -3,10 +3,9 @@ package net.osmand.core.samples.android.sample1.search.requests; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import net.osmand.core.samples.android.sample1.search.SearchAPI; -import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback; -import net.osmand.core.samples.android.sample1.search.items.SearchItem; -import net.osmand.core.samples.android.sample1.search.requests.SearchRequest; +import net.osmand.core.samples.android.sample1.search.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; @@ -14,27 +13,29 @@ import java.util.List; public class IntermediateSearchRequest extends SearchRequest { - private List searchItems; + private List searchObjects; protected String keyword = ""; - public IntermediateSearchRequest(@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) { - super(searchAPI, maxSearchResults, searchCallback); - this.searchItems = new ArrayList<>(searchAPI.getSearchItems()); + public IntermediateSearchRequest(@NonNull SearchScope searchScope, List searchObjects, + int maxSearchResults, @Nullable SearchApiCallback searchCallback) { + super(searchScope, maxSearchResults, searchCallback); + this.searchObjects = searchObjects; - SearchToken token = searchString.getLastToken(); + SearchToken token = searchScope.getSearchString().getLastToken(); if (token != null && token.getType() == SearchToken.TokenType.NAME_FILTER) { - keyword = token.getQueryText(); + keyword = token.getQueryText().toLowerCase(); } } @Override - protected List doSearch() { - List res = new ArrayList<>(); - for (SearchItem item : searchItems) { + protected List doSearch() { + List res = new ArrayList<>(); + for (SearchObject item : searchObjects) { if (cancelled) { break; } - if (keyword.isEmpty() || item.getName().contains(keyword)) { + if (keyword.isEmpty() || item.getName(searchScope.getLang()).toLowerCase().contains(keyword) + || item.getNativeName().toLowerCase().contains(keyword)) { res.add(item); } } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/SearchRequest.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/SearchRequest.java index c91170b3e0..4085cf9a8d 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/SearchRequest.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/requests/SearchRequest.java @@ -4,62 +4,57 @@ import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import net.osmand.core.samples.android.sample1.search.SearchAPI; -import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback; +import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchApiCallback; import net.osmand.core.samples.android.sample1.search.SearchScope; -import net.osmand.core.samples.android.sample1.search.SearchString; -import net.osmand.core.samples.android.sample1.search.items.SearchItem; +import net.osmand.core.samples.android.sample1.search.objects.SearchObject; import java.util.List; public abstract class SearchRequest { - protected SearchAPI searchAPI; - protected SearchString searchString; protected SearchScope searchScope; protected int maxSearchResults; protected Runnable onFinished; - protected SearchCallback searchCallback; + protected SearchApiCallback searchCallback; protected boolean cancelled; - public SearchRequest(@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) { - this.searchAPI = searchAPI; - this.searchString = searchAPI.getSearchString(); - this.searchScope= searchAPI.getSearchScope(); + public SearchRequest(@NonNull SearchScope searchScope, int maxSearchResults, + @Nullable SearchApiCallback searchCallback) { + this.searchScope = searchScope; this.maxSearchResults = maxSearchResults; this.searchCallback = searchCallback; } public void run() { - new AsyncTask>() { + new AsyncTask>() { @Override - protected List doInBackground(Void... params) { + protected List doInBackground(Void... params) { return doSearch(); } @Override - protected void onPostExecute(List searchItems) { + protected void onPostExecute(List searchObjects) { - onSearchRequestPostExecute(searchItems); + onSearchRequestPostExecute(searchObjects); if (onFinished != null) { onFinished.run(); } if (searchCallback != null && !cancelled) { - searchCallback.onSearchFinished(searchItems); + searchCallback.onSearchFinished(searchObjects); } } }.execute(); } - protected void onSearchRequestPostExecute(List searchItems) { + protected void onSearchRequestPostExecute(List searchObjects) { } - protected abstract List doSearch(); + protected abstract List doSearch(); public void cancel() { cancelled = true; diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/CitySearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/CitySearchToken.java deleted file mode 100644 index b77f471b0f..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/CitySearchToken.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.tokens; - -import java.math.BigInteger; - -public class CitySearchToken extends SearchToken { - - private BigInteger obfId; - - public CitySearchToken(BigInteger obfId, int startIndex, String queryText, String name) { - super(TokenType.CITY, startIndex, queryText, name); - this.obfId = obfId; - } - - public BigInteger getObfId() { - return obfId; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/NameFilterSearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/NameFilterSearchToken.java index 8229843423..fbd1c299dc 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/NameFilterSearchToken.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/NameFilterSearchToken.java @@ -3,6 +3,6 @@ package net.osmand.core.samples.android.sample1.search.tokens; public class NameFilterSearchToken extends SearchToken { public NameFilterSearchToken(int startIndex, String queryText) { - super(TokenType.NAME_FILTER, startIndex, queryText, queryText); + super(TokenType.NAME_FILTER, startIndex, queryText, null); } } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/ObjectSearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/ObjectSearchToken.java new file mode 100644 index 0000000000..5a0e8482cc --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/ObjectSearchToken.java @@ -0,0 +1,14 @@ +package net.osmand.core.samples.android.sample1.search.tokens; + +import net.osmand.core.samples.android.sample1.search.objects.SearchObject; + +public class ObjectSearchToken extends SearchToken { + + public ObjectSearchToken(SearchToken searchToken, SearchObject searchObject) { + super(TokenType.SEARCH_OBJECT, searchToken.getStartIndex(), searchToken.getQueryText(), searchObject); + } + + public ObjectSearchToken(int startIndex, String queryText, SearchObject searchObject) { + super(TokenType.SEARCH_OBJECT, startIndex, queryText, searchObject); + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiCategorySearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiCategorySearchToken.java deleted file mode 100644 index 9ac128a4d0..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiCategorySearchToken.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.tokens; - -import android.support.annotation.NonNull; - -import net.osmand.osm.PoiCategory; - -public class PoiCategorySearchToken extends SearchToken { - private PoiCategory poiCategory; - - public PoiCategorySearchToken(@NonNull PoiCategory poiCategory, int startIndex, String queryText) { - super(TokenType.POI_CATEGORY, startIndex, queryText, poiCategory.getKeyName()); - this.poiCategory = poiCategory; - } - - public PoiCategory getPoiCategory() { - return poiCategory; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiFilterSearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiFilterSearchToken.java deleted file mode 100644 index e33e7c8c73..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiFilterSearchToken.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.tokens; - -import android.support.annotation.NonNull; - -import net.osmand.osm.PoiCategory; -import net.osmand.osm.PoiFilter; - -public class PoiFilterSearchToken extends SearchToken { - private PoiFilter poiFilter; - - public PoiFilterSearchToken(@NonNull PoiFilter poiFilter, int startIndex, String queryText) { - super(TokenType.POI_FILTER, startIndex, queryText, poiFilter.getKeyName()); - this.poiFilter = poiFilter; - } - - public PoiFilter getPoiFilter() { - return poiFilter; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiTypeSearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiTypeSearchToken.java deleted file mode 100644 index 98d33e3b8e..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PoiTypeSearchToken.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.tokens; - -import android.support.annotation.NonNull; - -import net.osmand.osm.PoiFilter; -import net.osmand.osm.PoiType; - -public class PoiTypeSearchToken extends SearchToken { - private PoiType poiType; - - public PoiTypeSearchToken(@NonNull PoiType poiType, int startIndex, String queryText) { - super(TokenType.POI_TYPE, startIndex, queryText, poiType.getKeyName()); - this.poiType = poiType; - } - - public PoiType getPoiType() { - return poiType; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PostcodeSearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PostcodeSearchToken.java deleted file mode 100644 index 2af28a47e8..0000000000 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/PostcodeSearchToken.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.osmand.core.samples.android.sample1.search.tokens; - -import java.math.BigInteger; - -public class PostcodeSearchToken extends SearchToken { - private BigInteger obfId; - - public PostcodeSearchToken(BigInteger obfId, int startIndex, String queryText, String name) { - super(TokenType.POSTCODE, startIndex, queryText, name); - this.obfId = obfId; - } - - public BigInteger getObfId() { - return obfId; - } -} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/SearchToken.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/SearchToken.java index d947b3a26b..01359b3141 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/SearchToken.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/tokens/SearchToken.java @@ -1,29 +1,24 @@ package net.osmand.core.samples.android.sample1.search.tokens; +import net.osmand.core.samples.android.sample1.search.objects.SearchObject; + public abstract class SearchToken { public enum TokenType { - CITY, - POSTCODE, - STREET, - BUILDING, - POI_CATEGORY, - POI_FILTER, - POI_TYPE, - LOCATION, + SEARCH_OBJECT, NAME_FILTER } private TokenType type; + private SearchObject searchObject; private int startIndex; protected String queryText; - protected String name; - public SearchToken(TokenType type, int startIndex, String queryText, String name) { + public SearchToken(TokenType type, int startIndex, String queryText, SearchObject searchObject) { this.type = type; this.startIndex = startIndex; this.queryText = queryText; - this.name = name; + this.searchObject = searchObject; } public TokenType getType() { @@ -50,7 +45,7 @@ public abstract class SearchToken { return queryText.length(); } - public String getName() { - return name; + public SearchObject getSearchObject() { + return searchObject; } }