From 201af02431f0cf4499694023e3a5f6ee2461d300 Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Fri, 5 Feb 2016 21:41:25 +0300 Subject: [PATCH] Markers in progress --- OsmAnd/res/layout/map_markers.xml | 14 ++ OsmAnd/res/values/strings.xml | 3 + .../src/net/osmand/plus/AppInitializer.java | 1 + .../src/net/osmand/plus/MapMarkersHelper.java | 224 ++++++++++++++++++ .../net/osmand/plus/OsmandApplication.java | 5 + .../src/net/osmand/plus/OsmandSettings.java | 32 ++- .../plus/activities/MapActivityLayers.java | 5 + .../plus/activities/MapMarkersActivity.java | 201 ++++++++++++++++ .../plus/base/MapViewTrackingUtilities.java | 15 +- .../plus/mapcontextmenu/MenuController.java | 5 + .../controllers/MapMarkerMenuController.java | 74 ++++++ .../osmand/plus/views/MapMarkersLayer.java | 159 +++++++++++++ 12 files changed, 725 insertions(+), 13 deletions(-) create mode 100644 OsmAnd/res/layout/map_markers.xml create mode 100644 OsmAnd/src/net/osmand/plus/MapMarkersHelper.java create mode 100644 OsmAnd/src/net/osmand/plus/activities/MapMarkersActivity.java create mode 100644 OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java create mode 100644 OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java diff --git a/OsmAnd/res/layout/map_markers.xml b/OsmAnd/res/layout/map_markers.xml new file mode 100644 index 0000000000..885ad6464f --- /dev/null +++ b/OsmAnd/res/layout/map_markers.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 413fa3077f..abd958b898 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,9 @@ 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 --> + Active markers + Map markers + Map marker Show polygons Underlay transparency Find a parking diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index a7c3c33587..7c6b2c5a28 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -342,6 +342,7 @@ public class AppInitializer implements IProgress { app.rendererRegistry = startupInit(new RendererRegistry(app), RendererRegistry.class); app.geocodingLookupService = startupInit(new GeocodingLookupService(app), GeocodingLookupService.class); app.targetPointsHelper = startupInit(new TargetPointsHelper(app), TargetPointsHelper.class); + app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class); } diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java new file mode 100644 index 0000000000..1fd859c3b2 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -0,0 +1,224 @@ +package net.osmand.plus; + +import android.content.Context; + +import net.osmand.StateChangedListener; +import net.osmand.data.LatLon; +import net.osmand.data.LocationPoint; +import net.osmand.data.PointDescription; +import net.osmand.plus.GeocodingLookupService; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; + +import java.util.ArrayList; +import java.util.List; + +public class MapMarkersHelper { + private List mapMarkers = new ArrayList<>(); + private List mapMarkersHistory = new ArrayList<>(); + private OsmandSettings settings; + private List> listeners = new ArrayList>(); + private OsmandApplication ctx; + + public static class MapMarker implements LocationPoint { + public LatLon point; + private PointDescription pointDescription; + public int colorIndex; + public int index; + + public MapMarker(LatLon point, PointDescription name, int colorIndex) { + this.point = point; + this.pointDescription = name; + this.colorIndex = colorIndex; + } + + public MapMarker(LatLon point, PointDescription name, int colorIndex, int index) { + this.point = point; + this.pointDescription = name; + this.colorIndex = colorIndex; + this.index = index; + } + + public PointDescription getPointDescription(Context ctx) { + return new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, ctx.getString(R.string.map_marker, ""), + getOnlyName()); + } + + public PointDescription getOriginalPointDescription() { + return pointDescription; + } + + public String getOnlyName() { + return pointDescription == null ? "" : pointDescription.getName(); + } + + public boolean isSearchingAddress(Context ctx) { + return pointDescription != null && pointDescription.isSearchingAddress(ctx); + } + + public static MapMarker create(LatLon point, PointDescription name, int color) { + if (point != null) { + return new MapMarker(point, name, color); + } + return null; + } + + public double getLatitude() { + return point.getLatitude(); + } + + public double getLongitude() { + return point.getLongitude(); + } + + public int getColorIndex() { + return colorIndex; + } + + @Override + public int getColor() { + return 0; + } + + @Override + public boolean isVisible() { + return false; + } + + } + + public MapMarkersHelper(OsmandApplication ctx) { + this.ctx = ctx; + this.settings = ctx.getSettings(); + readFromSettings(); + } + + private void readFromSettings() { + mapMarkers.clear(); + mapMarkersHistory.clear(); + List ips = settings.getMapMarkersPoints(); + List desc = settings.getMapMarkersPointDescriptions(ips.size()); + List colors = settings.getMapMarkersColors(ips.size()); + for (int i = 0; i < ips.size(); i++) { + final MapMarker mapMarker = new MapMarker(ips.get(i), + PointDescription.deserializeFromString(desc.get(i), ips.get(i)), colors.get(i), i); + mapMarkers.add(mapMarker); + lookupAddress(mapMarker, false); + } + ips = settings.getMapMarkersHistoryPoints(); + desc = settings.getMapMarkersHistoryPointDescriptions(ips.size()); + colors = settings.getMapMarkersHistoryColors(ips.size()); + for (int i = 0; i < ips.size(); i++) { + final MapMarker mapMarker = new MapMarker(ips.get(i), + PointDescription.deserializeFromString(desc.get(i), ips.get(i)), colors.get(i), i); + mapMarkersHistory.add(mapMarker); + lookupAddress(mapMarker, true); + } + } + + private void lookupAddress(final MapMarker mapMarker, final boolean history) { + if (mapMarker != null && mapMarker.pointDescription.isSearchingAddress(ctx)) { + cancelPointAddressRequests(mapMarker.point); + GeocodingLookupService.AddressLookupRequest lookupRequest = new GeocodingLookupService.AddressLookupRequest(mapMarker.point, new GeocodingLookupService.OnAddressLookupResult() { + @Override + public void geocodingDone(String address) { + mapMarker.pointDescription.setName(address); + if (history) { + settings.updateMapMarkerHistory(mapMarker.point.getLatitude(), mapMarker.point.getLongitude(), + mapMarker.pointDescription, mapMarker.colorIndex); + } else { + settings.updateMapMarker(mapMarker.point.getLatitude(), mapMarker.point.getLongitude(), + mapMarker.pointDescription, mapMarker.colorIndex); + } + refresh(); + } + }, null); + ctx.getGeocodingLookupService().lookupAddress(lookupRequest); + } + } + + public void removeMapMarker(int index) { + settings.deleteMapMarker(index); + MapMarker mapMarker = mapMarkers.remove(index); + cancelPointAddressRequests(mapMarker.point); + int ind = 0; + for (MapMarker marker : mapMarkers) { + marker.index = ind++; + } + refresh(); + } + + public List getActiveMapMarkers() { + return mapMarkers; + } + + public List getMapMarkersHistory() { + return mapMarkersHistory; + } + + public List getActiveMarkersLatLon() { + List list = new ArrayList(); + for (MapMarker m : this.mapMarkers) { + list.add(m.point); + } + return list; + } + + public List getMarkersHistoryLatLon() { + List list = new ArrayList(); + for (MapMarker m : this.mapMarkersHistory) { + list.add(m.point); + } + return list; + } + + public void removeActiveMarkers() { + cancelAddressRequests(); + + settings.clearIntermediatePoints(); + mapMarkers.clear(); + readFromSettings(); + refresh(); + } + + public void removeMarkersHistory() { + cancelAddressRequests(); + + settings.clearIntermediatePoints(); + mapMarkersHistory.clear(); + readFromSettings(); + refresh(); + } + + public void addListener(StateChangedListener l) { + listeners.add(l); + } + + private void updateListeners() { + for (StateChangedListener l : listeners) { + l.stateChanged(null); + } + } + + public void refresh() { + updateListeners(); + } + + private void cancelAddressRequests() { + List list = getActiveMarkersLatLon(); + for (LatLon latLon : list) { + cancelPointAddressRequests(latLon); + } + list = getMarkersHistoryLatLon(); + for (LatLon latLon : list) { + cancelPointAddressRequests(latLon); + } + } + + private void cancelPointAddressRequests(LatLon latLon) { + if (latLon != null) { + ctx.getGeocodingLookupService().cancel(latLon); + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 23c41644d1..4e8b6b828a 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -91,6 +91,7 @@ public class OsmandApplication extends MultiDexApplication { NotificationHelper notificationHelper; LiveMonitoringHelper liveMonitoringHelper; TargetPointsHelper targetPointsHelper; + MapMarkersHelper mapMarkersHelper; WaypointHelper waypointHelper; DownloadIndexesThread downloadIndexesThread; AvoidSpecificRoads avoidSpecificRoads; @@ -540,6 +541,10 @@ public class OsmandApplication extends MultiDexApplication { return targetPointsHelper; } + public MapMarkersHelper getMapMarkersHelper() { + return mapMarkersHelper; + } + public void showShortToastMessage(final int msgId, final Object... args) { uiHandler.post(new Runnable() { @Override diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 7df5f81a9c..7530e57995 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -1574,13 +1574,13 @@ public class OsmandSettings { } public boolean insertPoint(double latitude, double longitude, - PointDescription historyDescription, int color, int index) { + PointDescription historyDescription, int colorIndex, int index) { List ps = getPoints(); List ds = getPointDescriptions(ps.size()); List cs = getColors(ps.size()); ps.add(index, new LatLon(latitude, longitude)); ds.add(index, PointDescription.serializeToString(historyDescription)); - cs.add(index, color); + cs.add(index, colorIndex); if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) { SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription); } @@ -1588,13 +1588,13 @@ public class OsmandSettings { } public boolean updatePoint(double latitude, double longitude, - PointDescription historyDescription, int color) { + PointDescription historyDescription, int colorIndex) { List ps = getPoints(); List ds = getPointDescriptions(ps.size()); List cs = getColors(ps.size()); int i = ps.indexOf(new LatLon(latitude, longitude)); ds.set(i, PointDescription.serializeToString(historyDescription)); - cs.set(i, color); + cs.set(i, colorIndex); if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) { SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription); } @@ -1787,18 +1787,22 @@ public class OsmandSettings { return mapMarkersStorage.getPointDescriptions(sz); } + public List getMapMarkersColors(int sz) { + return mapMarkersStorage.getColors(sz); + } + public List getMapMarkersPoints() { return mapMarkersStorage.getPoints(); } public boolean insertMapMarker(double latitude, double longitude, - PointDescription historyDescription, int color, int index) { - return mapMarkersStorage.insertPoint(latitude, longitude, historyDescription, color, index); + PointDescription historyDescription, int colorIndex, int index) { + return mapMarkersStorage.insertPoint(latitude, longitude, historyDescription, colorIndex, index); } public boolean updateMapMarker(double latitude, double longitude, - PointDescription historyDescription, int color) { - return mapMarkersStorage.updatePoint(latitude, longitude, historyDescription, color); + PointDescription historyDescription, int colorIndex) { + return mapMarkersStorage.updatePoint(latitude, longitude, historyDescription, colorIndex); } public boolean deleteMapMarker(int index) { @@ -1814,18 +1818,22 @@ public class OsmandSettings { return mapMarkersHistoryStorage.getPointDescriptions(sz); } + public List getMapMarkersHistoryColors(int sz) { + return mapMarkersHistoryStorage.getColors(sz); + } + public List getMapMarkersHistoryPoints() { return mapMarkersHistoryStorage.getPoints(); } public boolean insertMapMarkerHistory(double latitude, double longitude, - PointDescription historyDescription, int color, int index) { - return mapMarkersHistoryStorage.insertPoint(latitude, longitude, historyDescription, color, index); + PointDescription historyDescription, int colorIndex, int index) { + return mapMarkersHistoryStorage.insertPoint(latitude, longitude, historyDescription, colorIndex, index); } public boolean updateMapMarkerHistory(double latitude, double longitude, - PointDescription historyDescription, int color) { - return mapMarkersHistoryStorage.updatePoint(latitude, longitude, historyDescription, color); + PointDescription historyDescription, int colorIndex) { + return mapMarkersHistoryStorage.updatePoint(latitude, longitude, historyDescription, colorIndex); } public boolean deleteMapMarkerHistory(int index) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index 5c2c36fbab..868e0333b0 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -38,6 +38,7 @@ import net.osmand.plus.views.GPXLayer; import net.osmand.plus.views.ImpassableRoadsLayer; import net.osmand.plus.views.MapControlsLayer; import net.osmand.plus.views.MapInfoLayer; +import net.osmand.plus.views.MapMarkersLayer; import net.osmand.plus.views.MapTextLayer; import net.osmand.plus.views.MapTileLayer; import net.osmand.plus.views.OsmandMapTileView; @@ -72,6 +73,7 @@ public class MapActivityLayers { private TransportInfoLayer transportInfoLayer; private PointLocationLayer locationLayer; private PointNavigationLayer navigationLayer; + private MapMarkersLayer mapMarkersLayer; private ImpassableRoadsLayer impassableRoadsLayer; private MapInfoLayer mapInfoLayer; private MapTextLayer mapTextLayer; @@ -143,6 +145,9 @@ public class MapActivityLayers { // 7. point navigation layer navigationLayer = new PointNavigationLayer(activity); mapView.addLayer(navigationLayer, 7); + // 7.3 map markers layer + mapMarkersLayer = new MapMarkersLayer(activity); + mapView.addLayer(mapMarkersLayer, 7.3f); // 7.5 Impassible roads impassableRoadsLayer = new ImpassableRoadsLayer(activity); mapView.addLayer(impassableRoadsLayer, 7.5f); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapMarkersActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapMarkersActivity.java new file mode 100644 index 0000000000..605990e7e1 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/activities/MapMarkersActivity.java @@ -0,0 +1,201 @@ +package net.osmand.plus.activities; + +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.CompoundButton; +import android.widget.TextView; + +import net.osmand.AndroidUtils; +import net.osmand.plus.GeocodingLookupService; +import net.osmand.plus.MapMarkersHelper; +import net.osmand.plus.MapMarkersHelper.MapMarker; +import net.osmand.plus.R; +import net.osmand.plus.helpers.WaypointHelper; +import net.osmand.plus.views.controls.StableArrayAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class MapMarkersActivity extends OsmandListActivity { + + public static final int ACTIVE_MARKERS = 0; + public static final int MARKERS_HISTORY = 1; + + private boolean nightMode; + + @Override + protected void onCreate(Bundle savedInstanceState) { + getMyApplication().applyTheme(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.map_markers); + getSupportActionBar().setTitle(R.string.map_markers); + + nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls(); + setListAdapter(getMapMarkersListAdapter()); + } + + @Override + public StableArrayAdapter getListAdapter() { + return (StableArrayAdapter) super.getListAdapter(); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + getListAdapter().getItem(position); + // + } + + @Override + protected void onResume() { + super.onResume(); + getListAdapter().notifyDataSetChanged(); + } + + public StableArrayAdapter getMapMarkersListAdapter() { + + final List objects = getListObjects(); + List activeObjects = getActiveObjects(objects); + + final StableArrayAdapter listAdapter = new StableArrayAdapter(getMyApplication(), + R.layout.waypoint_reached, R.id.title, objects, activeObjects) { + + @Override + public void buildDividers() { + dividers = getCustomDividers(ctx, getObjects(), nightMode); + } + + @Override + public View getView(final int position, View convertView, ViewGroup parent) { + // User super class to create the View + View v = convertView; + final ArrayAdapter thisAdapter = this; + Object obj = getItem(position); + boolean labelView = (obj instanceof Integer); + boolean topDividerView = (obj instanceof Boolean) && ((Boolean) obj); + boolean bottomDividerView = (obj instanceof Boolean) && !((Boolean) obj); + if (labelView) { + v = createItemForCategory(ctx, (Integer) obj, running, position, thisAdapter, nightMode); + AndroidUtils.setListItemBackground(MapMarkersActivity.this, v, nightMode); + } else if (topDividerView) { + v = ctx.getLayoutInflater().inflate(R.layout.card_top_divider, null); + } else if (bottomDividerView) { + v = ctx.getLayoutInflater().inflate(R.layout.card_bottom_divider, null); + } else if (obj instanceof MapMarker) { + MapMarker marker = (MapMarker) obj; + v = updateWaypointItemView(edit, deletedPoints, app, ctx, helper, v, marker, this, + nightMode, flat); + AndroidUtils.setListItemBackground(MapMarkersActivity.this, v, nightMode); + } + return v; + } + }; + + for (Object p : objects) { + if (p instanceof MapMarker) { + final MapMarker marker = (MapMarker) p; + if (marker.getOriginalPointDescription() != null + && marker.getOriginalPointDescription().isSearchingAddress(this)) { + GeocodingLookupService.AddressLookupRequest lookupRequest + = new GeocodingLookupService.AddressLookupRequest(marker.point, new GeocodingLookupService.OnAddressLookupResult() { + @Override + public void geocodingDone(String address) { + if (helperCallbacks != null) { + helperCallbacks.reloadAdapter(); + } else { + reloadListAdapter(listAdapter); + } + } + }, null); + getMyApplication().getGeocodingLookupService().lookupAddress(lookupRequest); + } + } + } + + return listAdapter; + } + + protected View createItemForCategory(final int type, final int position, final ArrayAdapter thisAdapter, boolean nightMode) { + View v = getLayoutInflater().inflate(R.layout.waypoint_header, null); + final CompoundButton btn = (CompoundButton) v.findViewById(R.id.check_item); + btn.setVisibility(waypointHelper.isTypeConfigurable(type) ? View.VISIBLE : View.GONE); + btn.setOnCheckedChangeListener(null); + final boolean checked = waypointHelper.isTypeEnabled(type); + btn.setChecked(checked); + btn.setEnabled(running[0] == -1); + v.findViewById(R.id.ProgressBar).setVisibility(position == running[0] ? View.VISIBLE : View.GONE); + btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + running[0] = position; + thisAdapter.notifyDataSetInvalidated(); + if (type == WaypointHelper.POI && isChecked) { + selectPoi(running, thisAdapter, type, isChecked, ctx); + } else { + enableType(running, thisAdapter, type, isChecked); + } + } + + }); + + TextView tv = (TextView) v.findViewById(R.id.header_text); + AndroidUtils.setTextPrimaryColor(mapActivity, tv, nightMode); + tv.setText(getHeader(type, checked, ctx)); + return v; + } + + protected String getHeader(int type) { + String str = getString(R.string.map_markers); + switch (type) { + case ACTIVE_MARKERS: + str = getString(R.string.active_markers); + break; + case MARKERS_HISTORY: + str = getString(R.string.shared_string_history); + break; + } + return str; + } + + + //LatLon lastKnownMapLocation = getMyApplication().getSettings().getLastKnownMapLocation(); + //int dist = (int) (MapUtils.getDistance(marker.getLatitude(), marker.getLongitude(), + //lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude())); + + protected List getListObjects() { + final List objects = new ArrayList<>(); + final MapMarkersHelper markersHelper = getMyApplication().getMapMarkersHelper(); + + List activeMarkers = markersHelper.getActiveMapMarkers(); + if (activeMarkers.size() > 0) { + objects.add(true); + objects.add(ACTIVE_MARKERS); + objects.addAll(activeMarkers); + objects.add(false); + } + + List markersHistory = markersHelper.getMapMarkersHistory(); + if (markersHistory.size() > 0) { + objects.add(true); + objects.add(MARKERS_HISTORY); + objects.addAll(markersHistory); + objects.add(false); + } + + return objects; + } + + private List getActiveObjects(List objects) { + List activeObjects = new ArrayList<>(); + for (Object obj : objects) { + if (obj instanceof MapMarker) { + activeObjects.add(obj); + } + } + return activeObjects; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java index ecd6adbf45..07d7ad6e5f 100644 --- a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java +++ b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java @@ -53,6 +53,7 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc app.getLocationProvider().addLocationListener(this); app.getLocationProvider().addCompassListener(this); addTargetPointListener(app); + addMapMarkersListener(app); app.getRoutingHelper().addListener(this); } @@ -67,7 +68,19 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc } }); } - + + private void addMapMarkersListener(OsmandApplication app) { + app.getMapMarkersHelper().addListener(new StateChangedListener() { + + @Override + public void stateChanged(Void change) { + if(mapView != null) { + mapView.refreshMap(); + } + } + }); + } + public void setMapView(OsmandMapTileView mapView) { this.mapView = mapView; if(mapView != null) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java index 49924b84f9..532cdc6698 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuController.java @@ -11,6 +11,8 @@ import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; +import net.osmand.plus.MapMarkersHelper; +import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper.TargetPoint; @@ -24,6 +26,7 @@ import net.osmand.plus.mapcontextmenu.controllers.GpxItemMenuController; import net.osmand.plus.mapcontextmenu.controllers.HistoryMenuController; import net.osmand.plus.mapcontextmenu.controllers.ImpassibleRoadsMenuController; import net.osmand.plus.mapcontextmenu.controllers.MapDataMenuController; +import net.osmand.plus.mapcontextmenu.controllers.MapMarkerMenuController; import net.osmand.plus.mapcontextmenu.controllers.MyLocationMenuController; import net.osmand.plus.mapcontextmenu.controllers.PointDescriptionMenuController; import net.osmand.plus.mapcontextmenu.controllers.TargetPointMenuController; @@ -101,6 +104,8 @@ public abstract class MenuController extends BaseMenuController { menuController = new OsmBugMenuController(app, mapActivity, pointDescription, (OpenStreetNote) object); } else if (object instanceof GpxDisplayItem) { menuController = new GpxItemMenuController(app, mapActivity, pointDescription, (GpxDisplayItem) object); + } else if (object instanceof MapMarker) { + menuController = new MapMarkerMenuController(app, mapActivity, pointDescription, (MapMarker) object); } else if (object instanceof LatLon) { if (pointDescription.isParking()) { menuController = new ParkingPositionMenuController(app, mapActivity, pointDescription); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java new file mode 100644 index 0000000000..aa5e32cebf --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java @@ -0,0 +1,74 @@ +package net.osmand.plus.mapcontextmenu.controllers; + +import android.graphics.drawable.Drawable; + +import net.osmand.data.PointDescription; +import net.osmand.plus.MapMarkersHelper; +import net.osmand.plus.MapMarkersHelper.MapMarker; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.mapcontextmenu.MenuBuilder; +import net.osmand.plus.mapcontextmenu.MenuController; +import net.osmand.util.Algorithms; + +public class MapMarkerMenuController extends MenuController { + + private MapMarker mapMarker; + + public MapMarkerMenuController(OsmandApplication app, MapActivity mapActivity, PointDescription pointDescription, MapMarker mapMarker) { + super(new MenuBuilder(app), pointDescription, mapActivity); + this.mapMarker = mapMarker; + final MapMarkersHelper markersHelper = app.getMapMarkersHelper(); + leftTitleButtonController = new TitleButtonController() { + @Override + public void buttonPressed() { + markersHelper.removeMapMarker(getMapMarker().index); + getMapActivity().getContextMenu().close(); + } + }; + leftTitleButtonController.caption = getMapActivity().getString(R.string.shared_string_remove); + leftTitleButtonController.leftIconId = R.drawable.ic_action_delete_dark; + } + + @Override + protected void setObject(Object object) { + if (object instanceof MapMarker) { + this.mapMarker = (MapMarker) object; + } + } + + public MapMarker getMapMarker() { + return mapMarker; + } + + @Override + protected int getSupportedMenuStatesPortrait() { + return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN; + } + + @Override + public boolean needTypeStr() { + return !Algorithms.isEmpty(getNameStr()); + } + + @Override + public boolean displayDistanceDirection() { + return true; + } + + @Override + public Drawable getLeftIcon() { + return getIconOrig(R.drawable.list_intermediate); + } + + @Override + public String getTypeStr() { + return mapMarker.getPointDescription(getMapActivity()).getTypeName(); + } + + @Override + public boolean needStreetName() { + return !needTypeStr(); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java b/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java new file mode 100644 index 0000000000..3587f72c73 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/views/MapMarkersLayer.java @@ -0,0 +1,159 @@ +package net.osmand.plus.views; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PointF; + +import net.osmand.data.LatLon; +import net.osmand.data.PointDescription; +import net.osmand.data.RotatedTileBox; +import net.osmand.plus.MapMarkersHelper; +import net.osmand.plus.MapMarkersHelper.MapMarker; +import net.osmand.plus.R; +import net.osmand.plus.TargetPointsHelper; +import net.osmand.plus.activities.MapActivity; + +import java.util.List; + +public class MapMarkersLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider { + private final MapActivity map; + private OsmandMapTileView view; + + private Paint bitmapPaint; + private Bitmap markerBitmap; + + public MapMarkersLayer(MapActivity map) { + this.map = map; + } + + private void initUI() { + bitmapPaint = new Paint(); + bitmapPaint.setDither(true); + bitmapPaint.setAntiAlias(true); + bitmapPaint.setFilterBitmap(true); + markerBitmap = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_intermediate_point); + } + + @Override + public void initLayer(OsmandMapTileView view) { + this.view = view; + initUI(); + } + + @Override + public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) { + if (tb.getZoom() < 3) { + return; + } + + MapMarkersHelper markersHelper = map.getMyApplication().getMapMarkersHelper(); + int index = 0; + for (MapMarker marker : markersHelper.getActiveMapMarkers()) { + index++; + if (isLocationVisible(tb, marker)) { + int marginX = markerBitmap.getWidth() / 6; + int marginY = markerBitmap.getHeight(); + int locationX = tb.getPixXFromLonNoRot(marker.getLongitude()); + int locationY = tb.getPixYFromLatNoRot(marker.getLatitude()); + canvas.rotate(-tb.getRotate(), locationX, locationY); + canvas.drawBitmap(markerBitmap, locationX - marginX, locationY - marginY, bitmapPaint); + canvas.rotate(tb.getRotate(), locationX, locationY); + } + } + } + + public boolean isLocationVisible(RotatedTileBox tb, MapMarker marker) { + if (marker == null || tb == null) { + return false; + } + return tb.containsLatLon(marker.getLatitude(), marker.getLongitude()); + } + + + @Override + public void destroyLayer() { + + } + + @Override + public boolean drawInScreenPixels() { + return false; + } + + @Override + public boolean disableSingleTap() { + return false; + } + + @Override + public boolean disableLongPressOnMap() { + return false; + } + + @Override + public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List o) { + MapMarkersHelper markersHelper = map.getMyApplication().getMapMarkersHelper(); + List markers = markersHelper.getActiveMapMarkers(); + int r = getRadiusPoi(tileBox); + for (int i = 0; i < markers.size(); i++) { + MapMarker marker = markers.get(i); + LatLon latLon = marker.point; + if (latLon != null) { + int ex = (int) point.x; + int ey = (int) point.y; + int x = (int) tileBox.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude()); + int y = (int) tileBox.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude()); + if (calculateBelongs(ex, ey, x, y, r)) { + o.add(marker); + } + } + } + + + } + + private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) { + return Math.abs(objx - ex) <= radius && (ey - objy) <= radius && (objy - ey) <= 2.5 * radius; + } + + public int getRadiusPoi(RotatedTileBox tb) { + int r = 0; + final double zoom = tb.getZoom(); + if (zoom <= 15) { + r = 10; + } else if (zoom <= 16) { + r = 14; + } else if (zoom <= 17) { + r = 16; + } else { + r = 18; + } + return (int) (r * tb.getDensity()); + } + + @Override + public LatLon getObjectLocation(Object o) { + if (o instanceof MapMarker) { + return ((MapMarker) o).point; + } + return null; + } + + @Override + public String getObjectDescription(Object o) { + if (o instanceof MapMarker) { + return ((MapMarker) o).getPointDescription(view.getContext()).getFullPlainName(view.getContext()); + } + return null; + } + + @Override + public PointDescription getObjectName(Object o) { + if (o instanceof MapMarker) { + return ((MapMarker) o).getPointDescription(view.getContext()); + } + return null; + } +}