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:
Victor Shcherb 2010-11-02 23:27:39 +00:00
parent 2c30496c45
commit 0cbabe4bd2
4 changed files with 96 additions and 38 deletions

View file

@ -17,6 +17,7 @@ import net.osmand.data.PostCode;
import net.osmand.data.Street;
import net.osmand.data.City.CityType;
import net.osmand.osm.MapUtils;
import net.sf.junidecode.Junidecode;
import org.apache.commons.logging.Log;
@ -106,6 +107,9 @@ public class BinaryMapIndexReader {
return;
case OsmandOdb.OsmAndAddressIndex.NAME_FIELD_NUMBER :
region.name = codedIS.readString();
if(region.enName == null){
region.enName = Junidecode.unidecode(region.name);
}
break;
case OsmandOdb.OsmAndAddressIndex.NAME_EN_FIELD_NUMBER :
region.enName = codedIS.readString();
@ -312,20 +316,23 @@ public class BinaryMapIndexReader {
codedIS.seek(r.citiesOffset);
int len = readInt();
int old = codedIS.pushLimit(len);
readCities(cities);
readCities(cities, 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, String nameContains, 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);
readCities(cities);
readCities(cities, nameContains, useEn);
codedIS.popLimit(old);
}
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){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -388,7 +395,41 @@ public class BinaryMapIndexReader {
int length = codedIS.readRawVarint32();
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);
break;
default:
@ -453,7 +494,7 @@ public class BinaryMapIndexReader {
return p;
case OsmandOdb.PostcodeIndex.POSTCODE_FIELD_NUMBER :
String name = codedIS.readString();
if(postcodeFilter != null && postcodeFilter.equalsIgnoreCase(name)){
if(postcodeFilter != null && !postcodeFilter.equalsIgnoreCase(name)){
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return null;
}
@ -515,6 +556,9 @@ public class BinaryMapIndexReader {
break;
case OsmandOdb.CityIndex.NAME_FIELD_NUMBER :
c.setName(codedIS.readString());
if(c.getEnName() == null){
c.setEnName(Junidecode.unidecode(c.getName()));
}
break;
case OsmandOdb.CityIndex.X_FIELD_NUMBER :
x = codedIS.readFixed32();
@ -564,6 +608,9 @@ public class BinaryMapIndexReader {
break;
case OsmandOdb.StreetIndex.NAME_FIELD_NUMBER :
s.setName(codedIS.readString());
if(s.getEnName() == null){
s.setEnName(Junidecode.unidecode(s.getName()));
}
break;
case OsmandOdb.StreetIndex.X_FIELD_NUMBER :
int sx = codedIS.readSInt32();
@ -622,6 +669,9 @@ public class BinaryMapIndexReader {
break;
case OsmandOdb.BuildingIndex.NAME_FIELD_NUMBER :
b.setName(codedIS.readString());
if(b.getEnName() == null){
b.setEnName(Junidecode.unidecode(b.getName()));
}
break;
case OsmandOdb.BuildingIndex.X_FIELD_NUMBER :
x = codedIS.readSInt32() + street24X;
@ -1008,8 +1058,8 @@ public class BinaryMapIndexReader {
}
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\\Belarus.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");
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
System.out.println("VERSION " + reader.getVersion());
@ -1030,22 +1080,25 @@ public class BinaryMapIndexReader {
String reg = reader.getRegionNames().get(0);
long time = System.currentTimeMillis();
List<City> cs = reader.getCities(reg);
for(City c : cs){
reader.preloadStreets(c);
int buildings = 0;
for(Street s : c.getStreets()){
reader.preloadBuildings(s);
buildings += s.getBuildings().size();
}
System.out.println(c.getName() + " " + c.getLocation() + " " + c.getStreets().size() + " " + buildings);
}
List<City> villages = reader.getVillages(reg);
List<PostCode> postcodes = reader.getPostcodes(reg);
for(PostCode c : postcodes){
reader.preloadStreets(c);
// System.out.println(c.getName());
}
// for(City c : cs){
// reader.preloadStreets(c);
// int buildings = 0;
// for(Street s : c.getStreets()){
// reader.preloadBuildings(s);
// buildings += s.getBuildings().size();
// }
// System.out.println(c.getName() + " " + c.getLocation() + " " + c.getStreets().size() + " " + buildings);
// }
// List<PostCode> postcodes = reader.getPostcodes(reg);
// for(PostCode c : postcodes){
// reader.preloadStreets(c);
//// 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(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
System.out.println("Time " + (System.currentTimeMillis() - time));
}

View file

@ -86,7 +86,9 @@ public class City extends MapObject {
} else {
// try to merge streets
Street prev = streets.get(name);
prev.getWayNodes().addAll(street.getWayNodes());
if(!street.getWayNodes().isEmpty()){
prev.getWayNodes().addAll(street.getWayNodes());
}
prev.getBuildings().addAll(street.getBuildings());
return prev;
}

View file

@ -95,6 +95,9 @@ public class Street extends MapObject {
public List<Way> getWayNodes() {
if(wayNodes == null){
wayNodes = new ArrayList<Way>();
}
return wayNodes;
}

View file

@ -3,7 +3,6 @@ package net.osmand;
import java.io.IOException;
import java.text.Collator;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
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 boolean useEnglishNames = false;
private Comparator<MapObject> comparator = new MapObjectComparator(useEnglishNames);
public RegionAddressRepositoryBinary(BinaryMapIndexReader file, String name) {
this.file = file;
this.region = name;
@ -68,13 +64,13 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
buildingsToFill.add(building);
}
}
Collections.sort(buildingsToFill, comparator);
}
private void preloadBuildings(Street street) {
if(street.getBuildings().isEmpty()){
try {
file.preloadBuildings(street);
street.sortBuildings();
} catch (IOException e) {
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;
City city = (City) (o instanceof City ? o : null);
PostCode post = (PostCode) (o instanceof PostCode ? o : null);
preloadStreets(o);
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){
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();
for(City c : file.getVillages(name)){
String cName = useEnglishNames ? c.getEnName() : c.getName();
String lowerCase = cName.toLowerCase();
if (lowerCase.startsWith(name)) {
for(City c : file.getVillages(region, name, useEnglishNames )){
String cName = c.getName(useEnglishNames).toLowerCase();
if (cName.startsWith(name)) {
citiesToFill.add(ind, c);
ind++;
} else if (lowerCase.contains(name)) {
} else if (cName.contains(name)) {
citiesToFill.add(c);
}
}
@ -275,9 +273,12 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
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);
name = name.toLowerCase();
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) {
String sName = useEnglishNames ? s.getEnName() : s.getName();
String lowerCase = sName.toLowerCase();
@ -293,7 +294,6 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override
public void setUseEnglishNames(boolean useEnglishNames) {
this.useEnglishNames = useEnglishNames;
this.comparator = new MapObjectComparator(useEnglishNames);
}
@Override