Address search in progress
This commit is contained in:
parent
cd68355c97
commit
85553fd2c3
39 changed files with 1009 additions and 743 deletions
|
@ -15,7 +15,7 @@
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_marginRight="8dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="top"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="centerInside"
|
||||||
android:visibility="visible"/>
|
android:visibility="visible"/>
|
||||||
|
|
||||||
|
|
|
@ -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.MultiTouchSupport.MultiTouchZoomListener;
|
||||||
import net.osmand.core.samples.android.sample1.adapters.SearchListAdapter;
|
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.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;
|
||||||
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.items.SearchItem;
|
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
|
@ -84,7 +83,7 @@ public class MainActivity extends Activity {
|
||||||
private SearchAPI searchAPI;
|
private SearchAPI searchAPI;
|
||||||
private ListView searchListView;
|
private ListView searchListView;
|
||||||
private SearchListAdapter adapter;
|
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;
|
private final static int MAX_SEARCH_RESULTS_IU = 50;
|
||||||
|
|
||||||
// Germany
|
// Germany
|
||||||
|
@ -204,7 +203,7 @@ public class MainActivity extends Activity {
|
||||||
|
|
||||||
//Setup search
|
//Setup search
|
||||||
|
|
||||||
searchAPI = new SearchAPI(obfsCollection);
|
searchAPI = new SearchAPI(obfsCollection, MapUtils.LANGUAGE);
|
||||||
|
|
||||||
final EditText searchEditText = (EditText) findViewById(R.id.searchEditText);
|
final EditText searchEditText = (EditText) findViewById(R.id.searchEditText);
|
||||||
searchEditText.addTextChangedListener(new TextWatcher() {
|
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||||
|
@ -218,9 +217,7 @@ public class MainActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
if (s.length() > 2) {
|
runSearch(getScreenCenter31(), getScreenBounds31(), s.toString());
|
||||||
runSearch(getScreenBounds31(), s.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||||
|
@ -255,9 +252,13 @@ public class MainActivity extends Activity {
|
||||||
hideSearchList();
|
hideSearchList();
|
||||||
mapView.requestFocus();
|
mapView.requestFocus();
|
||||||
SearchListItem item = adapter.getItem(position);
|
SearchListItem item = adapter.getItem(position);
|
||||||
PointI target = Utilities.convertLatLonTo31(new LatLon(item.getLatitude(), item.getLongitude()));
|
if (item instanceof SearchListPositionItem) {
|
||||||
setTarget(target);
|
SearchListPositionItem positionItem = (SearchListPositionItem) item;
|
||||||
setZoom(17f);
|
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();
|
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() {
|
private AreaI getScreenBounds31() {
|
||||||
PointI topLeftPoint = new PointI();
|
PointI topLeftPoint = new PointI();
|
||||||
PointI bottomRightPoint = new PointI();
|
PointI bottomRightPoint = new PointI();
|
||||||
|
@ -398,33 +405,31 @@ public class MainActivity extends Activity {
|
||||||
|| gestureDetector.onTouchEvent(event);
|
|| 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.setObfAreaFilter(bounds31);
|
||||||
searchAPI.startSearch(keyword, MAX_SEARCH_RESULTS_CORE,
|
searchAPI.startSearch(keyword, MAX_SEARCH_RESULTS_CORE,
|
||||||
// Intermediate search callback
|
// Intermediate search callback
|
||||||
new SearchCallback() {
|
new SearchApiCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSearchFinished(List<SearchItem> searchItems) {
|
public void onSearchFinished(List<SearchObject> searchObjects) {
|
||||||
processSearchResult(searchItems);
|
processSearchResult(searchObjects);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Core search callback
|
// Core search callback
|
||||||
new SearchCallback() {
|
new SearchApiCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSearchFinished(List<SearchItem> searchItems) {
|
public void onSearchFinished(List<SearchObject> searchObjects) {
|
||||||
processSearchResult(searchItems);
|
processSearchResult(searchObjects);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processSearchResult(List<SearchItem> searchItems) {
|
private void processSearchResult(List<SearchObject> searchObjects) {
|
||||||
if (searchItems != null) {
|
if (searchObjects != null) {
|
||||||
LatLon latLon = Utilities.convert31ToLatLon(target31);
|
|
||||||
double latitude = latLon.getLatitude();
|
|
||||||
double longitude = latLon.getLongitude();
|
|
||||||
List<SearchListItem> rows = new ArrayList<>();
|
List<SearchListItem> rows = new ArrayList<>();
|
||||||
for (SearchItem item : searchItems) {
|
for (SearchObject item : searchObjects) {
|
||||||
SearchListItem listItem =
|
SearchListItem listItem =
|
||||||
SearchListItem.buildListItem((SampleApplication)getApplication(), item);
|
SearchListItem.buildListItem((SampleApplication)getApplication(), item);
|
||||||
if (listItem != null) {
|
if (listItem != 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<String, String> 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String, String> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,8 +25,11 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
||||||
public void updateDistance(double latitude, double longitude) {
|
public void updateDistance(double latitude, double longitude) {
|
||||||
for (int i = 0; i < getCount(); i++) {
|
for (int i = 0; i < getCount(); i++) {
|
||||||
SearchListItem item = getItem(i);
|
SearchListItem item = getItem(i);
|
||||||
item.setDistance(Utilities.distance(
|
if (item instanceof SearchListPositionItem) {
|
||||||
longitude, latitude, item.getLongitude(), item.getLatitude()));
|
SearchListPositionItem positionItem = (SearchListPositionItem) item;
|
||||||
|
positionItem.setDistance(Utilities.distance(
|
||||||
|
longitude, latitude, positionItem.getLongitude(), positionItem.getLatitude()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +54,17 @@ public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
||||||
|
|
||||||
imageView.setImageDrawable(listItem.getIcon());
|
imageView.setImageDrawable(listItem.getIcon());
|
||||||
title.setText(listItem.getName());
|
title.setText(listItem.getName());
|
||||||
subtitle.setText(listItem.getType());
|
subtitle.setText(listItem.getTypeName());
|
||||||
if (listItem.getDistance() == 0) {
|
if (listItem instanceof SearchListPositionItem) {
|
||||||
distance.setText("");
|
SearchListPositionItem positionItem = (SearchListPositionItem) listItem;
|
||||||
|
if (positionItem.getDistance() == 0) {
|
||||||
|
distance.setText("");
|
||||||
|
} else {
|
||||||
|
distance.setText(Utils.getFormattedDistance(positionItem.getDistance()));
|
||||||
|
}
|
||||||
|
distance.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
distance.setText(Utils.getFormattedDistance(listItem.getDistance()));
|
distance.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,52 +3,49 @@ package net.osmand.core.samples.android.sample1.adapters;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
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.objects.CitySearchObject;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem;
|
import net.osmand.core.samples.android.sample1.search.objects.PoiSearchObject;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
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 {
|
public class SearchListItem {
|
||||||
|
|
||||||
protected SampleApplication app;
|
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.app = app;
|
||||||
this.searchItem = searchItem;
|
this.searchObject = searchObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SearchListItem buildListItem(SampleApplication app, SearchItem item) {
|
public static SearchListItem buildListItem(SampleApplication app, SearchObject item) {
|
||||||
|
switch (item.getType()) {
|
||||||
if (item instanceof AmenitySearchItem) {
|
case POI:
|
||||||
return new AmenitySearchListItem(app, (AmenitySearchItem) item);
|
return new PoiSearchListItem(app, (PoiSearchObject) item);
|
||||||
} else if (item instanceof AddressSearchItem) {
|
case STREET:
|
||||||
return new AddressSearchListItem(app, (AddressSearchItem) item);
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getLatitude() {
|
protected SearchObject getSearchObject() {
|
||||||
return searchItem.getLatitude();
|
return searchObject;
|
||||||
}
|
|
||||||
|
|
||||||
public double getLongitude() {
|
|
||||||
return searchItem.getLongitude();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return searchItem.getName();
|
return searchObject.getNativeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getTypeName() {
|
||||||
return searchItem.getType();
|
return searchObject.getType().name();
|
||||||
}
|
|
||||||
|
|
||||||
public double getDistance() {
|
|
||||||
return searchItem.getDistance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDistance(double distance) {
|
|
||||||
searchItem.setDistance(distance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Drawable getIcon() {
|
public Drawable getIcon() {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,11 +5,13 @@ import android.support.annotation.NonNull;
|
||||||
import net.osmand.core.jni.AreaI;
|
import net.osmand.core.jni.AreaI;
|
||||||
import net.osmand.core.jni.ObfsCollection;
|
import net.osmand.core.jni.ObfsCollection;
|
||||||
import net.osmand.core.jni.PointI;
|
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.CoreSearchRequest;
|
||||||
import net.osmand.core.samples.android.sample1.search.requests.IntermediateSearchRequest;
|
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.requests.SearchRequest;
|
||||||
|
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SearchAPI {
|
public class SearchAPI {
|
||||||
|
@ -17,23 +19,44 @@ public class SearchAPI {
|
||||||
private ObfsCollection obfsCollection;
|
private ObfsCollection obfsCollection;
|
||||||
private AreaI searchableArea;
|
private AreaI searchableArea;
|
||||||
private AreaI obfAreaFilter;
|
private AreaI obfAreaFilter;
|
||||||
private PointI searchLocation;
|
private PointI searchLocation31;
|
||||||
private double searchRadius;
|
private double searchRadius;
|
||||||
|
private String lang;
|
||||||
|
|
||||||
private SearchRequestExecutor executor;
|
private SearchRequestExecutor executor;
|
||||||
private SearchString searchString;
|
private SearchString searchString;
|
||||||
private SearchScope searchScope;
|
private List<SearchObject> searchObjects;
|
||||||
private List<SearchItem> searchItems;
|
|
||||||
|
|
||||||
public interface SearchCallback {
|
private SearchCallbackInternal internalCallback = new SearchCallbackInternal() {
|
||||||
void onSearchFinished(List<SearchItem> searchItems);
|
@Override
|
||||||
|
public void onSearchObjectsFound(List<SearchObject> searchObjects) {
|
||||||
|
setSearchObjects(searchObjects);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewTokenFound(SearchToken oldToken, SearchToken newToken) {
|
||||||
|
searchString.replaceToken(oldToken, newToken);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public interface SearchApiCallback {
|
||||||
|
void onSearchFinished(List<SearchObject> searchObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchAPI(@NonNull ObfsCollection obfsCollection) {
|
public interface SearchCallbackInternal {
|
||||||
|
void onSearchObjectsFound(List<SearchObject> searchObjects);
|
||||||
|
void onNewTokenFound(SearchToken oldToken, SearchToken newToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchAPI(@NonNull ObfsCollection obfsCollection, String lang) {
|
||||||
this.obfsCollection = obfsCollection;
|
this.obfsCollection = obfsCollection;
|
||||||
this.executor = new SearchRequestExecutor();
|
this.executor = new SearchRequestExecutor();
|
||||||
this.searchString = new SearchString();
|
this.searchString = new SearchString();
|
||||||
this.searchScope = new SearchScope(this);
|
this.lang = lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLang() {
|
||||||
|
return lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AreaI getSearchableArea() {
|
public AreaI getSearchableArea() {
|
||||||
|
@ -52,12 +75,12 @@ public class SearchAPI {
|
||||||
this.obfAreaFilter = obfAreaFilter;
|
this.obfAreaFilter = obfAreaFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PointI getSearchLocation() {
|
public PointI getSearchLocation31() {
|
||||||
return searchLocation;
|
return searchLocation31;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSearchLocation(PointI searchLocation) {
|
public void setSearchLocation31(PointI position31) {
|
||||||
this.searchLocation = searchLocation;
|
this.searchLocation31 = position31;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getSearchRadius() {
|
public double getSearchRadius() {
|
||||||
|
@ -72,35 +95,32 @@ public class SearchAPI {
|
||||||
return obfsCollection;
|
return obfsCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchString getSearchString() {
|
public SearchString getSearchStringCopy() {
|
||||||
return searchString;
|
return searchString.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchScope getSearchScope() {
|
public List<SearchObject> getSearchObjects() {
|
||||||
return searchScope;
|
return searchObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SearchItem> getSearchItems() {
|
public void setSearchObjects(List<SearchObject> searchObjects) {
|
||||||
return searchItems;
|
this.searchObjects = searchObjects;
|
||||||
}
|
|
||||||
|
|
||||||
public void setSearchItems(List<SearchItem> searchItems) {
|
|
||||||
this.searchItems = searchItems;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startSearch(String query, int maxSearchResults,
|
public void startSearch(String query, int maxSearchResults,
|
||||||
SearchCallback intermediateSearchCallback,
|
SearchApiCallback intermediateSearchCallback,
|
||||||
SearchCallback coreSearchCallback) {
|
SearchApiCallback coreSearchCallback) {
|
||||||
|
|
||||||
searchString.setQueryText(query);
|
searchString.setQueryText(query);
|
||||||
searchScope.updateScope();
|
SearchScope searchScope = new SearchScope(this);
|
||||||
IntermediateSearchRequest intermediateSearchRequest = null;
|
IntermediateSearchRequest intermediateSearchRequest = null;
|
||||||
if (searchItems != null && !searchItems.isEmpty()) {
|
if (searchObjects != null && !searchObjects.isEmpty()) {
|
||||||
intermediateSearchRequest =
|
intermediateSearchRequest =
|
||||||
new IntermediateSearchRequest(this, maxSearchResults, intermediateSearchCallback);
|
new IntermediateSearchRequest(searchScope, new ArrayList<>(searchObjects),
|
||||||
|
maxSearchResults, intermediateSearchCallback);
|
||||||
}
|
}
|
||||||
executor.run(new CoreSearchRequest(intermediateSearchRequest, this,
|
executor.run(new CoreSearchRequest(intermediateSearchRequest, searchScope,
|
||||||
maxSearchResults, coreSearchCallback), true);
|
maxSearchResults, coreSearchCallback, internalCallback), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelSearch() {
|
public void cancelSearch() {
|
||||||
|
|
|
@ -2,117 +2,190 @@ package net.osmand.core.samples.android.sample1.search;
|
||||||
|
|
||||||
import net.osmand.core.jni.AddressesByNameSearch;
|
import net.osmand.core.jni.AddressesByNameSearch;
|
||||||
import net.osmand.core.jni.AmenitiesByNameSearch;
|
import net.osmand.core.jni.AmenitiesByNameSearch;
|
||||||
import net.osmand.core.jni.LatLon;
|
import net.osmand.core.jni.AreaI;
|
||||||
import net.osmand.core.jni.QStringList;
|
import net.osmand.core.jni.ObfAddressStreetGroupSubtype;
|
||||||
import net.osmand.core.jni.QStringStringListHash;
|
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.jni.Utilities;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem;
|
import net.osmand.core.samples.android.sample1.search.objects.PoiSearchObject;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem;
|
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
import net.osmand.core.samples.android.sample1.search.objects.SearchObject.SearchObjectType;
|
||||||
import net.osmand.core.samples.android.sample1.search.tokens.CitySearchToken;
|
import net.osmand.core.samples.android.sample1.search.objects.SearchPositionObject;
|
||||||
import net.osmand.core.samples.android.sample1.search.tokens.PoiTypeSearchToken;
|
import net.osmand.core.samples.android.sample1.search.objects.StreetGroupSearchObject;
|
||||||
import net.osmand.core.samples.android.sample1.search.tokens.PostcodeSearchToken;
|
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;
|
||||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken.TokenType;
|
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class SearchScope {
|
public class SearchScope {
|
||||||
|
|
||||||
private SearchAPI searchAPI;
|
private ObfsCollection obfsCollection;
|
||||||
private Map<TokenType, SearchToken> resolvedTokens;
|
private SearchString searchString;
|
||||||
private double searchLat;
|
private String lang;
|
||||||
private double searchLon;
|
private Map<SearchObjectType, SearchToken> objectTokens;
|
||||||
|
private PointI searchLocation31;
|
||||||
|
private AreaI searchableArea;
|
||||||
|
private AreaI obfAreaFilter;
|
||||||
private double searchRadius;
|
private double searchRadius;
|
||||||
|
|
||||||
public SearchScope(SearchAPI searchAPI) {
|
public SearchScope(SearchAPI searchAPI) {
|
||||||
this.searchAPI = searchAPI;
|
obfsCollection = searchAPI.getObfsCollection();
|
||||||
}
|
lang = searchAPI.getLang();
|
||||||
|
searchString = searchAPI.getSearchStringCopy();
|
||||||
public void updateScope() {
|
objectTokens = searchString.getObjectTokens();
|
||||||
resolvedTokens = searchAPI.getSearchString().getResolvedTokens();
|
searchLocation31 = searchAPI.getSearchLocation31();
|
||||||
LatLon latLon = Utilities.convert31ToLatLon(searchAPI.getSearchLocation());
|
searchableArea = searchAPI.getSearchableArea();
|
||||||
searchLat = latLon.getLatitude();
|
obfAreaFilter = searchAPI.getObfAreaFilter();
|
||||||
searchLon = latLon.getLongitude();
|
|
||||||
searchRadius = searchAPI.getSearchRadius();
|
searchRadius = searchAPI.getSearchRadius();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObfsCollection getObfsCollection() {
|
||||||
|
return obfsCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLang() {
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchString getSearchString() {
|
||||||
|
return searchString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<SearchObjectType, SearchToken> 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) {
|
public void setupAmenitySearchCriteria(AmenitiesByNameSearch.Criteria criteria) {
|
||||||
String categoryName = null;
|
//todo criteria.setCategoriesFilter() if needed;
|
||||||
String typeName = null;
|
|
||||||
if (resolvedTokens.containsKey(TokenType.POI_TYPE)) {
|
|
||||||
PoiTypeSearchToken token = (PoiTypeSearchToken)resolvedTokens.get(TokenType.POI_TYPE);
|
|
||||||
categoryName = token.getPoiType().getCategory().getKeyName();
|
|
||||||
typeName = token.getName();
|
|
||||||
} else if (resolvedTokens.containsKey(TokenType.POI_FILTER)) {
|
|
||||||
SearchToken token = resolvedTokens.get(TokenType.POI_FILTER);
|
|
||||||
categoryName = token.getName();
|
|
||||||
} else if (resolvedTokens.containsKey(TokenType.POI_CATEGORY)) {
|
|
||||||
SearchToken token = resolvedTokens.get(TokenType.POI_CATEGORY);
|
|
||||||
categoryName = token.getName();
|
|
||||||
}
|
|
||||||
if (!Algorithms.isEmpty(categoryName) && !Algorithms.isEmpty(typeName)) {
|
|
||||||
QStringStringListHash list = new QStringStringListHash();
|
|
||||||
QStringList stringList = new QStringList();
|
|
||||||
//todo list.set(categoryName, stringList);
|
|
||||||
criteria.setCategoriesFilter(list);
|
|
||||||
} else if (!Algorithms.isEmpty(categoryName)) {
|
|
||||||
QStringStringListHash list = new QStringStringListHash();
|
|
||||||
//todo list.set(categoryName, new QStringList());
|
|
||||||
criteria.setCategoriesFilter(list);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupAddressSearchCriteria(AddressesByNameSearch.Criteria criteria) {
|
public void setupAddressSearchCriteria(AddressesByNameSearch.Criteria criteria) {
|
||||||
//not implemented
|
//not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean processAmenitySearchItem(AmenitySearchItem item) {
|
public boolean processPoiSearchObject(PoiSearchObject poiSearchObject) {
|
||||||
boolean res = true;
|
updateDistance(poiSearchObject);
|
||||||
updateDistance(item);
|
return true;
|
||||||
if (searchRadius > 0) {
|
|
||||||
res = item.getDistance() < searchRadius;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean processAddressSearchItem(AddressSearchItem item) {
|
public boolean processAddressSearchObject(SearchPositionObject addressSearchObject) {
|
||||||
boolean res = true;
|
updateDistance(addressSearchObject);
|
||||||
if (resolvedTokens.containsKey(TokenType.CITY) && item.getParentCityObfId() != null) {
|
return true;
|
||||||
CitySearchToken token = (CitySearchToken)resolvedTokens.get(TokenType.CITY);
|
|
||||||
res = token.getObfId().equals(item.getParentCityObfId());
|
|
||||||
} else if (resolvedTokens.containsKey(TokenType.POSTCODE) && item.getParentPostcodeObfId() != null) {
|
|
||||||
PostcodeSearchToken token = (PostcodeSearchToken)resolvedTokens.get(TokenType.CITY);
|
|
||||||
res = token.getObfId().equals(item.getParentPostcodeObfId());
|
|
||||||
}
|
|
||||||
if (res) {
|
|
||||||
updateDistance(item);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processSearchResult(List<SearchItem> searchItems) {
|
public SearchToken processSearchResult(SearchToken token, List<SearchObject> searchObjects) {
|
||||||
/*
|
|
||||||
Collections.sort(searchItems, new Comparator<SearchItem>() {
|
SearchToken newToken = null;
|
||||||
@Override
|
|
||||||
public int compare(SearchItem lhs, SearchItem rhs) {
|
boolean cityVillagePostcodeSelected = objectTokens.containsKey(SearchObjectType.CITY)
|
||||||
int res = Double.compare(lhs.getDistance(), rhs.getDistance());
|
|| objectTokens.containsKey(SearchObjectType.VILLAGE)
|
||||||
if (res == 0) {
|
|| objectTokens.containsKey(SearchObjectType.POSTCODE);
|
||||||
return lhs.getName().compareToIgnoreCase(rhs.getName());
|
|
||||||
} else {
|
for (SearchObject searchObject : searchObjects) {
|
||||||
return res;
|
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<SearchObject>() {
|
||||||
|
@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) {
|
private float getCityType(StreetGroupSearchObject searchObject) {
|
||||||
item.setDistance(Utilities.distance(
|
if (searchObject.getStreetGroup().getType() == ObfAddressStreetGroupType.CityOrTown) {
|
||||||
searchLon, searchLat, item.getLongitude(), item.getLatitude()));
|
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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package net.osmand.core.samples.android.sample1.search;
|
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.NameFilterSearchToken;
|
||||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken.TokenType;
|
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken.TokenType;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -17,11 +19,18 @@ public class SearchString {
|
||||||
public SearchString() {
|
public SearchString() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SearchString copy() {
|
||||||
|
SearchString res = new SearchString();
|
||||||
|
res.queryText = queryText;
|
||||||
|
res.tokens = new ArrayList<>(tokens);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
public String getQueryText() {
|
public String getQueryText() {
|
||||||
return queryText;
|
return queryText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setQueryText(String queryText) {
|
public void setQueryText(String queryText) {
|
||||||
int newTextLength = queryText.length();
|
int newTextLength = queryText.length();
|
||||||
int currTextLength = this.queryText.length();
|
int currTextLength = this.queryText.length();
|
||||||
boolean isNewText = currTextLength == 0
|
boolean isNewText = currTextLength == 0
|
||||||
|
@ -73,12 +82,19 @@ public class SearchString {
|
||||||
if (firstWordIndex <= newTextLength - 1) {
|
if (firstWordIndex <= newTextLength - 1) {
|
||||||
SearchToken token = new NameFilterSearchToken(firstWordIndex, queryText.substring(firstWordIndex));
|
SearchToken token = new NameFilterSearchToken(firstWordIndex, queryText.substring(firstWordIndex));
|
||||||
tokens.add(token);
|
tokens.add(token);
|
||||||
|
} else if (endWithDelimeter(queryText)) {
|
||||||
|
SearchToken token = new NameFilterSearchToken(firstWordIndex, "");
|
||||||
|
tokens.add(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.queryText = queryText;
|
this.queryText = queryText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean endWithDelimeter(String text) {
|
||||||
|
return !Algorithms.isEmpty(text) && isDelimiterChar(text.charAt(text.length() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean startWithDelimiter(String text) {
|
private boolean startWithDelimiter(String text) {
|
||||||
char firstChar = text.charAt(0);
|
char firstChar = text.charAt(0);
|
||||||
return isDelimiterChar(firstChar);
|
return isDelimiterChar(firstChar);
|
||||||
|
@ -88,7 +104,7 @@ public class SearchString {
|
||||||
return c == ',' || c == ' ';
|
return c == ',' || c == ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized SearchToken getNextNameFilterToken() {
|
public SearchToken getNextNameFilterToken() {
|
||||||
SearchToken res = null;
|
SearchToken res = null;
|
||||||
if (!tokens.isEmpty()) {
|
if (!tokens.isEmpty()) {
|
||||||
for (int i = tokens.size() - 1; i >= 0; i--) {
|
for (int i = tokens.size() - 1; i >= 0; i--) {
|
||||||
|
@ -103,18 +119,18 @@ public class SearchString {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized SearchToken getLastToken() {
|
public SearchToken getLastToken() {
|
||||||
if (!tokens.isEmpty()) {
|
if (!tokens.isEmpty()) {
|
||||||
return tokens.get(tokens.size() - 1);
|
return tokens.get(tokens.size() - 1);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean hasNameFilterTokens() {
|
public boolean hasNameFilterTokens() {
|
||||||
return getNextNameFilterToken() != null;
|
return getNextNameFilterToken() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean replaceToken(SearchToken oldToken, SearchToken newToken) {
|
public boolean replaceToken(SearchToken oldToken, SearchToken newToken) {
|
||||||
int index = tokens.indexOf(oldToken);
|
int index = tokens.indexOf(oldToken);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
tokens.set(index, newToken);
|
tokens.set(index, newToken);
|
||||||
|
@ -123,11 +139,11 @@ public class SearchString {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Map<TokenType, SearchToken> getResolvedTokens() {
|
public Map<SearchObjectType, SearchToken> getObjectTokens() {
|
||||||
Map<TokenType, SearchToken> map = new HashMap<>();
|
Map<SearchObjectType, SearchToken> map = new HashMap<>();
|
||||||
for (SearchToken token : tokens) {
|
for (SearchToken token : tokens) {
|
||||||
if (token.getType() != SearchToken.TokenType.NAME_FILTER) {
|
if (token.getType() == TokenType.SEARCH_OBJECT) {
|
||||||
map.put(token.getType(), token);
|
map.put(token.getSearchObject().getType(), token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<String, String> 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<String, String> getValues() {
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return Algorithms.capitalizeFirstLetterAndLowercase(subcategory);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<String, String> 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<String, String> 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() + "}";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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() + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,12 +10,16 @@ import net.osmand.core.jni.Amenity;
|
||||||
import net.osmand.core.jni.IQueryController;
|
import net.osmand.core.jni.IQueryController;
|
||||||
import net.osmand.core.jni.ISearch;
|
import net.osmand.core.jni.ISearch;
|
||||||
import net.osmand.core.jni.NullableAreaI;
|
import net.osmand.core.jni.NullableAreaI;
|
||||||
import net.osmand.core.samples.android.sample1.search.SearchAPI;
|
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchApiCallback;
|
||||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback;
|
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallbackInternal;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.AddressSearchItem;
|
import net.osmand.core.samples.android.sample1.search.SearchScope;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.AmenitySearchItem;
|
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.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.core.samples.android.sample1.search.tokens.SearchToken;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -24,14 +28,18 @@ public class CoreSearchRequest extends SearchRequest {
|
||||||
|
|
||||||
private IntermediateSearchRequest intermediateSearchRequest;
|
private IntermediateSearchRequest intermediateSearchRequest;
|
||||||
private boolean intermediateSearchDone;
|
private boolean intermediateSearchDone;
|
||||||
|
private SearchCallbackInternal internalCallback;
|
||||||
|
|
||||||
private int amenityResultsCounter;
|
private int amenityResultsCounter;
|
||||||
private int addressResultsCounter;
|
private int addressResultsCounter;
|
||||||
|
|
||||||
public CoreSearchRequest(@Nullable IntermediateSearchRequest intermediateSearchRequest,
|
public CoreSearchRequest(@Nullable IntermediateSearchRequest intermediateSearchRequest,
|
||||||
@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) {
|
@NonNull SearchScope searchScope, int maxSearchResults,
|
||||||
super(searchAPI, maxSearchResults, searchCallback);
|
@Nullable SearchApiCallback searchCallback,
|
||||||
|
@Nullable SearchCallbackInternal internalCallback) {
|
||||||
|
super(searchScope, maxSearchResults, searchCallback);
|
||||||
this.intermediateSearchRequest = intermediateSearchRequest;
|
this.intermediateSearchRequest = intermediateSearchRequest;
|
||||||
|
this.internalCallback = internalCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,11 +59,13 @@ public class CoreSearchRequest extends SearchRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSearchRequestPostExecute(List<SearchItem> searchItems) {
|
protected void onSearchRequestPostExecute(List<SearchObject> searchObjects) {
|
||||||
if (intermediateSearchRequest != null && !intermediateSearchDone) {
|
if (intermediateSearchRequest != null && !intermediateSearchDone) {
|
||||||
intermediateSearchRequest.cancel();
|
intermediateSearchRequest.cancel();
|
||||||
}
|
}
|
||||||
searchAPI.setSearchItems(searchItems);
|
if (internalCallback != null) {
|
||||||
|
internalCallback.onSearchObjectsFound(searchObjects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,37 +77,42 @@ public class CoreSearchRequest extends SearchRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<SearchItem> doSearch() {
|
protected List<SearchObject> doSearch() {
|
||||||
|
|
||||||
List<SearchItem> res = new ArrayList<>();
|
List<SearchObject> res = new ArrayList<>();
|
||||||
|
|
||||||
|
SearchString searchString = searchScope.getSearchString();
|
||||||
|
SearchToken lastToken = searchString.getLastToken();
|
||||||
SearchToken token = searchString.getNextNameFilterToken();
|
SearchToken token = searchString.getNextNameFilterToken();
|
||||||
while (token != null && !cancelled) {
|
while (token != null && !cancelled) {
|
||||||
if (token.getType() == SearchToken.TokenType.NAME_FILTER) {
|
if (token.getType() == SearchToken.TokenType.NAME_FILTER
|
||||||
List<SearchItem> searchItems = doCoreSearch(token);
|
&& !Algorithms.isEmpty(token.getQueryText())) {
|
||||||
res.clear();
|
res = doCoreSearch(token);
|
||||||
res.addAll(searchItems);
|
}
|
||||||
|
if (token != lastToken) {
|
||||||
|
token = searchString.getNextNameFilterToken();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
token = searchString.getNextNameFilterToken();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SearchItem> doCoreSearch(@NonNull SearchToken token) {
|
private List<SearchObject> doCoreSearch(@NonNull SearchToken token) {
|
||||||
System.out.println("=== Start search");
|
System.out.println("=== Start search");
|
||||||
amenityResultsCounter = 0;
|
amenityResultsCounter = 0;
|
||||||
addressResultsCounter = 0;
|
addressResultsCounter = 0;
|
||||||
|
|
||||||
String keyword = token.getQueryText();
|
String keyword = token.getQueryText();
|
||||||
final List<SearchItem> searchItems = new ArrayList<>();
|
final List<SearchObject> searchObjects = new ArrayList<>();
|
||||||
|
|
||||||
// Setup Amenities by name search
|
// Setup Amenities by name search
|
||||||
AmenitiesByNameSearch amByNameSearch = new AmenitiesByNameSearch(searchAPI.getObfsCollection());
|
AmenitiesByNameSearch amByNameSearch = new AmenitiesByNameSearch(searchScope.getObfsCollection());
|
||||||
AmenitiesByNameSearch.Criteria amenityByNameCriteria = new AmenitiesByNameSearch.Criteria();
|
AmenitiesByNameSearch.Criteria amenityByNameCriteria = new AmenitiesByNameSearch.Criteria();
|
||||||
amenityByNameCriteria.setName(keyword);
|
amenityByNameCriteria.setName(keyword);
|
||||||
if (searchAPI.getObfAreaFilter() != null) {
|
if (searchScope.getObfAreaFilter() != null) {
|
||||||
amenityByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchAPI.getObfAreaFilter()));
|
amenityByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchScope.getObfAreaFilter()));
|
||||||
}
|
}
|
||||||
searchScope.setupAmenitySearchCriteria(amenityByNameCriteria);
|
searchScope.setupAmenitySearchCriteria(amenityByNameCriteria);
|
||||||
|
|
||||||
|
@ -105,9 +120,9 @@ public class CoreSearchRequest extends SearchRequest {
|
||||||
@Override
|
@Override
|
||||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||||
Amenity amenity = new AmenityResultEntry(resultEntry).getAmenity();
|
Amenity amenity = new AmenityResultEntry(resultEntry).getAmenity();
|
||||||
AmenitySearchItem amenitySearchItem = new AmenitySearchItem(amenity);
|
PoiSearchObject amenitySearchItem = new PoiSearchObject(amenity);
|
||||||
if (searchScope.processAmenitySearchItem(amenitySearchItem)) {
|
if (searchScope.processPoiSearchObject(amenitySearchItem)) {
|
||||||
searchItems.add(amenitySearchItem);
|
searchObjects.add(amenitySearchItem);
|
||||||
}
|
}
|
||||||
System.out.println("Poi found === " + amenitySearchItem.toString());
|
System.out.println("Poi found === " + amenitySearchItem.toString());
|
||||||
amenityResultsCounter++;
|
amenityResultsCounter++;
|
||||||
|
@ -115,11 +130,11 @@ public class CoreSearchRequest extends SearchRequest {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup Addresses by name search
|
// Setup Addresses by name search
|
||||||
AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(searchAPI.getObfsCollection());
|
AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(searchScope.getObfsCollection());
|
||||||
AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria();
|
final AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria();
|
||||||
addrByNameCriteria.setName(keyword);
|
addrByNameCriteria.setName(keyword);
|
||||||
if (searchAPI.getObfAreaFilter() != null) {
|
if (searchScope.getObfAreaFilter() != null) {
|
||||||
addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchAPI.getObfAreaFilter()));
|
addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(searchScope.getObfAreaFilter()));
|
||||||
}
|
}
|
||||||
searchScope.setupAddressSearchCriteria(addrByNameCriteria);
|
searchScope.setupAddressSearchCriteria(addrByNameCriteria);
|
||||||
|
|
||||||
|
@ -127,12 +142,14 @@ public class CoreSearchRequest extends SearchRequest {
|
||||||
@Override
|
@Override
|
||||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||||
Address address = new AddressResultEntry(resultEntry).getAddress();
|
Address address = new AddressResultEntry(resultEntry).getAddress();
|
||||||
AddressSearchItem addrSearchItem = new AddressSearchItem(address);
|
SearchPositionObject addressSearchObject = SearchObjectsHelper.getAddressObject(address);
|
||||||
if (searchScope.processAddressSearchItem(addrSearchItem)) {
|
if (addressSearchObject != null) {
|
||||||
searchItems.add(addrSearchItem);
|
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) {
|
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");
|
System.out.println("=== Finish search");
|
||||||
|
|
||||||
return searchItems;
|
return searchObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AmenityResultEntry extends AmenitiesByNameSearch.ResultEntry {
|
private class AmenityResultEntry extends AmenitiesByNameSearch.ResultEntry {
|
||||||
|
|
|
@ -3,10 +3,9 @@ package net.osmand.core.samples.android.sample1.search.requests;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.core.samples.android.sample1.search.SearchAPI;
|
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchApiCallback;
|
||||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback;
|
import net.osmand.core.samples.android.sample1.search.SearchScope;
|
||||||
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.SearchRequest;
|
|
||||||
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
import net.osmand.core.samples.android.sample1.search.tokens.SearchToken;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -14,27 +13,29 @@ import java.util.List;
|
||||||
|
|
||||||
public class IntermediateSearchRequest extends SearchRequest {
|
public class IntermediateSearchRequest extends SearchRequest {
|
||||||
|
|
||||||
private List<SearchItem> searchItems;
|
private List<SearchObject> searchObjects;
|
||||||
protected String keyword = "";
|
protected String keyword = "";
|
||||||
|
|
||||||
public IntermediateSearchRequest(@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) {
|
public IntermediateSearchRequest(@NonNull SearchScope searchScope, List<SearchObject> searchObjects,
|
||||||
super(searchAPI, maxSearchResults, searchCallback);
|
int maxSearchResults, @Nullable SearchApiCallback searchCallback) {
|
||||||
this.searchItems = new ArrayList<>(searchAPI.getSearchItems());
|
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) {
|
if (token != null && token.getType() == SearchToken.TokenType.NAME_FILTER) {
|
||||||
keyword = token.getQueryText();
|
keyword = token.getQueryText().toLowerCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<SearchItem> doSearch() {
|
protected List<SearchObject> doSearch() {
|
||||||
List<SearchItem> res = new ArrayList<>();
|
List<SearchObject> res = new ArrayList<>();
|
||||||
for (SearchItem item : searchItems) {
|
for (SearchObject item : searchObjects) {
|
||||||
if (cancelled) {
|
if (cancelled) {
|
||||||
break;
|
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);
|
res.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,62 +4,57 @@ import android.os.AsyncTask;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.core.samples.android.sample1.search.SearchAPI;
|
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchApiCallback;
|
||||||
import net.osmand.core.samples.android.sample1.search.SearchAPI.SearchCallback;
|
|
||||||
import net.osmand.core.samples.android.sample1.search.SearchScope;
|
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.SearchObject;
|
||||||
import net.osmand.core.samples.android.sample1.search.items.SearchItem;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class SearchRequest {
|
public abstract class SearchRequest {
|
||||||
protected SearchAPI searchAPI;
|
|
||||||
protected SearchString searchString;
|
|
||||||
protected SearchScope searchScope;
|
protected SearchScope searchScope;
|
||||||
|
|
||||||
protected int maxSearchResults;
|
protected int maxSearchResults;
|
||||||
protected Runnable onFinished;
|
protected Runnable onFinished;
|
||||||
protected SearchCallback searchCallback;
|
protected SearchApiCallback searchCallback;
|
||||||
|
|
||||||
protected boolean cancelled;
|
protected boolean cancelled;
|
||||||
|
|
||||||
public SearchRequest(@NonNull SearchAPI searchAPI, int maxSearchResults, @Nullable SearchCallback searchCallback) {
|
public SearchRequest(@NonNull SearchScope searchScope, int maxSearchResults,
|
||||||
this.searchAPI = searchAPI;
|
@Nullable SearchApiCallback searchCallback) {
|
||||||
this.searchString = searchAPI.getSearchString();
|
this.searchScope = searchScope;
|
||||||
this.searchScope= searchAPI.getSearchScope();
|
|
||||||
this.maxSearchResults = maxSearchResults;
|
this.maxSearchResults = maxSearchResults;
|
||||||
this.searchCallback = searchCallback;
|
this.searchCallback = searchCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
new AsyncTask<Void, Void, List<SearchItem>>() {
|
new AsyncTask<Void, Void, List<SearchObject>>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<SearchItem> doInBackground(Void... params) {
|
protected List<SearchObject> doInBackground(Void... params) {
|
||||||
return doSearch();
|
return doSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(List<SearchItem> searchItems) {
|
protected void onPostExecute(List<SearchObject> searchObjects) {
|
||||||
|
|
||||||
onSearchRequestPostExecute(searchItems);
|
onSearchRequestPostExecute(searchObjects);
|
||||||
|
|
||||||
if (onFinished != null) {
|
if (onFinished != null) {
|
||||||
onFinished.run();
|
onFinished.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchCallback != null && !cancelled) {
|
if (searchCallback != null && !cancelled) {
|
||||||
searchCallback.onSearchFinished(searchItems);
|
searchCallback.onSearchFinished(searchObjects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onSearchRequestPostExecute(List<SearchItem> searchItems) {
|
protected void onSearchRequestPostExecute(List<SearchObject> searchObjects) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract List<SearchItem> doSearch();
|
protected abstract List<SearchObject> doSearch();
|
||||||
|
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,6 @@ package net.osmand.core.samples.android.sample1.search.tokens;
|
||||||
public class NameFilterSearchToken extends SearchToken {
|
public class NameFilterSearchToken extends SearchToken {
|
||||||
|
|
||||||
public NameFilterSearchToken(int startIndex, String queryText) {
|
public NameFilterSearchToken(int startIndex, String queryText) {
|
||||||
super(TokenType.NAME_FILTER, startIndex, queryText, queryText);
|
super(TokenType.NAME_FILTER, startIndex, queryText, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +1,24 @@
|
||||||
package net.osmand.core.samples.android.sample1.search.tokens;
|
package net.osmand.core.samples.android.sample1.search.tokens;
|
||||||
|
|
||||||
|
import net.osmand.core.samples.android.sample1.search.objects.SearchObject;
|
||||||
|
|
||||||
public abstract class SearchToken {
|
public abstract class SearchToken {
|
||||||
|
|
||||||
public enum TokenType {
|
public enum TokenType {
|
||||||
CITY,
|
SEARCH_OBJECT,
|
||||||
POSTCODE,
|
|
||||||
STREET,
|
|
||||||
BUILDING,
|
|
||||||
POI_CATEGORY,
|
|
||||||
POI_FILTER,
|
|
||||||
POI_TYPE,
|
|
||||||
LOCATION,
|
|
||||||
NAME_FILTER
|
NAME_FILTER
|
||||||
}
|
}
|
||||||
|
|
||||||
private TokenType type;
|
private TokenType type;
|
||||||
|
private SearchObject searchObject;
|
||||||
private int startIndex;
|
private int startIndex;
|
||||||
protected String queryText;
|
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.type = type;
|
||||||
this.startIndex = startIndex;
|
this.startIndex = startIndex;
|
||||||
this.queryText = queryText;
|
this.queryText = queryText;
|
||||||
this.name = name;
|
this.searchObject = searchObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TokenType getType() {
|
public TokenType getType() {
|
||||||
|
@ -50,7 +45,7 @@ public abstract class SearchToken {
|
||||||
return queryText.length();
|
return queryText.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public SearchObject getSearchObject() {
|
||||||
return name;
|
return searchObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue