From c2100d4fb266ddb966adfd2a5539aeab9a071206 Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Sat, 18 Jun 2016 20:48:11 +0300 Subject: [PATCH] Added address search to OsmAndCore sample --- .../adapters/AddressSearchListItem.java | 43 +++++++++ .../adapters/AmenitySearchListItem.java | 2 +- .../sample1/adapters/SearchListItem.java | 3 + .../sample1/search/AddressSearchItem.java | 91 +++++++++++++++++++ .../sample1/search/AmenitySearchItem.java | 36 +------- .../android/sample1/search/SearchAPI.java | 69 ++++++++++---- .../android/sample1/search/SearchItem.java | 47 +++++++++- 7 files changed, 236 insertions(+), 55 deletions(-) create mode 100644 OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AddressSearchListItem.java create mode 100644 OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AddressSearchItem.java diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AddressSearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AddressSearchListItem.java new file mode 100644 index 0000000000..85f3ce1653 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AddressSearchListItem.java @@ -0,0 +1,43 @@ +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.AddressSearchItem; +import net.osmand.util.Algorithms; + +public class AddressSearchListItem extends SearchListItem { + private String nameStr; + private String typeStr; + + public AddressSearchListItem(SampleApplication app, AddressSearchItem searchItem) { + super(app, searchItem); + + StringBuilder sb = new StringBuilder(); + String localizedName = searchItem.getLocalizedNames().get(MapUtils.LANGUAGE); + if (Algorithms.isEmpty(localizedName)) { + localizedName = searchItem.getNativeName(); + } + if (!Algorithms.isEmpty(searchItem.getNamePrefix())) { + sb.append(searchItem.getNamePrefix()); + sb.append(" "); + } + sb.append(localizedName); + if (!Algorithms.isEmpty(searchItem.getNameSuffix())) { + sb.append(" "); + sb.append(searchItem.getNameSuffix()); + } + + nameStr = sb.toString(); + typeStr = searchItem.getType(); + } + + @Override + public String getName() { + return nameStr; + } + + @Override + public String getType() { + return typeStr; + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AmenitySearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AmenitySearchListItem.java index b6fb092020..9e44607f0a 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AmenitySearchListItem.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/AmenitySearchListItem.java @@ -35,7 +35,7 @@ public class AmenitySearchListItem extends SearchListItem { for (Entry entry : searchItem.getLocalizedNames().entrySet()) { a.setName(entry.getKey(), entry.getValue()); } - //a.setAdditionalInfo(searchItem.getValues()); + a.setAdditionalInfo(searchItem.getValues()); return a; } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java index 6c466a88da..a222114e0a 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/adapters/SearchListItem.java @@ -3,6 +3,7 @@ package net.osmand.core.samples.android.sample1.adapters; import android.graphics.drawable.Drawable; import net.osmand.core.samples.android.sample1.SampleApplication; +import net.osmand.core.samples.android.sample1.search.AddressSearchItem; import net.osmand.core.samples.android.sample1.search.AmenitySearchItem; import net.osmand.core.samples.android.sample1.search.SearchItem; @@ -21,6 +22,8 @@ public class SearchListItem { if (item instanceof AmenitySearchItem) { return new AmenitySearchListItem(app, (AmenitySearchItem) item); + } else if (item instanceof AddressSearchItem) { + return new AddressSearchListItem(app, (AddressSearchItem) item); } return null; } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AddressSearchItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AddressSearchItem.java new file mode 100644 index 0000000000..baeb7e7721 --- /dev/null +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AddressSearchItem.java @@ -0,0 +1,91 @@ +package net.osmand.core.samples.android.sample1.search; + +import net.osmand.core.jni.Address; +import net.osmand.core.jni.ObfAddressStreetGroupSubtype; +import net.osmand.core.jni.Street; +import net.osmand.core.jni.StreetGroup; +import net.osmand.util.Algorithms; + +public class AddressSearchItem extends SearchItem { + + private String namePrefix; + private String nameSuffix; + private String typeStr; + + 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) { + nameSuffix = "st."; + typeStr = getTypeStr(street.getStreetGroup()); + } 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; + } + + private class StreetInternal extends Street { + public StreetInternal(Address address) { + super(Address.getCPtr(address), false); + } + } + + private class StreetGroupInternal extends StreetGroup { + public StreetGroupInternal(Address address) { + super(Address.getCPtr(address), false); + } + } +} diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AmenitySearchItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AmenitySearchItem.java index cde5981adf..a6f87645f5 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AmenitySearchItem.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/AmenitySearchItem.java @@ -12,23 +12,15 @@ import java.util.Map; public class AmenitySearchItem extends SearchItem { - private String nativeName; private String category; private String subcategory; - private Map localizedNames = new HashMap<>(); private Map values = new HashMap<>(); public AmenitySearchItem(Amenity amenity) { super(amenity.getPosition31()); - nativeName = amenity.getNativeName(); - QStringStringHash locNames = amenity.getLocalizedNames(); - QStringList locNamesKeys = locNames.keys(); - for (int i = 0; i < locNamesKeys.size(); i++) { - String key = locNamesKeys.get(i); - String val = locNames.get(key); - localizedNames.put(key, val); - } + setNativeName(amenity.getNativeName()); + addLocalizedNames(amenity.getLocalizedNames()); DecodedCategoryList catList = amenity.getDecodedCategories(); if (catList.size() > 0) { @@ -48,10 +40,6 @@ public class AmenitySearchItem extends SearchItem { } } - public String getNativeName() { - return nativeName; - } - public String getCategory() { return category; } @@ -60,32 +48,12 @@ public class AmenitySearchItem extends SearchItem { return subcategory; } - public Map getLocalizedNames() { - return localizedNames; - } - public Map getValues() { return values; } - @Override - public String getName() { - return nativeName; - } - @Override public String getType() { return Algorithms.capitalizeFirstLetterAndLowercase(subcategory); } - - @Override - public double getLatitude() { - return latitude; - } - - @Override - public double getLongitude() { - return longitude; - } - } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java index 1603b91fe0..9a96783f72 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchAPI.java @@ -2,11 +2,14 @@ package net.osmand.core.samples.android.sample1.search; import android.os.AsyncTask; +import net.osmand.core.jni.Address; +import net.osmand.core.jni.AddressesByNameSearch; import net.osmand.core.jni.AmenitiesByNameSearch; import net.osmand.core.jni.Amenity; import net.osmand.core.jni.AreaI; import net.osmand.core.jni.IQueryController; import net.osmand.core.jni.ISearch; +import net.osmand.core.jni.ISearch.INewResultEntryCallback; import net.osmand.core.jni.NullableAreaI; import net.osmand.core.jni.ObfsCollection; @@ -102,7 +105,8 @@ public class SearchAPI { private SearchAPICallback apiCallback; private boolean cancelled; - private int resCount; + private int amenityResultsCounter; + private int addressResultsCounter; public SearchRequest(String keyword, int maxSearchResults, SearchAPICallback apiCallback) { this.keyword = keyword; @@ -134,31 +138,58 @@ public class SearchAPI { private List doSearch(String keyword) { System.out.println("=== Start search"); - resCount = 0; + amenityResultsCounter = 0; + addressResultsCounter = 0; final List searchItems = new ArrayList<>(); - AmenitiesByNameSearch byNameSearch = new AmenitiesByNameSearch(obfsCollection); - AmenitiesByNameSearch.Criteria criteria = new AmenitiesByNameSearch.Criteria(); - criteria.setName(keyword); + // Setup Amenities by name search + AmenitiesByNameSearch amByNameSearch = new AmenitiesByNameSearch(obfsCollection); + AmenitiesByNameSearch.Criteria amByNameCriteria = new AmenitiesByNameSearch.Criteria(); + amByNameCriteria.setName(keyword); if (obfAreaFilter != null) { - criteria.setObfInfoAreaFilter(new NullableAreaI(obfAreaFilter)); + amByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(obfAreaFilter)); } - - ISearch.INewResultEntryCallback newResultEntryCallback = new ISearch.INewResultEntryCallback() { + INewResultEntryCallback amByNameResultCallback = new ISearch.INewResultEntryCallback() { @Override public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) { - Amenity amenity = new ResultEntry(resultEntry).getAmenity(); - searchItems.add(new AmenitySearchItem(amenity)); - System.out.println("Poi found === " + amenity.getNativeName()); - resCount++; + Amenity amenity = new AmenityResultEntry(resultEntry).getAmenity(); + AmenitySearchItem amenitySearchItem = new AmenitySearchItem(amenity); + searchItems.add(amenitySearchItem); + System.out.println("Poi found === " + amenitySearchItem.toString()); + amenityResultsCounter++; } }; - byNameSearch.performSearch(criteria, newResultEntryCallback.getBinding(), new IQueryController() { + // Setup Addresses by name search + AddressesByNameSearch addrByNameSearch = new AddressesByNameSearch(obfsCollection); + AddressesByNameSearch.Criteria addrByNameCriteria = new AddressesByNameSearch.Criteria(); + addrByNameCriteria.setName(keyword); + if (obfAreaFilter != null) { + addrByNameCriteria.setObfInfoAreaFilter(new NullableAreaI(obfAreaFilter)); + } + INewResultEntryCallback addrByNameResultCallback = new ISearch.INewResultEntryCallback() { + @Override + public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) { + Address address = new AddressResultEntry(resultEntry).getAddress(); + AddressSearchItem addrSearchItem = new AddressSearchItem(address); + searchItems.add(addrSearchItem); + System.out.println("Address found === " + addrSearchItem.toString()); + addressResultsCounter++; + } + }; + + amByNameSearch.performSearch(amByNameCriteria, amByNameResultCallback.getBinding(), new IQueryController() { @Override public boolean isAborted() { - return resCount >= maxSearchResults || cancelled; + return amenityResultsCounter >= maxSearchResults || cancelled; + } + }); + + addrByNameSearch.performSearch(addrByNameCriteria, addrByNameResultCallback.getBinding(), new IQueryController() { + @Override + public boolean isAborted() { + return addressResultsCounter >= maxSearchResults || cancelled; } }); @@ -176,8 +207,14 @@ public class SearchAPI { } } - private static class ResultEntry extends AmenitiesByNameSearch.ResultEntry { - protected ResultEntry(ISearch.IResultEntry resultEntry) { + private static class AmenityResultEntry extends AmenitiesByNameSearch.ResultEntry { + protected AmenityResultEntry(ISearch.IResultEntry resultEntry) { + super(ISearch.IResultEntry.getCPtr(resultEntry), false); + } + } + + private static class AddressResultEntry extends AddressesByNameSearch.ResultEntry { + protected AddressResultEntry(ISearch.IResultEntry resultEntry) { super(ISearch.IResultEntry.getCPtr(resultEntry), false); } } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchItem.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchItem.java index 22bbf2fa31..8dc3a2f1a0 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchItem.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/search/SearchItem.java @@ -2,25 +2,37 @@ package net.osmand.core.samples.android.sample1.search; import net.osmand.core.jni.LatLon; import net.osmand.core.jni.PointI; +import net.osmand.core.jni.QStringList; +import net.osmand.core.jni.QStringStringHash; import net.osmand.core.jni.Utilities; +import java.util.HashMap; +import java.util.Map; + public abstract class SearchItem { protected double latitude; protected double longitude; + protected String nativeName; + protected Map localizedNames = new HashMap<>(); - public SearchItem(double latitude, double longitude) { + protected SearchItem() { + } + + protected SearchItem(double latitude, double longitude) { this.latitude = latitude; this.longitude = longitude; } - public SearchItem(PointI location31) { + protected SearchItem(PointI location31) { LatLon latLon = Utilities.convert31ToLatLon(location31); latitude = latLon.getLatitude(); longitude = latLon.getLongitude(); } - public abstract String getName(); + public String getName() { + return nativeName; + } public abstract String getType(); @@ -32,8 +44,35 @@ public abstract class SearchItem { return longitude; } + public String getNativeName() { + return nativeName; + } + + public Map getLocalizedNames() { + return localizedNames; + } + + protected void setLocation(PointI location31) { + LatLon latLon = Utilities.convert31ToLatLon(location31); + latitude = latLon.getLatitude(); + longitude = latLon.getLongitude(); + } + + protected void setNativeName(String nativeName) { + this.nativeName = nativeName; + } + + protected void addLocalizedNames(QStringStringHash localizedNames) { + QStringList locNamesKeys = localizedNames.keys(); + for (int i = 0; i < locNamesKeys.size(); i++) { + String key = locNamesKeys.get(i); + String val = localizedNames.get(key); + this.localizedNames.put(key, val); + } + } + @Override public String toString() { - return getName() + " {lat:" + getLatitude() + " lon: " + getLongitude() + "}"; + return getName() + " (" + getType() + ") {lat:" + getLatitude() + " lon: " + getLongitude() + "}"; } }