forked from organicmaps/organicmaps
Compare commits
3 commits
master
...
github/for
Author | SHA1 | Date | |
---|---|---|---|
1dfb6988a9 | |||
|
b65605c0b7 | ||
c6d8adc2fd |
33 changed files with 1089 additions and 778 deletions
4
.clangd
Normal file
4
.clangd
Normal file
|
@ -0,0 +1,4 @@
|
|||
CompileFlags:
|
||||
Remove:
|
||||
# clang has an issue with this flag, while gcc does not
|
||||
- "-mno-direct-extern-access"
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -188,3 +188,6 @@ screenshots/
|
|||
android/src/google/play/listings/
|
||||
keywords/
|
||||
iphone/metadata/**/keywords.txt
|
||||
|
||||
# clangd cache
|
||||
.cache/clangd/
|
||||
|
|
|
@ -11,6 +11,8 @@ set(CMAKE_C_VISIBILITY_PRESET hidden)
|
|||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Fixes warning ld: warning: ignoring duplicate libraries on Mac and Windows.
|
||||
if (POLICY CMP0156)
|
||||
cmake_policy(SET CMP0156 NEW)
|
||||
|
|
|
@ -10,6 +10,12 @@ routing::RoutingOptions::Road makeValue(jint option)
|
|||
return static_cast<routing::RoutingOptions::Road>(road);
|
||||
}
|
||||
|
||||
routing::EdgeEstimator::Strategy makeStrategyValue(jint strategy)
|
||||
{
|
||||
int convertedStrat = static_cast<int>(strategy);
|
||||
return static_cast<routing::EdgeEstimator::Strategy>(convertedStrat);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
|
@ -22,6 +28,14 @@ Java_app_organicmaps_routing_RoutingOptions_nativeHasOption(JNIEnv * env, jclass
|
|||
return static_cast<jboolean>(routingOptions.Has(road));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_mapswithme_maps_routing_RoutingOptions_nativeGetStrategy(JNIEnv * env, jclass clazz)
|
||||
{
|
||||
CHECK(g_framework, ("Framework isn't created yet!"));
|
||||
routing::EdgeEstimator::Strategy routingStrategy = routing::EdgeEstimator::LoadRoutingStrategyFromSettings();
|
||||
return static_cast<jint>(routingStrategy);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_routing_RoutingOptions_nativeAddOption(JNIEnv * env, jclass clazz, jint option)
|
||||
{
|
||||
|
@ -32,7 +46,6 @@ Java_app_organicmaps_routing_RoutingOptions_nativeAddOption(JNIEnv * env, jclass
|
|||
routing::RoutingOptions::SaveCarOptionsToSettings(routingOptions);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_routing_RoutingOptions_nativeRemoveOption(JNIEnv * env, jclass clazz, jint option)
|
||||
{
|
||||
|
@ -42,4 +55,11 @@ Java_app_organicmaps_routing_RoutingOptions_nativeRemoveOption(JNIEnv * env, jcl
|
|||
routingOptions.Remove(road);
|
||||
routing::RoutingOptions::SaveCarOptionsToSettings(routingOptions);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_mapswithme_maps_routing_RoutingOptions_nativeSetStrategy(JNIEnv * env, jclass clazz, jint strategy)
|
||||
{
|
||||
CHECK(g_framework, ("Framework isn't created yet!"));
|
||||
routing::EdgeEstimator::SaveRoutingStrategyToSettings(makeStrategyValue(strategy));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package app.organicmaps.routing;
|
|||
import androidx.annotation.NonNull;
|
||||
|
||||
import app.organicmaps.settings.RoadType;
|
||||
import app.organicmaps.settings.RoutingStrategyType;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
@ -24,9 +25,21 @@ public class RoutingOptions
|
|||
return nativeHasOption(roadType.ordinal());
|
||||
}
|
||||
|
||||
public static int getStrategy()
|
||||
{
|
||||
return nativeGetStrategy();
|
||||
}
|
||||
|
||||
public static void setStrategy(@NonNull RoutingStrategyType routingStrategyType)
|
||||
{
|
||||
nativeSetStrategy(routingStrategyType.ordinal());
|
||||
}
|
||||
|
||||
private static native void nativeAddOption(int option);
|
||||
private static native void nativeRemoveOption(int option);
|
||||
private static native boolean nativeHasOption(int option);
|
||||
private static native int nativeGetStrategy();
|
||||
private static native void nativeSetStrategy(int strategy);
|
||||
|
||||
public static boolean hasAnyOptions()
|
||||
{
|
||||
|
@ -49,4 +62,10 @@ public class RoutingOptions
|
|||
}
|
||||
return roadTypes;
|
||||
}
|
||||
|
||||
public static RoutingStrategyType getActiveRoutingStrategyType()
|
||||
{
|
||||
int strategyType = getStrategy();
|
||||
return RoutingStrategyType.values()[strategyType];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -25,8 +26,11 @@ import java.util.Set;
|
|||
public class DrivingOptionsFragment extends BaseMwmToolbarFragment
|
||||
{
|
||||
public static final String BUNDLE_ROAD_TYPES = "road_types";
|
||||
public static final String BUNDLE_ROUTING_STRATEGY_TYPE = "routing_strategy_type";
|
||||
@NonNull
|
||||
private Set<RoadType> mRoadTypes = Collections.emptySet();
|
||||
@NonNull
|
||||
private RoutingStrategyType mStrategy = RoutingStrategyType.Fastest;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
@ -38,6 +42,9 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment
|
|||
mRoadTypes = savedInstanceState != null && savedInstanceState.containsKey(BUNDLE_ROAD_TYPES)
|
||||
? makeRouteTypes(savedInstanceState)
|
||||
: RoutingOptions.getActiveRoadTypes();
|
||||
mStrategy = savedInstanceState != null && savedInstanceState.containsKey(BUNDLE_ROUTING_STRATEGY_TYPE)
|
||||
? makeRoutingStrategyType(savedInstanceState)
|
||||
: RoutingOptions.getActiveRoutingStrategyType();
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -53,6 +60,13 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment
|
|||
return result;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private RoutingStrategyType makeRoutingStrategyType(@NonNull Bundle bundle)
|
||||
{
|
||||
RoutingStrategyType result = Objects.requireNonNull((RoutingStrategyType)bundle.getSerializable(BUNDLE_ROUTING_STRATEGY_TYPE));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState)
|
||||
{
|
||||
|
@ -63,12 +77,15 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment
|
|||
savedRoadTypes.add(each.ordinal());
|
||||
}
|
||||
outState.putIntegerArrayList(BUNDLE_ROAD_TYPES, savedRoadTypes);
|
||||
|
||||
outState.putSerializable(BUNDLE_ROUTING_STRATEGY_TYPE, mStrategy);
|
||||
}
|
||||
|
||||
private boolean areSettingsNotChanged()
|
||||
{
|
||||
Set<RoadType> lastActiveRoadTypes = RoutingOptions.getActiveRoadTypes();
|
||||
return mRoadTypes.equals(lastActiveRoadTypes);
|
||||
RoutingStrategyType lastActiveStrategyType = RoutingOptions.getActiveRoutingStrategyType();
|
||||
return mRoadTypes.equals(lastActiveRoadTypes) && mStrategy.equals(lastActiveStrategyType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,6 +121,26 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment
|
|||
CompoundButton.OnCheckedChangeListener dirtyBtnListener =
|
||||
new ToggleRoutingOptionListener(RoadType.Dirty);
|
||||
dirtyRoadsBtn.setOnCheckedChangeListener(dirtyBtnListener);
|
||||
|
||||
RadioGroup strategyRadioGroup = root.findViewById(R.id.routing_strategy_types);
|
||||
RoutingStrategyType currentStrategy = RoutingOptions.getActiveRoutingStrategyType();
|
||||
int currentCheckedStrategyId;
|
||||
switch (currentStrategy)
|
||||
{
|
||||
case Shortest:
|
||||
currentCheckedStrategyId = R.id.use_strategy_shortest;
|
||||
break;
|
||||
case FewerTurns:
|
||||
currentCheckedStrategyId = R.id.use_strategy_fewerTurns;
|
||||
break;
|
||||
default:
|
||||
currentCheckedStrategyId = R.id.use_strategy_fastest;
|
||||
break;
|
||||
}
|
||||
strategyRadioGroup.check(currentCheckedStrategyId);
|
||||
RadioGroup.OnCheckedChangeListener strategyRadioGroupListener =
|
||||
new ToggleRoutingStrategyListener();
|
||||
strategyRadioGroup.setOnCheckedChangeListener(strategyRadioGroupListener);
|
||||
}
|
||||
|
||||
private static class ToggleRoutingOptionListener implements CompoundButton.OnCheckedChangeListener
|
||||
|
@ -125,4 +162,26 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment
|
|||
RoutingOptions.removeOption(mRoadType);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ToggleRoutingStrategyListener implements RadioGroup.OnCheckedChangeListener
|
||||
{
|
||||
private ToggleRoutingStrategyListener() {}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup group, int checkedId)
|
||||
{
|
||||
switch (checkedId)
|
||||
{
|
||||
case R.id.use_strategy_fastest:
|
||||
RoutingOptions.setStrategy(RoutingStrategyType.Fastest);
|
||||
break;
|
||||
case R.id.use_strategy_shortest:
|
||||
RoutingOptions.setStrategy(RoutingStrategyType.Shortest);
|
||||
break;
|
||||
case R.id.use_strategy_fewerTurns:
|
||||
RoutingOptions.setStrategy(RoutingStrategyType.FewerTurns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package app.organicmaps.settings;
|
||||
|
||||
public enum RoutingStrategyType
|
||||
{
|
||||
Fastest,
|
||||
Shortest,
|
||||
FewerTurns
|
||||
}
|
|
@ -104,4 +104,46 @@
|
|||
android:padding="@dimen/margin_half_double_plus"
|
||||
android:layout_height="match_parent"/>
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="3dp"
|
||||
android:background="@android:color/darker_gray"/>
|
||||
<TextView
|
||||
android:text="@string/driving_options_subheader2"
|
||||
android:textAppearance="?android:attr/textAppearance"
|
||||
android:textColor="?colorAccent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginTop="@dimen/margin_half_double_plus"
|
||||
android:paddingEnd="@dimen/margin_base"
|
||||
android:paddingStart="@dimen/margin_base"/>
|
||||
<RadioGroup
|
||||
android:id="@+id/routing_strategy_types"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_base">
|
||||
<RadioButton
|
||||
android:id="@+id/use_strategy_fastest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/margin_half_plus"
|
||||
android:checked="true"
|
||||
android:text="@string/use_strategy_fastest"/>
|
||||
<RadioButton
|
||||
android:id="@+id/use_strategy_shortest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/margin_half_plus"
|
||||
android:checked="false"
|
||||
android:text="@string/use_strategy_shortest"/>
|
||||
<RadioButton
|
||||
android:id="@+id/use_strategy_fewerTurns"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/margin_half_plus"
|
||||
android:checked="false"
|
||||
android:text="@string/use_strategy_fewerTurns"/>
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -697,12 +697,16 @@
|
|||
<string name="access_rules_author_only">Online editing</string>
|
||||
<string name="driving_options_title">Routing options</string>
|
||||
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
|
||||
<string name="driving_options_subheader2">Routing Strategy</string>
|
||||
<string name="avoid_tolls">Avoid tolls</string>
|
||||
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
|
||||
<string name="avoid_unpaved">Avoid unpaved roads</string>
|
||||
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
|
||||
<string name="avoid_ferry">Avoid ferries</string>
|
||||
<string name="avoid_motorways">Avoid freeways</string>
|
||||
<string name="use_strategy_fastest">Fastest</string>
|
||||
<string name="use_strategy_shortest">Shortest</string>
|
||||
<string name="use_strategy_fewerTurns">Fewer turns</string>
|
||||
<string name="unable_to_calc_alert_title">Unable to calculate route</string>
|
||||
<string name="unable_to_calc_alert_subtitle">A route could not be found. This may be caused by your routing options or incomplete OpenStreetMap data. Please change your routing options and retry.</string>
|
||||
<string name="define_to_avoid_btn">Define roads to avoid</string>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,7 @@ class DataSource;
|
|||
|
||||
namespace power_management
|
||||
{
|
||||
class PowerManager;
|
||||
class PowerManager;
|
||||
}
|
||||
|
||||
struct RoutePointInfo
|
||||
|
@ -79,12 +79,11 @@ public:
|
|||
using GetStringsBundleFn = std::function<StringsBundle const &()>;
|
||||
using PowerManagerGetter = std::function<power_management::PowerManager const &()>;
|
||||
|
||||
template <typename DataSourceGetter, typename CountryInfoGetter,
|
||||
typename CountryParentNameGetter, typename StringsBundleGetter,
|
||||
typename PowerManagerGetter>
|
||||
template <typename DataSourceGetter, typename CountryInfoGetter, typename CountryParentNameGetter,
|
||||
typename StringsBundleGetter, typename PowerManagerGetter>
|
||||
Callbacks(DataSourceGetter && dataSourceGetter, CountryInfoGetter && countryInfoGetter,
|
||||
CountryParentNameGetter && countryParentNameGetter,
|
||||
StringsBundleGetter && stringsBundleGetter, PowerManagerGetter && powerManagerGetter)
|
||||
CountryParentNameGetter && countryParentNameGetter, StringsBundleGetter && stringsBundleGetter,
|
||||
PowerManagerGetter && powerManagerGetter)
|
||||
: m_dataSourceGetter(std::forward<DataSourceGetter>(dataSourceGetter))
|
||||
, m_countryInfoGetter(std::forward<CountryInfoGetter>(countryInfoGetter))
|
||||
, m_countryParentNameGetterFn(std::forward<CountryParentNameGetter>(countryParentNameGetter))
|
||||
|
@ -100,12 +99,9 @@ public:
|
|||
PowerManagerGetter m_powerManagerGetter;
|
||||
};
|
||||
|
||||
using RouteBuildingCallback =
|
||||
std::function<void(routing::RouterResultCode, storage::CountriesSet const &)>;
|
||||
using RouteSpeedCamShowCallback =
|
||||
std::function<void(m2::PointD const &, double)>;
|
||||
using RouteSpeedCamsClearCallback =
|
||||
std::function<void()>;
|
||||
using RouteBuildingCallback = std::function<void(routing::RouterResultCode, storage::CountriesSet const &)>;
|
||||
using RouteSpeedCamShowCallback = std::function<void(m2::PointD const &, double)>;
|
||||
using RouteSpeedCamsClearCallback = std::function<void()>;
|
||||
|
||||
using RouteStartBuildCallback = std::function<void(std::vector<RouteMarkData> const & points)>;
|
||||
|
||||
|
@ -169,40 +165,27 @@ public:
|
|||
}
|
||||
void FollowRoute();
|
||||
void CloseRouting(bool removeRoutePoints);
|
||||
void GetRouteFollowingInfo(routing::FollowingInfo & info) const
|
||||
{
|
||||
m_routingSession.GetRouteFollowingInfo(info);
|
||||
}
|
||||
void GetRouteFollowingInfo(routing::FollowingInfo & info) const { m_routingSession.GetRouteFollowingInfo(info); }
|
||||
|
||||
TransitRouteInfo GetTransitRouteInfo() const;
|
||||
|
||||
m2::PointD GetRouteEndPoint() const { return m_routingSession.GetEndPoint(); }
|
||||
/// Returns the most situable router engine type.
|
||||
routing::RouterType GetBestRouter(m2::PointD const & startPoint,
|
||||
m2::PointD const & finalPoint) const;
|
||||
routing::RouterType GetBestRouter(m2::PointD const & startPoint, m2::PointD const & finalPoint) const;
|
||||
routing::RouterType GetLastUsedRouter() const;
|
||||
void SetLastUsedRouter(routing::RouterType type);
|
||||
// Sound notifications for turn instructions.
|
||||
void EnableTurnNotifications(bool enable) { m_routingSession.EnableTurnNotifications(enable); }
|
||||
bool AreTurnNotificationsEnabled() const
|
||||
{
|
||||
return m_routingSession.AreTurnNotificationsEnabled();
|
||||
}
|
||||
bool AreTurnNotificationsEnabled() const { return m_routingSession.AreTurnNotificationsEnabled(); }
|
||||
/// \brief Sets a locale for TTS.
|
||||
/// \param locale is a string with locale code. For example "en", "ru", "zh-Hant" and so on.
|
||||
/// \note See sound/tts/languages.txt for the full list of available locales.
|
||||
void SetTurnNotificationsLocale(std::string const & locale)
|
||||
{
|
||||
m_routingSession.SetTurnNotificationsLocale(locale);
|
||||
}
|
||||
void SetTurnNotificationsLocale(std::string const & locale) { m_routingSession.SetTurnNotificationsLocale(locale); }
|
||||
/// @return current TTS locale. For example "en", "ru", "zh-Hant" and so on.
|
||||
/// In case of error returns an empty string.
|
||||
/// \note The method returns correct locale after SetTurnNotificationsLocale has been called.
|
||||
/// If not, it returns an empty string.
|
||||
std::string GetTurnNotificationsLocale() const
|
||||
{
|
||||
return m_routingSession.GetTurnNotificationsLocale();
|
||||
}
|
||||
std::string GetTurnNotificationsLocale() const { return m_routingSession.GetTurnNotificationsLocale(); }
|
||||
// @return polyline of the route.
|
||||
routing::FollowedPolyline const & GetRoutePolylineForTests() const
|
||||
{
|
||||
|
@ -234,8 +217,8 @@ public:
|
|||
void RemoveRoutePoints();
|
||||
void RemoveIntermediateRoutePoints();
|
||||
void MoveRoutePoint(size_t currentIndex, size_t targetIndex);
|
||||
void MoveRoutePoint(RouteMarkType currentType, size_t currentIntermediateIndex,
|
||||
RouteMarkType targetType, size_t targetIntermediateIndex);
|
||||
void MoveRoutePoint(RouteMarkType currentType, size_t currentIntermediateIndex, RouteMarkType targetType,
|
||||
size_t targetIntermediateIndex);
|
||||
void HideRoutePoint(RouteMarkType type, size_t intermediateIndex = 0);
|
||||
bool CouldAddIntermediatePoint() const;
|
||||
bool IsMyPosition(RouteMarkType type, size_t intermediateIndex = 0);
|
||||
|
@ -244,8 +227,7 @@ public:
|
|||
void RemoveRoute(bool deactivateFollowing);
|
||||
|
||||
void CheckLocationForRouting(location::GpsInfo const & info);
|
||||
void CallRouteBuilded(routing::RouterResultCode code,
|
||||
storage::CountriesSet const & absentCountries);
|
||||
void CallRouteBuilded(routing::RouterResultCode code, storage::CountriesSet const & absentCountries);
|
||||
void OnBuildRouteReady(routing::Route const & route, routing::RouterResultCode code);
|
||||
void OnRebuildRouteReady(routing::Route const & route, routing::RouterResultCode code);
|
||||
void OnNeedMoreMaps(uint64_t routeId, storage::CountriesSet const & absentCountries);
|
||||
|
@ -329,10 +311,7 @@ private:
|
|||
{
|
||||
RoadInfo() = default;
|
||||
|
||||
explicit RoadInfo(m2::PointD const & pt, FeatureID const & featureId)
|
||||
: m_startPoint(pt)
|
||||
, m_featureId(featureId)
|
||||
{}
|
||||
explicit RoadInfo(m2::PointD const & pt, FeatureID const & featureId) : m_startPoint(pt), m_featureId(featureId) {}
|
||||
|
||||
m2::PointD m_startPoint;
|
||||
FeatureID m_featureId;
|
||||
|
@ -340,15 +319,14 @@ private:
|
|||
};
|
||||
using RoadWarningsCollection = std::map<routing::RoutingOptions::Road, std::vector<RoadInfo>>;
|
||||
|
||||
using GetMwmIdFn = std::function<MwmSet::MwmId (routing::NumMwmId numMwmId)>;
|
||||
using GetMwmIdFn = std::function<MwmSet::MwmId(routing::NumMwmId numMwmId)>;
|
||||
void CollectRoadWarnings(std::vector<routing::RouteSegment> const & segments, m2::PointD const & startPt,
|
||||
double baseDistance, GetMwmIdFn const & getMwmIdFn, RoadWarningsCollection & roadWarnings);
|
||||
void CreateRoadWarningMarks(RoadWarningsCollection && roadWarnings);
|
||||
|
||||
/// \returns false if the location could not be matched to the route and should be matched to the
|
||||
/// road graph. Otherwise returns true.
|
||||
void MatchLocationToRoute(location::GpsInfo & info,
|
||||
location::RouteMatchingInfo & routeMatchingInfo);
|
||||
void MatchLocationToRoute(location::GpsInfo & info, location::RouteMatchingInfo & routeMatchingInfo);
|
||||
location::RouteMatchingInfo GetRouteMatchingInfo(location::GpsInfo & info);
|
||||
uint32_t GenerateRoutePointsTransactionId() const;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "map/framework.hpp"
|
||||
|
||||
#include "routing/router.hpp"
|
||||
#include "routing/edge_estimator.hpp"
|
||||
|
||||
#include "platform/settings.hpp"
|
||||
|
||||
|
@ -24,12 +25,26 @@ std::string const kUseCachedRoutingSettings = "use_cached_settings_desktop";
|
|||
std::string const kStartCoordsCachedSettings = "start_coords_desktop";
|
||||
std::string const kFinishCoordsCachedSettings = "finish_coords_desktop";
|
||||
std::string const kRouterTypeCachedSettings = "router_type_desktop";
|
||||
std::string const kRouterStrategyCachedSettings = "router_strategy";
|
||||
std::string const kAvoidRoutingOptionSettings = "avoid_routing_options_car";
|
||||
|
||||
int constexpr DefaultRouterIndex()
|
||||
{
|
||||
// Car router by default.
|
||||
return static_cast<int>(routing::RouterType::Vehicle);
|
||||
}
|
||||
|
||||
int constexpr DefaultStrategyIndex()
|
||||
{
|
||||
// Routing strategy by default
|
||||
return static_cast<int>(routing::EdgeEstimator::Strategy::Fastest);
|
||||
}
|
||||
|
||||
int constexpr DefaultAvoidOptionIndex()
|
||||
{
|
||||
// Avoid routing option by default
|
||||
return static_cast<int>(routing::RoutingOptions::Road::Usual);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
|
@ -93,6 +108,8 @@ void RoutingSettings::LoadSession(Framework & framework)
|
|||
settings::Delete(kStartCoordsCachedSettings);
|
||||
settings::Delete(kFinishCoordsCachedSettings);
|
||||
settings::Delete(kRouterTypeCachedSettings);
|
||||
settings::Delete(kRouterStrategyCachedSettings);
|
||||
settings::Delete(kAvoidRoutingOptionSettings);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +151,20 @@ RoutingSettings::RoutingSettings(QWidget * parent, Framework & framework)
|
|||
m_routerType->insertItem(static_cast<int>(RouterType::Ruler), "ruler");
|
||||
form->addRow("Choose router:", m_routerType);
|
||||
|
||||
m_routerStrategy = new QComboBox(frame);
|
||||
m_routerStrategy->insertItem(static_cast<int>(EdgeEstimator::Strategy::Fastest), "fastest");
|
||||
m_routerStrategy->insertItem(static_cast<int>(EdgeEstimator::Strategy::Shortest), "shortest");
|
||||
m_routerStrategy->insertItem(static_cast<int>(EdgeEstimator::Strategy::FewerTurns), "fewer turns");
|
||||
form->addRow("Choose strategy:", m_routerStrategy);
|
||||
|
||||
m_avoidRoutingOptions = new QComboBox(frame);
|
||||
m_avoidRoutingOptions->insertItem(static_cast<int>(RoutingOptions::Road::Dirty), "dirty");
|
||||
m_avoidRoutingOptions->insertItem(static_cast<int>(RoutingOptions::Road::Ferry), "ferry");
|
||||
m_avoidRoutingOptions->insertItem(static_cast<int>(RoutingOptions::Road::Motorway), "motorway");
|
||||
m_avoidRoutingOptions->insertItem(static_cast<int>(RoutingOptions::Road::Toll), "toll");
|
||||
m_avoidRoutingOptions->insertItem(static_cast<int>(RoutingOptions::Road::Usual), "usual");
|
||||
form->addRow("Choose avoid option:", m_avoidRoutingOptions);
|
||||
|
||||
m_showTurnsCheckbox = new QCheckBox({}, frame);
|
||||
form->addRow("Show turns:", m_showTurnsCheckbox);
|
||||
|
||||
|
@ -190,6 +221,8 @@ bool RoutingSettings::SaveSettings()
|
|||
settings::Set(kUseDebugGuideSettings, m_useDebugGuideCheckbox->isChecked());
|
||||
settings::Set(kUseCachedRoutingSettings, m_saveSessionCheckbox->isChecked());
|
||||
settings::Set(kRouterTypeCachedSettings, m_routerType->currentIndex());
|
||||
settings::Set(kRouterStrategyCachedSettings, m_routerStrategy->currentIndex());
|
||||
settings::Set(kAvoidRoutingOptionSettings, m_avoidRoutingOptions->currentIndex());
|
||||
return ValidateAndSaveCoordsFromInput();
|
||||
}
|
||||
|
||||
|
@ -207,6 +240,14 @@ void RoutingSettings::LoadSettings()
|
|||
settings::TryGet(kRouterTypeCachedSettings, routerType);
|
||||
m_routerType->setCurrentIndex(routerType);
|
||||
|
||||
int routerStrategy = DefaultStrategyIndex();
|
||||
settings::TryGet(kRouterStrategyCachedSettings, routerStrategy);
|
||||
m_routerStrategy->setCurrentIndex(routerStrategy);
|
||||
|
||||
int avoidRoutingOption = DefaultAvoidOptionIndex();
|
||||
settings::TryGet(kAvoidRoutingOptionSettings, avoidRoutingOption);
|
||||
m_avoidRoutingOptions->setCurrentIndex(avoidRoutingOption);
|
||||
|
||||
bool showTurns = false;
|
||||
settings::TryGet(kShowTurnsSettings, showTurns);
|
||||
m_showTurnsCheckbox->setChecked(showTurns);
|
||||
|
|
|
@ -40,6 +40,8 @@ private:
|
|||
QLineEdit * m_finishInput;
|
||||
|
||||
QComboBox * m_routerType;
|
||||
QComboBox * m_routerStrategy;
|
||||
QComboBox * m_avoidRoutingOptions;
|
||||
QCheckBox * m_showTurnsCheckbox;
|
||||
QCheckBox * m_useDebugGuideCheckbox;
|
||||
QCheckBox * m_saveSessionCheckbox;
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#include "routing/turns.hpp"
|
||||
|
||||
#include "drape_frontend/drape_api.hpp"
|
||||
#include "drape_frontend/drape_engine.hpp"
|
||||
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "routing/async_router.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "routing/routing_options.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
#include "base/macros.hpp"
|
||||
|
@ -19,8 +21,7 @@ AsyncRouter::RouterDelegateProxy::RouterDelegateProxy(ReadyCallbackOwnership con
|
|||
NeedMoreMapsCallback const & onNeedMoreMaps,
|
||||
RemoveRouteCallback const & onRemoveRoute,
|
||||
PointCheckCallback const & onPointCheck,
|
||||
ProgressCallback const & onProgress,
|
||||
uint32_t timeoutSec)
|
||||
ProgressCallback const & onProgress, uint32_t timeoutSec)
|
||||
: m_onReadyOwnership(onReady)
|
||||
, m_onNeedMoreMaps(onNeedMoreMaps)
|
||||
, m_onRemoveRoute(onRemoveRoute)
|
||||
|
@ -45,8 +46,7 @@ void AsyncRouter::RouterDelegateProxy::OnReady(std::shared_ptr<Route> route, Rou
|
|||
m_onReadyOwnership(std::move(route), resultCode);
|
||||
}
|
||||
|
||||
void AsyncRouter::RouterDelegateProxy::OnNeedMoreMaps(uint64_t routeId,
|
||||
std::set<std::string> const & absentCounties)
|
||||
void AsyncRouter::RouterDelegateProxy::OnNeedMoreMaps(uint64_t routeId, std::set<std::string> const & absentCounties)
|
||||
{
|
||||
if (!m_onNeedMoreMaps)
|
||||
return;
|
||||
|
@ -76,8 +76,7 @@ void AsyncRouter::RouterDelegateProxy::Cancel()
|
|||
m_delegate.Cancel();
|
||||
}
|
||||
|
||||
bool AsyncRouter::FindClosestProjectionToRoad(m2::PointD const & point,
|
||||
m2::PointD const & direction, double radius,
|
||||
bool AsyncRouter::FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction, double radius,
|
||||
EdgeProj & proj)
|
||||
{
|
||||
return m_router->FindClosestProjectionToRoad(point, direction, radius, proj);
|
||||
|
@ -96,9 +95,7 @@ void AsyncRouter::RouterDelegateProxy::OnProgress(float progress)
|
|||
return;
|
||||
|
||||
onProgress = m_onProgress;
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [onProgress, progress]() {
|
||||
onProgress(progress);
|
||||
});
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [onProgress, progress]() { onProgress(progress); });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,10 +124,7 @@ void AsyncRouter::RouterDelegateProxy::OnPointCheck(ms::LatLon const & pt)
|
|||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
AsyncRouter::AsyncRouter(PointCheckCallback const & pointCheckCallback)
|
||||
: m_threadExit(false)
|
||||
, m_hasRequest(false)
|
||||
, m_clearState(false)
|
||||
, m_pointCheckCallback(pointCheckCallback)
|
||||
: m_threadExit(false), m_clearState(false), m_pointCheckCallback(pointCheckCallback)
|
||||
{
|
||||
m_thread = threads::SimpleThread(&AsyncRouter::ThreadFunc, this);
|
||||
}
|
||||
|
@ -149,8 +143,7 @@ AsyncRouter::~AsyncRouter()
|
|||
m_thread.join();
|
||||
}
|
||||
|
||||
void AsyncRouter::SetRouter(std::unique_ptr<IRouter> && router,
|
||||
std::unique_ptr<AbsentRegionsFinder> && finder)
|
||||
void AsyncRouter::SetRouter(std::unique_ptr<IRouter> && router, std::unique_ptr<AbsentRegionsFinder> && finder)
|
||||
{
|
||||
unique_lock ul(m_guard);
|
||||
|
||||
|
@ -160,8 +153,8 @@ void AsyncRouter::SetRouter(std::unique_ptr<IRouter> && router,
|
|||
m_absentRegionsFinder = std::move(finder);
|
||||
}
|
||||
|
||||
void AsyncRouter::CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction,
|
||||
bool adjustToPrevRoute,
|
||||
void AsyncRouter::CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction, bool adjustToPrevRoute,
|
||||
std::vector<EdgeEstimator::Strategy> strategies,
|
||||
ReadyCallbackOwnership const & readyCallback,
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback,
|
||||
|
@ -175,11 +168,17 @@ void AsyncRouter::CalculateRoute(Checkpoints const & checkpoints, m2::PointD con
|
|||
|
||||
ResetDelegate();
|
||||
|
||||
m_delegateProxy =
|
||||
std::make_shared<RouterDelegateProxy>(readyCallback, needMoreMapsCallback, removeRouteCallback,
|
||||
m_pointCheckCallback, progressCallback, timeoutSec);
|
||||
for (auto strategy : strategies)
|
||||
{
|
||||
// TODO: investigate why make_shared was being problematic; something to do with implicitly
|
||||
// deleted constructors on RouterDelegateProxy??
|
||||
m_requestQueue.push(std::shared_ptr<Request>(
|
||||
new Request{RouterDelegateProxy(readyCallback, needMoreMapsCallback, removeRouteCallback, m_pointCheckCallback,
|
||||
progressCallback, timeoutSec),
|
||||
strategy}));
|
||||
LOG(LINFO, ("Pushed request", static_cast<int>(strategy), m_requestQueue.size()));
|
||||
}
|
||||
|
||||
m_hasRequest = true;
|
||||
m_threadCondVar.notify_one();
|
||||
}
|
||||
|
||||
|
@ -204,68 +203,48 @@ void AsyncRouter::LogCode(RouterResultCode code, double const elapsedSec)
|
|||
{
|
||||
switch (code)
|
||||
{
|
||||
case RouterResultCode::StartPointNotFound:
|
||||
LOG(LWARNING, ("Can't find start or end node"));
|
||||
break;
|
||||
case RouterResultCode::EndPointNotFound:
|
||||
LOG(LWARNING, ("Can't find end point node"));
|
||||
break;
|
||||
case RouterResultCode::PointsInDifferentMWM:
|
||||
LOG(LWARNING, ("Points are in different MWMs"));
|
||||
break;
|
||||
case RouterResultCode::RouteNotFound:
|
||||
LOG(LWARNING, ("Route not found"));
|
||||
break;
|
||||
case RouterResultCode::RouteFileNotExist:
|
||||
LOG(LWARNING, ("There is no routing file"));
|
||||
break;
|
||||
case RouterResultCode::NeedMoreMaps:
|
||||
LOG(LINFO,
|
||||
("Routing can find a better way with additional maps, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::Cancelled:
|
||||
LOG(LINFO, ("Route calculation cancelled, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::NoError:
|
||||
LOG(LINFO, ("Route found, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::NoCurrentPosition:
|
||||
LOG(LINFO, ("No current position"));
|
||||
break;
|
||||
case RouterResultCode::InconsistentMWMandRoute:
|
||||
LOG(LINFO, ("Inconsistent mwm and route"));
|
||||
break;
|
||||
case RouterResultCode::InternalError:
|
||||
LOG(LINFO, ("Internal error"));
|
||||
break;
|
||||
case RouterResultCode::FileTooOld:
|
||||
LOG(LINFO, ("File too old"));
|
||||
break;
|
||||
case RouterResultCode::IntermediatePointNotFound:
|
||||
LOG(LWARNING, ("Can't find intermediate point node"));
|
||||
break;
|
||||
case RouterResultCode::TransitRouteNotFoundNoNetwork:
|
||||
LOG(LWARNING, ("No transit route is found because there's no transit network in the mwm of "
|
||||
"the route point"));
|
||||
break;
|
||||
case RouterResultCode::TransitRouteNotFoundTooLongPedestrian:
|
||||
LOG(LWARNING, ("No transit route is found because pedestrian way is too long"));
|
||||
break;
|
||||
case RouterResultCode::RouteNotFoundRedressRouteError:
|
||||
LOG(LWARNING, ("Route not found because of a redress route error"));
|
||||
break;
|
||||
case RouterResultCode::HasWarnings:
|
||||
LOG(LINFO, ("Route has warnings, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::StartPointNotFound: LOG(LWARNING, ("Can't find start or end node")); break;
|
||||
case RouterResultCode::EndPointNotFound: LOG(LWARNING, ("Can't find end point node")); break;
|
||||
case RouterResultCode::PointsInDifferentMWM: LOG(LWARNING, ("Points are in different MWMs")); break;
|
||||
case RouterResultCode::RouteNotFound: LOG(LWARNING, ("Route not found")); break;
|
||||
case RouterResultCode::RouteFileNotExist: LOG(LWARNING, ("There is no routing file")); break;
|
||||
case RouterResultCode::NeedMoreMaps:
|
||||
LOG(LINFO, ("Routing can find a better way with additional maps, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::Cancelled: LOG(LINFO, ("Route calculation cancelled, elapsed seconds:", elapsedSec)); break;
|
||||
case RouterResultCode::NoError: LOG(LINFO, ("Route found, elapsed seconds:", elapsedSec)); break;
|
||||
case RouterResultCode::NoCurrentPosition: LOG(LINFO, ("No current position")); break;
|
||||
case RouterResultCode::InconsistentMWMandRoute: LOG(LINFO, ("Inconsistent mwm and route")); break;
|
||||
case RouterResultCode::InternalError: LOG(LINFO, ("Internal error")); break;
|
||||
case RouterResultCode::FileTooOld: LOG(LINFO, ("File too old")); break;
|
||||
case RouterResultCode::IntermediatePointNotFound: LOG(LWARNING, ("Can't find intermediate point node")); break;
|
||||
case RouterResultCode::TransitRouteNotFoundNoNetwork:
|
||||
LOG(LWARNING, ("No transit route is found because there's no transit network in the mwm of "
|
||||
"the route point"));
|
||||
break;
|
||||
case RouterResultCode::TransitRouteNotFoundTooLongPedestrian:
|
||||
LOG(LWARNING, ("No transit route is found because pedestrian way is too long"));
|
||||
break;
|
||||
case RouterResultCode::RouteNotFoundRedressRouteError:
|
||||
LOG(LWARNING, ("Route not found because of a redress route error"));
|
||||
break;
|
||||
case RouterResultCode::HasWarnings: LOG(LINFO, ("Route has warnings, elapsed seconds:", elapsedSec)); break;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncRouter::ResetDelegate()
|
||||
{
|
||||
if (m_delegateProxy)
|
||||
if (m_request)
|
||||
{
|
||||
m_delegateProxy->Cancel();
|
||||
m_delegateProxy.reset();
|
||||
m_request->m_delegateProxy.Cancel();
|
||||
m_request.reset();
|
||||
}
|
||||
|
||||
// also have to cancel and clear all queued requests
|
||||
while (!m_requestQueue.empty())
|
||||
{
|
||||
m_requestQueue.front()->m_delegateProxy.Cancel();
|
||||
m_requestQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +254,14 @@ void AsyncRouter::ThreadFunc()
|
|||
{
|
||||
{
|
||||
unique_lock ul(m_guard);
|
||||
m_threadCondVar.wait(ul, [this](){ return m_threadExit || m_hasRequest || m_clearState; });
|
||||
|
||||
LOG(LINFO, ("Waiting for queued request"));
|
||||
m_threadCondVar.wait(ul,
|
||||
[this]()
|
||||
{
|
||||
LOG(LINFO, ("Testing queued request", m_requestQueue.size()));
|
||||
return m_threadExit || !m_requestQueue.empty() || m_clearState;
|
||||
});
|
||||
|
||||
if (m_clearState && m_router)
|
||||
{
|
||||
|
@ -286,8 +272,10 @@ void AsyncRouter::ThreadFunc()
|
|||
if (m_threadExit)
|
||||
break;
|
||||
|
||||
if (!m_hasRequest)
|
||||
if (m_requestQueue.empty())
|
||||
continue;
|
||||
|
||||
LOG(LINFO, ("CalculateRoute dequeued:", static_cast<int>(m_requestQueue.front()->m_strategy)));
|
||||
}
|
||||
|
||||
CalculateRoute();
|
||||
|
@ -297,7 +285,7 @@ void AsyncRouter::ThreadFunc()
|
|||
void AsyncRouter::CalculateRoute()
|
||||
{
|
||||
Checkpoints checkpoints;
|
||||
std::shared_ptr<RouterDelegateProxy> delegateProxy;
|
||||
std::shared_ptr<Request> request;
|
||||
m2::PointD startDirection;
|
||||
bool adjustToPrevRoute = false;
|
||||
std::shared_ptr<AbsentRegionsFinder> absentRegionsFinder;
|
||||
|
@ -308,21 +296,22 @@ void AsyncRouter::CalculateRoute()
|
|||
{
|
||||
unique_lock ul(m_guard);
|
||||
|
||||
bool hasRequest = m_hasRequest;
|
||||
m_hasRequest = false;
|
||||
bool hasRequest = !m_requestQueue.empty();
|
||||
if (!hasRequest)
|
||||
return;
|
||||
if (!m_router)
|
||||
return;
|
||||
if (!m_delegateProxy)
|
||||
return;
|
||||
|
||||
m_request = m_requestQueue.front();
|
||||
m_requestQueue.pop();
|
||||
LOG(LINFO, ("CalculateRoute POPPED:", static_cast<int>(m_request->m_strategy), m_requestQueue.size()));
|
||||
|
||||
checkpoints = m_checkpoints;
|
||||
startDirection = m_startDirection;
|
||||
adjustToPrevRoute = m_adjustToPrevRoute;
|
||||
delegateProxy = m_delegateProxy;
|
||||
router = m_router;
|
||||
absentRegionsFinder = m_absentRegionsFinder;
|
||||
request = m_request;
|
||||
routeId = ++m_routeCounter;
|
||||
routerName = router->GetName();
|
||||
router->SetGuides(std::move(m_guides));
|
||||
|
@ -330,6 +319,7 @@ void AsyncRouter::CalculateRoute()
|
|||
}
|
||||
|
||||
auto route = std::make_shared<Route>(router->GetName(), routeId);
|
||||
route->SetStrategy(request->m_strategy);
|
||||
RouterResultCode code;
|
||||
|
||||
base::Timer timer;
|
||||
|
@ -341,15 +331,20 @@ void AsyncRouter::CalculateRoute()
|
|||
"m. checkpoints:", checkpoints, "startDirection:", startDirection, "router name:", router->GetName()));
|
||||
|
||||
if (absentRegionsFinder)
|
||||
absentRegionsFinder->GenerateAbsentRegions(checkpoints, delegateProxy->GetDelegate());
|
||||
absentRegionsFinder->GenerateAbsentRegions(checkpoints, request->m_delegateProxy.GetDelegate());
|
||||
|
||||
RoutingOptions const routingOptions = RoutingOptions::LoadCarOptionsFromSettings();
|
||||
router->SetEstimatorOptions(routingOptions.GetOptions());
|
||||
|
||||
router->SetEstimatorStrategy(request->m_strategy);
|
||||
|
||||
// Run basic request.
|
||||
code = router->CalculateRoute(checkpoints, startDirection, adjustToPrevRoute,
|
||||
delegateProxy->GetDelegate(), *route);
|
||||
request->m_delegateProxy.GetDelegate(), *route);
|
||||
router->SetGuides({});
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time
|
||||
LogCode(code, elapsedSec);
|
||||
LOG(LINFO, ("ETA:", route->GetTotalTimeSec(), "sec."));
|
||||
LOG(LINFO, ("ETA:", route->GetTotalTimeSec(), "sec.", static_cast<int>(request->m_strategy)));
|
||||
}
|
||||
catch (RootException const & e)
|
||||
{
|
||||
|
@ -358,7 +353,7 @@ void AsyncRouter::CalculateRoute()
|
|||
// Note. After call of this method |route| should be used only on ui thread.
|
||||
// And |route| should stop using on routing background thread, in this method.
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[delegateProxy, route, code]() { delegateProxy->OnReady(route, code); });
|
||||
[request, route, code]() { request->m_delegateProxy.OnReady(route, code); });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -368,11 +363,10 @@ void AsyncRouter::CalculateRoute()
|
|||
// Note. After call of this method |route| should be used only on ui thread.
|
||||
// And |route| should stop using on routing background thread, in this method.
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[delegateProxy, route, code]() { delegateProxy->OnReady(route, code); });
|
||||
[request, route, code]() { request->m_delegateProxy.OnReady(route, code); });
|
||||
}
|
||||
|
||||
bool const needAbsentRegions = (code != RouterResultCode::Cancelled &&
|
||||
route->GetRouterId() != "ruler-router");
|
||||
bool const needAbsentRegions = (code != RouterResultCode::Cancelled && route->GetRouterId() != "ruler-router");
|
||||
|
||||
std::set<std::string> absent;
|
||||
if (needAbsentRegions)
|
||||
|
@ -388,7 +382,7 @@ void AsyncRouter::CalculateRoute()
|
|||
}
|
||||
}
|
||||
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time + absents fetch time
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time + absents fetch time
|
||||
LogCode(code, elapsedSec);
|
||||
|
||||
// Call callback only if we have some new data.
|
||||
|
@ -396,14 +390,12 @@ void AsyncRouter::CalculateRoute()
|
|||
{
|
||||
if (code == RouterResultCode::NeedMoreMaps)
|
||||
{
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [delegateProxy, routeId, absent]() {
|
||||
delegateProxy->OnNeedMoreMaps(routeId, absent);
|
||||
});
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[request, routeId, absent]() { request->m_delegateProxy.OnNeedMoreMaps(routeId, absent); });
|
||||
}
|
||||
else
|
||||
{
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[delegateProxy, code]() { delegateProxy->OnRemoveRoute(code); });
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [request, code]() { request->m_delegateProxy.OnRemoveRoute(code); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,15 @@
|
|||
#include "routing/router_delegate.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/thread.hpp"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace routing
|
||||
{
|
||||
|
@ -34,8 +31,7 @@ public:
|
|||
/// Sets a synchronous router, current route calculation will be cancelled
|
||||
/// @param router pointer to a router implementation
|
||||
/// @param finder pointer to a router for generated absent wmwms.
|
||||
void SetRouter(std::unique_ptr<IRouter> && router,
|
||||
std::unique_ptr<AbsentRegionsFinder> && finder);
|
||||
void SetRouter(std::unique_ptr<IRouter> && router, std::unique_ptr<AbsentRegionsFinder> && finder);
|
||||
|
||||
/// Main method to calculate new route from startPt to finalPt with start direction
|
||||
/// Processed result will be passed to callback. Callback will be called at the GUI thread.
|
||||
|
@ -48,19 +44,18 @@ public:
|
|||
/// @param timeoutSec timeout to cancel routing. 0 is infinity.
|
||||
// @TODO(bykoianko) Gather |readyCallback|, |needMoreMapsCallback| and |removeRouteCallback|
|
||||
// to one delegate. No need to add |progressCallback| to the delegate.
|
||||
void CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction,
|
||||
bool adjustToPrevRoute, ReadyCallbackOwnership const & readyCallback,
|
||||
void CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction, bool adjustToPrevRoute,
|
||||
std::vector<EdgeEstimator::Strategy> strategies, ReadyCallbackOwnership const & readyCallback,
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback,
|
||||
ProgressCallback const & progressCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback, ProgressCallback const & progressCallback,
|
||||
uint32_t timeoutSec = RouterDelegate::kNoTimeout);
|
||||
|
||||
void SetGuidesTracks(GuidesTracks && guides);
|
||||
/// Interrupt routing and clear buffers
|
||||
void ClearState();
|
||||
|
||||
bool FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction,
|
||||
double radius, EdgeProj & proj);
|
||||
bool FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction, double radius,
|
||||
EdgeProj & proj);
|
||||
|
||||
private:
|
||||
/// Worker thread function
|
||||
|
@ -75,12 +70,9 @@ private:
|
|||
class RouterDelegateProxy
|
||||
{
|
||||
public:
|
||||
RouterDelegateProxy(ReadyCallbackOwnership const & onReady,
|
||||
NeedMoreMapsCallback const & onNeedMoreMaps,
|
||||
RemoveRouteCallback const & onRemoveRoute,
|
||||
PointCheckCallback const & onPointCheck,
|
||||
ProgressCallback const & onProgress,
|
||||
uint32_t timeoutSec);
|
||||
RouterDelegateProxy(ReadyCallbackOwnership const & onReady, NeedMoreMapsCallback const & onNeedMoreMaps,
|
||||
RemoveRouteCallback const & onRemoveRoute, PointCheckCallback const & onPointCheck,
|
||||
ProgressCallback const & onProgress, uint32_t timeoutSec);
|
||||
|
||||
void OnReady(std::shared_ptr<Route> route, RouterResultCode resultCode);
|
||||
void OnNeedMoreMaps(uint64_t routeId, std::set<std::string> const & absentCounties);
|
||||
|
@ -105,6 +97,12 @@ private:
|
|||
RouterDelegate m_delegate;
|
||||
};
|
||||
|
||||
struct Request
|
||||
{
|
||||
RouterDelegateProxy m_delegateProxy;
|
||||
EdgeEstimator::Strategy m_strategy;
|
||||
};
|
||||
|
||||
private:
|
||||
std::mutex m_guard;
|
||||
|
||||
|
@ -112,7 +110,6 @@ private:
|
|||
threads::SimpleThread m_thread;
|
||||
std::condition_variable m_threadCondVar;
|
||||
bool m_threadExit;
|
||||
bool m_hasRequest;
|
||||
|
||||
/// Current request parameters
|
||||
bool m_clearState = false;
|
||||
|
@ -121,7 +118,8 @@ private:
|
|||
|
||||
m2::PointD m_startDirection = m2::PointD::Zero();
|
||||
bool m_adjustToPrevRoute = false;
|
||||
std::shared_ptr<RouterDelegateProxy> m_delegateProxy;
|
||||
std::shared_ptr<Request> m_request;
|
||||
std::queue<std::shared_ptr<Request>> m_requestQueue;
|
||||
std::shared_ptr<AbsentRegionsFinder> m_absentRegionsFinder;
|
||||
std::shared_ptr<IRouter> m_router;
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#include "routing/edge_estimator.hpp"
|
||||
|
||||
#include "platform/settings.hpp"
|
||||
|
||||
#include "routing/geometry.hpp"
|
||||
#include "routing/latlon_with_altitude.hpp"
|
||||
#include "routing/routing_helpers.hpp"
|
||||
#include "routing/routing_options.hpp"
|
||||
#include "routing/traffic_stash.hpp"
|
||||
|
||||
#include "traffic/speed_groups.hpp"
|
||||
|
@ -60,12 +63,15 @@ bool IsTransit(std::optional<HighwayType> type)
|
|||
}
|
||||
|
||||
template <class CalcSpeed>
|
||||
double CalcClimbSegment(EdgeEstimator::Purpose purpose, Segment const & segment,
|
||||
RoadGeometry const & road, CalcSpeed && calcSpeed)
|
||||
double CalcClimbSegment(EdgeEstimator::Purpose purpose, EdgeEstimator::Strategy strategy,
|
||||
Segment const & segment, RoadGeometry const & road, CalcSpeed && calcSpeed)
|
||||
{
|
||||
double const distance = road.GetDistance(segment.GetSegmentIdx());
|
||||
double speedMpS = GetSpeedMpS(purpose, segment, road);
|
||||
|
||||
if (strategy == EdgeEstimator::Strategy::Shortest && purpose == EdgeEstimator::Purpose::Weight)
|
||||
speedMpS = 1.0;
|
||||
|
||||
static double constexpr kSmallDistanceM = 1; // we have altitude threshold is 0.5m
|
||||
if (distance > kSmallDistanceM && !IsTransit(road.GetHighwayType()))
|
||||
{
|
||||
|
@ -167,6 +173,26 @@ double GetCarClimbPenalty(EdgeEstimator::Purpose, double, geometry::Altitude)
|
|||
}
|
||||
|
||||
// EdgeEstimator -----------------------------------------------------------------------------------
|
||||
|
||||
string const EdgeEstimator::kRoutingStrategySettings = "router_strategy";
|
||||
|
||||
// static
|
||||
EdgeEstimator::Strategy EdgeEstimator::LoadRoutingStrategyFromSettings()
|
||||
{
|
||||
int mode = 0;
|
||||
if (!settings::Get(kRoutingStrategySettings, mode))
|
||||
mode = 0;
|
||||
|
||||
return (EdgeEstimator::Strategy) mode;
|
||||
}
|
||||
|
||||
// static
|
||||
void EdgeEstimator::SaveRoutingStrategyToSettings(Strategy strategy)
|
||||
{
|
||||
settings::Set(kRoutingStrategySettings,
|
||||
strings::to_string(static_cast<int>(strategy)));
|
||||
}
|
||||
|
||||
EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH,
|
||||
DataSource * /*dataSourcePtr*/, std::shared_ptr<NumMwmIds> /*numMwmIds*/)
|
||||
: m_maxWeightSpeedMpS(KmphToMps(maxWeightSpeedKMpH))
|
||||
|
@ -180,6 +206,9 @@ EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroa
|
|||
|
||||
if (m_offroadSpeedKMpH.m_eta != kNotUsed)
|
||||
CHECK_GREATER_OR_EQUAL(m_maxWeightSpeedMpS, KmphToMps(m_offroadSpeedKMpH.m_eta), ());
|
||||
|
||||
m_avoidRoutingOptions = RoutingOptions();
|
||||
m_strategy = EdgeEstimator::Strategy::Fastest;
|
||||
}
|
||||
|
||||
double EdgeEstimator::CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const
|
||||
|
@ -260,6 +289,26 @@ double EdgeEstimator::CalcOffroad(ms::LatLon const & from, ms::LatLon const & to
|
|||
return TimeBetweenSec(from, to, KmphToMps(offroadSpeedKMpH));
|
||||
}
|
||||
|
||||
RoutingOptions EdgeEstimator::GetAvoidRoutingOptions() const
|
||||
{
|
||||
return m_avoidRoutingOptions;
|
||||
}
|
||||
|
||||
void EdgeEstimator::SetAvoidRoutingOptions(RoutingOptions::RoadType options)
|
||||
{
|
||||
m_avoidRoutingOptions.SetOptions(options);
|
||||
}
|
||||
|
||||
EdgeEstimator::Strategy EdgeEstimator::GetStrategy() const
|
||||
{
|
||||
return m_strategy;
|
||||
}
|
||||
|
||||
void EdgeEstimator::SetStrategy(EdgeEstimator::Strategy strategy)
|
||||
{
|
||||
m_strategy = strategy;
|
||||
}
|
||||
|
||||
// PedestrianEstimator -----------------------------------------------------------------------------
|
||||
class PedestrianEstimator final : public EdgeEstimator
|
||||
{
|
||||
|
@ -270,7 +319,20 @@ public:
|
|||
}
|
||||
|
||||
// EdgeEstimator overrides:
|
||||
double GetUTurnPenalty(Purpose /* purpose */) const override { return 0.0 /* seconds */; }
|
||||
double GetUTurnPenalty(Purpose purpose) const override
|
||||
{
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && GetStrategy() == EdgeEstimator::Strategy::FewerTurns)
|
||||
return 60 * 60;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double GetTurnPenalty(Purpose purpose) const override
|
||||
{
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && GetStrategy() == EdgeEstimator::Strategy::FewerTurns)
|
||||
return 60 * 60;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double GetFerryLandingPenalty(Purpose purpose) const override
|
||||
{
|
||||
switch (purpose)
|
||||
|
@ -283,11 +345,16 @@ public:
|
|||
|
||||
double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override
|
||||
{
|
||||
return CalcClimbSegment(purpose, segment, road,
|
||||
double result = CalcClimbSegment(purpose, GetStrategy(), segment, road,
|
||||
[purpose](double speedMpS, double tangent, geometry::Altitude altitude)
|
||||
{
|
||||
return speedMpS / GetPedestrianClimbPenalty(purpose, tangent, altitude);
|
||||
});
|
||||
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && !road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions()))
|
||||
result += (24 * 60 * 60);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -301,7 +368,20 @@ public:
|
|||
}
|
||||
|
||||
// EdgeEstimator overrides:
|
||||
double GetUTurnPenalty(Purpose /* purpose */) const override { return 20.0 /* seconds */; }
|
||||
double GetUTurnPenalty(Purpose purpose) const override
|
||||
{
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && GetStrategy() == EdgeEstimator::Strategy::FewerTurns)
|
||||
return 60 * 60;
|
||||
return 20.0;
|
||||
}
|
||||
|
||||
double GetTurnPenalty(Purpose purpose) const override
|
||||
{
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && GetStrategy() == EdgeEstimator::Strategy::FewerTurns)
|
||||
return 60 * 60;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double GetFerryLandingPenalty(Purpose purpose) const override
|
||||
{
|
||||
switch (purpose)
|
||||
|
@ -314,7 +394,7 @@ public:
|
|||
|
||||
double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override
|
||||
{
|
||||
return CalcClimbSegment(purpose, segment, road,
|
||||
double result = CalcClimbSegment(purpose, GetStrategy(), segment, road,
|
||||
[purpose, this](double speedMpS, double tangent, geometry::Altitude altitude)
|
||||
{
|
||||
auto const factor = GetBicycleClimbPenalty(purpose, tangent, altitude);
|
||||
|
@ -347,6 +427,12 @@ public:
|
|||
|
||||
return std::min(speedMpS, GetMaxWeightSpeedMpS());
|
||||
});
|
||||
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && !road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions()))
|
||||
result += (24 * 60 * 60);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -364,14 +450,24 @@ public:
|
|||
|
||||
// EdgeEstimator overrides:
|
||||
double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override;
|
||||
double GetUTurnPenalty(Purpose /* purpose */) const override
|
||||
double GetUTurnPenalty(Purpose purpose) const override
|
||||
{
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && GetStrategy() == EdgeEstimator::Strategy::FewerTurns)
|
||||
return 60 * 60;
|
||||
|
||||
// Adds 2 minutes penalty for U-turn. The value is quite arbitrary
|
||||
// and needs to be properly selected after a number of real-world
|
||||
// experiments.
|
||||
return 2 * 60; // seconds
|
||||
}
|
||||
|
||||
double GetTurnPenalty(Purpose purpose) const override
|
||||
{
|
||||
if (purpose == EdgeEstimator::Purpose::Weight)
|
||||
return 60 * 60;
|
||||
return 0;
|
||||
}
|
||||
|
||||
double GetFerryLandingPenalty(Purpose purpose) const override
|
||||
{
|
||||
switch (purpose)
|
||||
|
@ -390,6 +486,9 @@ double CarEstimator::CalcSegmentWeight(Segment const & segment, RoadGeometry con
|
|||
{
|
||||
double result = road.GetDistance(segment.GetSegmentIdx()) / GetSpeedMpS(purpose, segment, road);
|
||||
|
||||
if (purpose == EdgeEstimator::Purpose::Weight && !road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions()))
|
||||
result += (24 * 60 * 60);
|
||||
|
||||
if (m_trafficStash)
|
||||
{
|
||||
SpeedGroup const speedGroup = m_trafficStash->GetSpeedGroup(segment);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing/routing_options.hpp"
|
||||
#include "routing/segment.hpp"
|
||||
#include "routing/vehicle_mask.hpp"
|
||||
|
||||
|
@ -27,10 +28,22 @@ public:
|
|||
ETA
|
||||
};
|
||||
|
||||
static std::string const kRoutingStrategySettings;
|
||||
|
||||
enum class Strategy
|
||||
{
|
||||
Fastest,
|
||||
Shortest,
|
||||
FewerTurns
|
||||
};
|
||||
|
||||
EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH,
|
||||
DataSource * dataSourcePtr = nullptr, std::shared_ptr<NumMwmIds> numMwmIds = nullptr);
|
||||
virtual ~EdgeEstimator() = default;
|
||||
|
||||
static Strategy LoadRoutingStrategyFromSettings();
|
||||
static void SaveRoutingStrategyToSettings(Strategy strategy);
|
||||
|
||||
double CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const;
|
||||
// Estimates time in seconds it takes to go from point |from| to point |to| along a leap (fake)
|
||||
// edge |from|-|to| using real features.
|
||||
|
@ -45,9 +58,16 @@ public:
|
|||
// Estimates time in seconds it takes to go from point |from| to point |to| along direct fake edge.
|
||||
double CalcOffroad(ms::LatLon const & from, ms::LatLon const & to, Purpose purpose) const;
|
||||
|
||||
RoutingOptions GetAvoidRoutingOptions() const;
|
||||
void SetAvoidRoutingOptions(RoutingOptions::RoadType options);
|
||||
|
||||
Strategy GetStrategy() const;
|
||||
void SetStrategy(Strategy strategy);
|
||||
|
||||
virtual double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road,
|
||||
Purpose purpose) const = 0;
|
||||
virtual double GetUTurnPenalty(Purpose purpose) const = 0;
|
||||
virtual double GetTurnPenalty(Purpose purpose) const = 0;
|
||||
virtual double GetFerryLandingPenalty(Purpose purpose) const = 0;
|
||||
|
||||
static std::shared_ptr<EdgeEstimator> Create(VehicleType vehicleType, double maxWeighSpeedKMpH,
|
||||
|
@ -65,6 +85,8 @@ public:
|
|||
private:
|
||||
double const m_maxWeightSpeedMpS;
|
||||
SpeedKMpH const m_offroadSpeedKMpH;
|
||||
RoutingOptions m_avoidRoutingOptions;
|
||||
Strategy m_strategy;
|
||||
|
||||
//DataSource * m_dataSourcePtr;
|
||||
//std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "base/timer.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
@ -254,8 +255,8 @@ void IndexGraph::GetNeighboringEdges(astar::VertexData<Segment, RouteWeight> con
|
|||
if (!road.IsValid())
|
||||
return;
|
||||
|
||||
if (useRoutingOptions && !road.SuitableForOptions(m_avoidRoutingOptions))
|
||||
return;
|
||||
// if (useRoutingOptions && !road.SuitableForOptions(m_avoidRoutingOptions))
|
||||
// return;
|
||||
|
||||
bool const bidirectional = !road.IsOneWay();
|
||||
auto const & from = fromVertexData.m_vertex;
|
||||
|
@ -282,8 +283,8 @@ void IndexGraph::GetSegmentCandidateForRoadPoint(RoadPoint const & rp, NumMwmId
|
|||
if (!road.IsValid())
|
||||
return;
|
||||
|
||||
if (!road.SuitableForOptions(m_avoidRoutingOptions))
|
||||
return;
|
||||
// if (!road.SuitableForOptions(m_avoidRoutingOptions))
|
||||
// return;
|
||||
|
||||
bool const bidirectional = !road.IsOneWay();
|
||||
auto const pointId = rp.GetPointId();
|
||||
|
@ -514,6 +515,9 @@ RouteWeight IndexGraph::GetPenalties(EdgeEstimator::Purpose purpose, Segment con
|
|||
if (IsUTurn(u, v))
|
||||
weightPenalty += m_estimator->GetUTurnPenalty(purpose);
|
||||
|
||||
if (IsTurn(u, v))
|
||||
weightPenalty += m_estimator->GetTurnPenalty(purpose);
|
||||
|
||||
if (IsBoarding(fromPenaltyData.m_isFerry, toPenaltyData.m_isFerry))
|
||||
weightPenalty += m_estimator->GetFerryLandingPenalty(purpose);
|
||||
|
||||
|
@ -549,6 +553,57 @@ bool IndexGraph::IsUTurnAndRestricted(Segment const & parent, Segment const & ch
|
|||
return uTurn.m_atTheEnd && turnPoint == n - 1;
|
||||
}
|
||||
|
||||
bool IndexGraph::IsTurn(Segment const & u, Segment const & v) const
|
||||
{
|
||||
// Boundary check for segmentIdx
|
||||
if (u.GetSegmentIdx() == 0 && !(u.IsForward()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v.GetSegmentIdx() == 0 && !(v.IsForward()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto geoU = GetRoadGeometry(u.GetFeatureId());
|
||||
auto startPointU = geoU.GetPoint(u.GetSegmentIdx());
|
||||
auto endPointU = geoU.GetPoint(u.IsForward() ? u.GetSegmentIdx() + 1: u.GetSegmentIdx() - 1);
|
||||
|
||||
auto geoV = GetRoadGeometry(v.GetFeatureId());
|
||||
auto startPointV = geoV.GetPoint(v.GetSegmentIdx());
|
||||
auto endPointV = geoV.GetPoint(v.IsForward() ? v.GetSegmentIdx() + 1: v.GetSegmentIdx() - 1);
|
||||
|
||||
if (!(endPointU == startPointV))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double vectorU[2] = {endPointU.m_lat - startPointU.m_lat, endPointU.m_lon - startPointU.m_lon};
|
||||
double vectorV[2] = {endPointV.m_lat - startPointV.m_lat, endPointV.m_lon - startPointV.m_lon};
|
||||
|
||||
//dot product
|
||||
double dot = vectorU[0] * vectorV[0] + vectorU[1] * vectorV[1];
|
||||
|
||||
//determinant
|
||||
double det = vectorU[0] * vectorV[1] - vectorU[1] * vectorV[0];
|
||||
|
||||
//calculate the anlge
|
||||
double angle = atan2(det, dot);
|
||||
|
||||
//convert to degree value
|
||||
angle = angle * 180 / 3.141592;
|
||||
|
||||
if (abs(angle) >= 15)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool isOutgoing,
|
||||
Segment const & from, Segment const & to,
|
||||
std::optional<RouteWeight const> const & prevWeight) const
|
||||
|
@ -556,7 +611,18 @@ RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool
|
|||
auto const & segment = isOutgoing ? to : from;
|
||||
auto const & road = GetRoadGeometry(segment.GetFeatureId());
|
||||
|
||||
// m_estimator->SetAvoidRoutingOptions(this->m_avoidRoutingOptions.GetOptions());
|
||||
|
||||
auto const weight = RouteWeight(m_estimator->CalcSegmentWeight(segment, road, purpose));
|
||||
|
||||
if (purpose == EdgeEstimator::Purpose::Weight)
|
||||
{
|
||||
if(m_estimator->GetStrategy() == EdgeEstimator::Strategy::Shortest)
|
||||
{
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
|
||||
auto const penalties = GetPenalties(purpose, isOutgoing ? from : to, isOutgoing ? to : from, prevWeight);
|
||||
|
||||
return weight + penalties;
|
||||
|
|
|
@ -133,6 +133,8 @@ public:
|
|||
|
||||
bool IsUTurnAndRestricted(Segment const & parent, Segment const & child, bool isOutgoing) const;
|
||||
|
||||
bool IsTurn(Segment const & u, Segment const & v) const;
|
||||
|
||||
/// @param[in] isOutgoing true, when movig from -> to, false otherwise.
|
||||
/// @param[in] prevWeight used for fetching access:conditional.
|
||||
/// I suppose :) its time when user will be at the end of |from| (|to| if \a isOutgoing == false) segment.
|
||||
|
|
|
@ -326,6 +326,10 @@ bool IndexRouter::FindClosestProjectionToRoad(m2::PointD const & point,
|
|||
return true;
|
||||
}
|
||||
|
||||
void IndexRouter::SetEstimatorOptions(RoutingOptions::RoadType options) {m_estimator ->SetAvoidRoutingOptions(options);}
|
||||
|
||||
void IndexRouter::SetEstimatorStrategy(EdgeEstimator::Strategy strategy) {m_estimator ->SetStrategy(strategy);}
|
||||
|
||||
void IndexRouter::SetGuides(GuidesTracks && guides) { m_guides = GuidesConnections(guides); }
|
||||
|
||||
RouterResultCode IndexRouter::CalculateRoute(Checkpoints const & checkpoints,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "routing/regions_decl.hpp"
|
||||
#include "routing/router.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
#include "routing/routing_options.hpp"
|
||||
#include "routing/segment.hpp"
|
||||
#include "routing/segmented_route.hpp"
|
||||
|
||||
|
@ -77,6 +78,10 @@ public:
|
|||
std::string GetName() const override { return m_name; }
|
||||
void ClearState() override;
|
||||
|
||||
void SetEstimatorOptions(RoutingOptions::RoadType options) override;
|
||||
|
||||
void SetEstimatorStrategy(EdgeEstimator::Strategy strategy) override;
|
||||
|
||||
void SetGuides(GuidesTracks && guides) override;
|
||||
RouterResultCode CalculateRoute(Checkpoints const & checkpoints,
|
||||
m2::PointD const & startDirection, bool adjustToPrevRoute,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "routing/checkpoints.hpp"
|
||||
#include "routing/regions_decl.hpp"
|
||||
#include "routing/router_delegate.hpp"
|
||||
#include "routing/segment.hpp"
|
||||
|
||||
#include "base/thread.hpp"
|
||||
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
#include "traffic/speed_groups.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "platform/location.hpp"
|
||||
|
||||
#include "geometry/angles.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -25,14 +24,9 @@ double constexpr kSteetNameLinkMeters = 400.0;
|
|||
std::string DebugPrint(RouteSegment::RoadNameInfo const & rni)
|
||||
{
|
||||
stringstream out;
|
||||
out << "RoadNameInfo "
|
||||
<< "{ m_name = " << rni.m_name
|
||||
<< ", m_ref = " << rni.m_ref
|
||||
<< ", m_junction_ref = " << rni.m_junction_ref
|
||||
<< ", m_destination_ref = " << rni.m_destination_ref
|
||||
<< ", m_destination = " << rni.m_destination
|
||||
<< ", m_isLink = " << rni.m_isLink
|
||||
<< " }";
|
||||
out << "RoadNameInfo " << "{ m_name = " << rni.m_name << ", m_ref = " << rni.m_ref
|
||||
<< ", m_junction_ref = " << rni.m_junction_ref << ", m_destination_ref = " << rni.m_destination_ref
|
||||
<< ", m_destination = " << rni.m_destination << ", m_isLink = " << rni.m_isLink << " }";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
@ -41,9 +35,7 @@ std::string DebugPrint(RouteSegment::SpeedCamera const & rhs)
|
|||
return "SpeedCamera{ " + std::to_string(rhs.m_coef) + ", " + std::to_string(int(rhs.m_maxSpeedKmPH)) + " }";
|
||||
}
|
||||
|
||||
|
||||
Route::Route(string const & router, vector<m2::PointD> const & points, uint64_t routeId,
|
||||
string const & name)
|
||||
Route::Route(string const & router, vector<m2::PointD> const & points, uint64_t routeId, string const & name)
|
||||
: m_router(router)
|
||||
, m_routingSettings(GetRoutingSettings(VehicleType::Car))
|
||||
, m_name(name)
|
||||
|
@ -87,8 +79,7 @@ double Route::GetMercatorDistanceFromBegin() const
|
|||
|
||||
CHECK_LESS(curIter.m_ind, m_routeSegments.size(), ());
|
||||
|
||||
double const distMerc =
|
||||
curIter.m_ind == 0 ? 0.0 : m_routeSegments[curIter.m_ind - 1].GetDistFromBeginningMerc();
|
||||
double const distMerc = curIter.m_ind == 0 ? 0.0 : m_routeSegments[curIter.m_ind - 1].GetDistFromBeginningMerc();
|
||||
return distMerc + m_poly.GetDistFromCurPointToRoutePointMerc();
|
||||
}
|
||||
|
||||
|
@ -97,10 +88,7 @@ double Route::GetTotalTimeSec() const
|
|||
return m_routeSegments.empty() ? 0 : m_routeSegments.back().GetTimeFromBeginningSec();
|
||||
}
|
||||
|
||||
double Route::GetCurrentTimeToEndSec() const
|
||||
{
|
||||
return GetCurrentTimeToSegmentSec(m_routeSegments.size() - 1);
|
||||
}
|
||||
double Route::GetCurrentTimeToEndSec() const { return GetCurrentTimeToSegmentSec(m_routeSegments.size() - 1); }
|
||||
|
||||
double Route::GetCurrentTimeToNearestTurnSec() const
|
||||
{
|
||||
|
@ -136,7 +124,8 @@ double Route::GetCurrentTimeFromBeginSec() const
|
|||
auto const & curIter = m_poly.GetCurrentIter();
|
||||
CHECK_LESS(curIter.m_ind, m_routeSegments.size(), ());
|
||||
|
||||
double const toLastPointSec = (curIter.m_ind == 0) ? 0.0 : m_routeSegments[curIter.m_ind - 1].GetTimeFromBeginningSec();
|
||||
double const toLastPointSec =
|
||||
(curIter.m_ind == 0) ? 0.0 : m_routeSegments[curIter.m_ind - 1].GetTimeFromBeginningSec();
|
||||
double const toNextPointSec = m_routeSegments[curIter.m_ind].GetTimeFromBeginningSec();
|
||||
|
||||
double const curSegLenMeters = GetSegLenMeters(curIter.m_ind);
|
||||
|
@ -288,8 +277,7 @@ void Route::GetNearestTurn(double & distanceToTurnMeters, TurnItem & turn) const
|
|||
GetClosestTurnAfterIdx(m_poly.GetCurrentIter().m_ind, turn);
|
||||
CHECK_LESS(m_poly.GetCurrentIter().m_ind, turn.m_index, ());
|
||||
|
||||
distanceToTurnMeters = m_poly.GetDistanceM(m_poly.GetCurrentIter(),
|
||||
m_poly.GetIterToIndex(turn.m_index));
|
||||
distanceToTurnMeters = m_poly.GetDistanceM(m_poly.GetCurrentIter(), m_poly.GetIterToIndex(turn.m_index));
|
||||
}
|
||||
|
||||
optional<turns::TurnItem> Route::GetCurrentIteratorTurn() const
|
||||
|
@ -326,8 +314,7 @@ bool Route::GetNextTurn(double & distanceToTurnMeters, TurnItem & nextTurn) cons
|
|||
CHECK_LESS(curTurn.m_index, m_routeSegments.size(), ());
|
||||
GetClosestTurnAfterIdx(curTurn.m_index, nextTurn);
|
||||
CHECK_LESS(curTurn.m_index, nextTurn.m_index, ());
|
||||
distanceToTurnMeters = m_poly.GetDistanceM(m_poly.GetCurrentIter(),
|
||||
m_poly.GetIterToIndex(nextTurn.m_index));
|
||||
distanceToTurnMeters = m_poly.GetDistanceM(m_poly.GetCurrentIter(), m_poly.GetIterToIndex(nextTurn.m_index));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -345,10 +332,7 @@ bool Route::GetNextTurns(vector<TurnItemDist> & turns) const
|
|||
return true;
|
||||
}
|
||||
|
||||
void Route::GetCurrentDirectionPoint(m2::PointD & pt) const
|
||||
{
|
||||
m_poly.GetCurrentDirectionPoint(pt, kOnEndToleranceM);
|
||||
}
|
||||
void Route::GetCurrentDirectionPoint(m2::PointD & pt) const { m_poly.GetCurrentDirectionPoint(pt, kOnEndToleranceM); }
|
||||
|
||||
void Route::SetRouteSegments(vector<RouteSegment> && routeSegments)
|
||||
{
|
||||
|
@ -357,8 +341,7 @@ void Route::SetRouteSegments(vector<RouteSegment> && routeSegments)
|
|||
m_haveAltitudes = true;
|
||||
for (size_t i = 0; i < m_routeSegments.size(); ++i)
|
||||
{
|
||||
if (m_haveAltitudes &&
|
||||
m_routeSegments[i].GetJunction().GetAltitude() == geometry::kInvalidAltitude)
|
||||
if (m_haveAltitudes && m_routeSegments[i].GetJunction().GetAltitude() == geometry::kInvalidAltitude)
|
||||
{
|
||||
m_haveAltitudes = false;
|
||||
}
|
||||
|
@ -372,9 +355,8 @@ void Route::SetRouteSegments(vector<RouteSegment> && routeSegments)
|
|||
|
||||
bool Route::MoveIterator(location::GpsInfo const & info)
|
||||
{
|
||||
m2::RectD const rect = mercator::MetersToXY(
|
||||
info.m_longitude, info.m_latitude,
|
||||
max(m_routingSettings.m_matchingThresholdM, info.m_horizontalAccuracy));
|
||||
m2::RectD const rect = mercator::MetersToXY(info.m_longitude, info.m_latitude,
|
||||
max(m_routingSettings.m_matchingThresholdM, info.m_horizontalAccuracy));
|
||||
|
||||
return m_poly.UpdateMatchingProjection(rect);
|
||||
}
|
||||
|
@ -395,13 +377,11 @@ double Route::GetPolySegAngle(size_t ind) const
|
|||
do
|
||||
{
|
||||
p2 = m_poly.GetPolyline().GetPoint(i);
|
||||
}
|
||||
while (m2::AlmostEqualULPs(p1, p2) && ++i < polySz);
|
||||
} while (m2::AlmostEqualULPs(p1, p2) && ++i < polySz);
|
||||
return (i == polySz) ? 0 : base::RadToDeg(ang::AngleTo(p1, p2));
|
||||
}
|
||||
|
||||
bool Route::MatchLocationToRoute(location::GpsInfo & location,
|
||||
location::RouteMatchingInfo & routeMatchingInfo) const
|
||||
bool Route::MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo) const
|
||||
{
|
||||
if (!IsValid())
|
||||
return false;
|
||||
|
@ -463,9 +443,8 @@ bool Route::IsSubroutePassed(size_t subrouteIdx) const
|
|||
CHECK_LESS(segmentIdx, m_routeSegments.size(), ());
|
||||
double const lengthMeters = m_routeSegments[segmentIdx].GetDistFromBeginningMeters();
|
||||
double const passedDistanceMeters = m_poly.GetDistanceFromStartMeters();
|
||||
double const finishToleranceM = segmentIdx == m_routeSegments.size() - 1
|
||||
? m_routingSettings.m_finishToleranceM
|
||||
: kOnEndToleranceM;
|
||||
double const finishToleranceM =
|
||||
segmentIdx == m_routeSegments.size() - 1 ? m_routingSettings.m_finishToleranceM : kOnEndToleranceM;
|
||||
return lengthMeters - passedDistanceMeters < finishToleranceM;
|
||||
}
|
||||
|
||||
|
@ -514,10 +493,7 @@ void Route::SetMwmsPartlyProhibitedForSpeedCams(vector<platform::CountryFile> &&
|
|||
m_speedCamPartlyProhibitedMwms = std::move(mwms);
|
||||
}
|
||||
|
||||
bool Route::CrossMwmsPartlyProhibitedForSpeedCams() const
|
||||
{
|
||||
return !m_speedCamPartlyProhibitedMwms.empty();
|
||||
}
|
||||
bool Route::CrossMwmsPartlyProhibitedForSpeedCams() const { return !m_speedCamPartlyProhibitedMwms.empty(); }
|
||||
|
||||
vector<platform::CountryFile> const & Route::GetMwmsPartlyProhibitedForSpeedCams() const
|
||||
{
|
||||
|
@ -551,6 +527,13 @@ std::string Route::DebugPrintTurns() const
|
|||
return res;
|
||||
}
|
||||
|
||||
std::shared_ptr<const Route> Routes::GetRoute(EdgeEstimator::Strategy strategy) { return *m_routes.Find(strategy); }
|
||||
|
||||
void Routes::SetRoute(EdgeEstimator::Strategy strategy, std::shared_ptr<Route> route)
|
||||
{
|
||||
m_routes.Insert(strategy, route);
|
||||
}
|
||||
|
||||
bool IsNormalTurn(TurnItem const & turn)
|
||||
{
|
||||
CHECK_NOT_EQUAL(turn.m_turn, CarDirection::Count, ());
|
||||
|
@ -559,8 +542,5 @@ bool IsNormalTurn(TurnItem const & turn)
|
|||
return !turn.IsTurnNone();
|
||||
}
|
||||
|
||||
string DebugPrint(Route const & r)
|
||||
{
|
||||
return DebugPrint(r.m_poly.GetPolyline());
|
||||
}
|
||||
} // namespace routing
|
||||
string DebugPrint(Route const & r) { return DebugPrint(r.m_poly.GetPolyline()); }
|
||||
} // namespace routing
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing/base/followed_polyline.hpp"
|
||||
#include "routing/edge_estimator.hpp"
|
||||
#include "routing/routing_options.hpp"
|
||||
#include "routing/routing_settings.hpp"
|
||||
#include "routing/segment.hpp"
|
||||
#include "routing/transit_info.hpp"
|
||||
#include "routing/turns.hpp"
|
||||
|
||||
#include "routing/base/followed_polyline.hpp"
|
||||
#include "traffic/speed_groups.hpp"
|
||||
|
||||
#include "routing_common/maxspeed_conversion.hpp"
|
||||
|
||||
#include "traffic/speed_groups.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
|
||||
#include "geometry/point_with_altitude.hpp"
|
||||
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/math.hpp"
|
||||
#include "base/small_map.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
@ -29,9 +30,9 @@
|
|||
|
||||
namespace location
|
||||
{
|
||||
class GpsInfo;
|
||||
class RouteMatchingInfo;
|
||||
}
|
||||
class GpsInfo;
|
||||
class RouteMatchingInfo;
|
||||
} // namespace location
|
||||
|
||||
namespace routing
|
||||
{
|
||||
|
@ -46,12 +47,9 @@ public:
|
|||
struct SpeedCamera
|
||||
{
|
||||
SpeedCamera() = default;
|
||||
SpeedCamera(double coef, uint8_t maxSpeedKmPH): m_coef(coef), m_maxSpeedKmPH(maxSpeedKmPH) {}
|
||||
SpeedCamera(double coef, uint8_t maxSpeedKmPH) : m_coef(coef), m_maxSpeedKmPH(maxSpeedKmPH) {}
|
||||
|
||||
bool EqualCoef(SpeedCamera const & rhs) const
|
||||
{
|
||||
return base::AlmostEqualAbs(m_coef, rhs.m_coef, 1.0E-5);
|
||||
}
|
||||
bool EqualCoef(SpeedCamera const & rhs) const { return base::AlmostEqualAbs(m_coef, rhs.m_coef, 1.0E-5); }
|
||||
|
||||
bool operator<(SpeedCamera const & rhs) const
|
||||
{
|
||||
|
@ -78,9 +76,9 @@ public:
|
|||
std::string m_destination_ref; // Number of next road, e.g. "CA 85", Sometimes "CA 85 South". Usually match |m_ref|
|
||||
// of next main road.
|
||||
// This is for 1st segment of link after junction. Exit |junction_ref| to |m_destination_ref| for |m_destination|.
|
||||
std::string m_junction_ref; // Number of junction e.g. "398B".
|
||||
std::string m_destination; // E.g. "Cupertino".
|
||||
std::string m_ref; // Number of street/road e.g. "CA 85".
|
||||
std::string m_junction_ref; // Number of junction e.g. "398B".
|
||||
std::string m_destination; // E.g. "Cupertino".
|
||||
std::string m_ref; // Number of street/road e.g. "CA 85".
|
||||
bool m_isLink = false;
|
||||
|
||||
RoadNameInfo() = default;
|
||||
|
@ -125,13 +123,9 @@ public:
|
|||
friend std::string DebugPrint(RoadNameInfo const & rni);
|
||||
};
|
||||
|
||||
RouteSegment(Segment const & segment, turns::TurnItem const & turn,
|
||||
geometry::PointWithAltitude const & junction, RoadNameInfo const & roadNameInfo)
|
||||
: m_segment(segment)
|
||||
, m_turn(turn)
|
||||
, m_junction(junction)
|
||||
, m_roadNameInfo(roadNameInfo)
|
||||
, m_transitInfo(nullptr)
|
||||
RouteSegment(Segment const & segment, turns::TurnItem const & turn, geometry::PointWithAltitude const & junction,
|
||||
RoadNameInfo const & roadNameInfo)
|
||||
: m_segment(segment), m_turn(turn), m_junction(junction), m_roadNameInfo(roadNameInfo), m_transitInfo(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -152,10 +146,7 @@ public:
|
|||
m_timeFromBeginningS = timeFromBeginningS;
|
||||
}
|
||||
|
||||
void SetTransitInfo(std::unique_ptr<TransitInfo> transitInfo)
|
||||
{
|
||||
m_transitInfo.Set(std::move(transitInfo));
|
||||
}
|
||||
void SetTransitInfo(std::unique_ptr<TransitInfo> transitInfo) { m_transitInfo.Set(std::move(transitInfo)); }
|
||||
|
||||
Segment const & GetSegment() const { return m_segment; }
|
||||
Segment & GetSegment() { return m_segment; }
|
||||
|
@ -231,13 +222,9 @@ public:
|
|||
public:
|
||||
SubrouteAttrs() = default;
|
||||
|
||||
SubrouteAttrs(geometry::PointWithAltitude const & start,
|
||||
geometry::PointWithAltitude const & finish, size_t beginSegmentIdx,
|
||||
size_t endSegmentIdx)
|
||||
: m_start(start)
|
||||
, m_finish(finish)
|
||||
, m_beginSegmentIdx(beginSegmentIdx)
|
||||
, m_endSegmentIdx(endSegmentIdx)
|
||||
SubrouteAttrs(geometry::PointWithAltitude const & start, geometry::PointWithAltitude const & finish,
|
||||
size_t beginSegmentIdx, size_t endSegmentIdx)
|
||||
: m_start(start), m_finish(finish), m_beginSegmentIdx(beginSegmentIdx), m_endSegmentIdx(endSegmentIdx)
|
||||
{
|
||||
CHECK_LESS_OR_EQUAL(beginSegmentIdx, endSegmentIdx, ());
|
||||
}
|
||||
|
@ -272,8 +259,7 @@ public:
|
|||
/// \brief For every subroute some attributes are kept in the following structure.
|
||||
struct SubrouteSettings final
|
||||
{
|
||||
SubrouteSettings(RoutingSettings const & routingSettings, std::string const & router,
|
||||
SubrouteUid id)
|
||||
SubrouteSettings(RoutingSettings const & routingSettings, std::string const & router, SubrouteUid id)
|
||||
: m_routingSettings(routingSettings), m_router(router), m_id(id)
|
||||
{
|
||||
}
|
||||
|
@ -292,17 +278,15 @@ public:
|
|||
|
||||
template <class TIter>
|
||||
Route(std::string const & router, TIter beg, TIter end, uint64_t routeId)
|
||||
: m_router(router)
|
||||
, m_routingSettings(GetRoutingSettings(VehicleType::Car))
|
||||
, m_poly(beg, end)
|
||||
, m_routeId(routeId)
|
||||
: m_router(router), m_routingSettings(GetRoutingSettings(VehicleType::Car)), m_poly(beg, end), m_routeId(routeId)
|
||||
{
|
||||
}
|
||||
|
||||
Route(std::string const & router, std::vector<m2::PointD> const & points, uint64_t routeId,
|
||||
std::string const & name = std::string());
|
||||
|
||||
template <class TIter> void SetGeometry(TIter beg, TIter end)
|
||||
template <class TIter>
|
||||
void SetGeometry(TIter beg, TIter end)
|
||||
{
|
||||
if (beg == end)
|
||||
{
|
||||
|
@ -327,6 +311,8 @@ public:
|
|||
std::vector<RouteSegment> const & GetRouteSegments() const { return m_routeSegments; }
|
||||
RoutingSettings const & GetCurrentRoutingSettings() const { return m_routingSettings; }
|
||||
|
||||
std::optional<EdgeEstimator::Strategy> GetStrategy() const { return m_strategy; }
|
||||
|
||||
void SetCurrentSubrouteIdx(size_t currentSubrouteIdx) { m_currentSubrouteIdx = currentSubrouteIdx; }
|
||||
|
||||
template <class V>
|
||||
|
@ -410,8 +396,7 @@ public:
|
|||
|
||||
/// \brief Finds projection of |location| to the nearest route and sets |routeMatchingInfo|.
|
||||
/// fields accordingly.
|
||||
bool MatchLocationToRoute(location::GpsInfo & location,
|
||||
location::RouteMatchingInfo & routeMatchingInfo) const;
|
||||
bool MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo) const;
|
||||
|
||||
/// Add country name if we have no country filename to make route.
|
||||
void AddAbsentCountry(std::string const & name);
|
||||
|
@ -419,10 +404,9 @@ public:
|
|||
/// Get absent file list of a routing files for shortest path finding.
|
||||
std::set<std::string> const & GetAbsentCountries() const { return m_absentCountries; }
|
||||
|
||||
inline void SetRoutingSettings(RoutingSettings const & routingSettings)
|
||||
{
|
||||
m_routingSettings = routingSettings;
|
||||
}
|
||||
inline void SetRoutingSettings(RoutingSettings const & routingSettings) { m_routingSettings = routingSettings; }
|
||||
|
||||
inline void SetStrategy(EdgeEstimator::Strategy strategy) { m_strategy = strategy; }
|
||||
|
||||
// Subroute interface.
|
||||
/// \returns Number of subroutes.
|
||||
|
@ -486,6 +470,7 @@ private:
|
|||
double GetCurrentTimeFromBeginSec() const;
|
||||
|
||||
std::string m_router;
|
||||
std::optional<EdgeEstimator::Strategy> m_strategy;
|
||||
RoutingSettings m_routingSettings;
|
||||
std::string m_name;
|
||||
|
||||
|
@ -507,7 +492,27 @@ private:
|
|||
std::vector<platform::CountryFile> m_speedCamPartlyProhibitedMwms;
|
||||
};
|
||||
|
||||
class Routes
|
||||
{
|
||||
public:
|
||||
// should this just be a regular const ref?
|
||||
std::shared_ptr<const Route> GetRoute(EdgeEstimator::Strategy strategy);
|
||||
void SetRoute(EdgeEstimator::Strategy strategy, std::shared_ptr<Route> route);
|
||||
|
||||
private:
|
||||
base::SmallMapBase<EdgeEstimator::Strategy, std::shared_ptr<Route>> m_routes;
|
||||
};
|
||||
|
||||
// NOTE: Should strategy just be included into Route, and avoid having this extra struct
|
||||
// or is this separation fine? If it is, then perhaps the name could be simplified to avoid such
|
||||
// verbosity. Or maybe use inheritance?
|
||||
// struct RouteWithStrategy
|
||||
// {
|
||||
// std::shared_ptr<Route> m_route;
|
||||
// EdgeEstimator::Strategy m_strategy;
|
||||
// };
|
||||
|
||||
/// \returns true if |turn| is not equal to turns::CarDirection::None or
|
||||
/// |turns::PedestrianDirection::None|.
|
||||
bool IsNormalTurn(turns::TurnItem const & turn);
|
||||
} // namespace routing
|
||||
} // namespace routing
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing/checkpoints.hpp"
|
||||
#include "routing/edge_estimator.hpp"
|
||||
#include "routing/road_graph.hpp"
|
||||
#include "routing/router_delegate.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
#include "routing/routing_options.hpp"
|
||||
|
||||
#include "kml/type_utils.hpp"
|
||||
|
||||
|
@ -62,6 +64,10 @@ public:
|
|||
/// Clear all temporary buffers.
|
||||
virtual void ClearState() {}
|
||||
|
||||
virtual void SetEstimatorOptions(RoutingOptions::RoadType options) {}
|
||||
|
||||
virtual void SetEstimatorStrategy(EdgeEstimator::Strategy strategy) {}
|
||||
|
||||
virtual void SetGuides(GuidesTracks && guides) = 0;
|
||||
|
||||
/// Override this function with routing implementation.
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing/turns.hpp"
|
||||
|
||||
#include "geometry/latlon.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
|
@ -9,7 +7,6 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
@ -45,16 +42,16 @@ enum class RouterResultCode
|
|||
|
||||
enum class SessionState
|
||||
{
|
||||
NoValidRoute, // No valid route: no route after application launching or the route was removed.
|
||||
RouteBuilding, // We requested a route and wait when it will be built. User may be following
|
||||
// the previous route.
|
||||
RouteNotStarted, // Route is built but the user isn't on it.
|
||||
OnRoute, // User follows the route.
|
||||
RouteNeedRebuild, // User left the route.
|
||||
RouteFinished, // Destination point is reached but the session isn't closed.
|
||||
RouteNoFollowing, // Route is built but following mode has been disabled.
|
||||
RouteRebuilding, // We requested a route rebuild and wait when it will be rebuilt.
|
||||
// User may following the previous route.
|
||||
NoValidRoute, // No valid route: no route after application launching or the route was removed.
|
||||
RouteBuilding, // We requested a route and wait when it will be built. User may be following
|
||||
// the previous route.
|
||||
RouteNotStarted, // Route is built but the user isn't on it.
|
||||
OnRoute, // User follows the route.
|
||||
RouteNeedRebuild, // User left the route.
|
||||
RouteFinished, // Destination point is reached but the session isn't closed.
|
||||
RouteNoFollowing, // Route is built but following mode has been disabled.
|
||||
RouteRebuilding, // We requested a route rebuild and wait when it will be rebuilt.
|
||||
// User may following the previous route.
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -113,10 +110,7 @@ inline std::string ToString(RouterResultCode code)
|
|||
return result;
|
||||
}
|
||||
|
||||
inline std::string DebugPrint(RouterResultCode code)
|
||||
{
|
||||
return ToString(code);
|
||||
}
|
||||
inline std::string DebugPrint(RouterResultCode code) { return ToString(code); }
|
||||
|
||||
// This define should be set to see the spread of A* waves on the map.
|
||||
// #define SHOW_ROUTE_DEBUG_MARKS
|
||||
|
|
|
@ -50,6 +50,11 @@ bool RoutingOptions::Has(RoutingOptions::Road type) const
|
|||
return (m_options & static_cast<RoadType>(type)) != 0;
|
||||
}
|
||||
|
||||
void RoutingOptions::SetOptions(RoadType options)
|
||||
{
|
||||
m_options = options;
|
||||
}
|
||||
|
||||
// RoutingOptionsClassifier ---------------------------------------------------------------------------
|
||||
|
||||
RoutingOptionsClassifier::RoutingOptionsClassifier()
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
bool Has(Road type) const;
|
||||
|
||||
RoadType GetOptions() const { return m_options; }
|
||||
void SetOptions(RoadType options);
|
||||
|
||||
private:
|
||||
RoadType m_options = 0;
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
#include "routing/routing_session.hpp"
|
||||
|
||||
#include "routing/routing_helpers.hpp"
|
||||
#include "routing/speed_camera.hpp"
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
|
||||
#include "platform/distance.hpp"
|
||||
#include "platform/location.hpp"
|
||||
#include "platform/measurement_utils.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "platform/distance.hpp"
|
||||
|
||||
#include "geometry/angles.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace
|
||||
|
@ -45,7 +42,7 @@ void FormatDistance(double dist, std::string & value, std::string & suffix)
|
|||
|
||||
RoutingSession::RoutingSession()
|
||||
: m_router(nullptr)
|
||||
, m_route(std::make_shared<Route>(std::string{} /* router */, 0 /* route id */))
|
||||
, m_active_route(std::make_shared<Route>(std::string{} /* router */, 0 /* route id */))
|
||||
, m_state(SessionState::NoValidRoute)
|
||||
, m_isFollowing(false)
|
||||
, m_speedCameraManager(m_turnNotificationsMgr)
|
||||
|
@ -55,7 +52,7 @@ RoutingSession::RoutingSession()
|
|||
{
|
||||
// To call |m_changeSessionStateCallback| on |m_state| initialization.
|
||||
SetState(SessionState::NoValidRoute);
|
||||
m_speedCameraManager.SetRoute(m_route);
|
||||
m_speedCameraManager.SetRoute(m_active_route);
|
||||
}
|
||||
|
||||
void RoutingSession::Init(PointCheckCallback const & pointCheckCallback)
|
||||
|
@ -73,35 +70,34 @@ void RoutingSession::BuildRoute(Checkpoints const & checkpoints, uint32_t timeou
|
|||
m_router->ClearState();
|
||||
|
||||
m_isFollowing = false;
|
||||
m_routingRebuildCount = -1; // -1 for the first rebuild.
|
||||
m_routingRebuildCount = -1; // -1 for the first rebuild.
|
||||
|
||||
RebuildRoute(checkpoints.GetStart(), m_buildReadyCallback, m_needMoreMapsCallback,
|
||||
m_removeRouteCallback, timeoutSec, SessionState::RouteBuilding, false /* adjust */);
|
||||
RebuildRoute(checkpoints.GetStart(), m_buildReadyCallback, m_needMoreMapsCallback, m_removeRouteCallback, timeoutSec,
|
||||
SessionState::RouteBuilding, false /* adjust */);
|
||||
}
|
||||
|
||||
void RoutingSession::RebuildRoute(m2::PointD const & startPoint,
|
||||
ReadyCallback const & readyCallback,
|
||||
void RoutingSession::RebuildRoute(m2::PointD const & startPoint, ReadyCallback const & readyCallback,
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback,
|
||||
uint32_t timeoutSec, SessionState routeRebuildingState,
|
||||
bool adjustToPrevRoute)
|
||||
RemoveRouteCallback const & removeRouteCallback, uint32_t timeoutSec,
|
||||
SessionState routeRebuildingState, bool adjustToPrevRoute)
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
CHECK(m_router, ());
|
||||
SetState(routeRebuildingState);
|
||||
|
||||
++m_routingRebuildCount;
|
||||
auto const & direction = m_routingSettings.m_useDirectionForRouteBuilding
|
||||
? m_positionAccumulator.GetDirection()
|
||||
: m2::PointD::Zero();
|
||||
auto const & direction =
|
||||
m_routingSettings.m_useDirectionForRouteBuilding ? m_positionAccumulator.GetDirection() : m2::PointD::Zero();
|
||||
|
||||
Checkpoints checkpoints(m_checkpoints);
|
||||
checkpoints.SetPointFrom(startPoint);
|
||||
|
||||
// NOTE: purposefully clunky way to enumerate strategies; this will need to be revisited later
|
||||
// Use old-style callback construction, because lambda constructs buggy function on Android
|
||||
// (callback param isn't captured by value).
|
||||
m_router->CalculateRoute(checkpoints, direction, adjustToPrevRoute,
|
||||
DoReadyCallback(*this, readyCallback), needMoreMapsCallback,
|
||||
removeRouteCallback, m_progressCallback, timeoutSec);
|
||||
m_router->CalculateRoute(
|
||||
checkpoints, direction, adjustToPrevRoute, {EdgeEstimator::Strategy::Fastest, EdgeEstimator::Strategy::Shortest},
|
||||
DoReadyCallback(*this, readyCallback), needMoreMapsCallback, removeRouteCallback, m_progressCallback, timeoutSec);
|
||||
}
|
||||
|
||||
m2::PointD RoutingSession::GetStartPoint() const
|
||||
|
@ -118,9 +114,9 @@ m2::PointD RoutingSession::GetEndPoint() const
|
|||
|
||||
void RoutingSession::DoReadyCallback::operator()(std::shared_ptr<Route> const & route, RouterResultCode e)
|
||||
{
|
||||
ASSERT(m_rs.m_route, ());
|
||||
ASSERT(m_rs.m_active_route, ());
|
||||
m_rs.AssignRoute(route, e);
|
||||
m_callback(*m_rs.m_route, e);
|
||||
m_callback(*m_rs.m_active_route, e);
|
||||
}
|
||||
|
||||
void RoutingSession::RemoveRoute()
|
||||
|
@ -131,9 +127,9 @@ void RoutingSession::RemoveRoute()
|
|||
m_moveAwayCounter = 0;
|
||||
m_turnNotificationsMgr.Reset();
|
||||
|
||||
m_route = std::make_shared<Route>(std::string{} /* router */, 0 /* route id */);
|
||||
m_active_route = std::make_shared<Route>(std::string{} /* router */, 0 /* route id */);
|
||||
m_speedCameraManager.Reset();
|
||||
m_speedCameraManager.SetRoute(m_route);
|
||||
m_speedCameraManager.SetRoute(m_active_route);
|
||||
}
|
||||
|
||||
void RoutingSession::RebuildRouteOnTrafficUpdate()
|
||||
|
@ -152,9 +148,7 @@ void RoutingSession::RebuildRouteOnTrafficUpdate()
|
|||
case SessionState::RouteBuilding:
|
||||
case SessionState::RouteNotStarted:
|
||||
case SessionState::RouteNoFollowing:
|
||||
case SessionState::RouteRebuilding:
|
||||
startPoint = m_checkpoints.GetPointFrom();
|
||||
break;
|
||||
case SessionState::RouteRebuilding: startPoint = m_checkpoints.GetPointFrom(); break;
|
||||
|
||||
case SessionState::OnRoute:
|
||||
case SessionState::RouteNeedRebuild: break;
|
||||
|
@ -165,8 +159,8 @@ void RoutingSession::RebuildRouteOnTrafficUpdate()
|
|||
}
|
||||
|
||||
RebuildRoute(startPoint, m_rebuildReadyCallback, nullptr /* needMoreMapsCallback */,
|
||||
nullptr /* removeRouteCallback */, RouterDelegate::kNoTimeout,
|
||||
SessionState::RouteRebuilding, false /* adjustToPrevRoute */);
|
||||
nullptr /* removeRouteCallback */, RouterDelegate::kNoTimeout, SessionState::RouteRebuilding,
|
||||
false /* adjustToPrevRoute */);
|
||||
}
|
||||
|
||||
bool RoutingSession::IsActive() const
|
||||
|
@ -265,17 +259,17 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info)
|
|||
return m_state;
|
||||
}
|
||||
|
||||
CHECK(m_route, (m_state));
|
||||
CHECK(m_active_route, (m_state));
|
||||
// Note. The route may not be valid here. It happens in case when while the first route
|
||||
// build is cancelled because of traffic jam were downloaded. After that route rebuilding
|
||||
// happens. While the rebuilding may be called OnLocationPositionChanged(...)
|
||||
if (!m_route->IsValid())
|
||||
if (!m_active_route->IsValid())
|
||||
return m_state;
|
||||
|
||||
m_turnNotificationsMgr.SetSpeedMetersPerSecond(info.m_speedMpS);
|
||||
|
||||
auto const formerIter = m_route->GetCurrentIteratorTurn();
|
||||
if (m_route->MoveIterator(info))
|
||||
auto const formerIter = m_active_route->GetCurrentIteratorTurn();
|
||||
if (m_active_route->MoveIterator(info))
|
||||
{
|
||||
m_moveAwayCounter = 0;
|
||||
m_lastDistance = 0.0;
|
||||
|
@ -284,7 +278,7 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info)
|
|||
|
||||
if (m_checkpoints.IsFinished())
|
||||
{
|
||||
m_passedDistanceOnRouteMeters += m_route->GetTotalDistanceMeters();
|
||||
m_passedDistanceOnRouteMeters += m_active_route->GetTotalDistanceMeters();
|
||||
SetState(SessionState::RouteFinished);
|
||||
}
|
||||
else
|
||||
|
@ -296,11 +290,10 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info)
|
|||
if (m_userCurrentPositionValid)
|
||||
m_lastGoodPosition = m_userCurrentPosition;
|
||||
|
||||
auto const curIter = m_route->GetCurrentIteratorTurn();
|
||||
auto const curIter = m_active_route->GetCurrentIteratorTurn();
|
||||
// If we are moving to the next segment after passing the turn
|
||||
// it means the turn is changed. So the |m_onNewTurn| should be called.
|
||||
if (formerIter && curIter && IsNormalTurn(*formerIter) &&
|
||||
formerIter->m_index < curIter->m_index && m_onNewTurn)
|
||||
if (formerIter && curIter && IsNormalTurn(*formerIter) && formerIter->m_index < curIter->m_index && m_onNewTurn)
|
||||
{
|
||||
m_onNewTurn();
|
||||
}
|
||||
|
@ -312,9 +305,9 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info)
|
|||
{
|
||||
// Distance from the last known projection on route
|
||||
// (check if we are moving far from the last known projection).
|
||||
auto const & lastGoodPoint = m_route->GetFollowedPolyline().GetCurrentIter().m_pt;
|
||||
double const dist = mercator::DistanceOnEarth(lastGoodPoint,
|
||||
mercator::FromLatLon(info.m_latitude, info.m_longitude));
|
||||
auto const & lastGoodPoint = m_active_route->GetFollowedPolyline().GetCurrentIter().m_pt;
|
||||
double const dist =
|
||||
mercator::DistanceOnEarth(lastGoodPoint, mercator::FromLatLon(info.m_latitude, info.m_longitude));
|
||||
if (base::AlmostEqualAbs(dist, m_lastDistance, kRunawayDistanceSensitivityMeters))
|
||||
return m_state;
|
||||
|
||||
|
@ -327,7 +320,7 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info)
|
|||
|
||||
if (m_moveAwayCounter > kOnRouteMissedCount)
|
||||
{
|
||||
m_passedDistanceOnRouteMeters += m_route->GetCurrentDistanceFromBeginMeters();
|
||||
m_passedDistanceOnRouteMeters += m_active_route->GetCurrentDistanceFromBeginMeters();
|
||||
SetState(SessionState::RouteNeedRebuild);
|
||||
}
|
||||
}
|
||||
|
@ -374,9 +367,9 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
|
|||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
|
||||
ASSERT(m_route, ());
|
||||
ASSERT(m_active_route, ());
|
||||
|
||||
if (!m_route->IsValid())
|
||||
if (!m_active_route->IsValid())
|
||||
{
|
||||
// nothing should be displayed on the screen about turns if these lines are executed
|
||||
info = FollowingInfo();
|
||||
|
@ -386,22 +379,21 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
|
|||
if (!IsNavigable())
|
||||
{
|
||||
info = FollowingInfo();
|
||||
info.m_distToTarget = platform::Distance::CreateFormatted(m_route->GetTotalDistanceMeters());
|
||||
info.m_time = static_cast<int>(std::max(kMinimumETASec, m_route->GetCurrentTimeToEndSec()));
|
||||
info.m_distToTarget = platform::Distance::CreateFormatted(m_active_route->GetTotalDistanceMeters());
|
||||
info.m_time = static_cast<int>(std::max(kMinimumETASec, m_active_route->GetCurrentTimeToEndSec()));
|
||||
return;
|
||||
}
|
||||
|
||||
info.m_distToTarget =
|
||||
platform::Distance::CreateFormatted(m_route->GetCurrentDistanceToEndMeters());
|
||||
info.m_distToTarget = platform::Distance::CreateFormatted(m_active_route->GetCurrentDistanceToEndMeters());
|
||||
|
||||
double distanceToTurnMeters = 0.;
|
||||
turns::TurnItem turn;
|
||||
m_route->GetNearestTurn(distanceToTurnMeters, turn);
|
||||
m_active_route->GetNearestTurn(distanceToTurnMeters, turn);
|
||||
info.m_distToTurn = platform::Distance::CreateFormatted(distanceToTurnMeters);
|
||||
info.m_turn = turn.m_turn;
|
||||
|
||||
SpeedInUnits speedLimit;
|
||||
m_route->GetCurrentSpeedLimit(speedLimit);
|
||||
m_active_route->GetCurrentSpeedLimit(speedLimit);
|
||||
if (speedLimit.IsNumeric())
|
||||
info.m_speedLimitMps = measurement_utils::KmphToMps(speedLimit.GetSpeedKmPH());
|
||||
else if (speedLimit.GetSpeed() == kNoneMaxSpeed)
|
||||
|
@ -416,20 +408,20 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
|
|||
info.m_nextTurn = routing::turns::CarDirection::None;
|
||||
|
||||
info.m_exitNum = turn.m_exitNum;
|
||||
info.m_time = static_cast<int>(std::max(kMinimumETASec, m_route->GetCurrentTimeToEndSec()));
|
||||
info.m_time = static_cast<int>(std::max(kMinimumETASec, m_active_route->GetCurrentTimeToEndSec()));
|
||||
RouteSegment::RoadNameInfo currentRoadNameInfo, nextRoadNameInfo, nextNextRoadNameInfo;
|
||||
m_route->GetCurrentStreetName(currentRoadNameInfo);
|
||||
m_active_route->GetCurrentStreetName(currentRoadNameInfo);
|
||||
GetFullRoadName(currentRoadNameInfo, info.m_currentStreetName);
|
||||
m_route->GetNextTurnStreetName(nextRoadNameInfo);
|
||||
m_active_route->GetNextTurnStreetName(nextRoadNameInfo);
|
||||
GetFullRoadName(nextRoadNameInfo, info.m_nextStreetName);
|
||||
m_route->GetNextNextTurnStreetName(nextNextRoadNameInfo);
|
||||
m_active_route->GetNextNextTurnStreetName(nextNextRoadNameInfo);
|
||||
GetFullRoadName(nextNextRoadNameInfo, info.m_nextNextStreetName);
|
||||
|
||||
info.m_completionPercent = GetCompletionPercent();
|
||||
|
||||
// Lane information
|
||||
info.m_lanes.clear();
|
||||
if (distanceToTurnMeters < kShowLanesMinDistInMeters || m_route->GetCurrentTimeToNearestTurnSec() < 60.0)
|
||||
if (distanceToTurnMeters < kShowLanesMinDistInMeters || m_active_route->GetCurrentTimeToNearestTurnSec() < 60.0)
|
||||
{
|
||||
// There are two nested loops below. Outer one is for lanes and inner one (ctor of
|
||||
// SingleLaneInfo) is
|
||||
|
@ -441,23 +433,21 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
|
|||
}
|
||||
|
||||
// Pedestrian info.
|
||||
info.m_pedestrianTurn = (distanceToTurnMeters < kShowPedestrianTurnInMeters)
|
||||
? turn.m_pedestrianTurn
|
||||
: turns::PedestrianDirection::None;
|
||||
info.m_pedestrianTurn =
|
||||
(distanceToTurnMeters < kShowPedestrianTurnInMeters) ? turn.m_pedestrianTurn : turns::PedestrianDirection::None;
|
||||
}
|
||||
|
||||
double RoutingSession::GetCompletionPercent() const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
ASSERT(m_route, ());
|
||||
ASSERT(m_active_route, ());
|
||||
|
||||
double const denominator = m_passedDistanceOnRouteMeters + m_route->GetTotalDistanceMeters();
|
||||
if (!m_route->IsValid() || denominator == 0.0)
|
||||
double const denominator = m_passedDistanceOnRouteMeters + m_active_route->GetTotalDistanceMeters();
|
||||
if (!m_active_route->IsValid() || denominator == 0.0)
|
||||
return 0;
|
||||
|
||||
double const percent =
|
||||
100.0 * (m_passedDistanceOnRouteMeters + m_route->GetCurrentDistanceFromBeginMeters()) /
|
||||
denominator;
|
||||
100.0 * (m_passedDistanceOnRouteMeters + m_active_route->GetCurrentDistanceFromBeginMeters()) / denominator;
|
||||
if (percent - m_lastCompletionPercent > kCompletionPercentAccuracy)
|
||||
{
|
||||
m_lastCompletionPercent = percent;
|
||||
|
@ -468,9 +458,9 @@ double RoutingSession::GetCompletionPercent() const
|
|||
void RoutingSession::PassCheckpoints()
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
while (!m_checkpoints.IsFinished() && m_route->IsSubroutePassed(m_checkpoints.GetPassedIdx()))
|
||||
while (!m_checkpoints.IsFinished() && m_active_route->IsSubroutePassed(m_checkpoints.GetPassedIdx()))
|
||||
{
|
||||
m_route->PassNextSubroute();
|
||||
m_active_route->PassNextSubroute();
|
||||
m_checkpoints.PassNextPoint();
|
||||
LOG(LINFO, ("Pass checkpoint, ", m_checkpoints));
|
||||
m_checkpointCallback(m_checkpoints.GetPassedIdx());
|
||||
|
@ -482,24 +472,24 @@ void RoutingSession::GenerateNotifications(std::vector<std::string> & notificati
|
|||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
notifications.clear();
|
||||
|
||||
ASSERT(m_route, ());
|
||||
ASSERT(m_active_route, ());
|
||||
|
||||
// Voice turn notifications.
|
||||
if (!m_routingSettings.m_soundDirection)
|
||||
return;
|
||||
|
||||
if (!m_route->IsValid() || !IsNavigable())
|
||||
if (!m_active_route->IsValid() || !IsNavigable())
|
||||
return;
|
||||
|
||||
// Generate turns notifications.
|
||||
std::vector<turns::TurnItemDist> turns;
|
||||
if (m_route->GetNextTurns(turns))
|
||||
if (m_active_route->GetNextTurns(turns))
|
||||
{
|
||||
RouteSegment::RoadNameInfo nextStreetInfo;
|
||||
|
||||
// only populate nextStreetInfo if TtsStreetNames is enabled
|
||||
if (announceStreets)
|
||||
m_route->GetNextTurnStreetName(nextStreetInfo);
|
||||
m_active_route->GetNextTurnStreetName(nextStreetInfo);
|
||||
|
||||
m_turnNotificationsMgr.GenerateTurnNotifications(turns, notifications, nextStreetInfo);
|
||||
}
|
||||
|
@ -515,7 +505,7 @@ void RoutingSession::AssignRoute(std::shared_ptr<Route> const & route, RouterRes
|
|||
{
|
||||
// Route building was not success. If the former route is valid let's continue moving along it.
|
||||
// If not, let's set corresponding state.
|
||||
if (m_route->IsValid())
|
||||
if (m_active_route->IsValid())
|
||||
SetState(SessionState::OnRoute);
|
||||
else
|
||||
SetState(SessionState::NoValidRoute);
|
||||
|
@ -528,13 +518,15 @@ void RoutingSession::AssignRoute(std::shared_ptr<Route> const & route, RouterRes
|
|||
m_checkpoints.SetPointFrom(route->GetPoly().Front());
|
||||
|
||||
route->SetRoutingSettings(m_routingSettings);
|
||||
m_route = route;
|
||||
m_active_route = route;
|
||||
auto strategy = route->GetStrategy();
|
||||
// if (strategy)
|
||||
// m_routes->SetRoute(strategy.value(), route);
|
||||
m_speedCameraManager.Reset();
|
||||
m_speedCameraManager.SetRoute(m_route);
|
||||
m_speedCameraManager.SetRoute(m_active_route);
|
||||
}
|
||||
|
||||
void RoutingSession::SetRouter(std::unique_ptr<IRouter> && router,
|
||||
std::unique_ptr<AbsentRegionsFinder> && finder)
|
||||
void RoutingSession::SetRouter(std::unique_ptr<IRouter> && router, std::unique_ptr<AbsentRegionsFinder> && finder)
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
ASSERT(m_router != nullptr, ());
|
||||
|
@ -545,7 +537,7 @@ void RoutingSession::SetRouter(std::unique_ptr<IRouter> && router,
|
|||
void RoutingSession::MatchLocationToRoadGraph(location::GpsInfo & location)
|
||||
{
|
||||
auto const locationMerc = mercator::FromLatLon(location.m_latitude, location.m_longitude);
|
||||
double const radius = m_route->GetCurrentRoutingSettings().m_matchingThresholdM;
|
||||
double const radius = m_active_route->GetCurrentRoutingSettings().m_matchingThresholdM;
|
||||
|
||||
m2::PointD const direction = m_positionAccumulator.GetDirection();
|
||||
|
||||
|
@ -570,12 +562,11 @@ void RoutingSession::MatchLocationToRoadGraph(location::GpsInfo & location)
|
|||
|
||||
if (m_proj.m_edge.GetFeatureId() == proj.m_edge.GetFeatureId())
|
||||
{
|
||||
if (m_route->GetCurrentRoutingSettings().m_matchRoute)
|
||||
if (m_active_route->GetCurrentRoutingSettings().m_matchRoute)
|
||||
{
|
||||
if (!base::AlmostEqualAbs(m_proj.m_point, proj.m_point, kEps))
|
||||
{
|
||||
location.m_bearing =
|
||||
location::AngleToBearing(base::RadToDeg(ang::AngleTo(m_proj.m_point, proj.m_point)));
|
||||
location.m_bearing = location::AngleToBearing(base::RadToDeg(ang::AngleTo(m_proj.m_point, proj.m_point)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,24 +581,22 @@ void RoutingSession::MatchLocationToRoadGraph(location::GpsInfo & location)
|
|||
m_proj = proj;
|
||||
}
|
||||
|
||||
bool RoutingSession::MatchLocationToRoute(location::GpsInfo & location,
|
||||
location::RouteMatchingInfo & routeMatchingInfo)
|
||||
bool RoutingSession::MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo)
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
if (!IsOnRoute())
|
||||
return true;
|
||||
|
||||
ASSERT(m_route, ());
|
||||
ASSERT(m_active_route, ());
|
||||
|
||||
bool const matchedToRoute = m_route->MatchLocationToRoute(location, routeMatchingInfo);
|
||||
bool const matchedToRoute = m_active_route->MatchLocationToRoute(location, routeMatchingInfo);
|
||||
if (matchedToRoute)
|
||||
m_projectedToRoadGraph = false;
|
||||
|
||||
return matchedToRoute;
|
||||
}
|
||||
|
||||
traffic::SpeedGroup RoutingSession::MatchTraffic(
|
||||
location::RouteMatchingInfo const & routeMatchingInfo) const
|
||||
traffic::SpeedGroup RoutingSession::MatchTraffic(location::RouteMatchingInfo const & routeMatchingInfo) const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
if (!routeMatchingInfo.IsMatched())
|
||||
|
@ -615,7 +604,7 @@ traffic::SpeedGroup RoutingSession::MatchTraffic(
|
|||
|
||||
size_t const index = routeMatchingInfo.GetIndexInRoute();
|
||||
|
||||
return m_route->GetTraffic(index);
|
||||
return m_active_route->GetTraffic(index);
|
||||
}
|
||||
|
||||
bool RoutingSession::DisableFollowMode()
|
||||
|
@ -685,8 +674,7 @@ void RoutingSession::SetCheckpointCallback(CheckpointCallback const & checkpoint
|
|||
m_checkpointCallback = checkpointCallback;
|
||||
}
|
||||
|
||||
void RoutingSession::SetChangeSessionStateCallback(
|
||||
ChangeSessionStateCallback const & changeSessionStateCallback)
|
||||
void RoutingSession::SetChangeSessionStateCallback(ChangeSessionStateCallback const & changeSessionStateCallback)
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
m_changeSessionStateCallback = changeSessionStateCallback;
|
||||
|
@ -753,16 +741,16 @@ std::string RoutingSession::GetTurnNotificationsLocale() const
|
|||
void RoutingSession::RouteCall(RouteCallback const & callback) const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
CHECK(m_route, ());
|
||||
callback(*m_route);
|
||||
CHECK(m_active_route, ());
|
||||
callback(*m_active_route);
|
||||
}
|
||||
|
||||
void RoutingSession::EmitCloseRoutingEvent() const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
ASSERT(m_route, ());
|
||||
ASSERT(m_active_route, ());
|
||||
|
||||
if (!m_route->IsValid())
|
||||
if (!m_active_route->IsValid())
|
||||
{
|
||||
ASSERT(false, ());
|
||||
return;
|
||||
|
@ -772,31 +760,31 @@ void RoutingSession::EmitCloseRoutingEvent() const
|
|||
bool RoutingSession::HasRouteAltitude() const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
ASSERT(m_route, ());
|
||||
return m_route->HaveAltitudes();
|
||||
ASSERT(m_active_route, ());
|
||||
return m_active_route->HaveAltitudes();
|
||||
}
|
||||
|
||||
bool RoutingSession::IsRouteId(uint64_t routeId) const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
return m_route->IsRouteId(routeId);
|
||||
return m_active_route->IsRouteId(routeId);
|
||||
}
|
||||
|
||||
bool RoutingSession::IsRouteValid() const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
return m_route && m_route->IsValid();
|
||||
return m_active_route && m_active_route->IsValid();
|
||||
}
|
||||
|
||||
bool RoutingSession::GetRouteJunctionPoints(std::vector<m2::PointD> & routeJunctionPoints) const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
ASSERT(m_route, ());
|
||||
ASSERT(m_active_route, ());
|
||||
|
||||
if (!m_route->IsValid())
|
||||
if (!m_active_route->IsValid())
|
||||
return false;
|
||||
|
||||
auto const & segments = m_route->GetRouteSegments();
|
||||
auto const & segments = m_active_route->GetRouteSegments();
|
||||
routeJunctionPoints.reserve(segments.size());
|
||||
|
||||
for (size_t i = 0; i < segments.size(); ++i)
|
||||
|
@ -813,17 +801,17 @@ bool RoutingSession::GetRouteAltitudesAndDistancesM(std::vector<double> & routeS
|
|||
geometry::Altitudes & routeAltitudesM) const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
ASSERT(m_route, ());
|
||||
ASSERT(m_active_route, ());
|
||||
|
||||
if (!m_route->IsValid() || !m_route->HaveAltitudes())
|
||||
if (!m_active_route->IsValid() || !m_active_route->HaveAltitudes())
|
||||
return false;
|
||||
|
||||
auto const & distances = m_route->GetSegDistanceMeters();
|
||||
auto const & distances = m_active_route->GetSegDistanceMeters();
|
||||
routeSegDistanceM.reserve(distances.size() + 1);
|
||||
routeSegDistanceM.push_back(0);
|
||||
routeSegDistanceM.insert(routeSegDistanceM.end(), distances.begin(), distances.end());
|
||||
|
||||
m_route->GetAltitudes(routeAltitudesM);
|
||||
m_active_route->GetAltitudes(routeAltitudesM);
|
||||
|
||||
ASSERT_EQUAL(routeSegDistanceM.size(), routeAltitudesM.size(), ());
|
||||
return true;
|
||||
|
@ -848,19 +836,23 @@ void RoutingSession::OnTrafficInfoAdded(TrafficInfo && info)
|
|||
|
||||
// Note. |coloring| should not be used after this call on gui thread.
|
||||
auto const mwmId = info.GetMwmId();
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [this, mwmId, coloring]() {
|
||||
Set(mwmId, coloring);
|
||||
RebuildRouteOnTrafficUpdate();
|
||||
});
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[this, mwmId, coloring]()
|
||||
{
|
||||
Set(mwmId, coloring);
|
||||
RebuildRouteOnTrafficUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
void RoutingSession::OnTrafficInfoRemoved(MwmSet::MwmId const & mwmId)
|
||||
{
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [this, mwmId]() {
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
Remove(mwmId);
|
||||
RebuildRouteOnTrafficUpdate();
|
||||
});
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[this, mwmId]()
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
Remove(mwmId);
|
||||
RebuildRouteOnTrafficUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
void RoutingSession::CopyTraffic(traffic::AllMwmTrafficInfo & trafficColoring) const
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
#include "routing/route.hpp"
|
||||
#include "routing/router.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
#include "routing/speed_camera.hpp"
|
||||
#include "routing/speed_camera_manager.hpp"
|
||||
#include "routing/turns.hpp"
|
||||
#include "routing/turns_notification_manager.hpp"
|
||||
|
||||
#include "traffic/speed_groups.hpp"
|
||||
|
@ -21,16 +18,11 @@
|
|||
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/point_with_altitude.hpp"
|
||||
#include "geometry/polyline2d.hpp"
|
||||
|
||||
#include "base/thread_checker.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
|
||||
namespace location
|
||||
|
@ -52,16 +44,14 @@ public:
|
|||
|
||||
void Init(PointCheckCallback const & pointCheckCallback);
|
||||
|
||||
void SetRouter(std::unique_ptr<IRouter> && router,
|
||||
std::unique_ptr<AbsentRegionsFinder> && finder);
|
||||
void SetRouter(std::unique_ptr<IRouter> && router, std::unique_ptr<AbsentRegionsFinder> && finder);
|
||||
|
||||
/// @param[in] checkpoints in mercator
|
||||
/// @param[in] timeoutSec timeout in seconds, if zero then there is no timeout
|
||||
void BuildRoute(Checkpoints const & checkpoints, uint32_t timeoutSec);
|
||||
void RebuildRoute(m2::PointD const & startPoint, ReadyCallback const & readyCallback,
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback, uint32_t timeoutSec,
|
||||
SessionState routeRebuildingState, bool adjustToPrevRoute);
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback, RemoveRouteCallback const & removeRouteCallback,
|
||||
uint32_t timeoutSec, SessionState routeRebuildingState, bool adjustToPrevRoute);
|
||||
|
||||
m2::PointD GetStartPoint() const;
|
||||
m2::PointD GetEndPoint() const;
|
||||
|
@ -101,8 +91,7 @@ public:
|
|||
SessionState OnLocationPositionChanged(location::GpsInfo const & info);
|
||||
void GetRouteFollowingInfo(FollowingInfo & info) const;
|
||||
|
||||
bool MatchLocationToRoute(location::GpsInfo & location,
|
||||
location::RouteMatchingInfo & routeMatchingInfo);
|
||||
bool MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo);
|
||||
void MatchLocationToRoadGraph(location::GpsInfo & location);
|
||||
// Get traffic speed for the current route position.
|
||||
// Returns SpeedGroup::Unknown if any trouble happens: position doesn't match with route or something else.
|
||||
|
@ -125,8 +114,7 @@ public:
|
|||
bool EnableFollowMode();
|
||||
|
||||
void SetRoutingSettings(RoutingSettings const & routingSettings);
|
||||
void SetRoutingCallbacks(ReadyCallback const & buildReadyCallback,
|
||||
ReadyCallback const & rebuildReadyCallback,
|
||||
void SetRoutingCallbacks(ReadyCallback const & buildReadyCallback, ReadyCallback const & rebuildReadyCallback,
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback);
|
||||
void SetProgressCallback(ProgressCallback const & progressCallback);
|
||||
|
@ -169,7 +157,7 @@ public:
|
|||
SpeedCameraManager & GetSpeedCamManager() { return m_speedCameraManager; }
|
||||
SpeedCameraManager const & GetSpeedCamManager() const { return m_speedCameraManager; }
|
||||
|
||||
std::shared_ptr<Route> GetRouteForTests() const { return m_route; }
|
||||
std::shared_ptr<Route> GetRouteForTests() const { return m_active_route; }
|
||||
void SetGuidesForTests(GuidesTracks guides) { m_router->SetGuidesTracks(std::move(guides)); }
|
||||
|
||||
double GetCompletionPercent() const;
|
||||
|
@ -180,9 +168,7 @@ private:
|
|||
RoutingSession & m_rs;
|
||||
ReadyCallback m_callback;
|
||||
|
||||
DoReadyCallback(RoutingSession & rs, ReadyCallback const & cb)
|
||||
: m_rs(rs), m_callback(cb)
|
||||
{}
|
||||
DoReadyCallback(RoutingSession & rs, ReadyCallback const & cb) : m_rs(rs), m_callback(cb) {}
|
||||
|
||||
void operator()(std::shared_ptr<Route> const & route, RouterResultCode e);
|
||||
};
|
||||
|
@ -196,7 +182,8 @@ private:
|
|||
|
||||
private:
|
||||
std::unique_ptr<AsyncRouter> m_router;
|
||||
std::shared_ptr<Route> m_route;
|
||||
std::unique_ptr<Routes> m_routes;
|
||||
std::shared_ptr<Route> m_active_route;
|
||||
SessionState m_state;
|
||||
bool m_isFollowing;
|
||||
Checkpoints m_checkpoints;
|
||||
|
@ -233,7 +220,7 @@ private:
|
|||
// Passed distance on route including reroutes
|
||||
double m_passedDistanceOnRouteMeters = 0.0;
|
||||
// Rerouting count
|
||||
int m_routingRebuildCount = -1; // -1 for the first rebuild called in BuildRoute().
|
||||
int m_routingRebuildCount = -1; // -1 for the first rebuild called in BuildRoute().
|
||||
mutable double m_lastCompletionPercent = 0.0;
|
||||
|
||||
DECLARE_THREAD_CHECKER(m_threadChecker);
|
||||
|
|
|
@ -146,6 +146,7 @@ double WeightedEdgeEstimator::CalcSegmentWeight(Segment const & segment,
|
|||
}
|
||||
|
||||
double WeightedEdgeEstimator::GetUTurnPenalty(Purpose purpose) const { return 0.0; }
|
||||
double WeightedEdgeEstimator::GetTurnPenalty(Purpose purpose) const { return 0.0; }
|
||||
double WeightedEdgeEstimator::GetFerryLandingPenalty(Purpose purpose) const { return 0.0; }
|
||||
|
||||
// TestIndexGraphTopology --------------------------------------------------------------------------
|
||||
|
|
|
@ -181,6 +181,7 @@ public:
|
|||
EdgeEstimator::Purpose purpose) const override;
|
||||
|
||||
double GetUTurnPenalty(Purpose purpose) const override;
|
||||
double GetTurnPenalty(Purpose purpose) const override;
|
||||
double GetFerryLandingPenalty(Purpose purpose) const override;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Add table
Reference in a new issue