From fb2245e73c155b7c8f5d79488adb0b541f0821eb Mon Sep 17 00:00:00 2001 From: crimean Date: Thu, 14 Mar 2019 22:13:04 +0300 Subject: [PATCH] Make PT bages clickable --- .../osmand/router/TransportRoutePlanner.java | 21 +++ .../bottom_sheet_item_with_radio_btn_left.xml | 2 +- .../transport_stop_route_item_with_icon.xml | 44 +++-- .../ChooseRouteFragment.java | 5 +- .../MapRouteInfoMenu.java | 9 +- .../ShowRouteInfoDialogFragment.java | 156 ++++++++++++----- .../cards/PublicTransportCard.java | 164 +++++++++++++----- .../plus/routing/TransportRoutingHelper.java | 5 +- 8 files changed, 298 insertions(+), 108 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/TransportRoutePlanner.java b/OsmAnd-java/src/main/java/net/osmand/router/TransportRoutePlanner.java index cd09765af1..a96588d53d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/TransportRoutePlanner.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/TransportRoutePlanner.java @@ -1,8 +1,10 @@ package net.osmand.router; +import net.osmand.Location; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.data.LatLon; +import net.osmand.data.QuadRect; import net.osmand.data.TransportRoute; import net.osmand.data.TransportSchedule; import net.osmand.data.TransportStop; @@ -319,6 +321,25 @@ public class TransportRoutePlanner { return route.getForwardStops().subList(start, end + 1); } + public QuadRect getSegmentRect() { + double left = 0, right = 0; + double top = 0, bottom = 0; + for (Node n : getNodes()) { + if (left == 0 && right == 0) { + left = n.getLongitude(); + right = n.getLongitude(); + top = n.getLatitude(); + bottom = n.getLatitude(); + } else { + left = Math.min(left, n.getLongitude()); + right = Math.max(right, n.getLongitude()); + top = Math.max(top, n.getLatitude()); + bottom = Math.min(bottom, n.getLatitude()); + } + } + return left == 0 && right == 0 ? null : new QuadRect(left, top, right, bottom); + } + public List getNodes() { List nodes = new ArrayList<>(); List ways = getGeometry(); diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_radio_btn_left.xml b/OsmAnd/res/layout/bottom_sheet_item_with_radio_btn_left.xml index 08826f3f3f..f3a6a91618 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_with_radio_btn_left.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_with_radio_btn_left.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="@dimen/bottom_sheet_list_item_height" - android:background="?android:attr/selectableItemBackground" + android:background="?attr/selectableItemBackground" android:gravity="center_vertical" android:minHeight="@dimen/bottom_sheet_list_item_height" android:paddingLeft="@dimen/content_padding" diff --git a/OsmAnd/res/layout/transport_stop_route_item_with_icon.xml b/OsmAnd/res/layout/transport_stop_route_item_with_icon.xml index 1588b41775..f3756ee79f 100644 --- a/OsmAnd/res/layout/transport_stop_route_item_with_icon.xml +++ b/OsmAnd/res/layout/transport_stop_route_item_with_icon.xml @@ -7,24 +7,32 @@ android:background="@drawable/transport_stop_route_bg" android:orientation="horizontal"> - - - + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackgroundBorderless"> + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java index ec59d1da56..e0e9f246ab 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java @@ -25,6 +25,7 @@ import net.osmand.plus.LockableViewPager; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.helpers.AndroidUiHelper; @@ -63,6 +64,7 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements CardListe portrait = AndroidUiHelper.isOrientationPortrait(mapActivity); map = getMapActivity().getMapView(); OsmandApplication app = mapActivity.getMyApplication(); + TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper(); List routes = app.getTransportRoutingHelper().getRoutes(); if (routes != null && !routes.isEmpty()) { view = inflater.inflate(R.layout.fragment_show_all_routes, null); @@ -71,7 +73,8 @@ public class ChooseRouteFragment extends BaseOsmAndFragment implements CardListe AndroidUtils.addStatusBarPadding21v(mapActivity, view); for (int i = 0; i < routes.size(); i++) { - PublicTransportCard card = new PublicTransportCard(mapActivity, routes.get(i), i); + PublicTransportCard card = new PublicTransportCard(mapActivity, targetPointsHelper.getPointToStart(), + targetPointsHelper.getPointToNavigate(), routes.get(i), i); card.setListener(this); card.setShowTopShadow(false); card.setShowBottomShadow(false); diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java index d83f2f17c4..6029aecad3 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java @@ -36,6 +36,7 @@ import net.osmand.ValueHolder; import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.plus.ApplicationMode; import net.osmand.plus.GeocodingLookupService; @@ -72,15 +73,18 @@ import net.osmand.plus.routepreparationmenu.cards.HomeWorkCard; import net.osmand.plus.routepreparationmenu.cards.MapMarkersCard; import net.osmand.plus.routepreparationmenu.cards.PreviousRouteCard; import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard; +import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard.PublicTransportCardListener; import net.osmand.plus.routepreparationmenu.cards.SimpleRouteCard; import net.osmand.plus.routepreparationmenu.cards.TracksCard; import net.osmand.plus.routepreparationmenu.cards.WarningCard; import net.osmand.plus.routing.IRouteInformationListener; +import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.search.QuickSearchHelper; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; import net.osmand.router.TransportRoutePlanner.TransportRouteResult; +import net.osmand.router.TransportRoutePlanner.TransportRouteResultSegment; import net.osmand.search.SearchUICore.SearchResultCollection; import net.osmand.search.core.SearchResult; @@ -465,6 +469,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener mainView = main; OsmandApplication app = mapActivity.getMyApplication(); nightMode = app.getDaynightHelper().isNightModeForMapControls(); + TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper(); updateStartPointView(); updateWaypointsView(); @@ -486,7 +491,8 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener } else if (isTransportRouteCalculated()) { List routes = app.getTransportRoutingHelper().getRoutes(); for (int i = 0; i < routes.size(); i++) { - PublicTransportCard card = new PublicTransportCard(mapActivity, routes.get(i), i); + PublicTransportCard card = new PublicTransportCard(mapActivity, targetPointsHelper.getPointToStart(), + targetPointsHelper.getPointToNavigate(), routes.get(i), i); card.setShowBottomShadow(i == routes.size() - 1); card.setShowTopShadow(i != 0); card.setListener(this); @@ -502,7 +508,6 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener menuCards.add(homeWorkCard); // Previous route card - TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper(); TargetPoint startBackup = targetPointsHelper.getPointToStartBackup(); if (startBackup == null) { startBackup = targetPointsHelper.getMyLocationToStart(); diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ShowRouteInfoDialogFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ShowRouteInfoDialogFragment.java index e023eb2ebc..9b1f6655a9 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ShowRouteInfoDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ShowRouteInfoDialogFragment.java @@ -92,6 +92,7 @@ import net.osmand.plus.mapcontextmenu.MenuBuilder.CollapsableView; import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard; +import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard.PublicTransportCardListener; import net.osmand.plus.routepreparationmenu.cards.RouteInfoCard; import net.osmand.plus.routepreparationmenu.cards.RouteStatisticCard; import net.osmand.plus.routing.RouteCalculationResult; @@ -128,7 +129,7 @@ import static net.osmand.plus.routepreparationmenu.MapRouteInfoMenu.MenuState.FU import static net.osmand.plus.routepreparationmenu.MapRouteInfoMenu.MenuState.HALF_SCREEN; import static net.osmand.plus.routepreparationmenu.MapRouteInfoMenu.MenuState.HEADER_ONLY; -public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { +public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment implements PublicTransportCardListener { public static final String TAG = "ShowRouteInfoDialogFragment"; @@ -443,7 +444,10 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { List routes = routingHelper.getTransportRoutingHelper().getRoutes(); if (routes != null && routes.size() > transportRouteId) { TransportRouteResult routeResult = routingHelper.getTransportRoutingHelper().getRoutes().get(transportRouteId); - PublicTransportCard card = new PublicTransportCard(mapActivity, routeResult, transportRouteId); + TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper(); + PublicTransportCard card = new PublicTransportCard(mapActivity, targetPointsHelper.getPointToStart(), + targetPointsHelper.getPointToNavigate(), routeResult, transportRouteId); + card.setTransportCardListener(this); menuCards.add(card); cardsContainer.addView(card.build(mapActivity)); buildRowDivider(cardsContainer, false); @@ -595,7 +599,7 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { !nightMode ? R.color.ctx_menu_collapse_icon_color_light : R.color.ctx_menu_collapse_icon_color_dark); } - private void buildSegmentItem(View view, TransportRouteResultSegment segment, long startTime) { + private void buildSegmentItem(View view, final TransportRouteResultSegment segment, long startTime) { TransportRoute transportRoute = segment.route; List stops = segment.getTravelStops(); final TransportStop startStop = stops.get(0); @@ -629,13 +633,20 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { title.setSpan(new CustomTypefaceSpan(typeface), 0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); title.setSpan(new ForegroundColorSpan(getActiveColor()), 0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - buildStartStopRow(stopsContainer, icon, timeText, transportStopRoute, title, secondaryText, new OnClickListener() { + buildStartStopRow(stopsContainer, icon, timeText, title, secondaryText, new OnClickListener() { @Override public void onClick(View v) { showLocationOnMap(startStop.getLocation()); } }); + buildTransportStopRouteRow(stopsContainer, transportStopRoute, new OnClickListener() { + @Override + public void onClick(View v) { + showRouteSegmentOnMap(segment); + } + }); + CollapsableView collapsableView = null; if (stops.size() > 2) { collapsableView = getCollapsableTransportStopRoutesView(app, transportStopRoute, stops.subList(1, stops.size() - 1)); @@ -873,14 +884,26 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { } } - public void showWalkingRouteOnMap(TransportRouteResultSegment startSegment, TransportRouteResultSegment endSegment) { + public void showRouteOnMap(@NonNull RouteCalculationResult result) { + QuadRect rect = result.getLocationsRect(); + if (rect != null) { + openMenuHeaderOnly(); + fitRectOnMap(rect); + } + } + + public void showWalkingRouteOnMap(@Nullable TransportRouteResultSegment startSegment, @Nullable TransportRouteResultSegment endSegment) { RouteCalculationResult walkingRouteSegment = app.getTransportRoutingHelper().getWalkingRouteSegment(startSegment, endSegment); if (walkingRouteSegment != null) { - QuadRect rect = walkingRouteSegment.getLocationsRect(); - if (rect != null) { - openMenuHeaderOnly(); - fitRectOnMap(rect, null, true); - } + showRouteOnMap(walkingRouteSegment); + } + } + + public void showRouteSegmentOnMap(@NonNull TransportRouteResultSegment segment) { + QuadRect rect = segment.getSegmentRect(); + if (rect != null) { + openMenuHeaderOnly(); + fitRectOnMap(rect); } } @@ -889,7 +912,7 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { QuadRect rect = app.getTransportRoutingHelper().getTransportRouteRect(result); if (rect != null) { openMenuHeaderOnly(); - fitRectOnMap(rect, null, true); + fitRectOnMap(rect); } } } @@ -1039,8 +1062,8 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { ((LinearLayout) view).addView(baseItemView); } - public void buildStartStopRow(final View view, Drawable icon, String timeText, TransportStopRoute transportStopRoute, - final Spannable title, Spannable secondaryText, OnClickListener onClickListener) { + public void buildStartStopRow(final View view, Drawable icon, String timeText, final Spannable title, + Spannable secondaryText, OnClickListener onClickListener) { MapActivity mapActivity = getMapActivity(); if (mapActivity == null) { return; @@ -1102,23 +1125,58 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { baseItemView.addView(timeView); } - if (transportStopRoute != null) { - TextView routeTypeView = new TextView(view.getContext()); - LinearLayout.LayoutParams routeTypeParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - routeTypeParams.setMargins(0, dpToPx(4), 0, 0); - routeTypeView.setLayoutParams(routeTypeParams); - routeTypeView.setTextSize(16); - AndroidUtils.setTextSecondaryColor(app, routeTypeView, nightMode); - routeTypeView.setText(transportStopRoute.getDescription(app)); - llText.addView(routeTypeView); - - View routeBadge = createRouteBadge(mapActivity, transportStopRoute, nightMode); - LinearLayout.LayoutParams routeBadgeParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - routeBadgeParams.setMargins(0, dpToPx(6), 0, dpToPx(8)); - routeBadge.setLayoutParams(routeBadgeParams); - llText.addView(routeBadge); + if (onClickListener != null) { + ll.setOnClickListener(onClickListener); } + ((LinearLayout) view).addView(baseItemView); + } + + public void buildTransportStopRouteRow(final View view, @NonNull TransportStopRoute transportStopRoute, + OnClickListener onClickListener) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity == null) { + return; + } + final String routeDescription = transportStopRoute.getDescription(app); + FrameLayout baseItemView = new FrameLayout(view.getContext()); + FrameLayout.LayoutParams baseViewLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + baseItemView.setLayoutParams(baseViewLayoutParams); + + LinearLayout baseView = new LinearLayout(view.getContext()); + baseView.setOrientation(LinearLayout.VERTICAL); + baseView.setLayoutParams(baseViewLayoutParams); + baseView.setGravity(Gravity.END); + baseView.setBackgroundResource(AndroidUtils.resolveAttribute(view.getContext(), android.R.attr.selectableItemBackground)); + baseItemView.addView(baseView); + + LinearLayout ll = buildHorizontalContainerView(36, new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + copyToClipboard(routeDescription, view.getContext()); + return true; + } + }); + baseView.addView(ll); + + LinearLayout llText = buildTextContainerView(); + ll.addView(llText); + + TextView routeTypeView = new TextView(view.getContext()); + LinearLayout.LayoutParams routeTypeParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + routeTypeParams.setMargins(0, dpToPx(4), 0, 0); + routeTypeView.setLayoutParams(routeTypeParams); + routeTypeView.setTextSize(16); + AndroidUtils.setTextSecondaryColor(app, routeTypeView, nightMode); + routeTypeView.setText(routeDescription); + llText.addView(routeTypeView); + + View routeBadge = createRouteBadge(mapActivity, transportStopRoute, nightMode); + LinearLayout.LayoutParams routeBadgeParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + routeBadgeParams.setMargins(0, dpToPx(6), 0, dpToPx(8)); + routeBadge.setLayoutParams(routeBadgeParams); + llText.addView(routeBadge); + if (onClickListener != null) { ll.setOnClickListener(onClickListener); } @@ -1263,7 +1321,17 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { } } - private void fitRectOnMap(QuadRect rect, LatLon location, boolean forceFit) { + private void showOnMap(@NonNull LatLon start, @NonNull LatLon end) { + double left = Math.min(start.getLongitude(), end.getLongitude()); + double right = Math.max(start.getLongitude(), end.getLongitude()); + double top = Math.max(start.getLatitude(), end.getLatitude()); + double bottom = Math.min(start.getLatitude(), end.getLatitude()); + QuadRect rect = new QuadRect(left, top, right, bottom); + openMenuHeaderOnly(); + fitRectOnMap(rect); + } + + private void fitRectOnMap(QuadRect rect) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); @@ -1278,17 +1346,8 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { } if (tileBoxHeightPx > 0) { int topMarginPx = toolbar.getHeight(); - if (forceFit) { - mapActivity.getMapView().fitRectToMap(rect.left, rect.right, rect.top, rect.bottom, - tileBoxWidthPx, tileBoxHeightPx, topMarginPx); - } else if (location != null && - !mapActivity.getMapView().getTileBox(tileBoxWidthPx, tileBoxHeightPx, topMarginPx).containsLatLon(location)) { - boolean animating = mapActivity.getMapView().getAnimatedDraggingThread().isAnimating(); - mapActivity.getMapView().fitLocationToMap(location.getLatitude(), location.getLongitude(), - mapActivity.getMapView().getZoom(), tileBoxWidthPx, tileBoxHeightPx, topMarginPx, !animating); - } else { - mapActivity.refreshMap(); - } + mapActivity.getMapView().fitRectToMap(rect.left, rect.right, rect.top, rect.bottom, + tileBoxWidthPx, tileBoxHeightPx, topMarginPx); } } } @@ -1773,6 +1832,21 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { } } + @Override + public void onPublicTransportCardBadgePressed(@NonNull PublicTransportCard card, @NonNull TransportRouteResultSegment segment) { + showRouteSegmentOnMap(segment); + } + + @Override + public void onPublicTransportCardBadgePressed(@NonNull PublicTransportCard card, @NonNull RouteCalculationResult result) { + showRouteOnMap(result); + } + + @Override + public void onPublicTransportCardBadgePressed(@NonNull PublicTransportCard card, @NonNull LatLon start, @NonNull LatLon end) { + showOnMap(start, end); + } + public class CumulativeInfo { public int distance; public int time; @@ -2399,7 +2473,7 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment { } private void doLayoutMenu() { - final int posY = getPosY(getViewY(), false, getCurrentMenuState()); + final int posY = getPosY(initLayout ? CURRENT_Y_UNDEFINED : getViewY(), false, getCurrentMenuState()); setViewY(posY, true, !initLayout); updateMainViewLayout(posY); } diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/PublicTransportCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/PublicTransportCard.java index 98882459cf..db62b03cf0 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/PublicTransportCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/PublicTransportCard.java @@ -3,6 +3,8 @@ package net.osmand.plus.routepreparationmenu.cards; import android.graphics.Typeface; import android.graphics.drawable.GradientDrawable; import android.os.Build; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; @@ -14,13 +16,17 @@ import android.widget.LinearLayout; import android.widget.TextView; import net.osmand.AndroidUtils; +import net.osmand.data.LatLon; import net.osmand.data.TransportRoute; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.R; +import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.routepreparationmenu.ShowRouteInfoDialogFragment; import net.osmand.plus.helpers.FontCache; +import net.osmand.plus.routepreparationmenu.ShowRouteInfoDialogFragment; +import net.osmand.plus.routing.RouteCalculationResult; +import net.osmand.plus.routing.TransportRoutingHelper; import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.widgets.FlowLayout; import net.osmand.plus.widgets.style.CustomTypefaceSpan; @@ -37,12 +43,23 @@ public class PublicTransportCard extends BaseCard { public static final int DETAILS_BUTTON_INDEX = 0; public static final int SHOW_BUTTON_INDEX = 1; + private TargetPoint startPoint; + private TargetPoint endPoint; private TransportRouteResult routeResult; + private PublicTransportCardListener transportCardListener; private int routeId; - public PublicTransportCard(MapActivity mapActivity, TransportRouteResult routeResult, int routeId) { + public interface PublicTransportCardListener { + void onPublicTransportCardBadgePressed(@NonNull PublicTransportCard card, @NonNull TransportRouteResultSegment segment); + void onPublicTransportCardBadgePressed(@NonNull PublicTransportCard card, @NonNull RouteCalculationResult result); + void onPublicTransportCardBadgePressed(@NonNull PublicTransportCard card, @NonNull LatLon start, @NonNull LatLon end); + } + + public PublicTransportCard(MapActivity mapActivity, TargetPoint startPoint, TargetPoint endPoint, TransportRouteResult routeResult, int routeId) { super(mapActivity); + this.startPoint = startPoint; + this.endPoint = endPoint; this.routeResult = routeResult; this.routeId = routeId; } @@ -52,6 +69,14 @@ public class PublicTransportCard extends BaseCard { return R.layout.transport_route_card; } + public PublicTransportCardListener getTransportCardListener() { + return transportCardListener; + } + + public void setTransportCardListener(PublicTransportCardListener listener) { + this.transportCardListener = listener; + } + @Override protected void updateContent() { List segments = routeResult.getSegments(); @@ -177,14 +202,29 @@ public class PublicTransportCard extends BaseCard { FlowLayout routesBadges = (FlowLayout) view.findViewById(R.id.routes_badges); routesBadges.removeAllViews(); + TransportRoutingHelper transportRoutingHelper = app.getTransportRoutingHelper(); Iterator iterator = segments.iterator(); + TransportRouteResultSegment prevSegment = null; while (iterator.hasNext()) { TransportRouteResultSegment s = iterator.next(); - if (s.walkDist > 0) { + RouteCalculationResult walkingSegment = transportRoutingHelper.getWalkingRouteSegment(prevSegment, s); + if (walkingSegment != null) { + double walkTime = walkingSegment.getRoutingTime(); + if (walkTime > MIN_WALK_TIME) { + routesBadges.addView(createWalkRouteBadge(walkingSegment), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); + routesBadges.addView(createArrow(), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); + } + } else if (s.walkDist > 0) { double walkTime = getWalkTime(s.walkDist, routeResult.getWalkSpeed()); if (walkTime > MIN_WALK_TIME) { - String walkTimeS = OsmAndFormatter.getFormattedDuration((int) walkTime, app); - routesBadges.addView(createWalkRouteBadge(walkTimeS), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); + LatLon start; + LatLon end = s.getEnd().getLocation(); + if (prevSegment != null) { + start = prevSegment.getStart().getLocation(); + } else { + start = this.startPoint.point; + } + routesBadges.addView(createWalkRouteBadge(walkTime, start, end), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); routesBadges.addView(createArrow(), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); } } @@ -192,60 +232,96 @@ public class PublicTransportCard extends BaseCard { if (iterator.hasNext()) { routesBadges.addView(createArrow(), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); } else { - double finishWalkDist = routeResult.getFinishWalkDist(); - if (finishWalkDist > 0) { - double walkTime2 = getWalkTime(finishWalkDist, routeResult.getWalkSpeed()); - if (walkTime2 > MIN_WALK_TIME) { - String walkTimeS = OsmAndFormatter.getFormattedDuration((int) walkTime2, app); + walkingSegment = transportRoutingHelper.getWalkingRouteSegment(s, null); + if (walkingSegment != null) { + double walkTime = walkingSegment.getRoutingTime(); + if (walkTime > MIN_WALK_TIME) { routesBadges.addView(createArrow(), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); - routesBadges.addView(createWalkRouteBadge(walkTimeS)); + routesBadges.addView(createWalkRouteBadge(walkingSegment), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); + } + } else { + double finishWalkDist = routeResult.getFinishWalkDist(); + if (finishWalkDist > 0) { + double walkTime = getWalkTime(finishWalkDist, routeResult.getWalkSpeed()); + if (walkTime > MIN_WALK_TIME) { + LatLon start = s.getEnd().getLocation(); + LatLon end = this.endPoint.point; + routesBadges.addView(createArrow(), new FlowLayout.LayoutParams(itemsSpacing, itemsSpacing)); + routesBadges.addView(createWalkRouteBadge(walkTime, start, end)); + } } } } + prevSegment = s; } } - private View createRouteBadge(TransportRouteResultSegment segment) { - LinearLayout convertView = (LinearLayout) getMapActivity().getLayoutInflater().inflate(R.layout.transport_stop_route_item_with_icon, null, false); - if (segment != null) { - TransportRoute transportRoute = segment.route; - TransportStopRoute transportStopRoute = TransportStopRoute.getTransportStopRoute(transportRoute, segment.getStart()); + private View createRouteBadge(@NonNull final TransportRouteResultSegment segment) { + LinearLayout bageView = (LinearLayout) mapActivity.getLayoutInflater().inflate(R.layout.transport_stop_route_item_with_icon, null, false); + TransportRoute transportRoute = segment.route; + TransportStopRoute transportStopRoute = TransportStopRoute.getTransportStopRoute(transportRoute, segment.getStart()); - String routeRef = segment.route.getAdjustedRouteRef(); - int bgColor = transportStopRoute.getColor(app, nightMode); + String routeRef = segment.route.getAdjustedRouteRef(); + int bgColor = transportStopRoute.getColor(app, nightMode); - TextView transportStopRouteTextView = (TextView) convertView.findViewById(R.id.transport_stop_route_text); - ImageView transportStopRouteImageView = (ImageView) convertView.findViewById(R.id.transport_stop_route_icon); + TextView transportStopRouteTextView = (TextView) bageView.findViewById(R.id.transport_stop_route_text); + ImageView transportStopRouteImageView = (ImageView) bageView.findViewById(R.id.transport_stop_route_icon); - int drawableResId = transportStopRoute.type == null ? R.drawable.ic_action_bus_dark : transportStopRoute.type.getResourceId(); - transportStopRouteImageView.setImageDrawable(app.getUIUtilities().getPaintedIcon(drawableResId, UiUtilities.getContrastColor(app, bgColor, true))); - transportStopRouteTextView.setText(routeRef); - GradientDrawable gradientDrawableBg = (GradientDrawable) convertView.getBackground(); - gradientDrawableBg.setColor(bgColor); - transportStopRouteTextView.setTextColor(UiUtilities.getContrastColor(app, bgColor, true)); + int drawableResId = transportStopRoute.type == null ? R.drawable.ic_action_bus_dark : transportStopRoute.type.getResourceId(); + transportStopRouteImageView.setImageDrawable(app.getUIUtilities().getPaintedIcon(drawableResId, UiUtilities.getContrastColor(app, bgColor, true))); + transportStopRouteTextView.setText(routeRef); + GradientDrawable gradientDrawableBg = (GradientDrawable) bageView.getBackground(); + gradientDrawableBg.setColor(bgColor); + transportStopRouteTextView.setTextColor(UiUtilities.getContrastColor(app, bgColor, true)); + + if (transportCardListener != null) { + bageView.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + transportCardListener.onPublicTransportCardBadgePressed(PublicTransportCard.this, segment); + } + }); } - - return convertView; + return bageView; } - private View createWalkRouteBadge(String walkTime) { - LinearLayout convertView = (LinearLayout) getMapActivity().getLayoutInflater().inflate(R.layout.transport_stop_route_item_with_icon, null, false); - if (walkTime != null) { - int bgColor = ContextCompat.getColor(app, nightMode ? R.color.active_buttons_and_links_dark : R.color.active_buttons_and_links_light); - - TextView transportStopRouteTextView = (TextView) convertView.findViewById(R.id.transport_stop_route_text); - ImageView transportStopRouteImageView = (ImageView) convertView.findViewById(R.id.transport_stop_route_icon); - - transportStopRouteImageView.setImageDrawable(getColoredIcon(R.drawable.ic_action_pedestrian_dark, nightMode ? R.color.ctx_menu_bottom_view_url_color_dark : R.color.ctx_menu_bottom_view_url_color_light)); - transportStopRouteTextView.setText(walkTime); - GradientDrawable gradientDrawableBg = (GradientDrawable) convertView.getBackground(); - gradientDrawableBg.setColor(bgColor); - transportStopRouteTextView.setTextColor(ContextCompat.getColor(app, nightMode ? R.color.ctx_menu_bottom_view_url_color_dark : R.color.ctx_menu_bottom_view_url_color_light)); - - AndroidUtils.setBackground(app, convertView, nightMode, R.drawable.btn_border_active_light, R.drawable.btn_border_active_dark); + private View createWalkRouteBadge(@NonNull final RouteCalculationResult result) { + View v = createWalkRouteBadge(result.getRoutingTime(), null, null); + if (transportCardListener != null) { + v.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + transportCardListener.onPublicTransportCardBadgePressed(PublicTransportCard.this, result); + } + }); } + return v; + } - return convertView; + private View createWalkRouteBadge(double walkTime, @Nullable final LatLon start, @Nullable final LatLon end) { + LinearLayout bageView = (LinearLayout) getMapActivity().getLayoutInflater().inflate(R.layout.transport_stop_route_item_with_icon, null, false); + int bgColor = ContextCompat.getColor(app, nightMode ? R.color.active_buttons_and_links_dark : R.color.active_buttons_and_links_light); + + TextView transportStopRouteTextView = (TextView) bageView.findViewById(R.id.transport_stop_route_text); + ImageView transportStopRouteImageView = (ImageView) bageView.findViewById(R.id.transport_stop_route_icon); + + transportStopRouteImageView.setImageDrawable(getColoredIcon(R.drawable.ic_action_pedestrian_dark, nightMode ? R.color.ctx_menu_bottom_view_url_color_dark : R.color.ctx_menu_bottom_view_url_color_light)); + transportStopRouteTextView.setText(OsmAndFormatter.getFormattedDuration((int) walkTime, app)); + GradientDrawable gradientDrawableBg = (GradientDrawable) bageView.getBackground(); + gradientDrawableBg.setColor(bgColor); + transportStopRouteTextView.setTextColor(ContextCompat.getColor(app, nightMode ? R.color.ctx_menu_bottom_view_url_color_dark : R.color.ctx_menu_bottom_view_url_color_light)); + + AndroidUtils.setBackground(app, bageView, nightMode, R.drawable.btn_border_active_light, R.drawable.btn_border_active_dark); + + if (transportCardListener != null && start != null && end != null) { + bageView.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + transportCardListener.onPublicTransportCardBadgePressed(PublicTransportCard.this, start, end); + } + }); + } + return bageView; } private View createArrow() { diff --git a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java index 7f0db299c4..e097f40451 100644 --- a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java @@ -105,7 +105,10 @@ public class TransportRoutingHelper { @Nullable public RouteCalculationResult getWalkingRouteSegment(TransportRouteResultSegment s1, TransportRouteResultSegment s2) { - return walkingRouteSegments.get(new Pair<>(s1, s2)); + if (walkingRouteSegments != null) { + return walkingRouteSegments.get(new Pair<>(s1, s2)); + } + return null; } public void setCurrentRoute(int currentRoute) {