Show suburbs correctly

This commit is contained in:
Victor Shcherb 2014-07-14 02:02:32 +02:00
parent cd363b160f
commit b105d89881
5 changed files with 99 additions and 8 deletions

View file

@ -45,6 +45,7 @@ public class City extends MapObject {
private Map<String, Street> streets = new TreeMap<String, Street>(OsmAndCollator.primaryCollator()); private Map<String, Street> streets = new TreeMap<String, Street>(OsmAndCollator.primaryCollator());
private String isin = null; private String isin = null;
private String postcode = null; private String postcode = null;
private City closestCity = null;
private static long POSTCODE_INTERNAL_ID = -1000; private static long POSTCODE_INTERNAL_ID = -1000;
public static City createPostcode(String postcode){ public static City createPostcode(String postcode){
@ -92,6 +93,14 @@ public class City extends MapObject {
public void setPostcode(String postcode) { public void setPostcode(String postcode) {
this.postcode = postcode; this.postcode = postcode;
} }
public City getClosestCity() {
return closestCity;
}
public void setClosestCity(City closestCity) {
this.closestCity = closestCity;
}
protected Street registerStreet(Street street, boolean en) { protected Street registerStreet(Street street, boolean en) {
String name = en ? street.getEnName() : street.getName(); String name = en ? street.getEnName() : street.getName();

View file

@ -35,6 +35,23 @@ public class QuadTree<T> {
doInsertData(data, box, root, depth); doInsertData(data, box, root, depth);
} }
public void clear() {
clear(root);
}
private void clear(Node<T> rt) {
if(rt != null ){
if(rt.data != null) {
rt.data.clear();
}
if(rt.children != null) {
for(Node<T> c : rt.children) {
clear(c);
}
}
}
}
public void insert(T data, float x, float y) { public void insert(T data, float x, float y) {
insert(data, new QuadRect(x, y, x, y)); insert(data, new QuadRect(x, y, x, y));
} }

View file

@ -12,6 +12,7 @@
<asset source="voice/el/ttsconfig.p" destination="voice/el-tts/_ttsconfig.p" mode="overwriteOnlyIfExists" /> <asset source="voice/el/ttsconfig.p" destination="voice/el-tts/_ttsconfig.p" mode="overwriteOnlyIfExists" />
<asset source="voice/en/ttsconfig.p" destination="voice/en-tts/_ttsconfig.p" mode="alwaysOverwriteOrCopy" /> <asset source="voice/en/ttsconfig.p" destination="voice/en-tts/_ttsconfig.p" mode="alwaysOverwriteOrCopy" />
<asset source="voice/es/ttsconfig.p" destination="voice/es-tts/_ttsconfig.p" mode="alwaysOverwriteOrCopy" /> <asset source="voice/es/ttsconfig.p" destination="voice/es-tts/_ttsconfig.p" mode="alwaysOverwriteOrCopy" />
<asset source="voice/fa/ttsconfig.p" destination="voice/fa-tts/_ttsconfig.p" mode="overwriteOnlyIfExists" />
<asset source="voice/fi/ttsconfig.p" destination="voice/fi-tts/_ttsconfig.p" mode="overwriteOnlyIfExists" /> <asset source="voice/fi/ttsconfig.p" destination="voice/fi-tts/_ttsconfig.p" mode="overwriteOnlyIfExists" />
<asset source="voice/fr/ttsconfig.p" destination="voice/fr-tts/_ttsconfig.p" mode="alwaysOverwriteOrCopy" /> <asset source="voice/fr/ttsconfig.p" destination="voice/fr-tts/_ttsconfig.p" mode="alwaysOverwriteOrCopy" />
<asset source="voice/hi/ttsconfig.p" destination="voice/hi-tts/_ttsconfig.p" mode="overwriteOnlyIfExists" /> <asset source="voice/hi/ttsconfig.p" destination="voice/hi-tts/_ttsconfig.p" mode="overwriteOnlyIfExists" />
@ -34,21 +35,21 @@
<asset source="voice/en/config.p" destination="voice/en/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/en/config.p" destination="voice/en/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/es/config.p" destination="voice/es/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/es/config.p" destination="voice/es/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/fa/config.p" destination="voice/fa/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/de/config.p" destination="voice/de/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/de/config.p" destination="voice/de/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/it/config.p" destination="voice/it/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/it/config.p" destination="voice/it/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/pt/config.p" destination="voice/pt/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/pt/config.p" destination="voice/pt/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/ru/config.p" destination="voice/ru/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/ru/config.p" destination="voice/ru/_config.p" mode="overwriteOnlyIfExists" />
<!-- TODO delete deprecated --> <!-- TODO delete deprecated
<asset source="voice/fr-ov/config.p" destination="voice/fr/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/fr-ov/config.p" destination="voice/fr/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/he-ov/config.p" destination="voice/he/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/he-ov/config.p" destination="voice/he/_config.p" mode="overwriteOnlyIfExists" />
<!-- Could be deleted later after release -->
<asset source="voice/it-Chiara-ov/config.p" destination="voice/it-Chiara/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/it-Chiara-ov/config.p" destination="voice/it-Chiara/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/it-Roberto-ov/config.p" destination="voice/it-Roberto/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/it-Roberto-ov/config.p" destination="voice/it-Roberto/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/ru2-ov/config.p" destination="voice/ru2/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/ru2-ov/config.p" destination="voice/ru2/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/ru3-ov/config.p" destination="voice/ru3/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/ru3-ov/config.p" destination="voice/ru3/_config.p" mode="overwriteOnlyIfExists" />
<asset source="voice/sk-Ruzena-ov/config.p" destination="voice/sk-Ruzena/_config.p" mode="overwriteOnlyIfExists" /> <asset source="voice/sk-Ruzena-ov/config.p" destination="voice/sk-Ruzena/_config.p" mode="overwriteOnlyIfExists" />
-->
<asset source="sounds/camera_click.ogg" destination="sounds/camera_click.ogg" mode="copyOnlyIfDoesNotExist" /> <asset source="sounds/camera_click.ogg" destination="sounds/camera_click.ogg" mode="copyOnlyIfDoesNotExist" />
</assets> </assets>

View file

@ -146,13 +146,20 @@ public class SearchCityByNameActivity extends SearchByNameAbstractActivity<City>
@Override @Override
public String getText(City obj) { public String getText(City obj) {
LatLon l = obj.getLocation(); LatLon l = obj.getLocation();
if (getFilter().length() > 2 && locationToSearch != null && l != null) { if (getCurrentFilter().length() > 2 ) {
String name = obj.getName(region.useEnglishNames()); String name = obj.getName(region.useEnglishNames());
if (obj.getType() != null) { if (obj.getType() != null) {
name += " [" + OsmAndFormatter.toPublicString(obj.getType(), getMyApplication()) + "]"; name += " [" + OsmAndFormatter.toPublicString(obj.getType(), getMyApplication()) + "]";
} }
return name + " - " + //$NON-NLS-1$ if(obj.getClosestCity() != null) {
OsmAndFormatter.getFormattedDistance((int) MapUtils.getDistance(l, locationToSearch), getMyApplication()); name += " - " + obj.getClosestCity().getName(region.useEnglishNames()) ;
LatLon loc = obj.getClosestCity().getLocation();
if(loc != null && l != null) {
name += " " + OsmAndFormatter.getFormattedDistance((int) MapUtils.getDistance(l, loc), getMyApplication());
}
return name;
}
return name;
} else { } else {
return obj.getName(region.useEnglishNames()); return obj.getName(region.useEnglishNames());
} }

View file

@ -22,7 +22,10 @@ import net.osmand.data.Building;
import net.osmand.data.City; import net.osmand.data.City;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.MapObject; import net.osmand.data.MapObject;
import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree;
import net.osmand.data.Street; import net.osmand.data.Street;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -34,6 +37,9 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
private final LinkedHashMap<Long, City> cities = new LinkedHashMap<Long, City>(); private final LinkedHashMap<Long, City> cities = new LinkedHashMap<Long, City>();
private int ZOOM_QTREE = 10;
private QuadTree<City> citiesQtree = new QuadTree<City>(new QuadRect(0, 0, 1 << (ZOOM_QTREE + 1),
1 << (ZOOM_QTREE + 1)), 8, 0.55f);
private final Map<String, City> postCodes; private final Map<String, City> postCodes;
private boolean useEnglishNames = false; private boolean useEnglishNames = false;
private final Collator collator; private final Collator collator;
@ -59,12 +65,45 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE); BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE);
for (City c : cs) { for (City c : cs) {
cities.put(c.getId(), c); cities.put(c.getId(), c);
LatLon loc = c.getLocation();
if(loc != null) {
int y31 = MapUtils.get31TileNumberY(loc.getLatitude());
int x31 = MapUtils.get31TileNumberX(loc.getLongitude());
int dz = (31 - ZOOM_QTREE);
citiesQtree.insert(c, new QuadRect((x31 >> dz) - 1, (y31 >> dz) - 1, (x31 >> dz) + 1, (y31 >> dz) + 1));
}
} }
} catch (IOException e) { } catch (IOException e) {
log.error("Disk operation failed", e); //$NON-NLS-1$ log.error("Disk operation failed", e); //$NON-NLS-1$
} }
} }
} }
public City getClosestCity(LatLon l, List<City> cache) {
City closest = null;
if (l != null) {
int y31 = MapUtils.get31TileNumberY(l.getLatitude());
int x31 = MapUtils.get31TileNumberX(l.getLongitude());
int dz = (31 - ZOOM_QTREE);
if (cache == null) {
cache = new ArrayList<City>();
}
cache.clear();
citiesQtree.queryInBox(new QuadRect((x31 >> dz) - 1, (y31 >> dz) - 1, (x31 >> dz) + 1, (y31 >> dz) + 1),
cache);
int min = -1;
for (City c : cache) {
double d = MapUtils.getDistance(l, c.getLocation());
if (min == -1 || d < min) {
min = (int) d;
closest = c;
}
}
}
return closest;
}
@Override @Override
public synchronized void preloadBuildings(Street street, ResultMatcher<Building> resultMatcher) { public synchronized void preloadBuildings(Street street, ResultMatcher<Building> resultMatcher) {
@ -119,7 +158,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override @Override
public List<City> fillWithSuggestedCities(String name, ResultMatcher<City> resultMatcher, boolean searchVillages, LatLon currentLocation) { public List<City> fillWithSuggestedCities(String name, final ResultMatcher<City> resultMatcher, boolean searchVillages, LatLon currentLocation) {
List<City> citiesToFill = new ArrayList<City>(); List<City> citiesToFill = new ArrayList<City>();
if (cities.isEmpty()) { if (cities.isEmpty()) {
preloadCities(resultMatcher); preloadCities(resultMatcher);
@ -163,9 +202,26 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
int initialsize = citiesToFill.size(); int initialsize = citiesToFill.size();
if (/*name.length() >= 3 && */searchVillages) { if (/*name.length() >= 3 && */searchVillages) {
List<City> foundCities = file.getCities(region, BinaryMapIndexReader.buildAddressRequest(resultMatcher),
List<City> foundCities = file.getCities(region, BinaryMapIndexReader.buildAddressRequest(new ResultMatcher<City>() {
List<City> cache = new ArrayList<City>();
@Override
public boolean publish(City c) {
if(c.getLocation() != null) {
City ct = getClosestCity(c.getLocation(), cache);
c.setClosestCity(ct);
}
return resultMatcher.publish(c);
}
@Override
public boolean isCancelled() {
return resultMatcher.isCancelled();
}
}),
new CollatorStringMatcher(name,StringMatcherMode.CHECK_STARTS_FROM_SPACE), useEnglishNames, new CollatorStringMatcher(name,StringMatcherMode.CHECK_STARTS_FROM_SPACE), useEnglishNames,
BinaryMapAddressReaderAdapter.VILLAGES_TYPE); BinaryMapAddressReaderAdapter.VILLAGES_TYPE);
for (City c : foundCities) { for (City c : foundCities) {
citiesToFill.add(c); citiesToFill.add(c);
if (resultMatcher.isCancelled()) { if (resultMatcher.isCancelled()) {
@ -281,6 +337,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override @Override
public void clearCache() { public void clearCache() {
cities.clear(); cities.clear();
citiesQtree.clear();
postCodes.clear(); postCodes.clear();
} }