fix performance for hamlets in address inde
git-svn-id: https://osmand.googlecode.com/svn/trunk@627 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
2c30496c45
commit
0cbabe4bd2
4 changed files with 96 additions and 38 deletions
|
@ -17,6 +17,7 @@ import net.osmand.data.PostCode;
|
||||||
import net.osmand.data.Street;
|
import net.osmand.data.Street;
|
||||||
import net.osmand.data.City.CityType;
|
import net.osmand.data.City.CityType;
|
||||||
import net.osmand.osm.MapUtils;
|
import net.osmand.osm.MapUtils;
|
||||||
|
import net.sf.junidecode.Junidecode;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
@ -106,6 +107,9 @@ public class BinaryMapIndexReader {
|
||||||
return;
|
return;
|
||||||
case OsmandOdb.OsmAndAddressIndex.NAME_FIELD_NUMBER :
|
case OsmandOdb.OsmAndAddressIndex.NAME_FIELD_NUMBER :
|
||||||
region.name = codedIS.readString();
|
region.name = codedIS.readString();
|
||||||
|
if(region.enName == null){
|
||||||
|
region.enName = Junidecode.unidecode(region.name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OsmandOdb.OsmAndAddressIndex.NAME_EN_FIELD_NUMBER :
|
case OsmandOdb.OsmAndAddressIndex.NAME_EN_FIELD_NUMBER :
|
||||||
region.enName = codedIS.readString();
|
region.enName = codedIS.readString();
|
||||||
|
@ -312,20 +316,23 @@ public class BinaryMapIndexReader {
|
||||||
codedIS.seek(r.citiesOffset);
|
codedIS.seek(r.citiesOffset);
|
||||||
int len = readInt();
|
int len = readInt();
|
||||||
int old = codedIS.pushLimit(len);
|
int old = codedIS.pushLimit(len);
|
||||||
readCities(cities);
|
readCities(cities, null, false);
|
||||||
codedIS.popLimit(old);
|
codedIS.popLimit(old);
|
||||||
}
|
}
|
||||||
return cities;
|
return cities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<City> getVillages(String region) throws IOException {
|
public List<City> getVillages(String region) throws IOException {
|
||||||
|
return getVillages(region, null, false);
|
||||||
|
}
|
||||||
|
public List<City> getVillages(String region, String nameContains, boolean useEn) throws IOException {
|
||||||
List<City> cities = new ArrayList<City>();
|
List<City> cities = new ArrayList<City>();
|
||||||
AddressRegion r = getRegionByName(region);
|
AddressRegion r = getRegionByName(region);
|
||||||
if(r.villagesOffset != -1){
|
if(r.villagesOffset != -1){
|
||||||
codedIS.seek(r.villagesOffset);
|
codedIS.seek(r.villagesOffset);
|
||||||
int len = readInt();
|
int len = readInt();
|
||||||
int old = codedIS.pushLimit(len);
|
int old = codedIS.pushLimit(len);
|
||||||
readCities(cities);
|
readCities(cities, nameContains, useEn);
|
||||||
codedIS.popLimit(old);
|
codedIS.popLimit(old);
|
||||||
}
|
}
|
||||||
return cities;
|
return cities;
|
||||||
|
@ -376,7 +383,7 @@ public class BinaryMapIndexReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readCities(List<City> cities) throws IOException{
|
private void readCities(List<City> cities, String nameContains, boolean useEn) throws IOException {
|
||||||
while(true){
|
while(true){
|
||||||
int t = codedIS.readTag();
|
int t = codedIS.readTag();
|
||||||
int tag = WireFormat.getTagFieldNumber(t);
|
int tag = WireFormat.getTagFieldNumber(t);
|
||||||
|
@ -388,7 +395,41 @@ public class BinaryMapIndexReader {
|
||||||
int length = codedIS.readRawVarint32();
|
int length = codedIS.readRawVarint32();
|
||||||
|
|
||||||
int oldLimit = codedIS.pushLimit(length);
|
int oldLimit = codedIS.pushLimit(length);
|
||||||
cities.add(readCity(null, offset, false));
|
if(nameContains != null){
|
||||||
|
String name = null;
|
||||||
|
int read = 0;
|
||||||
|
int toRead = useEn ? 3 : 2;
|
||||||
|
int seek = codedIS.getTotalBytesRead();
|
||||||
|
while(read++ < toRead){
|
||||||
|
int ts = codedIS.readTag();
|
||||||
|
int tags = WireFormat.getTagFieldNumber(ts);
|
||||||
|
switch (tags) {
|
||||||
|
case OsmandOdb.CityIndex.NAME_EN_FIELD_NUMBER :
|
||||||
|
name = codedIS.readString();
|
||||||
|
break;
|
||||||
|
case OsmandOdb.CityIndex.NAME_FIELD_NUMBER :
|
||||||
|
name = codedIS.readString();
|
||||||
|
if(useEn){
|
||||||
|
name = Junidecode.unidecode(name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OsmandOdb.CityIndex.CITY_TYPE_FIELD_NUMBER :
|
||||||
|
codedIS.readUInt32();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(name == null || !name.toLowerCase().contains(nameContains)){
|
||||||
|
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||||
|
codedIS.popLimit(oldLimit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
codedIS.seek(seek);
|
||||||
|
}
|
||||||
|
|
||||||
|
City c = readCity(null, offset, false);
|
||||||
|
if(c != null){
|
||||||
|
cities.add(c);
|
||||||
|
}
|
||||||
codedIS.popLimit(oldLimit);
|
codedIS.popLimit(oldLimit);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -453,7 +494,7 @@ public class BinaryMapIndexReader {
|
||||||
return p;
|
return p;
|
||||||
case OsmandOdb.PostcodeIndex.POSTCODE_FIELD_NUMBER :
|
case OsmandOdb.PostcodeIndex.POSTCODE_FIELD_NUMBER :
|
||||||
String name = codedIS.readString();
|
String name = codedIS.readString();
|
||||||
if(postcodeFilter != null && postcodeFilter.equalsIgnoreCase(name)){
|
if(postcodeFilter != null && !postcodeFilter.equalsIgnoreCase(name)){
|
||||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -515,6 +556,9 @@ public class BinaryMapIndexReader {
|
||||||
break;
|
break;
|
||||||
case OsmandOdb.CityIndex.NAME_FIELD_NUMBER :
|
case OsmandOdb.CityIndex.NAME_FIELD_NUMBER :
|
||||||
c.setName(codedIS.readString());
|
c.setName(codedIS.readString());
|
||||||
|
if(c.getEnName() == null){
|
||||||
|
c.setEnName(Junidecode.unidecode(c.getName()));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OsmandOdb.CityIndex.X_FIELD_NUMBER :
|
case OsmandOdb.CityIndex.X_FIELD_NUMBER :
|
||||||
x = codedIS.readFixed32();
|
x = codedIS.readFixed32();
|
||||||
|
@ -564,6 +608,9 @@ public class BinaryMapIndexReader {
|
||||||
break;
|
break;
|
||||||
case OsmandOdb.StreetIndex.NAME_FIELD_NUMBER :
|
case OsmandOdb.StreetIndex.NAME_FIELD_NUMBER :
|
||||||
s.setName(codedIS.readString());
|
s.setName(codedIS.readString());
|
||||||
|
if(s.getEnName() == null){
|
||||||
|
s.setEnName(Junidecode.unidecode(s.getName()));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OsmandOdb.StreetIndex.X_FIELD_NUMBER :
|
case OsmandOdb.StreetIndex.X_FIELD_NUMBER :
|
||||||
int sx = codedIS.readSInt32();
|
int sx = codedIS.readSInt32();
|
||||||
|
@ -622,6 +669,9 @@ public class BinaryMapIndexReader {
|
||||||
break;
|
break;
|
||||||
case OsmandOdb.BuildingIndex.NAME_FIELD_NUMBER :
|
case OsmandOdb.BuildingIndex.NAME_FIELD_NUMBER :
|
||||||
b.setName(codedIS.readString());
|
b.setName(codedIS.readString());
|
||||||
|
if(b.getEnName() == null){
|
||||||
|
b.setEnName(Junidecode.unidecode(b.getName()));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OsmandOdb.BuildingIndex.X_FIELD_NUMBER :
|
case OsmandOdb.BuildingIndex.X_FIELD_NUMBER :
|
||||||
x = codedIS.readSInt32() + street24X;
|
x = codedIS.readSInt32() + street24X;
|
||||||
|
@ -1008,8 +1058,8 @@ public class BinaryMapIndexReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.map.pbf"), "r");
|
// RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.map.pbf"), "r");
|
||||||
// RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Belarus.map.pbf"), "r");
|
RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Belarus.map.pbf"), "r");
|
||||||
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
|
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
|
||||||
System.out.println("VERSION " + reader.getVersion());
|
System.out.println("VERSION " + reader.getVersion());
|
||||||
|
|
||||||
|
@ -1030,22 +1080,25 @@ public class BinaryMapIndexReader {
|
||||||
String reg = reader.getRegionNames().get(0);
|
String reg = reader.getRegionNames().get(0);
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
List<City> cs = reader.getCities(reg);
|
List<City> cs = reader.getCities(reg);
|
||||||
for(City c : cs){
|
// for(City c : cs){
|
||||||
reader.preloadStreets(c);
|
// reader.preloadStreets(c);
|
||||||
int buildings = 0;
|
// int buildings = 0;
|
||||||
for(Street s : c.getStreets()){
|
// for(Street s : c.getStreets()){
|
||||||
reader.preloadBuildings(s);
|
// reader.preloadBuildings(s);
|
||||||
buildings += s.getBuildings().size();
|
// buildings += s.getBuildings().size();
|
||||||
}
|
// }
|
||||||
System.out.println(c.getName() + " " + c.getLocation() + " " + c.getStreets().size() + " " + buildings);
|
// System.out.println(c.getName() + " " + c.getLocation() + " " + c.getStreets().size() + " " + buildings);
|
||||||
}
|
// }
|
||||||
List<City> villages = reader.getVillages(reg);
|
// List<PostCode> postcodes = reader.getPostcodes(reg);
|
||||||
List<PostCode> postcodes = reader.getPostcodes(reg);
|
// for(PostCode c : postcodes){
|
||||||
for(PostCode c : postcodes){
|
// reader.preloadStreets(c);
|
||||||
reader.preloadStreets(c);
|
//// System.out.println(c.getName());
|
||||||
// System.out.println(c.getName());
|
// }
|
||||||
}
|
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
|
||||||
|
List<City> villages = reader.getVillages(reg, "кост", false);
|
||||||
|
|
||||||
System.out.println("Villages " + villages.size());
|
System.out.println("Villages " + villages.size());
|
||||||
|
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
|
||||||
System.out.println("Time " + (System.currentTimeMillis() - time));
|
System.out.println("Time " + (System.currentTimeMillis() - time));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,9 @@ public class City extends MapObject {
|
||||||
} else {
|
} else {
|
||||||
// try to merge streets
|
// try to merge streets
|
||||||
Street prev = streets.get(name);
|
Street prev = streets.get(name);
|
||||||
|
if(!street.getWayNodes().isEmpty()){
|
||||||
prev.getWayNodes().addAll(street.getWayNodes());
|
prev.getWayNodes().addAll(street.getWayNodes());
|
||||||
|
}
|
||||||
prev.getBuildings().addAll(street.getBuildings());
|
prev.getBuildings().addAll(street.getBuildings());
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,9 @@ public class Street extends MapObject {
|
||||||
|
|
||||||
|
|
||||||
public List<Way> getWayNodes() {
|
public List<Way> getWayNodes() {
|
||||||
|
if(wayNodes == null){
|
||||||
|
wayNodes = new ArrayList<Way>();
|
||||||
|
}
|
||||||
return wayNodes;
|
return wayNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package net.osmand;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -32,9 +31,6 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
||||||
private Map<String, PostCode> postCodes = new TreeMap<String, PostCode>(Collator.getInstance());
|
private Map<String, PostCode> postCodes = new TreeMap<String, PostCode>(Collator.getInstance());
|
||||||
private boolean useEnglishNames = false;
|
private boolean useEnglishNames = false;
|
||||||
|
|
||||||
private Comparator<MapObject> comparator = new MapObjectComparator(useEnglishNames);
|
|
||||||
|
|
||||||
|
|
||||||
public RegionAddressRepositoryBinary(BinaryMapIndexReader file, String name) {
|
public RegionAddressRepositoryBinary(BinaryMapIndexReader file, String name) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.region = name;
|
this.region = name;
|
||||||
|
@ -68,13 +64,13 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
||||||
buildingsToFill.add(building);
|
buildingsToFill.add(building);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(buildingsToFill, comparator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void preloadBuildings(Street street) {
|
private void preloadBuildings(Street street) {
|
||||||
if(street.getBuildings().isEmpty()){
|
if(street.getBuildings().isEmpty()){
|
||||||
try {
|
try {
|
||||||
file.preloadBuildings(street);
|
file.preloadBuildings(street);
|
||||||
|
street.sortBuildings();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Disk operation failed" , e); //$NON-NLS-1$
|
log.error("Disk operation failed" , e); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
@ -87,10 +83,13 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
||||||
assert o instanceof PostCode || o instanceof City;
|
assert o instanceof PostCode || o instanceof City;
|
||||||
City city = (City) (o instanceof City ? o : null);
|
City city = (City) (o instanceof City ? o : null);
|
||||||
PostCode post = (PostCode) (o instanceof PostCode ? o : null);
|
PostCode post = (PostCode) (o instanceof PostCode ? o : null);
|
||||||
preloadStreets(o);
|
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
|
|
||||||
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets() ;
|
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets() ;
|
||||||
|
if(streets.isEmpty()){
|
||||||
|
preloadStreets(o);
|
||||||
|
streets = post == null ? city.getStreets() : post.getStreets();
|
||||||
|
}
|
||||||
|
|
||||||
if(name.length() == 0){
|
if(name.length() == 0){
|
||||||
streetsToFill.addAll(streets);
|
streetsToFill.addAll(streets);
|
||||||
|
@ -107,7 +106,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(streetsToFill, comparator);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -175,13 +174,12 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
||||||
}
|
}
|
||||||
int initialsize = citiesToFill.size();
|
int initialsize = citiesToFill.size();
|
||||||
|
|
||||||
for(City c : file.getVillages(name)){
|
for(City c : file.getVillages(region, name, useEnglishNames )){
|
||||||
String cName = useEnglishNames ? c.getEnName() : c.getName();
|
String cName = c.getName(useEnglishNames).toLowerCase();
|
||||||
String lowerCase = cName.toLowerCase();
|
if (cName.startsWith(name)) {
|
||||||
if (lowerCase.startsWith(name)) {
|
|
||||||
citiesToFill.add(ind, c);
|
citiesToFill.add(ind, c);
|
||||||
ind++;
|
ind++;
|
||||||
} else if (lowerCase.contains(name)) {
|
} else if (cName.contains(name)) {
|
||||||
citiesToFill.add(c);
|
citiesToFill.add(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,9 +273,12 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
||||||
assert o instanceof PostCode || o instanceof City;
|
assert o instanceof PostCode || o instanceof City;
|
||||||
City city = (City) (o instanceof City ? o : null);
|
City city = (City) (o instanceof City ? o : null);
|
||||||
PostCode post = (PostCode) (o instanceof PostCode ? o : null);
|
PostCode post = (PostCode) (o instanceof PostCode ? o : null);
|
||||||
preloadStreets(o);
|
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets();
|
Collection<Street> streets = post == null ? city.getStreets() : post.getStreets();
|
||||||
|
if(streets.isEmpty()){
|
||||||
|
preloadStreets(o);
|
||||||
|
streets = post == null ? city.getStreets() : post.getStreets();
|
||||||
|
}
|
||||||
for (Street s : streets) {
|
for (Street s : streets) {
|
||||||
String sName = useEnglishNames ? s.getEnName() : s.getName();
|
String sName = useEnglishNames ? s.getEnName() : s.getName();
|
||||||
String lowerCase = sName.toLowerCase();
|
String lowerCase = sName.toLowerCase();
|
||||||
|
@ -293,7 +294,6 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
|
||||||
@Override
|
@Override
|
||||||
public void setUseEnglishNames(boolean useEnglishNames) {
|
public void setUseEnglishNames(boolean useEnglishNames) {
|
||||||
this.useEnglishNames = useEnglishNames;
|
this.useEnglishNames = useEnglishNames;
|
||||||
this.comparator = new MapObjectComparator(useEnglishNames);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue