Skip to content

Commit e51715a

Browse files
authored
Merge branch 'osmandapp:master' into hardy_Afa+searchprio
2 parents c571533 + 0e734a0 commit e51715a

26 files changed

Lines changed: 437 additions & 124 deletions

OsmAnd-java/src/main/java/net/osmand/search/core/spatial/SpatialPoiSearch.java

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import java.io.IOException;
44
import java.util.ArrayList;
55
import java.util.Collections;
6+
import java.util.Iterator;
67
import java.util.LinkedHashMap;
8+
import java.util.LinkedList;
79
import java.util.List;
810
import java.util.Map;
911
import java.util.concurrent.ConcurrentHashMap;
@@ -66,6 +68,21 @@ public SpatialPoiType(String additional, String key, int id) {
6668
this.id = id;
6769
this.poiAdditional = additional;
6870
}
71+
72+
public boolean accept(Amenity a) {
73+
if (key.equals(a.getType().getKeyName())) {
74+
return true;
75+
}
76+
// contains for ';'
77+
boolean multi = a.getSubType().indexOf(';') != -1;
78+
if (key.equals(a.getSubType())
79+
|| (multi && key.startsWith(a.getSubType() + ";"))
80+
|| (multi && key.endsWith(";" + a.getSubType()))
81+
|| (multi && key.contains(";" + a.getSubType() + ";"))) {
82+
return true;
83+
}
84+
return false;
85+
}
6986

7087
}
7188

@@ -288,6 +305,21 @@ public SpatialPoiType getByKey(String key) {
288305
}
289306

290307

308+
private List<BinaryMapIndexReader> filterByRadius(LatLon l, int rad, List<BinaryMapIndexReader> oFiles,
309+
List<BinaryMapIndexReader> res) {
310+
QuadRect rect = MapUtils.calculateBbox(rad, l);
311+
Iterator<BinaryMapIndexReader> it = oFiles.iterator();
312+
while (it.hasNext()) {
313+
BinaryMapIndexReader next = it.next();
314+
if (next.containsPoiData((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom)) {
315+
res.add(next);
316+
it.remove();
317+
}
318+
}
319+
return res;
320+
}
321+
322+
291323
public List<Amenity> loadPOIObjects(SpatialSearchContext ctx, long id, LatLon latLon, int radMeters, int limit)
292324
throws IOException {
293325
final SpatialPoiType spt = byId.get((int) id);
@@ -356,7 +388,8 @@ public boolean publish(Amenity object) {
356388

357389
@Override
358390
public boolean isCancelled() {
359-
return alimit[0] == 0;
391+
return false; // allow to read all for proper sorting
392+
// return alimit[0] == 0;
360393
}
361394
};
362395
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(
@@ -366,16 +399,29 @@ public boolean isCancelled() {
366399
req = BinaryMapIndexReader.buildSearchPoiRequest((int) qr.left, (int) qr.right, (int) qr.top,
367400
(int) qr.bottom, -1, typeFilter, addFilter, matcher);
368401
}
369-
for (BinaryMapIndexReader bir : ctx.files) {
370-
ctx.stats.poiByTypeTime.start();
371-
long br = bir.getBytesRead();
372-
bir.searchPoi(req);
373-
ctx.stats.poiByTypeBytes += (bir.getBytesRead() - br);
374-
ctx.stats.poiByTypeTime.finish();
375-
ctx.stats.poiByTypeBboxes += req.numberOfReadSubtrees;
402+
List<BinaryMapIndexReader> oFiles = new LinkedList<BinaryMapIndexReader>(ctx.files);
403+
iterateSearch(ctx, req, filterByRadius(latLon, 5_000, oFiles, new ArrayList<BinaryMapIndexReader>()));
404+
if (alimit[0] != 0 && radMeters > 5_000) {
405+
iterateSearch(ctx, req, filterByRadius(latLon, 50_000, oFiles, new ArrayList<BinaryMapIndexReader>()));
406+
}
407+
if (alimit[0] != 0 && radMeters > 50_000) {
408+
iterateSearch(ctx, req, oFiles);
376409
}
377410
}
378411
return results;
379412
}
380413

414+
415+
private void iterateSearch(SpatialSearchContext ctx, SearchRequest<Amenity> req, List<BinaryMapIndexReader> res)
416+
throws IOException {
417+
for (BinaryMapIndexReader bir : res) {
418+
ctx.stats.poiByTypeTime.start();
419+
long br = bir.getBytesRead();
420+
bir.searchPoi(req);
421+
ctx.stats.poiByTypeBytes += (bir.getBytesRead() - br);
422+
ctx.stats.poiByTypeTime.finish();
423+
ctx.stats.poiByTypeBboxes += req.numberOfReadSubtrees;
424+
}
425+
}
426+
381427
}

OsmAnd-java/src/main/java/net/osmand/search/core/spatial/SpatialSearchResultsList.java

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import net.osmand.data.MapObject;
2626
import net.osmand.data.Street;
2727
import net.osmand.search.core.HashQuadTree;
28+
import net.osmand.search.core.spatial.SpatialPoiSearch.SpatialPoiType;
2829
import net.osmand.search.core.spatial.SpatialSearchToken.NameIndexAtom;
2930
import net.osmand.search.core.spatial.SpatialTextSearch.SpatialTextSearchSettings;
3031
import net.osmand.util.MapUtils;
@@ -145,6 +146,16 @@ public List<SpatialSearchToken> getMissingTokens(SpatialSearchContext ctx) {
145146
public void loadObjectsAndCalcBuildings(SpatialSearchContext ctx) throws IOException {
146147
ctx.stats.sub2LoadObjectsBldTime.start();
147148
loadObjects(ctx);
149+
// calculate amenity type
150+
for (int indx = 0; indx < getCombinations(); indx++) {
151+
if (skipResults.contains(indx)) {
152+
continue;
153+
}
154+
boolean skip = checkAmenityType(ctx, indx);
155+
if (!skip) {
156+
skipResults.put(indx, true);
157+
}
158+
}
148159

149160
if (ctx.settings.SEARCH_BUILDINGS) {
150161
Map<String, Building> bldCheckCache = new HashMap<>();
@@ -167,6 +178,50 @@ public void loadObjectsAndCalcBuildings(SpatialSearchContext ctx) throws IOExcep
167178

168179
ctx.stats.sub2LoadObjectsBldTime.finish();
169180
}
181+
182+
private boolean checkAmenityType(SpatialSearchContext ctx, int indx) {
183+
SpatialPoiType type = null;
184+
for (int i = 0; i < tCount; i++) {
185+
NameIndexAtom atom = linearResults.get(indx * tCount + i);
186+
if (atom.isPoiCategory()) {
187+
type = ctx.poiSearch.getById((int) atom.id);
188+
break;
189+
}
190+
}
191+
if (type == null) {
192+
return true;
193+
}
194+
for (int i = 0; i < tCount; i++) {
195+
NameIndexAtom atom = linearResults.get(indx * tCount + i);
196+
if (atom.object instanceof Amenity a) {
197+
boolean matched = type.accept(a);
198+
if (!matched) {
199+
return false;
200+
}
201+
// old logic for missing tokens
202+
// for (SpatialSearchToken st : missingTokens) {
203+
// if (st.hasPoiType(a.getType().getKeyName(), ctx.poiSearch) != null
204+
// || st.hasPoiType(a.getSubType(), ctx.poiSearch) != null) {
205+
// matched = true;
206+
// break;
207+
// }
208+
// if (a.getSubType().indexOf(';') != -1) {
209+
// for (String subtStr : a.getSubType().split(";")) {
210+
// if (st.hasPoiType(subtStr, ctx.poiSearch) != null) {
211+
// matched = true;
212+
// break;
213+
// }
214+
// }
215+
// }
216+
// }
217+
// if (matched) {
218+
// atom.otherWordsCnt = -1; // could be added to surplusWords later
219+
// break;
220+
// }
221+
}
222+
}
223+
return true;
224+
}
170225

171226
private void calcStreetIntersections(SpatialSearchContext ctx, int indx) {
172227
NameIndexAtom first = null;
@@ -673,13 +728,15 @@ private boolean acceptIntersection(SpatialSearchContext ctx, SpatialSearchResul
673728
} else if ((a.buildingInd >= 0) && pa.isStreetBuilding() && !a.isCityStreetName()) {
674729
return false;
675730
}
676-
// if poi doesn't have bbox don't intersect or add bbox!
677-
if ((pa.buildingInd >= 0) && a.isPOI() && a.coords.bbox31 == null) {
678-
return false;
679-
} else if ((a.buildingInd >= 0) && pa.isPOI() && pa.coords.bbox31 == null) {
680-
return false;
731+
// if poi doesn't have bbox don't intersect or add bbox! (transport stops take street names)
732+
if (!ctx.settings.TEST_ALLOW_HOUSE_POI_TYPE_INTERSECTION) {
733+
if ((pa.buildingInd >= 0) && a.isPOI() && a.coords.bbox31 == null) {
734+
return false;
735+
} else if ((a.buildingInd >= 0) && pa.isPOI() && pa.coords.bbox31 == null) {
736+
return false;
737+
}
681738
}
682-
739+
//
683740
}
684741
// 2. Duplicate words in query
685742
for (int i = 0; parent != null && i < parent.tCount; i++) {
@@ -721,6 +778,7 @@ private boolean acceptIntersection(SpatialSearchContext ctx, SpatialSearchResul
721778
atomObjs.put(a.id, a);
722779
}
723780
NameIndexAtom poiType = a.isPoiCategory() ? a : null;
781+
SpatialSearchToken poiTypeToken = tokens[0];
724782
for (int i = 0; parent != null && i < parent.tCount; i++) {
725783
NameIndexAtom pa = parent.linearResults.get(pindx * parent.tCount + i);
726784
if (pa.id == a.id) {
@@ -729,6 +787,7 @@ private boolean acceptIntersection(SpatialSearchContext ctx, SpatialSearchResul
729787
if (pa.isPoiCategory()) {
730788
if (poiType == null || pa.id == a.id) {
731789
poiType = pa;
790+
poiTypeToken = parent.tokens[i];
732791
} else {
733792
// no 2 poi categories
734793
return false;
@@ -758,8 +817,15 @@ private boolean acceptIntersection(SpatialSearchContext ctx, SpatialSearchResul
758817
// return false;
759818
// }
760819
}
820+
// investigate to find types
761821
if (poiType != null && atomObjs.size() > 0) {
762-
return false;
822+
NameIndexAtom p = atomObjs.values().iterator().next();
823+
if (poiTypeToken.incomplete) {
824+
return false;
825+
}
826+
if (!p.isPOI()) {
827+
return false;
828+
}
763829
}
764830
if (atomObjs.size() > 1) {
765831
Iterator<NameIndexAtom> it = atomObjs.values().iterator();

OsmAnd-java/src/main/java/net/osmand/search/core/spatial/SpatialSearchTestAndDocs.java

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,24 @@
3737
// TESTING delete default enlarge and enlarge data
3838
// TESTING Venezia city Street / Place - <City Street> ('<Salt Lake City>') with Street ('Pennsylvania street')
3939
// TESTING find check that token is reused in parent - and ignore intersection for complete mattch
40-
// TESTING TODO WEB ! POI Categories + top poi categories !! RZR
4140
// TESTING POI CATEGORY Specific Healthcare specialties (Vegan) - https://github.com/osmandapp/OsmAnd/issues/24941
4241
// TESTING BUG: numbers obj- filter cafe & rest + incorrect PrivatBank counts
43-
// TESTING: check additional filter not stored old
42+
// TESTING check additional filter not stored old
43+
// TESTING Sort maps poi categories API search (sort bboxes?)
44+
// TESTING query = "Church Catedral-Basílica de Nuestra Señora del Pilar"; - POI_TYPE /\ POI (SYNONYMS!)
45+
// TEST_ALLOW_HOUSE_POI_TYPE_INTERSECTION Review if poi doesn't have bbox don't intersect or add bbox! - Shell 2 Rožňavská (test)
4446

4547
////////// IN PROGRESS //////////
4648

47-
// TODO POI: Sort maps poi categories API search (sort bboxes?)
48-
49-
// TODO POI Categories translations / synonyms (WEB) - Стоматол., Dentist, Stomatology
50-
// TODO query = "Catedral-Basílica de Nuestra Señora del Pilar"; - POI_TYPE /\ POI
51-
// TODO Review if poi doesn't have bbox don't intersect or add bbox! - Shell 2 Rožňavská
52-
53-
// TODO INSPECTOR stats index_words_dashboard.html
49+
// INSPECTOR stats index_words_dashboard.html
5450

5551
// TO DO Ivan / Gateway
5652
// TODO DEDUPLICATE: Review / implement similarity radius - similarityRadius = 50000 ... Route Id
5753
// TODO DEDUPLICATE: Unite RouteArticle, POI by wikidata id ? - DEPTH_TO_CHECK_SAME_SEARCH_RESULTS = 20;...
5854
// TODO DEDUPLICATE: Venezia ? - No place=city in POI is it on purpose ? 2 Wikidataids! Rating not merged. POI - relation/44741 (Q641), CITY - way/64778090 (Q33723961).
5955
// TODO DEDUPLICATE: review osm route id combine by?
6056
// TODO DEDUPLICATE: Index place=state, county.. + wikidata id for boundaries (regions.ocbf) & display them - analyze
61-
// TODO DEDUPLICATE: Test wiki / travel maps, seamarks map
57+
// TODO DEDUPLICATE: Test wiki / travel maps / seamarks map
6258
// TODO DEDUPLICATE: same location (5-10m) 2 streets different cities
6359
// TODO DEDUPLICATE: brand langs - 'Поїхали з нами' / 'Поехали с нами'
6460
// TODO UNIT TESTS: (duplicate words), Бульварно-Кудрявська, NC-42, 2-га Нова (2 Нова), M2...
@@ -68,21 +64,24 @@
6864
// TODO INSPECTOR : doesn't show suffixes
6965

7066
// LARGE IMPORTANT TASKS
71-
// TODO ANALYZE: find slow queries on Autotests
67+
// TODO INDEX: Speedup load after sorting - to limit objects (store elo in index)!
68+
// TODO INDEX: Store Poi category index (effective intersection 'Church St. Miguel' - refactor checkAmenity)
69+
// TODO INDEX: Find POI Categories translations / synonyms (WEB) - Стоматол., Dentist, Stomatology, Basilica (?)
70+
// TODO ANALYZE: BUG - Germany POI words - . (115,158, 115,158), und (97,839, 97,839), - not common? - bach (56,475, 56,475) - could be common?
7271
// TODO ANALYZE: too many wiki places on streets?
73-
// TODO ANALYZE: Germany POI words - . (115,158, 115,158), und (97,839, 97,839), - not common? - bach (56,475, 56,475) - could be common?
74-
// TODO POI CATEGORY Bboxes too large - test size OsmAndPoiNameIndexDataAtom, quad tree (90% < 10K) add rare categories
75-
// TODO ANALYZE: Large Geo atoms "Berlin"
72+
// TODO ANALYZE: find slow queries on Autotests
73+
// TODO ANALYZE: Large Geo atoms "Berlin" (Slow query)
7674

7775
// TO DO - RZR
78-
// TODO WEB PRODUCTION: display results std way: house, interpolation results, poi...
79-
// TODO WEB Production: Multithread pool, Monitor / time & memory optimize memory?
76+
// TODO WEB: POI Categories + top poi categories
77+
// TODO WEB: display results std way: house, interpolation results, poi...
78+
// TODO WEB: Multithread pool, Monitor / time & memory optimize memory?
8079
// TODO ANDROID: Integrate (include regions.ocbf) on client
8180
// TODO ANDROID: Progress / cancel
8281
// TODO ANDROID: memory performance
83-
//
84-
82+
8583
/////////////// EXTRA FEATURES ///////////////
84+
// TODO OBF POI CATEGORY Bboxes too large - investigate size (introduce for categories OBF) - OsmAndPoiNameIndexDataAtom, quad tree (90% < 10K)
8685
// TODO Review Abbrevations (synonyms / direction words) other languages?
8786
// TODO Store and test conscription number for some cities - issue (RZR)
8887
// TODO Search in large parks, neighborhood same as in boundaries (index bbox POI), residential way/56238205
@@ -168,6 +167,7 @@ public static void main(String[] args) throws IOException, InterruptedException
168167
// pattern = "Map";
169168
String pattern2 = ".....";
170169
String query = "Berlin hauptstrasse"; // slow
170+
query = "Berlin";
171171
// query = "Kelterstraße Kernen im Remstal";
172172
// query = "Germany Kelter. Kernen im Remstal";
173173
// query = "3 Hofäckerstraße Kernen im Remstal";
@@ -272,19 +272,18 @@ public static void main(String[] args) throws IOException, InterruptedException
272272

273273
// pattern = "regions.ocbf" ;
274274

275-
pattern = "Ukraine_kyiv-city";
275+
// pattern = "Ukraine_kyiv-city";
276276
// pattern = "Test_Ukraine_kyiv-city_europe_12.obf";
277-
// pattern = "Ukraine_";
277+
pattern = "Ukraine_";
278278
// poi types
279279
// location = new LatLon(50.439, 30.516);
280-
settings.SEARCH_POI = false;
281-
settings.DEV_PRINT_POI_CAT_LIMIT = 100000;
282-
settings.DEV_PRINT_POI_CAT_RADIUS_KM = 1000;
283-
query = "п.";
284-
query = "New york.";
280+
// settings.SEARCH_POI = false;
281+
// settings.DEV_PRINT_POI_CAT_LIMIT = 1000;
282+
// settings.DEV_PRINT_POI_CAT_RADIUS_KM = 10;
283+
// query = "при.";
285284
// query = "Cafe";
286285
// query = "Aquarium.";
287-
// query = "Vegeterian";
286+
// query = "Veget.";
288287
// query = "Mcdonald's";
289288
// query = "Stomat.";
290289

@@ -332,6 +331,7 @@ public static void main(String[] args) throws IOException, InterruptedException
332331
// pattern = "Slovakia";
333332
// query = "Bratislava Billa";
334333
// settings.DEDUPLICATE_RES = false;
334+
// settings.TEST_ALLOW_HOUSE_POI_TYPE_INTERSECTION = false;
335335
// query = "Shell 2 Rožňavská";
336336

337337
// pattern = "Us_new-york_new"; // new-york, new-jersey
@@ -389,9 +389,10 @@ public static void main(String[] args) throws IOException, InterruptedException
389389
// query = "Венец.";
390390

391391
// pattern = "Spain_aragon_europe_";
392-
// query = "Basílica de Nuestra Señora del Pilar";
392+
// query = "Church Basílica de Nuestra Señora del Pilar"; // Church vs Roman Church
393393
// query = "Catedral-Basílica de Nuestra Señora del Pilar"; // 7 words! 2^7 combinations
394-
394+
// query = "Square de Nuestra Señora del Pilar"; // Church vs Square
395+
//
395396
// pattern = "Peru_";
396397
// query ="Calle 20 188 San Isidro Lima"; // 1430799557
397398
// query ="Lima Calle 20 San Isidro";
@@ -414,7 +415,7 @@ public static void main(String[] args) throws IOException, InterruptedException
414415
// settings.DEDUPLICATE_RES = false;
415416
SpatialPoiSearch poiSearch = new SpatialPoiSearch(MapPoiTypes.getDefault());
416417
SpatialSearchContext searchContext = new SpatialSearchContext(settings, ls, poiSearch, location);
417-
SpatialSearchResults rs = a.searchTest(query, searchContext, 10);
418+
SpatialSearchResults rs = a.searchTest(query, searchContext, 10000);
418419
SpatialSearchResult mainResult = rs.getFirstResult();
419420
if (mainResult != null && mainResult.matchedTokens() < rs.tokens.size() - 2) {
420421
// another way to check to check to get mainResult - boundary object

0 commit comments

Comments
 (0)