[routing] New API for lanes

Signed-off-by: Andrei Shkrob <github@shkrob.dev>
This commit is contained in:
Andrei Shkrob
2025-07-29 22:54:24 +02:00
committed by x7z4w
parent 93293e7b31
commit c014e224b2
36 changed files with 1047 additions and 634 deletions

View File

@@ -31,18 +31,19 @@ public final class RoutingHelpers
@NonNull
public static LaneDirection createLaneDirection(@NonNull LaneWay laneWay, boolean isRecommended)
{
int shape = LaneDirection.SHAPE_UNKNOWN;
shape = switch (laneWay)
@LaneDirection.Shape
final int shape = switch (laneWay)
{
case REVERSE -> LaneDirection.SHAPE_U_TURN_LEFT;
case SHARP_LEFT -> LaneDirection.SHAPE_SHARP_LEFT;
case LEFT -> LaneDirection.SHAPE_NORMAL_LEFT;
case SLIGHT_LEFT, MERGE_TO_LEFT -> LaneDirection.SHAPE_SLIGHT_LEFT;
case SLIGHT_RIGHT, MERGE_TO_RIGHT -> LaneDirection.SHAPE_SLIGHT_RIGHT;
case THROUGH -> LaneDirection.SHAPE_STRAIGHT;
case RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT;
case SHARP_RIGHT -> LaneDirection.SHAPE_SHARP_RIGHT;
default -> shape;
case ReverseLeft -> LaneDirection.SHAPE_U_TURN_LEFT;
case SharpLeft -> LaneDirection.SHAPE_SHARP_LEFT;
case Left -> LaneDirection.SHAPE_NORMAL_LEFT;
case MergeToLeft, SlightLeft -> LaneDirection.SHAPE_SLIGHT_LEFT;
case Through -> LaneDirection.SHAPE_STRAIGHT;
case SlightRight, MergeToRight -> LaneDirection.SHAPE_SLIGHT_RIGHT;
case Right -> LaneDirection.SHAPE_NORMAL_RIGHT;
case SharpRight -> LaneDirection.SHAPE_SHARP_RIGHT;
case ReverseRight -> LaneDirection.SHAPE_U_TURN_RIGHT;
default -> LaneDirection.SHAPE_UNKNOWN;
};
return LaneDirection.create(shape, isRecommended);

View File

@@ -8,14 +8,15 @@ import androidx.car.app.CarContext;
import androidx.car.app.model.CarIcon;
import androidx.car.app.navigation.model.Destination;
import androidx.car.app.navigation.model.Lane;
import androidx.car.app.navigation.model.LaneDirection;
import androidx.car.app.navigation.model.Step;
import androidx.car.app.navigation.model.TravelEstimate;
import androidx.car.app.navigation.model.Trip;
import androidx.core.graphics.drawable.IconCompat;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.LaneInfo;
import app.organicmaps.sdk.routing.LaneWay;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.SingleLaneInfo;
import app.organicmaps.sdk.util.Distance;
import app.organicmaps.util.Graphics;
import app.organicmaps.widget.LanesDrawable;
@@ -69,11 +70,12 @@ public final class RoutingUtils
builder.setManeuver(RoutingHelpers.createManeuver(context, info.carDirection, info.exitNum));
if (info.lanes != null)
{
for (final SingleLaneInfo laneInfo : info.lanes)
for (final LaneInfo laneInfo : info.lanes)
{
final Lane.Builder laneBuilder = new Lane.Builder();
for (final LaneWay laneWay : laneInfo.mLane)
laneBuilder.addDirection(RoutingHelpers.createLaneDirection(laneWay, laneInfo.mIsActive));
for (final LaneWay laneWay : laneInfo.mLaneWays)
laneBuilder.addDirection(
RoutingHelpers.createLaneDirection(laneWay, /* isRecommended */ laneWay == laneInfo.mActiveLaneWay));
builder.addLane(laneBuilder.build());
}
final LanesDrawable lanesDrawable = new LanesDrawable(context, info.lanes);

View File

@@ -8,12 +8,14 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.content.ContextCompat;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.SingleLaneInfo;
import app.organicmaps.sdk.routing.LaneInfo;
import app.organicmaps.sdk.routing.LaneWay;
import java.util.Objects;
public class LanesDrawable extends Drawable
@@ -41,16 +43,19 @@ public class LanesDrawable extends Drawable
{
private final Drawable mDrawable;
private LaneDrawable(@NonNull final Context context, @NonNull SingleLaneInfo laneInfo, int horizontalOffset,
private LaneDrawable(@NonNull final Context context, @NonNull LaneInfo laneInfo, int horizontalOffset,
TintColorInfo colorInfo)
{
mDrawable = Objects.requireNonNull(AppCompatResources.getDrawable(context, laneInfo.mLane[0].mTurnRes));
final boolean isActive = laneInfo.mActiveLaneWay != LaneWay.None;
@DrawableRes
final int turnRes = isActive ? laneInfo.mActiveLaneWay.mTurnRes : laneInfo.mLaneWays[0].mTurnRes;
mDrawable = Objects.requireNonNull(AppCompatResources.getDrawable(context, turnRes));
final int width = mDrawable.getIntrinsicWidth();
final int height = mDrawable.getIntrinsicHeight();
mDrawable.setBounds(horizontalOffset, 0, horizontalOffset + width, height);
mDrawable.setTint(laneInfo.mIsActive ? colorInfo.mActiveLaneTint : colorInfo.mInactiveLaneTint);
mDrawable.setTint(isActive ? colorInfo.mActiveLaneTint : colorInfo.mInactiveLaneTint);
}
private void draw(@NonNull final Canvas canvas)
@@ -65,14 +70,14 @@ public class LanesDrawable extends Drawable
private int mWidth;
private int mHeight;
public LanesDrawable(@NonNull final Context context, @NonNull SingleLaneInfo[] lanes)
public LanesDrawable(@NonNull final Context context, @NonNull LaneInfo[] lanes)
{
final TintColorInfo tintColorInfo = new TintColorInfo(ContextCompat.getColor(context, ACTIVE_LANE_TINT_RES),
ContextCompat.getColor(context, INACTIVE_LANE_TINT_RES));
mLanes = createLaneDrawables(context, lanes, tintColorInfo);
}
public LanesDrawable(@NonNull final Context context, @NonNull SingleLaneInfo[] lanes, @ColorInt int activeLaneTint,
public LanesDrawable(@NonNull final Context context, @NonNull LaneInfo[] lanes, @ColorInt int activeLaneTint,
@ColorInt int inactiveLaneTint)
{
final TintColorInfo tintColorInfo = new TintColorInfo(activeLaneTint, inactiveLaneTint);
@@ -143,7 +148,7 @@ public class LanesDrawable extends Drawable
}
@NonNull
private LaneDrawable[] createLaneDrawables(@NonNull Context context, @NonNull SingleLaneInfo[] lanes,
private LaneDrawable[] createLaneDrawables(@NonNull Context context, @NonNull LaneInfo[] lanes,
@NonNull TintColorInfo tintColorInfo)
{
assert lanes.length > 0;

View File

@@ -16,7 +16,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleableRes;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.SingleLaneInfo;
import app.organicmaps.sdk.routing.LaneInfo;
import app.organicmaps.sdk.routing.LaneWay;
public class LanesView extends View
{
@@ -77,7 +78,7 @@ public class LanesView extends View
mBackgroundPaint.setColor(backgroundColor);
}
public void setLanes(@Nullable SingleLaneInfo[] lanes)
public void setLanes(@Nullable LaneInfo[] lanes)
{
if (lanes == null || lanes.length == 0)
mLanesDrawable = null;
@@ -157,16 +158,16 @@ public class LanesView extends View
private void createLanesForEditMode(int lanesCount)
{
final SingleLaneInfo[] lanes = new SingleLaneInfo[lanesCount];
lanes[0] = new SingleLaneInfo(new byte[] {1}, false);
final LaneInfo[] lanes = new LaneInfo[lanesCount];
lanes[0] = new LaneInfo(new LaneWay[] {LaneWay.ReverseLeft, LaneWay.Left}, LaneWay.None);
if (lanes.length > 1)
lanes[1] = new SingleLaneInfo(new byte[] {3}, false);
lanes[1] = new LaneInfo(new LaneWay[] {LaneWay.SharpLeft, LaneWay.Left, LaneWay.Through}, LaneWay.None);
for (int i = 2; i <= lanes.length - 1; i++)
lanes[i] = new SingleLaneInfo(new byte[] {0}, true);
lanes[i] = new LaneInfo(new LaneWay[] {LaneWay.Through, LaneWay.Left}, LaneWay.Through);
if (lanes.length > 2)
lanes[lanes.length - 2] = new SingleLaneInfo(new byte[] {8}, false);
lanes[lanes.length - 2] = new LaneInfo(new LaneWay[] {LaneWay.SlightRight, LaneWay.Right}, LaneWay.SlightRight);
if (lanes.length > 3)
lanes[lanes.length - 1] = new SingleLaneInfo(new byte[] {9}, false);
lanes[lanes.length - 1] = new LaneInfo(new LaneWay[] {LaneWay.ReverseRight}, LaneWay.None);
setLanes(lanes);
}