Merge remote-tracking branch 'origin/master'
|
@ -29,8 +29,8 @@ public class OpeningHoursParser {
|
|||
private static final String[] localMothsStr;
|
||||
|
||||
private static final int LOW_TIME_LIMIT = 120;
|
||||
private static final int HIGH_TIME_LIMIT = 300;
|
||||
private static final int WITHOUT_TIME_LIMIT = -1;
|
||||
private static final int CURRENT_DAY_TIME_LIMIT = -2;
|
||||
|
||||
static {
|
||||
DateFormatSymbols dateFormatSymbols = DateFormatSymbols.getInstance(Locale.US);
|
||||
|
@ -120,6 +120,15 @@ public class OpeningHoursParser {
|
|||
rules.add(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* add rules to the opening hours
|
||||
*
|
||||
* @param rules to add
|
||||
*/
|
||||
public void addRules(List<OpeningHoursRule> rules) {
|
||||
this.rules.addAll(rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the list of rules
|
||||
*
|
||||
|
@ -203,7 +212,7 @@ public class OpeningHoursParser {
|
|||
}
|
||||
|
||||
public String getOpeningTime(Calendar cal) {
|
||||
return getTime(cal, HIGH_TIME_LIMIT, true);
|
||||
return getTime(cal, CURRENT_DAY_TIME_LIMIT, true);
|
||||
}
|
||||
|
||||
public String getNearToClosingTime(Calendar cal) {
|
||||
|
@ -865,11 +874,11 @@ public class OpeningHoursParser {
|
|||
for (int i = 0; i < startTimes.size(); i++) {
|
||||
int startTime = startTimes.get(i);
|
||||
int endTime = endTimes.get(i);
|
||||
if (opening) {
|
||||
if (opening != off) {
|
||||
if (startTime < endTime || endTime == -1) {
|
||||
if (days[d] && !checkAnotherDay) {
|
||||
int diff = startTime - time;
|
||||
if (limit == WITHOUT_TIME_LIMIT || ((time <= startTime) && (diff <= limit))) {
|
||||
if (limit == WITHOUT_TIME_LIMIT || (time <= startTime && (diff <= limit || limit == CURRENT_DAY_TIME_LIMIT))) {
|
||||
formatTime(startTime, sb);
|
||||
break;
|
||||
}
|
||||
|
@ -881,7 +890,7 @@ public class OpeningHoursParser {
|
|||
} else if (time > endTime && days[ad] && checkAnotherDay) {
|
||||
diff = 24 * 60 - endTime + time;
|
||||
}
|
||||
if (limit == WITHOUT_TIME_LIMIT || ((diff != -1) && (diff <= limit))) {
|
||||
if (limit == WITHOUT_TIME_LIMIT || (diff != -1 && diff <= limit || limit == CURRENT_DAY_TIME_LIMIT)) {
|
||||
formatTime(startTime, sb);
|
||||
break;
|
||||
}
|
||||
|
@ -890,7 +899,7 @@ public class OpeningHoursParser {
|
|||
if (startTime < endTime && endTime != -1) {
|
||||
if (days[d] && !checkAnotherDay) {
|
||||
int diff = endTime - time;
|
||||
if (limit == WITHOUT_TIME_LIMIT || ((time <= endTime) && (diff <= limit))) {
|
||||
if ((limit == WITHOUT_TIME_LIMIT && diff >= 0) || (time <= endTime && diff <= limit)) {
|
||||
formatTime(endTime, sb);
|
||||
break;
|
||||
}
|
||||
|
@ -900,9 +909,9 @@ public class OpeningHoursParser {
|
|||
if (time <= endTime && days[d] && !checkAnotherDay) {
|
||||
diff = 24 * 60 - time + endTime;
|
||||
} else if (time < endTime && days[ad] && checkAnotherDay) {
|
||||
diff = startTime - time;
|
||||
diff = endTime - time;
|
||||
}
|
||||
if (limit == WITHOUT_TIME_LIMIT || ((diff != -1) && (diff <= limit))) {
|
||||
if (limit == WITHOUT_TIME_LIMIT || (diff != -1 && diff <= limit)) {
|
||||
formatTime(endTime, sb);
|
||||
break;
|
||||
}
|
||||
|
@ -1176,7 +1185,7 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
|
||||
public static OpeningHoursParser.OpeningHoursRule parseRuleV2(String r) {
|
||||
public static void parseRuleV2(String r, List<OpeningHoursParser.OpeningHoursRule> rules) {
|
||||
r = r.toLowerCase();
|
||||
|
||||
final String[] daysStr = new String[]{"mo", "tu", "we", "th", "fr", "sa", "su"};
|
||||
|
@ -1197,7 +1206,8 @@ public class OpeningHoursParser {
|
|||
Arrays.fill(days, true);
|
||||
Arrays.fill(months, true);
|
||||
basic.addTimeRange(0, 24 * 60);
|
||||
return basic;
|
||||
rules.add(basic);
|
||||
return;
|
||||
}
|
||||
List<Token> tokens = new ArrayList<>();
|
||||
int startWord = 0;
|
||||
|
@ -1280,6 +1290,10 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
buildRule(basic, tokens, rules);
|
||||
}
|
||||
|
||||
private static void buildRule(BasicOpeningHourRule basic, List<Token> tokens, List<OpeningHoursRule> rules) {
|
||||
// order MONTH MONTH_DAY DAY_WEEK HOUR_MINUTE OPEN_OFF
|
||||
TokenType currentParse = TokenType.TOKEN_UNKNOWN;
|
||||
List<Token[]> listOfPairs = new ArrayList<>();
|
||||
|
@ -1291,10 +1305,9 @@ public class OpeningHoursParser {
|
|||
Token t = i == tokens.size() ? null : tokens.get(i);
|
||||
if (t == null || t.type.ord() > currentParse.ord()) {
|
||||
presentTokens.add(currentParse);
|
||||
// case tokens.get(i).type.ordinal() < currentParse.ordinal() - not supported (Fr 15:00-18:00, Sa 16-18)
|
||||
if (currentParse == TokenType.TOKEN_MONTH || currentParse == TokenType.TOKEN_DAY_MONTH
|
||||
|| currentParse == TokenType.TOKEN_DAY_WEEK || currentParse == TokenType.TOKEN_HOLIDAY) {
|
||||
|
||||
|
||||
boolean[] array = (currentParse == TokenType.TOKEN_MONTH) ? basic.getMonths()
|
||||
: (currentParse == TokenType.TOKEN_DAY_MONTH) ? basic.getDayMonths() : basic.getDays();
|
||||
for (Token[] pair : listOfPairs) {
|
||||
|
@ -1313,28 +1326,28 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
} else if (pair[0] != null) {
|
||||
if(pair[0].type == TokenType.TOKEN_HOLIDAY) {
|
||||
if(pair[0].mainNumber == 0) {
|
||||
if (pair[0].type == TokenType.TOKEN_HOLIDAY) {
|
||||
if (pair[0].mainNumber == 0) {
|
||||
basic.publicHoliday = true;
|
||||
} else if(pair[0].mainNumber == 1) {
|
||||
} else if (pair[0].mainNumber == 1) {
|
||||
basic.schoolHoliday = true;
|
||||
} else if(pair[0].mainNumber == 2) {
|
||||
} else if (pair[0].mainNumber == 2) {
|
||||
basic.easter = true;
|
||||
}
|
||||
} else if(pair[0].mainNumber >= 0){
|
||||
} else if (pair[0].mainNumber >= 0) {
|
||||
array[pair[0].mainNumber] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (currentParse == TokenType.TOKEN_HOUR_MINUTES) {
|
||||
for (Token[] pair : listOfPairs) {
|
||||
if(pair[0] != null && pair[1] != null) {
|
||||
if (pair[0] != null && pair[1] != null) {
|
||||
basic.addTimeRange(pair[0].mainNumber, pair[1].mainNumber);
|
||||
}
|
||||
}
|
||||
} else if (currentParse == TokenType.TOKEN_OFF_ON) {
|
||||
Token[] l = listOfPairs.get(0);
|
||||
if(l[0] != null && l[0].mainNumber == 0) {
|
||||
if (l[0] != null && l[0].mainNumber == 0) {
|
||||
basic.off = true;
|
||||
}
|
||||
}
|
||||
|
@ -1343,16 +1356,23 @@ public class OpeningHoursParser {
|
|||
indexP = 0;
|
||||
listOfPairs.add(currentPair);
|
||||
currentPair[indexP++] = t;
|
||||
if(t != null) {
|
||||
if (t != null) {
|
||||
currentParse = t.type;
|
||||
}
|
||||
} else if(t.type == TokenType.TOKEN_COMMA) {
|
||||
currentPair = new Token[2];
|
||||
indexP = 0;
|
||||
listOfPairs.add(currentPair);
|
||||
} else if(t.type == TokenType.TOKEN_DASH) {
|
||||
|
||||
} else if(t.type.ord() == currentParse.ord()) {
|
||||
} else if (t.type.ord() < currentParse.ord() && indexP == 0 && tokens.size() > i) {
|
||||
buildRule(new BasicOpeningHourRule(), tokens.subList(i, tokens.size()), rules);
|
||||
tokens = tokens.subList(0, i + 1);
|
||||
} else if (t.type == TokenType.TOKEN_COMMA) {
|
||||
if (tokens.size() > i + 1 && tokens.get(i + 1) != null && tokens.get(i + 1).type.ord() < currentParse.ord()) {
|
||||
indexP = 0;
|
||||
} else {
|
||||
currentPair = new Token[2];
|
||||
indexP = 0;
|
||||
listOfPairs.add(currentPair);
|
||||
}
|
||||
} else if (t.type == TokenType.TOKEN_DASH) {
|
||||
|
||||
} else if (t.type.ord() == currentParse.ord()) {
|
||||
if(indexP < 2) {
|
||||
currentPair[indexP++] = t;
|
||||
}
|
||||
|
@ -1364,7 +1384,7 @@ public class OpeningHoursParser {
|
|||
// if(!presentTokens.contains(TokenType.TOKEN_DAY_MONTH)) {
|
||||
// Arrays.fill(basic.getDayMonths(), true);
|
||||
// }
|
||||
if(!presentTokens.contains(TokenType.TOKEN_DAY_WEEK) && !presentTokens.contains(TokenType.TOKEN_HOLIDAY) &&
|
||||
if(!presentTokens.contains(TokenType.TOKEN_DAY_WEEK) && !presentTokens.contains(TokenType.TOKEN_HOLIDAY) &&
|
||||
!presentTokens.contains(TokenType.TOKEN_DAY_MONTH)) {
|
||||
Arrays.fill(basic.getDays(), true);
|
||||
}
|
||||
|
@ -1372,7 +1392,7 @@ public class OpeningHoursParser {
|
|||
// basic.addTimeRange(0, 24 * 60);
|
||||
// }
|
||||
// System.out.println(r + " " + tokens);
|
||||
return basic;
|
||||
rules.add(0, basic);
|
||||
}
|
||||
|
||||
private static void findInArray(Token t, String[] list, TokenType tokenType) {
|
||||
|
@ -1391,8 +1411,8 @@ public class OpeningHoursParser {
|
|||
* @param r the string to parse
|
||||
* @return BasicRule if the String is successfully parsed and UnparseableRule otherwise
|
||||
*/
|
||||
public static OpeningHoursParser.OpeningHoursRule parseRule(String r) {
|
||||
return parseRuleV2(r);
|
||||
public static void parseRules(String r, List<OpeningHoursParser.OpeningHoursRule> rules) {
|
||||
parseRuleV2(r, rules);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1416,10 +1436,12 @@ public class OpeningHoursParser {
|
|||
continue;
|
||||
}
|
||||
// check if valid
|
||||
final OpeningHoursRule r1 = parseRule(r);
|
||||
boolean rule = r1 instanceof BasicOpeningHourRule;
|
||||
if (rule) {
|
||||
rs.addRule(r1);
|
||||
List<OpeningHoursParser.OpeningHoursRule> rList = new ArrayList<>();
|
||||
parseRules(r, rList);
|
||||
for (OpeningHoursParser.OpeningHoursRule rule : rList) {
|
||||
if (rule instanceof BasicOpeningHourRule) {
|
||||
rs.addRule(rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
|
@ -1446,7 +1468,9 @@ public class OpeningHoursParser {
|
|||
continue;
|
||||
}
|
||||
// check if valid
|
||||
rs.addRule(OpeningHoursParser.parseRule(r));
|
||||
List<OpeningHoursParser.OpeningHoursRule> rList = new ArrayList<>();
|
||||
parseRules(r, rList);
|
||||
rs.addRules(rList);
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
@ -1486,6 +1510,66 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test if the calculated opening hours are what you expect
|
||||
*
|
||||
* @param time the time to test in the format "dd.MM.yyyy HH:mm"
|
||||
* @param hours the OpeningHours object
|
||||
* @param expected the expected string in format:
|
||||
* "Open from HH:mm" - open in 5 hours
|
||||
* "Will open at HH:mm" - open in 2 hours
|
||||
* "Open till HH:mm" - close in 5 hours
|
||||
* "Will close at HH:mm" - close in 2 hours
|
||||
* "Will open on HH:mm (Mo,Tu,We,Th,Fr,Sa,Su)" - open in >5 hours
|
||||
* "Open 24/7" - open 24/7
|
||||
*/
|
||||
private static void testInfo(String time, OpeningHours hours, String expected) throws ParseException
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.US).parse(time));
|
||||
|
||||
boolean opened24_calc = false;
|
||||
boolean openFrom_calc = false;
|
||||
boolean willOpenAt_calc = false;
|
||||
boolean openTill_calc = false;
|
||||
boolean willCloseAt_calc = false;
|
||||
boolean willOpenOn_calc = false;
|
||||
|
||||
boolean opened = hours.isOpenedForTimeV2(cal);
|
||||
if (opened) {
|
||||
opened24_calc = hours.isOpened24_7();
|
||||
openTill_calc = !Algorithms.isEmpty(hours.getClosingTime(cal));
|
||||
willCloseAt_calc = !Algorithms.isEmpty(hours.getNearToClosingTime(cal));
|
||||
} else {
|
||||
openFrom_calc = !Algorithms.isEmpty(hours.getOpeningTime(cal));
|
||||
willOpenAt_calc = !Algorithms.isEmpty(hours.getNearToOpeningTime(cal));
|
||||
willOpenOn_calc = !Algorithms.isEmpty(hours.getOpeningDay(cal));
|
||||
}
|
||||
|
||||
String description = "Unknown";
|
||||
if (opened24_calc) {
|
||||
description = "Open 24/7";
|
||||
} else if (willOpenAt_calc) {
|
||||
description = "Will open at " + hours.getNearToOpeningTime(cal);
|
||||
} else if (openFrom_calc) {
|
||||
description = "Open from " + hours.getOpeningTime(cal);
|
||||
} else if (willCloseAt_calc) {
|
||||
description = "Will close at " + hours.getNearToClosingTime(cal);
|
||||
} else if (openTill_calc) {
|
||||
description = "Open till " + hours.getClosingTime(cal);
|
||||
} else if (willOpenOn_calc) {
|
||||
description = "Will open on " + hours.getOpeningDay(cal);
|
||||
}
|
||||
|
||||
boolean result = expected.equalsIgnoreCase(description);
|
||||
|
||||
System.out.printf(" %sok: Expected %s (%s): %s (rule %s)\n",
|
||||
(!result ? "NOT " : ""), time, expected, description, hours.getCurrentRuleTime(cal));
|
||||
|
||||
if (!result)
|
||||
throw new IllegalArgumentException("BUG!!!");
|
||||
}
|
||||
|
||||
private static void testParsedAndAssembledCorrectly(String timeString, OpeningHours hours) {
|
||||
String assembledString = hours.toString();
|
||||
boolean isCorrect = assembledString.equalsIgnoreCase(timeString);
|
||||
|
@ -1693,8 +1777,59 @@ public class OpeningHoursParser {
|
|||
String hoursString = "mo-fr 11:00-21:00; PH off";
|
||||
hours = parseOpenedHoursHandleErrors(hoursString);
|
||||
testParsedAndAssembledCorrectly(hoursString, hours);
|
||||
|
||||
|
||||
// test open from/till
|
||||
hours = parseOpenedHours("Mo-Fr 08:30-17:00; 12:00-12:40 off;");
|
||||
System.out.println(hours);
|
||||
testInfo("15.01.2018 09:00", hours, "Open till 12:00");
|
||||
testInfo("15.01.2018 11:00", hours, "Will close at 12:00");
|
||||
testInfo("15.01.2018 12:00", hours, "Will open at 12:40");
|
||||
|
||||
hours = parseOpenedHours("Mo-Fr: 9:00-13:00, 14:00-18:00");
|
||||
System.out.println(hours);
|
||||
testInfo("15.01.2018 08:00", hours, "Will open at 09:00");
|
||||
testInfo("15.01.2018 09:00", hours, "Open till 13:00");
|
||||
testInfo("15.01.2018 12:00", hours, "Will close at 13:00");
|
||||
testInfo("15.01.2018 13:10", hours, "Will open at 14:00");
|
||||
testInfo("15.01.2018 14:00", hours, "Open till 18:00");
|
||||
testInfo("15.01.2018 16:00", hours, "Will close at 18:00");
|
||||
testInfo("15.01.2018 18:10", hours, "Will open on 09:00 Tu");
|
||||
|
||||
hours = parseOpenedHours("Mo-Sa 02:00-10:00; Th off");
|
||||
System.out.println(hours);
|
||||
testInfo("15.01.2018 23:00", hours, "Will open on 02:00 Tu");
|
||||
|
||||
hours = parseOpenedHours("Mo-Sa 23:00-02:00; Th off");
|
||||
System.out.println(hours);
|
||||
testInfo("15.01.2018 22:00", hours, "Will open at 23:00");
|
||||
testInfo("15.01.2018 23:00", hours, "Open till 02:00");
|
||||
testInfo("16.01.2018 00:30", hours, "Will close at 02:00");
|
||||
testInfo("16.01.2018 02:00", hours, "Open from 23:00");
|
||||
|
||||
hours = parseOpenedHours("Mo-Sa 08:30-17:00; Th off");
|
||||
System.out.println(hours);
|
||||
testInfo("17.01.2018 20:00", hours, "Will open on 08:30 Fr");
|
||||
testInfo("18.01.2018 05:00", hours, "Will open on 08:30 Fr");
|
||||
testInfo("20.01.2018 05:00", hours, "Open from 08:30");
|
||||
testInfo("21.01.2018 05:00", hours, "Will open on 08:30 Mo");
|
||||
testInfo("22.01.2018 02:00", hours, "Open from 08:30");
|
||||
testInfo("22.01.2018 04:00", hours, "Open from 08:30");
|
||||
testInfo("22.01.2018 07:00", hours, "Will open at 08:30");
|
||||
testInfo("23.01.2018 10:00", hours, "Open till 17:00");
|
||||
testInfo("23.01.2018 16:00", hours, "Will close at 17:00");
|
||||
|
||||
hours = parseOpenedHours("24/7");
|
||||
System.out.println(hours);
|
||||
testInfo("24.01.2018 02:00", hours, "Open 24/7");
|
||||
|
||||
hours = parseOpenedHours("Mo-Su 07:00-23:00, Fr 08:00-20:00");
|
||||
System.out.println(hours);
|
||||
testOpened("15.01.2018 06:45", hours, false);
|
||||
testOpened("15.01.2018 07:45", hours, true);
|
||||
testOpened("15.01.2018 23:45", hours, false);
|
||||
testOpened("19.01.2018 07:45", hours, false);
|
||||
testOpened("19.01.2018 08:45", hours, true);
|
||||
testOpened("19.01.2018 20:45", hours, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
BIN
OsmAnd/res/drawable-hdpi/ic_action_location_color.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
OsmAnd/res/drawable-hdpi/ic_action_route_direction_from_here.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
OsmAnd/res/drawable-hdpi/ic_action_route_direction_here.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
OsmAnd/res/drawable-hdpi/ic_action_route_first_intermediate.png
Normal file
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
BIN
OsmAnd/res/drawable-hdpi/ic_action_route_last_intermediate.png
Normal file
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_location_color.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_route_direction_from_here.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_route_direction_here.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_route_first_intermediate.png
Normal file
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_route_last_intermediate.png
Normal file
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
BIN
OsmAnd/res/drawable-xhdpi/ic_action_location_color.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 1.4 KiB |
BIN
OsmAnd/res/drawable-xhdpi/ic_action_route_direction_here.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
OsmAnd/res/drawable-xhdpi/ic_action_route_first_intermediate.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-xhdpi/ic_action_route_last_intermediate.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/ic_action_location_color.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/ic_action_route_direction_here.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/ic_action_route_last_intermediate.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
|
@ -49,6 +49,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginTop="@dimen/dashboard_map_toolbar"
|
||||
android:visibility="gone">
|
||||
|
||||
<net.osmand.plus.views.controls.DynamicListView
|
||||
|
|
|
@ -1114,7 +1114,7 @@ Mémoire proportionnelle %4$s Mo (limite Android %5$s Mo, Dalvik %6$s Mo).</stri
|
|||
<string name="plugin_distance_point_speed">vitesse</string>
|
||||
<string name="plugin_distance_point_ele">altitude</string>
|
||||
<string name="gpx_file_name">Nom du fichier GPX</string>
|
||||
<string name="gpx_saved_sucessfully">L\'enregistrement du fichier GPX {0} a réussi</string>
|
||||
<string name="gpx_saved_sucessfully">L\`enregistrement du fichier GPX {0} a réussi</string>
|
||||
<string name="osmand_distance_planning_plugin_description">Ce greffon permet, depuis la carte, de créer un itinéraire soit un cliquant sur la carte, soit en ouvrant ou en modifiant un fichier GPX existant; ainsi que de mesurer la distance entre des points. L\'itinéraire peut être enregistré dans un fichier GPX qui peut lui-même être utilisé plus tard pour une navigation.</string>
|
||||
<string name="osmand_distance_planning_plugin_name">Mesure de distance et Outil de planification</string>
|
||||
<string name="shared_string_do_not_show_again">Ne plus afficher</string>
|
||||
|
|
|
@ -184,5 +184,5 @@
|
|||
<dimen name="grid_menu_item_bottom_top_margin">24dp</dimen>
|
||||
<dimen name="grid_menu_item_sides_margin">60dp</dimen>
|
||||
|
||||
<dimen name="bottom_sheet_menu_peek_height">300dp</dimen>
|
||||
<dimen name="bottom_sheet_menu_peek_height">450dp</dimen>
|
||||
</resources>
|
|
@ -3714,5 +3714,14 @@
|
|||
<string name="poi_climbing_summit_log_no">Журнал восхождений: нет</string>
|
||||
<string name="poi_climbing_routes">Скальные маршруты</string>
|
||||
|
||||
<string name="poi_circumference">Обхват ствола</string>
|
||||
<string name="poi_diameter_crown">Диаметр кроны</string>
|
||||
|
||||
<string name="poi_meadow_agricultural">Тип: сельскохозяйственный</string>
|
||||
<string name="poi_meadow_perpetual">Тип: природный</string>
|
||||
<string name="poi_meadow_transitional">Тип: зарастающий</string>
|
||||
<string name="poi_meadow_pasture">Тип: пастбище</string>
|
||||
|
||||
<string name="poi_frozen_food">Замороженные продукты</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -2809,4 +2809,8 @@
|
|||
<string name="shared_string_marker">Маркер</string>
|
||||
<string name="shared_string_without_name">Без имени</string>
|
||||
<string name="lang_lo">Лаосский</string>
|
||||
<string name="day_off_label">вых.</string>
|
||||
<string name="winter_and_ski_renderer">Зимний/лыжный</string>
|
||||
<string name="touring_view_renderer">Туристический (контраст и детали)</string>
|
||||
<string name="nautical_renderer">Морской</string>
|
||||
</resources>
|
||||
|
|
|
@ -3157,4 +3157,9 @@
|
|||
<string name="osm_recipient_stat">Редагувань %1$s, сума %2$s mBTC</string>
|
||||
<string name="osm_recipients_label">OSM-одержувачі</string>
|
||||
<string name="total_donations">Всього пожертвувань</string>
|
||||
<string name="day_off_label">вих.</string>
|
||||
<string name="winter_and_ski_renderer">Зимовий/лижний</string>
|
||||
<string name="touring_view_renderer">Туристичний (контраст і деталі)</string>
|
||||
<string name="nautical_renderer">Морський</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -3690,5 +3690,15 @@
|
|||
<string name="poi_climbing_summit_log_no">Climbing summit log: no</string>
|
||||
<string name="poi_climbing_routes">Climbing routes</string>
|
||||
|
||||
<string name="poi_circumference">Circumference</string>
|
||||
<string name="poi_diameter_crown">Diameter of the crown</string>
|
||||
|
||||
<string name="poi_meadow_agricultural">Type: agricultural</string>
|
||||
<string name="poi_meadow_perpetual">Type: perpetual</string>
|
||||
<string name="poi_meadow_transitional">Type: transitional</string>
|
||||
<string name="poi_meadow_pasture">Type: pasture</string>
|
||||
|
||||
<string name="poi_frozen_food">Frozen food</string>
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -257,5 +257,5 @@
|
|||
<dimen name="grid_menu_item_bottom_top_margin">16dp</dimen>
|
||||
<dimen name="grid_menu_item_sides_margin">40dp</dimen>
|
||||
|
||||
<dimen name="bottom_sheet_menu_peek_height">200dp</dimen>
|
||||
<dimen name="bottom_sheet_menu_peek_height">300dp</dimen>
|
||||
</resources>
|
|
@ -2841,4 +2841,8 @@
|
|||
<string name="add_segment_to_the_track">Add to a GPX track</string>
|
||||
<string name="osm_recipients_label">OSM recipients</string>
|
||||
<string name="total_donations">Total donations</string>
|
||||
<string name="day_off_label">off</string>
|
||||
<string name="winter_and_ski_renderer">Winter and ski</string>
|
||||
<string name="touring_view_renderer">Touring view (contrast and details)</string>
|
||||
<string name="nautical_renderer">Nautical</string>
|
||||
</resources>
|
||||
|
|
|
@ -134,7 +134,12 @@ public abstract class OsmandPlugin {
|
|||
allPlugins.add(new MapillaryPlugin(app));
|
||||
enabledPlugins.add(MapillaryPlugin.ID);
|
||||
|
||||
// plugins with additional actions for context menu in right order:
|
||||
allPlugins.add(new AudioVideoNotesPlugin(app));
|
||||
allPlugins.add(new OsmEditingPlugin(app));
|
||||
checkMarketPlugin(app, new ParkingPositionPlugin(app), false, ParkingPositionPlugin.PARKING_PLUGIN_COMPONENT, null);
|
||||
allPlugins.add(new OsmandRasterMapsPlugin(app));
|
||||
|
||||
allPlugins.add(new OsmandMonitoringPlugin(app));
|
||||
// allPlugins.add(new OsMoPlugin(app));
|
||||
checkMarketPlugin(app, new SRTMPlugin(app), true, SRTM_PLUGIN_COMPONENT_PAID, SRTM_PLUGIN_COMPONENT);
|
||||
|
@ -144,12 +149,7 @@ public abstract class OsmandPlugin {
|
|||
checkMarketPlugin(app, new NauticalMapsPlugin(app), false, NauticalMapsPlugin.COMPONENT, null);
|
||||
checkMarketPlugin(app, new SkiMapsPlugin(app), false, SkiMapsPlugin.COMPONENT, null);
|
||||
|
||||
// checkMarketPlugin(app, new RoutePointsPlugin(app), false /*FIXME*/, RoutePointsPlugin.ROUTE_POINTS_PLUGIN_COMPONENT, null);
|
||||
allPlugins.add(new AudioVideoNotesPlugin(app));
|
||||
checkMarketPlugin(app, new ParkingPositionPlugin(app), false, ParkingPositionPlugin.PARKING_PLUGIN_COMPONENT, null);
|
||||
//allPlugins.add(new DistanceCalculatorPlugin(app));
|
||||
allPlugins.add(new AccessibilityPlugin(app));
|
||||
allPlugins.add(new OsmEditingPlugin(app));
|
||||
allPlugins.add(new OsmandDevelopmentPlugin(app));
|
||||
|
||||
activatePlugins(app, enabledPlugins);
|
||||
|
@ -446,21 +446,7 @@ public abstract class OsmandPlugin {
|
|||
|
||||
public static void registerMapContextMenu(MapActivity map, double latitude, double longitude, ContextMenuAdapter adapter, Object selectedObj) {
|
||||
for (OsmandPlugin plugin : getEnabledPlugins()) {
|
||||
if (plugin instanceof ParkingPositionPlugin) {
|
||||
plugin.registerMapContextMenuActions(map, latitude, longitude, adapter, selectedObj);
|
||||
}
|
||||
}
|
||||
for (OsmandPlugin plugin : getEnabledPlugins()) {
|
||||
if (!(plugin instanceof ParkingPositionPlugin)) {
|
||||
int itemsCount = adapter.length();
|
||||
plugin.registerMapContextMenuActions(map, latitude, longitude, adapter, selectedObj);
|
||||
if (adapter.length() > itemsCount) {
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setPosition(itemsCount)
|
||||
.setLayout(R.layout.bottom_sheet_dialog_fragment_divider)
|
||||
.createItem());
|
||||
}
|
||||
}
|
||||
plugin.registerMapContextMenuActions(map, latitude, longitude, adapter, selectedObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import net.osmand.plus.ContextMenuItem;
|
|||
import net.osmand.plus.ContextMenuItem.ItemBuilder;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.MapMarkersHelper;
|
||||
import net.osmand.plus.OsmAndLocationProvider;
|
||||
|
@ -272,15 +273,18 @@ public class MapActivityActions implements DialogProvider {
|
|||
public void contextMenuPoint(final double latitude, final double longitude, final ContextMenuAdapter iadapter, Object selectedObj) {
|
||||
final ContextMenuAdapter adapter = iadapter == null ? new ContextMenuAdapter() : iadapter;
|
||||
ItemBuilder itemBuilder = new ItemBuilder();
|
||||
adapter.addItem(itemBuilder.setTitleId(R.string.context_menu_item_search, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_search_dark).createItem());
|
||||
adapter.addItem(itemBuilder.setTitleId(R.string.context_menu_item_directions_from, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_gdirections_dark).createItem());
|
||||
if (getMyApplication().getTargetPointsHelper().getPointToNavigate() != null &&
|
||||
(mapActivity.getRoutingHelper().isFollowingMode() || mapActivity.getRoutingHelper().isRoutePlanningMode())) {
|
||||
adapter.addItem(itemBuilder.setTitleId(R.string.context_menu_item_last_intermediate_point, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_intermediate).createItem());
|
||||
}
|
||||
|
||||
adapter.addItem(itemBuilder
|
||||
.setTitleId(R.string.context_menu_item_directions_from, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_route_direction_from_here)
|
||||
.setPosition(0)
|
||||
.createItem());
|
||||
adapter.addItem(itemBuilder
|
||||
.setTitleId(R.string.context_menu_item_search, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_search_dark)
|
||||
.setPosition(1)
|
||||
.createItem());
|
||||
|
||||
OsmandPlugin.registerMapContextMenu(mapActivity, latitude, longitude, adapter, selectedObj);
|
||||
|
||||
ContextMenuAdapter.ItemClickListener listener = new ContextMenuAdapter.ItemClickListener() {
|
||||
|
@ -295,24 +299,22 @@ public class MapActivityActions implements DialogProvider {
|
|||
}
|
||||
};
|
||||
|
||||
if (!mapActivity.getMyApplication().getSelectedGpxHelper().getSelectedGPXFiles().isEmpty()
|
||||
if (selectedObj instanceof WptPt
|
||||
&& getMyApplication().getSelectedGpxHelper().getSelectedGPXFile((WptPt) selectedObj) != null) {
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.context_menu_item_edit_waypoint, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_edit_dark)
|
||||
.setPosition(getPositionForGpxAction(adapter))
|
||||
.setListener(listener).createItem());
|
||||
} else if (!getMyApplication().getSelectedGpxHelper().getSelectedGPXFiles().isEmpty()
|
||||
|| (OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null)) {
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.context_menu_item_add_waypoint, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_gnew_label_dark)
|
||||
.setPosition(getPositionForGpxAction(adapter))
|
||||
.setListener(listener).createItem());
|
||||
}
|
||||
|
||||
if (selectedObj instanceof GPXUtilities.WptPt) {
|
||||
GPXUtilities.WptPt pt = (GPXUtilities.WptPt) selectedObj;
|
||||
if (getMyApplication().getSelectedGpxHelper().getSelectedGPXFile(pt) != null) {
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.context_menu_item_edit_waypoint, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_edit_dark)
|
||||
.setListener(listener).createItem());
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayAdapter<ContextMenuItem> listAdapter =
|
||||
adapter.createListAdapter(mapActivity, getMyApplication().getSettings().isLightContent());
|
||||
|
||||
|
@ -325,8 +327,6 @@ public class MapActivityActions implements DialogProvider {
|
|||
ItemClickListener click = item.getItemClickListener();
|
||||
if (click != null) {
|
||||
click.onContextMenuClick(listAdapter, standardId, position, false, null);
|
||||
} else if (standardId == R.string.context_menu_item_last_intermediate_point) {
|
||||
mapActivity.getContextMenu().addAsLastIntermediate();
|
||||
} else if (standardId == R.string.context_menu_item_search) {
|
||||
mapActivity.showQuickSearch(latitude, longitude);
|
||||
} else if (standardId == R.string.context_menu_item_directions_from) {
|
||||
|
@ -348,6 +348,17 @@ public class MapActivityActions implements DialogProvider {
|
|||
actionsBottomSheetDialogFragment.show(mapActivity.getSupportFragmentManager(), AdditionalActionsBottomSheetDialogFragment.TAG);
|
||||
}
|
||||
|
||||
private int getPositionForGpxAction(ContextMenuAdapter adapter) {
|
||||
for (int i = 0; i < adapter.length(); i++) {
|
||||
int titleId = adapter.getItem(i).getTitleId();
|
||||
if (titleId == R.string.context_menu_item_add_parking_point
|
||||
|| titleId == R.string.context_menu_item_update_map) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return adapter.length();
|
||||
}
|
||||
|
||||
public void setGPXRouteParams(GPXFile result) {
|
||||
if (result == null) {
|
||||
mapActivity.getRoutingHelper().setGpxParams(null);
|
||||
|
|
|
@ -406,7 +406,7 @@ public abstract class SettingsBaseActivity extends ActionBarPreferenceActivity
|
|||
protected void profileDialog() {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(this);
|
||||
final Set<ApplicationMode> selected = new LinkedHashSet<ApplicationMode>();
|
||||
View v = AppModeDialog.prepareAppModeView(this, selected, false, null, true, false,
|
||||
View v = AppModeDialog.prepareAppModeView(this, selected, false, null, true, true, false,
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.util.Set;
|
|||
public class AppModeDialog {
|
||||
|
||||
public static View prepareAppModeView(Activity a, final Set<ApplicationMode> selected, boolean showDefault,
|
||||
ViewGroup parent, final boolean singleSelection, boolean useMapTheme, final View.OnClickListener onClickListener) {
|
||||
ViewGroup parent, final boolean singleSelection, boolean useListBg, boolean useMapTheme, final View.OnClickListener onClickListener) {
|
||||
OsmandSettings settings = ((OsmandApplication) a.getApplication()).getSettings();
|
||||
final List<ApplicationMode> values = new ArrayList<ApplicationMode>(ApplicationMode.values(settings));
|
||||
if(!showDefault) {
|
||||
|
@ -31,7 +31,7 @@ public class AppModeDialog {
|
|||
if (showDefault || (settings.getApplicationMode() != ApplicationMode.DEFAULT && !singleSelection)) {
|
||||
selected.add(settings.getApplicationMode());
|
||||
}
|
||||
return prepareAppModeView(a, values, selected, parent, singleSelection, false, useMapTheme, onClickListener);
|
||||
return prepareAppModeView(a, values, selected, parent, singleSelection, useListBg, useMapTheme, onClickListener);
|
||||
}
|
||||
|
||||
//special method for drawer menu
|
||||
|
@ -45,10 +45,14 @@ public class AppModeDialog {
|
|||
}
|
||||
|
||||
public static View prepareAppModeView(Activity a, final List<ApplicationMode> values , final Set<ApplicationMode> selected,
|
||||
ViewGroup parent, final boolean singleSelection, boolean drawer, boolean useMapTheme, final View.OnClickListener onClickListener) {
|
||||
ViewGroup parent, final boolean singleSelection, boolean useListBg, boolean useMapTheme, final View.OnClickListener onClickListener) {
|
||||
View ll = a.getLayoutInflater().inflate(R.layout.mode_toggles, parent);
|
||||
boolean nightMode = isNightMode(((OsmandApplication) a.getApplication()), useMapTheme);
|
||||
ll.setBackgroundColor(ContextCompat.getColor(a, nightMode ? R.color.route_info_bg_dark : R.color.route_info_bg_light));
|
||||
if (useListBg) {
|
||||
AndroidUtils.setListItemBackground(a, ll, nightMode);
|
||||
} else {
|
||||
ll.setBackgroundColor(ContextCompat.getColor(a, nightMode ? R.color.route_info_bg_dark : R.color.route_info_bg_light));
|
||||
}
|
||||
final View[] buttons = new View[values.size()];
|
||||
int k = 0;
|
||||
for(ApplicationMode ma : values) {
|
||||
|
|
|
@ -1238,7 +1238,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|
|||
animators.add(ObjectAnimator.ofFloat(content, View.TRANSLATION_X, initialValueX, finalValueX));
|
||||
animators.add(ObjectAnimator.ofFloat(content, View.TRANSLATION_Y, initialValueY, finalValueY));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && ViewCompat.isAttachedToWindow(content)) {
|
||||
int centerX = content.getMeasuredWidth() / 2;
|
||||
int centerY = content.getMeasuredHeight() / 2;
|
||||
float initialRadius = show ? 0 : (float) Math.sqrt(Math.pow(content.getWidth() / 2, 2) + Math.pow(content.getHeight() / 2, 2));
|
||||
|
|
|
@ -225,7 +225,7 @@ public class SettingsDevelopmentActivity extends SettingsBaseActivity {
|
|||
modes.remove(ApplicationMode.DEFAULT);
|
||||
final Set<ApplicationMode> selected = new LinkedHashSet<ApplicationMode>(ApplicationMode.values(settings));
|
||||
selected.remove(ApplicationMode.DEFAULT);
|
||||
View v = AppModeDialog.prepareAppModeView(this, modes, selected, null, false, false, false,
|
||||
View v = AppModeDialog.prepareAppModeView(this, modes, selected, null, false, true, false,
|
||||
new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,717 +0,0 @@
|
|||
package net.osmand.plus.distancecalculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Cap;
|
||||
import android.graphics.Paint.Join;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.ContextMenuAdapter;
|
||||
import net.osmand.plus.ContextMenuItem;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXUtilities.Route;
|
||||
import net.osmand.plus.GPXUtilities.Track;
|
||||
import net.osmand.plus.GPXUtilities.TrkSegment;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.OsmandSettings.CommonPreference;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.views.ContextMenuLayer;
|
||||
import net.osmand.plus.views.MapInfoLayer;
|
||||
import net.osmand.plus.views.OsmandMapLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
public class DistanceCalculatorPlugin extends OsmandPlugin {
|
||||
private static final String ID = "osmand.distance";
|
||||
private OsmandApplication app;
|
||||
private DistanceCalculatorLayer distanceCalculatorLayer;
|
||||
private TextInfoWidget distanceControl;
|
||||
|
||||
private List<LinkedList<WptPt>> measurementPoints = new ArrayList<>();
|
||||
private GPXFile originalGPX;
|
||||
private String distance = null;
|
||||
|
||||
private int distanceMeasurementMode = 0;
|
||||
|
||||
public DistanceCalculatorPlugin(OsmandApplication app) {
|
||||
this.app = app;
|
||||
ApplicationMode.regWidgetVisibility("distance.measurement", ApplicationMode.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return app.getString(R.string.osmand_distance_planning_plugin_description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return app.getString(R.string.osmand_distance_planning_plugin_name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpFileName() {
|
||||
return "feature_articles/distance-calculator-and-planning-tool.html";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayers(OsmandMapTileView mapView, MapActivity activity) {
|
||||
if(isActive()) {
|
||||
if(distanceCalculatorLayer == null) {
|
||||
registerLayers(activity);
|
||||
}
|
||||
if(!mapView.isLayerVisible(distanceCalculatorLayer)) {
|
||||
activity.getMapView().addLayer(distanceCalculatorLayer, 4.5f);
|
||||
}
|
||||
if(distanceControl == null) {
|
||||
registerWidget(activity);
|
||||
}
|
||||
} else {
|
||||
MapInfoLayer mapInfoLayer = activity.getMapLayers().getMapInfoLayer();
|
||||
if(distanceCalculatorLayer != null) {
|
||||
activity.getMapView().removeLayer(distanceCalculatorLayer);
|
||||
}
|
||||
if (mapInfoLayer != null && distanceControl != null ) {
|
||||
mapInfoLayer.removeSideWidget(distanceControl);
|
||||
mapInfoLayer.recreateControls();
|
||||
distanceControl = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerLayers(MapActivity activity) {
|
||||
// remove old if existing
|
||||
if(distanceCalculatorLayer != null) {
|
||||
activity.getMapView().removeLayer(distanceCalculatorLayer);
|
||||
}
|
||||
distanceCalculatorLayer = new DistanceCalculatorLayer();
|
||||
activity.getMapView().addLayer(distanceCalculatorLayer, 4.5f);
|
||||
|
||||
registerWidget(activity);
|
||||
}
|
||||
|
||||
private void registerWidget(MapActivity activity) {
|
||||
MapInfoLayer mapInfoLayer = activity.getMapLayers().getMapInfoLayer();
|
||||
if (mapInfoLayer != null ) {
|
||||
distanceControl = createDistanceControl(activity);
|
||||
mapInfoLayer.registerSideWidget(distanceControl,
|
||||
R.drawable.ic_action_ruler, R.string.map_widget_distancemeasurement, "distance.measurement", false, 35);
|
||||
mapInfoLayer.recreateControls();
|
||||
updateText();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateText() {
|
||||
if (distanceControl != null) {
|
||||
String ds = distance;
|
||||
if (ds == null) {
|
||||
if(distanceMeasurementMode == 0) {
|
||||
distanceControl.setText(app.getString(R.string.shared_string_control_start), "");
|
||||
} else {
|
||||
distanceControl.setText("0", ""); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
int ls = ds.lastIndexOf(' ');
|
||||
if (ls == -1) {
|
||||
distanceControl.setText(ds, null);
|
||||
} else {
|
||||
distanceControl.setText(ds.substring(0, ls), ds.substring(ls + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void showDialog(final MapActivity activity) {
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(activity);
|
||||
final TIntArrayList list = new TIntArrayList();
|
||||
if(distanceMeasurementMode == 0) {
|
||||
list.add(R.string.distance_measurement_start_editing);
|
||||
} else {
|
||||
list.add(R.string.distance_measurement_finish_editing);
|
||||
}
|
||||
if(measurementPoints.size() > 0) {
|
||||
list.add(R.string.distance_measurement_finish_subtrack);
|
||||
list.add(R.string.distance_measurement_clear_route);
|
||||
list.add(R.string.shared_string_save_as_gpx);
|
||||
}
|
||||
list.add(R.string.distance_measurement_load_gpx);
|
||||
String[] items = new String[list.size()];
|
||||
for(int i = 0; i < items.length; i++) {
|
||||
items[i] = activity.getString(list.get(i));
|
||||
}
|
||||
bld.setItems(items, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
int id = list.get(which);
|
||||
if (id == R.string.distance_measurement_start_editing) {
|
||||
distanceMeasurementMode = 1;
|
||||
startEditingHelp(activity) ;
|
||||
} else if (id == R.string.distance_measurement_finish_editing) {
|
||||
distanceMeasurementMode = 0;
|
||||
} else if (id == R.string.distance_measurement_finish_subtrack) {
|
||||
measurementPoints.add(new LinkedList<GPXUtilities.WptPt>());
|
||||
} else if (id == R.string.distance_measurement_clear_route) {
|
||||
distanceMeasurementMode = 0;
|
||||
originalGPX = null;
|
||||
measurementPoints.clear();
|
||||
calculateDistance();
|
||||
activity.getContextMenu().close();
|
||||
} else if (id == R.string.shared_string_save_as_gpx) {
|
||||
saveGpx(activity);
|
||||
} else if (id == R.string.distance_measurement_load_gpx) {
|
||||
loadGpx(activity);
|
||||
}
|
||||
activity.getMapView().refreshMap();
|
||||
updateText();
|
||||
}
|
||||
});
|
||||
bld.show();
|
||||
}
|
||||
|
||||
|
||||
protected void loadGpx(final MapActivity activity) {
|
||||
GpxUiHelper.selectGPXFile(activity, false, false, new CallbackWithObject<GPXUtilities.GPXFile[]>() {
|
||||
|
||||
@Override
|
||||
public boolean processResult(GPXFile[] res) {
|
||||
measurementPoints.clear();
|
||||
if (res.length > 0 && res[0] != null) {
|
||||
GPXFile result = res[0];
|
||||
originalGPX = result;
|
||||
for (Track t : result.tracks) {
|
||||
for (TrkSegment s : t.segments) {
|
||||
if (s.points.size() > 0) {
|
||||
LinkedList<WptPt> l = new LinkedList<WptPt>(s.points);
|
||||
measurementPoints.add(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Route r : result.routes) {
|
||||
LinkedList<WptPt> l = new LinkedList<WptPt>(r.points);
|
||||
measurementPoints.add(l);
|
||||
}
|
||||
for (WptPt p : result.getPoints()) {
|
||||
LinkedList<WptPt> l = new LinkedList<WptPt>();
|
||||
l.add(p);
|
||||
measurementPoints.add(l);
|
||||
}
|
||||
WptPt pt = result.findPointToShow();
|
||||
OsmandMapTileView mapView = activity.getMapView();
|
||||
if(pt != null){
|
||||
mapView.getAnimatedDraggingThread().startMoving(pt.lat, pt.lon,
|
||||
mapView.getZoom(), true);
|
||||
}
|
||||
}
|
||||
calculateDistance();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void saveGpx(final MapActivity activity) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(activity);
|
||||
final File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
LinearLayout ll = new LinearLayout(activity);
|
||||
ll.setOrientation(LinearLayout.VERTICAL);
|
||||
ll.setPadding(7, 7, 7, 7);
|
||||
final TextView tv = new TextView(activity);
|
||||
tv.setText("");
|
||||
|
||||
tv.setTextColor(Color.RED);
|
||||
ll.addView(tv);
|
||||
final EditText editText = new EditText(activity);
|
||||
editText.setHint(R.string.gpx_file_name);
|
||||
if(originalGPX != null && originalGPX.path != null){
|
||||
String p = originalGPX.path;
|
||||
int li = p.lastIndexOf('/');
|
||||
if(li >= 0) {
|
||||
p = p.substring(li + 1);
|
||||
}
|
||||
int pi = p.lastIndexOf('.');
|
||||
if(pi >= 0) {
|
||||
p = p.substring(0, pi);
|
||||
}
|
||||
editText.setText(p);
|
||||
}
|
||||
editText.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
boolean e = false;
|
||||
try {
|
||||
e = new File(dir, s.toString()).exists() || new File(dir, s.toString() +".gpx").exists();
|
||||
} catch (Exception e1) {
|
||||
}
|
||||
if (e) {
|
||||
tv.setText(R.string.file_with_name_already_exists);
|
||||
} else {
|
||||
tv.setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
ll.addView(editText);
|
||||
b.setView(ll);
|
||||
b.setPositiveButton(R.string.shared_string_save, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String newName = editText.getText().toString();
|
||||
if(!newName.endsWith(".gpx")){
|
||||
newName += ".gpx";
|
||||
}
|
||||
saveGpx(activity, newName);
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
b.show();
|
||||
}
|
||||
|
||||
private void saveGpx(final MapActivity activity,
|
||||
final String fileNameSave) {
|
||||
final AsyncTask<Void, Void, String> exportTask = new AsyncTask<Void, Void, String>() {
|
||||
private ProgressDialog dlg;
|
||||
private File toSave;
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
toSave = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), fileNameSave);
|
||||
GPXFile gpx;
|
||||
boolean saveTrackToRte = measurementPoints.size() <= 1;
|
||||
if (originalGPX != null) {
|
||||
gpx = originalGPX;
|
||||
saveTrackToRte = originalGPX.routes.size() > 0 && originalGPX.tracks.size() == 0;
|
||||
gpx.tracks.clear();
|
||||
gpx.routes.clear();
|
||||
app.getSelectedGpxHelper().clearPoints(gpx);
|
||||
} else {
|
||||
gpx = new GPXFile();
|
||||
}
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
LinkedList<WptPt> lt = measurementPoints.get(i);
|
||||
if (lt.size() == 1) {
|
||||
app.getSelectedGpxHelper().addPoint(lt.getFirst(), gpx);
|
||||
} else if (lt.size() > 1) {
|
||||
if (saveTrackToRte) {
|
||||
Route rt = new Route();
|
||||
gpx.routes.add(rt);
|
||||
rt.points.addAll(lt);
|
||||
} else {
|
||||
if (gpx.tracks.size() == 0) {
|
||||
gpx.tracks.add(new Track());
|
||||
}
|
||||
Track ts = gpx.tracks.get(gpx.tracks.size() - 1);
|
||||
TrkSegment sg = new TrkSegment();
|
||||
ts.segments.add(sg);
|
||||
sg.points.addAll(lt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return GPXUtilities.writeGpxFile(toSave, gpx, app);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
dlg = new ProgressDialog(activity);
|
||||
dlg.setMessage(app.getString(R.string.saving_gpx_tracks));
|
||||
dlg.show();
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String warning) {
|
||||
if (warning == null) {
|
||||
Toast.makeText(activity,
|
||||
MessageFormat.format(app.getString(R.string.gpx_saved_sucessfully), toSave.getAbsolutePath()),
|
||||
Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(activity, warning, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
if(dlg != null && dlg.isShowing()) {
|
||||
dlg.dismiss();
|
||||
}
|
||||
};
|
||||
};
|
||||
exportTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
private void startEditingHelp(MapActivity ctx) {
|
||||
final CommonPreference<Boolean> pref = app.getSettings().registerBooleanPreference("show_measurement_help_first_time", true);
|
||||
pref.makeGlobal();
|
||||
if(pref.get()) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
builder.setMessage(R.string.use_distance_measurement_help);
|
||||
builder.setNegativeButton(R.string.shared_string_do_not_show_again, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
pref.set(false);
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(R.string.shared_string_ok, null);
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private TextInfoWidget createDistanceControl(final MapActivity activity) {
|
||||
final TextInfoWidget distanceControl = new TextInfoWidget(activity);
|
||||
distanceControl.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showDialog(activity);
|
||||
}
|
||||
});
|
||||
distanceControl.setIcons(R.drawable.widget_distance_day, R.drawable.widget_distance_night);
|
||||
return distanceControl;
|
||||
}
|
||||
|
||||
private void calculateDistance() {
|
||||
float dist = 0;
|
||||
if (measurementPoints.size() == 0 && distanceMeasurementMode == 0 ) {
|
||||
distance = null;
|
||||
} else {
|
||||
for (int j = 0; j < measurementPoints.size(); j++) {
|
||||
List<WptPt> ls = measurementPoints.get(j);
|
||||
for (int i = 1; i < ls.size(); i++) {
|
||||
dist += MapUtils.getDistance(ls.get(i - 1).lat, ls.get(i - 1).lon, ls.get(i).lat, ls.get(i).lon);
|
||||
}
|
||||
}
|
||||
distance = OsmAndFormatter.getFormattedDistance(dist, app);
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
|
||||
public class DistanceCalculatorLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
|
||||
private OsmandMapTileView view;
|
||||
|
||||
private Bitmap originIcon;
|
||||
private Bitmap destinationIcon;
|
||||
private Paint bitmapPaint;
|
||||
|
||||
private Path path;
|
||||
|
||||
private Paint paint;
|
||||
private Paint paint2;
|
||||
|
||||
public DistanceCalculatorLayer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initLayer(OsmandMapTileView view) {
|
||||
this.view = view;
|
||||
originIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_origin);
|
||||
destinationIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_destination);
|
||||
bitmapPaint = new Paint();
|
||||
bitmapPaint.setDither(true);
|
||||
bitmapPaint.setAntiAlias(true);
|
||||
bitmapPaint.setFilterBitmap(true);
|
||||
path = new Path();
|
||||
|
||||
int distanceColor = view.getResources().getColor(R.color.color_distance);
|
||||
paint = new Paint();
|
||||
paint.setStyle(Style.STROKE);
|
||||
paint.setStrokeWidth(7 * view.getDensity());
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeCap(Cap.ROUND);
|
||||
paint.setStrokeJoin(Join.ROUND);
|
||||
paint.setColor(distanceColor);
|
||||
|
||||
paint2 = new Paint();
|
||||
paint2.setStyle(Style.FILL_AND_STROKE);
|
||||
paint2.setAntiAlias(true);
|
||||
paint2.setColor(distanceColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
|
||||
if(distanceMeasurementMode == 1) {
|
||||
LatLon l = tileBox.getLatLonFromPixel(point.x, point.y);
|
||||
if(measurementPoints.size() == 0) {
|
||||
measurementPoints.add(new LinkedList<GPXUtilities.WptPt>());
|
||||
}
|
||||
WptPt pt = new WptPt();
|
||||
pt.lat = l.getLatitude();
|
||||
pt.lon = l.getLongitude();
|
||||
measurementPoints.get(measurementPoints.size() - 1).add(pt);
|
||||
calculateDistance();
|
||||
view.refreshMap();
|
||||
updateText();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
|
||||
|
||||
List<Object> s = new ArrayList<>();
|
||||
collectObjectsFromPoint(point, tileBox, s, true);
|
||||
|
||||
if (s.size() == 0 && distanceMeasurementMode == 1 && measurementPoints.size() > 0) {
|
||||
LinkedList<WptPt> lt = measurementPoints.get(measurementPoints.size() - 1);
|
||||
if (lt.size() > 0) {
|
||||
lt.removeLast();
|
||||
}
|
||||
calculateDistance();
|
||||
view.refreshMap();
|
||||
updateText();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
|
||||
if (measurementPoints.size() > 0) {
|
||||
path.reset();
|
||||
int marginY = originIcon.getHeight();
|
||||
int marginX = originIcon.getWidth() / 2;
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
Iterator<WptPt> it = measurementPoints.get(i).iterator();
|
||||
boolean first = true;
|
||||
while (it.hasNext()) {
|
||||
WptPt point = it.next();
|
||||
int locationX = tileBox.getPixXFromLonNoRot(point.lon);
|
||||
int locationY = tileBox.getPixYFromLatNoRot(point.lat);
|
||||
if (first) {
|
||||
path.moveTo(locationX, locationY);
|
||||
first = false;
|
||||
} else {
|
||||
path.lineTo(locationX, locationY);
|
||||
}
|
||||
}
|
||||
}
|
||||
canvas.drawPath(path, paint);
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
Iterator<WptPt> it = measurementPoints.get(i).iterator();
|
||||
boolean first = true;
|
||||
while(it.hasNext()) {
|
||||
WptPt pt = it.next();
|
||||
if (tileBox.containsLatLon(pt.lat, pt.lon)) {
|
||||
int locationX = tileBox.getPixXFromLonNoRot(pt.lon);
|
||||
int locationY = tileBox.getPixYFromLatNoRot(pt.lat);
|
||||
|
||||
if(first || !it.hasNext() || pt.desc != null) {
|
||||
canvas.rotate(-view.getRotate(), locationX, locationY);
|
||||
canvas.drawBitmap(distanceMeasurementMode == 1? originIcon : destinationIcon,
|
||||
locationX - marginX, locationY - marginY, bitmapPaint);
|
||||
canvas.rotate(view.getRotate(), locationX, locationY);
|
||||
} else if(tileBox.getZoom() >= 16){
|
||||
canvas.drawCircle(locationX, locationY, 10 * tileBox.getDensity(), paint2);
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyLayer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawInScreenPixels() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableSingleTap() {
|
||||
return distanceMeasurementMode == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableLongPressOnMap() {
|
||||
return distanceMeasurementMode == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObjectClickable(Object o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runExclusiveAction(Object o, boolean unknownLocation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> o, boolean unknownLocation) {
|
||||
getMPointsFromPoint(tileBox, point, o);
|
||||
}
|
||||
|
||||
public void getMPointsFromPoint(RotatedTileBox tb, PointF point, List<? super WptPt> res) {
|
||||
int r = (int) (14 * tb.getDensity());
|
||||
int rs = (int) (10 * tb.getDensity());
|
||||
int ex = (int) point.x;
|
||||
int ey = (int) point.y;
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
Iterator<WptPt> it = measurementPoints.get(i).iterator();
|
||||
boolean first = true;
|
||||
while (it.hasNext()) {
|
||||
WptPt pt = it.next();
|
||||
int x = (int) tb.getPixXFromLatLon(pt.lat, pt.lon);
|
||||
int y = (int) tb.getPixYFromLatLon(pt.lat, pt.lon);
|
||||
if (pt.desc != null || !it.hasNext() || first) {
|
||||
if (calculateBelongsBig(ex, ey, x, y, r)) {
|
||||
res.add(pt);
|
||||
}
|
||||
} else {
|
||||
if (calculateBelongsSmall(ex, ey, x, y, rs)) {
|
||||
res.add(pt);
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean calculateBelongsBig(int ex, int ey, int objx, int objy, int radius) {
|
||||
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
|
||||
}
|
||||
|
||||
private boolean calculateBelongsSmall(int ex, int ey, int objx, int objy, int radius) {
|
||||
return Math.abs(objx - ex) <= radius && Math.abs(ey - objy) <= radius ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLon getObjectLocation(Object o) {
|
||||
if (o instanceof WptPt) {
|
||||
return new LatLon(((WptPt) o).lat, ((WptPt) o).lon);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateObjectContextMenu(LatLon latLon, Object o, ContextMenuAdapter adapter, MapActivity mapActivity) {
|
||||
if (o != null && o instanceof WptPt) {
|
||||
final WptPt p = (WptPt) o;
|
||||
boolean containsPoint = false;
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
for (WptPt wptPt : measurementPoints.get(i)) {
|
||||
if (wptPt == p) {
|
||||
containsPoint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (containsPoint) {
|
||||
ContextMenuAdapter.ItemClickListener listener = new ContextMenuAdapter.ItemClickListener() {
|
||||
|
||||
@Override
|
||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||
if (itemId == R.string.delete_point) {
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
Iterator<WptPt> it = measurementPoints.get(i).iterator();
|
||||
while (it.hasNext()) {
|
||||
if (it.next() == p) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
calculateDistance();
|
||||
if (adapter.getContext() instanceof MapActivity) {
|
||||
((MapActivity)adapter.getContext()).getContextMenu().close();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.delete_point, mapActivity)
|
||||
.setIcon(R.drawable.ic_action_delete_dark)
|
||||
.setListener(listener).createItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PointDescription getObjectName(Object o) {
|
||||
if(o instanceof WptPt) {
|
||||
if(((WptPt) o).desc == null) {
|
||||
return new PointDescription(PointDescription.POINT_TYPE_MARKER, app.getString(R.string.plugin_distance_point));
|
||||
}
|
||||
return new PointDescription(PointDescription.POINT_TYPE_MARKER, ((WptPt) o).desc );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<? extends Activity> getSettingsActivity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAssetResourceName() {
|
||||
return R.drawable.distance_calculator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLogoResourceId() {
|
||||
return R.drawable.ic_action_marker_dark;
|
||||
}
|
||||
}
|
|
@ -91,23 +91,23 @@ public class AdditionalActionsBottomSheetDialogFragment extends net.osmand.plus.
|
|||
int itemsAdded = 0;
|
||||
for (int i = 0; i < adapter.length(); i++) {
|
||||
ContextMenuItem item = adapter.getItem(i);
|
||||
int layoutResId = item.getLayout();
|
||||
layoutResId = layoutResId == ContextMenuItem.INVALID_ID ? R.layout.grid_menu_item : layoutResId;
|
||||
boolean dividerItem = layoutResId == R.layout.bottom_sheet_dialog_fragment_divider;
|
||||
|
||||
if (!dividerItem) {
|
||||
View menuItem = View.inflate(new ContextThemeWrapper(getContext(), themeRes), layoutResId, null);
|
||||
if (item.getIcon() != ContextMenuItem.INVALID_ID) {
|
||||
((ImageView) menuItem.findViewById(R.id.icon)).setImageDrawable(getContentIcon(item.getIcon()));
|
||||
}
|
||||
((TextView) menuItem.findViewById(R.id.title)).setText(item.getTitle());
|
||||
View menuItem = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.grid_menu_item, null);
|
||||
if (item.getIcon() != ContextMenuItem.INVALID_ID) {
|
||||
((ImageView) menuItem.findViewById(R.id.icon)).setImageDrawable(getContentIcon(item.getIcon()));
|
||||
}
|
||||
((TextView) menuItem.findViewById(R.id.title)).setText(item.getTitle());
|
||||
if (item.isClickable()) {
|
||||
menuItem.setTag(i);
|
||||
menuItem.setOnClickListener(onClickListener);
|
||||
((FrameLayout) row.findViewById(getMenuItemContainerId(itemsAdded))).addView(menuItem);
|
||||
itemsAdded++;
|
||||
} else {
|
||||
menuItem.setEnabled(false);
|
||||
menuItem.setAlpha(.5f);
|
||||
}
|
||||
((FrameLayout) row.findViewById(getMenuItemContainerId(itemsAdded))).addView(menuItem);
|
||||
itemsAdded++;
|
||||
|
||||
if (dividerItem || itemsAdded == 3 || (i == adapter.length() - 1 && itemsAdded > 0)) {
|
||||
if (itemsAdded == 3 || (i == adapter.length() - 1 && itemsAdded > 0)) {
|
||||
itemsLinearLayout.addView(row);
|
||||
row = (LinearLayout) View.inflate(getContext(), R.layout.grid_menu_row, null);
|
||||
itemsAdded = 0;
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.view.View;
|
|||
import android.widget.LinearLayout;
|
||||
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.StateChangedListener;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.FavouritePoint;
|
||||
|
@ -25,6 +26,7 @@ import net.osmand.plus.GPXUtilities.WptPt;
|
|||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.MapMarkersHelper.MapMarker;
|
||||
import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -85,6 +87,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
|
|||
private LatLon myLocation;
|
||||
private Float heading;
|
||||
private boolean inLocationUpdate = false;
|
||||
private boolean cachedMyLocation;
|
||||
private boolean appModeChanged;
|
||||
private boolean appModeListenerAdded;
|
||||
private boolean autoHide;
|
||||
|
@ -289,9 +292,10 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
|
|||
@Nullable PointDescription pointDescription,
|
||||
@Nullable Object object,
|
||||
boolean update, boolean restorePrevious) {
|
||||
OsmandApplication app = mapActivity.getMyApplication();
|
||||
|
||||
if (myLocation == null) {
|
||||
myLocation = mapActivity.getMyApplication().getSettings().getLastKnownMapLocation();
|
||||
updateMyLocation(app.getLocationProvider().getLastKnownLocation(), false);
|
||||
}
|
||||
|
||||
if (!update && isVisible()) {
|
||||
|
@ -349,9 +353,9 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
|
|||
mapActivity.refreshMap();
|
||||
|
||||
if (object instanceof MapMarker) {
|
||||
mapActivity.getMyApplication().getMapMarkersHelper().addListener(this);
|
||||
app.getMapMarkersHelper().addListener(this);
|
||||
} else if (object instanceof TargetPoint) {
|
||||
mapActivity.getMyApplication().getTargetPointsHelper().addPointListener(this);
|
||||
app.getTargetPointsHelper().addPointListener(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -418,6 +422,12 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
|
|||
init(latLon, pointDescription, object);
|
||||
}
|
||||
|
||||
public void onFragmentResume() {
|
||||
if (active && displayDistanceDirection() && myLocation != null) {
|
||||
updateLocation(false, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean navigateInPedestrianMode() {
|
||||
if (menuController != null) {
|
||||
return menuController.navigateInPedestrianMode();
|
||||
|
@ -1215,14 +1225,32 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
|
|||
return myLocation;
|
||||
}
|
||||
|
||||
public boolean isCachedMyLocation() {
|
||||
return cachedMyLocation;
|
||||
}
|
||||
|
||||
public Float getHeading() {
|
||||
return heading;
|
||||
}
|
||||
|
||||
public void updateMyLocation(net.osmand.Location location) {
|
||||
if (location != null && active && displayDistanceDirection()) {
|
||||
private void updateMyLocation(Location location, boolean updateLocationUi) {
|
||||
if (location == null) {
|
||||
location = getMapActivity().getMyApplication().getLocationProvider().getLastStaleKnownLocation();
|
||||
cachedMyLocation = location != null;
|
||||
} else {
|
||||
cachedMyLocation = false;
|
||||
}
|
||||
if (location != null) {
|
||||
myLocation = new LatLon(location.getLatitude(), location.getLongitude());
|
||||
updateLocation(false, true, false);
|
||||
if (updateLocationUi) {
|
||||
updateLocation(false, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMyLocation(net.osmand.Location location) {
|
||||
if (active && displayDistanceDirection()) {
|
||||
updateMyLocation(location, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadPoint;
|
||||
|
@ -48,8 +47,8 @@ import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
|
|||
import net.osmand.plus.mapcontextmenu.MenuController.MenuState;
|
||||
import net.osmand.plus.mapcontextmenu.MenuController.TitleButtonController;
|
||||
import net.osmand.plus.mapcontextmenu.MenuController.TitleProgressController;
|
||||
import net.osmand.plus.transport.TransportStopRoute;
|
||||
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
|
||||
import net.osmand.plus.transport.TransportStopRoute;
|
||||
import net.osmand.plus.views.AnimateDraggingMapThread;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.TransportStopsLayer;
|
||||
|
@ -928,6 +927,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
((View) parent).addOnLayoutChangeListener(containerLayoutListener);
|
||||
}
|
||||
menu.updateControlsVisibility(true);
|
||||
menu.onFragmentResume();
|
||||
getMapActivity().getMapLayers().getMapControlsLayer().showMapControlsIfHidden();
|
||||
}
|
||||
|
||||
|
@ -1221,8 +1221,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
OsmandApplication app = getMyApplication();
|
||||
if (app != null && view != null) {
|
||||
View compassView = view.findViewById(R.id.compass_layout);
|
||||
Location ll = app.getLocationProvider().getLastKnownLocation();
|
||||
if (ll != null && menu.displayDistanceDirection() && menu.getCurrentMenuState() != MenuState.FULL_SCREEN) {
|
||||
if (menu.getMyLocation() != null && menu.displayDistanceDirection() && menu.getCurrentMenuState() != MenuState.FULL_SCREEN) {
|
||||
updateDistanceDirection();
|
||||
compassView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
|
@ -1238,7 +1237,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
TextView distanceText = (TextView) view.findViewById(R.id.distance);
|
||||
ImageView direction = (ImageView) view.findViewById(R.id.direction);
|
||||
float myHeading = menu.getHeading() == null ? 0f : menu.getHeading();
|
||||
int color = nightMode ? R.color.ctx_menu_direction_color_dark : R.color.ctx_menu_direction_color_light;
|
||||
int color = menu.isCachedMyLocation() ? R.color.icon_color : 0;
|
||||
DashLocationFragment.updateLocationView(false, menu.getMyLocation(), myHeading, direction, color, distanceText,
|
||||
color, menu.getLatLon().getLatitude(), menu.getLatLon().getLongitude(), screenOrientation, app, activity);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class ImpassibleRoadsMenuController extends MenuController {
|
|||
super(new MenuBuilder(mapActivity), pointDescription, mapActivity);
|
||||
this.route = route;
|
||||
final OsmandApplication app = mapActivity.getMyApplication();
|
||||
rightTitleButtonController = new TitleButtonController() {
|
||||
leftTitleButtonController = new TitleButtonController() {
|
||||
@Override
|
||||
public void buttonPressed() {
|
||||
app.getAvoidSpecificRoads().removeImpassableRoad(
|
||||
|
@ -33,8 +33,8 @@ public class ImpassibleRoadsMenuController extends MenuController {
|
|||
getMapActivity().getContextMenu().close();
|
||||
}
|
||||
};
|
||||
rightTitleButtonController.caption = getMapActivity().getString(R.string.shared_string_remove);
|
||||
rightTitleButtonController.leftIconId = R.drawable.ic_action_delete_dark;
|
||||
leftTitleButtonController.caption = getMapActivity().getString(R.string.shared_string_remove);
|
||||
leftTitleButtonController.updateStateListDrawableIcon(R.drawable.ic_action_delete_dark, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,22 +3,36 @@ package net.osmand.plus.mapcontextmenu.controllers;
|
|||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.search.SearchHistoryFragment;
|
||||
import net.osmand.plus.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.plus.mapcontextmenu.MenuController;
|
||||
import net.osmand.plus.mapillary.MapillaryPlugin;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class PointDescriptionMenuController extends MenuController {
|
||||
|
||||
private boolean hasTypeInDescription;
|
||||
|
||||
public PointDescriptionMenuController(MapActivity mapActivity, final PointDescription pointDescription) {
|
||||
public PointDescriptionMenuController(final MapActivity mapActivity, final PointDescription pointDescription) {
|
||||
super(new MenuBuilder(mapActivity), pointDescription, mapActivity);
|
||||
builder.setShowNearestWiki(true);
|
||||
initData();
|
||||
|
||||
final OsmandApplication app = mapActivity.getMyApplication();
|
||||
final RoutingHelper routingHelper = app.getRoutingHelper();
|
||||
if (routingHelper.isRoutePlanningMode() || routingHelper.isFollowingMode()) {
|
||||
leftTitleButtonController = new TitleButtonController() {
|
||||
@Override
|
||||
public void buttonPressed() {
|
||||
app.getAvoidSpecificRoads().addImpassableRoad(mapActivity, getLatLon(), false, null, false);
|
||||
}
|
||||
};
|
||||
leftTitleButtonController.caption = mapActivity.getString(R.string.avoid_road);
|
||||
leftTitleButtonController.updateStateListDrawableIcon(R.drawable.ic_action_road_works_dark, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
|
|
|
@ -123,6 +123,10 @@ public class MapRouteInfoMenu implements IRouteInformationListener {
|
|||
this.onDismissListener = onDismissListener;
|
||||
}
|
||||
|
||||
public void cancelSelectionFromMap() {
|
||||
selectFromMapTouch = false;
|
||||
}
|
||||
|
||||
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
|
||||
if (selectFromMapTouch) {
|
||||
LatLon latlon = tileBox.getLatLonFromPixel(point.x, point.y);
|
||||
|
@ -237,7 +241,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener {
|
|||
ViewGroup vg = (ViewGroup) parentView.findViewById(R.id.app_modes);
|
||||
vg.removeAllViews();
|
||||
AppModeDialog.prepareAppModeView(mapActivity, selected, false,
|
||||
vg, true, true, new View.OnClickListener() {
|
||||
vg, true, false,true, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (selected.size() > 0) {
|
||||
|
|
|
@ -9,7 +9,6 @@ import net.osmand.plus.activities.MapActivity;
|
|||
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class MapillaryImageCard extends ImageCard {
|
||||
|
@ -28,7 +27,7 @@ public class MapillaryImageCard extends ImageCard {
|
|||
mapillaryPlugin.updateLayers(getMapActivity().getMapView(), getMapActivity(), true);
|
||||
}
|
||||
}
|
||||
getMapActivity().getContextMenu().hideMenues();
|
||||
getMapActivity().getContextMenu().close();
|
||||
MapillaryImageDialog.show(getMapActivity(), getKey(), getImageHiresUrl(), getUrl(), getLocation(),
|
||||
getCa(), getMyApplication().getString(R.string.mapillary), null, true);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import net.osmand.IProgress;
|
|||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.render.RenderingRuleProperty;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.osmand.render.RenderingRulesStorage.RenderingRulesStorageResolver;
|
||||
|
@ -31,11 +32,12 @@ public class RendererRegistry {
|
|||
|
||||
public final static String DEFAULT_RENDER = "OsmAnd"; //$NON-NLS-1$
|
||||
public final static String DEFAULT_RENDER_FILE_PATH = "default.render.xml";
|
||||
public final static String TOURING_VIEW = "Touring view (contrast and details)"; //$NON-NLS-1$
|
||||
public final static String WINTER_SKI_RENDER = "Winter and ski"; //$NON-NLS-1$
|
||||
public final static String NAUTICAL_RENDER = "Nautical"; //$NON-NLS-1$
|
||||
public final static String TOPO_RENDER = "Topo"; //$NON-NLS-1$
|
||||
public final static String MAPNIK_RENDER = "Mapnik"; //$NON-NLS-1$
|
||||
// Translatable renders
|
||||
public static String TOURING_VIEW;
|
||||
public static String WINTER_SKI_RENDER;
|
||||
public static String NAUTICAL_RENDER;
|
||||
|
||||
private RenderingRulesStorage defaultRender = null;
|
||||
private RenderingRulesStorage currentSelectedRender = null;
|
||||
|
@ -55,6 +57,9 @@ public class RendererRegistry {
|
|||
|
||||
public RendererRegistry(OsmandApplication app){
|
||||
this.app = app;
|
||||
WINTER_SKI_RENDER = app.getResources().getString(R.string.winter_and_ski_renderer);
|
||||
TOURING_VIEW = app.getResources().getString(R.string.touring_view_renderer);
|
||||
NAUTICAL_RENDER = app.getResources().getString(R.string.nautical_renderer);
|
||||
internalRenderers.put(DEFAULT_RENDER, DEFAULT_RENDER_FILE_PATH);
|
||||
internalRenderers.put(TOURING_VIEW, "Touring-view_(more-contrast-and-details)" +".render.xml");
|
||||
internalRenderers.put(TOPO_RENDER, "topo" + ".render.xml");
|
||||
|
|
|
@ -236,21 +236,20 @@ public class ContextMenuLayer extends OsmandMapLayer {
|
|||
|
||||
@Override
|
||||
public void populateObjectContextMenu(LatLon latLon, Object o, ContextMenuAdapter adapter, MapActivity mapActivity) {
|
||||
if (isObjectMoveable(o)) {
|
||||
ContextMenuAdapter.ItemClickListener listener = new ContextMenuAdapter.ItemClickListener() {
|
||||
@Override
|
||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||
RotatedTileBox tileBox = activity.getMapView().getCurrentRotatedTileBox();
|
||||
enterMovingMode(tileBox);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.change_markers_position, activity)
|
||||
.setIcon(R.drawable.ic_show_on_map)
|
||||
.setListener(listener)
|
||||
.createItem());
|
||||
}
|
||||
ContextMenuAdapter.ItemClickListener listener = new ContextMenuAdapter.ItemClickListener() {
|
||||
@Override
|
||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||
RotatedTileBox tileBox = activity.getMapView().getCurrentRotatedTileBox();
|
||||
enterMovingMode(tileBox);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.change_markers_position, activity)
|
||||
.setIcon(R.drawable.ic_show_on_map)
|
||||
.setClickable(isObjectMoveable(o))
|
||||
.setListener(listener)
|
||||
.createItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -617,7 +616,16 @@ public class ContextMenuLayer extends OsmandMapLayer {
|
|||
amenity.getX().addAll(renderedObject.getX());
|
||||
amenity.getY().addAll(renderedObject.getY());
|
||||
}
|
||||
selectedObjects.put(amenity, poiMenuProvider);
|
||||
boolean exists = false;
|
||||
for (Object o : selectedObjects.keySet()) {
|
||||
if (o instanceof Amenity && ((Amenity) o).compareTo(amenity) == 0) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists) {
|
||||
selectedObjects.put(amenity, poiMenuProvider);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
selectedObjects.put(renderedObject, null);
|
||||
|
|
|
@ -7,20 +7,16 @@ import android.graphics.Paint;
|
|||
import android.graphics.PointF;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.ContextMenuAdapter;
|
||||
import net.osmand.plus.ContextMenuItem;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidSpecificRoadsCallback;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -37,7 +33,6 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
|
|||
private Paint paint;
|
||||
private Map<Long, Location> impassableRoadLocations;
|
||||
private List<RouteDataObject> impassableRoads;
|
||||
private RoutingHelper routingHelper;
|
||||
|
||||
private ContextMenuLayer contextMenuLayer;
|
||||
|
||||
|
@ -51,7 +46,6 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
|
|||
public void initLayer(OsmandMapTileView view) {
|
||||
roadWorkIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_avoid_road);
|
||||
paint = new Paint();
|
||||
routingHelper = activity.getRoutingHelper();
|
||||
|
||||
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
|
||||
|
||||
|
@ -211,29 +205,6 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateObjectContextMenu(final LatLon latLon, final Object o, ContextMenuAdapter adapter, MapActivity mapActivity) {
|
||||
if (latLon != null && o == null
|
||||
&& (routingHelper.isRoutePlanningMode() || routingHelper.isFollowingMode())) {
|
||||
|
||||
ContextMenuAdapter.ItemClickListener listener = new ContextMenuAdapter.ItemClickListener() {
|
||||
@Override
|
||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||
if (itemId == R.string.avoid_road) {
|
||||
activity.getMyApplication().getAvoidSpecificRoads().addImpassableRoad(
|
||||
activity, latLon, false, null, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.avoid_road, activity)
|
||||
.setIcon(R.drawable.ic_action_road_works_dark)
|
||||
.setListener(listener)
|
||||
.createItem());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObjectMovable(Object o) {
|
||||
return o instanceof RouteDataObject;
|
||||
|
|
|
@ -450,6 +450,9 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
}
|
||||
|
||||
private void onNavigationClick() {
|
||||
if (mapRouteInfoMenu != null) {
|
||||
mapRouteInfoMenu.cancelSelectionFromMap();
|
||||
}
|
||||
MapActivity.clearPrevActivityIntent();
|
||||
RoutingHelper routingHelper = mapActivity.getRoutingHelper();
|
||||
if (!routingHelper.isFollowingMode() && !routingHelper.isRoutePlanningMode()) {
|
||||
|
|