Merge branch 'r3.7' into Fix_tablet_sizes

This commit is contained in:
Dima-1 2020-05-25 10:23:07 +03:00
commit 8c2dc90767
26 changed files with 4098 additions and 447 deletions

View file

@ -29,6 +29,7 @@ import java.util.TreeSet;
public class MapPoiTypes {
private static final String OTHER_MAP_CATEGORY = "Other";
private static MapPoiTypes DEFAULT_INSTANCE = null;
private static final Log log = PlatformUtil.getLog(MapRenderingTypes.class);
private String resourceName;
@ -96,7 +97,7 @@ public class MapPoiTypes {
public PoiCategory getOtherMapCategory() {
if (otherMapCategory == null) {
otherMapCategory = getPoiCategoryByName("Other", true);
otherMapCategory = getPoiCategoryByName(OTHER_MAP_CATEGORY, true);
}
return otherMapCategory;
}
@ -111,7 +112,8 @@ public class MapPoiTypes {
public List<AbstractPoiType> getTopVisibleFilters() {
List<AbstractPoiType> lf = new ArrayList<AbstractPoiType>();
for (PoiCategory pc : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory pc = categories.get(i);
if (pc.isTopVisible()) {
lf.add(pc);
}
@ -131,7 +133,8 @@ public class MapPoiTypes {
}
public PoiCategory getOsmwiki() {
for (PoiCategory category : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory category = categories.get(i);
if (category.isWiki()) {
return category;
}
@ -167,7 +170,8 @@ public class MapPoiTypes {
}
public PoiType getPoiTypeByKey(String name) {
for (PoiCategory pc : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory pc = categories.get(i);
PoiType pt = pc.getPoiTypeByKeyName(name);
if (pt != null && !pt.isReference()) {
return pt;
@ -184,7 +188,8 @@ public class MapPoiTypes {
}
public AbstractPoiType getAnyPoiTypeByKey(String name) {
for (PoiCategory pc : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory pc = categories.get(i);
if (pc.getKeyName().equals(name)) {
return pc;
}
@ -203,7 +208,8 @@ public class MapPoiTypes {
public Map<String, PoiType> getAllTranslatedNames(boolean skipNonEditable) {
Map<String, PoiType> translation = new HashMap<String, PoiType>();
for (PoiCategory pc : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory pc = categories.get(i);
if (skipNonEditable && pc.isNotEditableOsm()) {
continue;
}
@ -231,7 +237,8 @@ public class MapPoiTypes {
public List<AbstractPoiType> getAllTypesTranslatedNames(StringMatcher matcher) {
List<AbstractPoiType> tm = new ArrayList<AbstractPoiType>();
for (PoiCategory pc : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory pc = categories.get(i);
if (pc == otherMapCategory) {
continue;
}
@ -294,7 +301,7 @@ public class MapPoiTypes {
}
if (create) {
PoiCategory lastCategory = new PoiCategory(this, name, categories.size());
if (!lastCategory.getKeyName().equals("Other")) {
if (!lastCategory.getKeyName().equals(OTHER_MAP_CATEGORY)) {
lastCategory.setTopVisible(true);
}
addCategory(lastCategory);
@ -353,6 +360,11 @@ public class MapPoiTypes {
final Map<String, PoiType> allTypes = new LinkedHashMap<String, PoiType>();
final Map<String, List<PoiType>> categoryPoiAdditionalMap = new LinkedHashMap<String, List<PoiType>>();
final Map<AbstractPoiType, Set<String>> abstractTypeAdditionalCategories = new LinkedHashMap<AbstractPoiType, Set<String>>();
final Map<String, PoiType> poiTypesByTag = new LinkedHashMap<String, PoiType>();
final Map<String, String> deprecatedTags = new LinkedHashMap<String, String>();
final Map<String, String> poiAdditionalCategoryIconNames = new LinkedHashMap<String, String>();
final List<PoiType> textPoiAdditionals = new ArrayList<PoiType>();
List<PoiCategory> categoriesList = new ArrayList<>();
try {
XmlPullParser parser = PlatformUtil.newXMLPullParser();
@ -365,6 +377,8 @@ public class MapPoiTypes {
PoiType lastType = null;
Set<String> lastTypePoiAdditionalsCategories = new TreeSet<String>();
String lastPoiAdditionalCategory = null;
PoiCategory localOtherMapCategory = new PoiCategory(this, OTHER_MAP_CATEGORY, categoriesList.size());
categoriesList.add(localOtherMapCategory);
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (tok == XmlPullParser.START_TAG) {
String name = parser.getName();
@ -404,14 +418,17 @@ public class MapPoiTypes {
lastCategory.addPoiType(tp);
} else if (name.equals("poi_additional")) {
if (lastCategory == null) {
lastCategory = getOtherMapCategory();
lastCategory = localOtherMapCategory;
}
PoiType baseType = parsePoiAdditional(parser, lastCategory, lastFilter, lastType, null, null, lastPoiAdditionalCategory);
PoiType baseType = parsePoiAdditional(parser, lastCategory, lastFilter, lastType, null, null,
lastPoiAdditionalCategory, textPoiAdditionals);
if ("true".equals(parser.getAttributeValue("", "lang"))) {
for (String lng : MapRenderingTypes.langs) {
parsePoiAdditional(parser, lastCategory, lastFilter, lastType, lng, baseType, lastPoiAdditionalCategory);
parsePoiAdditional(parser, lastCategory, lastFilter, lastType, lng, baseType,
lastPoiAdditionalCategory, textPoiAdditionals);
}
parsePoiAdditional(parser, lastCategory, lastFilter, lastType, "en", baseType, lastPoiAdditionalCategory);
parsePoiAdditional(parser, lastCategory, lastFilter, lastType, "en", baseType,
lastPoiAdditionalCategory, textPoiAdditionals);
}
if (lastPoiAdditionalCategory != null) {
List<PoiType> categoryAdditionals = categoryPoiAdditionalMap.get(lastPoiAdditionalCategory);
@ -433,7 +450,7 @@ public class MapPoiTypes {
} else if (name.equals("poi_type")) {
if (lastCategory == null) {
lastCategory = getOtherMapCategory();
lastCategory = localOtherMapCategory;
}
if(!Algorithms.isEmpty(parser.getAttributeValue("", "deprecated_of"))){
String vl = parser.getAttributeValue("", "name");
@ -482,7 +499,7 @@ public class MapPoiTypes {
}
}
}
categories = categoriesList;
is.close();
} catch (IOException e) {
log.error("Unexpected error", e); //$NON-NLS-1$
@ -510,17 +527,25 @@ public class MapPoiTypes {
List<PoiType> poiAdditionals = categoryPoiAdditionalMap.get(category);
if (poiAdditionals != null) {
for (PoiType poiType : poiAdditionals) {
buildPoiAdditionalReference(poiType, entry.getKey());
buildPoiAdditionalReference(poiType, entry.getKey(), textPoiAdditionals);
}
}
}
}
findDefaultOtherCategory();
this.categories = categoriesList;
this.poiTypesByTag = poiTypesByTag;
this.deprecatedTags = deprecatedTags;
this.poiAdditionalCategoryIconNames = poiAdditionalCategoryIconNames;
this.textPoiAdditionals = textPoiAdditionals;
otherCategory = getPoiCategoryByName("user_defined_other");
if (otherCategory == null) {
throw new IllegalArgumentException("No poi category other");
}
init = true;
log.info("Time to init poi types " + (System.currentTimeMillis() - time)); //$NON-NLS-1$
}
private PoiType buildPoiAdditionalReference(PoiType poiAdditional, AbstractPoiType parent) {
private PoiType buildPoiAdditionalReference(PoiType poiAdditional, AbstractPoiType parent, List<PoiType> textPoiAdditionals) {
PoiCategory lastCategory = null;
PoiFilter lastFilter = null;
PoiType lastType = null;
@ -571,7 +596,8 @@ public class MapPoiTypes {
}
private PoiType parsePoiAdditional(XmlPullParser parser, PoiCategory lastCategory, PoiFilter lastFilter,
PoiType lastType, String lang, PoiType langBaseType, String poiAdditionalCategory) {
PoiType lastType, String lang, PoiType langBaseType,
String poiAdditionalCategory, List<PoiType> textPoiAdditionals) {
String oname = parser.getAttributeValue("", "name");
if (lang != null) {
oname += ":" + lang;
@ -653,13 +679,6 @@ public class MapPoiTypes {
return tp;
}
private void findDefaultOtherCategory() {
PoiCategory pc = getPoiCategoryByName("user_defined_other");
if (pc == null) {
throw new IllegalArgumentException("No poi category other");
}
otherCategory = pc;
}
public List<PoiCategory> getCategories(boolean includeMapCategory) {
ArrayList<PoiCategory> lst = new ArrayList<PoiCategory>(categories);
@ -705,7 +724,8 @@ public class MapPoiTypes {
public AbstractPoiType getAnyPoiAdditionalTypeByKey(String name) {
PoiType add = null;
for (PoiCategory pc : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory pc = categories.get(i);
add = getPoiAdditionalByKey(pc, name);
if (add != null) {
return add;
@ -811,7 +831,8 @@ public class MapPoiTypes {
if (!poiTypesByTag.isEmpty()) {
return;
}
for (PoiCategory poic : categories) {
for (int i = 0; i < categories.size(); i++) {
PoiCategory poic = categories.get(i);
for (PoiType p : poic.getPoiTypes()) {
initPoiType(p);
for (PoiType pts : p.getPoiAdditionals()) {

View file

@ -652,6 +652,10 @@ public class SearchUICore {
return prev;
}
public SearchResult getParentSearchResult() {
return parentSearchResult;
}
public List<SearchResult> getRequestResults() {
return requestResults;
}
@ -730,9 +734,9 @@ public class SearchUICore {
object.localeName = object.alternateName;
object.alternateName = null;
}
object.parentSearchResult = parentSearchResult;
if (matcher == null || matcher.publish(object)) {
count++;
object.parentSearchResult = parentSearchResult;
if (totalLimit == -1 || count < totalLimit) {
requestResults.add(object);
}
@ -740,6 +744,7 @@ public class SearchUICore {
}
return false;
}
@Override
public boolean isCancelled() {
boolean cancelled = request != requestNumber.get();
@ -849,12 +854,121 @@ public class SearchUICore {
}
}
private enum ResultCompareStep {
TOP_VISIBLE,
FOUND_WORD_COUNT,
UNKNOWN_PHRASE_MATCH_WEIGHT,
SEARCH_DISTANCE_IF_NOT_BY_NAME,
COMPARE_FIRST_NUMBER_IN_NAME,
COMPARE_DISTANCE_TO_PARENT_SEARCH_RESULT, // makes sense only for inner subqueries
COMPARE_BY_NAME,
COMPARE_BY_DISTANCE,
AMENITY_LAST_AND_SORT_BY_SUBTYPE
;
// -1 - means 1st is less (higher) than 2nd
public int compare(SearchResult o1, SearchResult o2, SearchResultComparator c) {
switch(this) {
case TOP_VISIBLE:
boolean topVisible1 = ObjectType.isTopVisible(o1.objectType);
boolean topVisible2 = ObjectType.isTopVisible(o2.objectType);
if (topVisible1 != topVisible2) {
// -1 - means 1st is less than 2nd
return topVisible1 ? -1 : 1;
}
break;
case FOUND_WORD_COUNT:
if (o1.getFoundWordCount() != o2.getFoundWordCount()) {
return -Algorithms.compare(o1.getFoundWordCount(), o2.getFoundWordCount());
}
break;
case UNKNOWN_PHRASE_MATCH_WEIGHT:
// here we check how much each sub search result matches the phrase
// also we sort it by type house -> street/poi -> city/postcode/village/other
if (o1.getUnknownPhraseMatchWeight() != o2.getUnknownPhraseMatchWeight()) {
return -Double.compare(o1.getUnknownPhraseMatchWeight(), o2.getUnknownPhraseMatchWeight());
}
break;
case SEARCH_DISTANCE_IF_NOT_BY_NAME:
if (!c.sortByName) {
double s1 = o1.getSearchDistance(c.loc);
double s2 = o2.getSearchDistance(c.loc);
if (s1 != s2) {
return Double.compare(s1, s2);
}
}
break;
case COMPARE_FIRST_NUMBER_IN_NAME: {
String localeName1 = o1.localeName == null ? "" : o1.localeName;
String localeName2 = o2.localeName == null ? "" : o2.localeName;
int st1 = Algorithms.extractFirstIntegerNumber(localeName1);
int st2 = Algorithms.extractFirstIntegerNumber(localeName2);
if (st1 != st2) {
return Algorithms.compare(st1, st2);
}
break;
}
case COMPARE_DISTANCE_TO_PARENT_SEARCH_RESULT:
double ps1 = o1.parentSearchResult == null ? 0 : o1.parentSearchResult.getSearchDistance(c.loc);
double ps2 = o2.parentSearchResult == null ? 0 : o2.parentSearchResult.getSearchDistance(c.loc);
if (ps1 != ps2) {
return Double.compare(ps1, ps2);
}
break;
case COMPARE_BY_NAME: {
String localeName1 = o1.localeName == null ? "" : o1.localeName;
String localeName2 = o2.localeName == null ? "" : o2.localeName;
int cmp = c.collator.compare(localeName1, localeName2);
if (cmp != 0) {
return cmp;
}
break;
}
case COMPARE_BY_DISTANCE:
double s1 = o1.getSearchDistance(c.loc, 1);
double s2 = o2.getSearchDistance(c.loc, 1);
if (s1 != s2) {
return Double.compare(s1, s2);
}
break;
case AMENITY_LAST_AND_SORT_BY_SUBTYPE: {
boolean am1 = o1.object instanceof Amenity;
boolean am2 = o2.object instanceof Amenity;
if (am1 != am2) {
// amenity second
return am1 ? 1 : -1;
} else if (am1 && am2) {
// here 2 points are amenity
Amenity a1 = (Amenity) o1.object;
Amenity a2 = (Amenity) o2.object;
String type1 = a1.getType().getKeyName();
String type2 = a2.getType().getKeyName();
int cmp = c.collator.compare(type1, type2);
if (cmp != 0) {
return cmp;
}
String subType1 = a1.getSubType() == null ? "" : a1.getSubType();
String subType2 = a2.getSubType() == null ? "" : a2.getSubType();
cmp = c.collator.compare(subType1, subType2);
if (cmp != 0) {
return cmp;
}
}
break;
}
}
return 0;
}
}
public static class SearchResultComparator implements Comparator<SearchResult> {
private SearchPhrase sp;
private Collator collator;
private LatLon loc;
private boolean sortByName;
public SearchResultComparator(SearchPhrase sp) {
this.sp = sp;
this.collator = sp.getCollator();
@ -865,66 +979,10 @@ public class SearchUICore {
@Override
public int compare(SearchResult o1, SearchResult o2) {
boolean topVisible1 = ObjectType.isTopVisible(o1.objectType);
boolean topVisible2 = ObjectType.isTopVisible(o2.objectType);
if (topVisible1 != topVisible2) {
// -1 - means 1st is less than 2nd
return topVisible1 ? -1 : 1;
}
if (o1.getUnknownPhraseMatchWeight() != o2.getUnknownPhraseMatchWeight()) {
return -Double.compare(o1.getUnknownPhraseMatchWeight(), o2.getUnknownPhraseMatchWeight());
}
if (o1.getFoundWordCount() != o2.getFoundWordCount()) {
return -Algorithms.compare(o1.getFoundWordCount(), o2.getFoundWordCount());
}
if (!sortByName) {
double s1 = o1.getSearchDistance(loc);
double s2 = o2.getSearchDistance(loc);
if (s1 != s2) {
return Double.compare(s1, s2);
}
}
String localeName1 = o1.localeName == null ? "" : o1.localeName;
String localeName2 = o2.localeName == null ? "" : o2.localeName;
int st1 = Algorithms.extractFirstIntegerNumber(localeName1);
int st2 = Algorithms.extractFirstIntegerNumber(localeName2);
if (st1 != st2) {
return Algorithms.compare(st1, st2);
}
double s1 = o1.getSearchDistance(loc, 1);
double s2 = o2.getSearchDistance(loc, 1);
double ps1 = o1.parentSearchResult == null ? 0 : o1.parentSearchResult.getSearchDistance(loc);
double ps2 = o2.parentSearchResult == null ? 0 : o2.parentSearchResult.getSearchDistance(loc);
if (ps1 != ps2) {
return Double.compare(ps1, ps2);
}
int cmp = collator.compare(localeName1, localeName2);
if (cmp != 0) {
return cmp;
}
if (s1 != s2) {
return Double.compare(s1, s2);
}
boolean am1 = o1.object instanceof Amenity;
boolean am2 = o2.object instanceof Amenity;
if (am1 != am2) {
return Boolean.compare(am1, am2);
} else if (am1 && am2) {
// here 2 points are amenity
Amenity a1 = (Amenity) o1.object;
Amenity a2 = (Amenity) o2.object;
String type1 = a1.getType().getKeyName();
String type2 = a2.getType().getKeyName();
cmp = collator.compare(type1, type2);
if (cmp != 0) {
return cmp;
}
String subType1 = a1.getSubType() == null ? "" : a1.getSubType();
String subType2 = a2.getSubType() == null ? "" : a2.getSubType();
cmp = collator.compare(subType1, subType2);
if (cmp != 0) {
return cmp;
for(ResultCompareStep step : ResultCompareStep.values()) {
int r = step.compare(o1, o2, this);
if(r != 0) {
return r;
}
}
return 0;

View file

@ -45,27 +45,24 @@ public enum ObjectType {
return null;
}
public static double getTypeWeight(ObjectType t) {
public static int getTypeWeight(ObjectType t) {
if (t == null) {
return 1.0;
return 1;
}
switch (t) {
case CITY:
return 1.0;
case VILLAGE:
return 1.0;
case POSTCODE:
return 1.0;
case STREET:
return 2.0;
case HOUSE:
return 3.0;
case STREET_INTERSECTION:
return 3.0;
return 4;
case STREET:
return 3;
case POI:
return 2.0;
return 2;
case CITY:
case VILLAGE:
case POSTCODE:
return 1;
default:
return 1.0;
return 1;
}
}
}

View file

@ -146,7 +146,7 @@ public class SearchCoreFactory {
phrase.countUnknownWordsMatch(res);
// int cnt = resultMatcher.getCount();
List<String> ws = phrase.getUnknownSearchWords(res.otherWordsMatch);
if(!res.firstUnknownWordMatches) {
if (!res.firstUnknownWordMatches) {
ws.add(phrase.getUnknownSearchWord());
}
// publish result to set parentSearchResult before search
@ -154,14 +154,10 @@ public class SearchCoreFactory {
if (!ws.isEmpty() && api != null && api.isSearchAvailable(phrase)) {
SearchPhrase nphrase = phrase.selectWord(res, ws,
phrase.isLastUnknownSearchWordComplete());
SearchResult prev = resultMatcher.setParentSearchResult(res);
res.parentSearchResult = prev;
resultMatcher.setParentSearchResult(res);
api.search(nphrase, resultMatcher);
resultMatcher.setParentSearchResult(prev);
resultMatcher.setParentSearchResult(res.parentSearchResult);
}
// if (resultMatcher.getCount() == cnt) {
// resultMatcher.publish(res);
// }
}
@Override

View file

@ -121,7 +121,12 @@ public class SearchPhrase {
int i1 = CommonWords.getCommonSearch(o1.toLowerCase());
int i2 = CommonWords.getCommonSearch(o2.toLowerCase());
if (i1 != i2) {
return icompare(i1, i2);
if(i1 == -1) {
return -1;
} else if(i2 == -1) {
return 1;
}
return -icompare(i1, i2);
}
// compare length without numbers to not include house numbers
return -icompare(lengthWithoutNumbers(o1), lengthWithoutNumbers(o2));
@ -458,20 +463,24 @@ public class SearchPhrase {
SearchPhrase sp = new SearchPhrase(this.settings, this.clt);
addResult(res, sp);
SearchResult prnt = res.parentSearchResult;
while(prnt != null) {
while (prnt != null) {
addResult(prnt, sp);
prnt = prnt.parentSearchResult;
}
sp.words.addAll(0, this.words);
if(unknownWords != null) {
if (unknownWords != null) {
sp.lastUnknownSearchWordComplete = lastComplete;
StringBuilder genUnknownSearchPhrase = new StringBuilder();
for (int i = 0; i < unknownWords.size(); i++) {
if (i == 0) {
sp.unknownSearchWordTrim = unknownWords.get(0);
} else {
sp.unknownWords.add(unknownWords.get(i));
}
genUnknownSearchPhrase.append(unknownWords.get(i)).append(" ");
}
sp.rawUnknownSearchPhrase = sp.unknownSearchPhrase = genUnknownSearchPhrase.toString().trim();
}
return sp;
}
@ -724,16 +733,17 @@ public class SearchPhrase {
}
public void countUnknownWordsMatch(SearchResult sr, String localeName, Collection<String> otherNames) {
if(unknownWords.size() > 0) {
for(int i = 0; i < unknownWords.size(); i++) {
if(unknownWordsMatcher.size() == i) {
if (unknownWords.size() > 0) {
for (int i = 0; i < unknownWords.size(); i++) {
if (unknownWordsMatcher.size() == i) {
unknownWordsMatcher.add(new NameStringMatcher(unknownWords.get(i),
i < unknownWords.size() - 1 || isLastUnknownSearchWordComplete() ? StringMatcherMode.CHECK_EQUALS_FROM_SPACE :
StringMatcherMode.CHECK_STARTS_FROM_SPACE));
i < unknownWords.size() - 1 || isLastUnknownSearchWordComplete()
? StringMatcherMode.CHECK_EQUALS_FROM_SPACE
: StringMatcherMode.CHECK_STARTS_FROM_SPACE));
}
NameStringMatcher ms = unknownWordsMatcher.get(i);
if(ms.matches(localeName) || ms.matches(otherNames)) {
if(sr.otherWordsMatch == null) {
if (ms.matches(localeName) || ms.matches(otherNames)) {
if (sr.otherWordsMatch == null) {
sr.otherWordsMatch = new TreeSet<>();
}
sr.otherWordsMatch.add(unknownWords.get(i));

View file

@ -34,17 +34,15 @@ public class SearchResult {
}
public double getUnknownPhraseMatchWeight() {
return getUnknownPhraseMatchWeight(false);
}
private double getUnknownPhraseMatchWeight(boolean isHouse) {
// if result is a complete match in the search we prioritize it highers
double res = 0;
isHouse = isHouse || objectType == ObjectType.HOUSE;
if (unknownPhraseMatches) {
res = isHouse ? ObjectType.getTypeWeight(ObjectType.HOUSE) : ObjectType.getTypeWeight(objectType);
res = ObjectType.getTypeWeight(objectType);
}
if (res == 0 && parentSearchResult != null) {
return parentSearchResult.getUnknownPhraseMatchWeight(isHouse);
if (parentSearchResult != null) {
// 10 > maximum type
// res = Math.max(res,parentSearchResult.getUnknownPhraseMatchWeight()) ;
res += parentSearchResult.getUnknownPhraseMatchWeight() / 10;
}
return res;
}

View file

@ -0,0 +1,111 @@
package net.osmand.search;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import net.osmand.OsmAndCollator;
import net.osmand.data.LatLon;
import net.osmand.search.SearchUICore.SearchResultCollection;
import net.osmand.search.core.SearchPhrase;
import net.osmand.search.core.SearchResult;
import net.osmand.search.core.SearchSettings;
import net.osmand.util.MapUtils;
public class SearchUICoreGenericTest {
@BeforeClass
public static void setUp() {
SearchUICoreTest.defaultSetup();
}
@Test
public void testDuplicates() throws IOException {
SearchSettings ss = new SearchSettings((SearchSettings)null);
ss = ss.setOriginalLocation(new LatLon(0, 0));
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
List<SearchResult> rs = new ArrayList<>();
SearchResult a1 = searchResult(rs, phrase, "a", 100);
SearchResult b2 = searchResult(rs, phrase, "b", 200);
SearchResult b1 = searchResult(rs, phrase, "b", 100);
/*SearchResult a3 = */ searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, true, true);
Assert.assertEquals(3, cll.getCurrentSearchResults().size());
Assert.assertSame(a1, cll.getCurrentSearchResults().get(0));
Assert.assertSame(b1, cll.getCurrentSearchResults().get(1));
Assert.assertSame(b2, cll.getCurrentSearchResults().get(2));
}
@Test
public void testNoResort() throws IOException {
SearchSettings ss = new SearchSettings((SearchSettings)null);
ss = ss.setOriginalLocation(new LatLon(0, 0));
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
List<SearchResult> rs = new ArrayList<>();
SearchResult a1 = searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
SearchResult b2 = searchResult(rs, phrase, "b", 200);
cll.addSearchResults(rs, false, true);
rs.clear();
SearchResult b1 = searchResult(rs, phrase, "b", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
/*SearchResult a3 = */ searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
Assert.assertEquals(3, cll.getCurrentSearchResults().size());
Assert.assertSame(a1, cll.getCurrentSearchResults().get(0));
Assert.assertSame(b2, cll.getCurrentSearchResults().get(1));
Assert.assertSame(b1, cll.getCurrentSearchResults().get(2));
}
@Test
public void testNoResortDuplicate() throws IOException {
SearchSettings ss = new SearchSettings((SearchSettings)null);
ss = ss.setOriginalLocation(new LatLon(0, 0));
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
List<SearchResult> rs = new ArrayList<>();
SearchResult a1 = searchResult(rs, phrase, "a", 100);
SearchResult b2 = searchResult(rs, phrase, "b", 200);
SearchResult b1 = searchResult(rs, phrase, "b", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
/*SearchResult a3 = */ searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
Assert.assertEquals(3, cll.getCurrentSearchResults().size());
Assert.assertSame(a1, cll.getCurrentSearchResults().get(0));
Assert.assertSame(b1, cll.getCurrentSearchResults().get(1));
Assert.assertSame(b2, cll.getCurrentSearchResults().get(2));
}
private SearchResult searchResult(List<SearchResult> rs, SearchPhrase phrase, String text, int dist) {
SearchResult res = new SearchResult(phrase);
res.localeName = text;
double d1 = MapUtils.getDistance(0, 0, 0, 1);
res.location = new LatLon(0, dist / d1);
rs.add(res);
return res;
}
}

View file

@ -1,12 +1,30 @@
package net.osmand.search;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.xmlpull.v1.XmlPullParserException;
import net.osmand.OsmAndCollator;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.Amenity;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.LatLon;
import net.osmand.data.MapObject;
import net.osmand.data.Street;
import net.osmand.osm.AbstractPoiType;
@ -17,35 +35,31 @@ import net.osmand.search.core.SearchPhrase;
import net.osmand.search.core.SearchResult;
import net.osmand.search.core.SearchSettings;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
public class SearchCoreUITest {
@RunWith(Parameterized.class)
public class SearchUICoreTest {
private static final String SEARCH_RESOURCES_PATH = "src/test/resources/search/";
private static Map<String, String> enPhrases = new HashMap<>();
private static Map<String, String> phrases = new HashMap<>();
private static boolean TEST_EXTRA_RESULTS = true;
static {
private File testFile;
public SearchUICoreTest(String name, File file) {
this.testFile = file;
}
@BeforeClass
public static void setUp() {
defaultSetup();
}
static void defaultSetup() {
MapPoiTypes.setDefault(new MapPoiTypes("src/test/resources/poi_types.xml"));
MapPoiTypes poiTypes = MapPoiTypes.getDefault();
Map<String, String> enPhrases = new HashMap<>();
Map<String, String> phrases = new HashMap<>();
try {
enPhrases = Algorithms.parseStringsXml(new File("src/test/resources/phrases/en/phrases.xml"));
//phrases = Algorithms.parseStringsXml(new File("src/test/resources/phrases/ru/phrases.xml"));
@ -56,7 +70,139 @@ public class SearchCoreUITest {
e.printStackTrace();
}
poiTypes.setPoiTranslator(new MapPoiTypes.PoiTranslator() {
poiTypes.setPoiTranslator(new TestSearchTranslator(phrases, enPhrases));
}
@Parameterized.Parameters(name = "{index}: {0}")
public static Iterable<Object[]> data() throws IOException {
final File[] files = new File(SEARCH_RESOURCES_PATH).listFiles();
ArrayList<Object[]> arrayList = new ArrayList<>();
if (files != null) {
for (File file : files) {
String fileName = file.getName();
if(fileName.endsWith(".json")) {
String name = fileName.substring(0, fileName.length() - ".json".length());
arrayList.add(new Object[] {name, file});
}
}
}
return arrayList;
}
@Test
public void testSearch() throws IOException, JSONException {
File jsonFile = testFile;
String sourceJsonText = Algorithms.getFileAsString(jsonFile);
Assert.assertNotNull(sourceJsonText);
Assert.assertTrue(sourceJsonText.length() > 0);
BinaryMapIndexReaderTest reader = new BinaryMapIndexReaderTest();
JSONObject sourceJson = new JSONObject(sourceJsonText);
String phraseText = sourceJson.getString("phrase");
JSONObject settingsJson = sourceJson.getJSONObject("settings");
if (sourceJson.has("amenities")) {
JSONArray amenitiesArr = sourceJson.getJSONArray("amenities");
List<Amenity> amenities = new ArrayList<>();
for (int i = 0; i < amenitiesArr.length(); i++) {
JSONObject amenityObj = amenitiesArr.getJSONObject(i);
amenities.add(Amenity.parseJSON(amenityObj));
}
reader.amenities = amenities;
}
if (sourceJson.has("cities")) {
JSONArray citiesArr = sourceJson.getJSONArray("cities");
List<City> cities = new ArrayList<>();
List<City> initCities = new ArrayList<>();
List<City> matchedCities = new ArrayList<>();
List<City> streetCities = new ArrayList<>();
for (int i = 0; i < citiesArr.length(); i++) {
JSONObject cityObj = citiesArr.getJSONObject(i);
final City city = City.parseJSON(cityObj);
cities.add(city);
if (cityObj.has("init")) {
initCities.add(city);
}
if (cityObj.has("matchCity")) {
matchedCities.add(city);
}
if (cityObj.has("matchStreet")) {
streetCities.add(city);
}
}
reader.cities = cities;
reader.initCities = initCities;
reader.matchedCities = matchedCities;
reader.streetCities = streetCities;
}
List<String> results = new ArrayList<>();
if (sourceJson.has("results")) {
JSONArray resultsArr = sourceJson.getJSONArray("results");
for (int i = 0; i < resultsArr.length(); i++) {
results.add(resultsArr.getString(i));
}
}
if (TEST_EXTRA_RESULTS && sourceJson.has("extra-results")) {
JSONArray resultsArr = sourceJson.getJSONArray("extra-results");
for (int i = 0; i < resultsArr.length(); i++) {
results.add(resultsArr.getString(i));
}
}
SearchSettings s = SearchSettings.parseJSON(settingsJson);
s.setOfflineIndexes(Collections.singletonList(reader));
SearchPhrase phrase = new SearchPhrase(s, OsmAndCollator.primaryCollator());
phrase = phrase.generateNewPhrase(phraseText, s);
final SearchUICore core = new SearchUICore(MapPoiTypes.getDefault(), "en", false);
core.init();
ResultMatcher<SearchResult> rm = new ResultMatcher<SearchResult>() {
@Override
public boolean publish(SearchResult object) {
return true;
}
@Override
public boolean isCancelled() {
return false;
}
};
SearchResultMatcher matcher = new SearchResultMatcher(rm, phrase, 1, new AtomicInteger(1), -1);
core.searchInternal(phrase, matcher);
SearchResultCollection collection = new SearchResultCollection(phrase);
collection.addSearchResults(matcher.getRequestResults(), true, true);
List<SearchResult> searchResults = collection.getCurrentSearchResults();
int i = 0;
for (SearchResult result : searchResults) {
String expected = results.get(i++);
String present = result.toString();
if (!Algorithms.stringsEqual(expected, present)) {
System.out.println(String.format("Mismatch for '%s' != '%s' (%d, %.3f, %s). Result: ", expected,
present, result.getFoundWordCount(), result.getUnknownPhraseMatchWeight(), result.objectType.toString()));
for (SearchResult r : searchResults) {
// System.out.println(String.format("\t\"%s\",", r.toString()));
System.out.println(String.format("\"%s\", (%d, %.3f, %s),", r.toString(),
r.getFoundWordCount(), r.getUnknownPhraseMatchWeight(), r.objectType.toString()));
}
}
Assert.assertEquals(expected, present);
if (i >= results.size()) {
break;
}
}
}
static class TestSearchTranslator implements MapPoiTypes.PoiTranslator {
private Map<String, String> enPhrases;
private Map<String, String> phrases;
public TestSearchTranslator(Map<String, String> phrases, Map<String, String> enPhrases) {
this.phrases = phrases;
this.enPhrases = enPhrases;
}
@Override
public String getTranslation(AbstractPoiType type) {
@ -125,196 +271,7 @@ public class SearchCoreUITest {
}
return val;
}
});
}
@Test
public void testDuplicates() throws IOException {
SearchSettings ss = new SearchSettings((SearchSettings)null);
ss = ss.setOriginalLocation(new LatLon(0, 0));
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
List<SearchResult> rs = new ArrayList<>();
SearchResult a1 = searchResult(rs, phrase, "a", 100);
SearchResult b2 = searchResult(rs, phrase, "b", 200);
SearchResult b1 = searchResult(rs, phrase, "b", 100);
/*SearchResult a3 = */ searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, true, true);
Assert.assertEquals(3, cll.getCurrentSearchResults().size());
Assert.assertSame(a1, cll.getCurrentSearchResults().get(0));
Assert.assertSame(b1, cll.getCurrentSearchResults().get(1));
Assert.assertSame(b2, cll.getCurrentSearchResults().get(2));
}
@Test
public void testNoResort() throws IOException {
SearchSettings ss = new SearchSettings((SearchSettings)null);
ss = ss.setOriginalLocation(new LatLon(0, 0));
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
List<SearchResult> rs = new ArrayList<>();
SearchResult a1 = searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
SearchResult b2 = searchResult(rs, phrase, "b", 200);
cll.addSearchResults(rs, false, true);
rs.clear();
SearchResult b1 = searchResult(rs, phrase, "b", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
/*SearchResult a3 = */ searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
Assert.assertEquals(3, cll.getCurrentSearchResults().size());
Assert.assertSame(a1, cll.getCurrentSearchResults().get(0));
Assert.assertSame(b2, cll.getCurrentSearchResults().get(1));
Assert.assertSame(b1, cll.getCurrentSearchResults().get(2));
}
@Test
public void testNoResortDuplicate() throws IOException {
SearchSettings ss = new SearchSettings((SearchSettings)null);
ss = ss.setOriginalLocation(new LatLon(0, 0));
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
List<SearchResult> rs = new ArrayList<>();
SearchResult a1 = searchResult(rs, phrase, "a", 100);
SearchResult b2 = searchResult(rs, phrase, "b", 200);
SearchResult b1 = searchResult(rs, phrase, "b", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
/*SearchResult a3 = */ searchResult(rs, phrase, "a", 100);
cll.addSearchResults(rs, false, true);
rs.clear();
Assert.assertEquals(3, cll.getCurrentSearchResults().size());
Assert.assertSame(a1, cll.getCurrentSearchResults().get(0));
Assert.assertSame(b1, cll.getCurrentSearchResults().get(1));
Assert.assertSame(b2, cll.getCurrentSearchResults().get(2));
}
private SearchResult searchResult(List<SearchResult> rs, SearchPhrase phrase, String text, int dist) {
SearchResult res = new SearchResult(phrase);
res.localeName = text;
double d1 = MapUtils.getDistance(0, 0, 0, 1);
res.location = new LatLon(0, dist / d1);
rs.add(res);
return res;
}
@Test
public void testSearchJsons() throws IOException {
final File[] files = new File(SEARCH_RESOURCES_PATH).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return filename.endsWith(".json");
}
});
if (files != null) {
for (File f : files) {
testSearchImpl(f);
}
}
}
private void testSearchImpl(File jsonFile) throws IOException, JSONException {
String sourceJsonText = Algorithms.getFileAsString(jsonFile);
Assert.assertNotNull(sourceJsonText);
Assert.assertTrue(sourceJsonText.length() > 0);
BinaryMapIndexReaderTest reader = new BinaryMapIndexReaderTest();
JSONObject sourceJson = new JSONObject(sourceJsonText);
String phraseText = sourceJson.getString("phrase");
JSONObject settingsJson = sourceJson.getJSONObject("settings");
if (sourceJson.has("amenities")) {
JSONArray amenitiesArr = sourceJson.getJSONArray("amenities");
List<Amenity> amenities = new ArrayList<>();
for (int i = 0; i < amenitiesArr.length(); i++) {
JSONObject amenityObj = amenitiesArr.getJSONObject(i);
amenities.add(Amenity.parseJSON(amenityObj));
}
reader.amenities = amenities;
}
if (sourceJson.has("cities")) {
JSONArray citiesArr = sourceJson.getJSONArray("cities");
List<City> cities = new ArrayList<>();
List<City> initCities = new ArrayList<>();
List<City> matchedCities = new ArrayList<>();
List<City> streetCities = new ArrayList<>();
for (int i = 0; i < citiesArr.length(); i++) {
JSONObject cityObj = citiesArr.getJSONObject(i);
final City city = City.parseJSON(cityObj);
cities.add(city);
if (cityObj.has("init")) {
initCities.add(city);
}
if (cityObj.has("matchCity")) {
matchedCities.add(city);
}
if (cityObj.has("matchStreet")) {
streetCities.add(city);
}
}
reader.cities = cities;
reader.initCities = initCities;
reader.matchedCities = matchedCities;
reader.streetCities = streetCities;
}
List<String> results = new ArrayList<>();
if (sourceJson.has("results")) {
JSONArray resultsArr = sourceJson.getJSONArray("results");
for (int i = 0; i < resultsArr.length(); i++) {
results.add(resultsArr.getString(i));
}
}
SearchSettings s = SearchSettings.parseJSON(settingsJson);
s.setOfflineIndexes(Collections.singletonList(reader));
SearchPhrase phrase = new SearchPhrase(s, OsmAndCollator.primaryCollator());
phrase = phrase.generateNewPhrase(phraseText, s);
final SearchUICore core = new SearchUICore(MapPoiTypes.getDefault(), "en", false);
core.init();
ResultMatcher<SearchResult> rm = new ResultMatcher<SearchResult>() {
@Override
public boolean publish(SearchResult object) {
return true;
}
@Override
public boolean isCancelled() {
return false;
}
};
SearchResultMatcher matcher = new SearchResultMatcher(rm, phrase, 1, new AtomicInteger(1), -1);
core.searchInternal(phrase, matcher);
SearchResultCollection collection = new SearchResultCollection(phrase);
collection.addSearchResults(matcher.getRequestResults(), true, true);
List<SearchResult> searchResults = collection.getCurrentSearchResults();
int i = 0;
for (SearchResult result : searchResults) {
String expected = results.get(i++);
String present = result.toString();
//System.out.println(present);
Assert.assertEquals(expected, present);
if (i >= results.size()) {
break;
}
}
}
private static class BinaryMapIndexReaderTest extends BinaryMapIndexReader {

View file

@ -12,17 +12,16 @@
"phrase": "48 Free Street Portland",
"results": [
"48.0, <input> ",
"48, Free Street (Downtown), Portland",
"48, Free Street (Downtown), Portland"
],
"extra-results": [
"48, Portland Street, North Berwick",
"48, Portland Avenue, Old Orchard Beach",
"Free Street (Downtown), Portland",
"Free Street (Ferry Village), South Portland",
"Portland Street",
"Portland Street (Downtown), Portland",
"Portland Street Pier, South Portland",
"Portland Street, Yarmouth",
"Portland Street, North Berwick",
"Portland Street, Berwick",
"Portland Street, South Berwick",
"Portland Street, Fryeburg",
"Portland Square, Portland"
"Portland Street, Yarmouth"
],
"amenities": [
{

File diff suppressed because it is too large Load diff

View file

@ -53,6 +53,109 @@
"Spring Street, Liberty",
"Spring Street (Livingston Manor), Rockland",
"Spring Street, Livingston Manor",
"Market Street, Cold Spring",
"New Street, Cold Spring",
"West Street, Cold Spring",
"Fish Street, Cold Spring",
"North Street, Cold Spring",
"Rock Street, Cold Spring",
"Stone Street, Cold Spring",
"Wall Street, Cold Spring",
"Cross Street, Cold Spring",
"Main Street, Cold Spring",
"Chestnut Street, Cold Spring",
"Furnace Street, Cold Spring",
"Garden Street, Cold Spring",
"Church Street, Cold Spring",
"Oak Street, Cold Spring",
"Cherry Street, Cold Spring",
"High Street, Cold Spring",
"Academy Street, Cold Spring",
"Haldane Street, Cold Spring",
"West Bank Street, Cold Spring",
"B Street, Cold Spring",
"West Belvedere Street, Cold Spring",
"Parrot Street, Cold Spring",
"Bank Street, Cold Spring",
"Orchard Street, Cold Spring",
"East Belvedere Street, Cold Spring",
"Pine Street, Cold Spring",
"Parsonage Street, Cold Spring",
"Hamilton Street, Cold Spring",
"Fair Street, Cold Spring",
"Cedar Street, Cold Spring",
"Flora Street, Cold Spring Harbor",
"West Main Street, Cold Spring Harbor",
"Grove Street, Cold Spring Harbor",
"Midland Street, Cold Spring Harbor",
"Rusco Street, Cold Spring Harbor",
"Main Street, Cold Spring Harbor",
"Chestnut Street, Cold Spring Harbor",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Academy Street, Cold Spring",
"Bank Street, Cold Spring",
"B Street, Cold Spring",
"Cedar Street, Cold Spring",
"Cherry Street, Cold Spring",
"Chestnut Street, Cold Spring",
"Church Street, Cold Spring",
"Cross Street, Cold Spring",
"East Belvedere Street, Cold Spring",
"Fair Street, Cold Spring",
"Fish Street, Cold Spring",
"Furnace Street, Cold Spring",
"Garden Street, Cold Spring",
"Haldane Street, Cold Spring",
"Hamilton Street, Cold Spring",
"High Street, Cold Spring",
"Main Street, Cold Spring",
"Market Street, Cold Spring",
"New Street, Cold Spring",
"North Street, Cold Spring",
"Oak Street, Cold Spring",
"Orchard Street, Cold Spring",
"Parrot Street, Cold Spring",
"Parsonage Street, Cold Spring",
"Pine Street, Cold Spring",
"Rock Street, Cold Spring",
"Stone Street, Cold Spring",
"Wall Street, Cold Spring",
"West Bank Street, Cold Spring",
"West Belvedere Street, Cold Spring",
"West Street, Cold Spring",
"Chestnut Street, Cold Spring Harbor",
"Flora Street, Cold Spring Harbor",
"Grove Street, Cold Spring Harbor",
"Main Street, Cold Spring Harbor",
"Midland Street, Cold Spring Harbor",
"Rusco Street, Cold Spring Harbor",
"Spring Street, Cold Spring Harbor",
"West Main Street, Cold Spring Harbor",
"Kraw Street, Spring Glen",
"Munro Street, Cold Spring",
"State Street, Cold Spring",
"Spring Street Salt Shed",
"6th Avenue & Spring Street",
"Spring Street Park",
"Broadway & Spring Street",
"Broadway/Spring Street",
"Spring Street Station (6) - Downtown",
"Spring Street Station (6) - Uptown & The Bronx",
"Richmond Road & Spring Street",
"West Spring Street School",
"Spring Street Gallery",
"Spring Street Apartments",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
@ -63,7 +166,6 @@
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street"
],
"amenities": [
{

View file

@ -7,8 +7,8 @@
android:layout_width="fill_parent"
android:layout_height="@dimen/dashboard_map_toolbar"
android:background="@color/app_bar_color_light"
app:contentInsetLeft="4dp"
app:contentInsetStart="4dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetRight="0dp"
app:contentInsetEnd="0dp">
@ -25,17 +25,18 @@
android:gravity="start"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
<ImageButton
android:id="@+id/toolbar_back"
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="@dimen/acceptable_touch_radius"
android:layout_height="@dimen/acceptable_touch_radius"
android:layout_marginStart="@dimen/list_item_button_padding"
android:layout_marginLeft="@dimen/list_item_button_padding"
android:layout_marginEnd="@dimen/list_item_button_padding"
android:layout_marginRight="@dimen/list_item_button_padding"
android:contentDescription="@string/back_to_map"
android:layout_marginLeft="@dimen/multi_selection_menu_padding_top"
android:layout_marginRight="@dimen/multi_selection_menu_padding_top"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="match_parent"
android:background="@drawable/dashboard_button_light"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_arrow_back"
tools:visibility="visible"/>
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/toolbar_list"
@ -53,6 +54,7 @@
android:id="@+id/toolbar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:scaleType="center"
android:textColor="@color/abc_primary_text_material_dark"
android:textSize="@dimen/abc_text_size_large_material"

View file

@ -21,14 +21,9 @@
<ImageButton
android:id="@+id/close_button"
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_width="@dimen/toolbar_height"
android:layout_height="@dimen/toolbar_height"
android:contentDescription="@string/access_shared_string_navigate_up"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_arrow_back" />
<LinearLayout

View file

@ -27,14 +27,9 @@
<ImageButton
android:id="@+id/close_button"
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_width="@dimen/toolbar_height"
android:layout_height="@dimen/toolbar_height"
android:contentDescription="@string/access_shared_string_navigate_up"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_arrow_back" />
<net.osmand.plus.widgets.TextViewEx

View file

@ -18,27 +18,26 @@
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="fill_parent"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:background="?attr/card_and_list_background_basic"
android:paddingRight="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:minHeight="@dimen/toolbar_height"
osmand:subtitleTextColor="?android:textColorPrimary"
osmand:theme="@style/ThemeOverlay.AppCompat.ActionBar"
osmand:titleTextColor="?android:textColorPrimary">
<androidx.appcompat.widget.AppCompatImageView
<ImageButton
android:id="@+id/toolbar_action"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="match_parent"
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="@dimen/acceptable_touch_radius"
android:layout_height="@dimen/acceptable_touch_radius"
android:layout_gravity="end"
android:contentDescription="@string/replace_all"
app:srcCompat="@drawable/ic_action_replace"
android:layout_marginRight="@dimen/content_padding_half"
android:layout_marginStart="@dimen/content_padding_half"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding" />
android:layout_marginStart="@dimen/list_item_button_padding"
android:layout_marginLeft="@dimen/list_item_button_padding"
android:layout_marginEnd="@dimen/list_item_button_padding"
android:layout_marginRight="@dimen/list_item_button_padding"
android:contentDescription="@string/access_shared_string_navigate_up"
app:srcCompat="@drawable/ic_action_replace" />
</androidx.appcompat.widget.Toolbar>

View file

@ -21,14 +21,9 @@
<ImageButton
android:id="@+id/close_button"
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_width="@dimen/toolbar_height"
android:layout_height="@dimen/toolbar_height"
android:contentDescription="@string/access_shared_string_navigate_up"
android:scaleType="fitCenter"
osmand:srcCompat="@drawable/ic_arrow_back"
android:tint="?attr/default_icon_color" />

View file

@ -27,14 +27,9 @@
<ImageButton
android:id="@+id/close_button"
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_width="@dimen/toolbar_height"
android:layout_height="@dimen/toolbar_height"
android:contentDescription="@string/access_shared_string_navigate_up"
android:scaleType="fitCenter"
osmand:srcCompat="@drawable/ic_arrow_back"
android:tint="?attr/default_icon_color" />

View file

@ -23,7 +23,7 @@
<string name="parking_positions">Parking positions</string>
<string name="create_edit_poi">Create / Edit POI</string>
<string name="quick_action_transport_descr">Button showing or hiding public transport on the map.</string>
<string name="quick_action_show_hide_transport">Show / hide public transport</string>
<string name="quick_action_show_hide_transport">Show/hide public transport</string>
<string name="quick_action_transport_show">Show public transport</string>
<string name="quick_action_transport_hide">Hide public transport</string>
<string name="release_3_7">

View file

@ -1161,7 +1161,6 @@ public class MapMarkersHelper {
removeGroupActiveMarkers(group, true);
return;
}
for (FavouritePoint fp : favGroup.getPoints()) {
addNewMarkerIfNeeded(group, groupMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), fp, null);
}

View file

@ -132,7 +132,7 @@ public class ContributionVersionActivity extends OsmandListActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(ACTIVITY_TO_INSTALL == requestCode && resultCode != RESULT_OK){
if (ACTIVITY_TO_INSTALL == requestCode && resultCode != RESULT_OK && currentInstalledDate != null) {
updateInstalledApp(false, currentInstalledDate);
}
}

View file

@ -24,6 +24,7 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ListView;
@ -49,13 +50,11 @@ import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.ValueHolder;
import net.osmand.data.LatLon;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnRowItemClick;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
@ -78,6 +77,8 @@ import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.LocalRoutingParameter;
import net.osmand.plus.routing.IRouteInformationListener;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.srtmplugin.ContourLinesMenu;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.srtmplugin.TerrainFragment;
@ -340,7 +341,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
UiUtilities iconsCache = mapActivity.getMyApplication().getUIUtilities();
ImageView lst = (ImageView) dashboardView.findViewById(R.id.toolbar_list);
lst.setVisibility(View.GONE);
ImageView back = (ImageView) dashboardView.findViewById(R.id.toolbar_back);
ImageButton back = (ImageButton) dashboardView.findViewById(R.id.toolbar_back);
Drawable icBack = getMyApplication().getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(mapActivity));
back.setImageDrawable(icBack);
back.setOnClickListener(new View.OnClickListener() {

View file

@ -37,9 +37,6 @@ import net.osmand.plus.DialogListItemAdapter;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings.ListStringPreference;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
@ -51,6 +48,9 @@ import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
import net.osmand.plus.render.RendererRegistry;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings.ListStringPreference;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.transport.TransportLinesMenu;
import net.osmand.plus.views.OsmandMapTileView;
@ -529,6 +529,9 @@ public class ConfigureMapMenu {
@Override
public boolean onContextMenuClick(final ArrayAdapter<ContextMenuItem> ad, int itemId,
final int pos, boolean isChecked, int[] viewCoordinates) {
if (!AndroidUtils.isActivityNotDestroyed(activity)) {
return false;
}
final OsmandMapTileView view = activity.getMapView();
AlertDialog.Builder bld = new AlertDialog.Builder(new ContextThemeWrapper(view.getContext(), themeRes));
bld.setTitle(R.string.daynight);
@ -570,6 +573,9 @@ public class ConfigureMapMenu {
@Override
public boolean onContextMenuClick(final ArrayAdapter<ContextMenuItem> ad, int itemId,
final int pos, boolean isChecked, int[] viewCoordinates) {
if (!AndroidUtils.isActivityNotDestroyed(activity)) {
return false;
}
final OsmandMapTileView view = activity.getMapView();
final OsmandSettings.OsmandPreference<Float> mapDensity = view.getSettings().MAP_DENSITY;
AlertDialog.Builder bld = new AlertDialog.Builder(new ContextThemeWrapper(view.getContext(), themeRes));
@ -638,6 +644,9 @@ public class ConfigureMapMenu {
@Override
public boolean onContextMenuClick(final ArrayAdapter<ContextMenuItem> ad, int itemId,
final int pos, boolean isChecked, int[] viewCoordinates) {
if (!AndroidUtils.isActivityNotDestroyed(activity)) {
return false;
}
final OsmandMapTileView view = activity.getMapView();
AlertDialog.Builder b = new AlertDialog.Builder(new ContextThemeWrapper(view.getContext(), themeRes));
// test old descr as title
@ -682,6 +691,9 @@ public class ConfigureMapMenu {
@Override
public boolean onContextMenuClick(final ArrayAdapter<ContextMenuItem> ad, int itemId,
final int pos, boolean isChecked, int[] viewCoordinates) {
if (!AndroidUtils.isActivityNotDestroyed(activity)) {
return false;
}
final OsmandMapTileView view = activity.getMapView();
AlertDialog.Builder b = new AlertDialog.Builder(new ContextThemeWrapper(view.getContext(), themeRes));
@ -991,7 +1003,9 @@ public class ConfigureMapMenu {
final int themeRes,
final boolean nightMode,
@ColorInt final int selectedProfileColor) {
if (!AndroidUtils.isActivityNotDestroyed(activity)) {
return;
}
AlertDialog.Builder bld = new AlertDialog.Builder(new ContextThemeWrapper(activity, themeRes));
boolean[] checkedItems = new boolean[prefs.size()];
final boolean[] tempPrefs = new boolean[prefs.size()];
@ -1246,6 +1260,9 @@ public class ConfigureMapMenu {
@Override
public boolean onContextMenuClick(final ArrayAdapter<ContextMenuItem> ad,
final int itemId, final int pos, boolean isChecked, int[] viewCoordinates) {
if (!AndroidUtils.isActivityNotDestroyed(activity)) {
return false;
}
AlertDialog.Builder b = new AlertDialog.Builder(new ContextThemeWrapper(view.getContext(), themeRes));
// test old descr as title
b.setTitle(propertyDescr);

View file

@ -525,7 +525,7 @@ public class PlanRouteFragment extends BaseOsmAndFragment implements OsmAndLocat
if (loc != null) {
end = TargetPoint.createStartPoint(new LatLon(loc.getLatitude(), loc.getLongitude()),
new PointDescription(PointDescription.POINT_TYPE_MY_LOCATION,
getString(R.string.shared_string_my_location)));
mapActivity.getString(R.string.shared_string_my_location)));
}
}
if (end != null) {

View file

@ -617,6 +617,10 @@ public class PoiFiltersHelper {
}
public void loadSelectedPoiFilters() {
// don't deal with not loaded poi types
if(!application.getPoiTypes().isInit()) {
return;
}
selectedPoiFilters.clear();
OsmandSettings settings = application.getSettings();
Set<String> filters = settings.getSelectedPoiFilters();

View file

@ -16,7 +16,7 @@ import net.osmand.plus.quickaction.QuickActionType;
public class TerrainAction extends QuickAction {
public static final QuickActionType TYPE = new QuickActionType(30,
"contourlines.showhide", TerrainAction.class).
"terrain.showhide", TerrainAction.class).
nameRes(R.string.quick_action_show_hide_hillshade).iconRes(R.drawable.ic_action_hillshade_dark).nonEditable().
category(QuickActionType.CONFIGURE_MAP);

View file

@ -395,7 +395,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe
}
if (this.nightMode != nightMode) {
this.nightMode = nightMode;
updateQuickActionButton(currentWidgetState);
updateQuickActionButton(currentWidgetState != null && currentWidgetState);
}
setupQuickActionBtnVisibility();
}