diff --git a/iphone/Maps/Core/Location/MWMLocationHelpers.h b/iphone/Maps/Core/Location/MWMLocationHelpers.h index a676ac9410..f37f022855 100644 --- a/iphone/Maps/Core/Location/MWMLocationHelpers.h +++ b/iphone/Maps/Core/Location/MWMLocationHelpers.h @@ -1,4 +1,5 @@ #import "MWMLocationManager.h" +#import "SwiftBridge.h" #include "platform/location.hpp" #include "platform/measurement_utils.hpp" @@ -8,60 +9,26 @@ namespace location_helpers { -static inline char const * getSpeedSymbol(CLLocationSpeed const & metersPerSecond) -{ - // 0-1 m/s - static char const * turtle = "\xF0\x9F\x90\xA2 "; - // 1-2 m/s - static char const * pedestrian = "\xF0\x9F\x9A\xB6 "; - // 2-5 m/s - static char const * tractor = "\xF0\x9F\x9A\x9C "; - // 5-10 m/s - static char const * bicycle = "\xF0\x9F\x9A\xB2 "; - // 10-36 m/s - static char const * car = "\xF0\x9F\x9A\x97 "; - // 36-120 m/s - static char const * train = "\xF0\x9F\x9A\x85 "; - // 120-278 m/s - static char const * airplane = "\xE2\x9C\x88\xEF\xB8\x8F "; - // 278+ - static char const * rocket = "\xF0\x9F\x9A\x80 "; - - if (metersPerSecond <= 1.) - return turtle; - else if (metersPerSecond <= 2.) - return pedestrian; - else if (metersPerSecond <= 5.) - return tractor; - else if (metersPerSecond <= 10.) - return bicycle; - else if (metersPerSecond <= 36.) - return car; - else if (metersPerSecond <= 120.) - return train; - else if (metersPerSecond <= 278.) - return airplane; - else - return rocket; -} static inline NSString * formattedSpeedAndAltitude(CLLocation * location) { if (!location) return nil; - string result; + NSMutableString * result = [@"" mutableCopy]; if (location.altitude) - result = "\xE2\x96\xB2 " /* this is simple mountain symbol */ + - measurement_utils::FormatAltitude(location.altitude); + [result appendString:[NSString stringWithFormat:@"%@ %@", @"\xE2\x96\xB2", @(measurement_utils::FormatAltitude(location.altitude).c_str())]]; + // Speed is actual only for just received location if (location.speed > 0. && [location.timestamp timeIntervalSinceNow] >= -2.0) { - if (!result.empty()) - result += " "; - result += getSpeedSymbol(location.speed) + - measurement_utils::FormatSpeedWithDeviceUnits(location.speed); + if (result.length) + [result appendString:@" "]; + + [result appendString:[NSString stringWithFormat:@"%@%@", + [MWMLocationManager speedSymbolFor:location.speed], + @(measurement_utils::FormatSpeedWithDeviceUnits(location.speed).c_str())]]; } - return result.empty() ? nil : @(result.c_str()); + return result; } static inline NSString * formattedDistance(double const & meters) diff --git a/iphone/Maps/Core/Location/MWMLocationManager+SpeedAndAltitude.swift b/iphone/Maps/Core/Location/MWMLocationManager+SpeedAndAltitude.swift new file mode 100644 index 0000000000..f3f65129f8 --- /dev/null +++ b/iphone/Maps/Core/Location/MWMLocationManager+SpeedAndAltitude.swift @@ -0,0 +1,15 @@ +extension MWMLocationManager { + + static func speedSymbolFor(_ speed: Double) -> String { + switch max(speed, 0) { + case 0..<1: return "🐢" + case 1..<2: return "🚶" + case 2..<5: return "🏃" + case 5..<10: return "🚲" + case 10..<36: return "🚗" + case 36..<120: return "🚄" + case 120..<278: return "🛩" + default: return "🚀" + } + } +} diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 9b6c8862d8..e4e3e7d083 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -918,6 +918,9 @@ F6558DA21E642CC0002203AE /* MWMFacilitiesController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6558DA01E642CC0002203AE /* MWMFacilitiesController.mm */; }; F6558DA31E642CC0002203AE /* MWMFacilitiesController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6558DA01E642CC0002203AE /* MWMFacilitiesController.mm */; }; F6588E2C1B15C26700EE1E58 /* MWMTextView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6588E2B1B15C26700EE1E58 /* MWMTextView.mm */; }; + F660DEE41EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */ = {isa = PBXBuildFile; fileRef = F660DEE31EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift */; }; + F660DEE51EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */ = {isa = PBXBuildFile; fileRef = F660DEE31EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift */; }; + F660DEE61EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */ = {isa = PBXBuildFile; fileRef = F660DEE31EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift */; }; F6664BF91E6459CB00E703C2 /* PPFacilityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6664BF71E6459CB00E703C2 /* PPFacilityCell.swift */; }; F6664BFA1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6664BF71E6459CB00E703C2 /* PPFacilityCell.swift */; }; F6664BFB1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6664BF71E6459CB00E703C2 /* PPFacilityCell.swift */; }; @@ -2074,6 +2077,7 @@ F6558DA01E642CC0002203AE /* MWMFacilitiesController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMFacilitiesController.mm; sourceTree = ""; }; F6588E2A1B15C26700EE1E58 /* MWMTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTextView.h; sourceTree = ""; }; F6588E2B1B15C26700EE1E58 /* MWMTextView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTextView.mm; sourceTree = ""; }; + F660DEE31EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MWMLocationManager+SpeedAndAltitude.swift"; sourceTree = ""; }; F6664BF71E6459CB00E703C2 /* PPFacilityCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PPFacilityCell.swift; sourceTree = ""; }; F6664BF81E6459CB00E703C2 /* PPFacilityCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PPFacilityCell.xib; sourceTree = ""; }; F6664BFF1E6459DA00E703C2 /* PPReviewHeaderCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PPReviewHeaderCell.swift; sourceTree = ""; }; @@ -2791,6 +2795,7 @@ 3404752A1E081A4600C92850 /* MWMLocationHelpers.h */, 3404752B1E081A4600C92850 /* MWMLocationManager.h */, 3404752C1E081A4600C92850 /* MWMLocationManager.mm */, + F660DEE31EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift */, 3404752D1E081A4600C92850 /* MWMLocationObserver.h */, 3404752E1E081A4600C92850 /* MWMLocationPredictor.h */, 3404752F1E081A4600C92850 /* MWMLocationPredictor.mm */, @@ -5274,6 +5279,7 @@ 3490D2E01CE9DD2500D0B838 /* MWMSideButtonsView.mm in Sources */, 340475491E081A4600C92850 /* AppInfo.mm in Sources */, 34F4072B1E9E1AFF00E57AC0 /* Banner.swift in Sources */, + F660DEE41EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */, F6E2FDF11E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.mm in Sources */, F6E2FD821E097BA00083EBEC /* MWMMapDownloaderSearchDataSource.mm in Sources */, F6664C011E6459DA00E703C2 /* PPReviewHeaderCell.swift in Sources */, @@ -5571,6 +5577,7 @@ 349B926D1DF0518E007779DD /* MWMToast.mm in Sources */, 3404754A1E081A4600C92850 /* AppInfo.mm in Sources */, 34F4072C1E9E1AFF00E57AC0 /* Banner.swift in Sources */, + F660DEE51EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */, F6E2FDF21E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.mm in Sources */, F6E2FD831E097BA00083EBEC /* MWMMapDownloaderSearchDataSource.mm in Sources */, 3490D2E11CE9DD2500D0B838 /* MWMSideButtonsView.mm in Sources */, @@ -5868,6 +5875,7 @@ 849CF6F11DE842290024A8A5 /* MWMCircularProgress.mm in Sources */, 849CF6F31DE842290024A8A5 /* MWMButton.mm in Sources */, 34F4072D1E9E1AFF00E57AC0 /* Banner.swift in Sources */, + F660DEE61EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */, F6E2FDF31E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.mm in Sources */, F6E2FD841E097BA00083EBEC /* MWMMapDownloaderSearchDataSource.mm in Sources */, F6664C031E6459DA00E703C2 /* PPReviewHeaderCell.swift in Sources */, diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm index a0111c162f..4e9ed0cd63 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm @@ -92,7 +92,7 @@ using namespace place_page; { if (self.title.length) m_previewRows.push_back(PreviewRows::Title); if (self.externalTitle.length) m_previewRows.push_back(PreviewRows::ExternalTitle); - if (self.subtitle.length) m_previewRows.push_back(PreviewRows::Subtitle); + if (self.subtitle.length || self.isMyPosition) m_previewRows.push_back(PreviewRows::Subtitle); if (self.schedule != OpeningHours::Unknown) m_previewRows.push_back(PreviewRows::Schedule); if (self.isBooking) m_previewRows.push_back(PreviewRows::Booking); if (self.address.length) m_previewRows.push_back(PreviewRows::Address); diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm index 4edf4f75c9..fae8fa658e 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm @@ -8,6 +8,7 @@ #import "MWMFrameworkListener.h" #import "MWMFrameworkObservers.h" #import "MWMLocationManager.h" +#import "MWMLocationHelpers.h" #import "MWMLocationObserver.h" #import "MWMPlacePageData.h" #import "MWMPlacePageLayout.h" @@ -82,7 +83,7 @@ void logSponsoredEvent(MWMPlacePageData * data, NSString * eventName) } [MWMLocationManager addObserver:self]; - [self.layout setDistanceToObject:self.distanceToObject]; + [self setupSpeedAndDistance]; [self.layout showWithData:self.data]; @@ -200,9 +201,16 @@ void logSponsoredEvent(MWMPlacePageData * data, NSString * eventName) [self.layout rotateDirectionArrowToAngle:angle]; } -- (void)onLocationUpdate:(location::GpsInfo const &)locationInfo +- (void)setupSpeedAndDistance { [self.layout setDistanceToObject:self.distanceToObject]; + if (self.data.isMyPosition) + [self.layout setSpeedAndAltitude:location_helpers::formattedSpeedAndAltitude(MWMLocationManager.lastLocation)]; +} + +- (void)onLocationUpdate:(location::GpsInfo const &)locationInfo +{ + [self setupSpeedAndDistance]; } - (void)mwm_refreshUI { [self.layout mwm_refreshUI]; } diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.h b/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.h index 39e5415424..87d3a3f6f3 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.h +++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.h @@ -40,6 +40,7 @@ - (void)rotateDirectionArrowToAngle:(CGFloat)angle; - (void)setDistanceToObject:(NSString *)distance; +- (void)setSpeedAndAltitude:(NSString *)speedAndAltitude; - (void)processDownloaderEventWithStatus:(storage::NodeStatus)status progress:(CGFloat)progress; diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.mm b/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.mm index ba7ce90984..ccbf046062 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.mm +++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/MWMPlacePageLayout.mm @@ -156,6 +156,11 @@ map const kMetaInfoCells = { [self.previewLayoutHelper setDistanceToObject:distance]; } +- (void)setSpeedAndAltitude:(NSString *)speedAndAltitude +{ + [self.previewLayoutHelper setSpeedAndAltitude:speedAndAltitude]; +} + - (MWMPlacePageActionBar *)actionBar { if (!_actionBar) diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.h b/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.h index a653e23473..fc7485e78c 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.h +++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.h @@ -15,6 +15,7 @@ withData:(MWMPlacePageData *)data; - (void)rotateDirectionArrowToAngle:(CGFloat)angle; - (void)setDistanceToObject:(NSString *)distance; +- (void)setSpeedAndAltitude:(NSString *)speedAndAltitude; - (void)insertRowAtTheEnd; - (CGFloat)height; diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.mm b/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.mm index 68a4aa3c12..f3cf0895f3 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.mm +++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Preview/MWMPPPreviewLayoutHelper.mm @@ -140,12 +140,14 @@ array const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi @property(nonatomic) CGFloat leading; @property(nonatomic) MWMDirectionView * directionView; @property(copy, nonatomic) NSString * distance; +@property(copy, nonatomic) NSString * speedAndAltitude; @property(weak, nonatomic) UIImageView * compass; @property(nonatomic) NSIndexPath * lastCellIndexPath; @property(nonatomic) BOOL lastCellIsBanner; @property(nonatomic) NSUInteger distanceRow; @property(weak, nonatomic) MWMAdBanner * cachedBannerCell; +@property(weak, nonatomic) _MWMPPPSubtitle * cachedSubtitle; @end @@ -177,7 +179,10 @@ array const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi self.lastCellIsBanner = NO; self.lastCellIndexPath = [NSIndexPath indexPathForRow:previewRows.size() - 1 inSection:0]; auto it = find(previewRows.begin(), previewRows.end(), PreviewRows::Space); - if (it != previewRows.end()) + + if (data.isMyPosition) + self.distanceRow = 0; + else if (it != previewRows.end()) self.distanceRow = distance(previewRows.begin(), it) - 1; } @@ -198,8 +203,16 @@ array const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi static_cast<_MWMPPPExternalTitle *>(c).externalTitle.text = data.externalTitle; break; case PreviewRows::Subtitle: - static_cast<_MWMPPPSubtitle *>(c).subtitle.text = data.subtitle; + { + auto subtitleCell = static_cast<_MWMPPPSubtitle *>(c); + if (data.isMyPosition) + subtitleCell.subtitle.text = self.speedAndAltitude; + else + subtitleCell.subtitle.text = data.subtitle; + + self.cachedSubtitle = subtitleCell; break; + } case PreviewRows::Schedule: { auto scheduleCell = static_cast<_MWMPPPSchedule *>(c); @@ -293,6 +306,15 @@ array const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi self.directionView.distanceLabel.text = distance; } +- (void)setSpeedAndAltitude:(NSString *)speedAndAltitude +{ + if ([speedAndAltitude isEqualToString:_speedAndAltitude] || !self.data.isMyPosition) + return; + + _speedAndAltitude = speedAndAltitude; + self.cachedSubtitle.subtitle.text = speedAndAltitude; +} + - (void)insertRowAtTheEnd { auto const & previewRows = self.data.previewRows;