Sort the list in search by address activities

This commit is contained in:
Pavol Zibrita 2012-06-03 09:13:56 +02:00
parent 046d4008c4
commit 1a7b0e82ee
8 changed files with 131 additions and 59 deletions

View file

@ -1,5 +1,6 @@
package net.osmand.plus.activities; package net.osmand.plus.activities;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import android.app.ListActivity; import android.app.ListActivity;
import android.widget.ListView; import android.widget.ListView;
@ -14,4 +15,8 @@ public abstract class OsmandListActivity extends ListActivity {
view.setCacheColorHint(getResources().getColor(R.color.activity_background)); view.setCacheColorHint(getResources().getColor(R.color.activity_background));
view.setDivider(getResources().getDrawable(R.drawable.tab_text_separator)); view.setDivider(getResources().getDrawable(R.drawable.tab_text_separator));
} }
protected OsmandApplication getMyApplication() {
return (OsmandApplication) getApplication();
}
} }

View file

@ -270,10 +270,6 @@ public class GeoIntentActivity extends OsmandListActivity {
return getMyApplication().getResourceManager(); return getMyApplication().getResourceManager();
} }
private OsmandApplication getMyApplication() {
return ((OsmandApplication) getApplication());
}
private class GeoPointSearch implements MyService { private class GeoPointSearch implements MyService {
private MapObject point; private MapObject point;

View file

@ -1,10 +1,12 @@
package net.osmand.plus.activities.search; package net.osmand.plus.activities.search;
import java.util.Comparator;
import java.util.List; import java.util.List;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.data.Building; import net.osmand.data.Building;
import net.osmand.data.City; import net.osmand.data.City;
import net.osmand.data.MapObjectComparator;
import net.osmand.data.Street; import net.osmand.data.Street;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -18,6 +20,11 @@ public class SearchBuildingByNameActivity extends SearchByNameAbstractActivity<B
private City city; private City city;
private Street street; private Street street;
@Override
protected Comparator<? super Building> createComparator() {
return new MapObjectComparator(getMyApplication().getSettings().usingEnglishNames());
}
@Override @Override
public AsyncTask<Object, ?, ?> getInitializeTask() { public AsyncTask<Object, ?, ?> getInitializeTask() {
return new AsyncTask<Object, Void, List<Building>>(){ return new AsyncTask<Object, Void, List<Building>>(){

View file

@ -2,7 +2,11 @@ package net.osmand.plus.activities.search;
import java.text.Collator; import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Locale;
import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher;
import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.CollatorStringMatcher.StringMatcherMode;
@ -52,8 +56,7 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
protected Collator collator; protected Collator collator;
protected NamesFilter namesFilter; protected NamesFilter namesFilter;
private String currentFilter = ""; private String currentFilter = "";
private static final Log log = LogUtil.getLog(SearchByNameAbstractActivity.class); private static final Log log = LogUtil.getLog(SearchByNameAbstractActivity.class);
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -65,10 +68,10 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
initializeTask = getInitializeTask(); initializeTask = getInitializeTask();
uiHandler = new UIUpdateHandler(); uiHandler = new UIUpdateHandler();
namesFilter = new NamesFilter(); namesFilter = new NamesFilter();
NamesAdapter namesAdapter = new NamesAdapter(new ArrayList<T>()); //$NON-NLS-1$ NamesAdapter namesAdapter = new NamesAdapter(new ArrayList<T>(),createComparator()); //$NON-NLS-1$
setListAdapter(namesAdapter); setListAdapter(namesAdapter);
collator = Collator.getInstance(); collator = Collator.getInstance(Locale.US);
collator.setStrength(Collator.PRIMARY); //ignores also case collator.setStrength(Collator.PRIMARY); //ignores also case
@ -141,6 +144,7 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
querySearch(searchText.getText().toString()); querySearch(searchText.getText().toString());
} }
protected abstract Comparator<? super T> createComparator();
public abstract String getText(T obj); public abstract String getText(T obj);
@ -188,12 +192,11 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
} }
protected void filterLoop(String query, List<T> list) { protected void filterLoop(String query, Collection<T> list) {
for (int i = 0; i < list.size(); i++) { for (T obj : list) {
if(namesFilter.isCancelled){ if(namesFilter.isCancelled){
break; break;
} }
T obj = list.get(i);
if(filterObject(obj, query)){ if(filterObject(obj, query)){
Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj); Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj);
msg.sendToTarget(); msg.sendToTarget();
@ -236,7 +239,7 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
uiHandler.sendEmptyMessage(MESSAGE_CLEAR_LIST); uiHandler.sendEmptyMessage(MESSAGE_CLEAR_LIST);
// make link copy // make link copy
List<T> list = initialListToFilter; Collection<T> list = initialListToFilter;
filterLoop(query, list); filterLoop(query, list);
active = false; active = false;
} }
@ -260,8 +263,15 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
} }
protected class NamesAdapter extends ArrayAdapter<T> { protected class NamesAdapter extends ArrayAdapter<T> {
NamesAdapter(List<T> list) {
private final Comparator<? super T> cmp;
private final List<T> list;
NamesAdapter(List<T> list, Comparator<? super T> cmp) {
super(SearchByNameAbstractActivity.this, R.layout.searchbyname_list, list); super(SearchByNameAbstractActivity.this, R.layout.searchbyname_list, list);
this.list = list;
this.cmp = cmp;
Collections.sort(list, cmp);
} }
@Override @Override
@ -277,5 +287,16 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
label.setText(getText(getItem(position))); label.setText(getText(getItem(position)));
return row; return row;
} }
@Override
public void add(T object) {
int index = Collections.binarySearch(list, object, cmp);
if (index < 0) {
index = -index-1;
}
super.insert(object, index);
};
} }
} }

View file

@ -1,7 +1,7 @@
package net.osmand.plus.activities.search; package net.osmand.plus.activities.search;
import java.text.Collator; import java.text.Collator;
import java.util.Collections; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
@ -22,8 +22,16 @@ import android.view.View;
import android.widget.TextView; import android.widget.TextView;
public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City> { public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City> {
private RegionAddressRepository region; private RegionAddressRepository region;
@Override
protected Comparator<? super City> createComparator() {
final Collator cs = Collator.getInstance();
final boolean en = region.useEnglishNames();
final StringMatcherMode startsWith = CollatorStringMatcher.StringMatcherMode.CHECK_ONLY_STARTS_WITH;
return new CityComparator(startsWith, cs, en);
}
@Override @Override
public AsyncTask<Object, ?, ?> getInitializeTask() { public AsyncTask<Object, ?, ?> getInitializeTask() {
@ -32,44 +40,6 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City>
protected void onPostExecute(List<City> result) { protected void onPostExecute(List<City> result) {
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_city); ((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_city);
progress.setVisibility(View.INVISIBLE); progress.setVisibility(View.INVISIBLE);
final Collator cs = Collator.getInstance();
final boolean en = region.useEnglishNames();
final String part = getFilter().toString();
final StringMatcherMode startsWith = CollatorStringMatcher.StringMatcherMode.CHECK_ONLY_STARTS_WITH;
Collections.sort(result, new Comparator<City>() {
@Override
public int compare(City lhs, City rhs) {
int compare = compareCityType(lhs, rhs);
if (compare != 0) {
return compare;
}
boolean st1 = CollatorStringMatcher.cmatches(cs, lhs.getName(en), part, startsWith);
boolean st2 = CollatorStringMatcher.cmatches(cs, rhs.getName(en), part, startsWith);
if(st1 != st2) {
return st1 ? 1 : -1;
}
compare = cs.compare(lhs.getName(en), rhs.getName(en));
if (compare != 0) {
return compare;
}
if (locationToSearch != null) {
double d1 = MapUtils.getDistance(locationToSearch, lhs.getLocation());
double d2 = MapUtils.getDistance(locationToSearch, rhs.getLocation());
return -Double.compare(d1, d2);
}
return 0;
}
private int compareCityType(City lhs, City rhs) {
boolean c1 = lhs.getType() == CityType.CITY || lhs.getType() == CityType.TOWN;
boolean c2 = rhs.getType() == CityType.CITY || rhs.getType() == CityType.TOWN;
if(c1 == c2){
return 0;
}
return c1? 1 : -1;
}
});
finishInitializing(result); finishInitializing(result);
} }
@ -106,7 +76,7 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City>
} }
@Override @Override
protected void filterLoop(String query, List<City> list) { protected void filterLoop(String query, Collection<City> list) {
if(!initializeTaskIsFinished() || query.length() <= 2){ if(!initializeTaskIsFinished() || query.length() <= 2){
super.filterLoop(query, list); super.filterLoop(query, list);
} else { } else {
@ -150,4 +120,52 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City>
} }
finish(); finish();
} }
private final class CityComparator implements Comparator<City> {
private final StringMatcherMode startsWith;
private final Collator cs;
private final boolean en;
private CityComparator(StringMatcherMode startsWith, Collator cs,
boolean en) {
this.startsWith = startsWith;
this.cs = cs;
this.en = en;
}
@Override
public int compare(City lhs, City rhs) {
final String part = getFilter().toString();
int compare = compareCityType(lhs, rhs);
if (compare != 0) {
return compare;
}
boolean st1 = CollatorStringMatcher.cmatches(cs, lhs.getName(en), part, startsWith);
boolean st2 = CollatorStringMatcher.cmatches(cs, rhs.getName(en), part, startsWith);
if(st1 != st2) {
return st1 ? 1 : -1;
}
compare = cs.compare(lhs.getName(en), rhs.getName(en));
if (compare != 0) {
return compare;
}
if (locationToSearch != null) {
double d1 = MapUtils.getDistance(locationToSearch, lhs.getLocation());
double d2 = MapUtils.getDistance(locationToSearch, rhs.getLocation());
return -Double.compare(d1, d2);
}
return 0;
}
private int compareCityType(City lhs, City rhs) {
boolean c1 = lhs.getType() == CityType.CITY || lhs.getType() == CityType.TOWN;
boolean c2 = rhs.getType() == CityType.CITY || rhs.getType() == CityType.TOWN;
if(c1 == c2){
return 0;
}
return c1? 1 : -1;
}
}
} }

View file

@ -1,6 +1,8 @@
package net.osmand.plus.activities.search; package net.osmand.plus.activities.search;
import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import net.osmand.access.AccessibleToast; import net.osmand.access.AccessibleToast;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -13,6 +15,18 @@ import android.widget.Toast;
public class SearchRegionByNameActivity extends SearchByNameAbstractActivity<RegionAddressRepository> { public class SearchRegionByNameActivity extends SearchByNameAbstractActivity<RegionAddressRepository> {
@Override
protected Comparator<? super RegionAddressRepository> createComparator() {
return new Comparator<RegionAddressRepository>() {
Collator col = Collator.getInstance();
@Override
public int compare(RegionAddressRepository lhs,
RegionAddressRepository rhs) {
return col.compare(lhs.getName(), rhs.getName());
}
};
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -21,7 +35,7 @@ public class SearchRegionByNameActivity extends SearchByNameAbstractActivity<Reg
AccessibleToast.makeText(this, R.string.none_region_found, Toast.LENGTH_LONG).show(); AccessibleToast.makeText(this, R.string.none_region_found, Toast.LENGTH_LONG).show();
} }
initialListToFilter = new ArrayList<RegionAddressRepository>(((OsmandApplication)getApplication()).getResourceManager().getAddressRepositories()); initialListToFilter = new ArrayList<RegionAddressRepository>(((OsmandApplication)getApplication()).getResourceManager().getAddressRepositories());
NamesAdapter namesAdapter = new NamesAdapter(new ArrayList<RegionAddressRepository>(initialListToFilter)); //$NON-NLS-1$ NamesAdapter namesAdapter = new NamesAdapter(new ArrayList<RegionAddressRepository>(initialListToFilter),createComparator()); //$NON-NLS-1$
setListAdapter(namesAdapter); setListAdapter(namesAdapter);
} }

View file

@ -1,8 +1,10 @@
package net.osmand.plus.activities.search; package net.osmand.plus.activities.search;
import java.util.Comparator;
import java.util.List; import java.util.List;
import net.osmand.data.City; import net.osmand.data.City;
import net.osmand.data.MapObjectComparator;
import net.osmand.data.Street; import net.osmand.data.Street;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -16,6 +18,10 @@ public class SearchStreet2ByNameActivity extends SearchByNameAbstractActivity<St
private City cityOrPostcode; private City cityOrPostcode;
private Street street1; private Street street1;
@Override
protected Comparator<? super Street> createComparator() {
return new MapObjectComparator(getMyApplication().getSettings().usingEnglishNames());
}
@Override @Override
public AsyncTask<Object, ?, ?> getInitializeTask() { public AsyncTask<Object, ?, ?> getInitializeTask() {

View file

@ -2,12 +2,15 @@ package net.osmand.plus.activities.search;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List; import java.util.List;
import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher;
import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.data.City; import net.osmand.data.City;
import net.osmand.data.MapObjectComparator;
import net.osmand.data.Street; import net.osmand.data.Street;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -21,6 +24,10 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
private RegionAddressRepository region; private RegionAddressRepository region;
private City city; private City city;
@Override
protected Comparator<? super Street> createComparator() {
return new MapObjectComparator(getMyApplication().getSettings().usingEnglishNames());
}
@Override @Override
public AsyncTask<Object, ?, ?> getInitializeTask() { public AsyncTask<Object, ?, ?> getInitializeTask() {
@ -67,24 +74,22 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
@Override @Override
protected void filterLoop(String query, List<Street> list) { protected void filterLoop(String query, Collection<Street> list) {
boolean emptyQuery = query == null || query.length() == 0; boolean emptyQuery = query == null || query.length() == 0;
for (int i = 0; i < list.size(); i++) { for (Street obj : list) {
if (namesFilter.isCancelled) { if (namesFilter.isCancelled) {
break; break;
} }
Street obj = list.get(i);
if (emptyQuery || CollatorStringMatcher.cmatches(collator, getText(obj), query, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) { if (emptyQuery || CollatorStringMatcher.cmatches(collator, getText(obj), query, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) {
Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj); Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj);
msg.sendToTarget(); msg.sendToTarget();
} }
} }
if (!emptyQuery) { if (!emptyQuery) {
for (int i = 0; i < list.size(); i++) { for (Street obj : list) {
if (namesFilter.isCancelled) { if (namesFilter.isCancelled) {
break; break;
} }
Street obj = list.get(i);
if (CollatorStringMatcher.cmatches(collator, getText(obj), query, StringMatcherMode.CHECK_STARTS_FROM_SPACE_NOT_BEGINNING)) { if (CollatorStringMatcher.cmatches(collator, getText(obj), query, StringMatcherMode.CHECK_STARTS_FROM_SPACE_NOT_BEGINNING)) {
Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj); Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj);
msg.sendToTarget(); msg.sendToTarget();