Implement incremental search
This commit is contained in:
parent
890277dd4b
commit
4d56ca74de
11 changed files with 218 additions and 139 deletions
|
@ -12,4 +12,9 @@ public interface ResultMatcher<T> {
|
|||
*/
|
||||
boolean publish(T object);
|
||||
|
||||
/**
|
||||
* @returns true to stop processing
|
||||
*/
|
||||
boolean isCancelled();
|
||||
|
||||
}
|
||||
|
|
|
@ -104,6 +104,9 @@ public class BinaryMapAddressReaderAdapter {
|
|||
}
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
if(resultMatcher != null && resultMatcher.isCancelled()){
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
|
@ -441,7 +444,7 @@ public class BinaryMapAddressReaderAdapter {
|
|||
}
|
||||
|
||||
// do not preload streets in city
|
||||
protected LatLon findIntersectedStreets(City c, Street s, Street s2, List<Street> streets) throws IOException {
|
||||
protected LatLon findIntersectedStreets(City c, Street s, Street s2, List<Street> streets) throws IOException {
|
||||
if(s.getIndexInCity() == -1){
|
||||
return null;
|
||||
}
|
||||
|
@ -493,6 +496,9 @@ public class BinaryMapAddressReaderAdapter {
|
|||
}
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
if(resultMatcher != null && resultMatcher.isCancelled()){
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
|
||||
import java.text.Collator;
|
||||
|
||||
import net.osmand.StringMatcher;
|
||||
|
@ -10,18 +11,50 @@ import net.osmand.StringMatcher;
|
|||
*
|
||||
* @author pavol.zibrita
|
||||
*/
|
||||
public abstract class CollatorStringMatcher implements StringMatcher {
|
||||
public class CollatorStringMatcher implements StringMatcher {
|
||||
|
||||
private final Collator collator;
|
||||
private final StringMatcherMode mode;
|
||||
private final String part;
|
||||
|
||||
public CollatorStringMatcher(Collator collator) {
|
||||
public enum StringMatcherMode {
|
||||
CHECK_ONLY_STARTS_WITH,
|
||||
CHECK_STARTS_FROM_SPACE,
|
||||
CHECK_STARTS_FROM_SPACE_NOT_BEGINNING,
|
||||
CHECK_CONTAINS
|
||||
}
|
||||
|
||||
public CollatorStringMatcher(Collator collator, String part, StringMatcherMode mode) {
|
||||
this.collator = collator;
|
||||
this.part = part;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public Collator getCollator() {
|
||||
return collator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String name) {
|
||||
return cmatches(collator, name, part, mode);
|
||||
}
|
||||
|
||||
|
||||
public static boolean cmatches(Collator collator, String base, String part, StringMatcherMode mode){
|
||||
switch (mode) {
|
||||
case CHECK_CONTAINS:
|
||||
return ccontains(collator, base, part);
|
||||
case CHECK_STARTS_FROM_SPACE:
|
||||
return cstartsWith(collator, base, part, true, true);
|
||||
case CHECK_STARTS_FROM_SPACE_NOT_BEGINNING:
|
||||
return cstartsWith(collator, base, part, false, true);
|
||||
case CHECK_ONLY_STARTS_WITH:
|
||||
return cstartsWith(collator, base, part, true, false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if part contains in base
|
||||
*
|
||||
|
@ -30,7 +63,7 @@ public abstract class CollatorStringMatcher implements StringMatcher {
|
|||
* @param base String where to search
|
||||
* @return true if part is contained in base
|
||||
*/
|
||||
public static boolean ccontains(Collator collator, String part, String base) {
|
||||
public static boolean ccontains(Collator collator, String base, String part) {
|
||||
int pos = 0;
|
||||
if (part.length() > 3) {
|
||||
// improve searching by searching first 3 characters
|
||||
|
@ -56,17 +89,40 @@ public abstract class CollatorStringMatcher implements StringMatcher {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks if string starts with another string
|
||||
* Checks if string starts with another string.
|
||||
* Special check try to find as well in the middle of name
|
||||
*
|
||||
* @param collator
|
||||
* @param searchIn
|
||||
* @param theStart
|
||||
* @return true if searchIn starts with token
|
||||
*/
|
||||
public static boolean cstartsWith(Collator collator, String searchIn, String theStart) {
|
||||
public static boolean cstartsWith(Collator collator, String searchIn, String theStart,
|
||||
boolean checkBeginning, boolean checkSpaces) {
|
||||
int startLength = theStart.length();
|
||||
int searchInLength = searchIn.length();
|
||||
if (startLength == 0) {
|
||||
return true;
|
||||
}
|
||||
if (startLength > searchInLength) {
|
||||
return false;
|
||||
}
|
||||
// simulate starts with for collator
|
||||
return collator.equals(
|
||||
searchIn.substring(0,
|
||||
Math.min(searchIn.length(), theStart.length())), theStart);
|
||||
if (checkBeginning) {
|
||||
boolean starts = collator.equals(searchIn.substring(0, startLength), theStart);
|
||||
if (starts) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (checkSpaces) {
|
||||
for (int i = 1; i <= searchInLength - startLength; i++) {
|
||||
if (Character.isSpace(searchIn.charAt(i - 1)) && !Character.isSpace(searchIn.charAt(i))) {
|
||||
if (collator.equals(searchIn.substring(i, i + startLength), theStart)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import java.text.Collator;
|
||||
|
||||
/**
|
||||
* This simple contains string matcher uses collator to check,
|
||||
* if the part is contained in matched string.
|
||||
*
|
||||
* @author pavol.zibrita
|
||||
*/
|
||||
public class ContainsStringMatcher extends CollatorStringMatcher {
|
||||
|
||||
private final String part;
|
||||
|
||||
/**
|
||||
* @param part Search this string in matched base string, see {@link #matches(String)}
|
||||
* @param collator Collator to use
|
||||
*/
|
||||
public ContainsStringMatcher(String part, Collator collator) {
|
||||
super(collator);
|
||||
this.part = part;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String base) {
|
||||
return ccontains(getCollator(), part, base);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import static net.osmand.plus.CollatorStringMatcher.ccontains;
|
||||
import static net.osmand.plus.CollatorStringMatcher.cstartsWith;
|
||||
import static net.osmand.plus.CollatorStringMatcher.cmatches;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -23,6 +21,7 @@ import net.osmand.data.MapObject;
|
|||
import net.osmand.data.PostCode;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.plus.CollatorStringMatcher.StringMatcherMode;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -61,13 +60,13 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
|||
}
|
||||
preloadBuildings(street, null);
|
||||
name = name.toLowerCase();
|
||||
int ind = 0;
|
||||
for (Building building : street.getBuildings()) {
|
||||
if(resultMatcher.isCancelled()){
|
||||
return buildingsToFill;
|
||||
}
|
||||
String bName = useEnglishNames ? building.getEnName() : building.getName(); //lower case not needed, collator ensures that
|
||||
if (cstartsWith(collator,bName,name)) {
|
||||
buildingsToFill.add(ind, building);
|
||||
ind++;
|
||||
} else if (ccontains(collator,name,bName)) {
|
||||
if (cmatches(collator, bName, name, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) {
|
||||
resultMatcher.publish(building);
|
||||
buildingsToFill.add(building);
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +86,11 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
|||
}
|
||||
|
||||
|
||||
// not use ccontains It is really slow, takes about 10 times more than other steps
|
||||
private StringMatcherMode[] streetsCheckMode = new StringMatcherMode[] {StringMatcherMode.CHECK_ONLY_STARTS_WITH,
|
||||
StringMatcherMode.CHECK_STARTS_FROM_SPACE_NOT_BEGINNING};
|
||||
|
||||
|
||||
@Override
|
||||
public List<Street> fillWithSuggestedStreets(MapObject o, ResultMatcher<Street> resultMatcher, String... names) {
|
||||
assert o instanceof PostCode || o instanceof City;
|
||||
|
@ -99,18 +103,22 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
|||
return streetsToFill;
|
||||
}
|
||||
preloadStreets(o, null);
|
||||
int ind = 0;
|
||||
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets() ;
|
||||
Iterator<Street> iterator = streets.iterator();
|
||||
while(iterator.hasNext()) {
|
||||
Street s = iterator.next();
|
||||
String sName = useEnglishNames ? s.getEnName() : s.getName(); // lower case not needed, collator ensures that
|
||||
for (String name : names) {
|
||||
if (cstartsWith(collator, sName, name)) {
|
||||
streetsToFill.add(ind, s);
|
||||
ind++;
|
||||
} else if (ccontains(collator, name, sName) || ccontains(collator, sName, name)) {
|
||||
streetsToFill.add(s);
|
||||
|
||||
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets();
|
||||
|
||||
// 1st step loading by starts with
|
||||
for (StringMatcherMode mode : streetsCheckMode) {
|
||||
for (Street s : streets) {
|
||||
if (resultMatcher.isCancelled()) {
|
||||
return streetsToFill;
|
||||
}
|
||||
String sName = s.getName(useEnglishNames); // lower case not needed, collator ensures that
|
||||
for (String name : names) {
|
||||
boolean match = CollatorStringMatcher.cmatches(collator, sName, name, mode);
|
||||
if (match) {
|
||||
resultMatcher.publish(s);
|
||||
streetsToFill.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,72 +151,55 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
|||
preloadCities(resultMatcher);
|
||||
citiesToFill.addAll(cities.values());
|
||||
return citiesToFill;
|
||||
} else {
|
||||
preloadCities(null);
|
||||
}
|
||||
|
||||
preloadCities(null);
|
||||
if (name.length() == 0) {
|
||||
citiesToFill.addAll(cities.values());
|
||||
return citiesToFill;
|
||||
}
|
||||
try {
|
||||
// essentially index is created that cities towns are first in cities map
|
||||
int ind = 0;
|
||||
if (name.length() >= 2 && Algoritms.containsDigit(name)) {
|
||||
// also try to identify postcodes
|
||||
String uName = name.toUpperCase();
|
||||
for (PostCode code : file.getPostcodes(region, resultMatcher, new ContainsStringMatcher(uName, collator))) {
|
||||
if (cstartsWith(collator, code.getName(), uName)) {
|
||||
citiesToFill.add(ind++, code);
|
||||
} else if (ccontains(collator, code.getName(), uName)) {
|
||||
citiesToFill.add(code);
|
||||
for (PostCode code : file.getPostcodes(region, resultMatcher, new CollatorStringMatcher(collator, uName,
|
||||
StringMatcherMode.CHECK_CONTAINS))) {
|
||||
citiesToFill.add(code);
|
||||
if (resultMatcher.isCancelled()) {
|
||||
return citiesToFill;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (name.length() < 3) {
|
||||
if (name.length() == 0) {
|
||||
citiesToFill.addAll(cities.values());
|
||||
} else {
|
||||
name = name.toLowerCase();
|
||||
for (City c : cities.values()) {
|
||||
String cName = useEnglishNames ? c.getEnName() : c.getName(); //lower case not needed, collator ensures that
|
||||
if (cstartsWith(collator, cName, name)) {
|
||||
if (resultMatcher.publish(c)) {
|
||||
citiesToFill.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
name = name.toLowerCase();
|
||||
for (City c : cities.values()) {
|
||||
String cName = useEnglishNames ? c.getEnName() : c.getName(); //lower case not needed, collator ensures that
|
||||
if (cstartsWith(collator,cName,name)) {
|
||||
if (resultMatcher.publish(c)) {
|
||||
citiesToFill.add(ind, c);
|
||||
ind++;
|
||||
}
|
||||
} else if (ccontains(collator,name,cName)) {
|
||||
if (resultMatcher.publish(c)) {
|
||||
citiesToFill.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int initialsize = citiesToFill.size();
|
||||
|
||||
for(City c : file.getVillages(region, resultMatcher, new ContainsStringMatcher(name,collator), useEnglishNames )){
|
||||
String cName = c.getName(useEnglishNames); //lower case not needed, collator ensures that
|
||||
if (cstartsWith(collator,cName,name)) {
|
||||
citiesToFill.add(ind, c);
|
||||
ind++;
|
||||
} else if (ccontains(collator,name, cName)) {
|
||||
name = name.toLowerCase();
|
||||
for (City c : cities.values()) {
|
||||
String cName = c.getName(useEnglishNames); // lower case not needed, collator ensures that
|
||||
if (cmatches(collator, cName, name, StringMatcherMode.CHECK_STARTS_FROM_SPACE)) {
|
||||
if (resultMatcher.publish(c)) {
|
||||
citiesToFill.add(c);
|
||||
}
|
||||
}
|
||||
log.debug("Loaded citites " + (citiesToFill.size() - initialsize)); //$NON-NLS-1$
|
||||
if (resultMatcher.isCancelled()) {
|
||||
return citiesToFill;
|
||||
}
|
||||
}
|
||||
|
||||
int initialsize = citiesToFill.size();
|
||||
if (name.length() >= 3) {
|
||||
for (City c : file.getVillages(region, resultMatcher, new CollatorStringMatcher(collator, name,
|
||||
StringMatcherMode.CHECK_STARTS_FROM_SPACE), useEnglishNames)) {
|
||||
citiesToFill.add(c);
|
||||
if (resultMatcher.isCancelled()) {
|
||||
return citiesToFill;
|
||||
}
|
||||
}
|
||||
}
|
||||
log.debug("Loaded citites " + (citiesToFill.size() - initialsize)); //$NON-NLS-1$
|
||||
} catch (IOException e) {
|
||||
log.error("Disk operation failed" , e); //$NON-NLS-1$
|
||||
log.error("Disk operation failed", e); //$NON-NLS-1$
|
||||
}
|
||||
return citiesToFill;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -255,6 +246,11 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
|||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + " repository";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useEnglishNames() {
|
||||
return useEnglishNames;
|
||||
|
@ -356,4 +352,6 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
|||
return file.getRegionCenter(region);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public class SearchBuildingByNameActivity extends SearchByNameAbstractActivity<B
|
|||
protected void onPostExecute(Void result) {
|
||||
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_building);
|
||||
progress.setVisibility(View.INVISIBLE);
|
||||
resetText();
|
||||
updateSearchText();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,6 +38,7 @@ public class SearchBuildingByNameActivity extends SearchByNameAbstractActivity<B
|
|||
}
|
||||
@Override
|
||||
protected Void doInBackground(Object... params) {
|
||||
region = ((OsmandApplication)getApplication()).getResourceManager().getRegionRepository(settings.getLastSearchedRegion());
|
||||
if(region != null){
|
||||
postcode = region.getPostcode(settings.getLastSearchedPostcode());
|
||||
city = region.getCityById(settings.getLastSearchedCity());
|
||||
|
@ -47,7 +48,11 @@ public class SearchBuildingByNameActivity extends SearchByNameAbstractActivity<B
|
|||
street = region.getStreetByName(city, settings.getLastSearchedStreet());
|
||||
}
|
||||
}
|
||||
region = ((OsmandApplication)getApplication()).getResourceManager().getRegionRepository(settings.getLastSearchedRegion());
|
||||
if(street != null){
|
||||
// preload here to avoid concurrent modification
|
||||
region.fillWithSuggestedBuildings(postcode, street, "", null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@ -62,6 +67,10 @@ public class SearchBuildingByNameActivity extends SearchByNameAbstractActivity<B
|
|||
task.progress(object);
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return task.isCancelled();
|
||||
}
|
||||
});
|
||||
}
|
||||
return new ArrayList<Building>();
|
||||
|
|
|
@ -41,17 +41,19 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
|
|||
super.onCreate(savedInstanceState);
|
||||
settings = OsmandSettings.getOsmandSettings(this);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.search_by_name);
|
||||
initializeTask = getInitializeTask();
|
||||
NamesAdapter namesAdapter = new NamesAdapter(new ArrayList<T>()); //$NON-NLS-1$
|
||||
setListAdapter(namesAdapter);
|
||||
|
||||
|
||||
progress = (ProgressBar) findViewById(R.id.ProgressBar);
|
||||
searchText = (EditText) findViewById(R.id.SearchText);
|
||||
searchText.addTextChangedListener(new TextWatcher(){
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if(initializeTask.getStatus() == Status.FINISHED){
|
||||
if(initializeTask == null || initializeTask.getStatus() == Status.FINISHED){
|
||||
setText(s.toString());
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +63,6 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
|
|||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
});
|
||||
searchText.requestFocus();
|
||||
|
||||
|
@ -69,13 +70,11 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
|
|||
findViewById(R.id.ResetButton).setOnClickListener(new View.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
resetText();
|
||||
searchText.setText("");
|
||||
}
|
||||
|
||||
});
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||
|
||||
initializeTask = getInitializeTask();
|
||||
if(initializeTask != null){
|
||||
initializeTask.execute();
|
||||
}
|
||||
|
@ -86,7 +85,6 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public boolean isFilterableByDefault(){
|
||||
return false;
|
||||
}
|
||||
|
@ -95,29 +93,24 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
|
|||
return searchText.getText();
|
||||
}
|
||||
|
||||
public void resetText(){
|
||||
setText("");
|
||||
public void updateSearchText(){
|
||||
setText(searchText.getText().toString());
|
||||
}
|
||||
|
||||
|
||||
public void setText(final String filter) {
|
||||
if(isFilterableByDefault()){
|
||||
if (isFilterableByDefault()) {
|
||||
((NamesAdapter) getListAdapter()).getFilter().filter(filter);
|
||||
return;
|
||||
}
|
||||
((NamesAdapter) getListAdapter()).clear();
|
||||
Status status = searchTask.getStatus();
|
||||
if(status == Status.FINISHED){
|
||||
searchTask = new SearchByNameTask();
|
||||
} else if(status == Status.RUNNING){
|
||||
if (status != Status.FINISHED) {
|
||||
searchTask.cancel(true);
|
||||
// TODO improve
|
||||
searchTask = new SearchByNameTask();
|
||||
}
|
||||
searchTask = new SearchByNameTask();
|
||||
searchTask.execute(filter);
|
||||
}
|
||||
|
||||
|
||||
public abstract List<T> getObjects(String filter, SearchByNameTask searchTask);
|
||||
|
||||
public abstract void updateTextView(T obj, TextView txt);
|
||||
|
@ -157,12 +150,16 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
|
|||
|
||||
protected class SearchByNameTask extends AsyncTask<String, T, List<T>> {
|
||||
|
||||
private String filter;
|
||||
private long startTime;
|
||||
|
||||
@Override
|
||||
protected List<T> doInBackground(String... params) {
|
||||
if(params == null || params.length == 0){
|
||||
return null;
|
||||
}
|
||||
String filter = params[0];
|
||||
filter = params[0];
|
||||
startTime = System.currentTimeMillis();
|
||||
return getObjects(filter, this);
|
||||
}
|
||||
|
||||
|
@ -184,6 +181,7 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
|
|||
|
||||
@Override
|
||||
protected void onPostExecute(List<T> result) {
|
||||
System.out.println("Search " + filter + " finished in " + (System.currentTimeMillis() - startTime));
|
||||
if (!isCancelled() && result != null) {
|
||||
((NamesAdapter) getListAdapter()).setNotifyOnChange(false);
|
||||
((NamesAdapter) getListAdapter()).clear();
|
||||
|
|
|
@ -10,13 +10,10 @@ import net.osmand.data.MapObject;
|
|||
import net.osmand.data.PostCode;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.RegionAddressRepository;
|
||||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import net.osmand.plus.activities.search.SearchByNameAbstractActivity.SearchByNameTask;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -26,12 +23,12 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<MapOb
|
|||
|
||||
@Override
|
||||
public AsyncTask<Object, ?, ?> getInitializeTask() {
|
||||
return new AsyncTask<Object, Void, Void>(){
|
||||
return new AsyncTask<Object, MapObject, Void>(){
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_city);
|
||||
progress.setVisibility(View.INVISIBLE);
|
||||
resetText();
|
||||
updateSearchText();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,9 +36,35 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<MapOb
|
|||
((TextView)findViewById(R.id.Label)).setText(R.string.loading_cities);
|
||||
progress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(MapObject... values) {
|
||||
if (hasWindowFocus()) {
|
||||
for (MapObject t : values) {
|
||||
((NamesAdapter) getListAdapter()).add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Object... params) {
|
||||
region = ((OsmandApplication)getApplication()).getResourceManager().getRegionRepository(settings.getLastSearchedRegion());
|
||||
if(region != null){
|
||||
// preload cities
|
||||
region.fillWithSuggestedCities("", new ResultMatcher<MapObject>() {
|
||||
|
||||
@Override
|
||||
public boolean publish(MapObject object) {
|
||||
publishProgress(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
}, locationToSearch);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@ -50,13 +73,18 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<MapOb
|
|||
@Override
|
||||
public List<MapObject> getObjects(String filter, final SearchByNameTask task) {
|
||||
if(region != null){
|
||||
region.fillWithSuggestedCities(filter, new ResultMatcher<MapObject>() {
|
||||
return region.fillWithSuggestedCities(filter, new ResultMatcher<MapObject>() {
|
||||
|
||||
@Override
|
||||
public boolean publish(MapObject object) {
|
||||
task.progress(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return task.isCancelled();
|
||||
}
|
||||
}, locationToSearch);
|
||||
}
|
||||
return new ArrayList<MapObject>();
|
||||
|
|
|
@ -21,6 +21,8 @@ public class SearchRegionByNameActivity extends SearchByNameAbstractActivity<Reg
|
|||
if(((OsmandApplication)getApplication()).getResourceManager().getAddressRepositories().isEmpty()){
|
||||
Toast.makeText(this, R.string.none_region_found, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
NamesAdapter namesAdapter = new NamesAdapter(getObjects("", null)); //$NON-NLS-1$
|
||||
setListAdapter(namesAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,7 +9,6 @@ import net.osmand.data.Street;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.RegionAddressRepository;
|
||||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import net.osmand.plus.activities.search.SearchByNameAbstractActivity.SearchByNameTask;
|
||||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
@ -29,7 +28,7 @@ public class SearchStreet2ByNameActivity extends SearchByNameAbstractActivity<St
|
|||
protected void onPostExecute(Void result) {
|
||||
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_street);
|
||||
progress.setVisibility(View.INVISIBLE);
|
||||
resetText();
|
||||
updateSearchText();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,7 +50,7 @@ public class SearchStreet2ByNameActivity extends SearchByNameAbstractActivity<St
|
|||
} else if(city != null){
|
||||
street1 = region.getStreetByName(city, (settings.getLastSearchedStreet()));
|
||||
}
|
||||
if(city != null){
|
||||
if(city != null && street1 != null){
|
||||
List<Street> t = new ArrayList<Street>();
|
||||
region.fillWithSuggestedStreetsIntersectStreets(city, street1, t);
|
||||
initialList = t;
|
||||
|
|
|
@ -22,12 +22,12 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
|
|||
|
||||
@Override
|
||||
public AsyncTask<Object, ?, ?> getInitializeTask() {
|
||||
return new AsyncTask<Object, Void, Void>(){
|
||||
return new AsyncTask<Object, Street, Void>(){
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_street);
|
||||
progress.setVisibility(View.INVISIBLE);
|
||||
resetText();
|
||||
updateSearchText();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,6 +35,7 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
|
|||
((TextView)findViewById(R.id.Label)).setText(R.string.loading_streets);
|
||||
progress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Object... params) {
|
||||
region = ((OsmandApplication)getApplication()).getResourceManager().getRegionRepository(settings.getLastSearchedRegion());
|
||||
|
@ -44,6 +45,8 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
|
|||
city = region.getCityById(settings.getLastSearchedCity());
|
||||
}
|
||||
}
|
||||
// preload here to avoid concurrent modification
|
||||
region.fillWithSuggestedStreets(postcode == null ? city : postcode, null);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@ -58,6 +61,10 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
|
|||
task.progress(object);
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return task.isCancelled();
|
||||
}
|
||||
}, filter);
|
||||
}
|
||||
return new ArrayList<Street>();
|
||||
|
|
Loading…
Reference in a new issue