Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2018-01-24 12:47:58 +01:00
commit 514cfa883a
64 changed files with 368 additions and 885 deletions

View file

@ -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);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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) {

View file

@ -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) {

View file

@ -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));

View file

@ -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

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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() {

View file

@ -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) {

View file

@ -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);
}

View file

@ -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");

View file

@ -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);

View file

@ -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;

View file

@ -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()) {