[Android] Added new routing type. Showing detailed ruler route info in bottom panel

Signed-off-by: S. Kozyr <s.trump@gmail.com>
This commit is contained in:
Sergiy Kozyr 2023-08-26 21:55:37 +03:00 committed by Viktor Govako
parent 858262b554
commit e430f48bb5
14 changed files with 195 additions and 41 deletions

View file

@ -1425,6 +1425,7 @@ Java_app_organicmaps_Framework_nativeSetRouter(JNIEnv * env, jclass, jint router
case 1: type = Type::Pedestrian; break;
case 2: type = Type::Bicycle; break;
case 3: type = Type::Transit; break;
case 4: type = Type::Ruler; break;
default: assert(false); break;
}
g_framework->GetRoutingManager().SetRouter(type);

View file

@ -0,0 +1,31 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M15.081,6.622m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
android:strokeWidth="1.2"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M18.156,15.261m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
android:strokeWidth="1.2"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M6.24,16.538m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
android:strokeWidth="1.2"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M7.301,15.429 L14.284,7.608"
android:strokeWidth="1.2"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="m15.495,7.908 l2.15,6.228"
android:strokeWidth="1.2"
android:fillColor="#00000000"
android:strokeColor="#000"/>
</vector>

View file

@ -46,7 +46,7 @@
android:id="@+id/transit_recycler_view"
android:layout_marginTop="@dimen/margin_half_plus"
android:layout_alignParentStart="true"
android:layout_below="@id/total_distance"
android:layout_below="@id/total_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>

View file

@ -73,6 +73,14 @@
android:layout_marginEnd="12dp"
tools:button="@drawable/ic_bike"
tools:buttonTint="?iconTintLight" />
<app.organicmaps.widget.RoutingToolbarButton
android:id="@+id/ruler"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
tools:button="@drawable/ic_ruler_route"
tools:buttonTint="?iconTintLight" />
</RadioGroup>
<LinearLayout
@ -113,6 +121,13 @@
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"
android:layout_marginEnd="12dp"/>
<app.organicmaps.widget.WheelProgressView
android:id="@+id/progress_ruler"
style="@style/MwmWidget.ProgressWheel.RoutingPlan"
android:layout_marginTop="@dimen/routing_selector_wheel_margin"
android:layout_marginBottom="@dimen/routing_selector_wheel_margin"
android:layout_marginEnd="12dp"/>
</LinearLayout>
</RelativeLayout>

View file

@ -51,6 +51,7 @@
<dimen name="text_size_routing_dimension_inline">20sp</dimen>
<dimen name="text_size_routing_plan_detail">16sp</dimen>
<dimen name="text_size_routing_plan_detail_arrival">14sp</dimen>
<dimen name="text_size_routing_plan_detail_intermediate">20sp</dimen>
<dimen name="text_size_time_picker">56sp</dimen>
<dimen name="text_size_nav_street">17sp</dimen>

View file

@ -42,6 +42,7 @@
<attr name="routingButtonHint" format="color" />
<attr name="drivingOptionsViewBg" format="color" />
<attr name="transitPedestrianBackground" format="color" />
<attr name="transitRulerBackground" format="color" />
<attr name="colorBtnHighlight" format="color" />
<attr name="transitStepDivider" format="reference" />
<attr name="colorAccentTransparent" format="reference" />

View file

@ -87,6 +87,7 @@
<item name="homeAsUpIndicator">@drawable/back_arrow</item>
<item name="transitPedestrianBackground">@color/black_4</item>
<item name="transitRulerBackground">@color/black_4</item>
<item name="transitStepDivider">@drawable/dot_divider</item>
<item name="trafficMenuEnabled">@drawable/ic_layers_traffic_active</item>
<item name="subwayMenuEnabled">@drawable/ic_layers_subway_active</item>
@ -221,6 +222,7 @@
<item name="homeAsUpIndicator">@drawable/back_arrow</item>
<item name="transitPedestrianBackground">@color/white_4</item>
<item name="transitRulerBackground">@color/white_4</item>
<item name="transitStepDivider">@drawable/dot_divider_night</item>
<item name="trafficMenuEnabled">@drawable/ic_layers_traffic_active_night</item>
<item name="subwayMenuEnabled">@drawable/ic_layers_subway_active_night</item>

View file

@ -46,7 +46,7 @@ public class Framework
public static final int MAP_STYLE_VEHICLE_DARK = 4;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ ROUTER_TYPE_VEHICLE, ROUTER_TYPE_PEDESTRIAN, ROUTER_TYPE_BICYCLE, ROUTER_TYPE_TRANSIT })
@IntDef({ ROUTER_TYPE_VEHICLE, ROUTER_TYPE_PEDESTRIAN, ROUTER_TYPE_BICYCLE, ROUTER_TYPE_TRANSIT, ROUTER_TYPE_RULER })
public @interface RouterType {}
@ -54,6 +54,7 @@ public class Framework
public static final int ROUTER_TYPE_PEDESTRIAN = 1;
public static final int ROUTER_TYPE_BICYCLE = 2;
public static final int ROUTER_TYPE_TRANSIT = 3;
public static final int ROUTER_TYPE_RULER = 4;
@Retention(RetentionPolicy.SOURCE)
@IntDef({DO_AFTER_UPDATE_NOTHING, DO_AFTER_UPDATE_AUTO_UPDATE, DO_AFTER_UPDATE_ASK_FOR_UPDATE})

View file

@ -29,13 +29,17 @@ import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.Framework;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.util.Distance;
import app.organicmaps.widget.recycler.DotDividerItemDecoration;
import app.organicmaps.widget.recycler.MultilineLayoutManager;
import app.organicmaps.util.Graphics;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.UiUtils;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
final class RoutingBottomMenuController implements View.OnClickListener
@ -135,9 +139,11 @@ final class RoutingBottomMenuController implements View.OnClickListener
void showAltitudeChartAndRoutingDetails()
{
UiUtils.hide(mError, mActionFrame, mTransitFrame);
UiUtils.hide(mError, mActionFrame, mAltitudeChart, mAltitudeDifference, mTransitFrame);
showRouteAltitudeChart();
if (!RoutingController.get().isVehicleRouterType() &&
!RoutingController.get().isRulerRouterType())
showRouteAltitudeChart();
showRoutingDetails();
UiUtils.show(mAltitudeChartFrame);
}
@ -172,6 +178,53 @@ final class RoutingBottomMenuController implements View.OnClickListener
distanceView.setText(info.getTotalPedestrianDistance() + " " + info.getTotalPedestrianDistanceUnits());
}
@SuppressLint("SetTextI18n")
void showRulerInfo(@NonNull RouteMarkData[] points, Distance totalLength)
{
UiUtils.hide(mError, mAltitudeChartFrame, mActionFrame, mAltitudeChartFrame);
showStartButton(false);
UiUtils.show(mTransitFrame);
RecyclerView rv = mTransitFrame.findViewById(R.id.transit_recycler_view);
if (points.length > 2)
{
UiUtils.show(rv);
TransitStepAdapter adapter = new TransitStepAdapter();
rv.setLayoutManager(new MultilineLayoutManager());
rv.setNestedScrollingEnabled(false);
rv.removeItemDecoration(mTransitViewDecorator);
rv.addItemDecoration(mTransitViewDecorator);
rv.setAdapter(adapter);
adapter.setItems(pointsToRulerSteps(points));
}
else
UiUtils.hide(rv); // Show only distance between start and finish
TextView totalTimeView = mTransitFrame.findViewById(R.id.total_time);
totalTimeView.setText(mContext.getString(R.string.placepage_distance) + ": " +
totalLength.mDistanceStr + " " + totalLength.getUnitsStr(mContext));
UiUtils.hide(mTransitFrame, R.id.dot);
UiUtils.hide(mTransitFrame, R.id.pedestrian_icon);
UiUtils.hide(mTransitFrame, R.id.total_distance);
}
// Create steps info to use in TransitStepAdapter.
private List<TransitStepInfo> pointsToRulerSteps(RouteMarkData[] points)
{
List<TransitStepInfo> transitSteps = new LinkedList<>();
for (int i = 1; i < points.length; i++)
{
RouteMarkData segmentStart = points[i - 1];
RouteMarkData segmentEnd = points[i];
DistanceAndAzimut dist = Framework.nativeGetDistanceAndAzimuthFromLatLon(segmentStart.mLat, segmentStart.mLon, segmentEnd.mLat, segmentEnd.mLon, 0);
if (i > 1)
transitSteps.add(TransitStepInfo.intermediatePoint(i - 2));
transitSteps.add(TransitStepInfo.ruler(dist.getDistance().mDistanceStr, dist.getDistance().getUnitsStr(mContext)));
}
return transitSteps;
}
void showAddStartFrame()
{
UiUtils.hide(mError, mTransitFrame);
@ -206,15 +259,17 @@ final class RoutingBottomMenuController implements View.OnClickListener
UiUtils.hide(mActionFrame);
}
void setStartButton()
void setStartButton(boolean show)
{
mStart.setText(mContext.getText(R.string.p2p_start));
mStart.setOnClickListener(v -> {
if (mListener != null)
mListener.onRoutingStart();
});
if (show) {
mStart.setText(mContext.getText(R.string.p2p_start));
mStart.setOnClickListener(v -> {
if (mListener != null)
mListener.onRoutingStart();
});
}
showStartButton(true);
showStartButton(show);
}
private void showError(@NonNull String message)

View file

@ -603,6 +603,11 @@ public class RoutingController implements Initializable<Void>
return mLastRouterType == Framework.ROUTER_TYPE_VEHICLE;
}
boolean isRulerRouterType()
{
return mLastRouterType == Framework.ROUTER_TYPE_RULER;
}
public boolean isNavigating()
{
return mState == State.NAVIGATION;
@ -815,22 +820,14 @@ public class RoutingController implements Initializable<Void>
}
if (isSamePoint)
{
Logger.d(TAG, "setEndPoint: skip the same end point");
return false;
}
if (point != null && point.sameAs(startPoint))
{
if (endPoint == null)
{
Logger.d(TAG, "setEndPoint: skip because end point is empty");
return false;
}
Logger.d(TAG, "setEndPoint: swap with starting point");
startPoint = endPoint;
}
endPoint = point;

View file

@ -39,6 +39,8 @@ public class RoutingPlanController extends ToolbarController
private final WheelProgressView mProgressTransit;
@NonNull
private final WheelProgressView mProgressBicycle;
@NonNull
private final WheelProgressView mProgressRuler;
// @NonNull
// private final WheelProgressView mProgressTaxi;
@ -93,6 +95,7 @@ public class RoutingPlanController extends ToolbarController
mProgressPedestrian = progressFrame.findViewById(R.id.progress_pedestrian);
mProgressTransit = progressFrame.findViewById(R.id.progress_transit);
mProgressBicycle = progressFrame.findViewById(R.id.progress_bicycle);
mProgressRuler = progressFrame.findViewById(R.id.progress_ruler);
// mProgressTaxi = (WheelProgressView) progressFrame.findViewById(R.id.progress_taxi);
mRoutingBottomMenuController = RoutingBottomMenuController.newInstance(requireActivity(), mFrame, listener);
@ -128,12 +131,13 @@ public class RoutingPlanController extends ToolbarController
{
setupRouterButton(R.id.vehicle, R.drawable.ic_car, this::onVehicleModeSelected);
setupRouterButton(R.id.pedestrian, R.drawable.ic_pedestrian, this::onPedestrianModeSelected);
setupRouterButton(R.id.bicycle, R.drawable.ic_bike, this::onBicycleModeSelected);
// setupRouterButton(R.id.taxi, R.drawable.ic_taxi, this::onTaxiModeSelected);
setupRouterButton(R.id.transit, R.drawable.ic_transit, v -> onTransitModeSelected());
setupRouterButton(R.id.transit, R.drawable.ic_transit, this::onTransitModeSelected);
setupRouterButton(R.id.bicycle, R.drawable.ic_bike, this::onBicycleModeSelected);
setupRouterButton(R.id.ruler, R.drawable.ic_ruler_route, this::onRulerModeSelected);
}
private void onTransitModeSelected()
private void onTransitModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_TRANSIT);
}
@ -143,6 +147,11 @@ public class RoutingPlanController extends ToolbarController
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_BICYCLE);
}
private void onRulerModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_RULER);
}
private void onPedestrianModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_PEDESTRIAN);
@ -188,39 +197,53 @@ public class RoutingPlanController extends ToolbarController
return;
}
mRoutingBottomMenuController.setStartButton();
if (isRulerType())
{
RoutingInfo routingInfo = RoutingController.get().getCachedRoutingInfo();
if (routingInfo != null)
mRoutingBottomMenuController.showRulerInfo(Framework.nativeGetRoutePoints(), routingInfo.distToTarget);
return;
}
boolean showStartButton = !RoutingController.get().isRulerRouterType();
mRoutingBottomMenuController.setStartButton(showStartButton);
mRoutingBottomMenuController.showAltitudeChartAndRoutingDetails();
}
public void updateBuildProgress(int progress, @Framework.RouterType int router)
{
UiUtils.invisible(mProgressVehicle, mProgressPedestrian, mProgressTransit,
mProgressBicycle);
mProgressBicycle, mProgressRuler);
WheelProgressView progressView;
if (router == Framework.ROUTER_TYPE_VEHICLE)
switch(router)
{
case Framework.ROUTER_TYPE_VEHICLE:
mRouterTypes.check(R.id.vehicle);
progressView = mProgressVehicle;
}
else if (router == Framework.ROUTER_TYPE_PEDESTRIAN)
{
break;
case Framework.ROUTER_TYPE_PEDESTRIAN:
mRouterTypes.check(R.id.pedestrian);
progressView = mProgressPedestrian;
}
// else if (router == Framework.ROUTER_TYPE_TAXI)
// {
// mRouterTypes.check(R.id.taxi);
// progressView = mProgressTaxi;
// }
else if (router == Framework.ROUTER_TYPE_TRANSIT)
{
break;
//case Framework.ROUTER_TYPE_TAXI:
// {
// mRouterTypes.check(R.id.taxi);
// progressView = mProgressTaxi;
// }
case Framework.ROUTER_TYPE_TRANSIT:
mRouterTypes.check(R.id.transit);
progressView = mProgressTransit;
}
else
{
break;
case Framework.ROUTER_TYPE_BICYCLE:
mRouterTypes.check(R.id.bicycle);
progressView = mProgressBicycle;
break;
case Framework.ROUTER_TYPE_RULER:
mRouterTypes.check(R.id.ruler);
progressView = mProgressRuler;
break;
default:
throw new IllegalArgumentException("unknown router: " + router);
}
RoutingToolbarButton button = mRouterTypes
@ -246,6 +269,11 @@ public class RoutingPlanController extends ToolbarController
return RoutingController.get().isTransitType();
}
private boolean isRulerType()
{
return RoutingController.get().isRulerRouterType();
}
void saveRoutingPanelState(@NonNull Bundle outState)
{
mRoutingBottomMenuController.saveRoutingPanelState(outState);

View file

@ -18,10 +18,11 @@ public class TransitStepInfo
private static final int TRANSIT_TYPE_TRAIN = 3;
private static final int TRANSIT_TYPE_LIGHT_RAIL = 4;
private static final int TRANSIT_TYPE_MONORAIL = 5;
private static final int TRANSIT_TYPE_RULER = 6;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ TRANSIT_TYPE_INTERMEDIATE_POINT, TRANSIT_TYPE_PEDESTRIAN, TRANSIT_TYPE_SUBWAY,
TRANSIT_TYPE_TRAIN, TRANSIT_TYPE_LIGHT_RAIL, TRANSIT_TYPE_MONORAIL })
TRANSIT_TYPE_TRAIN, TRANSIT_TYPE_LIGHT_RAIL, TRANSIT_TYPE_MONORAIL, TRANSIT_TYPE_RULER})
@interface TransitType {}
@NonNull
@ -48,6 +49,18 @@ public class TransitStepInfo
mIntermediateIndex = intermediateIndex;
}
@NonNull
public static TransitStepInfo intermediatePoint(int intermediateIndex)
{
return new TransitStepInfo(TRANSIT_TYPE_INTERMEDIATE_POINT, null, null, 0, null, 0, intermediateIndex);
}
@NonNull
public static TransitStepInfo ruler(@NonNull String distance, @NonNull String distanceUnits)
{
return new TransitStepInfo(TRANSIT_TYPE_RULER, distance, distanceUnits, 0, null, 0, -1);
}
@NonNull
public TransitStepType getType()
{

View file

@ -12,7 +12,8 @@ public enum TransitStepType
SUBWAY(R.drawable.ic_20px_route_planning_metro),
TRAIN(R.drawable.ic_20px_route_planning_train),
LIGHT_RAIL(R.drawable.ic_20px_route_planning_lightrail),
MONORAIL(R.drawable.ic_20px_route_planning_monorail);
MONORAIL(R.drawable.ic_20px_route_planning_monorail),
RULER(R.drawable.ic_ruler_route);
@DrawableRes
private final int mDrawable;

View file

@ -85,6 +85,12 @@ public class TransitStepView extends View implements MultilineLayoutManager.Sque
mDrawable = null;
mText = String.valueOf(info.getIntermediateIndex() + 1);
}
else if (mStepType == TransitStepType.RULER)
{
mDrawable = null;
mText = info.getDistance() + " " + info.getDistanceUnits();
mTextPaint.setColor(Color.BLACK);
}
else
{
mDrawable = ResourcesCompat.getDrawable(getResources(), mStepType.getDrawable(), null);
@ -101,6 +107,8 @@ public class TransitStepView extends View implements MultilineLayoutManager.Sque
{
case PEDESTRIAN:
return ThemeUtils.getColor(context, R.attr.transitPedestrianBackground);
case RULER:
return ThemeUtils.getColor(context, R.attr.transitRulerBackground);
case INTERMEDIATE_POINT:
return ThemeUtils.getColor(context, R.attr.colorPrimary);
default: