Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2016-08-05 13:44:35 +02:00
commit 290caa6ee6
4 changed files with 249 additions and 177 deletions

View file

@ -1,4 +1,14 @@
package net.osmand.search; package net.osmand.search;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import net.osmand.Collator; import net.osmand.Collator;
import net.osmand.OsmAndCollator; import net.osmand.OsmAndCollator;
@ -25,23 +35,12 @@ import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class SearchUICore { public class SearchUICore {
private static final int TIMEOUT_BETWEEN_CHARS = 200; private static final int TIMEOUT_BETWEEN_CHARS = 200;
private static final Log LOG = PlatformUtil.getLog(SearchUICore.class); private static final Log LOG = PlatformUtil.getLog(SearchUICore.class);
private SearchPhrase phrase; private SearchPhrase phrase;
private SearchResultCollection currentSearchResult = new SearchResultCollection(); private SearchResultCollection currentSearchResult;
private ThreadPoolExecutor singleThreadedExecutor; private ThreadPoolExecutor singleThreadedExecutor;
private LinkedBlockingQueue<Runnable> taskQueue; private LinkedBlockingQueue<Runnable> taskQueue;
@ -52,7 +51,6 @@ public class SearchUICore {
List<SearchCoreAPI> apis = new ArrayList<>(); List<SearchCoreAPI> apis = new ArrayList<>();
private SearchSettings searchSettings; private SearchSettings searchSettings;
private MapPoiTypes poiTypes; private MapPoiTypes poiTypes;
private Collator collator;
public SearchUICore(MapPoiTypes poiTypes, String locale) { public SearchUICore(MapPoiTypes poiTypes, String locale) {
@ -60,31 +58,146 @@ public class SearchUICore {
taskQueue = new LinkedBlockingQueue<Runnable>(); taskQueue = new LinkedBlockingQueue<Runnable>();
searchSettings = new SearchSettings(new ArrayList<BinaryMapIndexReader>()); searchSettings = new SearchSettings(new ArrayList<BinaryMapIndexReader>());
searchSettings = searchSettings.setLang(locale); searchSettings = searchSettings.setLang(locale);
phrase = new SearchPhrase(searchSettings); phrase = new SearchPhrase(searchSettings, OsmAndCollator.primaryCollator());
currentSearchResult = new SearchResultCollection(phrase);
singleThreadedExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, taskQueue); singleThreadedExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, taskQueue);
collator = OsmAndCollator.primaryCollator();
} }
public static class SearchResultCollection { public static class SearchResultCollection {
private List<SearchResult> searchResults; private List<SearchResult> searchResults;
private SearchPhrase phrase; private SearchPhrase phrase;
public SearchResultCollection(List<SearchResult> requestResults, SearchPhrase phrase) { public SearchResultCollection(SearchPhrase phrase) {
searchResults = requestResults; searchResults = new ArrayList<>();
this.phrase = phrase; this.phrase = phrase;
} }
public SearchResultCollection() { public SearchResultCollection combineWithCollection(SearchResultCollection collection, boolean resort, boolean removeDuplicates) {
searchResults = new ArrayList<>(); SearchResultCollection src = new SearchResultCollection(phrase);
src.addSearchResults(searchResults, false, false);
src.addSearchResults(collection.searchResults, resort, removeDuplicates);
return src;
} }
public void addSearchResults(List<SearchResult> sr, boolean resortAll, boolean removeDuplicates) {
if(resortAll) {
this.searchResults.addAll(sr);
sortSearchResults();
if(removeDuplicates) {
filterSearchDuplicateResults();
}
} else {
if(removeDuplicates) {
ArrayList<SearchResult> addedResults = new ArrayList<>(sr);
SearchResultComparator cmp = new SearchResultComparator(phrase);
Collections.sort(addedResults, cmp);
filterSearchDuplicateResults(addedResults);
int i = 0;
int j = 0;
while(j < addedResults.size()) {
SearchResult addedResult = addedResults.get(j);
if(i >= searchResults.size()) {
if(searchResults.size() == 0 ||
!sameSearchResult(addedResult, searchResults.get(searchResults.size() - 1))) {
searchResults.add(addedResult);
}
j++;
continue;
}
SearchResult existingResult = searchResults.get(i);
if(sameSearchResult(addedResult, existingResult)) {
j++;
continue;
}
int compare = cmp.compare(existingResult, addedResult);
if(compare == 0) {
// existingResult == addedResult
j++;
} else if(compare > 0) {
// existingResult > addedResult
this.searchResults.add(addedResults.get(j));
j++;
} else {
// existingResult < addedResult
i++;
}
}
}
}
}
public List<SearchResult> getCurrentSearchResults() { public List<SearchResult> getCurrentSearchResults() {
return searchResults; return Collections.unmodifiableList(searchResults);
} }
public SearchPhrase getPhrase() { public SearchPhrase getPhrase() {
return phrase; return phrase;
} }
public void sortSearchResults() {
Collections.sort(searchResults, new SearchResultComparator(phrase));
}
public void filterSearchDuplicateResults() {
filterSearchDuplicateResults(searchResults);
}
private void filterSearchDuplicateResults(List<SearchResult> lst) {
Iterator<SearchResult> it = lst.iterator();
SearchResult found = null;
while(it.hasNext()) {
SearchResult r = it.next();
if(found != null && sameSearchResult(found, r)) {
it.remove();
} else {
found = r;
}
}
}
public boolean sameSearchResult(SearchResult r1, SearchResult r2) {
if(r1.location != null && r2.location != null) {
Amenity a1 = null;
if(r1.object instanceof Amenity) {
a1 = (Amenity) r1.object;
}
Amenity a2 = null;
if(r2.object instanceof Amenity) {
a2 = (Amenity) r2.object;
}
if (r1.localeName.equals(r2.localeName)) {
double similarityRadius = 30;
if (a1 != null && a2 != null) {
// here 2 points are amenity
String type1 = a1.getType().getKeyName();
String type2 = a2.getType().getKeyName();
String subType1 = a1.getSubType();
String subType2 = a2.getSubType();
if (!type1.equals(type2)) {
return false;
}
if (type1.equals("natural")) {
similarityRadius = 10000;
} else if (subType1.equals(subType2)) {
if (subType1.contains("cn_ref") || subType1.contains("wn_ref")
|| (subType1.startsWith("route_hiking_") && subType1.endsWith("n_poi"))) {
similarityRadius = 10000;
}
}
} else if(ObjectType.isAddress(r1.objectType) && ObjectType.isAddress(r2.objectType)) {
similarityRadius = 100;
}
return MapUtils.getDistance(r1.location, r2.location) < similarityRadius;
}
}
return false;
}
} }
public void setPoiTypes(MapPoiTypes poiTypes) { public void setPoiTypes(MapPoiTypes poiTypes) {
@ -111,7 +224,6 @@ public class SearchUICore {
public <T extends SearchCoreAPI> SearchResultCollection shallowSearch(Class<T> cl, public <T extends SearchCoreAPI> SearchResultCollection shallowSearch(Class<T> cl,
String text, final ResultMatcher<SearchResult> matcher) throws IOException { String text, final ResultMatcher<SearchResult> matcher) throws IOException {
SearchResultCollection quickRes = new SearchResultCollection();
T api = getApiByClass(cl); T api = getApiByClass(cl);
if(api != null) { if(api != null) {
SearchPhrase sphrase = this.phrase.generateNewPhrase(text, searchSettings); SearchPhrase sphrase = this.phrase.generateNewPhrase(text, searchSettings);
@ -120,14 +232,13 @@ public class SearchUICore {
SearchResultMatcher rm = new SearchResultMatcher(matcher, ai.get(), ai, totalLimit); SearchResultMatcher rm = new SearchResultMatcher(matcher, ai.get(), ai, totalLimit);
api.search(sphrase, rm); api.search(sphrase, rm);
sortSearchResults(sphrase, rm.getRequestResults()); SearchResultCollection collection = new SearchResultCollection(
filterSearchDuplicateResults(sphrase, rm.getRequestResults());
LOG.info(">> Shallow Search phrase " + phrase + " " + rm.getRequestResults().size());
return new SearchResultCollection(rm.getRequestResults(),
sphrase); sphrase);
collection.addSearchResults(rm.getRequestResults(), true, true);
LOG.info(">> Shallow Search phrase " + phrase + " " + rm.getRequestResults().size());
return collection;
} }
return quickRes; return null;
} }
public void init() { public void init() {
@ -201,11 +312,10 @@ public class SearchUICore {
} }
public SearchResultCollection search(final String text, final ResultMatcher<SearchResult> matcher) { public SearchResultCollection search(final String text, final ResultMatcher<SearchResult> matcher) {
SearchResultCollection quickRes = new SearchResultCollection();
final int request = requestNumber.incrementAndGet(); final int request = requestNumber.incrementAndGet();
final SearchPhrase phrase = this.phrase.generateNewPhrase(text, searchSettings); final SearchPhrase phrase = this.phrase.generateNewPhrase(text, searchSettings);
this.phrase = phrase; this.phrase = phrase;
quickRes.phrase = phrase; SearchResultCollection quickRes = new SearchResultCollection(phrase);
filterCurrentResults(quickRes.searchResults, phrase); filterCurrentResults(quickRes.searchResults, phrase);
LOG.info("> Search phrase " + phrase + " " + quickRes.searchResults.size()); LOG.info("> Search phrase " + phrase + " " + quickRes.searchResults.size());
singleThreadedExecutor.submit(new Runnable() { singleThreadedExecutor.submit(new Runnable() {
@ -222,12 +332,11 @@ public class SearchUICore {
} }
searchInBackground(phrase, rm); searchInBackground(phrase, rm);
if (!rm.isCancelled()) { if (!rm.isCancelled()) {
sortSearchResults(phrase, rm.getRequestResults());
filterSearchDuplicateResults(phrase, rm.getRequestResults());
LOG.info(">> Search phrase " + phrase + " " + rm.getRequestResults().size()); SearchResultCollection collection = new SearchResultCollection(
SearchResultCollection collection = new SearchResultCollection(rm.getRequestResults(),
phrase); phrase);
collection.addSearchResults(rm.getRequestResults(), true, true);
LOG.info(">> Search phrase " + phrase + " " + rm.getRequestResults().size());
currentSearchResult = collection; currentSearchResult = collection;
if (onResultsComplete != null) { if (onResultsComplete != null) {
onResultsComplete.run(); onResultsComplete.run();
@ -267,6 +376,7 @@ public class SearchUICore {
} }
try { try {
api.search(phrase, matcher); api.search(phrase, matcher);
matcher.apiSearchFinished(api, phrase); matcher.apiSearchFinished(api, phrase);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@ -284,92 +394,10 @@ public class SearchUICore {
phrase.sortFiles(); phrase.sortFiles();
} }
public boolean sameSearchResult(SearchResult r1, SearchResult r2) {
if(r1.location != null && r2.location != null) {
Amenity a1 = null;
if(r1.object instanceof Amenity) {
a1 = (Amenity) r1.object;
}
Amenity a2 = null;
if(r2.object instanceof Amenity) {
a2 = (Amenity) r2.object;
}
if (r1.localeName.equals(r2.localeName)) {
double similarityRadius = 30;
if (a1 != null && a2 != null) {
// here 2 points are amenity
String type1 = a1.getType().getKeyName();
String type2 = a2.getType().getKeyName();
String subType1 = a1.getSubType();
String subType2 = a2.getSubType();
if (!type1.equals(type2)) {
return false;
}
if (type1.equals("natural")) {
similarityRadius = 10000;
} else if (subType1.equals(subType2)) {
if (subType1.contains("cn_ref") || subType1.contains("wn_ref")
|| (subType1.startsWith("route_hiking_") && subType1.endsWith("n_poi"))) {
similarityRadius = 10000;
}
}
} else if(ObjectType.isAddress(r1.objectType) && ObjectType.isAddress(r2.objectType)) {
similarityRadius = 100;
}
return MapUtils.getDistance(r1.location, r2.location) < similarityRadius;
}
}
return false;
}
public void filterSearchDuplicateResults(SearchPhrase sp, List<SearchResult> searchResults) {
Iterator<SearchResult> it = searchResults.iterator();
SearchResult found = null;
while(it.hasNext()) {
SearchResult r = it.next();
if(found != null && sameSearchResult(found, r)) {
it.remove();
} else {
found = r;
}
}
}
public void sortSearchResults(SearchPhrase sp, List<SearchResult> searchResults) {
// sort SearchResult by 1. searchDistance 2. Name
final LatLon loc = sp.getLastTokenLocation();
Collections.sort(searchResults, new Comparator<SearchResult>() {
@Override
public int compare(SearchResult o1, SearchResult o2) {
if(o1.getFoundWordCount() != o2.getFoundWordCount()) {
return -Algorithms.compare(o1.getFoundWordCount(), o2.getFoundWordCount());
}
double s1 = o1.getSearchDistance(loc);
double s2 = o2.getSearchDistance(loc);
int cmp = Double.compare(s1, s2);
if(cmp != 0) {
return cmp;
}
int st1 = Algorithms.extractFirstIntegerNumber(o1.localeName);
int st2 = Algorithms.extractFirstIntegerNumber(o2.localeName);
if(st1 != st2) {
return Algorithms.compare(st1, st2);
}
cmp = collator.compare(o1.localeName, o2.localeName);
if(cmp != 0) {
return cmp;
}
s1 = o1.getSearchDistance(loc, 1);
s2 = o2.getSearchDistance(loc, 1);
return Double.compare(s1, s2);
}
});
}
public static class SearchResultMatcher public static class SearchResultMatcher implements ResultMatcher<SearchResult>{
implements ResultMatcher<SearchResult>{
private final List<SearchResult> requestResults = new ArrayList<>(); private final List<SearchResult> requestResults = new ArrayList<>();
private final ResultMatcher<SearchResult> matcher; private final ResultMatcher<SearchResult> matcher;
private final int request; private final int request;
@ -439,5 +467,43 @@ public class SearchUICore {
boolean cancelled = request != requestNumber.get(); boolean cancelled = request != requestNumber.get();
return cancelled || (matcher != null && matcher.isCancelled()); return cancelled || (matcher != null && matcher.isCancelled());
} }
} }
public static class SearchResultComparator implements Comparator<SearchResult> {
private SearchPhrase sp;
private Collator collator;
private LatLon loc;
public SearchResultComparator(SearchPhrase sp) {
this.sp = sp;
this.collator = sp.getCollator();
loc = sp.getLastTokenLocation();
}
@Override
public int compare(SearchResult o1, SearchResult o2) {
if(o1.getFoundWordCount() != o2.getFoundWordCount()) {
return -Algorithms.compare(o1.getFoundWordCount(), o2.getFoundWordCount());
}
double s1 = o1.getSearchDistance(loc);
double s2 = o2.getSearchDistance(loc);
int cmp = Double.compare(s1, s2);
if(cmp != 0) {
return cmp;
}
int st1 = Algorithms.extractFirstIntegerNumber(o1.localeName);
int st2 = Algorithms.extractFirstIntegerNumber(o2.localeName);
if(st1 != st2) {
return Algorithms.compare(st1, st2);
}
cmp = collator.compare(o1.localeName, o2.localeName);
if(cmp != 0) {
return cmp;
}
s1 = o1.getSearchDistance(loc, 1);
s2 = o2.getSearchDistance(loc, 1);
return Double.compare(s1, s2);
}
}
} }

View file

@ -9,8 +9,10 @@ import java.util.List;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import net.osmand.Collator;
import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher;
import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.OsmAndCollator;
import net.osmand.StringMatcher; import net.osmand.StringMatcher;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
@ -37,6 +39,7 @@ public class SearchPhrase {
private static final String DELIMITER = " "; private static final String DELIMITER = " ";
private static final String ALLDELIMITERS = "\\s|,"; private static final String ALLDELIMITERS = "\\s|,";
private static final Pattern reg = Pattern.compile(ALLDELIMITERS); private static final Pattern reg = Pattern.compile(ALLDELIMITERS);
private Collator clt;
public enum SearchPhraseDataType { public enum SearchPhraseDataType {
@ -44,12 +47,17 @@ public class SearchPhrase {
} }
public SearchPhrase(SearchSettings settings) { public SearchPhrase(SearchSettings settings, Collator clt) {
this.settings = settings; this.settings = settings;
this.clt = clt;
}
public Collator getCollator() {
return clt;
} }
public SearchPhrase generateNewPhrase(String text, SearchSettings settings) { public SearchPhrase generateNewPhrase(String text, SearchSettings settings) {
SearchPhrase sp = new SearchPhrase(settings); SearchPhrase sp = new SearchPhrase(settings, this.clt);
String restText = text; String restText = text;
List<SearchWord> leftWords = this.words; List<SearchWord> leftWords = this.words;
String thisTxt = getText(true); String thisTxt = getText(true);
@ -259,7 +267,7 @@ public class SearchPhrase {
} }
public SearchPhrase selectWord(SearchResult res, List<String> unknownWords, boolean lastComplete) { public SearchPhrase selectWord(SearchResult res, List<String> unknownWords, boolean lastComplete) {
SearchPhrase sp = new SearchPhrase(this.settings); SearchPhrase sp = new SearchPhrase(this.settings, this.clt);
addResult(res, sp); addResult(res, sp);
SearchResult prnt = res.parentSearchResult; SearchResult prnt = res.parentSearchResult;
while(prnt != null) { while(prnt != null) {

View file

@ -2,6 +2,7 @@ package net.osmand.search;
import java.io.IOException; import java.io.IOException;
import net.osmand.OsmAndCollator;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.search.SearchUICore.SearchResultMatcher; import net.osmand.search.SearchUICore.SearchResultMatcher;
import net.osmand.search.core.SearchCoreFactory; import net.osmand.search.core.SearchCoreFactory;
@ -16,7 +17,7 @@ public class LocationSearchTest {
private void search(String string, LatLon latLon) throws IOException { private void search(String string, LatLon latLon) throws IOException {
SearchResultMatcher srm = new SearchUICore.SearchResultMatcher(null, 0, null, 100); SearchResultMatcher srm = new SearchUICore.SearchResultMatcher(null, 0, null, 100);
new SearchCoreFactory.SearchLocationAndUrlAPI(). new SearchCoreFactory.SearchLocationAndUrlAPI().
search(new SearchPhrase(null).generateNewPhrase(string, null), srm); search(new SearchPhrase(null, OsmAndCollator.primaryCollator()).generateNewPhrase(string, null), srm);
Assert.assertEquals(1, srm.getRequestResults().size()); Assert.assertEquals(1, srm.getRequestResults().size());
Assert.assertEquals(latLon, srm.getRequestResults().get(0).location); Assert.assertEquals(latLon, srm.getRequestResults().get(0).location);
} }

View file

@ -1,5 +1,45 @@
package net.osmand.plus.search; package net.osmand.plus.search;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.OsmAndCollator;
import net.osmand.ResultMatcher;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.osm.AbstractPoiType;
import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.LockableViewPager;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.search.QuickSearchHelper.SearchHistoryAPI;
import net.osmand.search.SearchUICore;
import net.osmand.search.SearchUICore.SearchResultCollection;
import net.osmand.search.core.ObjectType;
import net.osmand.search.core.SearchCoreAPI;
import net.osmand.search.core.SearchCoreFactory.SearchAmenityTypesAPI;
import net.osmand.search.core.SearchPhrase;
import net.osmand.search.core.SearchResult;
import net.osmand.search.core.SearchSettings;
import net.osmand.search.core.SearchWord;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -34,46 +74,6 @@ import android.widget.ListView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.ResultMatcher;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.osm.AbstractPoiType;
import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.LockableViewPager;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.search.QuickSearchHelper.SearchHistoryAPI;
import net.osmand.search.SearchUICore;
import net.osmand.search.SearchUICore.SearchResultCollection;
import net.osmand.search.core.ObjectType;
import net.osmand.search.core.SearchCoreAPI;
import net.osmand.search.core.SearchCoreFactory.SearchAmenityTypesAPI;
import net.osmand.search.core.SearchPhrase;
import net.osmand.search.core.SearchResult;
import net.osmand.search.core.SearchSettings;
import net.osmand.search.core.SearchWord;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class QuickSearchDialogFragment extends DialogFragment implements OsmAndCompassListener, OsmAndLocationListener { public class QuickSearchDialogFragment extends DialogFragment implements OsmAndCompassListener, OsmAndLocationListener {
public static final String TAG = "QuickSearchDialogFragment"; public static final String TAG = "QuickSearchDialogFragment";
@ -697,13 +697,13 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
try { try {
SearchResultCollection res = searchUICore.shallowSearch(SearchHistoryAPI.class, SearchResultCollection res = searchUICore.shallowSearch(SearchHistoryAPI.class,
"", null); "", null);
List<QuickSearchListItem> rows = new ArrayList<>();
if (res != null) { if (res != null) {
List<QuickSearchListItem> rows = new ArrayList<>();
for (SearchResult sr : res.getCurrentSearchResults()) { for (SearchResult sr : res.getCurrentSearchResults()) {
rows.add(new QuickSearchListItem(app, sr)); rows.add(new QuickSearchListItem(app, sr));
} }
historySearchFragment.updateListAdapter(rows, false);
} }
historySearchFragment.updateListAdapter(rows, false);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
app.showToastMessage(e.getMessage()); app.showToastMessage(e.getMessage());
@ -764,7 +764,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
if (paused) { if (paused) {
if (results.size() > 0) { if (results.size() > 0) {
getResultCollection().getCurrentSearchResults().addAll(results); getResultCollection().addSearchResults(results, true, true);
} }
return false; return false;
} }
@ -783,7 +783,6 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
apiResults = regionCollection.getCurrentSearchResults(); apiResults = regionCollection.getCurrentSearchResults();
} else { } else {
apiResults = results; apiResults = results;
searchUICore.sortSearchResults(phrase, apiResults);
} }
regionResultApi = null; regionResultApi = null;
@ -796,9 +795,12 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
if (!paused) { if (!paused) {
boolean appended = false; boolean appended = false;
if (getResultCollection() == null || getResultCollection().getPhrase() != phrase) { if (getResultCollection() == null || getResultCollection().getPhrase() != phrase) {
setResultCollection(new SearchResultCollection(apiResults, phrase)); SearchResultCollection resCollection =
new SearchResultCollection(phrase);
resCollection.addSearchResults(results, true, true);
setResultCollection(resCollection);
} else { } else {
getResultCollection().getCurrentSearchResults().addAll(apiResults); getResultCollection().addSearchResults(apiResults, false, true );
appended = true; appended = true;
} }
if (!hasRegionCollection) { if (!hasRegionCollection) {
@ -810,22 +812,17 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
break; break;
case SEARCH_API_REGION_FINISHED: case SEARCH_API_REGION_FINISHED:
regionResultApi = (SearchCoreAPI) object.object; regionResultApi = (SearchCoreAPI) object.object;
final List<SearchResult> regionResults = new ArrayList<>(results);
final SearchPhrase regionPhrase = object.requiredSearchPhrase; final SearchPhrase regionPhrase = object.requiredSearchPhrase;
searchUICore.sortSearchResults(regionPhrase, regionResults); regionResultCollection = new SearchResultCollection(regionPhrase);
regionResultCollection.addSearchResults(results, true, true);
app.runInUIThread(new Runnable() { app.runInUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!paused) { if (!paused) {
boolean appended = getResultCollection() != null && getResultCollection().getPhrase() == regionPhrase; boolean appended = getResultCollection() != null && getResultCollection().getPhrase() == regionPhrase;
regionResultCollection = new SearchResultCollection(regionResults, regionPhrase);
if (appended) { if (appended) {
List<SearchResult> res = new ArrayList<>(getResultCollection().getCurrentSearchResults()); SearchResultCollection resCollection =
res.addAll(regionResults); getResultCollection().combineWithCollection(regionResultCollection, false, true);
SearchResultCollection resCollection = new SearchResultCollection(res, regionPhrase);
searchUICore.filterSearchDuplicateResults(regionPhrase, resCollection.getCurrentSearchResults());
updateSearchResult(resCollection, true); updateSearchResult(resCollection, true);
} else { } else {
updateSearchResult(regionResultCollection, false); updateSearchResult(regionResultCollection, false);