diff --git a/OsmAnd-java/src/main/java/net/osmand/data/TransportStop.java b/OsmAnd-java/src/main/java/net/osmand/data/TransportStop.java index 1de6286527..0fdacabdc7 100644 --- a/OsmAnd-java/src/main/java/net/osmand/data/TransportStop.java +++ b/OsmAnd-java/src/main/java/net/osmand/data/TransportStop.java @@ -11,7 +11,7 @@ public class TransportStop extends MapObject { private static final int DELETED_STOP = -1; private int[] referencesToRoutes = null; - private Amenity amenity; + private TransportStopAggregated transportStopAggregated; public int distance; public int x31; public int y31; @@ -37,11 +37,53 @@ public class TransportStop extends MapObject { } public Amenity getAmenity() { - return amenity; + if (transportStopAggregated != null) { + return transportStopAggregated.getAmenity(); + } + return null; } public void setAmenity(Amenity amenity) { - this.amenity = amenity; + if (transportStopAggregated == null) { + transportStopAggregated = new TransportStopAggregated(); + } + transportStopAggregated.setAmenity(amenity); + } + + public List getLocalTransportStops() { + if (transportStopAggregated != null) { + return transportStopAggregated.getLocalTransportStops(); + } + return Collections.emptyList(); + } + + public void addLocalTransportStop(TransportStop stop) { + if (transportStopAggregated == null) { + transportStopAggregated = new TransportStopAggregated(); + } + transportStopAggregated.addLocalTransportStop(stop); + } + + public List getNearbyTransportStops() { + if (transportStopAggregated != null) { + return transportStopAggregated.getNearbyTransportStops(); + } + return Collections.emptyList(); + } + + public void addNearbyTransportStop(TransportStop stop) { + if (transportStopAggregated == null) { + transportStopAggregated = new TransportStopAggregated(); + } + transportStopAggregated.addNearbyTransportStop(stop); + } + + public TransportStopAggregated getTransportStopAggregated() { + return transportStopAggregated; + } + + public void setTransportStopAggregated(TransportStopAggregated stopAggregated) { + transportStopAggregated = stopAggregated; } @Override diff --git a/OsmAnd-java/src/main/java/net/osmand/data/TransportStopAggregated.java b/OsmAnd-java/src/main/java/net/osmand/data/TransportStopAggregated.java new file mode 100644 index 0000000000..4388014eed --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/data/TransportStopAggregated.java @@ -0,0 +1,65 @@ +package net.osmand.data; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class TransportStopAggregated { + + private Amenity amenity; + private List localTransportStops; + private List nearbyTransportStops; + + public TransportStopAggregated() { + } + + public Amenity getAmenity() { + return amenity; + } + + public void setAmenity(Amenity amenity) { + this.amenity = amenity; + } + + public List getLocalTransportStops() { + if (localTransportStops == null) { + return Collections.emptyList(); + } + return this.localTransportStops; + } + + public void addLocalTransportStop(TransportStop stop) { + if (localTransportStops == null) { + localTransportStops = new ArrayList<>(); + } + localTransportStops.add(stop); + } + + public void addLocalTransportStops(List stops) { + if (localTransportStops == null) { + localTransportStops = new ArrayList<>(); + } + localTransportStops.addAll(stops); + } + + public List getNearbyTransportStops() { + if (nearbyTransportStops == null) { + return Collections.emptyList(); + } + return this.nearbyTransportStops; + } + + public void addNearbyTransportStop(TransportStop stop) { + if (nearbyTransportStops == null) { + nearbyTransportStops = new ArrayList<>(); + } + nearbyTransportStops.add(stop); + } + + public void addNearbyTransportStops(List stops) { + if (nearbyTransportStops == null) { + nearbyTransportStops = new ArrayList<>(); + } + nearbyTransportStops.addAll(stops); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 8c385d9078..4e9ade0b9e 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -4,7 +4,6 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; -import android.content.res.Resources; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; @@ -39,12 +38,12 @@ import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; import net.osmand.osm.PoiCategory; -import net.osmand.plus.UiUtilities; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings.OsmandPreference; import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard; @@ -53,8 +52,8 @@ import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; -import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.render.RenderingIcons; +import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.views.TransportStopsLayer; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; @@ -67,8 +66,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import static android.util.TypedValue.COMPLEX_UNIT_DIP; -import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.*; +import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; public class MenuBuilder { @@ -91,7 +89,6 @@ public class MenuBuilder { private boolean showOnlinePhotos = true; protected List nearestWiki = new ArrayList<>(); private List menuPlugins = new ArrayList<>(); - private List routes = new ArrayList<>(); @Nullable private CardsRowBuilder onlinePhotoCardsRow; private List onlinePhotoCards; @@ -235,10 +232,6 @@ public class MenuBuilder { this.collapseExpandListener = collapseExpandListener; } - public void setRoutes(List routes) { - this.routes = routes; - } - public String getPreferredMapLang() { return preferredMapLang; } @@ -324,7 +317,7 @@ public class MenuBuilder { } private boolean showTransportRoutes() { - return routes.size() > 0; + return showLocalTransportRoutes() || showNearbyTransportRoutes(); } private boolean showLocalTransportRoutes() { @@ -460,17 +453,15 @@ public class MenuBuilder { } protected void buildTopInternal(View view) { - if (showTransportRoutes()) { - if (showLocalTransportRoutes()) { - buildRow(view, 0, null, app.getString(R.string.transport_Routes), 0, true, getCollapsableTransportStopRoutesView(view.getContext(), false, false), - false, 0, false, null, true); - } - if (showNearbyTransportRoutes()) { - CollapsableView collapsableView = getCollapsableTransportStopRoutesView(view.getContext(), false, true); - String routesWithingDistance = app.getString(R.string.transport_nearby_routes_within) + " " + OsmAndFormatter.getFormattedDistance(TransportStopController.SHOW_STOPS_RADIUS_METERS, app); - buildRow(view, 0, null, routesWithingDistance, 0, true, collapsableView, - false, 0, false, null, true); - } + if (showLocalTransportRoutes()) { + buildRow(view, 0, null, app.getString(R.string.transport_Routes), 0, true, getCollapsableTransportStopRoutesView(view.getContext(), false, false), + false, 0, false, null, true); + } + if (showNearbyTransportRoutes()) { + CollapsableView collapsableView = getCollapsableTransportStopRoutesView(view.getContext(), false, true); + String routesWithingDistance = app.getString(R.string.transport_nearby_routes_within) + " " + OsmAndFormatter.getFormattedDistance(TransportStopController.SHOW_STOPS_RADIUS_METERS, app); + buildRow(view, 0, null, routesWithingDistance, 0, true, collapsableView, + false, 0, false, null, true); } } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java index 84db89b3ee..4ea4f62481 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/AmenityMenuController.java @@ -7,45 +7,32 @@ import android.text.TextUtils; 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.PoiFilter; import net.osmand.osm.PoiType; 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.plus.wikipedia.WikipediaDialogFragment; import net.osmand.plus.mapcontextmenu.builders.AmenityMenuBuilder; import net.osmand.plus.render.RenderingIcons; -import net.osmand.plus.resources.TransportIndexRepository; import net.osmand.plus.transport.TransportStopRoute; -import net.osmand.plus.transport.TransportStopType; +import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.util.Algorithms; -import net.osmand.util.MapUtils; import net.osmand.util.OpeningHoursParser; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Map; -import gnu.trove.list.array.TLongArrayList; -import gnu.trove.map.hash.TLongObjectHashMap; - public class AmenityMenuController extends MenuController { private Amenity amenity; - private List routes = new ArrayList<>(); - private MapMarker marker; + private TransportStopController transportStopController; + public AmenityMenuController(@NonNull MapActivity mapActivity, @NonNull PointDescription pointDescription, @NonNull final Amenity amenity) { @@ -63,7 +50,11 @@ public class AmenityMenuController extends MenuController { } } if (showTransportStops) { - processTransportStop(); + TransportStop transportStop = TransportStopController.findBestTransportStopForAmenity(mapActivity.getMyApplication(), amenity); + if (transportStop != null) { + transportStopController = new TransportStopController(mapActivity, pointDescription, transportStop); + transportStopController.processRoutes(); + } } } @@ -213,23 +204,16 @@ public class AmenityMenuController extends MenuController { @Override public List getTransportStopRoutes() { - return routes; + if (transportStopController != null) { + return transportStopController.getTransportStopRoutes(); + } + return null; } @Override protected List getSubTransportStopRoutes(boolean nearby) { - List allRoutes = getTransportStopRoutes(); - if (allRoutes != null) { - List res = new ArrayList<>(); - for (TransportStopRoute route : allRoutes) { - boolean isCurrentRouteLocal = route.refStop != null && route.refStop.getName().equals(route.stop.getName()); - if (!nearby && isCurrentRouteLocal) { - res.add(route); - } else if (nearby && route.refStop == null) { - res.add(route); - } - } - return res; + if (transportStopController != null) { + return transportStopController.getSubTransportStopRoutes(nearby); } return null; } @@ -264,77 +248,4 @@ public class AmenityMenuController extends MenuController { } return null; } - - private void processTransportStop() { - routes = new ArrayList<>(); - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - OsmandApplication app = mapActivity.getMyApplication(); - List reps = app - .getResourceManager().searchTransportRepositories(amenity.getLocation().getLatitude(), - amenity.getLocation().getLongitude()); - - boolean useEnglishNames = app.getSettings().usingEnglishNames(); - boolean isSubwayEntrance = amenity.getSubType().equals("subway_entrance"); - - TLongArrayList addedTransportStops = new TLongArrayList(); - for (TransportIndexRepository t : reps) { - ArrayList ls = new ArrayList<>(); - QuadRect ll = MapUtils.calculateLatLonBbox(amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), - isSubwayEntrance ? 400 : 150); - t.searchTransportStops(ll.top, ll.left, ll.bottom, ll.right, -1, ls, null); - for (TransportStop tstop : ls) { - if (!addedTransportStops.contains(tstop.getId())) { - addedTransportStops.add(tstop.getId()); - if (!tstop.isDeleted()) { - addRoutes(useEnglishNames, t, tstop, - (int) MapUtils.getDistance(tstop.getLocation(), amenity.getLocation()), isSubwayEntrance); - } - } - } - } - Collections.sort(routes, new Comparator() { - - @Override - public int compare(TransportStopRoute o1, TransportStopRoute o2) { -// int radEqual = 50; -// int dist1 = o1.distance / radEqual; -// int dist2 = o2.distance / radEqual; -// if (dist1 != dist2) { -// return Algorithms.compare(dist1, dist2); -// } - int i1 = Algorithms.extractFirstIntegerNumber(o1.route.getRef()); - int i2 = Algorithms.extractFirstIntegerNumber(o2.route.getRef()); - if (i1 != i2) { - return Algorithms.compare(i1, i2); - } - return o1.desc.compareTo(o2.desc); - } - }); - - builder.setRoutes(routes); - } - } - - private void addRoutes(boolean useEnglishNames, TransportIndexRepository t, TransportStop s, int dist, boolean isSubwayEntrance) { - Collection rts = t.getRouteForStop(s); - if (rts != null) { - for (TransportRoute rs : rts) { - TransportStopType type = TransportStopType.findType(rs.getType()); - if (isSubwayEntrance && type != TransportStopType.SUBWAY && dist > 150) { - continue; - } - TransportStopRoute r = new TransportStopRoute(); - r.type = type; - r.desc = useEnglishNames ? rs.getEnName(true) : rs.getName(); - r.route = rs; - r.stop = s; - if (amenity.getLocation().equals(s.getLocation()) || (isSubwayEntrance && type == TransportStopType.SUBWAY)) { - r.refStop = s; - } - r.distance = dist; - this.routes.add(r); - } - } - } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java index 407a1bd37a..fb35d4b406 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/FavouritePointMenuController.java @@ -21,14 +21,13 @@ import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragment; import net.osmand.plus.transport.TransportStopRoute; import net.osmand.util.OpeningHoursParser; -import java.util.ArrayList; import java.util.List; public class FavouritePointMenuController extends MenuController { private FavouritePoint fav; private MapMarker mapMarker; - private List routes = new ArrayList<>(); + private TransportStopController transportStopController; public FavouritePointMenuController(@NonNull MapActivity mapActivity, @NonNull PointDescription pointDescription, final @NonNull FavouritePoint fav) { @@ -49,8 +48,7 @@ public class FavouritePointMenuController extends MenuController { if (getObject() instanceof TransportStop) { TransportStop stop = (TransportStop) getObject(); transportStopController = new TransportStopController(mapActivity, pointDescription, stop); - routes = transportStopController.processTransportStop(); - builder.setRoutes(routes); + transportStopController.processRoutes(); } Object originObject = getBuilder().getOriginObject(); @@ -73,7 +71,10 @@ public class FavouritePointMenuController extends MenuController { @Override public List getTransportStopRoutes() { - return routes; + if (transportStopController != null) { + return transportStopController.getTransportStopRoutes(); + } + return null; } @Override diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java index f1f71f6b27..4ebd3d21ad 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java @@ -1,6 +1,7 @@ package net.osmand.plus.mapcontextmenu.controllers; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import net.osmand.data.Amenity; import net.osmand.data.LatLon; @@ -8,6 +9,9 @@ import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; import net.osmand.data.TransportRoute; import net.osmand.data.TransportStop; +import net.osmand.data.TransportStopAggregated; +import net.osmand.data.TransportStopExit; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MenuController; @@ -29,9 +33,11 @@ import gnu.trove.list.array.TLongArrayList; public class TransportStopController extends MenuController { public static final int SHOW_STOPS_RADIUS_METERS = 150; + public static final int SHOW_SUBWAY_STOPS_FROM_ENTRANCES_RADIUS_METERS = 400; private TransportStop transportStop; - private List routes = new ArrayList<>(); + private List routesNearby = new ArrayList<>(); + private List routesOnTheSameExit = new ArrayList<>(); private TransportStopType topType; public TransportStopController(@NonNull MapActivity mapActivity, @@ -50,9 +56,10 @@ public class TransportStopController extends MenuController { } } - private void processRoutes() { - routes = processTransportStop(); - builder.setRoutes(routes); + public void processRoutes() { + routesOnTheSameExit.clear(); + routesNearby.clear(); + processTransportStop(routesOnTheSameExit, routesNearby); } @Override @@ -71,23 +78,14 @@ public class TransportStopController extends MenuController { @Override public List getTransportStopRoutes() { + List routes = new ArrayList<>(routesOnTheSameExit); + routes.addAll(routesNearby); return routes; } @Override protected List getSubTransportStopRoutes(boolean nearby) { - List allRoutes = getTransportStopRoutes(); - if (allRoutes != null) { - List res = new ArrayList<>(); - for (TransportStopRoute route : allRoutes) { - boolean isCurrentRouteNearby = route.stop != null && !route.stop.equals(transportStop); - if ((nearby && isCurrentRouteNearby) || (!nearby && !isCurrentRouteNearby)) { - res.add(route); - } - } - return res; - } - return null; + return nearby ? routesNearby : routesOnTheSameExit; } @Override @@ -112,8 +110,17 @@ public class TransportStopController extends MenuController { return getPointDescription().getTypeName(); } - public List processTransportStop() { - ArrayList routes = new ArrayList<>(); + @Override + public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) { + Amenity amenity = transportStop.getAmenity(); + if (amenity != null) { + AmenityMenuController.addTypeMenuItem(amenity, builder); + } else { + super.addPlainMenuItems(typeStr, pointDescription, latLon); + } + } + + private void processTransportStop(List routesOnTheSameExit, List routesNearby) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { List reps = mapActivity.getMyApplication() @@ -122,53 +129,57 @@ public class TransportStopController extends MenuController { boolean useEnglishNames = mapActivity.getMyApplication().getSettings().usingEnglishNames(); - TLongArrayList addedTransportStops = new TLongArrayList(); for (TransportIndexRepository t : reps) { if (t.acceptTransportStop(transportStop)) { - boolean empty = transportStop.getReferencesToRoutes() == null || transportStop.getReferencesToRoutes().length == 0; - if (!empty) { - addRoutes(routes, useEnglishNames, t, transportStop, transportStop, 0); - } - ArrayList ls = new ArrayList<>(); - QuadRect ll = MapUtils.calculateLatLonBbox(transportStop.getLocation().getLatitude(), transportStop.getLocation().getLongitude(), SHOW_STOPS_RADIUS_METERS); - t.searchTransportStops(ll.top, ll.left, ll.bottom, ll.right, -1, ls, null); - for (TransportStop tstop : ls) { - if (!addedTransportStops.contains(tstop.getId())) { - addedTransportStops.add(tstop.getId()); - if (!tstop.isDeleted() && (tstop.getId().longValue() != transportStop.getId().longValue() || empty)) { - addRoutes(routes, useEnglishNames, t, tstop, transportStop, - (int) MapUtils.getDistance(tstop.getLocation(), transportStop.getLocation())); - } - } - } + ArrayList transportStopsSameExit = new ArrayList(transportStop.getLocalTransportStops()); + ArrayList nearbyTransportStops = new ArrayList(transportStop.getNearbyTransportStops()); + + addTransportStopRoutes(transportStopsSameExit, routesOnTheSameExit, useEnglishNames, t); + addTransportStopRoutes(nearbyTransportStops, routesNearby, useEnglishNames, t); } } - Collections.sort(routes, new Comparator() { + sortTransportStopRoutes(routesOnTheSameExit); + sortTransportStopRoutes(routesNearby); + } + } - @Override - public int compare(TransportStopRoute o1, TransportStopRoute o2) { + private void sortTransportStopRoutes(List routes) { + Collections.sort(routes, new Comparator() { + + @Override + public int compare(TransportStopRoute o1, TransportStopRoute o2) { // int radEqual = 50; // int dist1 = o1.distance / radEqual; // int dist2 = o2.distance / radEqual; // if (dist1 != dist2) { // return Algorithms.compare(dist1, dist2); // } - int i1 = Algorithms.extractFirstIntegerNumber(o1.route.getRef()); - int i2 = Algorithms.extractFirstIntegerNumber(o2.route.getRef()); - if (i1 != i2) { - return Algorithms.compare(i1, i2); - } - return o1.desc.compareTo(o2.desc); + int i1 = Algorithms.extractFirstIntegerNumber(o1.route.getRef()); + int i2 = Algorithms.extractFirstIntegerNumber(o2.route.getRef()); + if (i1 != i2) { + return Algorithms.compare(i1, i2); } - }); + return o1.desc.compareTo(o2.desc); + } + }); + } + + private void addTransportStopRoutes(List stops, List routes, boolean useEnglishNames, TransportIndexRepository t) { + for (TransportStop tstop : stops) { + if (!tstop.isDeleted()) { + addRoutes(routes, useEnglishNames, t, tstop, transportStop, (int) MapUtils.getDistance(tstop.getLocation(), transportStop.getLocation())); + } } - return routes; } private void addRoutes(List routes, boolean useEnglishNames, TransportIndexRepository t, TransportStop s, TransportStop refStop, int dist) { Collection rts = t.getRouteForStop(s); if (rts != null) { for (TransportRoute rs : rts) { + boolean routeAlreadyAdded = checkSameRoute(routes, rs); + if (routeAlreadyAdded) { + continue; + } TransportStopType type = TransportStopType.findType(rs.getType()); if (topType == null && type != null && type.isTopType()) { topType = type; @@ -185,13 +196,112 @@ public class TransportStopController extends MenuController { } } - @Override - public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) { - Amenity amenity = transportStop.getAmenity(); - if (amenity != null) { - AmenityMenuController.addTypeMenuItem(amenity, builder); - } else { - super.addPlainMenuItems(typeStr, pointDescription, latLon); + public static void sortTransportStops(@NonNull LatLon latLon, List transportStops) { + for (TransportStop transportStop : transportStops) { + transportStop.distance = (int) MapUtils.getDistance(latLon, transportStop.getLocation()); } + Collections.sort(transportStops, new Comparator() { + + @Override + public int compare(TransportStop s1, TransportStop s2) { + return Algorithms.compare(s1.distance, s2.distance); + } + }); } -} + + @NonNull + public static List findTransportStopsAt(OsmandApplication app, double latitude, double longitude, int radiusMeters) { + ArrayList transportStops = new ArrayList<>(); + List reps = app.getResourceManager().searchTransportRepositories(latitude, longitude); + + TLongArrayList addedTransportStops = new TLongArrayList(); + for (TransportIndexRepository t : reps) { + ArrayList stops = new ArrayList<>(); + QuadRect ll = MapUtils.calculateLatLonBbox(latitude, longitude, radiusMeters); + t.searchTransportStops(ll.top, ll.left, ll.bottom, ll.right, -1, stops, null); + for (TransportStop transportStop : stops) { + if (!addedTransportStops.contains(transportStop.getId())) { + addedTransportStops.add(transportStop.getId()); + if (!transportStop.isDeleted()) { + transportStops.add(transportStop); + } + } + } + } + return transportStops; + } + + @Nullable + public static TransportStop findBestTransportStopForAmenity(OsmandApplication app, Amenity amenity) { + TransportStopAggregated stopAggregated; + boolean isSubwayEntrance = amenity.getSubType().equals("subway_entrance"); + + LatLon loc = amenity.getLocation(); + int radiusMeters = isSubwayEntrance ? SHOW_SUBWAY_STOPS_FROM_ENTRANCES_RADIUS_METERS : SHOW_STOPS_RADIUS_METERS; + List transportStops = findTransportStopsAt(app, loc.getLatitude(), loc.getLongitude(), radiusMeters); + sortTransportStops(loc, transportStops); + + if (isSubwayEntrance) { + stopAggregated = processTransportStopsForAmenity(transportStops, amenity); + } else { + stopAggregated = new TransportStopAggregated(); + stopAggregated.setAmenity(amenity); + TransportStop nearestStop = null; + for (TransportStop stop : transportStops) { + stop.setTransportStopAggregated(stopAggregated); + if ((stop.getName().startsWith(amenity.getName()) + && (nearestStop == null + || nearestStop.getLocation().equals(stop.getLocation()))) + || stop.getLocation().equals(loc)) { + stopAggregated.addLocalTransportStop(stop); + if (nearestStop == null) { + nearestStop = stop; + } + } else { + stopAggregated.addNearbyTransportStop(stop); + } + } + } + + List localStops = stopAggregated.getLocalTransportStops(); + List nearbyStops = stopAggregated.getNearbyTransportStops(); + if (!localStops.isEmpty()) { + return localStops.get(0); + } else if (!nearbyStops.isEmpty()) { + return nearbyStops.get(0); + } + return null; + } + + public static TransportStopAggregated processTransportStopsForAmenity(List transportStops, Amenity amenity) { + TransportStopAggregated stopAggregated = new TransportStopAggregated(); + stopAggregated.setAmenity(amenity); + + for (TransportStop stop : transportStops) { + stop.setTransportStopAggregated(stopAggregated); + List stopExits = stop.getExits(); + boolean stopOnSameExitAdded = false; + for (TransportStopExit exit : stopExits) { + if (exit.getLocation().equals(amenity.getLocation())) { + stopOnSameExitAdded = true; + stopAggregated.addLocalTransportStop(stop); + break; + } + } + if (!stopOnSameExitAdded && MapUtils.getDistance(stop.getLocation(), amenity.getLocation()) <= SHOW_STOPS_RADIUS_METERS) { + stopAggregated.addNearbyTransportStop(stop); + } + } + + return stopAggregated; + } + + public static boolean checkSameRoute(List stopRoutes, TransportRoute route) { + for (TransportStopRoute stopRoute : stopRoutes) { + if (stopRoute.route.compareRoute(route)) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java index 9b707dc2aa..f90e85f07c 100644 --- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java @@ -43,7 +43,6 @@ import net.osmand.core.jni.Utilities; 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; @@ -56,10 +55,10 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivityActions; import net.osmand.plus.mapcontextmenu.MapContextMenu; +import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; import net.osmand.plus.mapcontextmenu.other.MapMultiSelectionMenu; import net.osmand.plus.render.MapRenderRepositories; import net.osmand.plus.render.NativeOsmandLibrary; -import net.osmand.plus.resources.TransportIndexRepository; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; import net.osmand.plus.views.corenative.NativeCoreContext; @@ -67,8 +66,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; @@ -76,10 +73,8 @@ import java.util.Map.Entry; import java.util.Set; import gnu.trove.list.array.TIntArrayList; -import gnu.trove.list.array.TLongArrayList; import static net.osmand.plus.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_CHANGE_MARKER_POSITION; -import static net.osmand.plus.mapcontextmenu.controllers.TransportStopController.SHOW_STOPS_RADIUS_METERS; public class ContextMenuLayer extends OsmandMapLayer { //private static final Log LOG = PlatformUtil.getLog(ContextMenuLayer.class); @@ -864,31 +859,12 @@ public class ContextMenuLayer extends OsmandMapLayer { } } if (transportStopAmenities.size() > 0) { - List transportStops = findTransportStopsAt(latLon.getLatitude(), latLon.getLongitude()); - List transportStopsReplacement = new ArrayList<>(); for (Amenity amenity : transportStopAmenities) { - List amenityTransportStops = new ArrayList<>(); - for (TransportStop transportStop : transportStops) { - if (transportStop.getName().startsWith(amenity.getName())) { - amenityTransportStops.add(transportStop); - transportStop.setAmenity(amenity); - } - } - if (amenityTransportStops.size() > 0) { - selectedObjects.remove(amenity); - if (amenityTransportStops.size() > 1) { - sortTransportStops(amenity.getLocation(), amenityTransportStops); - } - TransportStop amenityTransportStop = amenityTransportStops.get(0); - if (!transportStopsReplacement.contains(amenityTransportStop)) { - transportStopsReplacement.add(amenityTransportStop); - } - } - } - if (transportStopsReplacement.size() > 0) { - TransportStopsLayer transportStopsLayer = activity.getMapLayers().getTransportStopsLayer(); - if (transportStopsLayer != null) { - for (TransportStop transportStop : transportStopsReplacement) { + TransportStop transportStop = TransportStopController.findBestTransportStopForAmenity(activity.getMyApplication(), amenity); + if (transportStop != null) { + TransportStopsLayer transportStopsLayer = activity.getMapLayers().getTransportStopsLayer(); + if (transportStopsLayer != null) { + selectedObjects.remove(amenity); selectedObjects.put(transportStop, transportStopsLayer); } } @@ -897,42 +873,6 @@ public class ContextMenuLayer extends OsmandMapLayer { } } - private void sortTransportStops(@NonNull LatLon latLon, List transportStops) { - for (TransportStop transportStop : transportStops) { - transportStop.distance = (int) MapUtils.getDistance(latLon, transportStop.getLocation()); - } - Collections.sort(transportStops, new Comparator() { - - @Override - public int compare(TransportStop s1, TransportStop s2) { - return Algorithms.compare(s1.distance, s2.distance); - } - }); - } - - @NonNull - private List findTransportStopsAt(double latitude, double longitude) { - ArrayList transportStops = new ArrayList<>(); - List reps = - activity.getMyApplication().getResourceManager().searchTransportRepositories(latitude, longitude); - - TLongArrayList addedTransportStops = new TLongArrayList(); - for (TransportIndexRepository t : reps) { - ArrayList ls = new ArrayList<>(); - QuadRect ll = MapUtils.calculateLatLonBbox(latitude, longitude, SHOW_STOPS_RADIUS_METERS); - t.searchTransportStops(ll.top, ll.left, ll.bottom, ll.right, -1, ls, null); - for (TransportStop tstop : ls) { - if (!addedTransportStops.contains(tstop.getId())) { - addedTransportStops.add(tstop.getId()); - if (!tstop.isDeleted()) { - transportStops.add(tstop); - } - } - } - } - return transportStops; - } - @NonNull private Map selectObjectsForContextMenu(RotatedTileBox tileBox, PointF point, boolean acquireObjLatLon,