Implement search by name. Refactor some binary file readers

This commit is contained in:
Victor Shcherb 2011-09-28 01:22:02 +02:00
parent 54c3487c48
commit 5f95151338
12 changed files with 638 additions and 206 deletions

View file

@ -0,0 +1,132 @@
package net.osmand;
import java.text.Collator;
import net.osmand.StringMatcher;
/**
* Abstract collator matcher that basically supports subclasses with some collator
* matching.
*
* @author pavol.zibrita
*/
public class CollatorStringMatcher implements StringMatcher {
private final Collator collator;
private final StringMatcherMode mode;
private final String part;
public enum StringMatcherMode {
CHECK_ONLY_STARTS_WITH,
CHECK_STARTS_FROM_SPACE,
CHECK_STARTS_FROM_SPACE_NOT_BEGINNING,
CHECK_CONTAINS
}
public CollatorStringMatcher(Collator collator, String part, StringMatcherMode mode) {
this.collator = collator;
this.part = part;
this.mode = mode;
}
public Collator getCollator() {
return collator;
}
@Override
public boolean matches(String name) {
return cmatches(collator, name, part, mode);
}
public static boolean cmatches(Collator collator, String base, String part, StringMatcherMode mode){
switch (mode) {
case CHECK_CONTAINS:
return ccontains(collator, base, part);
case CHECK_STARTS_FROM_SPACE:
return cstartsWith(collator, base, part, true, true);
case CHECK_STARTS_FROM_SPACE_NOT_BEGINNING:
return cstartsWith(collator, base, part, false, true);
case CHECK_ONLY_STARTS_WITH:
return cstartsWith(collator, base, part, true, false);
}
return false;
}
/**
* Check if part contains in base
*
* @param collator Collator to use
* @param part String to search
* @param base String where to search
* @return true if part is contained in base
*/
public static boolean ccontains(Collator collator, String base, String part) {
int pos = 0;
if (part.length() > 3) {
// improve searching by searching first 3 characters
pos = cindexOf(collator, pos, part.substring(0, 3), base);
if (pos == -1) {
return false;
}
}
pos = cindexOf(collator, pos, part, base);
if (pos == -1) {
return false;
}
return true;
}
private static int cindexOf(Collator collator, int start, String part, String base) {
for (int pos = start; pos <= base.length() - part.length(); pos++) {
if (collator.equals(base.substring(pos, pos + part.length()), part)) {
return pos;
}
}
return -1;
}
/**
* Checks if string starts with another string.
* Special check try to find as well in the middle of name
*
* @param collator
* @param searchIn
* @param theStart
* @return true if searchIn starts with token
*/
public static boolean cstartsWith(Collator collator, String searchIn, String theStart,
boolean checkBeginning, boolean checkSpaces) {
int startLength = theStart.length();
int searchInLength = searchIn.length();
if (startLength == 0) {
return true;
}
if (startLength > searchInLength) {
return false;
}
// simulate starts with for collator
if (checkBeginning) {
boolean starts = collator.equals(searchIn.substring(0, startLength), theStart);
if (starts) {
return true;
}
}
if (checkSpaces) {
for (int i = 1; i <= searchInLength - startLength; i++) {
if (isSpace(searchIn.charAt(i - 1)) && !isSpace(searchIn.charAt(i))) {
if (collator.equals(searchIn.substring(i, i + startLength), theStart)) {
return true;
}
}
}
}
return false;
}
private static boolean isSpace(char c){
return !Character.isLetter(c) && !Character.isDigit(c);
}
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import net.osmand.ResultMatcher;
import net.osmand.StringMatcher;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.MapObject;
@ -85,7 +86,7 @@ public class BinaryMapAddressReaderAdapter {
}
}
protected void readCities(List<City> cities, ResultMatcher<MapObject> resultMatcher, StringMatcher matcher, boolean useEn) throws IOException {
protected void readCities(List<City> cities, SearchRequest<MapObject> resultMatcher, StringMatcher matcher, boolean useEn) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -116,7 +117,7 @@ public class BinaryMapAddressReaderAdapter {
}
protected PostCode readPostcode(PostCode p, int fileOffset, ResultMatcher<Street> resultMatcher, boolean loadStreets, String postcodeFilter) throws IOException{
protected PostCode readPostcode(PostCode p, int fileOffset, SearchRequest<Street> resultMatcher, boolean loadStreets, String postcodeFilter) throws IOException{
int x = 0;
int y = 0;
while(true){
@ -173,7 +174,7 @@ public class BinaryMapAddressReaderAdapter {
}
protected City readCity(City c, int fileOffset, boolean loadStreets, ResultMatcher<Street> resultMatcher,
protected City readCity(City c, int fileOffset, boolean loadStreets, SearchRequest<Street> resultMatcher,
StringMatcher nameMatcher, boolean useEn) throws IOException{
int x = 0;
int y = 0;
@ -269,7 +270,7 @@ public class BinaryMapAddressReaderAdapter {
}
}
protected Street readStreet(Street s, ResultMatcher<Building> resultMatcher, boolean loadBuildings, int city24X, int city24Y, String postcodeFilter) throws IOException{
protected Street readStreet(Street s, SearchRequest<Building> resultMatcher, boolean loadBuildings, int city24X, int city24Y, String postcodeFilter) throws IOException{
int x = 0;
int y = 0;
boolean loadLocation = city24X != 0 || city24Y != 0;
@ -477,7 +478,7 @@ public class BinaryMapAddressReaderAdapter {
protected void readPostcodes(List<PostCode> postcodes, ResultMatcher<MapObject> resultMatcher, StringMatcher nameMatcher) throws IOException{
protected void readPostcodes(List<PostCode> postcodes, SearchRequest<MapObject> resultMatcher, StringMatcher nameMatcher) throws IOException{
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);

View file

@ -11,6 +11,7 @@ import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import net.osmand.Algoritms;
@ -375,7 +376,7 @@ public class BinaryMapIndexReader {
throw new IllegalArgumentException(name);
}
public List<PostCode> getPostcodes(String region, ResultMatcher<MapObject> resultMatcher, StringMatcher nameMatcher) throws IOException {
public List<PostCode> getPostcodes(String region, SearchRequest<MapObject> resultMatcher, StringMatcher nameMatcher) throws IOException {
List<PostCode> postcodes = new ArrayList<PostCode>();
AddressRegion r = getRegionByName(region);
if(r.postcodesOffset != -1){
@ -403,7 +404,7 @@ public class BinaryMapIndexReader {
return null;
}
public List<City> getCities(String region, ResultMatcher<MapObject> resultMatcher) throws IOException {
public List<City> getCities(String region, SearchRequest<MapObject> resultMatcher) throws IOException {
List<City> cities = new ArrayList<City>();
AddressRegion r = getRegionByName(region);
if(r.citiesOffset != -1){
@ -416,7 +417,7 @@ public class BinaryMapIndexReader {
return cities;
}
public List<City> getVillages(String region, ResultMatcher<MapObject> resultMatcher, StringMatcher nameMatcher, boolean useEn) throws IOException {
public List<City> getVillages(String region, SearchRequest<MapObject> resultMatcher, StringMatcher nameMatcher, boolean useEn) throws IOException {
List<City> cities = new ArrayList<City>();
AddressRegion r = getRegionByName(region);
if(r.villagesOffset != -1){
@ -430,7 +431,7 @@ public class BinaryMapIndexReader {
}
public void preloadStreets(City c, ResultMatcher<Street> resultMatcher) throws IOException {
public void preloadStreets(City c, SearchRequest<Street> resultMatcher) throws IOException {
checkAddressIndex(c.getFileOffset());
codedIS.seek(c.getFileOffset());
int size = codedIS.readRawVarint32();
@ -451,7 +452,7 @@ public class BinaryMapIndexReader {
}
public void preloadStreets(PostCode p, ResultMatcher<Street> resultMatcher) throws IOException {
public void preloadStreets(PostCode p, SearchRequest<Street> resultMatcher) throws IOException {
checkAddressIndex(p.getFileOffset());
codedIS.seek(p.getFileOffset());
@ -474,7 +475,7 @@ public class BinaryMapIndexReader {
}
}
public void preloadBuildings(Street s, ResultMatcher<Building> resultMatcher) throws IOException {
public void preloadBuildings(Street s, SearchRequest<Building> resultMatcher) throws IOException {
checkAddressIndex(s.getFileOffset());
codedIS.seek(s.getFileOffset());
int size = codedIS.readRawVarint32();
@ -712,7 +713,7 @@ public class BinaryMapIndexReader {
int cbottom = 0;
req.numberOfReadSubtrees++;
while(true){
if(req.isInterrupted()){
if(req.isCancelled()){
return;
}
int t = codedIS.readTag();
@ -918,6 +919,18 @@ public class BinaryMapIndexReader {
}
public void searchPoiByName(SearchRequest<Amenity> req) throws IOException {
if (req.nameQuery == null || req.nameQuery.length() == 0) {
throw new IllegalArgumentException();
}
for (PoiRegion poiIndex : poiIndexes) {
codedIS.seek(poiIndex.filePointer);
int old = codedIS.pushLimit(poiIndex.length);
poiAdapter.searchPoiByName(poiIndex, req);
codedIS.popLimit(old);
}
}
public List<Amenity> searchPoi(SearchRequest<Amenity> req) throws IOException {
req.numberOfVisitedObjects = 0;
req.numberOfAcceptedObjects = 0;
@ -963,25 +976,42 @@ public class BinaryMapIndexReader {
}
public static SearchRequest<BinaryMapDataObject> buildSearchRequest(int sleft, int sright, int stop, int sbottom, int zoom){
public static SearchRequest<BinaryMapDataObject> buildSearchRequest(int sleft, int sright, int stop, int sbottom, int zoom, SearchFilter searchFilter){
SearchRequest<BinaryMapDataObject> request = new SearchRequest<BinaryMapDataObject>();
request.left = sleft;
request.right = sright;
request.top = stop;
request.bottom = sbottom;
request.zoom = zoom;
request.searchFilter = searchFilter;
return request;
}
public static <T> SearchRequest<T> buildAddressRequest(ResultMatcher<T> resultMatcher){
SearchRequest<T> request = new SearchRequest<T>();
request.resultMatcher = resultMatcher;
return request;
}
public static SearchRequest<Amenity> buildSearchPoiRequest(int sleft, int sright, int stop, int sbottom, int zoom, int limit){
public static SearchRequest<Amenity> buildSearchPoiRequest(int sleft, int sright, int stop, int sbottom, int zoom, SearchPoiTypeFilter poiTypeFilter){
SearchRequest<Amenity> request = new SearchRequest<Amenity>();
request.left = sleft;
request.right = sright;
request.top = stop;
request.bottom = sbottom;
request.zoom = zoom;
request.limit = limit;
request.poiTypeFilter = poiTypeFilter;
return request;
}
public static SearchRequest<Amenity> buildSearchPoiRequest(int x, int y, String nameFilter, SearchPoiTypeFilter poiTypeFilter){
SearchRequest<Amenity> request = new SearchRequest<Amenity>();
request.x = x;
request.y = y;
request.poiTypeFilter = poiTypeFilter;
request.nameQuery = nameFilter;
return request;
}
@ -1022,18 +1052,31 @@ public class BinaryMapIndexReader {
}
public static class SearchRequest<T> {
private List<T> searchResults = new ArrayList<T>();
private ResultMatcher<T> resultMatcher;
// 31 zoom tiles
// common variables
int x = 0;
int y = 0;
int left = 0;
int right = 0;
int top = 0;
int bottom = 0;
int zoom = 15;
int limit = -1;
List<T> searchResults = new ArrayList<T>();
String nameQuery = null;
SearchFilter searchFilter = null;
SearchPoiTypeFilter poiTypeFilter = null;
// cache information
TIntArrayList cacheCoordinates = new TIntArrayList();
TIntArrayList cacheTypes = new TIntArrayList();
SearchFilter searchFilter = null;
SearchPoiTypeFilter poiTypeFilter = null;
// TRACE INFO
int numberOfVisitedObjects = 0;
@ -1045,19 +1088,13 @@ public class BinaryMapIndexReader {
protected SearchRequest(){
}
public SearchFilter getSearchFilter() {
return searchFilter;
}
public void setSearchFilter(SearchFilter searchFilter) {
this.searchFilter = searchFilter;
}
public void setPoiTypeFilter(SearchPoiTypeFilter poiTypeFilter) {
this.poiTypeFilter = poiTypeFilter;
}
public SearchPoiTypeFilter getPoiTypeFilter() {
return poiTypeFilter;
protected boolean publish(T obj){
if(resultMatcher == null || resultMatcher.publish(obj)){
searchResults.add(obj);
return true;
}
return false;
}
public List<T> getSearchResults() {
@ -1068,13 +1105,25 @@ public class BinaryMapIndexReader {
this.interrupted = interrupted;
}
public boolean isInterrupted() {
return interrupted;
public boolean isCancelled() {
if(this.interrupted){
return interrupted;
}
if(resultMatcher != null){
return resultMatcher.isCancelled();
}
return false;
}
public void clearSearchResults(){
// recreate whole list to allow GC collect old data
searchResults = new ArrayList<T>();
cacheCoordinates.clear();
cacheTypes.clear();
numberOfVisitedObjects = 0;
numberOfAcceptedObjects = 0;
numberOfReadSubtrees = 0;
numberOfAcceptedSubtrees = 0;
}
}
@ -1206,121 +1255,143 @@ public class BinaryMapIndexReader {
}
private static boolean testMapSearch = false;
private static boolean testAddressSearch = false;
private static boolean testPoiSearch = true;
private static boolean testTransportSearch = false;
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile(new File("/home/victor/projects/OsmAnd/data/osm-gen/POI/Test-Ru.poi.obf"), "r");
RandomAccessFile raf = new RandomAccessFile(new File("/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.obf"), "r");
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
System.out.println("VERSION " + reader.getVersion()); //$NON-NLS-1$
long time = System.currentTimeMillis();
testMapSearch(reader);
testAddressSearch(reader);
testTransportSearch(reader);
if (testMapSearch) {
testMapSearch(reader);
}
if(testAddressSearch) {
testAddressSearch(reader);
}
if(testTransportSearch) {
testTransportSearch(reader);
}
PoiRegion poiRegion = reader.getPoiIndexes().get(0);
System.out.println(poiRegion.leftLongitude + " " + poiRegion.rightLongitude + " " + poiRegion.bottomLatitude + " " + poiRegion.topLatitude);
// for (int i = 0; i < poiRegion.categories.size(); i++) {
// System.out.println(poiRegion.categories.get(i));
// System.out.println(" " + poiRegion.subcategories.get(i));
// }
int sleft = MapUtils.get31TileNumberX(37.5);
int sright = MapUtils.get31TileNumberX(37.9);
int stop = MapUtils.get31TileNumberY(55.814);
int sbottom = MapUtils.get31TileNumberY(55.81);
SearchRequest<Amenity> req = buildSearchPoiRequest(sleft, sright, stop, sbottom, -1, 200);
req.setPoiTypeFilter(new SearchPoiTypeFilter() {
@Override
public boolean accept(AmenityType type, String subcategory) {
return type == AmenityType.TRANSPORTATION && "fuel".equals(subcategory);
Locale.setDefault(new Locale("RU"));
if (testPoiSearch) {
PoiRegion poiRegion = reader.getPoiIndexes().get(0);
System.out.println(poiRegion.leftLongitude + " " + poiRegion.rightLongitude + " " + poiRegion.bottomLatitude + " "
+ poiRegion.topLatitude);
for (int i = 0; i < poiRegion.categories.size(); i++) {
System.out.println(poiRegion.categories.get(i));
System.out.println(" " + poiRegion.subcategories.get(i));
}
int sleft = MapUtils.get31TileNumberX(37.5);
int sright = MapUtils.get31TileNumberX(37.9);
int stop = MapUtils.get31TileNumberY(55.814);
int sbottom = MapUtils.get31TileNumberY(55.81);
SearchRequest<Amenity> req = buildSearchPoiRequest(sleft, sright, stop, sbottom, -1, new SearchPoiTypeFilter() {
@Override
public boolean accept(AmenityType type, String subcategory) {
return type == AmenityType.TRANSPORTATION && "fuel".equals(subcategory);
}
});
List<Amenity> results = reader.searchPoi(req);
for (Amenity a : results) {
System.out.println(a.getType() + " " + a.getSubType() + " " + a.getName() + " " + a.getLocation());
}
System.out.println("Searching by name...");
req = buildSearchPoiRequest(sleft, sright, "kolie", null);
reader.searchPoiByName(req);
for (Amenity a : req.getSearchResults()) {
System.out.println(a.getType() + " " + a.getSubType() + " " + a.getName() + " " + a.getLocation());
}
});
List<Amenity> results = reader.searchPoi(req);
for(Amenity a : results){
System.out.println(a.getType() + " " + a.getSubType() + " " + a.getName() + " " + a.getLocation());
}
System.out.println("MEMORY " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); //$NON-NLS-1$
System.out.println("Time " + (System.currentTimeMillis() - time)); //$NON-NLS-1$
}
private static void testTransportSearch(BinaryMapIndexReader reader) {
private static void testTransportSearch(BinaryMapIndexReader reader) throws IOException {
// test transport
// for(TransportIndex i : reader.transportIndexes){
// System.out.println(i.left + " " + i.right + " " + i.top + " " + i.bottom);
// System.out.println(i.stringTable.cacheOfStrings);
// System.out.println(i.stringTable.offsets);
// System.out.println(i.stringTable.window);
// }
// {
// int sleft = MapUtils.get31TileNumberX(27.573);
// int sright = MapUtils.get31TileNumberX(27.581);
// int stop = MapUtils.get31TileNumberY(53.912);
// int sbottom = MapUtils.get31TileNumberY(53.908);
// for (TransportStop s : reader.searchTransportIndex(buildSearchTransportRequest(sleft, sright, stop, sbottom, 15, null))) {
// System.out.println(s.getName());
// for (int i : s.getReferencesToRoutes()) {
// TransportRoute route = reader.getTransportRoute(i);
// System.out.println(" " + route.getRef() + " " + route.getName() + " " + route.getDistance() + " "
// + route.getAvgBothDistance());
// }
// }
// }
// {
// int sleft = MapUtils.get31TileNumberX(27.473);
// int sright = MapUtils.get31TileNumberX(27.681);
// int stop = MapUtils.get31TileNumberY(53.912);
// int sbottom = MapUtils.get31TileNumberY(53.708);
// for (TransportStop s : reader.searchTransportIndex(buildSearchTransportRequest(sleft, sright, stop, sbottom, 16, null))) {
// System.out.println(s.getName());
// for (int i : s.getReferencesToRoutes()) {
// TransportRoute route = reader.getTransportRoute(i);
// System.out.println(" " + route.getRef() + " " + route.getName() + " " + route.getDistance() + " "
// + route.getAvgBothDistance());
// }
// }
// }
for (TransportIndex i : reader.transportIndexes) {
System.out.println(i.left + " " + i.right + " " + i.top + " " + i.bottom);
System.out.println(i.stringTable.cacheOfStrings);
System.out.println(i.stringTable.offsets);
System.out.println(i.stringTable.window);
}
{
int sleft = MapUtils.get31TileNumberX(27.573);
int sright = MapUtils.get31TileNumberX(27.581);
int stop = MapUtils.get31TileNumberY(53.912);
int sbottom = MapUtils.get31TileNumberY(53.908);
for (TransportStop s : reader.searchTransportIndex(buildSearchTransportRequest(sleft, sright, stop, sbottom, 15, null))) {
System.out.println(s.getName());
for (int i : s.getReferencesToRoutes()) {
net.osmand.data.TransportRoute route = reader.getTransportRoute(i);
System.out.println(" " + route.getRef() + " " + route.getName() + " " + route.getDistance() + " "
+ route.getAvgBothDistance());
}
}
}
{
int sleft = MapUtils.get31TileNumberX(27.473);
int sright = MapUtils.get31TileNumberX(27.681);
int stop = MapUtils.get31TileNumberY(53.912);
int sbottom = MapUtils.get31TileNumberY(53.708);
for (TransportStop s : reader.searchTransportIndex(buildSearchTransportRequest(sleft, sright, stop, sbottom, 16, null))) {
System.out.println(s.getName());
for (int i : s.getReferencesToRoutes()) {
net.osmand.data.TransportRoute route = reader.getTransportRoute(i);
System.out.println(" " + route.getRef() + " " + route.getName() + " " + route.getDistance() + " "
+ route.getAvgBothDistance());
}
}
}
}
private static void testAddressSearch(BinaryMapIndexReader reader) throws IOException {
// test address index search
// String reg = reader.getRegionNames().get(0);
// List<City> cs = reader.getCities(reg, null);
// for(City c : cs){
// int buildings = 0;
// reader.preloadStreets(c, null);
// for(Street s : c.getStreets()){
// reader.preloadBuildings(s);
// buildings += s.getBuildings().size();
// }
// System.out.println(c.getName() + " " + c.getLocation() + " " + c.getStreets().size() + " " + buildings + " " + c.getEnName());
// }
// List<PostCode> postcodes = reader.getPostcodes(reg);
// for(PostCode c : postcodes){
// reader.preloadStreets(c);
// System.out.println(c.getName());
// }
// List<City> villages = reader.getVillages(reg, new StringMatcher() {
//
// @Override
// public boolean matches(String name) {
// return false;
// }
// }, true);
// System.out.println("Villages " + villages.size());
String reg = reader.getRegionNames().get(0);
List<City> cs = reader.getCities(reg, null);
for(City c : cs){
int buildings = 0;
reader.preloadStreets(c, null);
for(Street s : c.getStreets()){
reader.preloadBuildings(s, buildAddressRequest((ResultMatcher<Building>) null));
buildings += s.getBuildings().size();
}
System.out.println(c.getName() + " " + c.getLocation() + " " + c.getStreets().size() + " " + buildings + " " + c.getEnName());
}
List<PostCode> postcodes = reader.getPostcodes(reg, buildAddressRequest((ResultMatcher<MapObject>) null), null);
for(PostCode c : postcodes){
reader.preloadStreets(c, buildAddressRequest((ResultMatcher<Street>) null));
System.out.println(c.getName());
}
List<City> villages = reader.getVillages(reg, buildAddressRequest((ResultMatcher<MapObject>) null), new StringMatcher() {
@Override
public boolean matches(String name) {
return false;
}
}, true);
System.out.println("Villages " + villages.size());
}
private static void testMapSearch(BinaryMapIndexReader reader) throws IOException {
// System.out.println(reader.mapIndexes.get(0).encodingRules);
// int sleft = MapUtils.get31TileNumberX(27.596);
// int sright = MapUtils.get31TileNumberX(27.599);
// int stop = MapUtils.get31TileNumberY(53.921);
// int sbottom = MapUtils.get31TileNumberY(53.919);
// System.out.println("SEARCH " + sleft + " " + sright + " " + stop + " " + sbottom);
//
// for (BinaryMapDataObject obj : reader.searchMapIndex(buildSearchRequest(sleft, sright, stop, sbottom, 8))) {
// if (obj.getName() != null) {
// System.out.println(" " + obj.getName());
// }
// }
System.out.println(reader.mapIndexes.get(0).encodingRules);
int sleft = MapUtils.get31TileNumberX(27.596);
int sright = MapUtils.get31TileNumberX(27.599);
int stop = MapUtils.get31TileNumberY(53.921);
int sbottom = MapUtils.get31TileNumberY(53.919);
System.out.println("SEARCH " + sleft + " " + sright + " " + stop + " " + sbottom);
for (BinaryMapDataObject obj : reader.searchMapIndex(buildSearchRequest(sleft, sright, stop, sbottom, 8, null))) {
if (obj.getName() != null) {
System.out.println(" " + obj.getName());
}
}
}
}

View file

@ -7,6 +7,7 @@ import gnu.trove.list.array.TLongArrayList;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -812,7 +813,7 @@ public class BinaryMapIndexWriter {
codedOutStream.writeMessage(OsmandOdb.OsmAndPoiBox.CATEGORIES_FIELD_NUMBER, builder.build());
}
public Map<PoiTileBox, TLongList> writePoiNameIndex(Map<String, List<PoiTileBox>> namesIndex, long fpPoiIndex) throws IOException {
public Map<PoiTileBox, TLongList> writePoiNameIndex(Map<String, Set<PoiTileBox>> namesIndex) throws IOException {
checkPeekState(POI_INDEX_INIT);
codedOutStream.writeTag(OsmandOdb.OsmAndPoiIndex.NAMEINDEX_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
preserveInt32Size();
@ -821,9 +822,9 @@ public class BinaryMapIndexWriter {
Map<String, Integer> indexedTable = new LinkedHashMap<String, Integer>();
Map<PoiTileBox, TLongList> fpToWriteSeeks = new LinkedHashMap<PoiTileBox, TLongList>();
int previousSize = 0;
for(Map.Entry<String, List<PoiTileBox>> e : namesIndex.entrySet()) {
for(Map.Entry<String, Set<PoiTileBox>> e : namesIndex.entrySet()) {
OsmandOdb.OsmAndPoiNameIndexData.Builder builder = OsmandOdb.OsmAndPoiNameIndexData.newBuilder();
List<PoiTileBox> tileBoxes = e.getValue();
List<PoiTileBox> tileBoxes = new ArrayList<PoiTileBox>(e.getValue());
for(PoiTileBox box : tileBoxes) {
OsmandOdb.OsmAndPoiNameIndexDataAtom.Builder bs = OsmandOdb.OsmAndPoiNameIndexDataAtom.newBuilder();
bs.setX(box.getX());
@ -852,10 +853,10 @@ public class BinaryMapIndexWriter {
}
writeIndexedTable(OsmandOdb.OsmAndPoiNameIndex.TABLE_FIELD_NUMBER, indexedTable);
codedOutStream.flush();
int diff = (int) (raf.getFilePointer() - fpPoiIndex);
long l = raf.getFilePointer();
for (TLongList es : fpToWriteSeeks.values()) {
for (int i = 0; i < es.size(); i++) {
es.set(i, es.get(i) + diff);
es.set(i, es.get(i) + l);
}
}

View file

@ -1,9 +1,11 @@
package net.osmand.binary;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.map.hash.TIntLongHashMap;
import gnu.trove.set.hash.TLongHashSet;
import java.io.IOException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -11,7 +13,9 @@ import java.util.List;
import org.apache.commons.logging.Log;
import net.osmand.Algoritms;
import net.osmand.CollatorStringMatcher;
import net.osmand.LogUtil;
import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.data.Amenity;
import net.osmand.data.AmenityType;
@ -156,6 +160,184 @@ public class BinaryMapPoiReaderAdapter {
}
}
protected void searchPoiByName( PoiRegion region, SearchRequest<Amenity> req) throws IOException {
TIntArrayList offsets = new TIntArrayList();
Collator instance = Collator.getInstance();
instance.setStrength(Collator.PRIMARY);
CollatorStringMatcher matcher = new CollatorStringMatcher(instance, req.nameQuery,
StringMatcherMode.CHECK_STARTS_FROM_SPACE);
long time = System.currentTimeMillis();
int indexOffset = codedIS.getTotalBytesRead();
while(true){
if(req.isCancelled()){
return;
}
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.OsmAndPoiIndex.NAMEINDEX_FIELD_NUMBER :
int length = readInt();
int oldLimit = codedIS.pushLimit(length);
offsets = readPoiNameIndex(instance, req.nameQuery, req);
codedIS.popLimit(oldLimit);
break;
case OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER :
// also offsets can be randomly skipped by limit
offsets.sort();
LOG.info("Searched poi structure in "+(System.currentTimeMillis() - time) +
"ms. Found " + offsets.size() +" subtress");
for (int j = 0; j < offsets.size(); j++) {
codedIS.seek(offsets.get(j) + indexOffset);
int len = readInt();
int oldLim = codedIS.pushLimit(len);
readPoiData(matcher, req, region);
codedIS.popLimit(oldLim);
if(req.isCancelled()){
return;
}
}
LOG.info("Whole poi by name search is done in "+(System.currentTimeMillis() - time) +
"ms. Found " + req.getSearchResults().size());
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return;
default:
skipUnknownField(t);
break;
}
}
}
private TIntArrayList readPoiNameIndex(Collator instance, String query, SearchRequest<Amenity> req) throws IOException {
TIntArrayList offsets = new TIntArrayList();
TIntArrayList dataOffsets = null;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return offsets;
case OsmandOdb.OsmAndPoiNameIndex.TABLE_FIELD_NUMBER : {
int length = readInt();
int oldLimit = codedIS.pushLimit(length);
dataOffsets = readIndexedStringTable(instance, query);
codedIS.popLimit(oldLimit);
break; }
case OsmandOdb.OsmAndPoiNameIndex.DATA_FIELD_NUMBER : {
if(dataOffsets != null){
dataOffsets.sort();
int offset = codedIS.getTotalBytesRead();
for (int i = 0; i < dataOffsets.size(); i++) {
codedIS.seek(dataOffsets.get(i) + offset);
int len = codedIS.readRawVarint32();
int oldLim = codedIS.pushLimit(len);
readPoiNameIndexData(offsets);
codedIS.popLimit(oldLim);
if (req.isCancelled()) {
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return offsets;
}
}
}
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return offsets; }
default:
skipUnknownField(t);
break;
}
}
}
private void readPoiNameIndexData(TIntArrayList offsets) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.OsmAndPoiNameIndexData.ATOMS_FIELD_NUMBER :
int len = codedIS.readRawVarint32();
int oldLim = codedIS.pushLimit(len);
readPoiNameIndexDataAtom(offsets);
codedIS.popLimit(oldLim);
break;
default:
skipUnknownField(t);
break;
}
}
}
private void readPoiNameIndexDataAtom(TIntArrayList offsets) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.OsmAndPoiNameIndexDataAtom.X_FIELD_NUMBER :
/*int x = */codedIS.readUInt32();
break;
case OsmandOdb.OsmAndPoiNameIndexDataAtom.Y_FIELD_NUMBER :
/*int y = */codedIS.readUInt32();
break;
case OsmandOdb.OsmAndPoiNameIndexDataAtom.ZOOM_FIELD_NUMBER :
/*int zoom = */codedIS.readUInt32();
break;
case OsmandOdb.OsmAndPoiNameIndexDataAtom.SHIFTTO_FIELD_NUMBER :
offsets.add(readInt());
break;
default:
skipUnknownField(t);
break;
}
}
}
private TIntArrayList readIndexedStringTable(Collator instance, String query) throws IOException {
// TODO support fully functional indexed string table
TIntArrayList list = new TIntArrayList();
int charMatches = 0;
boolean keyMatches = false;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return list;
case OsmandOdb.IndexedStringTable.KEY_FIELD_NUMBER :
String key = codedIS.readString();
keyMatches = false;
int i=0;
for(; i<query.length(); i++){
if (i >= key.length() || instance.compare(key.substring(i, i + 1), query.substring(i, i + 1)) != 0) {
break;
}
}
if(i >= charMatches && i > 0){
if(i > charMatches){
list.clear();
charMatches = i;
}
keyMatches = true;
}
break;
case OsmandOdb.IndexedStringTable.VAL_FIELD_NUMBER :
int val = codedIS.readUInt32();
if (keyMatches) {
list.add(val);
}
break;
default:
skipUnknownField(t);
break;
}
}
}
protected void searchPoiIndex(int left31, int right31, int top31, int bottom31,
SearchRequest<Amenity> req, PoiRegion region) throws IOException {
int indexOffset = codedIS.getTotalBytesRead();
@ -168,7 +350,7 @@ public class BinaryMapPoiReaderAdapter {
}
TIntLongHashMap offsetsMap = new TIntLongHashMap();
while(true){
if(req.isInterrupted()){
if(req.isCancelled()){
return;
}
int t = codedIS.readTag();
@ -199,7 +381,7 @@ public class BinaryMapPoiReaderAdapter {
int oldLim = codedIS.pushLimit(len);
readPoiData(left31, right31, top31, bottom31, req, req.getSearchResults(), region, skipTiles, zoomToSkip);
codedIS.popLimit(oldLim);
if(req.isInterrupted()){
if(req.isCancelled()){
return;
}
}
@ -211,14 +393,13 @@ public class BinaryMapPoiReaderAdapter {
}
}
}
private void readPoiData(int left31, int right31, int top31, int bottom31,
SearchRequest<Amenity> req, List<Amenity> result, PoiRegion region, TLongHashSet toSkip, int zSkip) throws IOException {
private void readPoiData(CollatorStringMatcher matcher, SearchRequest<Amenity> req, PoiRegion region) throws IOException {
int x = 0;
int y = 0;
int zoom = 0;
while(true){
if(req.isInterrupted()){
if(req.isCancelled()){
return;
}
int t = codedIS.readTag();
@ -238,7 +419,48 @@ public class BinaryMapPoiReaderAdapter {
case OsmandOdb.OsmAndPoiBoxData.POIDATA_FIELD_NUMBER:
int len = codedIS.readRawVarint32();
int oldLim = codedIS.pushLimit(len);
Amenity am = readPoiPoint(left31, right31, top31, bottom31, x, y, zoom, req, region);
Amenity am = readPoiPoint(0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, x, y, zoom, req, region, false);
codedIS.popLimit(oldLim);
if (am != null) {
if(matcher.matches(am.getName(false)) || matcher.matches(am.getName(true))) {
req.publish(am);
}
}
break;
default:
skipUnknownField(t);
break;
}
}
}
private void readPoiData(int left31, int right31, int top31, int bottom31,
SearchRequest<Amenity> req, List<Amenity> result, PoiRegion region, TLongHashSet toSkip, int zSkip) throws IOException {
int x = 0;
int y = 0;
int zoom = 0;
while(true){
if(req.isCancelled()){
return;
}
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.OsmAndPoiBoxData.X_FIELD_NUMBER :
x = codedIS.readUInt32();
break;
case OsmandOdb.OsmAndPoiBoxData.ZOOM_FIELD_NUMBER :
zoom = codedIS.readUInt32();
break;
case OsmandOdb.OsmAndPoiBoxData.Y_FIELD_NUMBER :
y = codedIS.readUInt32();
break;
case OsmandOdb.OsmAndPoiBoxData.POIDATA_FIELD_NUMBER:
int len = codedIS.readRawVarint32();
int oldLim = codedIS.pushLimit(len);
Amenity am = readPoiPoint(left31, right31, top31, bottom31, x, y, zoom, req, region, true);
codedIS.popLimit(oldLim);
if (am != null) {
if (toSkip != null) {
@ -266,7 +488,7 @@ public class BinaryMapPoiReaderAdapter {
}
private Amenity readPoiPoint(int left31, int right31, int top31, int bottom31,
int px, int py, int zoom, SearchRequest<Amenity> req, PoiRegion region) throws IOException {
int px, int py, int zoom, SearchRequest<Amenity> req, PoiRegion region, boolean checkBounds) throws IOException {
Amenity am = null;
int x = 0;
int y = 0;
@ -291,9 +513,11 @@ public class BinaryMapPoiReaderAdapter {
case OsmandOdb.OsmAndPoiBoxDataAtom.DY_FIELD_NUMBER :
y = (codedIS.readSInt32() + (py << (24 - zoom))) << 7;
req.numberOfVisitedObjects++;
if(left31 > x || right31 < x || top31 > y || bottom31 < y){
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return null;
if (checkBounds) {
if (left31 > x || right31 < x || top31 > y || bottom31 < y) {
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return null;
}
}
am = new Amenity();
am.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
@ -392,7 +616,7 @@ public class BinaryMapPoiReaderAdapter {
int dy = py;
int dx = px;
while(true){
if(req.isInterrupted()){
if(req.isCancelled()){
return false;
}
int t = codedIS.readTag();

View file

@ -63,7 +63,7 @@ public class BinaryMapTransportReaderAdapter {
IndexStringTable stringTable = null;
}
private static class IndexStringTable {
protected static class IndexStringTable {
private static final int SIZE_OFFSET_ARRAY = 100;
private static final int WINDOW_SIZE = 25;
int fileOffset = 0;
@ -262,7 +262,7 @@ public class BinaryMapTransportReaderAdapter {
int cbottom = 0;
req.numberOfReadSubtrees++;
while(true){
if(req.isInterrupted()){
if(req.isCancelled()){
return;
}
int t = codedIS.readTag();
@ -300,13 +300,12 @@ public class BinaryMapTransportReaderAdapter {
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
if(lastIndexResult == -1){
lastIndexResult = req.searchResults.size();
lastIndexResult = req.getSearchResults().size();
}
req.numberOfVisitedObjects++;
TransportStop transportStop = readTransportStop(stopOffset, cleft, cright, ctop, cbottom, req);
if(transportStop != null){
req.searchResults.add(transportStop);
req.publish(transportStop);
}
codedIS.popLimit(oldLimit);
break;
@ -314,7 +313,7 @@ public class BinaryMapTransportReaderAdapter {
// left, ... already initialized
length = readInt();
int filePointer = codedIS.getTotalBytesRead();
if (req.limit == -1 || req.limit >= req.searchResults.size()) {
if (req.limit == -1 || req.limit >= req.getSearchResults().size()) {
oldLimit = codedIS.pushLimit(length);
searchTransportTreeBounds(cleft, cright, ctop, cbottom, req);
codedIS.popLimit(oldLimit);
@ -328,8 +327,8 @@ public class BinaryMapTransportReaderAdapter {
case OsmandOdb.TransportStopsTree.BASEID_FIELD_NUMBER :
long baseId = codedIS.readUInt64();
if (lastIndexResult != -1) {
for (int i = lastIndexResult; i < req.searchResults.size(); i++) {
TransportStop rs = req.searchResults.get(i);
for (int i = lastIndexResult; i < req.getSearchResults().size(); i++) {
TransportStop rs = req.getSearchResults().get(i);
rs.setId(rs.getId() + baseId);
}
}

View file

@ -18,8 +18,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import net.osmand.Algoritms;
@ -49,6 +51,7 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
private static final int ZOOM_TO_SAVE_START = 6;
private static final int ZOOM_TO_WRITE_CATEGORIES_START = 12;
private static final int ZOOM_TO_WRITE_CATEGORIES_END = 16;
private static final int CHARACTERS_TO_BUILD = 4;
private boolean useInMemoryCreator = true;
@ -193,7 +196,7 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
Collator collator = Collator.getInstance();
collator.setStrength(Collator.PRIMARY);
Map<String, List<PoiTileBox>> namesIndex = new LinkedHashMap<String, List<PoiTileBox>>();
Map<String, Set<PoiTileBox>> namesIndex = new TreeMap<String, Set<PoiTileBox>>();
// 0. process all entities
ResultSet rs;
@ -289,7 +292,8 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
Map<String, Integer> catIndexes = writer.writePOICategoriesTable(categories);
// 2.5 write names table
Map<PoiTileBox, TLongList> fpToWriteSeeks = writer.writePoiNameIndex(namesIndex, startFpPoiIndex);
//Map<PoiTileBox, TLongList> fpToWriteSeeks = new LinkedHashMap<PoiTileBox, TLongList>();
Map<PoiTileBox, TLongList> fpToWriteSeeks = writer.writePoiNameIndex(namesIndex);
// 3. write boxes
log.info("Poi box processing finishied");
@ -375,7 +379,7 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
}
public void addNamePrefix(String name, String nameEn, PoiTileBox data, Map<String, List<PoiTileBox>> poiData) {
public void addNamePrefix(String name, String nameEn, PoiTileBox data, Map<String, Set<PoiTileBox>> poiData) {
if(Algoritms.isEmpty(nameEn)){
nameEn = Junidecode.unidecode(name);
}
@ -383,19 +387,19 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
parsePrefix(nameEn, data, poiData);
}
private void parsePrefix(String name, PoiTileBox data, Map<String, List<PoiTileBox>> poiData) {
private void parsePrefix(String name, PoiTileBox data, Map<String, Set<PoiTileBox>> poiData) {
int prev = -1;
for (int i = 0; i <= name.length(); i++) {
if (i == name.length() || (!Character.isLetter(name.charAt(i)) &&
!Character.isDigit(name.charAt(i)))) {
if (prev != -1) {
String substr = name.substring(prev, i);
if (substr.length() > 3) {
substr = substr.substring(0, 3);
if (substr.length() > CHARACTERS_TO_BUILD) {
substr = substr.substring(0, CHARACTERS_TO_BUILD);
}
String val = substr.toLowerCase();
if(!poiData.containsKey(val)){
poiData.put(val, new ArrayList<PoiTileBox>());
poiData.put(val, new LinkedHashSet<PoiTileBox>());
}
poiData.get(val).add(data);
prev = -1;
@ -554,13 +558,14 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
// TODO support multiple reading amenity types! +/-
// TODO support proper POI editing
// TODO support string trigramms
// TODO support cancelling poi search request! Do it in another thread
// TODO support cancelling poi search request! Do it in another thread (Check is cancelled()!!!)
// TODO support fully functional indexed string table and pass name matcher
long time = System.currentTimeMillis();
IndexPoiCreator poiCreator = new IndexPoiCreator();
String fileSqlte = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.odb";
String outFile = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.obf";
// String fileSqlte = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Netherlands_europe.poi.odb";
// String outFile = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Netherlands.poi.obf";
// String fileSqlte = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.odb";
// String outFile = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.obf";
String fileSqlte = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Netherlands_europe.poi.odb";
String outFile = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Netherlands.poi.obf";
poiCreator.poiConnection = (Connection) DBDialect.SQLITE.getDatabaseConnection(
fileSqlte, log);

View file

@ -15,6 +15,7 @@ import net.osmand.LogUtil;
import net.osmand.binary.BinaryMapDataObject;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
import net.osmand.binary.BinaryMapIndexReader.SearchFilter;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
import net.osmand.osm.LatLon;
@ -66,10 +67,7 @@ public class BinaryRoutePlanner {
long now = System.nanoTime();
int zoomToLoad = 31 - ctx.getZoomToLoadTileWithRoads();
SearchRequest<BinaryMapDataObject> request = BinaryMapIndexReader.buildSearchRequest(tileX << zoomToLoad,
(tileX + 1) << zoomToLoad, tileY << zoomToLoad,
(tileY + 1) << zoomToLoad, 15);
request.setSearchFilter(new BinaryMapIndexReader.SearchFilter(){
SearchFilter searchFilter = new BinaryMapIndexReader.SearchFilter(){
@Override
public boolean accept(TIntArrayList types, MapIndex index) {
for (int j = 0; j < types.size(); j++) {
@ -90,7 +88,10 @@ public class BinaryRoutePlanner {
}
return false;
}
});
};
SearchRequest<BinaryMapDataObject> request = BinaryMapIndexReader.buildSearchRequest(tileX << zoomToLoad,
(tileX + 1) << zoomToLoad, tileY << zoomToLoad,
(tileY + 1) << zoomToLoad, 15, searchFilter);
for (BinaryMapIndexReader r : map) {
r.searchMapIndex(request);
for (BinaryMapDataObject o : request.getSearchResults()) {

View file

@ -50,9 +50,8 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
public List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom,
final PoiFilter filter, final List<Amenity> amenities) {
long now = System.currentTimeMillis();
int limit = zoom > 0 ? 200 : -1;
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(sleft, sright, stop, sbottom, zoom, limit);
req.setPoiTypeFilter(new SearchPoiTypeFilter(){
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(sleft, sright, stop, sbottom, zoom,
new SearchPoiTypeFilter(){
@Override
public boolean accept(AmenityType type, String subcategory) {
return filter.acceptTypeSubtype(type, subcategory);

View file

@ -116,7 +116,7 @@ public class CollatorStringMatcher implements StringMatcher {
}
if (checkSpaces) {
for (int i = 1; i <= searchInLength - startLength; i++) {
if (Character.isSpace(searchIn.charAt(i - 1)) && !Character.isSpace(searchIn.charAt(i))) {
if (considerAsSpace(searchIn.charAt(i - 1)) && !considerAsSpace(searchIn.charAt(i))) {
if (collator.equals(searchIn.substring(i, i + startLength), theStart)) {
return true;
}
@ -125,4 +125,8 @@ public class CollatorStringMatcher implements StringMatcher {
}
return false;
}
private static boolean considerAsSpace(char c){
return !Character.isLetter(c) && !Character.isDigit(c);
}
}

View file

@ -54,7 +54,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
public synchronized void preloadCities(ResultMatcher<MapObject> resultMatcher) {
if (cities.isEmpty()) {
try {
List<City> cs = file.getCities(region, resultMatcher);
List<City> cs = file.getCities(region, BinaryMapIndexReader.buildAddressRequest(resultMatcher));
for (City c : cs) {
cities.put(c.getId(), c);
}
@ -67,7 +67,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
public synchronized void preloadBuildings(Street street, ResultMatcher<Building> resultMatcher) {
if(street.getBuildings().isEmpty()){
try {
file.preloadBuildings(street, resultMatcher);
file.preloadBuildings(street, BinaryMapIndexReader.buildAddressRequest(resultMatcher));
street.sortBuildings();
} catch (IOException e) {
log.error("Disk operation failed" , e); //$NON-NLS-1$
@ -92,9 +92,9 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
}
try {
if(o instanceof PostCode){
file.preloadStreets((PostCode) o, resultMatcher);
file.preloadStreets((PostCode) o, BinaryMapIndexReader.buildAddressRequest(resultMatcher));
} else {
file.preloadStreets((City) o, resultMatcher);
file.preloadStreets((City) o, BinaryMapIndexReader.buildAddressRequest(resultMatcher));
}
} catch (IOException e) {
log.error("Disk operation failed" , e); //$NON-NLS-1$
@ -162,8 +162,8 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
if (name.length() >= 2 && Algoritms.containsDigit(name)) {
// also try to identify postcodes
String uName = name.toUpperCase();
for (PostCode code : file.getPostcodes(region, resultMatcher, new CollatorStringMatcher(collator, uName,
StringMatcherMode.CHECK_CONTAINS))) {
for (PostCode code : file.getPostcodes(region, BinaryMapIndexReader.buildAddressRequest(resultMatcher),
new CollatorStringMatcher(collator, uName, StringMatcherMode.CHECK_CONTAINS))) {
citiesToFill.add(code);
if (resultMatcher.isCancelled()) {
return citiesToFill;
@ -186,8 +186,8 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
int initialsize = citiesToFill.size();
if (name.length() >= 3) {
for (City c : file.getVillages(region, resultMatcher, new CollatorStringMatcher(collator, name,
StringMatcherMode.CHECK_STARTS_FROM_SPACE), useEnglishNames)) {
for (City c : file.getVillages(region, BinaryMapIndexReader.buildAddressRequest(resultMatcher),
new CollatorStringMatcher(collator, name,StringMatcherMode.CHECK_STARTS_FROM_SPACE), useEnglishNames)) {
citiesToFill.add(c);
if (resultMatcher.isCancelled()) {
return citiesToFill;
@ -267,7 +267,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
preloadCities(null);
if (!cities.containsKey(id)) {
try {
file.getVillages(region, new ResultMatcher<MapObject>() {
file.getVillages(region, BinaryMapIndexReader.buildAddressRequest(new ResultMatcher<MapObject>() {
boolean canceled = false;
@Override
@ -282,7 +282,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
}
return false;
}
}, null, useEnglishNames);
}), null, useEnglishNames);
} catch (IOException e) {
log.error("Disk operation failed", e); //$NON-NLS-1$
}

View file

@ -239,28 +239,28 @@ public class MapRenderRepositories {
int rightX = MapUtils.get31TileNumberX(cRightLongitude);
int bottomY = MapUtils.get31TileNumberY(cBottomLatitude);
int topY = MapUtils.get31TileNumberY(cTopLatitude);
searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom);
if (zoom < 17) {
searchRequest.setSearchFilter(new BinaryMapIndexReader.SearchFilter() {
BinaryMapIndexReader.SearchFilter searchFilter = new BinaryMapIndexReader.SearchFilter() {
@Override
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex root) {
for (int j = 0; j < types.size(); j++) {
int type = types.get(j);
int mask = type & 3;
TagValuePair pair = root.decodeType(type);
if (pair != null && renderingType.isObjectVisible(pair.tag, pair.value, zoom, mask, nightMode)) {
return true;
}
if(pair != null && mask == OsmandRenderingRulesParser.POINT_STATE &&
renderingType.isObjectVisible(pair.tag, pair.value, zoom, OsmandRenderingRulesParser.TEXT_STATE, nightMode)){
return true;
}
@Override
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex root) {
for (int j = 0; j < types.size(); j++) {
int type = types.get(j);
int mask = type & 3;
TagValuePair pair = root.decodeType(type);
if (pair != null && renderingType.isObjectVisible(pair.tag, pair.value, zoom, mask, nightMode)) {
return true;
}
if(pair != null && mask == OsmandRenderingRulesParser.POINT_STATE &&
renderingType.isObjectVisible(pair.tag, pair.value, zoom, OsmandRenderingRulesParser.TEXT_STATE, nightMode)){
return true;
}
return false;
}
return false;
}
});
};
if (zoom > 17) {
searchFilter = null;
}
// search lower level zooms only in basemap for now :) before it was intersection of maps on zooms 5-7
boolean basemapSearch = false;
@ -278,10 +278,8 @@ public class MapRenderRepositories {
continue;
}
BinaryMapIndexReader c = files.get(mapName);
searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom, null);
List<BinaryMapDataObject> res = c.searchMapIndex(searchRequest);
if (checkWhetherInterrupted()) {
return false;
}
for (BinaryMapDataObject r : res) {
if (PerformanceFlags.checkForDuplicateObjectIds) {
if (ids.contains(r.getId())) {
@ -306,14 +304,11 @@ public class MapRenderRepositories {
}
}
}
if (checkWhetherInterrupted()) {
return false;
}
tempList.add(r);
}
searchRequest.clearSearchResults();
}
List<MultyPolygon> pMulti = proccessMultiPolygons(multiPolygons, leftX, rightX, bottomY, topY, zoom);