Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
|
98e0742e77 | ||
|
8ea8316835 | ||
|
41c812903a | ||
|
3db30ffe8d | ||
|
bc3a37b65f | ||
|
df3104b032 |
3 changed files with 95 additions and 26 deletions
|
@ -1,20 +1,6 @@
|
||||||
package net.osmand.search.core;
|
package net.osmand.search.core;
|
||||||
|
|
||||||
import net.osmand.Collator;
|
|
||||||
import net.osmand.CollatorStringMatcher;import net.osmand.OsmAndCollator;
|
|
||||||
import net.osmand.CollatorStringMatcher.StringMatcherMode;
|
|
||||||
import net.osmand.StringMatcher;
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
|
||||||
import net.osmand.binary.CommonWords;
|
|
||||||
import net.osmand.data.LatLon;
|
|
||||||
import net.osmand.data.QuadRect;
|
|
||||||
import net.osmand.util.Algorithms;
|
|
||||||
import net.osmand.util.LocationParser;
|
|
||||||
import net.osmand.util.MapUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -26,6 +12,20 @@ import java.util.Set;
|
||||||
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.StringMatcherMode;
|
||||||
|
import net.osmand.OsmAndCollator;
|
||||||
|
import net.osmand.StringMatcher;
|
||||||
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||||
|
import net.osmand.binary.CommonWords;
|
||||||
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.data.QuadRect;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
import net.osmand.util.LocationParser;
|
||||||
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
// Immutable object !
|
// Immutable object !
|
||||||
public class SearchPhrase {
|
public class SearchPhrase {
|
||||||
public static final String DELIMITER = " ";
|
public static final String DELIMITER = " ";
|
||||||
|
@ -228,7 +228,17 @@ public class SearchPhrase {
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int countWords(String w) {
|
public static void splitWords(String w, Collection<String> ws) {
|
||||||
|
if (!Algorithms.isEmpty(w)) {
|
||||||
|
String[] wrs = w.split(ALLDELIMITERS);
|
||||||
|
for (int i = 0; i < wrs.length; i++) {
|
||||||
|
String wd = wrs[i].trim();
|
||||||
|
ws.add(wd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int countWords(String w) {
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
if (!Algorithms.isEmpty(w)) {
|
if (!Algorithms.isEmpty(w)) {
|
||||||
String[] ws = w.split(ALLDELIMITERS);
|
String[] ws = w.split(ALLDELIMITERS);
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package net.osmand.search.core;
|
package net.osmand.search.core;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
import net.osmand.data.City;
|
import net.osmand.data.City;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
@ -11,8 +15,6 @@ import net.osmand.osm.PoiType;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class SearchResult {
|
public class SearchResult {
|
||||||
// search phrase that makes search result valid
|
// search phrase that makes search result valid
|
||||||
public SearchPhrase requiredSearchPhrase;
|
public SearchPhrase requiredSearchPhrase;
|
||||||
|
@ -41,6 +43,8 @@ public class SearchResult {
|
||||||
public String localeRelatedObjectName;
|
public String localeRelatedObjectName;
|
||||||
public Object relatedObject;
|
public Object relatedObject;
|
||||||
public double distRelatedObjectName;
|
public double distRelatedObjectName;
|
||||||
|
|
||||||
|
private double unknownPhraseMatchWeight = 0;
|
||||||
|
|
||||||
public SearchResult(SearchPhrase sp) {
|
public SearchResult(SearchPhrase sp) {
|
||||||
this.requiredSearchPhrase = sp;
|
this.requiredSearchPhrase = sp;
|
||||||
|
@ -49,21 +53,53 @@ public class SearchResult {
|
||||||
|
|
||||||
// maximum corresponds to the top entry
|
// maximum corresponds to the top entry
|
||||||
public double getUnknownPhraseMatchWeight() {
|
public double getUnknownPhraseMatchWeight() {
|
||||||
|
if (unknownPhraseMatchWeight != 0) {
|
||||||
|
return unknownPhraseMatchWeight;
|
||||||
|
}
|
||||||
// if result is a complete match in the search we prioritize it higher
|
// if result is a complete match in the search we prioritize it higher
|
||||||
return getSumPhraseMatchWeight() / Math.pow(MAX_TYPE_WEIGHT, getDepth() - 1);
|
double res = getSumPhraseMatchWeight() / Math.pow(MAX_TYPE_WEIGHT, getDepth() - 1);
|
||||||
|
unknownPhraseMatchWeight = res;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getSumPhraseMatchWeight() {
|
public double getSumPhraseMatchWeight() {
|
||||||
// if result is a complete match in the search we prioritize it higher
|
// if result is a complete match in the search we prioritize it higher
|
||||||
int localWordsMatched = alternateName != null ?
|
String name = alternateName != null ? alternateName : localeName;
|
||||||
requiredSearchPhrase.countWords(alternateName) : requiredSearchPhrase.countWords(localeName) ;
|
List<String> localResultNames = new ArrayList<>();
|
||||||
boolean match = localWordsMatched <= getSelfWordCount();
|
SearchPhrase.splitWords(name, localResultNames);
|
||||||
double res = ObjectType.getTypeWeight(match ? objectType : null);
|
List<String> searchPhraseNames = new ArrayList<String>();
|
||||||
|
if (firstUnknownWordMatches) {
|
||||||
|
searchPhraseNames.add(requiredSearchPhrase.getFirstUnknownSearchWord());
|
||||||
|
}
|
||||||
|
if (otherWordsMatch != null) {
|
||||||
|
searchPhraseNames.addAll(otherWordsMatch);
|
||||||
|
}
|
||||||
|
int idxMatchedWord = -1;
|
||||||
|
boolean allWordsMatched = true;
|
||||||
|
for (int i = 0; i < searchPhraseNames.size(); i++) {
|
||||||
|
boolean wordMatched = false;
|
||||||
|
for (int j = idxMatchedWord + 1; j < localResultNames.size(); j++) {
|
||||||
|
int r = requiredSearchPhrase.getCollator().compare(searchPhraseNames.get(i), localResultNames.get(j));
|
||||||
|
if (r == 0) {
|
||||||
|
wordMatched = true;
|
||||||
|
idxMatchedWord = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!wordMatched) {
|
||||||
|
allWordsMatched = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double res = ObjectType.getTypeWeight(allWordsMatched ? objectType : null);
|
||||||
if (parentSearchResult != null) {
|
if (parentSearchResult != null) {
|
||||||
res = res + parentSearchResult.getSumPhraseMatchWeight() / MAX_TYPE_WEIGHT;
|
res = res + parentSearchResult.getSumPhraseMatchWeight() / MAX_TYPE_WEIGHT;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int getDepth() {
|
public int getDepth() {
|
||||||
if (parentSearchResult != null) {
|
if (parentSearchResult != null) {
|
||||||
|
@ -80,6 +116,19 @@ public class SearchResult {
|
||||||
return inc;
|
return inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSelfPhrase() {
|
||||||
|
String ph = "";
|
||||||
|
if (firstUnknownWordMatches) {
|
||||||
|
ph = requiredSearchPhrase.getFirstUnknownSearchWord();
|
||||||
|
}
|
||||||
|
if (otherWordsMatch != null) {
|
||||||
|
for (String s : otherWordsMatch) {
|
||||||
|
ph += " " + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ph;
|
||||||
|
}
|
||||||
|
|
||||||
private int getSelfWordCount() {
|
private int getSelfWordCount() {
|
||||||
int inc = 0;
|
int inc = 0;
|
||||||
if (firstUnknownWordMatches) {
|
if (firstUnknownWordMatches) {
|
||||||
|
|
|
@ -132,6 +132,10 @@ public class SearchUICoreTest {
|
||||||
|
|
||||||
reader = new BinaryMapIndexReader(new RandomAccessFile(obfFile.getPath(), "r"), obfFile);
|
reader = new BinaryMapIndexReader(new RandomAccessFile(obfFile.getPath(), "r"), obfFile);
|
||||||
}
|
}
|
||||||
|
boolean disabled = settingsJson.optBoolean("disabled", false);
|
||||||
|
if (disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
List<List<String>> results = new ArrayList<>();
|
List<List<String>> results = new ArrayList<>();
|
||||||
for (int i = 0; i < phrases.size(); i++) {
|
for (int i = 0; i < phrases.size(); i++) {
|
||||||
results.add(new ArrayList<String>());
|
results.add(new ArrayList<String>());
|
||||||
|
@ -180,21 +184,27 @@ public class SearchUICoreTest {
|
||||||
SearchResultCollection collection = new SearchResultCollection(phrase);
|
SearchResultCollection collection = new SearchResultCollection(phrase);
|
||||||
collection.addSearchResults(matcher.getRequestResults(), true, true);
|
collection.addSearchResults(matcher.getRequestResults(), true, true);
|
||||||
List<SearchResult> searchResults = collection.getCurrentSearchResults();
|
List<SearchResult> searchResults = collection.getCurrentSearchResults();
|
||||||
for(int i = 0; i < result.size(); i++) {
|
for (int i = 0; i < result.size(); i++) {
|
||||||
String expected = result.get(i);
|
String expected = result.get(i);
|
||||||
SearchResult res = i >= searchResults.size() ? null : searchResults.get(i);
|
SearchResult res = i >= searchResults.size() ? null : searchResults.get(i);
|
||||||
if (simpleTest && expected.indexOf('[') != -1) {
|
if (simpleTest && expected.indexOf('[') != -1) {
|
||||||
expected = expected.substring(0, expected.indexOf('[')).trim();
|
expected = expected.substring(0, expected.indexOf('[')).trim();
|
||||||
}
|
}
|
||||||
// String present = result.toString();
|
// String present = result.toString();
|
||||||
String present = res == null ? ("#MISSING " + (i+1)) : formatResult(simpleTest, res, phrase);
|
String present = res == null ? ("#MISSING " + (i + 1)) : formatResult(simpleTest, res, phrase);
|
||||||
if (!Algorithms.stringsEqual(expected, present)) {
|
if (!Algorithms.stringsEqual(expected, present)) {
|
||||||
System.out.println(String.format("Phrase: %s", phrase));
|
System.out.println(String.format("Phrase: %s", phrase));
|
||||||
System.out.println(String.format("Mismatch for '%s' != '%s'. Result: ", expected, present));
|
System.out.println(String.format("Mismatch for '%s' != '%s'. Result: ", expected, present));
|
||||||
}
|
System.out.println("CURRENT RESULTS: ");
|
||||||
for (SearchResult r : searchResults) {
|
for (SearchResult r : searchResults) {
|
||||||
System.out.println(String.format("\t\"%s\",", formatResult(false, r, phrase)));
|
System.out.println(String.format("\t\"%s\",", formatResult(false, r, phrase)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
System.out.println("EXPECTED : ");
|
||||||
|
for (String r : result) {
|
||||||
|
System.out.println(String.format("\t\"%s\",", r));
|
||||||
|
}
|
||||||
|
}
|
||||||
Assert.assertEquals(expected, present);
|
Assert.assertEquals(expected, present);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue