Partial implementation

This commit is contained in:
Victor Shcherb 2011-09-15 01:06:54 +02:00
parent 3e0350a963
commit 890277dd4b
13 changed files with 245 additions and 182 deletions

View file

@ -0,0 +1,15 @@
package net.osmand;
/**
* Easy matcher to be able to publish results immediately
*
*/
public interface ResultMatcher<T> {
/**
* @param name
* @return true if result should be added to final list
*/
boolean publish(T object);
}

View file

@ -3,9 +3,11 @@ package net.osmand.binary;
import java.io.IOException;
import java.util.List;
import net.osmand.ResultMatcher;
import net.osmand.StringMatcher;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.MapObject;
import net.osmand.data.PostCode;
import net.osmand.data.Street;
import net.osmand.data.City.CityType;
@ -83,7 +85,7 @@ public class BinaryMapAddressReaderAdapter {
}
}
protected void readCities(List<City> cities, StringMatcher matcher, boolean useEn) throws IOException {
protected void readCities(List<City> cities, ResultMatcher<MapObject> resultMatcher, StringMatcher matcher, boolean useEn) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -95,10 +97,12 @@ public class BinaryMapAddressReaderAdapter {
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
City c = readCity(null, offset, false, matcher, useEn);
City c = readCity(null, offset, false, null, matcher, useEn);
if(c != null){
if (resultMatcher == null || resultMatcher.publish(c)) {
cities.add(c);
}
}
codedIS.popLimit(oldLimit);
break;
default:
@ -109,7 +113,7 @@ public class BinaryMapAddressReaderAdapter {
}
protected PostCode readPostcode(PostCode p, int fileOffset, boolean loadStreets, String postcodeFilter) throws IOException{
protected PostCode readPostcode(PostCode p, int fileOffset, ResultMatcher<Street> resultMatcher, boolean loadStreets, String postcodeFilter) throws IOException{
int x = 0;
int y = 0;
while(true){
@ -117,8 +121,6 @@ public class BinaryMapAddressReaderAdapter {
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
p.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
p.setFileOffset(fileOffset);
return p;
case OsmandOdb.PostcodeIndex.POSTCODE_FIELD_NUMBER :
String name = codedIS.readString();
@ -128,6 +130,7 @@ public class BinaryMapAddressReaderAdapter {
}
if(p == null){
p = new PostCode(name);
p.setFileOffset(fileOffset);
}
p.setName(name);
break;
@ -136,6 +139,12 @@ public class BinaryMapAddressReaderAdapter {
break;
case OsmandOdb.PostcodeIndex.Y_FIELD_NUMBER :
y = codedIS.readFixed32();
p.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
if(!loadStreets){
// skip everything
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return p;
}
break;
case OsmandOdb.PostcodeIndex.STREETS_FIELD_NUMBER :
int offset = codedIS.getTotalBytesRead();
@ -144,8 +153,10 @@ public class BinaryMapAddressReaderAdapter {
Street s = new Street(null);
int oldLimit = codedIS.pushLimit(length);
s.setFileOffset(offset);
readStreet(s, true, x >> 7, y >> 7, p.getName());
readStreet(s, null, true, x >> 7, y >> 7, p.getName());
if (resultMatcher == null || resultMatcher.publish(s)) {
p.registerStreet(s, false);
}
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
@ -159,7 +170,8 @@ public class BinaryMapAddressReaderAdapter {
}
protected City readCity(City c, int fileOffset, boolean loadStreets, StringMatcher nameMatcher, boolean useEn) throws IOException{
protected City readCity(City c, int fileOffset, boolean loadStreets, ResultMatcher<Street> resultMatcher,
StringMatcher nameMatcher, boolean useEn) throws IOException{
int x = 0;
int y = 0;
int streetInd = 0;
@ -169,10 +181,6 @@ public class BinaryMapAddressReaderAdapter {
boolean englishNameMatched = false;
switch (tag) {
case 0:
c.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
if(c.getEnName().length() == 0){
c.setEnName(Junidecode.unidecode(c.getName()));
}
return c;
case OsmandOdb.CityIndex.CITY_TYPE_FIELD_NUMBER :
int type = codedIS.readUInt32();
@ -221,6 +229,15 @@ public class BinaryMapAddressReaderAdapter {
break;
case OsmandOdb.CityIndex.Y_FIELD_NUMBER :
y = codedIS.readFixed32();
c.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
if(c.getEnName().length() == 0){
c.setEnName(Junidecode.unidecode(c.getName()));
}
if(!loadStreets){
// skip everything
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return c;
}
break;
case OsmandOdb.CityIndex.INTERSECTIONS_FIELD_NUMBER :
codedIS.skipRawBytes(codedIS.readRawVarint32());
@ -233,8 +250,10 @@ public class BinaryMapAddressReaderAdapter {
int oldLimit = codedIS.pushLimit(length);
s.setFileOffset(offset);
s.setIndexInCity(streetInd++);
readStreet(s, false, x >> 7, y >> 7, null);
readStreet(s, null, false, x >> 7, y >> 7, null);
if (resultMatcher == null || resultMatcher.publish(s)) {
c.registerStreet(s);
}
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
@ -247,7 +266,7 @@ public class BinaryMapAddressReaderAdapter {
}
}
protected Street readStreet(Street s, boolean loadBuildings, int city24X, int city24Y, String postcodeFilter) throws IOException{
protected Street readStreet(Street s, ResultMatcher<Building> resultMatcher, boolean loadBuildings, int city24X, int city24Y, String postcodeFilter) throws IOException{
int x = 0;
int y = 0;
boolean loadLocation = city24X != 0 || city24Y != 0;
@ -295,8 +314,10 @@ public class BinaryMapAddressReaderAdapter {
int oldLimit = codedIS.pushLimit(length);
Building b = readBuilding(offset, x, y);
if (postcodeFilter == null || postcodeFilter.equalsIgnoreCase(b.getPostcode())) {
if (resultMatcher == null || resultMatcher.publish(b)) {
s.registerBuilding(b);
}
}
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
@ -453,7 +474,7 @@ public class BinaryMapAddressReaderAdapter {
void readPostcodes(List<PostCode> postcodes, StringMatcher nameMatcher) throws IOException{
protected void readPostcodes(List<PostCode> postcodes, ResultMatcher<MapObject> resultMatcher, StringMatcher nameMatcher) throws IOException{
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -464,11 +485,13 @@ public class BinaryMapAddressReaderAdapter {
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
final PostCode postCode = readPostcode(null, offset, false, null);
//TODO support getEnName??
final PostCode postCode = readPostcode(null, offset, null, false, null);
// support getEnName??
if (nameMatcher == null || nameMatcher.matches(postCode.getName())) {
if (resultMatcher == null || resultMatcher.publish(postCode)) {
postcodes.add(postCode);
}
}
codedIS.popLimit(oldLimit);
break;
default:
@ -478,7 +501,7 @@ public class BinaryMapAddressReaderAdapter {
}
}
PostCode findPostcode(String name) throws IOException{
protected PostCode findPostcode(String name) throws IOException{
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -489,7 +512,7 @@ public class BinaryMapAddressReaderAdapter {
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
PostCode p = readPostcode(null, offset, true, name);
PostCode p = readPostcode(null, offset, null, false, name);
codedIS.popLimit(oldLimit);
if(p != null){
return p;

View file

@ -15,10 +15,13 @@ import java.util.Map;
import net.osmand.Algoritms;
import net.osmand.LogUtil;
import net.osmand.ResultMatcher;
import net.osmand.StringMatcher;
import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion;
import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.MapObject;
import net.osmand.data.PostCode;
import net.osmand.data.Street;
import net.osmand.data.TransportStop;
@ -327,14 +330,14 @@ public class BinaryMapIndexReader {
throw new IllegalArgumentException(name);
}
public List<PostCode> getPostcodes(String region, StringMatcher nameMatcher) throws IOException {
public List<PostCode> getPostcodes(String region, ResultMatcher<MapObject> resultMatcher, StringMatcher nameMatcher) throws IOException {
List<PostCode> postcodes = new ArrayList<PostCode>();
AddressRegion r = getRegionByName(region);
if(r.postcodesOffset != -1){
codedIS.seek(r.postcodesOffset);
int len = readInt();
int old = codedIS.pushLimit(len);
addressAdapter.readPostcodes(postcodes,nameMatcher);
addressAdapter.readPostcodes(postcodes, resultMatcher, nameMatcher);
codedIS.popLimit(old);
}
return postcodes;
@ -355,42 +358,39 @@ public class BinaryMapIndexReader {
return null;
}
public List<City> getCities(String region) throws IOException {
public List<City> getCities(String region, ResultMatcher<MapObject> resultMatcher) throws IOException {
List<City> cities = new ArrayList<City>();
AddressRegion r = getRegionByName(region);
if(r.citiesOffset != -1){
codedIS.seek(r.citiesOffset);
int len = readInt();
int old = codedIS.pushLimit(len);
addressAdapter.readCities(cities, null, false);
addressAdapter.readCities(cities, resultMatcher, null, false);
codedIS.popLimit(old);
}
return cities;
}
public List<City> getVillages(String region) throws IOException {
return getVillages(region, null, false);
}
public List<City> getVillages(String region, StringMatcher nameMatcher, boolean useEn) throws IOException {
public List<City> getVillages(String region, ResultMatcher<MapObject> resultMatcher, StringMatcher nameMatcher, boolean useEn) throws IOException {
List<City> cities = new ArrayList<City>();
AddressRegion r = getRegionByName(region);
if(r.villagesOffset != -1){
codedIS.seek(r.villagesOffset);
int len = readInt();
int old = codedIS.pushLimit(len);
addressAdapter.readCities(cities, nameMatcher, useEn);
addressAdapter.readCities(cities, resultMatcher, nameMatcher, useEn);
codedIS.popLimit(old);
}
return cities;
}
public void preloadStreets(City c) throws IOException {
public void preloadStreets(City c, ResultMatcher<Street> resultMatcher) throws IOException {
checkAddressIndex(c.getFileOffset());
codedIS.seek(c.getFileOffset());
int size = codedIS.readRawVarint32();
int old = codedIS.pushLimit(size);
addressAdapter.readCity(c, c.getFileOffset(), true, null, false);
addressAdapter.readCity(c, c.getFileOffset(), true, resultMatcher, null, false);
codedIS.popLimit(old);
}
@ -406,13 +406,13 @@ public class BinaryMapIndexReader {
}
public void preloadStreets(PostCode p) throws IOException {
public void preloadStreets(PostCode p, ResultMatcher<Street> resultMatcher) throws IOException {
checkAddressIndex(p.getFileOffset());
codedIS.seek(p.getFileOffset());
int size = codedIS.readRawVarint32();
int old = codedIS.pushLimit(size);
addressAdapter.readPostcode(p, p.getFileOffset(), true, null);
addressAdapter.readPostcode(p, p.getFileOffset(), null, true, null);
codedIS.popLimit(old);
}
@ -429,12 +429,12 @@ public class BinaryMapIndexReader {
}
}
public void preloadBuildings(Street s) throws IOException {
public void preloadBuildings(Street s, ResultMatcher<Building> resultMatcher) throws IOException {
checkAddressIndex(s.getFileOffset());
codedIS.seek(s.getFileOffset());
int size = codedIS.readRawVarint32();
int old = codedIS.pushLimit(size);
addressAdapter.readStreet(s, true, 0, 0, null);
addressAdapter.readStreet(s, resultMatcher, true, 0, 0, null);
codedIS.popLimit(old);
}
@ -1138,7 +1138,7 @@ public class BinaryMapIndexReader {
// test address index search
String reg = reader.getRegionNames().get(0);
List<City> cs = reader.getCities(reg);
List<City> cs = reader.getCities(reg, null);
for(City c : cs){
int buildings = 0;
// reader.preloadStreets(c);

View file

@ -4,6 +4,7 @@ import java.text.Collator;
import java.util.Comparator;
import java.util.List;
import net.osmand.ResultMatcher;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.MapObject;
@ -60,13 +61,13 @@ public interface RegionAddressRepository {
public void setUseEnglishNames(boolean useEnglishNames);
public void fillWithSuggestedBuildings(PostCode postcode, Street street, String name, List<Building> buildingsToFill);
public List<Building> fillWithSuggestedBuildings(PostCode postcode, Street street, String name, ResultMatcher<Building> resultMatcher) ;
public void fillWithSuggestedStreetsIntersectStreets(City city, Street st, List<Street> streetsToFill);
public void fillWithSuggestedStreets(MapObject cityOrPostcode, List<Street> streetsToFill, String... name);
public List<Street> fillWithSuggestedStreets(MapObject o, ResultMatcher<Street> resultMatcher, String... names);
public void fillWithSuggestedCities(String name, List<MapObject> citiesToFill, LatLon currentLocation);
public List<MapObject> fillWithSuggestedCities(String name, ResultMatcher<MapObject> resultMatcher, LatLon currentLocation);
public LatLon findStreetIntersection(Street street, Street street2);
@ -80,8 +81,6 @@ public interface RegionAddressRepository {
public LatLon getEstimatedRegionCenter();
public boolean isMapRepository();
// is called on low memory
public void clearCache();

View file

@ -5,7 +5,9 @@ import static net.osmand.plus.CollatorStringMatcher.cstartsWith;
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;
@ -13,6 +15,7 @@ import java.util.TreeMap;
import net.osmand.Algoritms;
import net.osmand.LogUtil;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.Building;
import net.osmand.data.City;
@ -47,18 +50,16 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
this.file = null;
}
@Override
public boolean isMapRepository() {
return true;
}
@Override
public void fillWithSuggestedBuildings(PostCode postcode, Street street, String name, List<Building> buildingsToFill) {
preloadBuildings(street);
if(name.length() == 0){
public List<Building> fillWithSuggestedBuildings(PostCode postcode, Street street, String name, ResultMatcher<Building> resultMatcher) {
List<Building> buildingsToFill = new ArrayList<Building>();
if (name.length() == 0) {
preloadBuildings(street, resultMatcher);
buildingsToFill.addAll(street.getBuildings());
return;
return buildingsToFill;
}
preloadBuildings(street, null);
name = name.toLowerCase();
int ind = 0;
for (Building building : street.getBuildings()) {
@ -70,13 +71,14 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
buildingsToFill.add(building);
}
}
return buildingsToFill;
}
private void preloadBuildings(Street street) {
private void preloadBuildings(Street street, ResultMatcher<Building> resultMatcher) {
if(street.getBuildings().isEmpty()){
try {
file.preloadBuildings(street);
file.preloadBuildings(street, resultMatcher);
street.sortBuildings();
} catch (IOException e) {
log.error("Disk operation failed" , e); //$NON-NLS-1$
@ -86,33 +88,36 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override
public void fillWithSuggestedStreets(MapObject o, List<Street> streetsToFill, String... names) {
public List<Street> fillWithSuggestedStreets(MapObject o, ResultMatcher<Street> resultMatcher, String... names) {
assert o instanceof PostCode || o instanceof City;
City city = (City) (o instanceof City ? o : null);
PostCode post = (PostCode) (o instanceof PostCode ? o : null);
preloadStreets(o);
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets() ;
List<Street> streetsToFill = new ArrayList<Street>();
if(names.length == 0){
streetsToFill.addAll(streets);
return;
preloadStreets(o, resultMatcher);
streetsToFill.addAll(post == null ? city.getStreets() : post.getStreets());
return streetsToFill;
}
preloadStreets(o, null);
int ind = 0;
for (Street s : streets) {
String sName = useEnglishNames ? s.getEnName() : s.getName(); //lower case not needed, collator ensures that
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)) {
if (cstartsWith(collator, sName, name)) {
streetsToFill.add(ind, s);
ind++;
} else if (ccontains(collator,name,sName) || ccontains(collator,sName,name)) {
} else if (ccontains(collator, name, sName) || ccontains(collator, sName, name)) {
streetsToFill.add(s);
}
}
}
return streetsToFill;
}
private void preloadStreets(MapObject o) {
private void preloadStreets(MapObject o, ResultMatcher<Street> resultMatcher) {
assert o instanceof PostCode || o instanceof City;
Collection<Street> streets = o instanceof PostCode ? ((PostCode) o).getStreets() : ((City) o).getStreets();
if(!streets.isEmpty()){
@ -120,9 +125,9 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
}
try {
if(o instanceof PostCode){
file.preloadStreets((PostCode) o);
file.preloadStreets((PostCode) o, resultMatcher);
} else {
file.preloadStreets((City) o);
file.preloadStreets((City) o, resultMatcher);
}
} catch (IOException e) {
log.error("Disk operation failed" , e); //$NON-NLS-1$
@ -132,18 +137,25 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override
public void fillWithSuggestedCities(String name, List<MapObject> citiesToFill, LatLon currentLocation) {
preloadCities();
public List<MapObject> fillWithSuggestedCities(String name, ResultMatcher<MapObject> resultMatcher, LatLon currentLocation) {
List<MapObject> citiesToFill = new ArrayList<MapObject>();
if (cities.isEmpty()) {
preloadCities(resultMatcher);
citiesToFill.addAll(cities.values());
return citiesToFill;
} else {
preloadCities(null);
}
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,new ContainsStringMatcher(uName,collator))) {
if (cstartsWith(collator,code.getName(),uName)) {
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)){
} else if (ccontains(collator, code.getName(), uName)) {
citiesToFill.add(code);
}
}
@ -156,26 +168,32 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
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 (cstartsWith(collator, cName, name)) {
if (resultMatcher.publish(c)) {
citiesToFill.add(c);
}
}
}
}
} else {
name = name.toLowerCase();
Collection<City> src = cities.values();
for (City c : src) {
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, new ContainsStringMatcher(name,collator), useEnglishNames )){
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);
@ -189,13 +207,14 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
} catch (IOException e) {
log.error("Disk operation failed" , e); //$NON-NLS-1$
}
return citiesToFill;
}
@Override
public void fillWithSuggestedStreetsIntersectStreets(City city, Street st, List<Street> streetsToFill) {
if(city != null){
preloadStreets(city);
preloadStreets(city, null);
try {
file.findIntersectedStreets(city, st, streetsToFill);
} catch (IOException e) {
@ -208,7 +227,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
public LatLon findStreetIntersection(Street street, Street street2) {
City city = street.getCity();
if(city != null){
preloadStreets(city);
preloadStreets(city, null);
try {
return file.findStreetIntersection(city, street, street2);
} catch (IOException e) {
@ -221,7 +240,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override
public Building getBuildingByName(Street street, String name) {
preloadBuildings(street);
preloadBuildings(street, null);
for (Building b : street.getBuildings()) {
String bName = useEnglishNames ? b.getEnName() : b.getName();
if (bName.equals(name)) {
@ -249,15 +268,15 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
// do not preload cities for that case
return null;
}
preloadCities();
preloadCities(null);
return cities.get(id);
}
private void preloadCities() {
private void preloadCities(ResultMatcher<MapObject> resultMatcher) {
if (cities.isEmpty()) {
try {
List<City> cs = file.getCities(region);
List<City> cs = file.getCities(region, resultMatcher);
for (City c : cs) {
cities.put(c.getId(), c);
}
@ -290,7 +309,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
City city = (City) (o instanceof City ? o : null);
PostCode post = (PostCode) (o instanceof PostCode ? o : null);
name = name.toLowerCase();
preloadStreets(o);
preloadStreets(o, null);
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets();
for (Street s : streets) {
String sName = useEnglishNames ? s.getEnName() : s.getName(); //lower case not needed, collator ensures that

View file

@ -232,7 +232,7 @@ public class GeoIntentActivity extends ListActivity {
for (RegionAddressRepository rar : countriesToSearch) {
List<MapObject> citiesFound = new ArrayList<MapObject>();
for (String maybeCity : elements) {
rar.fillWithSuggestedCities(maybeCity, citiesFound, null);
citiesFound.addAll(rar.fillWithSuggestedCities(maybeCity, null, null));
}
if (!citiesFound.isEmpty()) {
citiesForRegion.put(rar, citiesFound);
@ -242,8 +242,7 @@ public class GeoIntentActivity extends ListActivity {
Map<MapObject, List<Street>> streetsForCity = new HashMap<MapObject, List<Street>>();
if (citiesForRegion.isEmpty()) {
for (RegionAddressRepository rar : countriesToSearch) {
ArrayList<MapObject> allcities = new ArrayList<MapObject>();
rar.fillWithSuggestedCities("", allcities, location);
List<MapObject> allcities = rar.fillWithSuggestedCities("", null, location);
findStreetsForCities(streetsForCity, rar, allcities);
}
} else {
@ -273,8 +272,7 @@ public class GeoIntentActivity extends ListActivity {
Map<MapObject, List<Street>> streetsForCity,
RegionAddressRepository rar, List<MapObject> allcities) {
for (MapObject city : allcities) {
List<Street> streets = new ArrayList<Street>();
rar.fillWithSuggestedStreets(city, streets,
List<Street> streets = rar.fillWithSuggestedStreets(city, null,
elements.toArray(new String[] {}));
// we must do this, or we will fill up the whole memory (streets
// are preloaded...)

View file

@ -7,7 +7,9 @@ import net.osmand.Algoritms;
import net.osmand.osm.LatLon;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.RegionAddressRepository;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.OsmandApplication;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
@ -319,6 +321,10 @@ public class SearchAddressActivity extends Activity {
street = null;
building = null;
region = osmandSettings.getLastSearchedRegion();
RegionAddressRepository reg = ((OsmandApplication)getApplication()).getResourceManager().getRegionRepository(region);
if(reg.useEnglishNames() != osmandSettings.USE_ENGLISH_NAMES.get()){
reg.setUseEnglishNames(osmandSettings.USE_ENGLISH_NAMES.get());
}
loadData();
updateUI();

View file

@ -3,11 +3,11 @@ package net.osmand.plus.activities.search;
import java.util.ArrayList;
import java.util.List;
import net.osmand.ResultMatcher;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.PostCode;
import net.osmand.data.Street;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.RegionAddressRepository;
import net.osmand.plus.activities.OsmandApplication;
@ -38,7 +38,6 @@ 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());
@ -55,12 +54,17 @@ public class SearchBuildingByNameActivity extends SearchByNameAbstractActivity<B
}
@Override
public List<Building> getObjects(String filter) {
List<Building> l = new ArrayList<Building>();
public List<Building> getObjects(String filter, final SearchByNameTask task) {
if(street != null){
region.fillWithSuggestedBuildings(postcode, street, filter, l);
return region.fillWithSuggestedBuildings(postcode, street, filter, new ResultMatcher<Building>() {
@Override
public boolean publish(Building object) {
task.progress(object);
return true;
}
return l;
});
}
return new ArrayList<Building>();
}
@Override

View file

@ -1,5 +1,6 @@
package net.osmand.plus.activities.search;
import java.util.ArrayList;
import java.util.List;
import net.osmand.osm.LatLon;
@ -9,9 +10,6 @@ import android.app.ListActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.AsyncTask.Status;
import android.text.Editable;
import android.text.TextWatcher;
@ -30,8 +28,8 @@ import android.widget.TextView;
public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
private EditText searchText;
private Handler handlerToLoop;
private AsyncTask<Object, ?, ?> initializeTask;
protected SearchByNameTask searchTask = new SearchByNameTask();
protected ProgressBar progress;
protected LatLon locationToSearch;
@ -45,7 +43,7 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.search_by_name);
NamesAdapter namesAdapter = new NamesAdapter(getObjects("")); //$NON-NLS-1$
NamesAdapter namesAdapter = new NamesAdapter(new ArrayList<T>()); //$NON-NLS-1$
setListAdapter(namesAdapter);
progress = (ProgressBar) findViewById(R.id.ProgressBar);
searchText = (EditText) findViewById(R.id.SearchText);
@ -101,19 +99,6 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
setText("");
}
protected void updateUIList(final List<T> objects){
runOnUiThread(new Runnable(){
@Override
public void run() {
((NamesAdapter)getListAdapter()).setNotifyOnChange(false);
for(T o : objects){
((NamesAdapter)getListAdapter()).add(o);
}
((NamesAdapter)getListAdapter()).notifyDataSetChanged();
progress.setVisibility(View.INVISIBLE);
}
});
}
public void setText(final String filter) {
if(isFilterableByDefault()){
@ -121,38 +106,19 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
return;
}
((NamesAdapter) getListAdapter()).clear();
if(handlerToLoop == null){
return;
Status status = searchTask.getStatus();
if(status == Status.FINISHED){
searchTask = new SearchByNameTask();
} else if(status == Status.RUNNING){
searchTask.cancel(true);
// TODO improve
searchTask = new SearchByNameTask();
}
handlerToLoop.removeMessages(1);
Message msg = Message.obtain(handlerToLoop, new Runnable() {
@Override
public void run() {
showProgress(View.VISIBLE);
List<T> loadedObjects = getObjects(filter);
if(handlerToLoop != null && !handlerToLoop.hasMessages(1)){
updateUIList(loadedObjects);
}
}
});
msg.what = 1;
handlerToLoop.sendMessageDelayed(msg, 150);
searchTask.execute(filter);
}
private void showProgress(final int v){
runOnUiThread(new Runnable(){
@Override
public void run() {
progress.setVisibility(v);
}
});
}
public abstract List<T> getObjects(String filter);
public abstract List<T> getObjects(String filter, SearchByNameTask searchTask);
public abstract void updateTextView(T obj, TextView txt);
@ -168,19 +134,6 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
@Override
protected void onResume() {
super.onResume();
synchronized (this) {
if (handlerToLoop == null) {
new Thread("Filter data") { //$NON-NLS-1$
@Override
public void run() {
Looper.prepare();
handlerToLoop = new Handler();
Looper.loop();
}
}.start();
}
}
Intent intent = getIntent();
if(intent != null){
if(intent.hasExtra(SearchActivity.SEARCH_LAT) && intent.hasExtra(SearchActivity.SEARCH_LON)){
@ -198,19 +151,53 @@ public abstract class SearchByNameAbstractActivity<T> extends ListActivity {
@Override
protected void onPause() {
super.onPause();
synchronized (this) {
if(handlerToLoop != null){
handlerToLoop.post(new Runnable(){
searchTask.cancel(true);
}
protected class SearchByNameTask extends AsyncTask<String, T, List<T>> {
@Override
public void run() {
Looper.myLooper().quit();
protected List<T> doInBackground(String... params) {
if(params == null || params.length == 0){
return null;
}
});
handlerToLoop = null;
String filter = params[0];
return getObjects(filter, this);
}
public void progress(T... values){
publishProgress(values);
}
protected void onProgressUpdate(T... values) {
for(T t :values){
((NamesAdapter) getListAdapter()).add(t);
}
};
@Override
protected void onPreExecute() {
super.onPreExecute();
progress.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(List<T> result) {
if (!isCancelled() && result != null) {
((NamesAdapter) getListAdapter()).setNotifyOnChange(false);
((NamesAdapter) getListAdapter()).clear();
for (T o : result) {
((NamesAdapter) getListAdapter()).add(o);
}
((NamesAdapter) getListAdapter()).notifyDataSetChanged();
}
if (!isCancelled()) {
progress.setVisibility(View.INVISIBLE);
}
}
}
class NamesAdapter extends ArrayAdapter<T> {
NamesAdapter(List<T> list) {

View file

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import net.osmand.OsmAndFormatter;
import net.osmand.ResultMatcher;
import net.osmand.data.City;
import net.osmand.data.MapObject;
import net.osmand.data.PostCode;
@ -13,6 +14,7 @@ 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;
@ -46,12 +48,18 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<MapOb
}
@Override
public List<MapObject> getObjects(String filter) {
List<MapObject> l = new ArrayList<MapObject>();
public List<MapObject> getObjects(String filter, final SearchByNameTask task) {
if(region != null){
region.fillWithSuggestedCities(filter, l, locationToSearch);
region.fillWithSuggestedCities(filter, new ResultMatcher<MapObject>() {
@Override
public boolean publish(MapObject object) {
task.progress(object);
return true;
}
return l;
}, locationToSearch);
}
return new ArrayList<MapObject>();
}
@Override

View file

@ -24,7 +24,7 @@ public class SearchRegionByNameActivity extends SearchByNameAbstractActivity<Reg
}
@Override
public List<RegionAddressRepository> getObjects(String filter) {
public List<RegionAddressRepository> getObjects(String filter, SearchByNameTask task) {
return new ArrayList<RegionAddressRepository>(((OsmandApplication)getApplication()).getResourceManager().getAddressRepositories());
}

View file

@ -6,12 +6,11 @@ import java.util.List;
import net.osmand.data.City;
import net.osmand.data.PostCode;
import net.osmand.data.Street;
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;
@ -29,7 +28,6 @@ public class SearchStreet2ByNameActivity extends SearchByNameAbstractActivity<St
@Override
protected void onPostExecute(Void result) {
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_street);
((TextView)findViewById(R.id.Label)).setText(R.string.incremental_search_building);
progress.setVisibility(View.INVISIBLE);
resetText();
}
@ -66,7 +64,7 @@ public class SearchStreet2ByNameActivity extends SearchByNameAbstractActivity<St
@Override
public List<Street> getObjects(String filter) {
public List<Street> getObjects(String filter, SearchByNameTask task) {
int ind = 0;
filter = filter.toLowerCase();
List<Street> filterList = new ArrayList<Street>();

View file

@ -3,6 +3,7 @@ package net.osmand.plus.activities.search;
import java.util.ArrayList;
import java.util.List;
import net.osmand.ResultMatcher;
import net.osmand.data.City;
import net.osmand.data.PostCode;
import net.osmand.data.Street;
@ -49,12 +50,17 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity<Str
}
@Override
public List<Street> getObjects(String filter) {
List<Street> l = new ArrayList<Street>();
public List<Street> getObjects(String filter, final SearchByNameTask task) {
if (city != null || postcode != null) {
region.fillWithSuggestedStreets(postcode == null ? city : postcode, l, filter);
return region.fillWithSuggestedStreets(postcode == null ? city : postcode, new ResultMatcher<Street>() {
@Override
public boolean publish(Street object) {
task.progress(object);
return true;
}
return l;
}, filter);
}
return new ArrayList<Street>();
}
@Override