[ios] Red for over speed; Speed limit for Carplay
iPhone: - Red speed digits for overspeed. CarPlay: - Show speed limit. - Red speed digits for overspeed. - Blinking for speed cam. Continuation of refactoring to unify all speed conversions and related localizations. Use MeterPerSecond everywhere. Use numeric speed instead of string. Rename of SpeedLimit to SpeedCamLimit to not confuse with usual limits (not speed cam). Signed-off-by: Anton Makouski <anton.makouski@gmail.com>
This commit is contained in:
parent
98c5c1b1c0
commit
de6ff3ce4c
28 changed files with 344 additions and 271 deletions
|
@ -1202,7 +1202,7 @@ Java_com_mapswithme_maps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jcl
|
|||
}
|
||||
|
||||
auto const & rm = frm()->GetRoutingManager();
|
||||
auto const isSpeedLimitExceeded = rm.IsRoutingActive() ? rm.IsSpeedLimitExceeded() : false;
|
||||
auto const isSpeedLimitExceeded = rm.IsRoutingActive() ? rm.IsSpeedCamLimitExceeded() : false;
|
||||
auto const shouldPlaySignal = frm()->GetRoutingManager().GetSpeedCamManager().ShouldPlayBeepSignal();
|
||||
jobject const result = env->NewObject(
|
||||
klass, ctorRouteInfoID, jni::ToJavaString(env, info.m_distToTarget),
|
||||
|
|
|
@ -3,6 +3,17 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface Measure : NSObject
|
||||
|
||||
@property(nonatomic, readonly) double value;
|
||||
@property(nonatomic, readonly) NSString* valueAsString;
|
||||
|
||||
@property(nonatomic, readonly) NSString* unit;
|
||||
|
||||
- (instancetype) initAsSpeed:(double) mps;
|
||||
|
||||
@end
|
||||
|
||||
NS_SWIFT_NAME(GeoUtil)
|
||||
@interface MWMGeoUtil : NSObject
|
||||
|
||||
|
|
|
@ -3,6 +3,56 @@
|
|||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/angles.hpp"
|
||||
|
||||
#include "platform/localization.hpp"
|
||||
#include "platform/settings.hpp"
|
||||
#include "platform/measurement_utils.hpp"
|
||||
|
||||
@implementation Measure
|
||||
|
||||
// Alternative native implementation.
|
||||
// It has the issue: some localized unit are too long even in .short style. E.g. speed for RU.
|
||||
/*
|
||||
let imperial = Settings.measurementUnits() == .imperial
|
||||
var speedMeasurement = Measurement(value: speed, unit: UnitSpeed.metersPerSecond)
|
||||
speedMeasurement.convert(to: imperial ? UnitSpeed.milesPerHour : UnitSpeed.kilometersPerHour)
|
||||
|
||||
let formatter = MeasurementFormatter()
|
||||
formatter.unitOptions = .providedUnit
|
||||
formatter.numberFormatter.maximumFractionDigits = 0
|
||||
formatter.unitStyle = .short
|
||||
|
||||
if speedMeasurement.value < 10
|
||||
{
|
||||
formatter.numberFormatter.minimumFractionDigits = 1
|
||||
formatter.numberFormatter.maximumFractionDigits = 1
|
||||
}
|
||||
|
||||
let speedString = formatter.string(from: speedMeasurement)
|
||||
*/
|
||||
|
||||
- (NSString*) valueAsString {
|
||||
if (self.value > 9.999)
|
||||
return [NSString stringWithFormat:@"%.0f", self.value];
|
||||
else
|
||||
return [NSString stringWithFormat:@"%.1f", self.value];
|
||||
}
|
||||
|
||||
- (instancetype)initAsSpeed:(double) mps {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
auto units = measurement_utils::Units::Metric;
|
||||
settings::TryGet(settings::kMeasurementUnits, units);
|
||||
//auto const units = coreUnits([MWMSettings measurementUnits]);
|
||||
|
||||
_value = measurement_utils::MpsToUnits(mps, units);
|
||||
|
||||
_unit = @(platform::GetLocalizedSpeedUnits(units).c_str());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMGeoUtil
|
||||
|
||||
+ (float)angleAtPoint:(CLLocationCoordinate2D)p1 toPoint:(CLLocationCoordinate2D)p2 {
|
||||
|
|
|
@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
+ (UIColor *)opentableBackground;
|
||||
+ (UIColor *)transparentGreen;
|
||||
+ (UIColor *)speedLimitRed;
|
||||
+ (UIColor *)speedLimitGeen;
|
||||
+ (UIColor *)speedLimitGreen;
|
||||
+ (UIColor *)speedLimitWhite;
|
||||
+ (UIColor *)speedLimitLightGray;
|
||||
+ (UIColor *)speedLimitDarkGray;
|
||||
|
|
|
@ -259,7 +259,7 @@ static NSDictionary<NSString *, UIColor *> *night;
|
|||
return [UIColor colorWithRed:scaled(224) green:scaled(31) blue:scaled(31) alpha:alpha100];
|
||||
}
|
||||
|
||||
+ (UIColor *)speedLimitGeen {
|
||||
+ (UIColor *)speedLimitGreen {
|
||||
return [UIColor colorWithRed:scaled(1) green:scaled(104) blue:scaled(44) alpha:alpha100];
|
||||
}
|
||||
|
||||
|
|
|
@ -22,29 +22,29 @@ final class CarPlayRouter: NSObject {
|
|||
var speedCameraMode: SpeedCameraManagerMode {
|
||||
return RoutingManager.routingManager.speedCameraMode
|
||||
}
|
||||
|
||||
|
||||
override init() {
|
||||
listenerContainer = ListenerContainer<CarPlayRouterListener>()
|
||||
initialSpeedCamSettings = RoutingManager.routingManager.speedCameraMode
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
||||
func addListener(_ listener: CarPlayRouterListener) {
|
||||
listenerContainer.addListener(listener)
|
||||
}
|
||||
|
||||
|
||||
func removeListener(_ listener: CarPlayRouterListener) {
|
||||
listenerContainer.removeListener(listener)
|
||||
}
|
||||
|
||||
|
||||
func subscribeToEvents() {
|
||||
RoutingManager.routingManager.add(self)
|
||||
}
|
||||
|
||||
|
||||
func unsubscribeFromEvents() {
|
||||
RoutingManager.routingManager.remove(self)
|
||||
}
|
||||
|
||||
|
||||
func completeRouteAndRemovePoints() {
|
||||
let manager = RoutingManager.routingManager
|
||||
manager.stopRoutingAndRemoveRoutePoints(true)
|
||||
|
@ -52,7 +52,7 @@ final class CarPlayRouter: NSObject {
|
|||
manager.apply(routeType: .vehicle)
|
||||
previewTrip = nil
|
||||
}
|
||||
|
||||
|
||||
func rebuildRoute() {
|
||||
guard let trip = previewTrip else { return }
|
||||
do {
|
||||
|
@ -64,7 +64,7 @@ final class CarPlayRouter: NSObject {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func buildRoute(trip: CPTrip) {
|
||||
completeRouteAndRemovePoints()
|
||||
previewTrip = trip
|
||||
|
@ -87,11 +87,11 @@ final class CarPlayRouter: NSObject {
|
|||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let manager = RoutingManager.routingManager
|
||||
manager.add(routePoint: startPoint)
|
||||
manager.add(routePoint: endPoint)
|
||||
|
||||
|
||||
do {
|
||||
try manager.buildRoute()
|
||||
} catch let error as NSError {
|
||||
|
@ -101,7 +101,7 @@ final class CarPlayRouter: NSObject {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func updateStartPointAndRebuild(trip: CPTrip) {
|
||||
let manager = RoutingManager.routingManager
|
||||
previewTrip = trip
|
||||
|
@ -128,27 +128,27 @@ final class CarPlayRouter: NSObject {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func startRoute() {
|
||||
let manager = RoutingManager.routingManager
|
||||
manager.startRoute()
|
||||
}
|
||||
|
||||
|
||||
func setupCarPlaySpeedCameraMode() {
|
||||
if case .auto = initialSpeedCamSettings {
|
||||
RoutingManager.routingManager.speedCameraMode = .always
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func setupInitialSpeedCameraMode() {
|
||||
RoutingManager.routingManager.speedCameraMode = initialSpeedCamSettings
|
||||
}
|
||||
|
||||
|
||||
func updateSpeedCameraMode(_ mode: SpeedCameraManagerMode) {
|
||||
initialSpeedCamSettings = mode
|
||||
RoutingManager.routingManager.speedCameraMode = mode
|
||||
}
|
||||
|
||||
|
||||
func restoreTripPreviewOnCarplay(beforeRootTemplateDidAppear: Bool) {
|
||||
guard MWMRouter.isRestoreProcessCompleted() else {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
|
@ -182,7 +182,7 @@ final class CarPlayRouter: NSObject {
|
|||
CarPlayService.shared.preparePreview(trips: [trip])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func restoredNavigationSession() -> (CPTrip, RouteInfo)? {
|
||||
let manager = RoutingManager.routingManager
|
||||
if manager.isOnRoute,
|
||||
|
@ -211,21 +211,21 @@ extension CarPlayRouter {
|
|||
self?.updateUpcomingManeuvers()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func cancelTrip() {
|
||||
routeSession?.cancelTrip()
|
||||
routeSession = nil
|
||||
completeRouteAndRemovePoints()
|
||||
RoutingManager.routingManager.resetOnNewTurnCallback()
|
||||
}
|
||||
|
||||
|
||||
func finishTrip() {
|
||||
routeSession?.finishTrip()
|
||||
routeSession = nil
|
||||
completeRouteAndRemovePoints()
|
||||
RoutingManager.routingManager.resetOnNewTurnCallback()
|
||||
}
|
||||
|
||||
|
||||
func updateUpcomingManeuvers() {
|
||||
let maneuvers = createUpcomingManeuvers()
|
||||
routeSession?.upcomingManeuvers = maneuvers
|
||||
|
@ -249,7 +249,7 @@ extension CarPlayRouter {
|
|||
let measurement = Measurement(value: distance, unit: routeInfo.turnUnits)
|
||||
return CPTravelEstimates(distanceRemaining: measurement, timeRemaining: 0.0)
|
||||
}
|
||||
|
||||
|
||||
private func createUpcomingManeuvers() -> [CPManeuver] {
|
||||
guard let routeInfo = RoutingManager.routingManager.routeInfo else {
|
||||
return []
|
||||
|
@ -286,7 +286,7 @@ extension CarPlayRouter {
|
|||
}
|
||||
return maneuvers
|
||||
}
|
||||
|
||||
|
||||
func createTrip(startPoint: MWMRoutePoint, endPoint: MWMRoutePoint, routeInfo: RouteInfo? = nil) -> CPTrip {
|
||||
let startPlacemark = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: startPoint.latitude,
|
||||
longitude: startPoint.longitude))
|
||||
|
@ -296,10 +296,10 @@ extension CarPlayRouter {
|
|||
let startItem = MKMapItem(placemark: startPlacemark)
|
||||
let endItem = MKMapItem(placemark: endPlacemark)
|
||||
endItem.name = endPoint.title
|
||||
|
||||
|
||||
let routeChoice = CPRouteChoice(summaryVariants: [" "], additionalInformationVariants: [], selectionSummaryVariants: [])
|
||||
routeChoice.userInfo = routeInfo
|
||||
|
||||
|
||||
let trip = CPTrip(origin: startItem, destination: endItem, routeChoices: [routeChoice])
|
||||
trip.userInfo = [CPConstants.Trip.start: startPoint, CPConstants.Trip.end: endPoint]
|
||||
return trip
|
||||
|
@ -308,10 +308,10 @@ extension CarPlayRouter {
|
|||
|
||||
// MARK: - RoutingManagerListener implementation
|
||||
extension CarPlayRouter: RoutingManagerListener {
|
||||
func updateCameraInfo(isCameraOnRoute: Bool, speedLimit limit: String?) {
|
||||
CarPlayService.shared.updateCameraUI(isCameraOnRoute: isCameraOnRoute, speedLimit: limit)
|
||||
func updateCameraInfo(isCameraOnRoute: Bool, speedLimitMps limit: Double) {
|
||||
CarPlayService.shared.updateCameraUI(isCameraOnRoute: isCameraOnRoute, speedLimitMps: limit < 0 ? nil : limit)
|
||||
}
|
||||
|
||||
|
||||
func processRouteBuilderEvent(with code: RouterResultCode, countries: [String]) {
|
||||
guard let trip = previewTrip else {
|
||||
return
|
||||
|
@ -345,10 +345,10 @@ extension CarPlayRouter: RoutingManagerListener {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func didLocationUpdate(_ notifications: [String]) {
|
||||
guard let trip = previewTrip else { return }
|
||||
|
||||
|
||||
let manager = RoutingManager.routingManager
|
||||
if manager.isRouteFinished {
|
||||
listenerContainer.forEach({
|
||||
|
@ -356,13 +356,13 @@ extension CarPlayRouter: RoutingManagerListener {
|
|||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
guard let routeInfo = manager.routeInfo,
|
||||
manager.isRoutingActive else { return }
|
||||
listenerContainer.forEach({
|
||||
$0.didUpdateRouteInfo(routeInfo, forTrip: trip)
|
||||
})
|
||||
|
||||
|
||||
let tts = MWMTextToSpeech.tts()!
|
||||
if manager.isOnRoute && tts.active {
|
||||
tts.playTurnNotifications(notifications)
|
||||
|
|
|
@ -31,7 +31,7 @@ final class CarPlayService: NSObject {
|
|||
}
|
||||
var preparedToPreviewTrips: [CPTrip] = []
|
||||
var isUserPanMap: Bool = false
|
||||
|
||||
|
||||
@objc func setup(window: CPWindow, interfaceController: CPInterfaceController) {
|
||||
isCarplayActivated = true
|
||||
self.window = window
|
||||
|
@ -63,7 +63,7 @@ final class CarPlayService: NSObject {
|
|||
ThemeManager.invalidate()
|
||||
FrameworkHelper.updatePositionArrowOffset(false, offset: 5)
|
||||
}
|
||||
|
||||
|
||||
@objc func destroy() {
|
||||
if let carplayVC = carplayVC {
|
||||
carplayVC.removeMapView()
|
||||
|
@ -89,7 +89,7 @@ final class CarPlayService: NSObject {
|
|||
ThemeManager.invalidate()
|
||||
FrameworkHelper.updatePositionArrowOffset(true, offset: 0)
|
||||
}
|
||||
|
||||
|
||||
@objc func interfaceStyle() -> UIUserInterfaceStyle {
|
||||
if let window = window,
|
||||
window.traitCollection.userInterfaceIdiom == .carPlay {
|
||||
|
@ -97,7 +97,7 @@ final class CarPlayService: NSObject {
|
|||
}
|
||||
return .unspecified
|
||||
}
|
||||
|
||||
|
||||
private func applyRootViewController() {
|
||||
guard let window = window else { return }
|
||||
let carplaySotyboard = UIStoryboard.instance(.carPlay)
|
||||
|
@ -110,14 +110,14 @@ final class CarPlayService: NSObject {
|
|||
mapVC.add(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func applyBaseRootTemplate() {
|
||||
let mapTemplate = MapTemplateBuilder.buildBaseTemplate(positionMode: currentPositionMode)
|
||||
mapTemplate.mapDelegate = self
|
||||
interfaceController?.setRootTemplate(mapTemplate, animated: true)
|
||||
FrameworkHelper.rotateMap(0.0, animated: false)
|
||||
}
|
||||
|
||||
|
||||
private func applyNavigationRootTemplate(trip: CPTrip, routeInfo: RouteInfo) {
|
||||
let mapTemplate = MapTemplateBuilder.buildNavigationTemplate()
|
||||
mapTemplate.mapDelegate = self
|
||||
|
@ -126,13 +126,13 @@ final class CarPlayService: NSObject {
|
|||
if let estimates = createEstimates(routeInfo: routeInfo) {
|
||||
mapTemplate.updateEstimates(estimates, for: trip)
|
||||
}
|
||||
|
||||
|
||||
if let carplayVC = carplayVC {
|
||||
carplayVC.updateCurrentSpeed(routeInfo.speed)
|
||||
carplayVC.updateCurrentSpeed(routeInfo.speedMps, speedLimitMps: routeInfo.speedLimitMps)
|
||||
carplayVC.showSpeedControl()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func pushTemplate(_ templateToPush: CPTemplate, animated: Bool) {
|
||||
if let interfaceController = interfaceController {
|
||||
switch templateToPush {
|
||||
|
@ -148,16 +148,16 @@ final class CarPlayService: NSObject {
|
|||
interfaceController.pushTemplate(templateToPush, animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func popTemplate(animated: Bool) {
|
||||
interfaceController?.popTemplate(animated: animated)
|
||||
}
|
||||
|
||||
|
||||
func presentAlert(_ template: CPAlertTemplate, animated: Bool) {
|
||||
interfaceController?.dismissTemplate(animated: false)
|
||||
interfaceController?.presentTemplate(template, animated: animated)
|
||||
}
|
||||
|
||||
|
||||
func cancelCurrentTrip() {
|
||||
router?.cancelTrip()
|
||||
if let carplayVC = carplayVC {
|
||||
|
@ -165,14 +165,13 @@ final class CarPlayService: NSObject {
|
|||
}
|
||||
updateMapTemplateUIToBase()
|
||||
}
|
||||
|
||||
func updateCameraUI(isCameraOnRoute: Bool, speedLimit limit: String?) {
|
||||
|
||||
func updateCameraUI(isCameraOnRoute: Bool, speedLimitMps limit: Double?) {
|
||||
if let carplayVC = carplayVC {
|
||||
let speedLimit = limit == nil ? nil : Int(limit!)
|
||||
carplayVC.updateCameraInfo(isCameraOnRoute: isCameraOnRoute, speedLimit: speedLimit)
|
||||
carplayVC.updateCameraInfo(isCameraOnRoute: isCameraOnRoute, speedLimitMps: limit)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func updateMapTemplateUIToBase() {
|
||||
guard let mapTemplate = rootMapTemplate else {
|
||||
return
|
||||
|
@ -188,7 +187,7 @@ final class CarPlayService: NSObject {
|
|||
updateVisibleViewPortState(.default)
|
||||
FrameworkHelper.rotateMap(0.0, animated: true)
|
||||
}
|
||||
|
||||
|
||||
func updateMapTemplateUIToTripFinished(_ trip: CPTrip) {
|
||||
guard let mapTemplate = rootMapTemplate else {
|
||||
return
|
||||
|
@ -206,7 +205,7 @@ final class CarPlayService: NSObject {
|
|||
if let address = trip.destination.placemark.postalAddress?.street {
|
||||
subtitle = subtitle + "\n" + address
|
||||
}
|
||||
|
||||
|
||||
let alert = CPNavigationAlert(titleVariants: [L("trip_finished")],
|
||||
subtitleVariants: [subtitle],
|
||||
imageSet: nil,
|
||||
|
@ -215,18 +214,18 @@ final class CarPlayService: NSObject {
|
|||
duration: 0)
|
||||
mapTemplate.present(navigationAlert: alert, animated: true)
|
||||
}
|
||||
|
||||
|
||||
func updateVisibleViewPortState(_ state: CPViewPortState) {
|
||||
guard let carplayVC = carplayVC else {
|
||||
return
|
||||
}
|
||||
carplayVC.updateVisibleViewPortState(state)
|
||||
}
|
||||
|
||||
|
||||
func updateRouteAfterChangingSettings() {
|
||||
router?.rebuildRoute()
|
||||
}
|
||||
|
||||
|
||||
@objc func showNoMapAlert() {
|
||||
guard let mapTemplate = interfaceController?.topTemplate as? CPMapTemplate,
|
||||
let info = mapTemplate.userInfo as? MapInfo,
|
||||
|
@ -237,7 +236,7 @@ final class CarPlayService: NSObject {
|
|||
alert.userInfo = [CPConstants.TemplateKey.alert: CPConstants.TemplateType.downloadMap]
|
||||
presentAlert(alert, animated: true)
|
||||
}
|
||||
|
||||
|
||||
@objc func hideNoMapAlert() {
|
||||
if let presentedTemplate = interfaceController?.presentedTemplate,
|
||||
let info = presentedTemplate.userInfo as? [String: String],
|
||||
|
@ -267,7 +266,7 @@ extension CarPlayService: CPInterfaceControllerDelegate {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func templateDidAppear(_ aTemplate: CPTemplate, animated: Bool) {
|
||||
guard let mapTemplate = aTemplate as? CPMapTemplate,
|
||||
let info = aTemplate.userInfo as? MapInfo else {
|
||||
|
@ -278,12 +277,12 @@ extension CarPlayService: CPInterfaceControllerDelegate {
|
|||
preparedToPreviewTrips = []
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if info.type == CPConstants.TemplateType.preview, let trips = info.trips {
|
||||
showPreview(mapTemplate: mapTemplate, trips: trips)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func templateWillDisappear(_ aTemplate: CPTemplate, animated: Bool) {
|
||||
guard let info = aTemplate.userInfo as? MapInfo else {
|
||||
return
|
||||
|
@ -292,7 +291,7 @@ extension CarPlayService: CPInterfaceControllerDelegate {
|
|||
router?.completeRouteAndRemovePoints()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func templateDidDisappear(_ aTemplate: CPTemplate, animated: Bool) {
|
||||
guard !preparedToPreviewTrips.isEmpty,
|
||||
let info = aTemplate.userInfo as? [String: String],
|
||||
|
@ -310,7 +309,7 @@ extension CarPlayService: CPInterfaceControllerDelegate {
|
|||
extension CarPlayService: CPSessionConfigurationDelegate {
|
||||
func sessionConfiguration(_ sessionConfiguration: CPSessionConfiguration,
|
||||
limitedUserInterfacesChanged limitedUserInterfaces: CPLimitableUserInterface) {
|
||||
|
||||
|
||||
}
|
||||
@available(iOS 13.0, *)
|
||||
func sessionConfiguration(_ sessionConfiguration: CPSessionConfiguration,
|
||||
|
@ -326,7 +325,7 @@ extension CarPlayService: CPMapTemplateDelegate {
|
|||
MapTemplateBuilder.configurePanUI(mapTemplate: mapTemplate)
|
||||
FrameworkHelper.stopLocationFollow()
|
||||
}
|
||||
|
||||
|
||||
public func mapTemplateDidDismissPanningInterface(_ mapTemplate: CPMapTemplate) {
|
||||
if let info = mapTemplate.userInfo as? MapInfo,
|
||||
info.type == CPConstants.TemplateType.navigation {
|
||||
|
@ -336,7 +335,7 @@ extension CarPlayService: CPMapTemplateDelegate {
|
|||
}
|
||||
FrameworkHelper.switchMyPositionMode()
|
||||
}
|
||||
|
||||
|
||||
func mapTemplate(_ mapTemplate: CPMapTemplate, panEndedWith direction: CPMapTemplate.PanDirection) {
|
||||
var offset = UIOffset(horizontal: 0.0, vertical: 0.0)
|
||||
let offsetStep: CGFloat = 0.25
|
||||
|
@ -347,7 +346,7 @@ extension CarPlayService: CPMapTemplateDelegate {
|
|||
FrameworkHelper.moveMap(offset)
|
||||
isUserPanMap = true
|
||||
}
|
||||
|
||||
|
||||
func mapTemplate(_ mapTemplate: CPMapTemplate, panWith direction: CPMapTemplate.PanDirection) {
|
||||
var offset = UIOffset(horizontal: 0.0, vertical: 0.0)
|
||||
let offsetStep: CGFloat = 0.1
|
||||
|
@ -358,7 +357,7 @@ extension CarPlayService: CPMapTemplateDelegate {
|
|||
FrameworkHelper.moveMap(offset)
|
||||
isUserPanMap = true
|
||||
}
|
||||
|
||||
|
||||
func mapTemplate(_ mapTemplate: CPMapTemplate, startedTrip trip: CPTrip, using routeChoice: CPRouteChoice) {
|
||||
guard let info = routeChoice.userInfo as? RouteInfo else {
|
||||
if let info = routeChoice.userInfo as? [String: Any],
|
||||
|
@ -370,13 +369,13 @@ extension CarPlayService: CPMapTemplateDelegate {
|
|||
}
|
||||
mapTemplate.userInfo = MapInfo(type: CPConstants.TemplateType.previewAccepted)
|
||||
mapTemplate.hideTripPreviews()
|
||||
|
||||
|
||||
guard let router = router,
|
||||
let interfaceController = interfaceController,
|
||||
let rootMapTemplate = rootMapTemplate else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
MapTemplateBuilder.configureNavigationUI(mapTemplate: rootMapTemplate)
|
||||
|
||||
if interfaceController.templates.count > 1 {
|
||||
|
@ -387,14 +386,14 @@ extension CarPlayService: CPMapTemplateDelegate {
|
|||
if let estimates = createEstimates(routeInfo: info) {
|
||||
rootMapTemplate.updateEstimates(estimates, for: trip)
|
||||
}
|
||||
|
||||
|
||||
if let carplayVC = carplayVC {
|
||||
carplayVC.updateCurrentSpeed(info.speed)
|
||||
carplayVC.updateCurrentSpeed(info.speedMps, speedLimitMps: info.speedLimitMps)
|
||||
carplayVC.showSpeedControl()
|
||||
}
|
||||
updateVisibleViewPortState(.navigation)
|
||||
}
|
||||
|
||||
|
||||
func mapTemplate(_ mapTemplate: CPMapTemplate, displayStyleFor maneuver: CPManeuver) -> CPManeuverDisplayStyle {
|
||||
if let type = maneuver.userInfo as? String,
|
||||
type == CPConstants.Maneuvers.secondary {
|
||||
|
@ -402,7 +401,7 @@ extension CarPlayService: CPMapTemplateDelegate {
|
|||
}
|
||||
return .leadingSymbol
|
||||
}
|
||||
|
||||
|
||||
func mapTemplate(_ mapTemplate: CPMapTemplate,
|
||||
selectedPreviewFor trip: CPTrip,
|
||||
using routeChoice: CPRouteChoice) {
|
||||
|
@ -481,7 +480,7 @@ extension CarPlayService: CPSearchTemplateDelegate {
|
|||
completionHandler(items)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func searchTemplate(_ searchTemplate: CPSearchTemplate, selectedResult item: CPListItem, completionHandler: @escaping () -> Void) {
|
||||
searchService?.saveLastQuery()
|
||||
if let info = item.userInfo as? ListItemInfo,
|
||||
|
@ -504,10 +503,10 @@ extension CarPlayService: CarPlayRouterListener {
|
|||
currentTemplate.updateEstimates(estimates, for: trip)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func didUpdateRouteInfo(_ routeInfo: RouteInfo, forTrip trip: CPTrip) {
|
||||
if let carplayVC = carplayVC {
|
||||
carplayVC.updateCurrentSpeed(routeInfo.speed)
|
||||
carplayVC.updateCurrentSpeed(routeInfo.speedMps, speedLimitMps: routeInfo.speedLimitMps)
|
||||
}
|
||||
guard let router = router,
|
||||
let template = rootMapTemplate else {
|
||||
|
@ -519,13 +518,13 @@ extension CarPlayService: CarPlayRouterListener {
|
|||
}
|
||||
trip.routeChoices.first?.userInfo = routeInfo
|
||||
}
|
||||
|
||||
|
||||
func didFailureBuildRoute(forTrip trip: CPTrip, code: RouterResultCode, countries: [String]) {
|
||||
guard let template = interfaceController?.topTemplate as? CPMapTemplate else { return }
|
||||
trip.routeChoices.first?.userInfo = [CPConstants.Trip.errorCode: code, CPConstants.Trip.missedCountries: countries]
|
||||
applyUndefinedEstimates(template: template, trip: trip)
|
||||
}
|
||||
|
||||
|
||||
func routeDidFinish(_ trip: CPTrip) {
|
||||
if router?.currentTrip == nil { return }
|
||||
router?.finishTrip()
|
||||
|
@ -558,7 +557,7 @@ extension CarPlayService: LocationModeListener {
|
|||
rootMapTemplate.leadingNavigationBarButtons = []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func processMyPositionPendingTimeout() {
|
||||
}
|
||||
}
|
||||
|
@ -589,7 +588,7 @@ extension CarPlayService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func preparePreview(forBookmark bookmark: MWMCarPlayBookmarkObject) {
|
||||
if let router = router,
|
||||
let startPoint = MWMRoutePoint(lastLocationAndType: .start,
|
||||
|
@ -607,7 +606,7 @@ extension CarPlayService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func preparePreview(trips: [CPTrip]) {
|
||||
let mapTemplate = MapTemplateBuilder.buildTripPreviewTemplate(forTrips: trips)
|
||||
if let interfaceController = interfaceController {
|
||||
|
@ -619,14 +618,14 @@ extension CarPlayService {
|
|||
interfaceController.pushTemplate(mapTemplate, animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func showPreview(mapTemplate: CPMapTemplate, trips: [CPTrip]) {
|
||||
let tripTextConfig = CPTripPreviewTextConfiguration(startButtonTitle: L("trip_start"),
|
||||
additionalRoutesButtonTitle: nil,
|
||||
overviewButtonTitle: nil)
|
||||
mapTemplate.showTripPreviews(trips, textConfiguration: tripTextConfig)
|
||||
}
|
||||
|
||||
|
||||
func createEstimates(routeInfo: RouteInfo) -> CPTravelEstimates? {
|
||||
if let distance = Double(routeInfo.targetDistance) {
|
||||
let measurement = Measurement(value: distance,
|
||||
|
@ -637,7 +636,7 @@ extension CarPlayService {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func applyUndefinedEstimates(template: CPMapTemplate, trip: CPTrip) {
|
||||
let measurement = Measurement(value: -1,
|
||||
unit: UnitLength.meters)
|
||||
|
@ -645,7 +644,7 @@ extension CarPlayService {
|
|||
timeRemaining: -1)
|
||||
template.updateEstimates(estimates, for: trip)
|
||||
}
|
||||
|
||||
|
||||
func showRerouteAlert(trips: [CPTrip]) {
|
||||
let yesAction = CPAlertAction(title: L("yes"), style: .default, handler: { [unowned self] _ in
|
||||
self.router?.cancelTrip()
|
||||
|
@ -660,7 +659,7 @@ extension CarPlayService {
|
|||
alert.userInfo = [CPConstants.TemplateKey.alert: CPConstants.TemplateType.redirectRoute]
|
||||
presentAlert(alert, animated: true)
|
||||
}
|
||||
|
||||
|
||||
func showKeyboardAlert() {
|
||||
let okAction = CPAlertAction(title: L("ok"), style: .default, handler: { [unowned self] _ in
|
||||
self.interfaceController?.dismissTemplate(animated: true)
|
||||
|
@ -668,7 +667,7 @@ extension CarPlayService {
|
|||
let alert = CPAlertTemplate(titleVariants: [L("keyboard_availability_alert")], actions: [okAction])
|
||||
presentAlert(alert, animated: true)
|
||||
}
|
||||
|
||||
|
||||
func showErrorAlert(code: RouterResultCode, countries: [String]) {
|
||||
var titleVariants = [String]()
|
||||
switch code {
|
||||
|
@ -697,18 +696,18 @@ extension CarPlayService {
|
|||
.transitRouteNotFoundTooLongPedestrian:
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let okAction = CPAlertAction(title: L("ok"), style: .cancel, handler: { [unowned self] _ in
|
||||
self.interfaceController?.dismissTemplate(animated: true)
|
||||
})
|
||||
let alert = CPAlertTemplate(titleVariants: titleVariants, actions: [okAction])
|
||||
presentAlert(alert, animated: true)
|
||||
}
|
||||
|
||||
|
||||
func showRecoverRouteAlert(trip: CPTrip, isTypeCorrect: Bool) {
|
||||
let yesAction = CPAlertAction(title: L("ok"), style: .default, handler: { [unowned self] _ in
|
||||
var info = trip.userInfo as? [String: MWMRoutePoint]
|
||||
|
||||
|
||||
if let startPoint = MWMRoutePoint(lastLocationAndType: .start,
|
||||
intermediateIndex: 0) {
|
||||
info?[CPConstants.Trip.start] = startPoint
|
||||
|
|
|
@ -8,9 +8,10 @@ class RouteInfo: NSObject {
|
|||
let turnUnits: UnitLength
|
||||
let turnImageName: String?
|
||||
let nextTurnImageName: String?
|
||||
let speed: Int
|
||||
let speedMps: Double
|
||||
let speedLimitMps: Double?
|
||||
let roundExitNumber: Int
|
||||
|
||||
|
||||
@objc init(timeToTarget: TimeInterval,
|
||||
targetDistance: String,
|
||||
targetUnits: String,
|
||||
|
@ -19,7 +20,8 @@ class RouteInfo: NSObject {
|
|||
turnUnits: String,
|
||||
turnImageName: String?,
|
||||
nextTurnImageName: String?,
|
||||
speed: Int,
|
||||
speedMps: Double,
|
||||
speedLimitMps: Double,
|
||||
roundExitNumber: Int) {
|
||||
self.timeToTarget = timeToTarget
|
||||
self.targetDistance = targetDistance
|
||||
|
@ -29,10 +31,11 @@ class RouteInfo: NSObject {
|
|||
self.turnUnits = RouteInfo.unitLength(for: turnUnits)
|
||||
self.turnImageName = turnImageName
|
||||
self.nextTurnImageName = nextTurnImageName
|
||||
self.speed = speed
|
||||
self.speedMps = speedMps
|
||||
self.speedLimitMps = speedLimitMps < 0 ? nil : speedLimitMps
|
||||
self.roundExitNumber = roundExitNumber
|
||||
}
|
||||
|
||||
|
||||
class func unitLength(for targetUnits: String) -> UnitLength {
|
||||
switch targetUnits {
|
||||
case "mi":
|
||||
|
|
|
@ -2,25 +2,24 @@
|
|||
|
||||
@interface MWMNavigationDashboardEntity : NSObject
|
||||
|
||||
@property(copy, nonatomic, readonly) NSArray<MWMRouterTransitStepInfo *> * transitSteps;
|
||||
@property(copy, nonatomic, readonly) NSAttributedString * estimate;
|
||||
@property(copy, nonatomic) NSArray<MWMRouterTransitStepInfo *> * transitSteps;
|
||||
@property(copy, nonatomic) NSAttributedString * estimate;
|
||||
@property(copy, nonatomic, readonly) NSAttributedString * estimateDot;
|
||||
@property(copy, nonatomic, readonly) NSString * distanceToTurn;
|
||||
@property(copy, nonatomic, readonly) NSString * streetName;
|
||||
@property(copy, nonatomic, readonly) NSString * targetDistance;
|
||||
@property(copy, nonatomic, readonly) NSString * targetUnits;
|
||||
@property(copy, nonatomic, readonly) NSString * turnUnits;
|
||||
@property(copy, nonatomic, readonly) NSString * speedLimit;
|
||||
@property(nonatomic, readonly) BOOL isValid;
|
||||
@property(nonatomic, readonly) CGFloat progress;
|
||||
@property(copy, nonatomic) NSString * distanceToTurn;
|
||||
@property(nonatomic) NSUInteger timeToTarget;
|
||||
@property(copy, nonatomic) NSString * streetName;
|
||||
@property(copy, nonatomic) NSString * targetDistance;
|
||||
@property(copy, nonatomic) NSString * targetUnits;
|
||||
@property(copy, nonatomic) NSString * turnUnits;
|
||||
@property(nonatomic) double speedLimitMps;
|
||||
@property(nonatomic) BOOL isValid;
|
||||
@property(nonatomic) CGFloat progress;
|
||||
@property(nonatomic, readonly) NSString * arrival;
|
||||
@property(nonatomic, readonly) NSString * eta;
|
||||
@property(nonatomic, readonly) NSString * speed;
|
||||
@property(nonatomic, readonly) NSString * speedUnits;
|
||||
@property(nonatomic, readonly) NSUInteger roundExitNumber;
|
||||
@property(nonatomic, readonly) UIImage * nextTurnImage;
|
||||
@property(nonatomic, readonly) UIImage * turnImage;
|
||||
@property(nonatomic, readonly) BOOL isSpeedLimitExceeded;
|
||||
@property(nonatomic) NSUInteger roundExitNumber;
|
||||
@property(nonatomic) UIImage * nextTurnImage;
|
||||
@property(nonatomic) UIImage * turnImage;
|
||||
@property(nonatomic, readonly) BOOL isSpeedCamLimitExceeded;
|
||||
|
||||
+ (instancetype) new __attribute__((unavailable("init is not available")));
|
||||
|
||||
|
|
|
@ -12,44 +12,11 @@
|
|||
#include "platform/localization.hpp"
|
||||
#include "platform/measurement_utils.hpp"
|
||||
|
||||
@interface MWMNavigationDashboardEntity ()
|
||||
|
||||
@property(copy, nonatomic, readwrite) NSArray<MWMRouterTransitStepInfo *> * transitSteps;
|
||||
@property(copy, nonatomic, readwrite) NSAttributedString * estimate;
|
||||
@property(copy, nonatomic, readwrite) NSString * distanceToTurn;
|
||||
@property(copy, nonatomic, readwrite) NSString * streetName;
|
||||
@property(copy, nonatomic, readwrite) NSString * targetDistance;
|
||||
@property(copy, nonatomic, readwrite) NSString * targetUnits;
|
||||
@property(copy, nonatomic, readwrite) NSString * turnUnits;
|
||||
@property(copy, nonatomic, readwrite) NSString * speedLimit;
|
||||
@property(nonatomic, readwrite) BOOL isValid;
|
||||
@property(nonatomic, readwrite) CGFloat progress;
|
||||
@property(nonatomic, readwrite) NSUInteger roundExitNumber;
|
||||
@property(nonatomic, readwrite) NSUInteger timeToTarget;
|
||||
@property(nonatomic, readwrite) UIImage * nextTurnImage;
|
||||
@property(nonatomic, readwrite) UIImage * turnImage;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMNavigationDashboardEntity
|
||||
|
||||
- (NSString *)speed
|
||||
- (BOOL)isSpeedCamLimitExceeded
|
||||
{
|
||||
CLLocation * lastLocation = [MWMLocationManager lastLocation];
|
||||
if (!lastLocation || lastLocation.speed < 0)
|
||||
return nil;
|
||||
auto const units = coreUnits([MWMSettings measurementUnits]);
|
||||
return @(measurement_utils::FormatSpeedNumeric(lastLocation.speed, units).c_str());
|
||||
}
|
||||
|
||||
- (BOOL)isSpeedLimitExceeded
|
||||
{
|
||||
return GetFramework().GetRoutingManager().IsSpeedLimitExceeded();
|
||||
}
|
||||
|
||||
- (NSString *)speedUnits
|
||||
{
|
||||
return @(platform::GetLocalizedSpeedUnits().c_str());
|
||||
return GetFramework().GetRoutingManager().IsSpeedCamLimitExceeded();
|
||||
}
|
||||
|
||||
- (NSString *)eta { return [NSDateComponentsFormatter etaStringFrom:self.timeToTarget]; }
|
||||
|
|
|
@ -97,25 +97,6 @@ NSAttributedString *estimate(NSTimeInterval time, NSAttributedString *dot, NSStr
|
|||
}
|
||||
} // namespace
|
||||
|
||||
@interface MWMNavigationDashboardEntity ()
|
||||
|
||||
@property(copy, nonatomic, readwrite) NSArray<MWMRouterTransitStepInfo *> *transitSteps;
|
||||
@property(copy, nonatomic, readwrite) NSAttributedString *estimate;
|
||||
@property(copy, nonatomic, readwrite) NSString *distanceToTurn;
|
||||
@property(copy, nonatomic, readwrite) NSString *streetName;
|
||||
@property(copy, nonatomic, readwrite) NSString *targetDistance;
|
||||
@property(copy, nonatomic, readwrite) NSString *targetUnits;
|
||||
@property(copy, nonatomic, readwrite) NSString *turnUnits;
|
||||
@property(copy, nonatomic, readwrite) NSString *speedLimit;
|
||||
@property(nonatomic, readwrite) BOOL isValid;
|
||||
@property(nonatomic, readwrite) CGFloat progress;
|
||||
@property(nonatomic, readwrite) NSUInteger roundExitNumber;
|
||||
@property(nonatomic, readwrite) NSUInteger timeToTarget;
|
||||
@property(nonatomic, readwrite) UIImage *nextTurnImage;
|
||||
@property(nonatomic, readwrite) UIImage *turnImage;
|
||||
|
||||
@end
|
||||
|
||||
@interface MWMRouterTransitStepInfo ()
|
||||
|
||||
- (instancetype)initWithStepInfo:(TransitStepInfo const &)info;
|
||||
|
@ -150,7 +131,7 @@ NSAttributedString *estimate(NSTimeInterval time, NSAttributedString *dot, NSStr
|
|||
entity.distanceToTurn = @(info.m_distToTurn.c_str());
|
||||
entity.turnUnits = [self localizedUnitLength:@(info.m_turnUnitsSuffix.c_str())];
|
||||
entity.streetName = @(info.m_displayedStreetName.c_str());
|
||||
entity.speedLimit = @(info.m_speedLimit.c_str());
|
||||
entity.speedLimitMps = info.m_speedLimitMps;
|
||||
|
||||
entity.estimate = estimate(entity.timeToTarget, entity.estimateDot, entity.targetDistance, entity.targetUnits,
|
||||
self.etaAttributes, self.etaSecondaryAttributes, NO);
|
||||
|
|
|
@ -155,23 +155,34 @@ final class NavigationControlView: SolidTouchView, MWMTextToSpeechObserver, MapO
|
|||
}
|
||||
}
|
||||
|
||||
var speed = info.speed ?? "0"
|
||||
if (info.speedLimit != "") {
|
||||
speed += " / " + info.speedLimit;
|
||||
var speedMps = 0.0
|
||||
if let s = LocationManager.lastLocation()?.speed, s > 0 {
|
||||
speedMps = s
|
||||
}
|
||||
|
||||
let speedMeasure = Measure(asSpeed: speedMps)
|
||||
var speed = speedMeasure.valueAsString;
|
||||
if (info.speedLimitMps > 0) {
|
||||
let speedLimitMeasure = Measure(asSpeed: info.speedLimitMps)
|
||||
speed += " / " + speedLimitMeasure.valueAsString;
|
||||
}
|
||||
|
||||
speedLabel.text = speed
|
||||
speedLegendLabel.text = info.speedUnits
|
||||
speedLegendLabel.text = speedMeasure.unit
|
||||
let speedWithLegend = NSMutableAttributedString(string: speed, attributes: routingNumberAttributes)
|
||||
speedWithLegend.append(NSAttributedString(string: info.speedUnits, attributes: routingLegendAttributes))
|
||||
speedWithLegend.append(NSAttributedString(string: speedMeasure.unit, attributes: routingLegendAttributes))
|
||||
speedWithLegendLabel.attributedText = speedWithLegend
|
||||
|
||||
let speedLimitExceeded = info.isSpeedLimitExceeded
|
||||
let textColor = speedLimitExceeded ? UIColor.white() : UIColor.blackPrimaryText()
|
||||
speedBackground.backgroundColor = speedLimitExceeded ? UIColor.buttonRed() : UIColor.clear
|
||||
speedLabel.textColor = textColor
|
||||
speedLegendLabel.textColor = textColor
|
||||
speedWithLegendLabel.textColor = textColor
|
||||
if info.isSpeedCamLimitExceeded {
|
||||
speedLabel.textColor = UIColor.white()
|
||||
speedBackground.backgroundColor = UIColor.buttonRed()
|
||||
}
|
||||
else {
|
||||
let isSpeedLimitExceeded = info.speedLimitMps > 0 && speedMps > info.speedLimitMps
|
||||
speedLabel.textColor = isSpeedLimitExceeded ? UIColor.buttonRed() : UIColor.blackPrimaryText()
|
||||
speedBackground.backgroundColor = UIColor.clear
|
||||
}
|
||||
speedLegendLabel.textColor = speedLabel.textColor
|
||||
speedWithLegendLabel.textColor = speedLabel.textColor
|
||||
|
||||
routingProgress.constant = progressView.width * info.progress / 100
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ using namespace storage;
|
|||
|
||||
- (void)processRouteBuilderProgress:(CGFloat)progress;
|
||||
- (void)processRouteRecommendation:(MWMRouterRecommendation)recommendation;
|
||||
- (void)speedCameraShowedUpOnRoute:(double)speedLimit;
|
||||
- (void)speedCameraShowedUpOnRoute:(double)speedLimitKMph;
|
||||
- (void)speedCameraLeftVisibleArea;
|
||||
|
||||
@end
|
||||
|
|
|
@ -11,7 +11,7 @@ NS_SWIFT_NAME(RoutingManagerListener)
|
|||
- (void)processRouteBuilderEventWithCode:(MWMRouterResultCode)code
|
||||
countries:(NSArray<NSString *> *)absentCountries;
|
||||
- (void)didLocationUpdate:(NSArray<NSString *> *)notifications;
|
||||
- (void)updateCameraInfo:(BOOL)isCameraOnRoute speedLimit:(nullable NSString *)limit NS_SWIFT_NAME(updateCameraInfo(isCameraOnRoute:speedLimit:));
|
||||
- (void)updateCameraInfo:(BOOL)isCameraOnRoute speedLimitMps:(double)limit NS_SWIFT_NAME(updateCameraInfo(isCameraOnRoute:speedLimitMps:));
|
||||
@end
|
||||
|
||||
NS_SWIFT_NAME(RoutingManager)
|
||||
|
|
|
@ -82,10 +82,9 @@
|
|||
self.rm.GetRouteFollowingInfo(info);
|
||||
if (!info.IsValid()) { return nil; }
|
||||
CLLocation * lastLocation = [MWMLocationManager lastLocation];
|
||||
NSString *speed = @"0";
|
||||
double speedMps = 0;
|
||||
if (lastLocation && lastLocation.speed >= 0) {
|
||||
auto const units = coreUnits([MWMSettings measurementUnits]);
|
||||
speed = @(measurement_utils::FormatSpeedNumeric(lastLocation.speed, units).c_str());
|
||||
speedMps = lastLocation.speed;
|
||||
}
|
||||
NSInteger roundExitNumber = 0;
|
||||
if (info.m_turn == routing::turns::CarDirection::EnterRoundAbout ||
|
||||
|
@ -93,7 +92,7 @@
|
|||
info.m_turn == routing::turns::CarDirection::LeaveRoundAbout) {
|
||||
roundExitNumber = info.m_exitNum;
|
||||
}
|
||||
|
||||
|
||||
MWMRouteInfo *objCInfo = [[MWMRouteInfo alloc] initWithTimeToTarget:info.m_time
|
||||
targetDistance:@(info.m_distToTarget.c_str())
|
||||
targetUnits:@(info.m_targetUnitsSuffix.c_str())
|
||||
|
@ -102,8 +101,9 @@
|
|||
turnUnits:@(info.m_turnUnitsSuffix.c_str())
|
||||
turnImageName:[self turnImageName:info.m_turn isPrimary:YES]
|
||||
nextTurnImageName:[self turnImageName:info.m_nextTurn isPrimary:NO]
|
||||
speed:[speed integerValue]
|
||||
roundExitNumber: roundExitNumber];
|
||||
speedMps:speedMps
|
||||
speedLimitMps:info.m_speedLimitMps
|
||||
roundExitNumber:roundExitNumber];
|
||||
return objCInfo;
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@
|
|||
- (void)buildRouteWithDidFailError:(NSError * __autoreleasing __nullable *)errorPtr {
|
||||
auto const & points = self.rm.GetRoutePoints();
|
||||
auto const pointsCount = points.size();
|
||||
|
||||
|
||||
if (pointsCount > 1) {
|
||||
self.rm.BuildRoute();
|
||||
} else {
|
||||
|
@ -229,12 +229,10 @@
|
|||
NSArray<id<MWMRoutingManagerListener>> * objects = self.listeners.allObjects;
|
||||
for (id<MWMRoutingManagerListener> object in objects) {
|
||||
if (speedLimit == routing::SpeedCameraOnRoute::kNoSpeedInfo) {
|
||||
[object updateCameraInfo:YES speedLimit:nil];
|
||||
[object updateCameraInfo:YES speedLimitMps:-1];
|
||||
} else {
|
||||
auto const metersPerSecond = measurement_utils::KmphToMps(speedLimit);
|
||||
|
||||
NSString *limit = @(measurement_utils::FormatSpeed(metersPerSecond).c_str());
|
||||
[object updateCameraInfo:YES speedLimit:limit];
|
||||
[object updateCameraInfo:YES speedLimitMps:metersPerSecond];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +240,7 @@
|
|||
- (void)speedCameraLeftVisibleArea {
|
||||
NSArray<id<MWMRoutingManagerListener>> * objects = self.listeners.allObjects;
|
||||
for (id<MWMRoutingManagerListener> object in objects) {
|
||||
[object updateCameraInfo:NO speedLimit:nil];
|
||||
[object updateCameraInfo:NO speedLimitMps:-1];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
final class CarPlayMapViewController: MWMViewController {
|
||||
private(set) var mapView: EAGLView?
|
||||
@IBOutlet var speedInfoView: UIView!
|
||||
@IBOutlet var speedLimitContainer: UIView!
|
||||
@IBOutlet var speedCamLimitContainer: UIView!
|
||||
@IBOutlet var speedCamImageView: UIImageView!
|
||||
@IBOutlet var speedLimitLabel: UILabel!
|
||||
@IBOutlet var speedCamLimitLabel: UILabel!
|
||||
@IBOutlet var currentSpeedView: UIView!
|
||||
@IBOutlet var currentSpeedLabel: UILabel!
|
||||
private var currentSpeed: Int = 0
|
||||
private var speedLimit: Int?
|
||||
private var currentSpeedMps: Double = 0.0
|
||||
private var speedLimitMps: Double?
|
||||
private var speedCamLimitMps: Double?
|
||||
private var isCameraOnRoute: Bool = false
|
||||
private var viewPortState: CPViewPortState = .default
|
||||
private var isSpeedCamBlinking: Bool = false
|
||||
private var isLeftWheelCar: Bool {
|
||||
return self.speedInfoView.frame.origin.x > self.view.frame.midX
|
||||
}
|
||||
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
}
|
||||
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
if mapView?.drapeEngineCreated == false {
|
||||
|
@ -25,11 +27,11 @@ final class CarPlayMapViewController: MWMViewController {
|
|||
}
|
||||
updateVisibleViewPortState(viewPortState)
|
||||
}
|
||||
|
||||
|
||||
func addMapView(_ mapView: EAGLView, mapButtonSafeAreaLayoutGuide: UILayoutGuide) {
|
||||
mapView.translatesAutoresizingMaskIntoConstraints = false
|
||||
removeMapView()
|
||||
|
||||
|
||||
self.mapView = mapView
|
||||
mapView.frame = view.bounds
|
||||
view.insertSubview(mapView, at: 0)
|
||||
|
@ -38,73 +40,117 @@ final class CarPlayMapViewController: MWMViewController {
|
|||
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
speedInfoView.trailingAnchor.constraint(equalTo: mapButtonSafeAreaLayoutGuide.trailingAnchor).isActive = true
|
||||
|
||||
speedCamLimitContainer.layer.borderWidth = 2.0
|
||||
}
|
||||
|
||||
|
||||
func removeMapView() {
|
||||
if let mapView = mapView {
|
||||
mapView.removeFromSuperview()
|
||||
self.mapView = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func hideSpeedControl() {
|
||||
if !speedInfoView.isHidden {
|
||||
speedInfoView.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func showSpeedControl() {
|
||||
if speedInfoView.isHidden {
|
||||
speedInfoView.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
func updateCurrentSpeed(_ speed: Int) {
|
||||
self.currentSpeed = speed
|
||||
|
||||
func updateCurrentSpeed(_ speedMps: Double, speedLimitMps: Double?) {
|
||||
self.currentSpeedMps = speedMps
|
||||
self.speedLimitMps = speedLimitMps
|
||||
updateSpeedControl()
|
||||
}
|
||||
|
||||
func updateCameraInfo(isCameraOnRoute: Bool, speedLimit: Int?) {
|
||||
|
||||
func updateCameraInfo(isCameraOnRoute: Bool, speedLimitMps: Double?) {
|
||||
self.isCameraOnRoute = isCameraOnRoute
|
||||
self.speedLimit = speedLimit
|
||||
self.speedCamLimitMps = speedLimitMps
|
||||
updateSpeedControl()
|
||||
}
|
||||
|
||||
|
||||
private func BlinkSpeedCamLimit(blink: Bool)
|
||||
{
|
||||
if blink {
|
||||
if !isSpeedCamBlinking {
|
||||
speedCamLimitLabel.alpha = 0
|
||||
speedCamImageView.alpha = 1
|
||||
UIView.animate(withDuration: 0.5,
|
||||
delay:0.0,
|
||||
options:[.repeat, .autoreverse, .curveEaseOut],
|
||||
animations: { self.speedCamImageView.alpha = 0; self.speedCamLimitLabel.alpha = 1 })
|
||||
isSpeedCamBlinking = true
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isSpeedCamBlinking) {
|
||||
speedCamLimitLabel.layer.removeAllAnimations()
|
||||
speedCamImageView.layer.removeAllAnimations()
|
||||
isSpeedCamBlinking = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateSpeedControl() {
|
||||
currentSpeedLabel.text = "\(currentSpeed)"
|
||||
let speedMeasure = Measure.init(asSpeed: currentSpeedMps)
|
||||
currentSpeedLabel.text = speedMeasure.valueAsString
|
||||
|
||||
if isCameraOnRoute {
|
||||
speedLimitContainer.layer.borderColor = UIColor.speedLimitRed().cgColor
|
||||
speedLimitContainer.layer.borderWidth = 2.0
|
||||
if let speedLimit = speedLimit {
|
||||
speedCamImageView.alpha = 0.0
|
||||
speedLimitLabel.textColor = UIColor.speedLimitDarkGray()
|
||||
speedLimitLabel.text = "\(speedLimit)"
|
||||
speedLimitLabel.alpha = 1.0
|
||||
speedCamLimitContainer.layer.borderColor = UIColor.speedLimitRed().cgColor
|
||||
speedCamImageView.tintColor = UIColor.speedLimitRed()
|
||||
|
||||
if let speedCamLimitMps = (speedCamLimitMps ?? speedLimitMps) {
|
||||
BlinkSpeedCamLimit(blink: true)
|
||||
let speedCamLimitMeasure = Measure.init(asSpeed: speedCamLimitMps)
|
||||
speedCamLimitLabel.text = speedCamLimitMeasure.valueAsString
|
||||
speedCamLimitLabel.textColor = UIColor.speedLimitDarkGray()
|
||||
|
||||
currentSpeedLabel.textColor = UIColor.white
|
||||
if speedLimit >= currentSpeed {
|
||||
currentSpeedView.backgroundColor = UIColor.speedLimitGeen()
|
||||
if speedCamLimitMps >= currentSpeedMps {
|
||||
currentSpeedView.backgroundColor = UIColor.speedLimitGreen()
|
||||
} else {
|
||||
currentSpeedView.backgroundColor = UIColor.speedLimitRed()
|
||||
}
|
||||
} else {
|
||||
speedLimitLabel.alpha = 0.0
|
||||
BlinkSpeedCamLimit(blink: false)
|
||||
speedCamLimitLabel.alpha = 0.0
|
||||
speedCamImageView.tintColor = UIColor.speedLimitRed()
|
||||
speedCamImageView.alpha = 1.0
|
||||
|
||||
currentSpeedLabel.textColor = UIColor.speedLimitDarkGray()
|
||||
currentSpeedView.backgroundColor = UIColor.speedLimitWhite()
|
||||
}
|
||||
} else {
|
||||
speedLimitContainer.layer.borderColor = UIColor.speedLimitLightGray().cgColor
|
||||
speedLimitContainer.layer.borderWidth = 2.0
|
||||
speedLimitLabel.alpha = 0.0
|
||||
speedCamImageView.tintColor = UIColor.speedLimitLightGray()
|
||||
speedCamImageView.alpha = 1.0
|
||||
} else { // !isCameraOnRoute
|
||||
BlinkSpeedCamLimit(blink: false)
|
||||
currentSpeedLabel.textColor = UIColor.speedLimitDarkGray()
|
||||
if let speedLimitMps = speedLimitMps {
|
||||
speedCamImageView.alpha = 0.0
|
||||
let speedLimitMeasure = Measure.init(asSpeed: speedLimitMps)
|
||||
speedCamLimitLabel.textColor = UIColor.speedLimitDarkGray()
|
||||
speedCamLimitLabel.text = speedLimitMeasure.valueAsString;
|
||||
speedCamLimitLabel.alpha = 1.0
|
||||
speedCamLimitContainer.layer.borderColor = UIColor.speedLimitRed().cgColor
|
||||
if currentSpeedMps > speedLimitMps {
|
||||
currentSpeedLabel.textColor = UIColor.speedLimitRed()
|
||||
}
|
||||
}
|
||||
else {
|
||||
speedCamImageView.tintColor = UIColor.speedLimitLightGray()
|
||||
speedCamImageView.alpha = 1.0
|
||||
speedCamLimitLabel.alpha = 0.0
|
||||
speedCamLimitContainer.layer.borderColor = UIColor.speedLimitLightGray().cgColor
|
||||
}
|
||||
currentSpeedView.backgroundColor = UIColor.speedLimitWhite()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func updateVisibleViewPortState(_ state: CPViewPortState) {
|
||||
viewPortState = state
|
||||
switch viewPortState {
|
||||
|
@ -116,7 +162,7 @@ final class CarPlayMapViewController: MWMViewController {
|
|||
updateVisibleViewPortToNavigationState()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func updateVisibleViewPortToPreviewState() {
|
||||
let viewBounds = view.bounds
|
||||
let previewWidth = self.view.frame.width * 0.45
|
||||
|
@ -128,7 +174,7 @@ final class CarPlayMapViewController: MWMViewController {
|
|||
height: viewBounds.height - origin.y)
|
||||
FrameworkHelper.setVisibleViewport(frame, scaleFactor: mapView?.contentScaleFactor ?? 1)
|
||||
}
|
||||
|
||||
|
||||
private func updateVisibleViewPortToNavigationState() {
|
||||
let viewBounds = view.bounds
|
||||
let previewWidth = viewBounds.width * 0.45
|
||||
|
@ -141,11 +187,11 @@ final class CarPlayMapViewController: MWMViewController {
|
|||
height: viewBounds.height - origin.y)
|
||||
FrameworkHelper.setVisibleViewport(frame, scaleFactor: mapView?.contentScaleFactor ?? 1)
|
||||
}
|
||||
|
||||
|
||||
private func updateVisibleViewPortToDefaultState() {
|
||||
FrameworkHelper.setVisibleViewport(view.bounds, scaleFactor: mapView?.contentScaleFactor ?? 1)
|
||||
}
|
||||
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
ThemeManager.invalidate()
|
||||
|
|
|
@ -36,7 +36,7 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
|||
vc.placePagePreviewData = placePageData.previewData
|
||||
return vc
|
||||
} ()
|
||||
|
||||
|
||||
lazy var wikiDescriptionViewController: WikiDescriptionViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: WikiDescriptionViewController.self)
|
||||
vc.view.isHidden = true
|
||||
|
@ -50,14 +50,14 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
|||
vc.delegate = interactor
|
||||
return vc
|
||||
} ()
|
||||
|
||||
|
||||
lazy var infoViewController: PlacePageInfoViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePageInfoViewController.self)
|
||||
vc.placePageInfoData = placePageData.infoData
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
} ()
|
||||
|
||||
|
||||
lazy var buttonsViewController: PlacePageButtonsViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePageButtonsViewController.self)
|
||||
vc.buttonsData = placePageData.buttonsData!
|
||||
|
@ -65,7 +65,7 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
|||
vc.delegate = interactor
|
||||
return vc
|
||||
} ()
|
||||
|
||||
|
||||
lazy var actionBarViewController: ActionBarViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: ActionBarViewController.self)
|
||||
vc.placePageData = placePageData
|
||||
|
@ -82,13 +82,13 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
|||
lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
|
||||
return PlacePageHeaderBuilder.build(data: placePageData.previewData, delegate: interactor, headerType: .fixed)
|
||||
} ()
|
||||
|
||||
|
||||
init(interactor: PlacePageInteractor, storyboard: UIStoryboard, data: PlacePageData) {
|
||||
self.interactor = interactor
|
||||
self.storyboard = storyboard
|
||||
self.placePageData = data
|
||||
}
|
||||
|
||||
|
||||
private func configureViewControllers() -> [UIViewController] {
|
||||
var viewControllers = [UIViewController]()
|
||||
viewControllers.append(previewViewController)
|
||||
|
@ -113,7 +113,7 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
|||
if placePageData.buttonsData != nil {
|
||||
viewControllers.append(buttonsViewController)
|
||||
}
|
||||
|
||||
|
||||
placePageData.onBookmarkStatusUpdate = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if self.placePageData.bookmarkData == nil {
|
||||
|
@ -212,9 +212,8 @@ extension PlacePageCommonLayout: MWMLocationObserver {
|
|||
let altString = "▲ \(unitsFormatter.string(from: altMeasurement))"
|
||||
|
||||
if location.speed > 0 && location.timestamp.timeIntervalSinceNow >= -2 {
|
||||
let speed = imperial ? location.speed * 2.237 : location.speed * 3.6
|
||||
let speedMeasurement = Measurement(value: speed.rounded(), unit: imperial ? UnitSpeed.milesPerHour: UnitSpeed.kilometersPerHour)
|
||||
let speedString = "\(LocationManager.speedSymbolFor(location.speed))\(unitsFormatter.string(from: speedMeasurement))"
|
||||
let speedMeasure = Measure.init(asSpeed: location.speed)
|
||||
let speedString = "\(LocationManager.speedSymbolFor(location.speed))\(speedMeasure.valueAsString) \(speedMeasure.unit)"
|
||||
previewViewController.updateSpeedAndAltitude("\(altString) \(speedString)")
|
||||
} else {
|
||||
previewViewController.updateSpeedAndAltitude(altString)
|
||||
|
|
|
@ -53,11 +53,11 @@
|
|||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_carplay_camera" translatesAutoresizingMaskIntoConstraints="NO" id="Vip-QN-Smh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="30" height="30"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="backgroundColor" white="1" alpha="0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="60" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ifo-0s-Ynd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="30" height="30"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="backgroundColor" white="1" alpha="0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -107,8 +107,8 @@
|
|||
<outlet property="currentSpeedView" destination="1hD-QK-pwq" id="Mbg-8c-EWp"/>
|
||||
<outlet property="speedCamImageView" destination="Vip-QN-Smh" id="ASc-eP-fXa"/>
|
||||
<outlet property="speedInfoView" destination="dAY-9Y-UMN" id="k1g-9g-oKS"/>
|
||||
<outlet property="speedLimitContainer" destination="uhn-dc-aMW" id="AQt-AB-ZyL"/>
|
||||
<outlet property="speedLimitLabel" destination="ifo-0s-Ynd" id="zgD-Di-6YZ"/>
|
||||
<outlet property="speedCamLimitContainer" destination="uhn-dc-aMW" id="AQt-AB-ZyL"/>
|
||||
<outlet property="speedCamLimitLabel" destination="ifo-0s-Ynd" id="zgD-Di-6YZ"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="6hr-Cq-l0z" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
|
|
|
@ -1475,7 +1475,7 @@ void RoutingManager::SetSubroutesVisibility(bool visible)
|
|||
lock.Get()->SetSubrouteVisibility(subrouteId, visible);
|
||||
}
|
||||
|
||||
bool RoutingManager::IsSpeedLimitExceeded() const
|
||||
bool RoutingManager::IsSpeedCamLimitExceeded() const
|
||||
{
|
||||
return m_routingSession.IsSpeedLimitExceeded();
|
||||
return m_routingSession.IsSpeedCamLimitExceeded();
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ public:
|
|||
void OnLocationUpdate(location::GpsInfo const & info);
|
||||
|
||||
routing::SpeedCameraManager & GetSpeedCamManager() { return m_routingSession.GetSpeedCamManager(); }
|
||||
bool IsSpeedLimitExceeded() const;
|
||||
bool IsSpeedCamLimitExceeded() const;
|
||||
|
||||
void SetTurnNotificationsUnits(measurement_utils::Units const units)
|
||||
{
|
||||
|
|
|
@ -55,11 +55,16 @@ LocalizedUnits GetLocalizedAltitudeUnits()
|
|||
return GetLocalizedUnits(units, MeasurementType::Altitude);
|
||||
}
|
||||
|
||||
std::string GetLocalizedSpeedUnits(measurement_utils::Units units)
|
||||
{
|
||||
return GetLocalizedUnits(units, MeasurementType::Speed).m_high;
|
||||
}
|
||||
|
||||
std::string GetLocalizedSpeedUnits()
|
||||
{
|
||||
auto units = measurement_utils::Units::Metric;
|
||||
settings::TryGet(settings::kMeasurementUnits, units);
|
||||
|
||||
return GetLocalizedUnits(units, MeasurementType::Speed).m_high;
|
||||
return GetLocalizedSpeedUnits(units);
|
||||
}
|
||||
} // namespace platform
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace measurement_utils
|
||||
{
|
||||
enum class Units;
|
||||
}
|
||||
|
||||
namespace platform
|
||||
{
|
||||
struct LocalizedUnits
|
||||
|
@ -18,5 +23,7 @@ extern std::string GetLocalizedMyPositionBookmarkName();
|
|||
|
||||
extern LocalizedUnits GetLocalizedDistanceUnits();
|
||||
extern LocalizedUnits GetLocalizedAltitudeUnits();
|
||||
|
||||
extern std::string GetLocalizedSpeedUnits(measurement_utils::Units units);
|
||||
extern std::string GetLocalizedSpeedUnits();
|
||||
} // namespace platform
|
||||
|
|
|
@ -224,14 +224,19 @@ string FormatSpeed(double metersPerSecond)
|
|||
return FormatSpeedNumeric(metersPerSecond, units) + " " + FormatSpeedUnits(units);
|
||||
}
|
||||
|
||||
string FormatSpeedNumeric(double metersPerSecond, Units units)
|
||||
double MpsToUnits(double metersPerSecond, measurement_utils::Units units)
|
||||
{
|
||||
double unitsPerHour;
|
||||
switch (units)
|
||||
{
|
||||
case Units::Imperial: unitsPerHour = KmphToMiph(MpsToKmph(metersPerSecond)); break;
|
||||
case Units::Metric: unitsPerHour = MpsToKmph(metersPerSecond); break;
|
||||
case Units::Imperial: return KmphToMiph(MpsToKmph(metersPerSecond)); break;
|
||||
case Units::Metric: return MpsToKmph(metersPerSecond); break;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
string FormatSpeedNumeric(double metersPerSecond, Units units)
|
||||
{
|
||||
double unitsPerHour = MpsToUnits(metersPerSecond, units);
|
||||
return ToStringPrecision(unitsPerHour, unitsPerHour >= 10.0 ? 0 : 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ inline double NauticalMilesToMeters(double nmi) { return nmi * 1852; }
|
|||
inline double KmphToMps(double kmph) { return kmph * 1000 / 3600; }
|
||||
|
||||
double ToSpeedKmPH(double speed, measurement_utils::Units units);
|
||||
double MpsToUnits(double mps, measurement_utils::Units units);
|
||||
|
||||
/// Takes into an account user settings [metric, imperial]
|
||||
/// @param[in] m meters
|
||||
|
|
|
@ -486,7 +486,7 @@ void DrawWidget::SubmitFakeLocationPoint(m2::PointD const & pt)
|
|||
else
|
||||
{
|
||||
LOG(LDEBUG, ("Distance:", loc.m_distToTarget + loc.m_targetUnitsSuffix, "Time:", loc.m_time,
|
||||
loc.m_speedLimitUnitsSuffix.empty() ? "" : "SpeedLimit: " + loc.m_speedLimit + loc.m_speedLimitUnitsSuffix,
|
||||
loc.m_speedLimitMps < 0 ? "" : "SpeedLimit: " + measurement_utils::FormatSpeed(loc.m_speedLimitMps),
|
||||
GetTurnString(loc.m_turn), (loc.m_exitNum != 0 ? ":" + std::to_string(loc.m_exitNum) : ""),
|
||||
"in", loc.m_distToTurn + loc.m_turnUnitsSuffix,
|
||||
loc.m_targetName.empty() ? "" : "to " + loc.m_targetName ));
|
||||
|
|
|
@ -84,9 +84,8 @@ public:
|
|||
turns::PedestrianDirection m_pedestrianTurn;
|
||||
//@}
|
||||
|
||||
// Current speed limit.
|
||||
// If no info about speed limit then m_speedLimit == "" and m_speedLimitUnitsSuffix == "".
|
||||
std::string m_speedLimit;
|
||||
std::string m_speedLimitUnitsSuffix;
|
||||
// Current speed limit in meters per second.
|
||||
// If no info about speed limit then m_speedLimitMps < 0.
|
||||
double m_speedLimitMps = -1.0;
|
||||
};
|
||||
} // namespace routing
|
||||
|
|
|
@ -48,16 +48,6 @@ void FormatDistance(double dist, string & value, string & suffix)
|
|||
value.erase(delim);
|
||||
};
|
||||
|
||||
void FormatSpeed(double speedKmPH, string & value, string & suffix)
|
||||
{
|
||||
value = measurement_utils::FormatSpeed(measurement_utils::KmphToMps(speedKmPH));
|
||||
|
||||
size_t const delim = value.find(' ');
|
||||
ASSERT(delim != string::npos, ());
|
||||
suffix = value.substr(delim + 1);
|
||||
value.erase(delim);
|
||||
};
|
||||
|
||||
RoutingSession::RoutingSession()
|
||||
: m_router(nullptr)
|
||||
, m_route(make_shared<Route>(string() /* router */, 0 /* route id */))
|
||||
|
@ -417,7 +407,9 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
|
|||
SpeedInUnits speedLimit;
|
||||
m_route->GetCurrentSpeedLimit(speedLimit);
|
||||
if (speedLimit.IsValid())
|
||||
FormatSpeed(speedLimit.GetSpeedKmPH(), info.m_speedLimit, info.m_speedLimitUnitsSuffix);
|
||||
info.m_speedLimitMps = measurement_utils::KmphToMps(speedLimit.GetSpeedKmPH());
|
||||
else
|
||||
info.m_speedLimitMps = -1.0;
|
||||
|
||||
// The turn after the next one.
|
||||
if (m_routingSettings.m_showTurnAfterNext)
|
||||
|
|
|
@ -161,7 +161,7 @@ public:
|
|||
|
||||
void AssignRouteForTesting(std::shared_ptr<Route> route, RouterResultCode e) { AssignRoute(route, e); }
|
||||
|
||||
bool IsSpeedLimitExceeded() const { return m_speedCameraManager.IsSpeedLimitExceeded(); }
|
||||
bool IsSpeedCamLimitExceeded() const { return m_speedCameraManager.IsSpeedLimitExceeded(); }
|
||||
SpeedCameraManager & GetSpeedCamManager() { return m_speedCameraManager; }
|
||||
SpeedCameraManager const & GetSpeedCamManager() const { return m_speedCameraManager; }
|
||||
|
||||
|
|
Reference in a new issue