Address search: search villages if nothing found (related: #2471)

This commit is contained in:
Roman Inflianskas 2016-06-06 10:52:17 +03:00
parent cdb04bf343
commit 9aa222ea70
7 changed files with 44 additions and 46 deletions

View file

@ -7,10 +7,8 @@ import gnu.trove.set.hash.TIntHashSet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.osmand.CollatorStringMatcher;
import net.osmand.CollatorStringMatcher.StringMatcherMode;

View file

@ -1299,9 +1299,6 @@ public class BinaryMapIndexReader {
}
public List<MapObject> searchAddressDataByName(SearchRequest<MapObject> req, List<Integer> typeFilter) throws IOException {
if (req.nameQuery == null || req.nameQuery.length() == 0) {
throw new IllegalArgumentException();
}
for (AddressRegion reg : addressIndexes) {
if (reg.indexNameOffset != -1) {
codedIS.seek(reg.indexNameOffset);

View file

@ -1,13 +1,8 @@
package net.osmand.data;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import net.osmand.OsmAndCollator;
import net.osmand.util.Algorithms;
public class City extends MapObject {
public enum CityType {

View file

@ -370,17 +370,19 @@ public abstract class SearchByNameAbstractActivity<T> extends OsmandListActivity
namesFilter.cancelPreviousFilter(currentFilter);
}
protected void filterLoop(String query, Collection<T> list) {
protected boolean filterLoop(String query, Collection<T> list) {
boolean result = false;
for (T obj : list) {
if (namesFilter.isCancelled){
break;
}
if (filterObject(obj, query)){
result = true;
Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj);
msg.sendToTarget();
}
}
return result;
}

View file

@ -13,7 +13,6 @@ import net.osmand.CollatorStringMatcher;
import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.OsmAndCollator;
import net.osmand.ResultMatcher;
import net.osmand.StringMatcher;
import net.osmand.data.City;
import net.osmand.data.City.CityType;
import net.osmand.data.LatLon;
@ -124,12 +123,17 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City>
}
@Override
protected void filterLoop(String query, Collection<City> list) {
protected boolean filterLoop(String query, Collection<City> list) {
final boolean[] result = {false};
redefineSearchVillagesMode(query);
if (!initializeTaskIsFinished() || !isVillagesSearchEnabled()) {
super.filterLoop(query, list);
} else {
region.fillWithSuggestedCities(query, new ResultMatcher<City>() {
result[0] = super.filterLoop(query, list);
if (!result[0] && !isVillagesSearchEnabled()) {
setVillagesSearchEnabled(true);
}
}
if (!result[0]) {
ResultMatcher<City> resultMatcher = new ResultMatcher<City>() {
@Override
public boolean isCancelled() {
return namesFilter.isCancelled;
@ -137,14 +141,26 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City>
@Override
public boolean publish(City object) {
result[0] = true;
Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, object);
msg.sendToTarget();
return true;
}
}, isVillagesSearchEnabled(), locationToSearch);
};
region.fillWithSuggestedCities(query, resultMatcher, isVillagesSearchEnabled(), locationToSearch);
}
return result[0];
}
private void setVillagesSearchEnabled(final boolean enable) {
searchVillagesMode = enable ? 0 : -1;
uiHandler.post(new Runnable() {
@Override
public void run() {
searchVillages.setVisibility(enable ? View.GONE : View.VISIBLE);
}
});
}
private boolean isVillagesSearchEnabled() {
return searchVillagesMode >= 0;
@ -154,21 +170,9 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City>
if (searchVillagesMode == 1) {
searchVillagesMode = 0;
} else if (searchVillagesMode == 0 && !initialListToFilter.isEmpty() && query.isEmpty()) {
searchVillagesMode = -1;
uiHandler.post(new Runnable() {
@Override
public void run() {
searchVillages.setVisibility(View.VISIBLE);
}
});
setVillagesSearchEnabled(false);
} else if (searchVillagesMode == -1 && Postcode.looksLikePostcodeStart(query, region.getCountryName())) {
searchVillagesMode = 0;
uiHandler.post(new Runnable() {
@Override
public void run() {
searchVillages.setVisibility(View.GONE);
}
});
setVillagesSearchEnabled(true);
}
}

View file

@ -124,7 +124,8 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
}
@Override
protected void filterLoop(String query, Collection<Street> list) {
protected boolean filterLoop(String query, Collection<Street> list) {
final boolean[] result = {false};
if (searchWithCity == -1) {
filter(query, list);
} else if (searchWithCity == 0) {
@ -133,6 +134,7 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
break;
}
if (filterObject(obj, query)) {
result[0] = true;
Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj);
msg.sendToTarget();
}
@ -145,6 +147,7 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
if (object instanceof Street) {
if (city == null ||
MapUtils.getDistance(city.getLocation(), object.getLocation()) < 100*1000) {
result[0] = true;
Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, object);
msg.sendToTarget();
return true;
@ -166,8 +169,7 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
}
});
}
return result[0];
}

View file

@ -3,7 +3,6 @@ package net.osmand.plus.resources;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
@ -24,12 +23,10 @@ import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.LatLon;
import net.osmand.data.MapObject;
import net.osmand.data.Postcode;
import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree;
import net.osmand.data.Street;
import net.osmand.plus.OsmandSettings.OsmandPreference;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
@ -39,7 +36,6 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
private static final Log log = PlatformUtil.getLog(RegionAddressRepositoryBinary.class);
private BinaryMapIndexReader file;
private LinkedHashMap<Long, City> cities = new LinkedHashMap<Long, City>();
private int POSTCODE_MIN_QUERY_LENGTH = 2;
private int ZOOM_QTREE = 10;
@ -224,19 +220,23 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
return result;
}
@Override
public synchronized List<City> fillWithSuggestedCities(String name, final ResultMatcher<City> resultMatcher, boolean searchVillages, LatLon currentLocation) {
List<City> citiesToFill = new ArrayList<>(cities.values());
private List<Integer> getCityTypeFilter(String name, boolean searchVillages) {
List<Integer> cityTypes = new ArrayList<>();
cityTypes.add(BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE);
if (searchVillages) {
cityTypes.add(BinaryMapAddressReaderAdapter.VILLAGES_TYPE);
if (searchVillages && name.length() >= POSTCODE_MIN_QUERY_LENGTH) {
if (name.length() >= POSTCODE_MIN_QUERY_LENGTH) {
cityTypes.add(BinaryMapAddressReaderAdapter.POSTCODES_TYPE);
}
}
return cityTypes;
}
@Override
public synchronized List<City> fillWithSuggestedCities(String name, final ResultMatcher<City> resultMatcher, boolean searchVillages, LatLon currentLocation) {
List<City> citiesToFill = new ArrayList<>(cities.values());
try {
citiesToFill.addAll(fillWithCities(name, resultMatcher, cityTypes));
citiesToFill.addAll(fillWithCities(name, resultMatcher, getCityTypeFilter(name, searchVillages)));
} catch (IOException e) {
log.error("Disk operation failed", e); //$NON-NLS-1$
}