From bd48ca3ad027be0f96f7e9fd8d466767a453e2ea Mon Sep 17 00:00:00 2001 From: Roman Kuznetsov Date: Sat, 10 Jun 2017 16:07:57 +0300 Subject: [PATCH 1/2] [Android] Added interface for new routing points methods --- android/jni/com/mapswithme/maps/Framework.cpp | 73 +++++++++++++++--- .../com/mapswithme/maps/UserMarkHelper.cpp | 73 ++++++++++++------ .../com/mapswithme/maps/UserMarkHelper.hpp | 5 +- .../src/com/mapswithme/maps/Framework.java | 15 +++- .../src/com/mapswithme/maps/MwmActivity.java | 11 +-- .../maps/bookmarks/data/Bookmark.java | 13 ++-- .../maps/bookmarks/data/MapObject.java | 25 +++++-- .../maps/location/LocationHelper.java | 2 +- .../maps/routing/RoutePointInfo.java | 75 +++++++++++++++++++ .../maps/routing/RoutingController.java | 42 ++++++++--- .../maps/search/SearchFragment.java | 2 +- map/routing_mark.hpp | 8 +- 12 files changed, 275 insertions(+), 69 deletions(-) create mode 100644 android/src/com/mapswithme/maps/routing/RoutePointInfo.java diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 94b39a2db7..820bbe091f 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -923,6 +923,12 @@ Java_com_mapswithme_maps_Framework_nativeBuildRoute(JNIEnv * env, jclass, 0 /* timeoutSec */); } +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_Framework_nativeRemoveRoute(JNIEnv * env, jclass) +{ + frm()->GetRoutingManager().RemoveRoute(false /* deactivateFollowing */); +} + JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeFollowRoute(JNIEnv * env, jclass) { @@ -1137,26 +1143,75 @@ Java_com_mapswithme_maps_Framework_nativeGetLastUsedRouter(JNIEnv * env, jclass) } JNIEXPORT jint JNICALL -Java_com_mapswithme_maps_Framework_nativeGetBestRouter(JNIEnv * env, jclass, jdouble srcLat, jdouble srcLon, jdouble dstLat, jdouble dstLon) +Java_com_mapswithme_maps_Framework_nativeGetBestRouter(JNIEnv * env, jclass, + jdouble srcLat, jdouble srcLon, + jdouble dstLat, jdouble dstLon) { return static_cast(frm()->GetRoutingManager().GetBestRouter( MercatorBounds::FromLatLon(srcLat, srcLon), MercatorBounds::FromLatLon(dstLat, dstLon))); } -JNIEXPORT void JNICALL -Java_com_mapswithme_maps_Framework_nativeSetRouteStartPoint(JNIEnv * env, jclass, jdouble lat, jdouble lon, jboolean valid) +void ExtractRoutePointInfo(JNIEnv * env, jobject routePointInfo, + RouteMarkType & markType, int8_t & intermediateIndex) { - frm()->GetRoutingManager().RemoveRoutePoint(RouteMarkType::Start); - frm()->GetRoutingManager().AddRoutePoint(m2::PointD(MercatorBounds::FromLatLon(lat, lon)), - static_cast(!valid), RouteMarkType::Start); + jclass const clazz = env->GetObjectClass(routePointInfo); + ASSERT(clazz, ()); + static jfieldID const markTypeField = env->GetFieldID(clazz, "mMarkType", "I"); + ASSERT(markTypeField, ()); + static jfieldID const intermediateIndexField = env->GetFieldID(clazz, "mIntermediateIndex", "I"); + ASSERT(intermediateIndexField, ()); + markType = static_cast(env->GetIntField(routePointInfo, markTypeField)); + intermediateIndex = static_cast(env->GetIntField(routePointInfo, intermediateIndexField)); } JNIEXPORT void JNICALL -Java_com_mapswithme_maps_Framework_nativeSetRouteEndPoint(JNIEnv * env, jclass, jdouble lat, jdouble lon, jboolean valid) +Java_com_mapswithme_maps_Framework_nativeAddRoutePoint(JNIEnv * env, jclass, + jdouble lat, jdouble lon, + jboolean isMyPosition, + jobject routePointInfo) { - frm()->GetRoutingManager().RemoveRoutePoint(RouteMarkType::Finish); + RouteMarkType markType; + int8_t intermediateIndex; + ExtractRoutePointInfo(env, routePointInfo, markType, intermediateIndex); + frm()->GetRoutingManager().AddRoutePoint(m2::PointD(MercatorBounds::FromLatLon(lat, lon)), - static_cast(!valid), RouteMarkType::Finish); + static_cast(isMyPosition), + markType, intermediateIndex); +} + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_Framework_nativeRemoveRoutePoint(JNIEnv * env, jclass, + jobject routePointInfo) +{ + RouteMarkType markType; + int8_t intermediateIndex; + ExtractRoutePointInfo(env, routePointInfo, markType, intermediateIndex); + + frm()->GetRoutingManager().RemoveRoutePoint(markType, intermediateIndex); +} + +JNIEXPORT jboolean JNICALL +Java_com_mapswithme_maps_Framework_nativeCouldAddIntermediatePoint(JNIEnv * env, jclass) +{ + return frm()->GetRoutingManager().CouldAddIntermediatePoint(); +} + +JNIEXPORT jobjectArray JNICALL +Java_com_mapswithme_maps_Framework_nativeGetRoutePoints(JNIEnv * env, jclass) +{ + std::vector const points = frm()->GetRoutingManager().GetRoutePoints(); + + static jclass const pointClazz = jni::GetGlobalClassRef(env, "com/mapswithme/maps/api/RoutePoint"); + // Java signature : RoutePoint(double lat, double lon, String name) + static jmethodID const pointConstructor = jni::GetConstructorID(env, pointClazz, + "(DDLjava/lang/String;)V"); + return jni::ToJavaArray(env, pointClazz, points, [&](JNIEnv * env, m2::PointD const & pt) + { + jni::TScopedLocalRef const name(env, jni::ToJavaString(env, "")); + return env->NewObject(pointClazz, pointConstructor, + MercatorBounds::YToLat(pt.y), + MercatorBounds::XToLon(pt.x), name.get()); + }); } JNIEXPORT void JNICALL diff --git a/android/jni/com/mapswithme/maps/UserMarkHelper.cpp b/android/jni/com/mapswithme/maps/UserMarkHelper.cpp index dfc6303ac1..7ee1297db5 100644 --- a/android/jni/com/mapswithme/maps/UserMarkHelper.cpp +++ b/android/jni/com/mapswithme/maps/UserMarkHelper.cpp @@ -40,19 +40,22 @@ jobject CreateMapObject(JNIEnv * env, string const & mwmName, int64_t mwmVersion string const & secondaryTitle, string const & subtitle, double lat, double lon, string const & address, Metadata const & metadata, string const & apiId, jobjectArray jbanners, bool isReachableByTaxi, - string const & bookingSearchUrl, jobject const & localAdInfo) + string const & bookingSearchUrl, jobject const & localAdInfo, + jobject const & routingPointInfo) { // public MapObject(@NonNull String mwmName, long mwmVersion, int featureIndex, - // @MapObjectType int mapObjectType, String title, String secondaryTitle, - // String subtitle, double lat, double lon, String address, String apiId, - // @NonNull Banner banner, boolean reachableByTaxi, - // @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo) + // @MapObjectType int mapObjectType, String title, @Nullable String secondaryTitle, + // String subtitle, String address, double lat, double lon, String apiId, + // @Nullable Banner[] banners, boolean reachableByTaxi, + // @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo, + // @Nullable RoutePointInfo routePointInfo) static jmethodID const ctorId = jni::GetConstructorID(env, g_mapObjectClazz, "(Ljava/lang/String;JIILjava/lang/String;Ljava/lang/" "String;Ljava/lang/String;Ljava/lang/String;DDLjava/lang/" "String;[Lcom/mapswithme/maps/ads/Banner;ZLjava/lang/String;" - "Lcom/mapswithme/maps/ads/LocalAdInfo;)V"); + "Lcom/mapswithme/maps/ads/LocalAdInfo;" + "Lcom/mapswithme/maps/routing/RoutePointInfo;)V"); jni::TScopedLocalRef jMwmName(env, jni::ToJavaString(env, mwmName)); jni::TScopedLocalRef jTitle(env, jni::ToJavaString(env, title)); @@ -63,8 +66,9 @@ jobject CreateMapObject(JNIEnv * env, string const & mwmName, int64_t mwmVersion jni::TScopedLocalRef jBookingSearchUrl(env, jni::ToJavaString(env, bookingSearchUrl)); jobject mapObject = env->NewObject( g_mapObjectClazz, ctorId, jMwmName.get(), (jlong)mwmVersion, (jint)featureIndex, - mapObjectType, jTitle.get(), jSecondaryTitle.get(), jSubtitle.get(), jAddress.get(), lat, lon, - jApiId.get(), jbanners, isReachableByTaxi, jBookingSearchUrl.get(), localAdInfo); + mapObjectType, jTitle.get(), jSecondaryTitle.get(), jSubtitle.get(), jAddress.get(), + lat, lon, jApiId.get(), jbanners, isReachableByTaxi, jBookingSearchUrl.get(), + localAdInfo, routingPointInfo); InjectMetadata(env, g_mapObjectClazz, mapObject, metadata); return mapObject; @@ -78,17 +82,25 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info) jni::TScopedLocalRef localAdInfo(env, CreateLocalAdInfo(env, info)); + jni::TScopedLocalRef routingPointInfo(env, nullptr); + if (info.m_isRoutePoint) + routingPointInfo.reset(CreateRoutePointInfo(env, info)); + if (info.IsBookmark()) { // public Bookmark(@NonNull String mwmName, long mwmVersion, int featureIndex, - // @IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, - // String name, @Nullable String objectTitle, @NonNull Banner banner, boolean reachableByTaxi) + // @IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, + // String title, @Nullable String secondaryTitle, @Nullable String objectTitle, + // @Nullable Banner[] banners, boolean reachableByTaxi, + // @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo, + // @Nullable RoutePointInfo routePointInfo) static jmethodID const ctorId = jni::GetConstructorID(env, g_bookmarkClazz, "(Ljava/lang/String;JIIILjava/lang/String;Ljava/" "lang/String;Ljava/lang/String;" "[Lcom/mapswithme/maps/ads/Banner;ZLjava/lang/String;" - "Lcom/mapswithme/maps/ads/LocalAdInfo;)V"); + "Lcom/mapswithme/maps/ads/LocalAdInfo;" + "Lcom/mapswithme/maps/routing/RoutePointInfo;)V"); auto const & bac = info.GetBookmarkAndCategory(); BookmarkCategory * cat = g_framework->NativeFramework()->GetBmCategory(bac.m_categoryIndex); @@ -105,7 +117,7 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info) info.GetID().m_index, static_cast(info.m_bac.m_categoryIndex), static_cast(info.m_bac.m_bookmarkIndex), jName.get(), jTitle.get(), jSecondaryTitle.get(), jbanners.get(), info.IsReachableByTaxi(), - jBookingSearchUrl.get(), localAdInfo.get()); + jBookingSearchUrl.get(), localAdInfo.get(), routingPointInfo.get()); if (info.IsFeature()) InjectMetadata(env, g_mapObjectClazz, mapObject, info.GetMetadata()); return mapObject; @@ -118,24 +130,31 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info) // TODO(yunikkk): object can be POI + API + search result + bookmark simultaneously. // TODO(yunikkk): Should we pass localized strings here and in other methods as byte arrays? if (info.IsMyPosition()) + { return CreateMapObject(env, info.GetID().GetMwmName(), info.GetID().GetMwmVersion(), info.GetID().m_index, kMyPosition, info.GetTitle(), info.GetSecondaryTitle(), info.GetSubtitle(), ll.lat, ll.lon, address.FormatAddress(), {}, "", jbanners.get(), - info.IsReachableByTaxi(), info.GetBookingSearchUrl(), localAdInfo.get()); + info.IsReachableByTaxi(), info.GetBookingSearchUrl(), + localAdInfo.get(), routingPointInfo.get()); + } if (info.HasApiUrl()) - return CreateMapObject( - env, info.GetID().GetMwmName(), info.GetID().GetMwmVersion(), info.GetID().m_index, - kApiPoint, info.GetTitle(), info.GetSecondaryTitle(), info.GetSubtitle(), ll.lat, ll.lon, - address.FormatAddress(), info.GetMetadata(), info.GetApiUrl(), jbanners.get(), - info.IsReachableByTaxi(), info.GetBookingSearchUrl(), localAdInfo.get()); + { + return CreateMapObject(env, info.GetID().GetMwmName(), info.GetID().GetMwmVersion(), + info.GetID().m_index, kApiPoint, info.GetTitle(), + info.GetSecondaryTitle(), info.GetSubtitle(), ll.lat, ll.lon, + address.FormatAddress(), info.GetMetadata(), info.GetApiUrl(), + jbanners.get(), info.IsReachableByTaxi(), info.GetBookingSearchUrl(), + localAdInfo.get(), routingPointInfo.get()); + } return CreateMapObject(env, info.GetID().GetMwmName(), info.GetID().GetMwmVersion(), info.GetID().m_index, kPoi, info.GetTitle(), info.GetSecondaryTitle(), info.GetSubtitle(), ll.lat, ll.lon, address.FormatAddress(), info.IsFeature() ? info.GetMetadata() : Metadata(), "", jbanners.get(), - info.IsReachableByTaxi(), info.GetBookingSearchUrl(), localAdInfo.get()); + info.IsReachableByTaxi(), info.GetBookingSearchUrl(), localAdInfo.get(), + routingPointInfo.get()); } jobjectArray ToBannersArray(JNIEnv * env, vector const & banners) @@ -148,12 +167,20 @@ jobjectArray ToBannersArray(JNIEnv * env, vector const & banners) jobject CreateLocalAdInfo(JNIEnv * env, place_page::Info const & info) { - static jclass const localAdInfoClazz = jni::GetGlobalClassRef(env, "com/mapswithme/maps/ads/LocalAdInfo"); - static jmethodID const ctorId = jni::GetConstructorID(env, localAdInfoClazz, + static jclass const localAdInfoClazz = jni::GetGlobalClassRef(env, "com/mapswithme/maps/ads/LocalAdInfo"); + static jmethodID const ctorId = jni::GetConstructorID(env, localAdInfoClazz, "(ILjava/lang/String;)V"); - jni::TScopedLocalRef jLocalAdUrl(env, jni::ToJavaString(env, info.GetLocalAdsUrl())); + jni::TScopedLocalRef jLocalAdUrl(env, jni::ToJavaString(env, info.GetLocalAdsUrl())); - return env->NewObject(localAdInfoClazz, ctorId, info.GetLocalAdsStatus(), jLocalAdUrl.get()); + return env->NewObject(localAdInfoClazz, ctorId, info.GetLocalAdsStatus(), jLocalAdUrl.get()); +} + +jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info) +{ + static jclass const clazz = jni::GetGlobalClassRef(env, "com/mapswithme/maps/routing/RoutePointInfo"); + static jmethodID const ctorId = jni::GetConstructorID(env, clazz, "(II)V"); + int const markType = static_cast(info.m_routeMarkType); + return env->NewObject(clazz, ctorId, markType, info.m_intermediateIndex); } } // namespace usermark_helper diff --git a/android/jni/com/mapswithme/maps/UserMarkHelper.hpp b/android/jni/com/mapswithme/maps/UserMarkHelper.hpp index 02633c3ef4..20fcdc3efa 100644 --- a/android/jni/com/mapswithme/maps/UserMarkHelper.hpp +++ b/android/jni/com/mapswithme/maps/UserMarkHelper.hpp @@ -28,12 +28,11 @@ static constexpr int kSearch = 4; // Fills mapobject's metadata. void InjectMetadata(JNIEnv * env, jclass clazz, jobject const mapObject, feature::Metadata const & metadata); -jobject CreateMapObject(JNIEnv * env, int mapObjectType, std::string const & title, std::string const & subtitle, - double lat, double lon, feature::Metadata const & metadata); - jobject CreateMapObject(JNIEnv * env, place_page::Info const & info); jobjectArray ToBannersArray(JNIEnv * env, vector const & banners); jobject CreateLocalAdInfo(JNIEnv * env, place_page::Info const & info); + +jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info); } // namespace usermark_helper diff --git a/android/src/com/mapswithme/maps/Framework.java b/android/src/com/mapswithme/maps/Framework.java index 38e1641b7d..e876e0b4ec 100644 --- a/android/src/com/mapswithme/maps/Framework.java +++ b/android/src/com/mapswithme/maps/Framework.java @@ -12,9 +12,11 @@ import com.mapswithme.maps.ads.LocalAdInfo; import com.mapswithme.maps.api.ParsedRoutingData; import com.mapswithme.maps.api.ParsedSearchRequest; import com.mapswithme.maps.api.ParsedUrlMwmRequest; +import com.mapswithme.maps.api.RoutePoint; import com.mapswithme.maps.bookmarks.data.DistanceAndAzimut; import com.mapswithme.maps.bookmarks.data.MapObject; import com.mapswithme.maps.location.LocationHelper; +import com.mapswithme.maps.routing.RoutePointInfo; import com.mapswithme.maps.routing.RoutingInfo; import com.mapswithme.util.Constants; @@ -221,7 +223,10 @@ public class Framework public static native void nativeCloseRouting(); - public static native void nativeBuildRoute(double startLat, double startLon, double finishLat, double finishLon, boolean isP2P); + public static native void nativeBuildRoute(double startLat, double startLon, + double finishLat, double finishLon, boolean isP2P); + + public static native void nativeRemoveRoute(); public static native void nativeFollowRoute(); @@ -268,9 +273,11 @@ public class Framework @RouterType public static native int nativeGetBestRouter(double srcLat, double srcLon, double dstLat, double dstLon); - public static native void nativeSetRouteStartPoint(double lat, double lon, boolean valid); - - public static native void nativeSetRouteEndPoint(double lat, double lon, boolean valid); + public static native void nativeAddRoutePoint(double lat, double lon, boolean isMyPosition, + @NonNull RoutePointInfo routePointInfo); + public static native void nativeRemoveRoutePoint(@NonNull RoutePointInfo routePointInfo); + public static native boolean nativeCouldAddIntermediatePoint(); + public static native RoutePoint[] nativeGetRoutePoints(); /** * Registers all maps(.mwms). Adds them to the models, generates indexes and does all necessary stuff. diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 1369b2ee02..c2577f48f4 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -56,6 +56,7 @@ import com.mapswithme.maps.editor.ReportFragment; import com.mapswithme.maps.location.CompassData; import com.mapswithme.maps.location.LocationHelper; import com.mapswithme.maps.routing.NavigationController; +import com.mapswithme.maps.routing.RoutePointInfo; import com.mapswithme.maps.routing.RoutingController; import com.mapswithme.maps.routing.RoutingPlanController; import com.mapswithme.maps.routing.RoutingPlanFragment; @@ -1480,10 +1481,10 @@ public class MwmActivity extends BaseMwmFragmentActivity final RoutePoint to = data.mPoints[1]; RoutingController.get().prepare(new MapObject("", 0L, 0, MapObject.API_POINT, from.mName, "", "", "", from.mLat, from.mLon, "", null, - false, "", null), - new MapObject("", 0L, 0, MapObject.API_POINT, to.mName, "", - "", "", to.mLat, to.mLon, "", null, false, "", - null)); + false, "", null, null), + new MapObject("", 0L, 0, MapObject.API_POINT, to.mName, + "", "", "", to.mLat, to.mLon, "", null, + false, "", null, null)); return true; case ParsedUrlMwmRequest.RESULT_SEARCH: final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest(); @@ -2069,7 +2070,7 @@ public class MwmActivity extends BaseMwmFragmentActivity { return new MapObject("", 0L, 0, MapObject.API_POINT, "", "", "", "", lat, lon, "", null, - false, "", null); + false, "", null, null); } BuildRouteTask(double latTo, double lonTo) diff --git a/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java b/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java index 53baafb886..d26dfbb0c3 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java @@ -10,6 +10,7 @@ import android.text.TextUtils; import com.mapswithme.maps.Framework; import com.mapswithme.maps.ads.Banner; import com.mapswithme.maps.ads.LocalAdInfo; +import com.mapswithme.maps.routing.RoutePointInfo; import com.mapswithme.util.Constants; // TODO consider refactoring to remove hack with MapObject unmarshalling itself and Bookmark at the same time. @@ -24,13 +25,15 @@ public class Bookmark extends MapObject @Nullable private final String mObjectTitle; - Bookmark(@NonNull String mwmName, long mwmVersion, int featureIndex, - @IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, String title, - @Nullable String secondaryTitle, @Nullable String objectTitle, @Nullable Banner[] banners, - boolean reachableByTaxi, @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo) + public Bookmark(@NonNull String mwmName, long mwmVersion, int featureIndex, + @IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, + String title, @Nullable String secondaryTitle, @Nullable String objectTitle, + @Nullable Banner[] banners, boolean reachableByTaxi, + @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo, + @Nullable RoutePointInfo routePointInfo) { super(mwmName, mwmVersion, featureIndex, BOOKMARK, title, secondaryTitle, "", "", 0, 0, "", - banners, reachableByTaxi, bookingSearchUrl, localAdInfo); + banners, reachableByTaxi, bookingSearchUrl, localAdInfo, routePointInfo); mCategoryId = categoryId; mBookmarkId = bookmarkId; diff --git a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java index 3d683f0498..c89c8e2988 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java @@ -9,6 +9,7 @@ import android.text.TextUtils; import com.mapswithme.maps.ads.Banner; import com.mapswithme.maps.ads.LocalAdInfo; +import com.mapswithme.maps.routing.RoutePointInfo; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -53,22 +54,27 @@ public class MapObject implements Parcelable private String mBookingSearchUrl; @Nullable private LocalAdInfo mLocalAdInfo; + @Nullable + private RoutePointInfo mRoutePointInfo; public MapObject(@NonNull String mwmName, long mwmVersion, int featureIndex, @MapObjectType int mapObjectType, String title, @Nullable String secondaryTitle, String subtitle, String address, double lat, double lon, String apiId, @Nullable Banner[] banners, boolean reachableByTaxi, - @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo) + @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo, + @Nullable RoutePointInfo routePointInfo) { - this(mwmName, mwmVersion, featureIndex, mapObjectType, title, secondaryTitle, subtitle, address, - lat, lon, new Metadata(), apiId, banners, reachableByTaxi, bookingSearchUrl, localAdInfo); + this(mwmName, mwmVersion, featureIndex, mapObjectType, title, secondaryTitle, + subtitle, address, lat, lon, new Metadata(), apiId, banners, + reachableByTaxi, bookingSearchUrl, localAdInfo, routePointInfo); } public MapObject(@NonNull String mwmName, long mwmVersion, int featureIndex, @MapObjectType int mapObjectType, String title, @Nullable String secondaryTitle, String subtitle, String address, double lat, double lon, Metadata metadata, String apiId, @Nullable Banner[] banners, boolean reachableByTaxi, - @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo) + @Nullable String bookingSearchUrl, @Nullable LocalAdInfo localAdInfo, + @Nullable RoutePointInfo routePointInfo) { mMwmName = mwmName; mMwmVersion = mwmVersion; @@ -85,6 +91,7 @@ public class MapObject implements Parcelable mReachableByTaxi = reachableByTaxi; mBookingSearchUrl = bookingSearchUrl; mLocalAdInfo = localAdInfo; + mRoutePointInfo = routePointInfo; if (banners != null) mBanners = new ArrayList<>(Arrays.asList(banners)); } @@ -107,7 +114,8 @@ public class MapObject implements Parcelable null, // mBanners source.readByte() != 0, // ReachableByTaxi source.readString(), // BookingSearchUrl - (LocalAdInfo) source.readParcelable(LocalAdInfo.class.getClassLoader())); // LocalAdInfo + (LocalAdInfo) source.readParcelable(LocalAdInfo.class.getClassLoader()), // LocalAdInfo + (RoutePointInfo) source.readParcelable(RoutePointInfo.class.getClassLoader())); // RoutePointInfo mBanners = readBanners(source); } @@ -248,6 +256,12 @@ public class MapObject implements Parcelable return mLocalAdInfo; } + @Nullable + public RoutePointInfo getRoutePointInfo() + { + return mRoutePointInfo; + } + @NonNull public String getMwmName() { @@ -299,6 +313,7 @@ public class MapObject implements Parcelable dest.writeByte((byte) (mReachableByTaxi ? 1 : 0)); dest.writeString(mBookingSearchUrl); dest.writeParcelable(mLocalAdInfo, 0); + dest.writeParcelable(mRoutePointInfo, 0); dest.writeTypedList(mBanners); } diff --git a/android/src/com/mapswithme/maps/location/LocationHelper.java b/android/src/com/mapswithme/maps/location/LocationHelper.java index 82dce7bf07..a3886ab50e 100644 --- a/android/src/com/mapswithme/maps/location/LocationHelper.java +++ b/android/src/com/mapswithme/maps/location/LocationHelper.java @@ -216,7 +216,7 @@ public enum LocationHelper if (mMyPosition == null) mMyPosition = new MapObject("", 0L, 0, MapObject.MY_POSITION, "", "", "", "", mSavedLocation.getLatitude(), mSavedLocation.getLongitude(), "", - null, false, "", null); + null, false, "", null, null); return mMyPosition; } diff --git a/android/src/com/mapswithme/maps/routing/RoutePointInfo.java b/android/src/com/mapswithme/maps/routing/RoutePointInfo.java new file mode 100644 index 0000000000..519c58cb75 --- /dev/null +++ b/android/src/com/mapswithme/maps/routing/RoutePointInfo.java @@ -0,0 +1,75 @@ +package com.mapswithme.maps.routing; + +import android.os.Parcel; +import android.os.Parcelable; +import android.support.annotation.IntDef; +import android.support.annotation.Nullable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public class RoutePointInfo implements Parcelable +{ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ROUTE_MARK_START, ROUTE_MARK_INTERMEDIATE, ROUTE_MARK_FINISH}) + public @interface RouteMarkType {} + + public static final int ROUTE_MARK_START = 0; + public static final int ROUTE_MARK_INTERMEDIATE = 1; + public static final int ROUTE_MARK_FINISH = 2; + + @RouteMarkType + private final int mMarkType; + @Nullable + private final int mIntermediateIndex; + + public RoutePointInfo(@RouteMarkType int markType, int intermediateIndex) + { + mMarkType = markType; + mIntermediateIndex = intermediateIndex; + } + + public @RouteMarkType int getMarkType() + { + return mMarkType; + } + + public int getIntermediateIndex() + { + return mIntermediateIndex; + } + + private RoutePointInfo(Parcel in) + { + //noinspection WrongConstant + this(in.readInt() /* mMarkType */, in.readInt() /* mIntermediateIndex */); + } + + public static final Creator CREATOR = new Creator() + { + @Override + public RoutePointInfo createFromParcel(Parcel in) + { + return new RoutePointInfo(in); + } + + @Override + public RoutePointInfo[] newArray(int size) + { + return new RoutePointInfo[size]; + } + }; + + @Override + public int describeContents() + { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) + { + dest.writeInt(mMarkType); + dest.writeInt(mIntermediateIndex); + } +} diff --git a/android/src/com/mapswithme/maps/routing/RoutingController.java b/android/src/com/mapswithme/maps/routing/RoutingController.java index b545745129..0a3150bfd4 100644 --- a/android/src/com/mapswithme/maps/routing/RoutingController.java +++ b/android/src/com/mapswithme/maps/routing/RoutingController.java @@ -18,6 +18,7 @@ import android.widget.TextView; import com.mapswithme.maps.Framework; import com.mapswithme.maps.MwmApplication; import com.mapswithme.maps.R; +import com.mapswithme.maps.api.RoutePoint; import com.mapswithme.maps.bookmarks.data.MapObject; import com.mapswithme.maps.downloader.MapManager; import com.mapswithme.maps.location.LocationHelper; @@ -272,6 +273,12 @@ public class RoutingController private void build() { + Framework.nativeRemoveRoute(); + + RoutePoint[] routePoints = Framework.nativeGetRoutePoints(); + if (routePoints.length < 2) + return; + mLogger.d(TAG, "build"); mUberRequestHandled = false; mLastBuildProgress = 0; @@ -291,12 +298,18 @@ public class RoutingController setBuildState(BuildState.BUILDING); updatePlan(); - boolean isP2P = !MapObject.isOfType(MapObject.MY_POSITION, mStartPoint) && !MapObject.isOfType(MapObject.MY_POSITION, mEndPoint); + boolean isP2P = !MapObject.isOfType(MapObject.MY_POSITION, mStartPoint) && + !MapObject.isOfType(MapObject.MY_POSITION, mEndPoint); Statistics.INSTANCE.trackRouteBuild(mLastRouterType, mStartPoint, mEndPoint); - org.alohalytics.Statistics.logEvent(AlohaHelper.ROUTING_BUILD, new String[]{Statistics.EventParam.FROM, Statistics.getPointType(mStartPoint), - Statistics.EventParam.TO, Statistics.getPointType(mEndPoint)}); - Framework.nativeBuildRoute(mStartPoint.getLat(), mStartPoint.getLon(), mEndPoint.getLat(), mEndPoint.getLon(), isP2P); + org.alohalytics.Statistics.logEvent(AlohaHelper.ROUTING_BUILD, + new String[]{Statistics.EventParam.FROM, Statistics.getPointType(mStartPoint), + Statistics.EventParam.TO, Statistics.getPointType(mEndPoint)}); + + // TODO: multipoint route must be here soon. + RoutePoint from = routePoints[0]; + RoutePoint to = routePoints[routePoints.length - 1]; + Framework.nativeBuildRoute(from.mLat, from.mLon, to.mLat, to.mLon, isP2P); } private void completeUberRequest() @@ -599,15 +612,26 @@ public class RoutingController private void setPointsInternal() { if (mStartPoint == null) - Framework.nativeSetRouteStartPoint(0.0, 0.0, false); + { + Framework.nativeRemoveRoutePoint(new RoutePointInfo(RoutePointInfo.ROUTE_MARK_START, 0)); + } else - Framework.nativeSetRouteStartPoint(mStartPoint.getLat(), mStartPoint.getLon(), - !MapObject.isOfType(MapObject.MY_POSITION, mStartPoint)); + { + Framework.nativeAddRoutePoint(mStartPoint.getLat(), mStartPoint.getLon(), + MapObject.isOfType(MapObject.MY_POSITION, mStartPoint), + new RoutePointInfo(RoutePointInfo.ROUTE_MARK_START, 0)); + } if (mEndPoint == null) - Framework.nativeSetRouteEndPoint(0.0, 0.0, false); + { + Framework.nativeRemoveRoutePoint(new RoutePointInfo(RoutePointInfo.ROUTE_MARK_FINISH, 0)); + } else - Framework.nativeSetRouteEndPoint(mEndPoint.getLat(), mEndPoint.getLon(), true); + { + Framework.nativeAddRoutePoint(mEndPoint.getLat(), mEndPoint.getLon(), + MapObject.isOfType(MapObject.MY_POSITION, mEndPoint), + new RoutePointInfo(RoutePointInfo.ROUTE_MARK_FINISH, 0)); + } } void checkAndBuildRoute() diff --git a/android/src/com/mapswithme/maps/search/SearchFragment.java b/android/src/com/mapswithme/maps/search/SearchFragment.java index 67a4f0ef53..07a030ded2 100644 --- a/android/src/com/mapswithme/maps/search/SearchFragment.java +++ b/android/src/com/mapswithme/maps/search/SearchFragment.java @@ -468,7 +468,7 @@ public class SearchFragment extends BaseMwmFragment { //noinspection ConstantConditions final MapObject point = new MapObject("", 0L, 0, MapObject.SEARCH, result.name, "", - result.description.featureType, "", result.lat, result.lon, "", null, false, "", null); + result.description.featureType, "", result.lat, result.lon, "", null, false, "", null, null); RoutingController.get().onPoiSelected(point); } diff --git a/map/routing_mark.hpp b/map/routing_mark.hpp index 50a1ed29bf..9393907903 100644 --- a/map/routing_mark.hpp +++ b/map/routing_mark.hpp @@ -4,11 +4,11 @@ #include -enum class RouteMarkType +enum class RouteMarkType : uint8_t { - Start, - Intermediate, - Finish + Start = 0, + Intermediate = 1, + Finish = 2 }; class RouteMarkPoint : public UserMark From 7e512a3d62e9a2370fd6570c2eab995c3c99cb56 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 13 Jun 2017 13:58:37 +0300 Subject: [PATCH 2/2] Review fixes --- android/jni/com/mapswithme/maps/Framework.cpp | 4 ++-- .../src/com/mapswithme/maps/Framework.java | 1 + .../maps/routing/RoutePointInfo.java | 24 ++++++------------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 820bbe091f..42bf68e908 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -1154,7 +1154,7 @@ Java_com_mapswithme_maps_Framework_nativeGetBestRouter(JNIEnv * env, jclass, void ExtractRoutePointInfo(JNIEnv * env, jobject routePointInfo, RouteMarkType & markType, int8_t & intermediateIndex) { - jclass const clazz = env->GetObjectClass(routePointInfo); + static jclass const clazz = env->GetObjectClass(routePointInfo); ASSERT(clazz, ()); static jfieldID const markTypeField = env->GetFieldID(clazz, "mMarkType", "I"); ASSERT(markTypeField, ()); @@ -1199,7 +1199,7 @@ Java_com_mapswithme_maps_Framework_nativeCouldAddIntermediatePoint(JNIEnv * env, JNIEXPORT jobjectArray JNICALL Java_com_mapswithme_maps_Framework_nativeGetRoutePoints(JNIEnv * env, jclass) { - std::vector const points = frm()->GetRoutingManager().GetRoutePoints(); + auto const points = frm()->GetRoutingManager().GetRoutePoints(); static jclass const pointClazz = jni::GetGlobalClassRef(env, "com/mapswithme/maps/api/RoutePoint"); // Java signature : RoutePoint(double lat, double lon, String name) diff --git a/android/src/com/mapswithme/maps/Framework.java b/android/src/com/mapswithme/maps/Framework.java index e876e0b4ec..cbb273570c 100644 --- a/android/src/com/mapswithme/maps/Framework.java +++ b/android/src/com/mapswithme/maps/Framework.java @@ -277,6 +277,7 @@ public class Framework @NonNull RoutePointInfo routePointInfo); public static native void nativeRemoveRoutePoint(@NonNull RoutePointInfo routePointInfo); public static native boolean nativeCouldAddIntermediatePoint(); + @NonNull public static native RoutePoint[] nativeGetRoutePoints(); /** diff --git a/android/src/com/mapswithme/maps/routing/RoutePointInfo.java b/android/src/com/mapswithme/maps/routing/RoutePointInfo.java index 519c58cb75..96fa983332 100644 --- a/android/src/com/mapswithme/maps/routing/RoutePointInfo.java +++ b/android/src/com/mapswithme/maps/routing/RoutePointInfo.java @@ -10,18 +10,18 @@ import java.lang.annotation.RetentionPolicy; public class RoutePointInfo implements Parcelable { - @Retention(RetentionPolicy.SOURCE) - @IntDef({ROUTE_MARK_START, ROUTE_MARK_INTERMEDIATE, ROUTE_MARK_FINISH}) - public @interface RouteMarkType {} - 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 - private final int mMarkType; - @Nullable - private final int mIntermediateIndex; + public final int mMarkType; + + public final int mIntermediateIndex; public RoutePointInfo(@RouteMarkType int markType, int intermediateIndex) { @@ -29,16 +29,6 @@ public class RoutePointInfo implements Parcelable mIntermediateIndex = intermediateIndex; } - public @RouteMarkType int getMarkType() - { - return mMarkType; - } - - public int getIntermediateIndex() - { - return mIntermediateIndex; - } - private RoutePointInfo(Parcel in) { //noinspection WrongConstant