From d4ebc9634a36a91165ceb5d5f016eee42b83c6fc Mon Sep 17 00:00:00 2001 From: Pavol Zibrita Date: Wed, 2 Feb 2011 21:36:13 +0100 Subject: [PATCH 1/3] Searching streets in complete country. Fixes issue 352 --- .../src/net/osmand/data/City.java | 19 +-- .../src/net/osmand/data/Street.java | 6 + OsmAnd/res/values/strings.xml | 1 + .../net/osmand/RegionAddressRepository.java | 9 +- .../osmand/RegionAddressRepositoryBinary.java | 113 ++++++++++++++++-- .../osmand/RegionAddressRepositoryOdb.java | 57 ++++++++- .../search/SearchAddressActivity.java | 3 +- .../search/SearchByNameAbstractActivity.java | 13 +- .../search/SearchStreetByNameActivity.java | 40 +++++-- 9 files changed, 227 insertions(+), 34 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/data/City.java b/DataExtractionOSM/src/net/osmand/data/City.java index 5506cf8e7e..129923dc80 100644 --- a/DataExtractionOSM/src/net/osmand/data/City.java +++ b/DataExtractionOSM/src/net/osmand/data/City.java @@ -47,17 +47,23 @@ public class City extends MapObject { private CityType type = null; // Be attentive ! Working with street names ignoring case - private Map streets = new TreeMap(Collator.getInstance()); + private final Map streets; private String isin = null; public City(Node el){ super(el); + Collator instance = Collator.getInstance(); + instance.setStrength(Collator.PRIMARY); + streets = new TreeMap(instance); type = CityType.valueFromString(el.getTag(OSMTagKey.PLACE)); isin = el.getTag(OSMTagKey.IS_IN); isin = isin != null ? isin.toLowerCase() : null; } public City(CityType type){ + Collator instance = Collator.getInstance(); + instance.setStrength(Collator.PRIMARY); + streets = new TreeMap(instance); this.type = type; } @@ -70,14 +76,14 @@ public class City extends MapObject { } public Street registerStreet(String street){ - if(!streets.containsKey(street.toLowerCase())){ - streets.put(street.toLowerCase(), new Street(this, street)); + if(!streets.containsKey(street)){ + streets.put(street, new Street(this, street)); } - return streets.get(street.toLowerCase()); + return streets.get(street); } public Street unregisterStreet(String name){ - return streets.remove(name.toLowerCase()); + return streets.remove(name); } public void removeAllStreets(){ @@ -86,7 +92,6 @@ public class City extends MapObject { public Street registerStreet(Street street, boolean en){ String name = en ? street.getEnName(): street.getName(); - name = name.toLowerCase(); if(!Algoritms.isEmpty(name)){ if(!streets.containsKey(name)){ return streets.put(name, street); @@ -125,7 +130,7 @@ public class City extends MapObject { } public Street getStreet(String name){ - return streets.get(name.toLowerCase()); + return streets.get(name); } @Override diff --git a/DataExtractionOSM/src/net/osmand/data/Street.java b/DataExtractionOSM/src/net/osmand/data/Street.java index dcf4120e4d..a7cfb317f1 100644 --- a/DataExtractionOSM/src/net/osmand/data/Street.java +++ b/DataExtractionOSM/src/net/osmand/data/Street.java @@ -146,4 +146,10 @@ public class Street extends MapObject { this.indexInCity = indexInCity; } + public String getDisplayName(boolean useEnglishNames) { + StringBuilder output = new StringBuilder(); + output.append(getName(useEnglishNames)).append(" (").append(getCity().getName(useEnglishNames)).append(')'); + return output.toString(); + } + } diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index db190d5640..4a56c3ef1d 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -1,5 +1,6 @@ + Search street incrementally. At least 3 chars. Can take long time! Use this flag to check rendering performance Trace rendering Day diff --git a/OsmAnd/src/net/osmand/RegionAddressRepository.java b/OsmAnd/src/net/osmand/RegionAddressRepository.java index 63ade05b8b..ec329b7710 100644 --- a/OsmAnd/src/net/osmand/RegionAddressRepository.java +++ b/OsmAnd/src/net/osmand/RegionAddressRepository.java @@ -1,6 +1,7 @@ package net.osmand; import java.text.Collator; +import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -65,7 +66,12 @@ public interface RegionAddressRepository { public void fillWithSuggestedStreetsIntersectStreets(City city, Street st, List streetsToFill); public void fillWithSuggestedStreets(MapObject cityOrPostcode, String name, List streetsToFill); - + + public void fillWithSuggestedStreets(String name, List streetsToFill); + + public void fillWithSuggestedStreets(final String name, + List streetsToFill, Collection streets, boolean onlyStartCheck); + public void fillWithSuggestedCities(String name, List citiesToFill, LatLon currentLocation); public LatLon findStreetIntersection(Street street, Street street2); @@ -84,5 +90,6 @@ public interface RegionAddressRepository { // called to close resources public void close(); + } diff --git a/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java b/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java index f2034bf09d..3b2f1e4787 100644 --- a/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java @@ -5,10 +5,12 @@ import static net.osmand.CollatorStringMatcher.cstartsWith; import java.io.IOException; import java.text.Collator; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.TreeMap; @@ -84,6 +86,34 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository { } + @Override + public void fillWithSuggestedStreets(String name, List streetsToFill) { + try { + Collection citiesToLook = cities.isEmpty() ? file.getCities(region) : cities.values(); + fillWithSuggestedStreetsInCities(citiesToLook, name, streetsToFill); + List villages = file.getVillages(region); + fillWithSuggestedStreetsInCities(villages, name, streetsToFill); + } catch (IOException e) { + log.error("Disk operation failed" , e); + } + } + + private void fillWithSuggestedStreetsInCities( + Collection citiesToLook, String name, + List streetsToFill) throws IOException { + for (City city : citiesToLook) { + boolean preloaded = false; + if (city.getStreets().isEmpty()) { + preloaded = true; + file.preloadStreets(city); + } + fillWithSuggestedStreets(name, streetsToFill, city.getStreets(), true); + if (preloaded) { + city.removeAllStreets(); //so that we don't have memory issues + } + } + } + @Override public void fillWithSuggestedStreets(MapObject o, String name, List streetsToFill) { assert o instanceof PostCode || o instanceof City; @@ -93,17 +123,64 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository { preloadStreets(o); Collection streets = post == null ? city.getStreets() : post.getStreets() ; + fillWithSuggestedStreets(name, streetsToFill, streets, false); + } + + @Override + public void fillWithSuggestedStreets(final String name, + List streetsToFill, Collection streets, boolean onlyStartCheck) { if(name.length() == 0){ streetsToFill.addAll(streets); } else { int ind = 0; - for (Street s : streets) { - String sName = useEnglishNames ? s.getEnName() : s.getName(); //lower case not needed, collator ensures that - if (cstartsWith(collator,sName,name)) { - streetsToFill.add(ind, s); - ind++; - } else if (ccontains(collator,name,sName) || ccontains(collator,sName,name)) { - streetsToFill.add(s); + if (onlyStartCheck) { + //we assume the streets are ordered! + ArrayList streetList = new ArrayList(streets); + Comparator startCompare = new Comparator() { + int length = name.length(); + @Override + public int compare(Street object1, Street object2) { + String name1 = object1.getName(useEnglishNames); + String name2 = object2.getName(useEnglishNames); + return collator.compare( + name1.substring(0, Math.min( + name1.length(), length)), + name2.substring(0, Math.min( + name2.length(), length))); + } + }; + Street searchedStreet = new Street(null,name); + int index = Collections.binarySearch(streetList, searchedStreet, startCompare); + if (index > -1) { + streetsToFill.add(streetList.get(index)); + boolean found = true; + int i = 1; + while (found) { + found = false; + if (index + i < streetList.size()) { + if (startCompare.compare(streetList.get(index+i),searchedStreet) == 0) { + streetsToFill.add(streetList.get(index+i)); + found = true; + } + } + if (index - i >= 0) { + if (startCompare.compare(streetList.get(index-i),searchedStreet) == 0) { + streetsToFill.add(streetList.get(index-i)); + found = true; + } + } + i++; + } + } + } else { + for (Street s : streets) { + String sName = useEnglishNames ? s.getEnName() : s.getName(); //lower case not needed, collator ensures that + if (cstartsWith(collator,sName,name)) { + streetsToFill.add(ind, s); + ind++; + } else if (onlyStartCheck && (ccontains(collator,name,sName) || ccontains(collator,sName,name))) { + streetsToFill.add(s); + } } } } @@ -249,7 +326,25 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository { return null; } preloadCities(); - return cities.get(id); + City city = cities.get(id); + if (city == null) { + return getVilageById(id); + } else { + return city; + } + } + + private City getVilageById(Long id) { + try { + for (City c : file.getVillages(region)) { + if (c.getId().equals(id)) { + return c; + } + } + } catch (IOException e) { + log.error("Disk operation failed", e); //$NON-NLS-1$ + } + return null; } diff --git a/OsmAnd/src/net/osmand/RegionAddressRepositoryOdb.java b/OsmAnd/src/net/osmand/RegionAddressRepositoryOdb.java index 34f065d54f..c03b33fbd1 100644 --- a/OsmAnd/src/net/osmand/RegionAddressRepositoryOdb.java +++ b/OsmAnd/src/net/osmand/RegionAddressRepositoryOdb.java @@ -1,6 +1,7 @@ package net.osmand; import java.io.File; +import java.io.IOException; import java.text.Collator; import java.util.ArrayList; import java.util.Collection; @@ -206,6 +207,32 @@ public class RegionAddressRepositoryOdb implements RegionAddressRepository { } } + @Override + public void fillWithSuggestedStreets(String name, List streetsToFill) { + try { + preloadCities(); + fillWithSuggestedStreetsInCities(cities.values(), name, streetsToFill); + fillWithSuggestedStreetsInCities(getVillages(), name, streetsToFill); + } catch (IOException e) { + log.error("Disk operation failed" , e); + } + } + + private void fillWithSuggestedStreetsInCities( + Collection citiesToLook, String name, + List streetsToFill) throws IOException { + for (City city : citiesToLook) { + boolean preloaded = false; + if (city.getStreets().isEmpty()) { + preloaded = true; + preloadStreets(city); + } + fillWithSuggestedStreets(name, streetsToFill, city.getStreets(), true); + if (preloaded) { + city.removeAllStreets(); //so that we don't have memory issues + } + } + } public void fillWithSuggestedStreets(MapObject o, String name, List streetsToFill){ assert o instanceof PostCode || o instanceof City; @@ -215,7 +242,13 @@ public class RegionAddressRepositoryOdb implements RegionAddressRepository { name = name.toLowerCase(); Collection streets = post == null ? city.getStreets() : post.getStreets() ; - int ind = 0; + fillWithSuggestedStreets(name, streetsToFill, streets, false); + } + + @Override + public void fillWithSuggestedStreets(String name, + List streetsToFill, Collection streets, boolean startsWithOnly) { + int ind; if(name.length() == 0){ streetsToFill.addAll(streets); return; @@ -227,7 +260,7 @@ public class RegionAddressRepositoryOdb implements RegionAddressRepository { if (lowerCase.startsWith(name)) { streetsToFill.add(ind, s); ind++; - } else if (lowerCase.contains(name)) { + } else if (!startsWithOnly && lowerCase.contains(name)) { streetsToFill.add(s); } } @@ -318,6 +351,26 @@ public class RegionAddressRepositoryOdb implements RegionAddressRepository { } } + private List getVillages() + { + List hamlets = new ArrayList(); + StringBuilder where = new StringBuilder(80); + where. + append("city_type not in ("). //$NON-NLS-1$ + append('\'').append(CityType.valueToString(CityType.CITY)).append('\'').append(", "). //$NON-NLS-1$ + append('\'').append(CityType.valueToString(CityType.TOWN)).append('\'').append(") and "). //$NON-NLS-1$ + append(useEnglishNames ? "name_en" : "name").append(" LIKE '"+name+"%'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + Cursor query = db.query("city", new String[]{"id","latitude", "longitude", "name", "name_en", "city_type"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ + where.toString(), null, null, null, null); + if (query.moveToFirst()) { + do { + hamlets.add(parseCityFromCursor(query)); + } while (query.moveToNext()); + } + query.close(); + return hamlets; + } + public void preloadWayNodes(Street street){ if(street.getWayNodes().isEmpty()){ Cursor query = db.query("street_node", new String[]{"id", "latitude", "longitude", "street", "way"}, "? = street", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ diff --git a/OsmAnd/src/net/osmand/activities/search/SearchAddressActivity.java b/OsmAnd/src/net/osmand/activities/search/SearchAddressActivity.java index ea8a2ecf9c..66ff4ab567 100644 --- a/OsmAnd/src/net/osmand/activities/search/SearchAddressActivity.java +++ b/OsmAnd/src/net/osmand/activities/search/SearchAddressActivity.java @@ -135,6 +135,7 @@ public class SearchAddressActivity extends Activity { findViewById(R.id.ResetCity).setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { + OsmandSettings.setLastSearchedCity(SearchAddressActivity.this, -1L); postcode = null; city = null; street = null; @@ -263,7 +264,7 @@ public class SearchAddressActivity extends Activity { } else { streetButton.setText(street.getName(region.useEnglishNames())); } - streetButton.setEnabled(city != null || postcode != null); + streetButton.setEnabled(region != null); buildingButton.setEnabled(street != null); ((RadioGroup)findViewById(R.id.RadioGroup)).setVisibility(street == null ? View.GONE : View.VISIBLE); diff --git a/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java b/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java index 111c10babd..b58f89b2e3 100644 --- a/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java +++ b/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java @@ -78,11 +78,13 @@ public abstract class SearchByNameAbstractActivity extends ListActivity { runOnUiThread(new Runnable(){ @Override public void run() { - ((NamesAdapter)getListAdapter()).setNotifyOnChange(false); + NamesAdapter namesAdapter = (NamesAdapter)getListAdapter(); + namesAdapter.setNotifyOnChange(false); + namesAdapter.clear(); for(T o : objects){ - ((NamesAdapter)getListAdapter()).add(o); + namesAdapter.add(o); } - ((NamesAdapter)getListAdapter()).notifyDataSetChanged(); + namesAdapter.notifyDataSetChanged(); progress.setVisibility(View.INVISIBLE); } }); @@ -93,7 +95,6 @@ public abstract class SearchByNameAbstractActivity extends ListActivity { ((NamesAdapter) getListAdapter()).getFilter().filter(filter); return; } - ((NamesAdapter) getListAdapter()).clear(); if(handlerToLoop == null){ return; @@ -104,9 +105,7 @@ public abstract class SearchByNameAbstractActivity extends ListActivity { public void run() { showProgress(View.VISIBLE); List loadedObjects = getObjects(filter); - if(handlerToLoop != null && !handlerToLoop.hasMessages(1)){ - updateUIList(loadedObjects); - } + updateUIList(loadedObjects); } }); msg.what = 1; diff --git a/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java b/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java index c65e52281a..aabda7a40d 100644 --- a/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java +++ b/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java @@ -18,6 +18,8 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity getObjects(String filter) { - List l = new ArrayList(); - if (city != null || postcode != null) { - region.fillWithSuggestedStreets(postcode == null ? city : postcode, filter, l); + NamesAdapter list = (NamesAdapter)getListAdapter(); + boolean countrySearch = isCountrySearch(); + boolean incremental = filter.startsWith(oldfilter) && oldfilter.length() > 0 && list.getCount() > 0; + this.oldfilter = filter; + List result = new ArrayList(); + if (incremental) { + List streets = new ArrayList(); + for (int i = 0; i < list.getCount(); i++ ) { + streets.add((Street) list.getItem(i)); + } + region.fillWithSuggestedStreets(filter,result,streets,countrySearch); + } else { + if (!countrySearch) { + region.fillWithSuggestedStreets(postcode == null ? city : postcode, filter, result); + } else if (filter.length() > 2) { + region.fillWithSuggestedStreets(filter, result); + } } - return l; + return result; + } + + private boolean isCountrySearch() { + return city == null && postcode == null; } @Override public void updateTextView(Street obj, TextView txt) { - txt.setText(obj.getName(region.useEnglishNames())); + if (city != null || postcode != null) { + txt.setText(obj.getName(region.useEnglishNames())); + } else { + txt.setText(obj.getDisplayName(region.useEnglishNames())); + } } @Override public void itemSelected(Street obj) { + if (obj.getCity() != null) { //can be in case of postcode + OsmandSettings.setLastSearchedCity(this, obj.getCity().getId()); + } OsmandSettings.setLastSearchedStreet(this, obj.getName(region.useEnglishNames())); finish(); - } } From d5ca3f39619a500bdc39602c8c2d9689c5e1c84b Mon Sep 17 00:00:00 2001 From: Pavol Zibrita Date: Wed, 2 Feb 2011 23:21:32 +0100 Subject: [PATCH 2/3] The incremental search might be wrong when ui thread is slower then next triggered search. Waiting for ui thread. --- .../search/SearchByNameAbstractActivity.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java b/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java index b58f89b2e3..ae719df3d2 100644 --- a/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java +++ b/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java @@ -1,6 +1,7 @@ package net.osmand.activities.search; import java.util.List; +import java.util.concurrent.Semaphore; import net.osmand.R; import android.app.ListActivity; @@ -106,11 +107,28 @@ public abstract class SearchByNameAbstractActivity extends ListActivity { showProgress(View.VISIBLE); List loadedObjects = getObjects(filter); updateUIList(loadedObjects); + //because of incremental, wait for the ui update + waitForUIThread(); } }); msg.what = 1; handlerToLoop.sendMessageDelayed(msg, 150); } + + private void waitForUIThread() { + final Semaphore semafor = new Semaphore(1); + try { + semafor.acquire(); + runOnUiThread(new Runnable() { + @Override + public void run() { + semafor.release(); + } + }); + semafor.acquire(); + } catch (InterruptedException e) { + } + } private void showProgress(final int v){ runOnUiThread(new Runnable(){ From 2d6f46e41e7e72b116adf88518373e0bea7723bb Mon Sep 17 00:00:00 2001 From: Pavol Zibrita Date: Wed, 2 Feb 2011 23:49:29 +0100 Subject: [PATCH 3/3] Forget to sync on ui thread, forget to sort streets. --- OsmAnd/src/net/osmand/RegionAddressRepository.java | 2 +- OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java | 8 ++++++++ .../activities/search/SearchByNameAbstractActivity.java | 7 +++++++ .../activities/search/SearchStreetByNameActivity.java | 8 ++------ 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/RegionAddressRepository.java b/OsmAnd/src/net/osmand/RegionAddressRepository.java index ec329b7710..b77d9f2b5f 100644 --- a/OsmAnd/src/net/osmand/RegionAddressRepository.java +++ b/OsmAnd/src/net/osmand/RegionAddressRepository.java @@ -70,7 +70,7 @@ public interface RegionAddressRepository { public void fillWithSuggestedStreets(String name, List streetsToFill); public void fillWithSuggestedStreets(final String name, - List streetsToFill, Collection streets, boolean onlyStartCheck); + List streetsToFill, Collection sortedStreets, boolean onlyStartCheck); public void fillWithSuggestedCities(String name, List citiesToFill, LatLon currentLocation); diff --git a/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java b/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java index 3b2f1e4787..0539d34d34 100644 --- a/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java @@ -93,6 +93,14 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository { fillWithSuggestedStreetsInCities(citiesToLook, name, streetsToFill); List villages = file.getVillages(region); fillWithSuggestedStreetsInCities(villages, name, streetsToFill); + Collections.sort(streetsToFill, new Comparator() { + @Override + public int compare(Street object1, Street object2) { + String name1 = object1.getName(useEnglishNames); + String name2 = object2.getName(useEnglishNames); + return collator.compare(name1,name2); + } + }); } catch (IOException e) { log.error("Disk operation failed" , e); } diff --git a/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java b/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java index ae719df3d2..815310c9d8 100644 --- a/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java +++ b/OsmAnd/src/net/osmand/activities/search/SearchByNameAbstractActivity.java @@ -191,10 +191,17 @@ public abstract class SearchByNameAbstractActivity extends ListActivity { class NamesAdapter extends ArrayAdapter { + private final List list; + NamesAdapter(List list) { super(SearchByNameAbstractActivity.this, R.layout.searchbyname_list, list); + this.list = list; } + public List getList() { + return list; + } + public View getView(int position, View convertView, ViewGroup parent) { View row; if (convertView != null) { diff --git a/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java b/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java index aabda7a40d..1d0bfae9b6 100644 --- a/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java +++ b/OsmAnd/src/net/osmand/activities/search/SearchStreetByNameActivity.java @@ -38,15 +38,11 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity getObjects(String filter) { NamesAdapter list = (NamesAdapter)getListAdapter(); boolean countrySearch = isCountrySearch(); - boolean incremental = filter.startsWith(oldfilter) && oldfilter.length() > 0 && list.getCount() > 0; + boolean incremental = filter.startsWith(oldfilter) && oldfilter.length() > 0 && !list.getList().isEmpty(); this.oldfilter = filter; List result = new ArrayList(); if (incremental) { - List streets = new ArrayList(); - for (int i = 0; i < list.getCount(); i++ ) { - streets.add((Street) list.getItem(i)); - } - region.fillWithSuggestedStreets(filter,result,streets,countrySearch); + region.fillWithSuggestedStreets(filter,result,list.getList(),countrySearch); } else { if (!countrySearch) { region.fillWithSuggestedStreets(postcode == null ? city : postcode, filter, result);