diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java index cd332bdfac..c3059f698a 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java @@ -1,26 +1,46 @@ package net.osmand.plus.mapcontextmenu.controllers; +import android.view.View; + import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.data.QuadRect; +import net.osmand.data.TransportRoute; +import net.osmand.data.TransportStop; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.mapcontextmenu.builders.AmenityMenuBuilder; +import net.osmand.plus.mapcontextmenu.controllers.TransportStopController.TransportStopRoute; import net.osmand.plus.render.RenderingIcons; +import net.osmand.plus.resources.TransportIndexRepository; +import net.osmand.plus.views.TransportStopsLayer; import net.osmand.util.Algorithms; +import net.osmand.util.MapUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; public class AmenityMenuController extends MenuController { private Amenity amenity; + private List routes = new ArrayList<>(); public AmenityMenuController(OsmandApplication app, MapActivity mapActivity, PointDescription pointDescription, Amenity amenity) { super(new AmenityMenuBuilder(app, amenity), pointDescription, mapActivity); this.amenity = amenity; + if (amenity.getType().getKeyName().equals("transportation")) { + processTransportStop(); + } } @Override @@ -103,6 +123,28 @@ public class AmenityMenuController extends MenuController { @Override public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) { addPlainMenuItems(amenity, typeStr, builder); + for (final TransportStopRoute r : routes) { + View.OnClickListener listener = new View.OnClickListener() { + @Override + public void onClick(View arg0) { + MapContextMenu mm = getMapActivity().getContextMenu(); + PointDescription pd = new PointDescription(PointDescription.POINT_TYPE_TRANSPORT_ROUTE, + r.getDescription(getMapActivity().getMyApplication(), false)); + mm.show(amenity.getLocation(), pd, r); + TransportStopsLayer stopsLayer = getMapActivity().getMapLayers().getTransportStopsLayer(); + stopsLayer.setRoute(r.route); + int cz = r.calculateZoom(0, getMapActivity().getMapView().getCurrentRotatedTileBox()); + getMapActivity().changeZoom(cz - getMapActivity().getMapView().getZoom()); + } + }; + if (r.type == null) { + builder.addPlainMenuItem(R.drawable.ic_action_polygom_dark, r.getDescription(getMapActivity().getMyApplication(), true), + false, false, listener ); + } else { + builder.addPlainMenuItem(r.type.getResourceId(), r.getDescription(getMapActivity().getMyApplication(), true), + false, false, listener); + } + } } public static void addPlainMenuItems(Amenity amenity, String typeStr, MenuBuilder builder) { @@ -118,4 +160,54 @@ public class AmenityMenuController extends MenuController { builder.addPlainMenuItem(resId, typeStr, false, false, null); } } + + private void processTransportStop() { + routes = new ArrayList<>(); + List reps = getMapActivity().getMyApplication() + .getResourceManager().searchTransportRepositories(amenity.getLocation().getLatitude(), + amenity.getLocation().getLongitude()); + + boolean useEnglishNames = getMapActivity().getMyApplication().getSettings().usingEnglishNames(); + + for (TransportIndexRepository t : reps) { + ArrayList ls = new ArrayList<>(); + QuadRect ll = MapUtils.calculateLatLonBbox(amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), 150); + t.searchTransportStops(ll.top, ll.left, ll.bottom, ll.right, -1, ls, null); + for (TransportStop tstop : ls) { + addRoutes(useEnglishNames, t, tstop, + (int) MapUtils.getDistance(tstop.getLocation(), amenity.getLocation())); + } + } + Collections.sort(routes, new Comparator() { + + @Override + public int compare(TransportStopRoute o1, TransportStopRoute o2) { + if (o1.distance != o2.distance) { + return Algorithms.compare(o1.distance, o2.distance); + } + int i1 = Algorithms.extractFirstIntegerNumber(o1.desc); + int i2 = Algorithms.extractFirstIntegerNumber(o2.desc); + if (i1 != i2) { + return Algorithms.compare(i1, i2); + } + return o1.desc.compareTo(o2.desc); + } + }); + } + + private void addRoutes(boolean useEnglishNames, TransportIndexRepository t, TransportStop s, int dist) { + Collection rts = t.getRouteForStop(s); + if (rts != null) { + for (TransportRoute rs : rts) { + TransportStopController.TransportStopType type = TransportStopController.TransportStopType.findType(rs.getType()); + TransportStopRoute r = new TransportStopRoute(); + r.type = type; + r.desc = rs.getRef() + " " + (useEnglishNames ? rs.getEnName(true) : rs.getName()); + r.route = rs; + r.stop = s; + r.distance = dist; + this.routes.add(r); + } + } + } } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java index ce5f9b8bdb..d8af544fe9 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java @@ -232,7 +232,7 @@ public class TransportStopController extends MenuController { public String getDescription(OsmandApplication ctx, boolean useDistance) { if (useDistance && distance > 0) { String nm = OsmAndFormatter.getFormattedDistance(distance, ctx); - if (!refStop.getName().equals(stop.getName())) { + if (refStop != null && !refStop.getName().equals(stop.getName())) { nm = refStop.getName() + ", " + nm; } return desc + " (" + nm + ")"; diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java index 6137f4b10a..342534a71b 100644 --- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java @@ -23,14 +23,12 @@ import android.widget.ImageView; import net.osmand.CallbackWithObject; import net.osmand.NativeLibrary.RenderedObject; import net.osmand.RenderingContext; -import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; -import net.osmand.data.TransportStop; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiFilter; import net.osmand.osm.PoiType; @@ -48,8 +46,6 @@ import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -387,7 +383,61 @@ public class ContextMenuLayer extends OsmandMapLayer { } private boolean showContextMenu(PointF point, RotatedTileBox tileBox, boolean showUnknownLocation) { + LatLon customLatLon = null; Map selectedObjects = selectObjectsForContextMenu(tileBox, point, false); + NativeOsmandLibrary nativeLib = NativeOsmandLibrary.getLoadedLibrary(); + if (nativeLib != null) { + MapRenderRepositories maps = activity.getMyApplication().getResourceManager().getRenderer(); + RenderingContext rc = maps.getVisibleRenderingContext(); + RenderedObject[] renderedObjects = null; + if (rc.zoom == tileBox.getZoom()) { + double lat = MapUtils.get31LatitudeY((int) (rc.topY * rc.tileDivisor)); + double lon = MapUtils.get31LongitudeX((int) (rc.leftX * rc.tileDivisor)); + float x = tileBox.getPixXFromLatLon(lat, lon); + float y = tileBox.getPixYFromLatLon(lat, lon); + renderedObjects = nativeLib.searchRenderedObjectsFromContext(rc, (int) (point.x - x), (int) (point.y - y)); + } + if (renderedObjects != null) { + IContextMenuProvider poiMenuProvider = activity.getMapLayers().getPoiMapLayer(); + for (RenderedObject renderedObject : renderedObjects) { + if (renderedObject.getX() != null && renderedObject.getX().size() == 1 + && renderedObject.getY() != null && renderedObject.getY().size() == 1) { + customLatLon = new LatLon(MapUtils.get31LatitudeY(renderedObject.getY().get(0)), + MapUtils.get31LongitudeX(renderedObject.getX().get(0))); + } else { + customLatLon = tileBox.getLatLonFromPixel(point.x, point.y); + } + if (renderedObject.getId() != null) { + List names = new ArrayList<>(); + if (!Algorithms.isEmpty(renderedObject.getName())) { + names.add(renderedObject.getName()); + } + for (Entry entry : renderedObject.getTags().entrySet()) { + if (entry.getKey().startsWith("name")) { + names.add(entry.getValue()); + } + } + Amenity amenity = findAmenity(renderedObject.getId() >> 7, names, + customLatLon.getLatitude(), customLatLon.getLongitude()); + if (amenity != null) { + selectedObjects.put(amenity, poiMenuProvider); + continue; + } + if (renderedObject.getX() != null && renderedObject.getX().size() > 1 + && renderedObject.getY() != null && renderedObject.getY().size() > 1) { + + List nodes = new ArrayList<>(renderedObject.getX().size()); + for (int i = 0; i < renderedObject.getX().size(); i++) { + nodes.add(new Node(MapUtils.get31LatitudeY(renderedObject.getY().get(i)), + MapUtils.get31LongitudeX(renderedObject.getX().get(i)), 0)); + } + customLatLon = OsmMapUtils.getMathWeightCenterForNodes(nodes); + } + selectedObjects.put(renderedObject, null); + } + } + } + } if (selectedObjects.size() == 1) { Object selectedObj = selectedObjects.keySet().iterator().next(); LatLon latLon = null; @@ -397,6 +447,9 @@ public class ContextMenuLayer extends OsmandMapLayer { latLon = provider.getObjectLocation(selectedObj); pointDescription = provider.getObjectName(selectedObj); } + if (latLon == null) { + latLon = customLatLon; + } if (latLon == null) { latLon = getLatLon(point, tileBox); } @@ -418,27 +471,6 @@ public class ContextMenuLayer extends OsmandMapLayer { return false; } - private boolean showContextMenu(LatLon latLon, Map selectedObjects) { - if (selectedObjects.size() == 1) { - Object selectedObj = selectedObjects.keySet().iterator().next(); - PointDescription pointDescription = null; - final IContextMenuProvider provider = selectedObjects.get(selectedObj); - if (provider != null) { - latLon = provider.getObjectLocation(selectedObj); - pointDescription = provider.getObjectName(selectedObj); - } - showContextMenu(latLon, pointDescription, selectedObj, provider); - return true; - - } else if (selectedObjects.size() > 1) { - selectedObjectContextMenuProvider = null; - showContextMenuForSelectedObjects(latLon, selectedObjects); - return true; - } - - return false; - } - @NonNull private LatLon getLatLon(PointF point, RotatedTileBox tileBox) { LatLon latLon; @@ -559,77 +591,6 @@ public class ContextMenuLayer extends OsmandMapLayer { boolean res = showContextMenu(point, tileBox, false); if (res) { return true; - } else { - NativeOsmandLibrary nativeLib = NativeOsmandLibrary.getLoadedLibrary(); - if (nativeLib != null) { - MapRenderRepositories maps = activity.getMyApplication().getResourceManager().getRenderer(); - RenderingContext rc = maps.getVisibleRenderingContext(); - RenderedObject[] renderedObjects = null; - if(rc.zoom == tileBox.getZoom()) { - double lat = MapUtils.get31LatitudeY((int)(rc.topY*rc.tileDivisor)); - double lon = MapUtils.get31LongitudeX((int)(rc.leftX*rc.tileDivisor)); - float x = tileBox.getPixXFromLatLon(lat, lon); - float y = tileBox.getPixYFromLatLon(lat, lon); - renderedObjects = nativeLib.searchRenderedObjectsFromContext(rc, (int)( point.x - x), (int)( point.y- y)); - } - if (renderedObjects != null) { - Map selectedObjects = new HashMap<>(); - IContextMenuProvider poiMenuProvider = activity.getMapLayers().getPoiMapLayer(); - IContextMenuProvider transportStopMenuProvider = activity.getMapLayers().getTransportStopsLayer(); - LatLon latLon = null; - for (RenderedObject renderedObject : renderedObjects) { - if (renderedObject.getX() != null && renderedObject.getX().size() == 1 - && renderedObject.getY() != null && renderedObject.getY().size() == 1) { - latLon = new LatLon(MapUtils.get31LatitudeY(renderedObject.getY().get(0)), - MapUtils.get31LongitudeX(renderedObject.getX().get(0))); - } else { - latLon = tileBox.getLatLonFromPixel(point.x, point.y); - } - if (renderedObject.getId() != null) { - TransportStop transportStop = findTransportStop(renderedObject.getId() >> 1, latLon.getLatitude(), latLon.getLongitude()); - if (transportStop != null) { - selectedObjects.put(transportStop, transportStopMenuProvider); - continue; - } - List names = new ArrayList<>(); - if (!Algorithms.isEmpty(renderedObject.getName())) { - names.add(renderedObject.getName()); - } - for (Entry entry : renderedObject.getTags().entrySet()) { - if (entry.getKey().startsWith("name")) { - names.add(entry.getValue()); - } - } - Amenity amenity = findAmenity(renderedObject.getId() >> 7, names, - latLon.getLatitude(), latLon.getLongitude()); - if (amenity != null) { - selectedObjects.put(amenity, poiMenuProvider); - continue; - } - TransportStop nearestTransportStop = findNearestTransportStop(latLon.getLatitude(), latLon.getLongitude()); - if (nearestTransportStop != null) { - selectedObjects.put(nearestTransportStop, transportStopMenuProvider); - //continue; - } - if (renderedObject.getX() != null && renderedObject.getX().size() > 1 - && renderedObject.getY() != null && renderedObject.getY().size() > 1) { - - List nodes = new ArrayList<>(renderedObject.getX().size()); - for (int i = 0; i < renderedObject.getX().size(); i++) { - nodes.add(new Node(MapUtils.get31LatitudeY(renderedObject.getY().get(i)), - MapUtils.get31LongitudeX(renderedObject.getX().get(i)), 0)); - } - latLon = OsmMapUtils.getMathWeightCenterForNodes(nodes); - } - selectedObjects.put(renderedObject, null); - } - } - if (selectedObjects.size() > 0 && latLon != null) { - showContextMenu(latLon, selectedObjects); - return true; - } - } - } } } @@ -675,70 +636,9 @@ public class ContextMenuLayer extends OsmandMapLayer { } } - if (res != null && getPublicTransportTypes().contains(res.getSubType())) { - return findNearestTransportStop(lat, lon) == null ? res : null; - } - return res; } - private TransportStop findTransportStop(long id, double lat, double lon) { - - QuadRect rect = MapUtils.calculateLatLonBbox(lat, lon, 50); - List res = activity.getMyApplication().getResourceManager() - .searchTransportSync(rect.top, rect.left, rect.bottom, rect.right, - new ResultMatcher() { - - @Override - public boolean publish(TransportStop object) { - return true; - } - - @Override - public boolean isCancelled() { - return false; - } - }); - - for (TransportStop stop : res) { - Long stopId = stop.getId(); - if (stopId != null && stopId == id) { - return stop; - } - } - return null; - } - - private TransportStop findNearestTransportStop(final double lat, final double lon) { - - QuadRect rect = MapUtils.calculateLatLonBbox(lat, lon, 50); - List res = activity.getMyApplication().getResourceManager() - .searchTransportSync(rect.top, rect.left, rect.bottom, rect.right, - new ResultMatcher() { - - @Override - public boolean publish(TransportStop object) { - return true; - } - - @Override - public boolean isCancelled() { - return false; - } - }); - - if (res.size() > 0) { - Collections.sort(res, new Comparator() { - @Override - public int compare(TransportStop stop1, TransportStop stop2) { - return Double.compare(MapUtils.getDistance(stop1.getLocation(), lat, lon), MapUtils.getDistance(stop2.getLocation(), lat, lon)); - } - }); - return res.get(0); - } - return null; - } - private void hideVisibleMenues() { if (multiSelectionMenu.isVisible()) { multiSelectionMenu.hide();