diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java index 5cd88c03d3..0bc9185630 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java @@ -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 getVillages(String region) throws IOException { + return getVillages(region, null, false); + } + public List getVillages(String region, String nameContains, boolean useEn) throws IOException { List cities = new ArrayList(); 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 cities) throws IOException{ + private void readCities(List 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 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 villages = reader.getVillages(reg); - List 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 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 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)); } diff --git a/DataExtractionOSM/src/net/osmand/data/City.java b/DataExtractionOSM/src/net/osmand/data/City.java index 2f2d09657c..269971696c 100644 --- a/DataExtractionOSM/src/net/osmand/data/City.java +++ b/DataExtractionOSM/src/net/osmand/data/City.java @@ -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; } diff --git a/DataExtractionOSM/src/net/osmand/data/Street.java b/DataExtractionOSM/src/net/osmand/data/Street.java index 91c4001318..cb5e9f3c52 100644 --- a/DataExtractionOSM/src/net/osmand/data/Street.java +++ b/DataExtractionOSM/src/net/osmand/data/Street.java @@ -95,6 +95,9 @@ public class Street extends MapObject { public List getWayNodes() { + if(wayNodes == null){ + wayNodes = new ArrayList(); + } return wayNodes; } diff --git a/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java b/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java index eee996385d..049c80f1a8 100644 --- a/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/RegionAddressRepositoryBinary.java @@ -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 postCodes = new TreeMap(Collator.getInstance()); private boolean useEnglishNames = false; - private Comparator 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 streets = post == null ? city.getStreets() : post.getStreets() ; + Collection 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 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