diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index da7d276afb..d7355cd6a5 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,8 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Show closed notes + Show/Hide OSM Notes on the map. GPX - suitable for export to JOSM or other OSM editors. OSC - suitable for export to OpenStreetMap. GPX file diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 9b7c0012ae..ab15c8c281 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -1161,6 +1161,8 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference SHOW_OSM_BUGS = new BooleanPreference("show_osm_bugs", false).makeGlobal(); + public final CommonPreference SHOW_CLOSED_OSM_BUGS = new BooleanPreference("show_closed_osm_bugs", false).makeGlobal(); + public final CommonPreference SHOW_OSM_BUGS_MIN_ZOOM = new IntPreference("show_osm_bugs_min_zoom", 8).makeGlobal(); public final CommonPreference MAP_INFO_CONTROLS = new StringPreference("map_info_controls", "").makeProfile(); { diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java index ce7f5efdef..538b9f680d 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java @@ -76,6 +76,7 @@ import net.osmand.plus.mapcontextmenu.other.RoutePreferencesMenu; import net.osmand.plus.mapcontextmenu.other.RoutePreferencesMenu.LocalRoutingParameter; import net.osmand.plus.mapillary.MapillaryFiltersFragment; import net.osmand.plus.mapillary.MapillaryPlugin.MapillaryFirstDialogFragment; +import net.osmand.plus.osmedit.OsmNotesMenu; import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper.IRouteInformationListener; @@ -189,7 +190,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis UNDERLAY_MAP, MAPILLARY, CONTOUR_LINES, - HILLSHADE + HILLSHADE, + OSM_NOTES } private Map actionButtons = new HashMap<>(); @@ -428,6 +430,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis tv.setText(R.string.srtm_plugin_name); } else if (visibleType == DashboardType.HILLSHADE) { tv.setText(R.string.layer_hillshade); + } else if (visibleType == DashboardType.OSM_NOTES) { + tv.setText(R.string.osm_notes); } ImageView edit = (ImageView) dashboardView.findViewById(R.id.toolbar_edit); edit.setVisibility(View.GONE); @@ -822,7 +826,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis && visibleType != DashboardType.CONFIGURE_SCREEN && visibleType != DashboardType.CONFIGURE_MAP && visibleType != DashboardType.CONTOUR_LINES - && visibleType != DashboardType.HILLSHADE) { + && visibleType != DashboardType.HILLSHADE + && visibleType != DashboardType.OSM_NOTES) { listView.setDivider(dividerDrawable); listView.setDividerHeight(dpToPx(1f)); } else { @@ -879,6 +884,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis cm = ContourLinesMenu.createListAdapter(mapActivity); } else if (visibleType == DashboardType.HILLSHADE) { cm = HillshadeMenu.createListAdapter(mapActivity); + } else if (visibleType == DashboardType.OSM_NOTES) { + cm = OsmNotesMenu.createListAdapter(mapActivity); } if (cm != null) { updateListAdapter(cm); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java index c84a7aa825..3372657550 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java @@ -50,7 +50,6 @@ import java.util.List; public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider { private static final Log log = PlatformUtil.getLog(OsmBugsLayer.class); - private final static int startZoom = 8; private final OsmEditingPlugin plugin; private OsmandMapTileView view; @@ -65,6 +64,8 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider private OsmBugsLocalUtil local; private MapLayerData> data; + private int startZoom; + public OsmBugsLayer(MapActivity activity, OsmEditingPlugin plugin) { this.activity = activity; this.plugin = plugin; @@ -116,6 +117,7 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider @Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { + startZoom = activity.getMyApplication().getSettings().SHOW_OSM_BUGS_MIN_ZOOM.get(); if (tileBox.getZoom() >= startZoom) { // request to load data.queryNewData(tileBox); @@ -127,7 +129,11 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider List fullObjects = new ArrayList<>(); List fullObjectsLatLon = new ArrayList<>(); List smallObjectsLatLon = new ArrayList<>(); + boolean showClosed = activity.getMyApplication().getSettings().SHOW_CLOSED_OSM_BUGS.get(); for (OpenStreetNote o : objects) { + if (!o.isOpened() && !showClosed) { + continue; + } float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude()); float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude()); @@ -146,6 +152,9 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider } } for (OpenStreetNote o : fullObjects) { + if (!o.isOpened() && !showClosed) { + continue; + } float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude()); float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude()); Bitmap b; @@ -200,9 +209,13 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider final int rad = getRadiusBug(tb); int radius = rad * 3 / 2; int small = rad * 3 / 4; + boolean showClosed = activity.getMyApplication().getSettings().SHOW_CLOSED_OSM_BUGS.get(); try { for (int i = 0; i < objects.size(); i++) { OpenStreetNote n = objects.get(i); + if (!n.isOpened() && !showClosed) { + continue; + } int x = (int) tb.getPixXFromLatLon(n.getLatitude(), n.getLongitude()); int y = (int) tb.getPixYFromLatLon(n.getLatitude(), n.getLongitude()); if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java index d84d952025..9ae8f1160f 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java @@ -15,6 +15,7 @@ import android.widget.EditText; import android.widget.Spinner; import android.widget.Toast; +import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.data.Amenity; import net.osmand.osm.PoiType; @@ -30,6 +31,7 @@ import net.osmand.plus.activities.EnumAdapter; import net.osmand.plus.activities.EnumAdapter.IEnumWithResource; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TabActivity; +import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.myplaces.AvailableGPXFragment; import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo; @@ -258,11 +260,23 @@ public class OsmEditingPlugin extends OsmandPlugin { @Override public void registerLayerContextMenuActions(OsmandMapTileView mapView, ContextMenuAdapter adapter, final MapActivity mapActivity) { - adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.layer_osm_bugs, mapActivity) + adapter.addItem(new ContextMenuItem.ItemBuilder() + .setTitleId(R.string.layer_osm_bugs, mapActivity) .setSelected(settings.SHOW_OSM_BUGS.get()) .setIcon(R.drawable.ic_action_bug_dark) .setColor(settings.SHOW_OSM_BUGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) - .setListener(new ContextMenuAdapter.ItemClickListener() { + .setSecondaryIcon(R.drawable.ic_action_additional_option) + .setListener(new ContextMenuAdapter.OnRowItemClick() { + + @Override + public boolean onRowItemClick(ArrayAdapter adapter, View view, int itemId, int position) { + if (itemId == R.string.layer_osm_bugs) { + mapActivity.getDashboard().setDashboardVisibility(true, + DashboardType.OSM_NOTES, AndroidUtils.getCenterViewCoordinates(view)); + return false; + } + return true; + } @Override public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { @@ -279,7 +293,6 @@ public class OsmEditingPlugin extends OsmandPlugin { }) .setPosition(16) .createItem()); - } @Override diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java new file mode 100644 index 0000000000..775bdd40c8 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java @@ -0,0 +1,135 @@ +package net.osmand.plus.osmedit; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.widget.ArrayAdapter; + +import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.ContextMenuItem; +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.OsmandSettings.CommonPreference; +import net.osmand.plus.OsmandSettings.OsmandPreference; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; + +import java.util.Arrays; + +public class OsmNotesMenu { + + private static Integer[] zoomIntValues = {8, 9, 10, 11, 12, 13, 14, 15, 16}; + + public static ContextMenuAdapter createListAdapter(final MapActivity mapActivity) { + ContextMenuAdapter adapter = new ContextMenuAdapter(); + adapter.setDefaultLayoutId(R.layout.list_item_icon_and_menu); + createLayersItems(adapter, mapActivity); + return adapter; + } + + private static void createLayersItems(final ContextMenuAdapter adapter, final MapActivity mapActivity) { + final OsmandSettings settings = mapActivity.getMyApplication().getSettings(); + final OsmEditingPlugin plugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class); + + if (plugin == null) { + return; + } + + final int osmNotesStringId = R.string.layer_osm_bugs; + final int showZoomLevelStringId = R.string.show_from_zoom_level; + final int showClosedNotesStringId = R.string.show_closed_notes; + + final OsmandPreference showOsmBugsPref = settings.SHOW_OSM_BUGS; + final CommonPreference showClosedOsmBugsPref = settings.SHOW_CLOSED_OSM_BUGS; + final CommonPreference showOsmBugsZoomPref = settings.SHOW_OSM_BUGS_MIN_ZOOM; + + final String[] zoomStrings = getZoomStrings(mapActivity); + + ContextMenuAdapter.OnRowItemClick l = new ContextMenuAdapter.OnRowItemClick() { + @Override + public boolean onContextMenuClick(final ArrayAdapter adapter, int itemId, + final int position, boolean isChecked, int[] viewCoordinates) { + if (itemId == osmNotesStringId) { + showOsmBugsPref.set(isChecked); + plugin.updateLayers(mapActivity.getMapView(), mapActivity); + mapActivity.refreshMap(); + mapActivity.getDashboard().refreshContent(true); + } else if (itemId == showZoomLevelStringId) { + int checked = Arrays.asList(zoomIntValues).indexOf(showOsmBugsZoomPref.get()); + + new AlertDialog.Builder(mapActivity) + .setTitle(R.string.show_from_zoom_level) + .setSingleChoiceItems(zoomStrings, checked, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + showOsmBugsZoomPref.set(zoomIntValues[which]); + ContextMenuItem item = adapter.getItem(position); + if (item != null) { + item.setDescription(zoomStrings[which]); + adapter.notifyDataSetChanged(); + } + mapActivity.refreshMap(); + dialog.dismiss(); + } + }) + .setNegativeButton(R.string.shared_string_dismiss, null) + .show(); + } else if (itemId == showClosedNotesStringId) { + showClosedOsmBugsPref.set(isChecked); + mapActivity.refreshMap(); + } + return false; + } + }; + + boolean showOsmBugs = showOsmBugsPref.get(); + boolean nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls(); + int toggleIconColorId; + if (showOsmBugs) { + toggleIconColorId = nightMode ? R.color.color_dialog_buttons_dark : R.color.color_dialog_buttons_light; + } else { + toggleIconColorId = nightMode ? 0 : R.color.icon_color; + } + + adapter.addItem(new ContextMenuItem.ItemBuilder() + .setTitleId(osmNotesStringId, mapActivity) + .setDescription(mapActivity.getString(R.string.switch_osm_notes_visibility_desc)) + .setIcon(R.drawable.ic_action_bug_dark) + .setColor(toggleIconColorId) + .setListener(l) + .setSelected(showOsmBugs) + .createItem()); + + adapter.addItem(new ContextMenuItem.ItemBuilder() + .setTitleId(showZoomLevelStringId, mapActivity) + .setDescription(zoomStrings[Arrays.asList(zoomIntValues).indexOf(showOsmBugsZoomPref.get())]) + .setLayout(R.layout.list_item_single_line_descrition_narrow) + .setIcon(R.drawable.ic_action_map_magnifier) + .setListener(l) + .setClickable(showOsmBugs) + .createItem()); + + adapter.addItem(new ContextMenuItem.ItemBuilder() + .setTitleId(showClosedNotesStringId, mapActivity) + .setIcon(R.drawable.ic_action_note_dark) + .setListener(l) + .setSelected(showClosedOsmBugsPref.get()) + .setClickable(showOsmBugs) + .hideDivider(true) + .createItem()); + + adapter.addItem(new ContextMenuItem.ItemBuilder() + .setLayout(R.layout.card_bottom_divider) + .setClickable(false) + .createItem()); + } + + private static String[] getZoomStrings(Context context) { + String[] res = new String[zoomIntValues.length]; + for (int i = 0; i < zoomIntValues.length; i++) { + String strVal = String.valueOf(zoomIntValues[i]); + res[i] = i == 0 ? context.getString(R.string.rendering_value_default_name) + " (" + strVal + ")" : strVal; + } + return res; + } +}