Merge remote-tracking branch 'origin/master' into map_source_dialog_7658

# Conflicts:
#	OsmAnd/res/values/strings.xml
This commit is contained in:
veliymolfar 2020-05-27 09:59:47 +03:00
commit 6be3458ad3
194 changed files with 16534 additions and 1884 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

@ -651,6 +651,10 @@ public class SearchUICore {
this.parentSearchResult = parentSearchResult;
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();
@ -848,12 +853,121 @@ public class SearchUICore {
return json;
}
}
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;
@ -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) {
unknownWordsMatcher.add(new NameStringMatcher(unknownWords.get(i),
i < unknownWords.size() - 1 || isLastUnknownSearchWordComplete() ? StringMatcherMode.CHECK_EQUALS_FROM_SPACE :
StringMatcherMode.CHECK_STARTS_FROM_SPACE));
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));
}
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) {
double res = 0;
isHouse = isHouse || objectType == ObjectType.HOUSE;
// if result is a complete match in the search we prioritize it highers
double res = 0;
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;
private File testFile;
static {
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,178 +70,29 @@ public class SearchCoreUITest {
e.printStackTrace();
}
poiTypes.setPoiTranslator(new MapPoiTypes.PoiTranslator() {
@Override
public String getTranslation(AbstractPoiType type) {
AbstractPoiType baseLangType = type.getBaseLangType();
if (baseLangType != null) {
return getTranslation(baseLangType) + " (" + type.getLang().toLowerCase() + ")";
}
return getTranslation(type.getIconKeyName());
}
@Override
public String getTranslation(String keyName) {
String val = phrases.get("poi_" + keyName);
if (val != null) {
int ind = val.indexOf(';');
if (ind > 0) {
return val.substring(0, ind);
}
}
return val;
}
@Override
public String getSynonyms(AbstractPoiType type) {
AbstractPoiType baseLangType = type.getBaseLangType();
if (baseLangType != null) {
return getSynonyms(baseLangType);
}
return getSynonyms(type.getIconKeyName());
}
@Override
public String getSynonyms(String keyName) {
String val = phrases.get("poi_" + keyName);
if (val != null) {
int ind = val.indexOf(';');
if (ind > 0) {
return val.substring(ind + 1);
}
return "";
}
return null;
}
@Override
public String getEnTranslation(AbstractPoiType type) {
AbstractPoiType baseLangType = type.getBaseLangType();
if (baseLangType != null) {
return getEnTranslation(baseLangType) + " (" + type.getLang().toLowerCase() + ")";
}
return getEnTranslation(type.getIconKeyName());
}
@Override
public String getEnTranslation(String keyName) {
if (enPhrases.isEmpty()) {
return Algorithms.capitalizeFirstLetter(keyName.replace('_', ' '));
}
String val = enPhrases.get("poi_" + keyName);
if (val != null) {
int ind = val.indexOf(';');
if (ind > 0) {
return val.substring(0, ind);
}
}
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));
poiTypes.setPoiTranslator(new TestSearchTranslator(phrases, enPhrases));
}
@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);
@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;
}
private void testSearchImpl(File jsonFile) throws IOException, JSONException {
@Test
public void testSearch() throws IOException, JSONException {
File jsonFile = testFile;
String sourceJsonText = Algorithms.getFileAsString(jsonFile);
Assert.assertNotNull(sourceJsonText);
Assert.assertTrue(sourceJsonText.length() > 0);
@ -277,6 +142,12 @@ public class SearchCoreUITest {
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));
@ -308,7 +179,15 @@ public class SearchCoreUITest {
for (SearchResult result : searchResults) {
String expected = results.get(i++);
String present = result.toString();
//System.out.println(present);
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;
@ -316,6 +195,84 @@ public class SearchCoreUITest {
}
}
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) {
AbstractPoiType baseLangType = type.getBaseLangType();
if (baseLangType != null) {
return getTranslation(baseLangType) + " (" + type.getLang().toLowerCase() + ")";
}
return getTranslation(type.getIconKeyName());
}
@Override
public String getTranslation(String keyName) {
String val = phrases.get("poi_" + keyName);
if (val != null) {
int ind = val.indexOf(';');
if (ind > 0) {
return val.substring(0, ind);
}
}
return val;
}
@Override
public String getSynonyms(AbstractPoiType type) {
AbstractPoiType baseLangType = type.getBaseLangType();
if (baseLangType != null) {
return getSynonyms(baseLangType);
}
return getSynonyms(type.getIconKeyName());
}
@Override
public String getSynonyms(String keyName) {
String val = phrases.get("poi_" + keyName);
if (val != null) {
int ind = val.indexOf(';');
if (ind > 0) {
return val.substring(ind + 1);
}
return "";
}
return null;
}
@Override
public String getEnTranslation(AbstractPoiType type) {
AbstractPoiType baseLangType = type.getBaseLangType();
if (baseLangType != null) {
return getEnTranslation(baseLangType) + " (" + type.getLang().toLowerCase() + ")";
}
return getEnTranslation(type.getIconKeyName());
}
@Override
public String getEnTranslation(String keyName) {
if (enPhrases.isEmpty()) {
return Algorithms.capitalizeFirstLetter(keyName.replace('_', ' '));
}
String val = enPhrases.get("poi_" + keyName);
if (val != null) {
int ind = val.indexOf(';');
if (ind > 0) {
return val.substring(0, ind);
}
}
return val;
}
};
private static class BinaryMapIndexReaderTest extends BinaryMapIndexReader {
List<Amenity> amenities = Collections.emptyList();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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",
"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"
"Free Street (Downtown), Portland",
"Free Street (Ferry Village), South Portland",
"Portland Street",
"Portland Street (Downtown), Portland",
"Portland Street Pier, South Portland",
"Portland Street, Yarmouth"
],
"amenities": [
{

View file

@ -11,42 +11,69 @@
},
"phrase": "Calle de las eras 5, Navacerrada",
"results": [
"5, Calle de las Eras (Uranización Los Corales), Navacerrada",
"5, Calle Navacerrada (Urb. Las Suertes), Las Suertes",
"50, Calle de Francisco Navacerrada, Salamanca",
"52, Calle de Francisco Navacerrada, Salamanca",
"53, Calle de Francisco Navacerrada, Salamanca",
"54, Calle de Francisco Navacerrada, Salamanca",
"55, Calle de Francisco Navacerrada, Salamanca",
"56, Calle de Francisco Navacerrada, Salamanca",
"57, Calle de Francisco Navacerrada, Salamanca",
"58, Calle de Francisco Navacerrada, Salamanca",
"59, Calle de Francisco Navacerrada, Salamanca",
"Calle del Puerto de Navacerrada, Las Nieves",
"Calle Puerto de Navacerrada, La Poveda",
"Calle del Embalse de Navacerrada, Villa de Vallecas",
"Calle del Puerto de Navacerrada, Puente de Vallecas",
"Calle de Francisco Navacerrada, Salamanca",
"Calle de Navacerrada, Moraleja de Enmedio",
"Calle Navacerrada (Urb. Las Suertes), Las Suertes",
"Calle Puerto de Navacerrada, Roman Candelas",
"Calle Navacerrada, Becerril de la Sierra",
"Carretera de Collado Villalba a Navacerrada, El Baillo y las Hojarascas",
"Calle Navacerrada (Cerceda), El Boalo",
"Calle Navacerrada (El Pedregal), Bustarviejo",
"Calle Navacerrada, Buitrago del Lozoya",
"Carretera de Colmenar Viejo a Navacerrada, Becerril de la Sierra",
"Carretera de Colmenar Viejo a Navacerrada, Manzanares el Real",
"Carretera de Collado Villalba a Navacerrada, Dehesa Boyal",
"Carretera de Collado Villalba a Navacerrada, Polideportivo Dehesa Boyal",
"Carretera de Navacerrada, Jazmines",
"Carretera de Colmenar Viejo a Navacerrada (Cerceda), El Boalo",
"Carretera de Collado Villalba a Navacerrada, Cerca de Cascarrilla",
"Carretera de Navacerrada, El Boalo",
"Carretera de Collado Villalba a Navacerrada, Collado Mediano",
"Camino de Navacerrada (Serranía de la Paloma), Collado Mediano",
"Camino de Los Molinos a Navacerrada, Collado Mediano",
"Carretera de Collado Villalba a Navacerrada, Navacerrada"
"5, Calle de las Eras (Uranización Los Corales), Navacerrada"
],
"extra-results": [
"Calle de las Eras (Uranización Los Corales), Navacerrada",
"Calle del Sotillo (Uranización Los Corales), Pasaje de las Eras (Uranización Los Corales), Navacerrada",
"Calle del Puerto de Navacerrada, Las Nieves",
"5, Calle Navacerrada (Urb. Las Suertes), Las Suertes",
"50, Calle de Francisco Navacerrada, Salamanca",
"52, Calle de Francisco Navacerrada, Salamanca",
"53, Calle de Francisco Navacerrada, Salamanca",
"54, Calle de Francisco Navacerrada, Salamanca",
"55, Calle de Francisco Navacerrada, Salamanca",
"56, Calle de Francisco Navacerrada, Salamanca",
"57, Calle de Francisco Navacerrada, Salamanca",
"58, Calle de Francisco Navacerrada, Salamanca",
"59, Calle de Francisco Navacerrada, Salamanca",
"Pasaje de las Eras (Uranización Los Corales), Navacerrada",
"Calle Barrio de las Peñas, Navacerrada",
"Calle de las Cruces (Residencial Sanabria), Navacerrada",
"Calle de las Escuelas, Navacerrada",
"Calle de las Huertas (Residencial Sanabria), Navacerrada",
"Calle de la Virgen de las Nieves, Puerto de Navacerrada",
"Calle Puerto de Navacerrada, La Poveda",
"Calle del Embalse de Navacerrada, Villa de Vallecas",
"Calle del Puerto de Navacerrada, Puente de Vallecas",
"Calle de Francisco Navacerrada, Salamanca",
"Calle de Navacerrada, Moraleja de Enmedio",
"Calle Navacerrada (Urb. Las Suertes), Las Suertes",
"Calle Puerto de Navacerrada, Roman Candelas",
"Calle Navacerrada, Becerril de la Sierra",
"Carretera de Collado Villalba a Navacerrada, El Baillo y las Hojarascas",
"Calle de Ángel Rojas, Navacerrada",
"Calle de los Robles (Uranización Los Corales), Navacerrada",
"Calle de los Enebros (Uranización Los Corales), Navacerrada",
"Calle de la Bola del Mundo (Residencial Sanabria), Navacerrada",
"Calle de la Maliciosa (Residencial Sanabria), Navacerrada",
"Calle de la Perdiz, Navacerrada",
"Calle de la Magdalena, Navacerrada",
"Calle las Jaras, Navacerrada",
"Calle de la Audiencia, Navacerrada",
"Calle de Prado Jerez, Navacerrada",
"Calle de Carmen Conde (Residencial Sanabria), Navacerrada",
"Calle de la Iglesia, Navacerrada",
"Calle de la Tejera, Navacerrada",
"Calle de la Encinilla, Navacerrada",
"Calle de la Canaleja (Residencial Sanabria), Navacerrada",
"Calle de Rafael Alvarado, Navacerrada",
"Calle de Andrés Segovia, Navacerrada",
"Calle de los Pradillos (Residencial Sanabria), Navacerrada",
"Calle de Abel, Navacerrada",
"Calle Praderas de San Sebastián, Navacerrada",
"Calle de San Sebastián (Residencial Sanabria), Navacerrada",
"Calle de Álvaro Iglesia, Navacerrada",
"Calle de los Arcos, Navacerrada",
"Calle de Peñalara, Puerto de Navacerrada",
"Calle de la Bola del Mundo, Puerto de Navacerrada",
"Calle de la Estación, Puerto de Navacerrada",
"Calle Ginos, Puerto de Navacerrada",
"Calle Vitoria, Puerto de Navacerrada",
"Calle Dos Castillas, Puerto de Navacerrada",
"Travesía de las Huertas, Navacerrada",
"Vereda de las Encinillas, Navacerrada",
"Centro Municipal de Mayores «Navacerrada»",
],
"amenities": [
{

View file

@ -11,59 +11,161 @@
},
"phrase": "spring street",
"results": [
"Spring (Natural)",
"Spring (Spring / Natural)",
"Spring (Ice rink / Sport)",
"Spring (Bridge / Transport construction)",
"Spring Street, South Nyack",
"Spring Street, Tomkins Cove",
"Spring Street, Southfields",
"Spring Street, Hastings-on-Hudson",
"Spring Street, Pleasantville",
"Spring Street (Mount Pleasant), Hawthorne",
"Spring Street, Durland",
"Spring Street, Warwick",
"Spring Street, Nelsonville",
"Spring Street, Goshen",
"Spring Street (Little Italy), Manhattan",
"Spring Street, Maybrook",
"West Spring Street, Maybrook",
"Spring Street, South Salem",
"Spring Street, Groveville",
"Spring Street, East Middletown",
"Spring Street, Montgomery",
"Spring Street, Chelsea",
"Spring Street, Wappingers Falls",
"Spring Street, Cold Spring Harbor",
"Spring Street, Staten Island",
"Spring Street, East Meadow",
"Spring Street, Inwood",
"Spring Street, Port Jervis",
"Spring Street, Roosevelt",
"Spring Street, Pawling",
"Spring Street, Fairview",
"Spring Street (Wyandanch), Wheatley Heights",
"Spring Street, Wyandanch",
"Spring Street, East Massapequa",
"Spring Street, Ellenville",
"Spring Street, Monticello",
"Spring Street, Tillson",
"Spring Street, Port Jefferson",
"Spring Street (Smallwood), Bethel",
"Spring Street, Liberty",
"Spring Street (Livingston Manor), Rockland",
"Spring Street, Livingston Manor",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street"
"Spring (Natural)",
"Spring (Spring / Natural)",
"Spring (Ice rink / Sport)",
"Spring (Bridge / Transport construction)",
"Spring Street, South Nyack",
"Spring Street, Tomkins Cove",
"Spring Street, Southfields",
"Spring Street, Hastings-on-Hudson",
"Spring Street, Pleasantville",
"Spring Street (Mount Pleasant), Hawthorne",
"Spring Street, Durland",
"Spring Street, Warwick",
"Spring Street, Nelsonville",
"Spring Street, Goshen",
"Spring Street (Little Italy), Manhattan",
"Spring Street, Maybrook",
"West Spring Street, Maybrook",
"Spring Street, South Salem",
"Spring Street, Groveville",
"Spring Street, East Middletown",
"Spring Street, Montgomery",
"Spring Street, Chelsea",
"Spring Street, Wappingers Falls",
"Spring Street, Cold Spring Harbor",
"Spring Street, Staten Island",
"Spring Street, East Meadow",
"Spring Street, Inwood",
"Spring Street, Port Jervis",
"Spring Street, Roosevelt",
"Spring Street, Pawling",
"Spring Street, Fairview",
"Spring Street (Wyandanch), Wheatley Heights",
"Spring Street, Wyandanch",
"Spring Street, East Massapequa",
"Spring Street, Ellenville",
"Spring Street, Monticello",
"Spring Street, Tillson",
"Spring Street, Port Jefferson",
"Spring Street (Smallwood), Bethel",
"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",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
"Spring Street",
],
"amenities": [
{

View file

@ -18,7 +18,7 @@
<string name="share_location_as">Standort teilen als</string>
<string name="live_now_description">Kontakte und Gruppen, die ihren Standort mit Ihnen teilen.</string>
<string name="logout_from_osmand_telegram">Aus OsmAnd Tracker abmelden\?</string>
<string name="shared_string_name">"Name "</string>
<string name="shared_string_name">Name</string>
<string name="by_distance">Nach Entfernung</string>
<string name="by_name">Nach Namen</string>
<string name="by_group">Nach Gruppe</string>
@ -44,7 +44,7 @@
<string name="send_my_location">Meinen Standort senden</string>
<string name="gps_and_location">Position</string>
<string name="open_osmand">OsmAnd öffnen</string>
<string name="shared_string_live">"Live "</string>
<string name="shared_string_live">Live</string>
<string name="get_telegram_title">Registrierung in Telegram</string>
<string name="get_telegram_account_first">Sie benötigen ein Telegram-Konto, um die Standortfreigabe nutzen zu können.</string>
<string name="get_telegram_description_continue">Bitte installieren Sie Telegram und richten Sie ein Konto ein.</string>
@ -151,9 +151,7 @@
<string name="start_location_sharing">Standort freigeben</string>
<string name="location_service_no_gps_available">Wählen Sie einen der Standortanbieter aus, um Ihren Standort freizugeben.</string>
<string name="sharing_location">Standort teilen</string>
<string name="welcome_descr">
<b>OsmAnd Tracker</b> ermöglicht es Ihnen, Ihren Standort zu teilen und den anderer in OsmAnd zu sehen.<br/>
<br/>Die App verwendet die API von Telegram, also benötigen Sie ein Telegram-Konto.</string>
<string name="welcome_descr"><b>OsmAnd Tracker</b> ermöglicht es Ihnen, Ihren Standort zu teilen und den anderer in OsmAnd zu sehen.<br/> <br/>Die App verwendet die API von Telegram, also benötigen Sie ein Telegram-Konto.</string>
<string name="enter_another_device_name">Wählen Sie einen Namen, den Sie noch nicht benutzt haben</string>
<string name="device_added_successfully">%1$s hinzugefügt.</string>
<string name="shared_string_add">Hinzufügen</string>

View file

@ -216,4 +216,13 @@
<string name="search_contacts_descr">Procura en tódolos teus grupos e contactos.</string>
<string name="type_contact_or_group_name">Escribe o nome do contacto ou do grupo</string>
<string name="shared_string_search">Procurar</string>
<string name="status_widget_title">Estado do Rastrexador do OsmAnd</string>
<string name="shared_string_suggested">Suxerido</string>
<string name="back_to_osmand">Voltar ó OsmAnd</string>
<string name="duration_ago">hai %1$s</string>
<string name="last_response_duration">Última resposta: hai %1$s</string>
<string name="last_update_from_telegram_duration">Última actualización dende o Telegram: hai %1$s</string>
<string name="last_response_date">Última resposta: %1$s</string>
<string name="last_update_from_telegram_date">Última actualización dende o Telegram: %1$s</string>
<string name="shared_string_error_short">ERR</string>
</resources>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

View file

@ -4,7 +4,7 @@
<item android:drawable="@color/map_background_color_light"/>
<item android:top="@dimen/splash_screen_logo_top">
<bitmap
android:gravity="center_horizontal|top"
android:gravity="center"
android:src="@drawable/ic_logo_splash_osmand"/>
</item>
</layer-list>

View file

@ -4,7 +4,7 @@
<item android:drawable="@color/map_background_color_light"/>
<item android:top="@dimen/splash_screen_logo_top">
<bitmap
android:gravity="center_horizontal|top"
android:gravity="center"
android:src="@drawable/ic_logo_splash_osmand"/>
</item>
</layer-list>

View file

@ -4,7 +4,7 @@
<item android:drawable="@color/map_background_color_light"/>
<item android:top="@dimen/splash_screen_logo_top">
<bitmap
android:gravity="center_horizontal|top"
android:gravity="center"
android:src="@drawable/ic_logo_splash_osmand_plus"/>
</item>
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11,3H5C3.8954,3 3,3.8954 3,5V19C3,20.1046 3.8954,21 5,21H19C20.1046,21 21,20.1046 21,19V13H19V19H5V5H11V3Z"
android:strokeAlpha="0.7"
android:fillColor="#ffffff"
android:fillAlpha="0.7"/>
<path
android:pathData="M13.0001,3H21.0001V11H19.0001V6.4142L11.7072,13.7071L10.293,12.2929L17.5859,5H13.0001V3Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M22,22V5C22,3.3431 20.6569,2 19,2H5C3.3431,2 2,3.3431 2,5V22H4V7H20V22H22Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M4,7h16v15h-16z"
android:strokeAlpha="0.2"
android:fillColor="#ffffff"
android:fillAlpha="0.2"/>
<path
android:pathData="M20,7H4V16H20V7ZM9,10V8.58C9,8.2597 8.7403,8 8.42,8C8.1486,8 7.8858,8.0951 7.6774,8.2689L5.3841,10.1799C5.1407,10.3827 5,10.6832 5,11C5,11.3168 5.1407,11.6173 5.3841,11.8201L7.6774,13.7311C7.8858,13.9049 8.1486,14 8.42,14C8.7403,14 9,13.7403 9,13.42L9,12H10C10.5523,12 11,12.4477 11,13V14C11,14.5523 11.4477,15 12,15C12.5523,15 13,14.5523 13,14V13C13,11.3431 11.6569,10 10,10H9ZM14,11C14,10.4477 14.4477,10 15,10H18C18.5523,10 19,10.4477 19,11C19,11.5523 18.5523,12 18,12H15C14.4477,12 14,11.5523 14,11Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2,2V8H16V22H19V5C19,3.3431 17.6569,2 16,2H2Z"
android:strokeAlpha="0.7"
android:fillColor="#ffffff"
android:fillAlpha="0.7"/>
<path
android:pathData="M2,8h14v14h-14z"
android:strokeAlpha="0.2"
android:fillColor="#ffffff"
android:fillAlpha="0.2"/>
<path
android:pathData="M19,8H19.5C19.7761,8 20,8.2239 20,8.5V15.5C20,15.7761 19.7761,16 19.5,16H19V8Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,45 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M7,19C7,20.1046 6.1046,21 5,21C3.8954,21 3,20.1046 3,19C3,17.8954 3.8954,17 5,17C6.1046,17 7,17.8954 7,19Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M14,19C14,20.1046 13.1046,21 12,21C10.8954,21 10,20.1046 10,19C10,17.8954 10.8954,17 12,17C13.1046,17 14,17.8954 14,19Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M19,21C20.1046,21 21,20.1046 21,19C21,17.8954 20.1046,17 19,17C17.8954,17 17,17.8954 17,19C17,20.1046 17.8954,21 19,21Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M7,12C7,13.1046 6.1046,14 5,14C3.8954,14 3,13.1046 3,12C3,10.8954 3.8954,10 5,10C6.1046,10 7,10.8954 7,12Z"
android:strokeAlpha="0.7"
android:fillColor="#ffffff"
android:fillAlpha="0.7"/>
<path
android:pathData="M14,12C14,13.1046 13.1046,14 12,14C10.8954,14 10,13.1046 10,12C10,10.8954 10.8954,10 12,10C13.1046,10 14,10.8954 14,12Z"
android:strokeAlpha="0.7"
android:fillColor="#ffffff"
android:fillAlpha="0.7"/>
<path
android:pathData="M19,14C20.1046,14 21,13.1046 21,12C21,10.8954 20.1046,10 19,10C17.8954,10 17,10.8954 17,12C17,13.1046 17.8954,14 19,14Z"
android:strokeAlpha="0.7"
android:fillColor="#ffffff"
android:fillAlpha="0.7"/>
<path
android:pathData="M7,5C7,6.1046 6.1046,7 5,7C3.8954,7 3,6.1046 3,5C3,3.8954 3.8954,3 5,3C6.1046,3 7,3.8954 7,5Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M14,5C14,6.1046 13.1046,7 12,7C10.8954,7 10,6.1046 10,5C10,3.8954 10.8954,3 12,3C13.1046,3 14,3.8954 14,5Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M19,7C20.1046,7 21,6.1046 21,5C21,3.8954 20.1046,3 19,3C17.8954,3 17,3.8954 17,5C17,6.1046 17.8954,7 19,7Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,23L6,12H8.2782L12,18.8233L15.7218,12H18L12,23Z"
android:fillColor="#505050"
android:fillType="evenOdd"/>
<path
android:pathData="M18,12L12,1L6,12H18Z"
android:fillColor="#E53935"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4.1161,21.9676L12,19.7647L19.8839,21.9676C19.9609,21.9891 20.0406,22 20.1206,22H20.1832C20.6343,22 21,21.6343 21,21.1832C21,21.0626 20.9733,20.9434 20.9218,20.8344L12.7135,3.4521C12.5832,3.1761 12.3053,3 12,3C11.6947,3 11.4168,3.1761 11.2865,3.4521L3.0782,20.8344C3.0267,20.9434 3,21.0626 3,21.1832C3,21.6343 3.3657,22 3.8168,22H3.8795C3.9594,22 4.0391,21.9891 4.1161,21.9676Z"
android:fillColor="#536DFE"/>
<path
android:pathData="M10,17V11H11L13,15V11H14V17H13L11,13V17H10Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4.1161,21.9676L12,19.7647L19.8839,21.9676C19.9609,21.9891 20.0406,22 20.1206,22H20.1832C20.6343,22 21,21.6343 21,21.1832C21,21.0626 20.9733,20.9434 20.9218,20.8344L12.7135,3.4521C12.5832,3.1761 12.3053,3 12,3C11.6947,3 11.4168,3.1761 11.2865,3.4521L3.0782,20.8344C3.0267,20.9434 3,21.0626 3,21.1832C3,21.6343 3.3657,22 3.8168,22H3.8795C3.9594,22 4.0391,21.9891 4.1161,21.9676Z"
android:fillColor="#536DFE"/>
<path
android:pathData="M10,17V11H11L13,15V11H14V17H13L11,13V17H10Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M16,10L12,3L8,10H16Z"
android:fillColor="#E53935"/>
<path
android:pathData="M8,21V12H10L14,18V12H16V21H14L10,15V21H8Z"
android:fillColor="#505050"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M16,10L12,3L8,10H16Z"
android:fillColor="#E53935"/>
<path
android:pathData="M8,21V12H10L14,18V12H16V21H14L10,15V21H8Z"
android:fillColor="#CCCCCC"/>
</vector>

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,23L6,12H8.2782L12,18.8233L15.7218,12H18L12,23Z"
android:fillColor="#CCCCCC"
android:fillType="evenOdd"/>
<path
android:pathData="M18,12L12,1L6,12H18Z"
android:fillColor="#E53935"/>
</vector>

View file

@ -5,6 +5,6 @@
android:viewportHeight="24">
<path
android:pathData="M5,3C3.8954,3 3,3.8954 3,5V19C3,20.1046 3.8954,21 5,21H19C20.1046,21 21,20.1046 21,19V5C21,3.8954 20.1046,3 19,3H5ZM19,5H5V19H19V5ZM7,7H11V11H7V7ZM17,7H13V11H17V7ZM7,13H11V17H7V13ZM17,13H13V17H17V13Z"
android:fillColor="#727272"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -5,5 +5,5 @@
android:viewportHeight="24">
<path
android:pathData="M13,2H11V11H2V13H11V22H13V13H22V11H13V2Z"
android:fillColor="#727272"/>
android:fillColor="#ffffff"/>
</vector>

View file

@ -5,5 +5,5 @@
android:viewportHeight="24">
<path
android:pathData="M22,11l-0,2l-20,0l-0,-2z"
android:fillColor="#727272"/>
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,25 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2,19L22,19V21C22,22.1046 21.1046,23 20,23H4C2.8954,23 2,22.1046 2,21V19Z"
android:fillColor="#ffffff"
android:fillAlpha="0.3"/>
<path
android:pathData="M2,4C2,2.8954 2.8954,2 4,2H20C21.1046,2 22,2.8954 22,4V20C22,21.1046 21.1046,22 20,22H4C2.8954,22 2,21.1046 2,20V4Z"
android:fillColor="#59361B"/>
<path
android:pathData="M4,4H20V20H4V4Z"
android:fillColor="#FFC107"/>
<path
android:pathData="M6,10H9V11H7V12H9V13H7V15H6V12.5V10ZM10,10H12.5C13.3284,10 14,10.6716 14,11.5C14,12.3284 13.3284,13 12.5,13H11V15H10V12.5V10ZM11,12H12.5C12.7761,12 13,11.7761 13,11.5C13,11.2239 12.7761,11 12.5,11H11V12ZM16,10C15.4477,10 15,10.4477 15,11V12C15,12.5523 15.4477,13 16,13H17V14H15V15H17C17.5523,15 18,14.5523 18,14V13C18,12.4477 17.5523,12 17,12H16V11H18V10H16Z"
android:fillColor="#ffffff"
android:fillAlpha="0.3"
android:fillType="evenOdd"/>
<path
android:pathData="M6,9H6.5H9V10H7V11H9V12H7V14H6V11.5V9.5V9ZM10,9H10.5H12.5C13.3284,9 14,9.6716 14,10.5C14,11.3284 13.3284,12 12.5,12H11V14H10V11.5V9.5V9ZM11,11H12.5C12.7761,11 13,10.7761 13,10.5C13,10.2239 12.7761,10 12.5,10H11V11ZM16,9C15.4477,9 15,9.4477 15,10V11C15,11.5523 15.4477,12 16,12H17V13H15V14H17C17.5523,14 18,13.5523 18,13V12C18,11.4477 17.5523,11 17,11H16V10H18V9H16Z"
android:fillColor="#59361B"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,25 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2,19L22,19V21C22,22.1046 21.1046,23 20,23H4C2.8954,23 2,22.1046 2,21V19Z"
android:fillColor="#000000"
android:fillAlpha="0.3"/>
<path
android:pathData="M2,4C2,2.8954 2.8954,2 4,2H20C21.1046,2 22,2.8954 22,4V20C22,21.1046 21.1046,22 20,22H4C2.8954,22 2,21.1046 2,20V4Z"
android:fillColor="#FFC107"/>
<path
android:pathData="M4,4H20V20H4V4Z"
android:fillColor="#59361B"/>
<path
android:pathData="M6,10H9V11H7V12H9V13H7V15H6V12.5V10ZM10,10H12.5C13.3284,10 14,10.6716 14,11.5C14,12.3284 13.3284,13 12.5,13H11V15H10V12.5V10ZM11,12H12.5C12.7761,12 13,11.7761 13,11.5C13,11.2239 12.7761,11 12.5,11H11V12ZM16,10C15.4477,10 15,10.4477 15,11V12C15,12.5523 15.4477,13 16,13H17V14H15V15H17C17.5523,15 18,14.5523 18,14V13C18,12.4477 17.5523,12 17,12H16V11H18V10H16Z"
android:fillColor="#000000"
android:fillAlpha="0.3"
android:fillType="evenOdd"/>
<path
android:pathData="M6,9H6.5H9V10H7V11H9V12H7V14H6V11.5V9.5V9ZM10,9H10.5H12.5C13.3284,9 14,9.6716 14,10.5C14,11.3284 13.3284,12 12.5,12H11V14H10V11.5V9.5V9ZM11,11H12.5C12.7761,11 13,10.7761 13,10.5C13,10.2239 12.7761,10 12.5,10H11V11ZM16,9C15.4477,9 15,9.4477 15,10V11C15,11.5523 15.4477,12 16,12H17V13H15V14H17C17.5523,14 18,13.5523 18,13V12C18,11.4477 17.5523,11 17,11H16V10H18V9H16Z"
android:fillColor="#FFC107"
android:fillType="evenOdd"/>
</vector>

View file

@ -7,8 +7,9 @@
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"
android:padding="0dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetRight="0dp"
app:contentInsetEnd="0dp">
@ -25,17 +26,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 +55,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

@ -20,7 +20,7 @@
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/list_content_padding"
android:layout_marginRight="@dimen/list_content_padding"
osmand:srcCompat="@drawable/map_favorite" />
osmand:srcCompat="@drawable/ic_action_favorite" />
<LinearLayout
android:layout_width="0dp"

View file

@ -27,6 +27,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="@dimen/dashboard_map_toolbar"
android:padding="0dp"
app:contentInsetLeft="54dp"
app:contentInsetStart="54dp"
app:contentInsetRight="0dp"
@ -93,7 +94,7 @@
android:layout_height="wrap_content"
android:background="?attr/bg_color"
app:itemBackground="?attr/bg_color"
app:labelVisibilityMode="labeled"
app:labelVisibilityMode="labeled"
app:itemIconTint="@color/bottom_navigation_color_selector_light"
app:itemTextColor="@color/bottom_navigation_color_selector_light"
app:menu="@menu/map_markers_bottom_navigation"/>

Some files were not shown because too many files have changed in this diff Show more