[android][sdk] Routing part 2

Signed-off-by: Andrei Shkrob <github@shkrob.dev>
This commit is contained in:
Andrei Shkrob 2025-01-18 10:29:54 +01:00
parent 96cfdaf2d1
commit e65d6cd394
34 changed files with 471 additions and 384 deletions

View file

@ -25,8 +25,16 @@ set(SRC
app/organicmaps/sdk/search/DisplayedCategories.cpp
app/organicmaps/sdk/search/SearchEngine.cpp
app/organicmaps/sdk/search/SearchRecents.cpp
app/organicmaps/sdk/routing/JunctionInfo.hpp
app/organicmaps/sdk/routing/RouteMarkData.hpp
app/organicmaps/sdk/routing/RouteMarkType.hpp
app/organicmaps/sdk/routing/RoutePointInfo.hpp
app/organicmaps/sdk/routing/RouteRecommendationType.hpp
app/organicmaps/sdk/routing/RoutingInfo.hpp
app/organicmaps/sdk/routing/RoutingOptions.cpp
app/organicmaps/sdk/routing/SingleLaneInfo.hpp
app/organicmaps/sdk/routing/TransitRouteInfo.hpp
app/organicmaps/sdk/routing/TransitStepInfo.hpp
app/organicmaps/sdk/ChoosePositionMode.cpp
app/organicmaps/sdk/MapStyle.cpp
app/organicmaps/sdk/OrganicMaps.cpp

View file

@ -4,7 +4,12 @@
#include "app/organicmaps/UserMarkHelper.hpp"
#include "app/organicmaps/opengl/androidoglcontextfactory.hpp"
#include "app/organicmaps/platform/AndroidPlatform.hpp"
#include "app/organicmaps/sdk/routing/JunctionInfo.hpp"
#include "app/organicmaps/sdk/routing/RouteMarkData.hpp"
#include "app/organicmaps/sdk/routing/RouteMarkType.hpp"
#include "app/organicmaps/sdk/routing/RouteRecommendationType.hpp"
#include "app/organicmaps/sdk/routing/RoutingInfo.hpp"
#include "app/organicmaps/sdk/routing/TransitRouteInfo.hpp"
#include "app/organicmaps/util/Distance.hpp"
#include "app/organicmaps/util/FeatureIdBuilder.hpp"
#include "app/organicmaps/util/NetworkPolicy.hpp"
@ -1242,7 +1247,7 @@ Java_app_organicmaps_Framework_nativeDisableFollowing(JNIEnv * env, jclass)
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_Framework_nativeGenerateNotifications(JNIEnv * env, jclass, bool announceStreets)
Java_app_organicmaps_Framework_nativeGenerateNotifications(JNIEnv * env, jclass, jboolean announceStreets)
{
::Framework * fr = frm();
if (!fr->GetRoutingManager().IsRoutingActive())
@ -1272,64 +1277,16 @@ Java_app_organicmaps_Framework_nativeGetSpeedCamManagerMode(JNIEnv * env, jclass
JNIEXPORT jobject JNICALL
Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass)
{
::Framework * fr = frm();
if (!fr->GetRoutingManager().IsRoutingActive())
RoutingManager & rm = frm()->GetRoutingManager();
if (!rm.IsRoutingActive())
return nullptr;
routing::FollowingInfo info;
fr->GetRoutingManager().GetRouteFollowingInfo(info);
rm.GetRouteFollowingInfo(info);
if (!info.IsValid())
return nullptr;
static jclass const klass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RoutingInfo");
// Java signature : RoutingInfo(Distance distToTarget, Distance distToTurn,
// String currentStreet, String nextStreet, String nextNextStreet,
// double completionPercent, int vehicleTurnOrdinal, int
// vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
// int totalTime, SingleLaneInfo[] lanes)
static jmethodID const ctorRouteInfoID =
jni::GetConstructorID(env, klass,
"(Lapp/organicmaps/util/Distance;Lapp/organicmaps/util/Distance;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DIIIII"
"[Lapp/organicmaps/sdk/routing/SingleLaneInfo;DZZ)V");
vector<routing::FollowingInfo::SingleLaneInfoClient> const & lanes = info.m_lanes;
jobjectArray jLanes = nullptr;
if (!lanes.empty())
{
static jclass const laneClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/SingleLaneInfo");
auto const lanesSize = static_cast<jsize>(lanes.size());
jLanes = env->NewObjectArray(lanesSize, laneClass, nullptr);
ASSERT(jLanes, (jni::DescribeException()));
static jmethodID const ctorSingleLaneInfoID = jni::GetConstructorID(env, laneClass, "([BZ)V");
for (jsize j = 0; j < lanesSize; ++j)
{
auto const laneSize = static_cast<jsize>(lanes[j].m_lane.size());
jni::TScopedLocalByteArrayRef singleLane(env, env->NewByteArray(laneSize));
ASSERT(singleLane.get(), (jni::DescribeException()));
env->SetByteArrayRegion(singleLane.get(), 0, laneSize, lanes[j].m_lane.data());
jni::TScopedLocalRef singleLaneInfo(
env, env->NewObject(laneClass, ctorSingleLaneInfoID, singleLane.get(),
lanes[j].m_isRecommended));
ASSERT(singleLaneInfo.get(), (jni::DescribeException()));
env->SetObjectArrayElement(jLanes, j, singleLaneInfo.get());
}
}
auto const & rm = frm()->GetRoutingManager();
auto const isSpeedCamLimitExceeded = rm.IsRoutingActive() ? rm.IsSpeedCamLimitExceeded() : false;
auto const shouldPlaySignal = frm()->GetRoutingManager().GetSpeedCamManager().ShouldPlayBeepSignal();
jobject const result = env->NewObject(
klass, ctorRouteInfoID, ToJavaDistance(env, info.m_distToTarget),
ToJavaDistance(env, info.m_distToTurn), jni::ToJavaString(env, info.m_currentStreetName),
jni::ToJavaString(env, info.m_nextStreetName), jni::ToJavaString(env, info.m_nextNextStreetName),
info.m_completionPercent, info.m_turn, info.m_nextTurn, info.m_pedestrianTurn, info.m_exitNum,
info.m_time, jLanes, info.m_speedLimitMps, static_cast<jboolean>(isSpeedCamLimitExceeded),
static_cast<jboolean>(shouldPlaySignal));
ASSERT(result, (jni::DescribeException()));
return result;
return CreateRoutingInfo(env, info, rm);
}
JNIEXPORT jobjectArray JNICALL
@ -1342,17 +1299,7 @@ Java_app_organicmaps_Framework_nativeGetRouteJunctionPoints(JNIEnv * env, jclass
return nullptr;
}
static jclass const junctionClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/JunctionInfo");
// Java signature : JunctionInfo(double lat, double lon)
static jmethodID const junctionConstructor = jni::GetConstructorID(env, junctionClazz, "(DD)V");
return jni::ToJavaArray(env, junctionClazz, junctionPoints,
[](JNIEnv * env, m2::PointD const & point)
{
return env->NewObject(junctionClazz, junctionConstructor,
mercator::YToLat(point.y),
mercator::XToLon(point.x));
});
return CreateJunctionInfoArray(env, junctionPoints);
}
JNIEXPORT jintArray JNICALL
@ -1503,7 +1450,7 @@ Java_app_organicmaps_Framework_nativeDeactivateMapSelectionCircle(JNIEnv * env,
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeAddRoutePoint(JNIEnv * env, jclass, jstring title,
jstring subtitle, jint markType,
jstring subtitle, jobject markType,
jint intermediateIndex,
jboolean isMyPosition,
jdouble lat, jdouble lon)
@ -1511,7 +1458,7 @@ Java_app_organicmaps_Framework_nativeAddRoutePoint(JNIEnv * env, jclass, jstring
RouteMarkData data;
data.m_title = jni::ToNativeString(env, title);
data.m_subTitle = jni::ToNativeString(env, subtitle);
data.m_pointType = static_cast<RouteMarkType>(markType);
data.m_pointType = GetRouteMarkType(env, markType);
data.m_intermediateIndex = static_cast<size_t>(intermediateIndex);
data.m_isMyPosition = static_cast<bool>(isMyPosition);
data.m_position = m2::PointD(mercator::FromLatLon(lat, lon));
@ -1526,10 +1473,9 @@ Java_app_organicmaps_Framework_nativeRemoveRoutePoints(JNIEnv * env, jclass)
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeRemoveRoutePoint(JNIEnv * env, jclass,
jint markType, jint intermediateIndex)
Java_app_organicmaps_Framework_nativeRemoveRoutePoint(JNIEnv * env, jclass, jobject markType, jint intermediateIndex)
{
frm()->GetRoutingManager().RemoveRoutePoint(static_cast<RouteMarkType>(markType),
frm()->GetRoutingManager().RemoveRoutePoint(GetRouteMarkType(env, markType),
static_cast<size_t>(intermediateIndex));
}
@ -1548,30 +1494,7 @@ Java_app_organicmaps_Framework_nativeCouldAddIntermediatePoint(JNIEnv * env, jcl
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_Framework_nativeGetRoutePoints(JNIEnv * env, jclass)
{
auto const points = frm()->GetRoutingManager().GetRoutePoints();
static jclass const pointClazz = jni::GetGlobalClassRef(env,
"app/organicmaps/sdk/routing/RouteMarkData");
// Java signature : RouteMarkData(String title, String subtitle,
// @RoutePointInfo.RouteMarkType int pointType,
// int intermediateIndex, boolean isVisible, boolean isMyPosition,
// boolean isPassed, double lat, double lon)
static jmethodID const pointConstructor = jni::GetConstructorID(env, pointClazz,
"(Ljava/lang/String;Ljava/lang/String;IIZZZDD)V");
return jni::ToJavaArray(env, pointClazz, points, [&](JNIEnv * jEnv, RouteMarkData const & data)
{
jni::TScopedLocalRef const title(env, jni::ToJavaString(env, data.m_title));
jni::TScopedLocalRef const subtitle(env, jni::ToJavaString(env, data.m_subTitle));
return env->NewObject(pointClazz, pointConstructor,
title.get(), subtitle.get(),
static_cast<jint>(data.m_pointType),
static_cast<jint>(data.m_intermediateIndex),
static_cast<jboolean>(data.m_isVisible),
static_cast<jboolean>(data.m_isMyPosition),
static_cast<jboolean>(data.m_isPassed),
mercator::YToLat(data.m_position.y),
mercator::XToLon(data.m_position.x));
});
return CreateRouteMarkDataArray(env, frm()->GetRoutingManager().GetRoutePoints());
}
JNIEXPORT void JNICALL
@ -1584,49 +1507,7 @@ Java_app_organicmaps_Framework_nativeMoveRoutePoint(JNIEnv * env, jclass,
JNIEXPORT jobject JNICALL
Java_app_organicmaps_Framework_nativeGetTransitRouteInfo(JNIEnv * env, jclass)
{
auto const routeInfo = frm()->GetRoutingManager().GetTransitRouteInfo();
static jclass const transitStepClass = jni::GetGlobalClassRef(env,
"app/organicmaps/sdk/routing/TransitStepInfo");
// Java signature : TransitStepInfo(@TransitType int type, @Nullable String distance, @Nullable String distanceUnits,
// int timeInSec, @Nullable String number, int color, int intermediateIndex)
static jmethodID const transitStepConstructor = jni::GetConstructorID(env, transitStepClass,
"(ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;II)V");
jni::TScopedLocalRef const steps(env, jni::ToJavaArray(env, transitStepClass,
routeInfo.m_steps,
[&](JNIEnv * jEnv, TransitStepInfo const & stepInfo)
{
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, stepInfo.m_distanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, stepInfo.m_distanceUnitsSuffix));
jni::TScopedLocalRef const number(env, jni::ToJavaString(env, stepInfo.m_number));
return env->NewObject(transitStepClass, transitStepConstructor,
static_cast<jint>(stepInfo.m_type),
distance.get(),
distanceUnits.get(),
static_cast<jint>(stepInfo.m_timeInSec),
number.get(),
static_cast<jint>(stepInfo.m_colorARGB),
static_cast<jint>(stepInfo.m_intermediateIndex));
}));
static jclass const transitRouteInfoClass = jni::GetGlobalClassRef(env,
"app/organicmaps/sdk/routing/TransitRouteInfo");
// Java signature : TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits, int totalTimeInSec,
// @NonNull String totalPedestrianDistance, @NonNull String totalPedestrianDistanceUnits,
// int totalPedestrianTimeInSec, @NonNull TransitStepInfo[] steps)
static jmethodID const transitRouteInfoConstructor = jni::GetConstructorID(env, transitRouteInfoClass,
"(Ljava/lang/String;Ljava/lang/String;I"
"Ljava/lang/String;Ljava/lang/String;I"
"[Lapp/organicmaps/sdk/routing/TransitStepInfo;)V");
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, routeInfo.m_totalDistanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, routeInfo.m_totalDistanceUnitsSuffix));
jni::TScopedLocalRef const distancePedestrian(env, jni::ToJavaString(env, routeInfo.m_totalPedestrianDistanceStr));
jni::TScopedLocalRef const distancePedestrianUnits(env, jni::ToJavaString(env, routeInfo.m_totalPedestrianUnitsSuffix));
return env->NewObject(transitRouteInfoClass, transitRouteInfoConstructor,
distance.get(), distanceUnits.get(), static_cast<jint>(routeInfo.m_totalTimeInSec),
distancePedestrian.get(), distancePedestrianUnits.get(), static_cast<jint>(routeInfo.m_totalPedestrianTimeInSec),
steps.get());
return CreateTransitRouteInfo(env, frm()->GetRoutingManager().GetTransitRouteInfo());
}
JNIEXPORT void JNICALL

View file

@ -1,5 +1,7 @@
#include "UserMarkHelper.hpp"
#include "app/organicmaps/sdk/routing/RoutePointInfo.hpp"
#include "map/elevation_info.hpp"
#include "map/place_page_info.hpp"
@ -213,14 +215,6 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info)
routingPointInfo.get(), popularity, jrawTypes.get());
}
jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info)
{
static jclass const clazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RoutePointInfo");
static jmethodID const ctorId = jni::GetConstructorID(env, clazz, "(II)V");
int const markType = static_cast<int>(info.GetRouteMarkType());
return env->NewObject(clazz, ctorId, markType, info.GetIntermediateIndex());
}
jobject CreateFeatureId(JNIEnv * env, FeatureID const & fid)
{
static jmethodID const featureCtorId =

View file

@ -40,8 +40,6 @@ jobjectArray ToRatingArray(JNIEnv * env, std::vector<std::string> const & rating
jobject CreateLocalAdInfo(JNIEnv * env, place_page::Info const & info);
jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info);
jobject CreateFeatureId(JNIEnv * env, FeatureID const & fid);
jobjectArray ToFeatureIdArray(JNIEnv * env, std::vector<FeatureID> const & ids);
} // namespace usermark_helper

View file

@ -0,0 +1,21 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "geometry/point2d.hpp"
#include <vector>
jobjectArray CreateJunctionInfoArray(JNIEnv * env, std::vector<m2::PointD> const & junctionPoints)
{
static jclass const junctionClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/JunctionInfo");
// Java signature : JunctionInfo(double lat, double lon)
static jmethodID const junctionConstructor = jni::GetConstructorID(env, junctionClazz, "(DD)V");
return jni::ToJavaArray(env, junctionClazz, junctionPoints,
[](JNIEnv * env, m2::PointD const & point)
{
return env->NewObject(junctionClazz, junctionConstructor, mercator::YToLat(point.y),
mercator::XToLon(point.x));
});
}

View file

@ -0,0 +1,29 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "geometry/point2d.hpp"
#include <vector>
jobjectArray CreateRouteMarkDataArray(JNIEnv * env, std::vector<RouteMarkData> const & points)
{
static jclass const pointClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RouteMarkData");
// Java signature : RouteMarkData(String title, String subtitle, int pointType,
// int intermediateIndex, boolean isVisible, boolean isMyPosition,
// boolean isPassed, double lat, double lon)
static jmethodID const pointConstructor =
jni::GetConstructorID(env, pointClazz, "(Ljava/lang/String;Ljava/lang/String;IIZZZDD)V");
return jni::ToJavaArray(env, pointClazz, points,
[&](JNIEnv * jEnv, RouteMarkData const & data)
{
jni::TScopedLocalRef const title(env, jni::ToJavaString(env, data.m_title));
jni::TScopedLocalRef const subtitle(env, jni::ToJavaString(env, data.m_subTitle));
return env->NewObject(
pointClazz, pointConstructor, title.get(), subtitle.get(),
static_cast<jint>(data.m_pointType), static_cast<jint>(data.m_intermediateIndex),
static_cast<jboolean>(data.m_isVisible), static_cast<jboolean>(data.m_isMyPosition),
static_cast<jboolean>(data.m_isPassed), mercator::YToLat(data.m_position.y),
mercator::XToLon(data.m_position.x));
});
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "app/organicmaps/sdk/routing/RouteMarkType.hpp"
#include "map/routing_mark.hpp"
RouteMarkType GetRouteMarkType(JNIEnv * env, jobject markType)
{
static jmethodID const ordinal = jni::GetMethodID(env, markType, "ordinal", "()I");
return static_cast<RouteMarkType>(env->CallIntMethod(markType, ordinal));
}

View file

@ -0,0 +1,13 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "map/place_page_info.hpp"
jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info)
{
static jclass const clazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RoutePointInfo");
static jmethodID const ctorId = jni::GetConstructorID(env, clazz, "(II)V");
int const markType = static_cast<int>(info.GetRouteMarkType());
return env->NewObject(clazz, ctorId, markType, info.GetIntermediateIndex());
}

View file

@ -1,3 +1,5 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
jobject GetRebuildAfterPointsLoading(JNIEnv * env)

View file

@ -0,0 +1,34 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "app/organicmaps/sdk/routing/SingleLaneInfo.hpp"
#include "map/routing_manager.hpp"
jobject CreateRoutingInfo(JNIEnv * env, routing::FollowingInfo const & info, RoutingManager & rm)
{
static jclass const klass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RoutingInfo");
// Java signature : RoutingInfo(Distance distToTarget, Distance distToTurn,
// String currentStreet, String nextStreet, String nextNextStreet,
// double completionPercent, int vehicleTurnOrdinal, int
// vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
// int totalTime, SingleLaneInfo[] lanes)
static jmethodID const ctorRouteInfoID =
jni::GetConstructorID(env, klass,
"(Lapp/organicmaps/util/Distance;Lapp/organicmaps/util/Distance;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DIIIII"
"[Lapp/organicmaps/sdk/routing/SingleLaneInfo;DZZ)V");
jobjectArray jLanes = CreateLanesInfo(env, info.m_lanes);
auto const isSpeedCamLimitExceeded = rm.IsSpeedCamLimitExceeded();
auto const shouldPlaySignal = rm.GetSpeedCamManager().ShouldPlayBeepSignal();
jobject const result = env->NewObject(
klass, ctorRouteInfoID, ToJavaDistance(env, info.m_distToTarget), ToJavaDistance(env, info.m_distToTurn),
jni::ToJavaString(env, info.m_currentStreetName), jni::ToJavaString(env, info.m_nextStreetName),
jni::ToJavaString(env, info.m_nextNextStreetName), info.m_completionPercent, info.m_turn, info.m_nextTurn,
info.m_pedestrianTurn, info.m_exitNum, info.m_time, jLanes, info.m_speedLimitMps,
static_cast<jboolean>(isSpeedCamLimitExceeded), static_cast<jboolean>(shouldPlaySignal));
ASSERT(result, (jni::DescribeException()));
return result;
}

View file

@ -0,0 +1,34 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "routing/following_info.hpp"
#include <vector>
jobjectArray CreateLanesInfo(JNIEnv * env, std::vector<routing::FollowingInfo::SingleLaneInfoClient> const & lanes)
{
if (lanes.empty())
return nullptr;
static jclass const laneClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/SingleLaneInfo");
auto const lanesSize = static_cast<jsize>(lanes.size());
jobjectArray jLanes = env->NewObjectArray(lanesSize, laneClass, nullptr);
ASSERT(jLanes, (jni::DescribeException()));
static jmethodID const ctorSingleLaneInfoID = jni::GetConstructorID(env, laneClass, "([BZ)V");
for (jsize j = 0; j < lanesSize; ++j)
{
auto const laneSize = static_cast<jsize>(lanes[j].m_lane.size());
jni::TScopedLocalByteArrayRef singleLane(env, env->NewByteArray(laneSize));
ASSERT(singleLane.get(), (jni::DescribeException()));
env->SetByteArrayRegion(singleLane.get(), 0, laneSize, lanes[j].m_lane.data());
jni::TScopedLocalRef singleLaneInfo(
env, env->NewObject(laneClass, ctorSingleLaneInfoID, singleLane.get(), lanes[j].m_isRecommended));
ASSERT(singleLaneInfo.get(), (jni::DescribeException()));
env->SetObjectArrayElement(jLanes, j, singleLaneInfo.get());
}
return jLanes;
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "app/organicmaps/sdk/routing/TransitStepInfo.hpp"
#include "map/transit/transit_display.hpp"
jobject CreateTransitRouteInfo(JNIEnv * env, TransitRouteInfo const & routeInfo)
{
jobjectArray steps = CreateTransitStepInfoArray(env, routeInfo.m_steps);
static jclass const transitRouteInfoClass =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/TransitRouteInfo");
// Java signature : TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits,
// int totalTimeInSec, @NonNull String totalPedestrianDistance, @NonNull String
// totalPedestrianDistanceUnits, int totalPedestrianTimeInSec, @NonNull
// TransitStepInfo[] steps)
static jmethodID const transitRouteInfoConstructor =
jni::GetConstructorID(env, transitRouteInfoClass,
"(Ljava/lang/String;Ljava/lang/String;I"
"Ljava/lang/String;Ljava/lang/String;I"
"[Lapp/organicmaps/sdk/routing/TransitStepInfo;)V");
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, routeInfo.m_totalDistanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, routeInfo.m_totalDistanceUnitsSuffix));
jni::TScopedLocalRef const distancePedestrian(env, jni::ToJavaString(env, routeInfo.m_totalPedestrianDistanceStr));
jni::TScopedLocalRef const distancePedestrianUnits(env,
jni::ToJavaString(env, routeInfo.m_totalPedestrianUnitsSuffix));
return env->NewObject(transitRouteInfoClass, transitRouteInfoConstructor, distance.get(), distanceUnits.get(),
static_cast<jint>(routeInfo.m_totalTimeInSec), distancePedestrian.get(),
distancePedestrianUnits.get(), static_cast<jint>(routeInfo.m_totalPedestrianTimeInSec), steps);
}

View file

@ -0,0 +1,28 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "map/transit/transit_display.hpp"
#include <vector>
jobjectArray CreateTransitStepInfoArray(JNIEnv * env, std::vector<TransitStepInfo> const & steps)
{
static jclass const transitStepClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/TransitStepInfo");
// Java signature : TransitStepInfo(int type, @Nullable String distance, @Nullable String distanceUnits,
// int timeInSec, @Nullable String number, int color, int intermediateIndex)
static jmethodID const transitStepConstructor =
jni::GetConstructorID(env, transitStepClass, "(ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;II)V");
return jni::ToJavaArray(
env, transitStepClass, steps,
[&](JNIEnv * jEnv, TransitStepInfo const & stepInfo)
{
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, stepInfo.m_distanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, stepInfo.m_distanceUnitsSuffix));
jni::TScopedLocalRef const number(env, jni::ToJavaString(env, stepInfo.m_number));
return env->NewObject(transitStepClass, transitStepConstructor, static_cast<jint>(stepInfo.m_type),
distance.get(), distanceUnits.get(), static_cast<jint>(stepInfo.m_timeInSec), number.get(),
static_cast<jint>(stepInfo.m_colorARGB), static_cast<jint>(stepInfo.m_intermediateIndex));
});
}

View file

@ -16,7 +16,7 @@ import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.products.ProductsConfig;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.PlacePageActivationListener;
@ -235,15 +235,14 @@ public class Framework
point.mIntermediateIndex, point.mIsMyPosition,
point.mLat, point.mLon);
}
public static native void nativeAddRoutePoint(String title, String subtitle,
@RoutePointInfo.RouteMarkType int markType,
public static native void nativeAddRoutePoint(String title, String subtitle, @NonNull RouteMarkType markType,
int intermediateIndex, boolean isMyPosition,
double lat, double lon);
public static native void nativeRemoveRoutePoints();
public static native void nativeRemoveRoutePoint(@RoutePointInfo.RouteMarkType int markType,
int intermediateIndex);
public static native void nativeRemoveRoutePoint(@NonNull RouteMarkType markType, int intermediateIndex);
public static native void nativeRemoveIntermediateRoutePoints();

View file

@ -79,6 +79,7 @@ import app.organicmaps.maplayer.isolines.IsolinesState;
import app.organicmaps.routing.ManageRouteBottomSheet;
import app.organicmaps.routing.NavigationController;
import app.organicmaps.routing.NavigationService;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.routing.RoutingBottomMenuListener;
import app.organicmaps.routing.RoutingController;
@ -2135,7 +2136,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
@Override
public void onSearchRoutePoint(@RoutePointInfo.RouteMarkType int pointType)
public void onSearchRoutePoint(@NonNull RouteMarkType pointType)
{
RoutingController.get().waitForPoiPick(pointType);
closeSearchToolbar(true, true);

View file

@ -8,8 +8,8 @@ import androidx.car.app.navigation.model.LaneDirection;
import androidx.car.app.navigation.model.Maneuver;
import androidx.core.graphics.drawable.IconCompat;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.SingleLaneInfo;
import app.organicmaps.sdk.routing.CarDirection;
import app.organicmaps.sdk.routing.LaneWay;
public final class RoutingHelpers
{
@ -30,7 +30,7 @@ public final class RoutingHelpers
}
@NonNull
public static LaneDirection createLaneDirection(@NonNull SingleLaneInfo.LaneWay laneWay, boolean isRecommended)
public static LaneDirection createLaneDirection(@NonNull LaneWay laneWay, boolean isRecommended)
{
int shape = LaneDirection.SHAPE_UNKNOWN;
switch (laneWay)
@ -67,7 +67,7 @@ public final class RoutingHelpers
}
@NonNull
public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull RoutingInfo.CarDirection carDirection, int roundaboutExitNum)
public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull CarDirection carDirection, int roundaboutExitNum)
{
int maneuverType = switch (carDirection)
{

View file

@ -15,6 +15,7 @@ import androidx.car.app.navigation.model.Trip;
import androidx.core.graphics.drawable.IconCompat;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.LaneWay;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.SingleLaneInfo;
import app.organicmaps.util.Graphics;
@ -71,7 +72,7 @@ public final class RoutingUtils
for (final SingleLaneInfo laneInfo : info.lanes)
{
final Lane.Builder laneBuilder = new Lane.Builder();
for (final SingleLaneInfo.LaneWay laneWay : laneInfo.mLane)
for (final LaneWay laneWay : laneInfo.mLane)
laneBuilder.addDirection(RoutingHelpers.createLaneDirection(laneWay, laneInfo.mIsActive));
builder.addLane(laneBuilder.build());
}

View file

@ -18,6 +18,7 @@ import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.util.StringUtils;
import app.organicmaps.util.UiUtils;
@ -67,21 +68,21 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
switch (mRoutePoints.get(position).mPointType)
{
case RoutePointInfo.ROUTE_MARK_START: // Starting point.
case Start: // Starting point.
if (mRoutePoints.get(position).mIsMyPosition)
iconId = R.drawable.ic_location_arrow_blue;
else
iconId = R.drawable.route_point_start;
break;
case RoutePointInfo.ROUTE_MARK_INTERMEDIATE: // Intermediate stop.
case Intermediate: // Intermediate stop.
TypedArray iconArray = mContext.getResources().obtainTypedArray(R.array.route_stop_icons);
iconId = iconArray.getResourceId(mRoutePoints.get(position).mIntermediateIndex,
R.drawable.route_point_20);
iconArray.recycle();
break;
case RoutePointInfo.ROUTE_MARK_FINISH: // Destination point.
case Finish: // Destination point.
iconId = R.drawable.route_point_finish;
break;
@ -101,7 +102,7 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
// My position point.
title = mContext.getString(R.string.core_my_position);
if (mRoutePoints.get(position).mPointType != RoutePointInfo.ROUTE_MARK_START)
if (mRoutePoints.get(position).mPointType != RouteMarkType.Start)
subtitle = mRoutePoints.get(position).mTitle;
else
{
@ -182,7 +183,7 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
myLocation.getLon());
// Replace route point in first position with 'My Position".
mRoutePoints.set(0, new RouteMarkData(latLonString, "", RoutePointInfo.ROUTE_MARK_START,
mRoutePoints.set(0, new RouteMarkData(latLonString, "", RouteMarkType.Start,
0, true, true, false, myLocation.getLat(),
myLocation.getLon()));
@ -219,15 +220,15 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
assert(mRoutePoints.size() >= 2);
// Set starting point.
mRoutePoints.get(0).mPointType = RoutePointInfo.ROUTE_MARK_START;
mRoutePoints.get(0).mPointType = RouteMarkType.Start;
// Set finish point.
mRoutePoints.get(mRoutePoints.size() - 1).mPointType = RoutePointInfo.ROUTE_MARK_FINISH;
mRoutePoints.get(mRoutePoints.size() - 1).mPointType = RouteMarkType.Finish;
// Set intermediate point(s).
for (int pos = 1; pos < mRoutePoints.size() - 1; pos++)
{
mRoutePoints.get(pos).mPointType = RoutePointInfo.ROUTE_MARK_INTERMEDIATE;
mRoutePoints.get(pos).mPointType = RouteMarkType.Intermediate;
mRoutePoints.get(pos).mIntermediateIndex = pos - 1;
}
}

View file

@ -19,6 +19,7 @@ import app.organicmaps.location.LocationHelper;
import app.organicmaps.maplayer.MapButtonsViewModel;
import app.organicmaps.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.routing.CarDirection;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.util.StringUtils;
import app.organicmaps.util.UiUtils;
@ -114,7 +115,7 @@ public class NavigationController implements TrafficManager.TrafficCallback,
mNextTurnDistance.setText(Utils.formatDistance(mFrame.getContext(), info.distToTurn));
info.carDirection.setTurnDrawable(mNextTurnImage);
if (RoutingInfo.CarDirection.isRoundAbout(info.carDirection))
if (CarDirection.isRoundAbout(info.carDirection))
UiUtils.setTextAndShow(mCircleExit, String.valueOf(info.exitNum));
else
UiUtils.hide(mCircleExit);

View file

@ -33,6 +33,7 @@ import app.organicmaps.R;
import app.organicmaps.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.TransitRouteInfo;
@ -256,7 +257,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
UiUtils.hide(mError, mTransitFrame);
UiUtils.show(mActionFrame);
mActionMessage.setText(R.string.routing_add_start_point);
mActionMessage.setTag(RoutePointInfo.ROUTE_MARK_START);
mActionMessage.setTag(RouteMarkType.Start);
if (LocationHelper.from(mContext).getMyPosition() != null)
{
UiUtils.show(mActionButton);
@ -276,7 +277,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
UiUtils.hide(mError, mTransitFrame);
UiUtils.show(mActionFrame);
mActionMessage.setText(R.string.routing_add_finish_point);
mActionMessage.setTag(RoutePointInfo.ROUTE_MARK_FINISH);
mActionMessage.setTag(RouteMarkType.Finish);
UiUtils.hide(mActionButton);
}
@ -488,8 +489,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
mListener.onUseMyPositionAsStart();
else if (id == R.id.btn__search_point && mListener != null)
{
@RoutePointInfo.RouteMarkType
int pointType = (Integer) mActionMessage.getTag();
final RouteMarkType pointType = (RouteMarkType) mActionMessage.getTag();
mListener.onSearchRoutePoint(pointType);
}
else if (id == R.id.btn__manage_route && mListener != null)

View file

@ -1,11 +1,13 @@
package app.organicmaps.routing;
import app.organicmaps.sdk.routing.RoutePointInfo;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.routing.RouteMarkType;
public interface RoutingBottomMenuListener
{
void onUseMyPositionAsStart();
void onSearchRoutePoint(@RoutePointInfo.RouteMarkType int type);
void onSearchRoutePoint(@NonNull RouteMarkType type);
void onRoutingStart();
void onManageRouteOpen();
}

View file

@ -18,6 +18,7 @@ import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RouteRecommendationType;
import app.organicmaps.sdk.routing.RoutingInfo;
@ -81,7 +82,6 @@ public class RoutingController
default void onStartRouteBuilding() {}
}
private static final int NO_WAITING_POI_PICK = -1;
private static final RoutingController sInstance = new RoutingController();
@Nullable
@ -89,8 +89,8 @@ public class RoutingController
private BuildState mBuildState = BuildState.NONE;
private State mState = State.NONE;
//@RoutePointInfo.RouteMarkType
private int mWaitingPoiPickType = NO_WAITING_POI_PICK;
@Nullable
private RouteMarkType mWaitingPoiPickType = null;
private int mLastBuildProgress;
private Router mLastRouterType;
@ -385,7 +385,7 @@ public class RoutingController
public void addStop(@NonNull MapObject mapObject)
{
addRoutePoint(RoutePointInfo.ROUTE_MARK_INTERMEDIATE, mapObject);
addRoutePoint(RouteMarkType.Intermediate, mapObject);
build();
if (mContainer != null)
mContainer.onAddedStop();
@ -464,8 +464,7 @@ public class RoutingController
{
Logger.d(TAG, "cancelInternal");
//noinspection WrongConstant
mWaitingPoiPickType = NO_WAITING_POI_PICK;
mWaitingPoiPickType = null;
setBuildState(BuildState.NONE);
setState(State.NONE);
@ -594,13 +593,13 @@ public class RoutingController
return mBuildState == BuildState.BUILT;
}
public void waitForPoiPick(@RoutePointInfo.RouteMarkType int pointType){
public void waitForPoiPick(@NonNull RouteMarkType pointType){
mWaitingPoiPickType = pointType;
}
public boolean isWaitingPoiPick()
{
return mWaitingPoiPickType != NO_WAITING_POI_PICK;
return mWaitingPoiPickType != null;
}
public BuildState getBuildState()
@ -611,17 +610,17 @@ public class RoutingController
@Nullable
public MapObject getStartPoint()
{
return getStartOrEndPointByType(RoutePointInfo.ROUTE_MARK_START);
return getStartOrEndPointByType(RouteMarkType.Start);
}
@Nullable
public MapObject getEndPoint()
{
return getStartOrEndPointByType(RoutePointInfo.ROUTE_MARK_FINISH);
return getStartOrEndPointByType(RouteMarkType.Finish);
}
@Nullable
private MapObject getStartOrEndPointByType(@RoutePointInfo.RouteMarkType int type)
private MapObject getStartOrEndPointByType(@NonNull RouteMarkType type)
{
RouteMarkData[] points = Framework.nativeGetRoutePoints();
int size = points.length;
@ -635,9 +634,9 @@ public class RoutingController
return point.mPointType == type ? toMapObject(point) : null;
}
if (type == RoutePointInfo.ROUTE_MARK_START)
if (type == RouteMarkType.Start)
return toMapObject(points[0]);
if (type == RoutePointInfo.ROUTE_MARK_FINISH)
if (type == RouteMarkType.Finish)
return toMapObject(points[size - 1]);
return null;
@ -665,10 +664,10 @@ public class RoutingController
applyRemovingIntermediatePointsTransaction();
if (hasStart)
addRoutePoint(RoutePointInfo.ROUTE_MARK_START , startPoint);
addRoutePoint(RouteMarkType.Start, startPoint);
if (hasEnd)
addRoutePoint(RoutePointInfo.ROUTE_MARK_FINISH , endPoint);
addRoutePoint(RouteMarkType.Finish, endPoint);
if (hasOnePointAtLeast && mContainer != null)
mContainer.updateMenu();
@ -703,7 +702,7 @@ public class RoutingController
if (point != null)
{
applyRemovingIntermediatePointsTransaction();
addRoutePoint(RoutePointInfo.ROUTE_MARK_START, point);
addRoutePoint(RouteMarkType.Start, point);
startPoint = getStartPoint();
}
@ -752,7 +751,7 @@ public class RoutingController
{
applyRemovingIntermediatePointsTransaction();
addRoutePoint(RoutePointInfo.ROUTE_MARK_FINISH, point);
addRoutePoint(RouteMarkType.Finish, point);
endPoint = getEndPoint();
}
@ -773,7 +772,7 @@ public class RoutingController
return true;
}
private static void addRoutePoint(@RoutePointInfo.RouteMarkType int type, @NonNull MapObject point)
private static void addRoutePoint(@NonNull RouteMarkType type, @NonNull MapObject point)
{
Pair<String, String> description = getDescriptionForPoint(point);
Framework.nativeAddRoutePoint(description.first /* title */, description.second /* subtitle */,
@ -871,15 +870,12 @@ public class RoutingController
if (!isWaitingPoiPick())
return;
if (mWaitingPoiPickType != RoutePointInfo.ROUTE_MARK_FINISH
&& mWaitingPoiPickType != RoutePointInfo.ROUTE_MARK_START)
{
if (mWaitingPoiPickType != RouteMarkType.Start && mWaitingPoiPickType != RouteMarkType.Finish)
throw new AssertionError("Only start and finish points can be added through search!");
}
if (point != null)
{
if (mWaitingPoiPickType == RoutePointInfo.ROUTE_MARK_FINISH)
if (mWaitingPoiPickType == RouteMarkType.Finish)
setEndPoint(point);
else
setStartPoint(point);
@ -891,8 +887,7 @@ public class RoutingController
showRoutePlan();
}
//noinspection WrongConstant
mWaitingPoiPickType = NO_WAITING_POI_PICK;
mWaitingPoiPickType = null;
}
public static CharSequence formatRoutingTime(Context context, int seconds, @DimenRes int unitsSize)
{

View file

@ -0,0 +1,73 @@
package app.organicmaps.sdk.routing;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.R;
/**
* IMPORTANT : Order of enum values MUST BE the same as native CarDirection enum.
*/
public enum CarDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_SHARP_RIGHT(R.drawable.ic_turn_right_sharp, R.drawable.ic_then_right_sharp),
TURN_SLIGHT_RIGHT(R.drawable.ic_turn_right_slight, R.drawable.ic_then_right_slight),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
TURN_SHARP_LEFT(R.drawable.ic_turn_left_sharp, R.drawable.ic_then_left_sharp),
TURN_SLIGHT_LEFT(R.drawable.ic_turn_left_slight, R.drawable.ic_then_left_slight),
U_TURN_LEFT(R.drawable.ic_turn_uleft, R.drawable.ic_then_uleft),
U_TURN_RIGHT(R.drawable.ic_turn_uright, R.drawable.ic_then_uright),
ENTER_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
LEAVE_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
STAY_ON_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
START_AT_THE_END_OF_STREET(0, 0),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish),
EXIT_HIGHWAY_TO_LEFT(R.drawable.ic_exit_highway_to_left, R.drawable.ic_then_exit_highway_to_left),
EXIT_HIGHWAY_TO_RIGHT(R.drawable.ic_exit_highway_to_right, R.drawable.ic_then_exit_highway_to_right);
private final int mTurnRes;
private final int mNextTurnRes;
CarDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public int getTurnRes()
{
return mTurnRes;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
public static boolean isRoundAbout(CarDirection turn)
{
return turn == ENTER_ROUND_ABOUT || turn == LEAVE_ROUND_ABOUT || turn == STAY_ON_ROUND_ABOUT;
}
}

View file

@ -10,7 +10,7 @@ public final class JunctionInfo
public final double mLat;
public final double mLon;
public JunctionInfo(double lat, double lon)
private JunctionInfo(double lat, double lon)
{
mLat = lat;
mLon = lon;

View file

@ -0,0 +1,33 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.DrawableRes;
import app.organicmaps.R;
/**
* IMPORTANT : Order of enum values MUST BE the same
* with native LaneWay enum (see routing/turns.hpp for details).
* Information for every lane is composed of some number values below.
* For example, a lane may have THROUGH and RIGHT values.
*/
public enum LaneWay
{
NONE(R.drawable.ic_turn_straight),
REVERSE(R.drawable.ic_turn_uleft),
SHARP_LEFT(R.drawable.ic_turn_left_sharp),
LEFT(R.drawable.ic_turn_left),
SLIGHT_LEFT(R.drawable.ic_turn_left_slight),
MERGE_TO_RIGHT(R.drawable.ic_turn_right_slight),
THROUGH(R.drawable.ic_turn_straight),
MERGE_TO_LEFT(R.drawable.ic_turn_left_slight),
SLIGHT_RIGHT(R.drawable.ic_turn_right_slight),
RIGHT(R.drawable.ic_turn_right),
SHARP_RIGHT(R.drawable.ic_turn_right_sharp);
public final int mTurnRes;
LaneWay(@DrawableRes int turnRes)
{
mTurnRes = turnRes;
}
}

View file

@ -0,0 +1,44 @@
package app.organicmaps.sdk.routing;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.R;
public enum PedestrianTurnDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish);
private final int mTurnRes;
private final int mNextTurnRes;
PedestrianTurnDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
}

View file

@ -15,8 +15,7 @@ public final class RouteMarkData
public final String mTitle;
@Nullable
public final String mSubtitle;
@RoutePointInfo.RouteMarkType
public int mPointType;
public RouteMarkType mPointType;
public int mIntermediateIndex;
public final boolean mIsVisible;
public final boolean mIsMyPosition;
@ -24,10 +23,16 @@ public final class RouteMarkData
public final double mLat;
public final double mLon;
private RouteMarkData(@Nullable String title, @Nullable String subtitle,
int pointType, int intermediateIndex, boolean isVisible,
boolean isMyPosition, boolean isPassed, double lat, double lon)
{
this(title, subtitle, RouteMarkType.values()[pointType], intermediateIndex, isVisible, isMyPosition, isPassed, lat, lon);
}
public RouteMarkData(@Nullable String title, @Nullable String subtitle,
@RoutePointInfo.RouteMarkType int pointType,
int intermediateIndex, boolean isVisible, boolean isMyPosition,
boolean isPassed, double lat, double lon)
RouteMarkType pointType, int intermediateIndex, boolean isVisible,
boolean isMyPosition, boolean isPassed, double lat, double lon)
{
mTitle = title;
mSubtitle = subtitle;

View file

@ -0,0 +1,8 @@
package app.organicmaps.sdk.routing;
public enum RouteMarkType
{
Start,
Intermediate,
Finish
}

View file

@ -3,11 +3,8 @@ package app.organicmaps.sdk.routing;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import androidx.annotation.NonNull;
// Called from JNI.
@Keep
@ -29,44 +26,35 @@ public final class RoutePointInfo implements Parcelable
}
};
public static final int ROUTE_MARK_START = 0;
public static final int ROUTE_MARK_INTERMEDIATE = 1;
public static final int ROUTE_MARK_FINISH = 2;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ ROUTE_MARK_START, ROUTE_MARK_INTERMEDIATE, ROUTE_MARK_FINISH })
public @interface RouteMarkType {}
@RouteMarkType
public final int mMarkType;
public final RouteMarkType mMarkType;
public final int mIntermediateIndex;
public RoutePointInfo(@RouteMarkType int markType, int intermediateIndex)
private RoutePointInfo(@NonNull RouteMarkType markType, int intermediateIndex)
{
mMarkType = markType;
mIntermediateIndex = intermediateIndex;
}
private RoutePointInfo(Parcel in)
private RoutePointInfo(@NonNull Parcel in)
{
//noinspection WrongConstant
this(in.readInt() /* mMarkType */, in.readInt() /* mIntermediateIndex */);
this(RouteMarkType.values()[in.readInt()] /* mMarkType */, in.readInt() /* mIntermediateIndex */);
}
boolean isIntermediatePoint()
{
return mMarkType == ROUTE_MARK_INTERMEDIATE;
return mMarkType == RouteMarkType.Intermediate;
}
boolean isFinishPoint()
{
return mMarkType == ROUTE_MARK_FINISH;
return mMarkType == RouteMarkType.Finish;
}
boolean isStartPoint()
{
return mMarkType == ROUTE_MARK_START;
return mMarkType == RouteMarkType.Start;
}
@Override
@ -78,7 +66,7 @@ public final class RoutePointInfo implements Parcelable
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mMarkType);
dest.writeInt(mMarkType.ordinal());
dest.writeInt(mIntermediateIndex);
}
}

View file

@ -1,12 +1,7 @@
package app.organicmaps.sdk.routing;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.R;
import app.organicmaps.util.Distance;
// Called from JNI.
@ -40,108 +35,7 @@ public final class RoutingInfo
private final boolean speedCamLimitExceeded;
private final boolean shouldPlayWarningSignal;
/**
* IMPORTANT : Order of enum values MUST BE the same as native CarDirection enum.
*/
public enum CarDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_SHARP_RIGHT(R.drawable.ic_turn_right_sharp, R.drawable.ic_then_right_sharp),
TURN_SLIGHT_RIGHT(R.drawable.ic_turn_right_slight, R.drawable.ic_then_right_slight),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
TURN_SHARP_LEFT(R.drawable.ic_turn_left_sharp, R.drawable.ic_then_left_sharp),
TURN_SLIGHT_LEFT(R.drawable.ic_turn_left_slight, R.drawable.ic_then_left_slight),
U_TURN_LEFT(R.drawable.ic_turn_uleft, R.drawable.ic_then_uleft),
U_TURN_RIGHT(R.drawable.ic_turn_uright, R.drawable.ic_then_uright),
ENTER_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
LEAVE_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
STAY_ON_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
START_AT_THE_END_OF_STREET(0, 0),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish),
EXIT_HIGHWAY_TO_LEFT(R.drawable.ic_exit_highway_to_left, R.drawable.ic_then_exit_highway_to_left),
EXIT_HIGHWAY_TO_RIGHT(R.drawable.ic_exit_highway_to_right, R.drawable.ic_then_exit_highway_to_right);
private final int mTurnRes;
private final int mNextTurnRes;
CarDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public int getTurnRes()
{
return mTurnRes;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
public static boolean isRoundAbout(CarDirection turn)
{
return turn == ENTER_ROUND_ABOUT || turn == LEAVE_ROUND_ABOUT || turn == STAY_ON_ROUND_ABOUT;
}
}
public enum PedestrianTurnDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish);
private final int mTurnRes;
private final int mNextTurnRes;
PedestrianTurnDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
}
public RoutingInfo(Distance distToTarget, Distance distToTurn, String currentStreet, String nextStreet, String nextNextStreet, double completionPercent,
private RoutingInfo(Distance distToTarget, Distance distToTurn, String currentStreet, String nextStreet, String nextNextStreet, double completionPercent,
int vehicleTurnOrdinal, int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
int totalTime, SingleLaneInfo[] lanes, double speedLimitMps, boolean speedLimitExceeded,
boolean shouldPlayWarningSignal)

View file

@ -46,6 +46,10 @@ public final class RoutingOptions
return roadTypes;
}
private RoutingOptions() throws IllegalAccessException
{
throw new IllegalAccessException("RoutingOptions is a utility class and should not be instantiated");
}
private static native void nativeAddOption(int option);
private static native void nativeRemoveOption(int option);

View file

@ -1,43 +1,12 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.R;
public final class SingleLaneInfo
{
public LaneWay[] mLane;
public boolean mIsActive;
/**
* IMPORTANT : Order of enum values MUST BE the same
* with native LaneWay enum (see routing/turns.hpp for details).
* Information for every lane is composed of some number values below.
* For example, a lane may have THROUGH and RIGHT values.
*/
public enum LaneWay
{
NONE(R.drawable.ic_turn_straight),
REVERSE(R.drawable.ic_turn_uleft),
SHARP_LEFT(R.drawable.ic_turn_left_sharp),
LEFT(R.drawable.ic_turn_left),
SLIGHT_LEFT(R.drawable.ic_turn_left_slight),
MERGE_TO_RIGHT(R.drawable.ic_turn_right_slight),
THROUGH(R.drawable.ic_turn_straight),
MERGE_TO_LEFT(R.drawable.ic_turn_left_slight),
SLIGHT_RIGHT(R.drawable.ic_turn_right_slight),
RIGHT(R.drawable.ic_turn_right),
SHARP_RIGHT(R.drawable.ic_turn_right_sharp);
public final int mTurnRes;
LaneWay(@DrawableRes int turnRes)
{
mTurnRes = turnRes;
}
}
public SingleLaneInfo(@NonNull byte[] laneOrdinals, boolean isActive)
{
mLane = new LaneWay[laneOrdinals.length];

View file

@ -28,7 +28,7 @@ public final class TransitRouteInfo
@NonNull
private final TransitStepInfo[] mSteps;
public TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits, int totalTimeInSec,
private TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits, int totalTimeInSec,
@NonNull String totalPedestrianDistance, @NonNull String totalPedestrianDistanceUnits,
int totalPedestrianTimeInSec, @NonNull TransitStepInfo[] steps)
{

View file

@ -1,13 +1,9 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Represents TransitStepInfo from core.
*/
@ -16,19 +12,6 @@ import java.lang.annotation.RetentionPolicy;
@SuppressWarnings("unused")
public final class TransitStepInfo
{
private static final int TRANSIT_TYPE_INTERMEDIATE_POINT = 0;
private static final int TRANSIT_TYPE_PEDESTRIAN = 1;
private static final int TRANSIT_TYPE_SUBWAY = 2;
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_RULER})
@interface TransitType {}
@NonNull
private final TransitStepType mType;
@Nullable
@ -41,8 +24,8 @@ public final class TransitStepInfo
private final int mColor;
private final int mIntermediateIndex;
TransitStepInfo(@TransitType int type, @Nullable String distance, @Nullable String distanceUnits,
int timeInSec, @Nullable String number, int color, int intermediateIndex)
private TransitStepInfo(int type, @Nullable String distance, @Nullable String distanceUnits,
int timeInSec, @Nullable String number, int color, int intermediateIndex)
{
mType = TransitStepType.values()[type];
mDistance = distance;
@ -56,13 +39,13 @@ public final class TransitStepInfo
@NonNull
public static TransitStepInfo intermediatePoint(int intermediateIndex)
{
return new TransitStepInfo(TRANSIT_TYPE_INTERMEDIATE_POINT, null, null, 0, null, 0, intermediateIndex);
return new TransitStepInfo(TransitStepType.INTERMEDIATE_POINT.ordinal(), 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);
return new TransitStepInfo(TransitStepType.RULER.ordinal(), distance, distanceUnits, 0, null, 0, -1);
}
@NonNull