From 7530e0a3accb51b88fcbea6a4ad0a35da36cc5f4 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Sat, 11 Feb 2017 02:06:20 -0500 Subject: [PATCH 1/4] [core] Expose Map::setZoom with anchor parameter --- include/mbgl/map/map.hpp | 1 + src/mbgl/map/map.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index c80420371dd..c51d7e9ffd7 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -98,6 +98,7 @@ class Map : private util::noncopyable { void setScale(double scale, optional = {}, const Duration& = Duration::zero()); double getScale() const; void setZoom(double zoom, const Duration& = Duration::zero()); + void setZoom(double zoom, optional, const Duration& = Duration::zero()); void setZoom(double zoom, optional, const Duration& = Duration::zero()); double getZoom() const; void setLatLngZoom(const LatLng&, double zoom, const Duration& = Duration::zero()); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 727fdf6d40e..bd69ce50f49 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -537,7 +537,13 @@ double Map::getScale() const { void Map::setZoom(double zoom, const Duration& duration) { impl->cameraMutated = true; - setZoom(zoom, {}, duration); + setZoom(zoom, optional {}, duration); +} + +void Map::setZoom(double zoom, optional anchor, const Duration& duration) { + impl->cameraMutated = true; + impl->transform.setZoom(zoom, anchor, duration); + impl->onUpdate(Update::RecalculateStyle); } void Map::setZoom(double zoom, optional padding, const Duration& duration) { From 3501438ccc9db7767b42c96990286a7ead2244b3 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Sat, 11 Feb 2017 02:11:17 -0500 Subject: [PATCH 2/4] [ios] Round tap-zoom gestures to nearest integer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round double-tap and two-finger tap zoom gestures to the nearest integer zoom level. This has the benefits for raster tiles, as well as styles with zoom-based functions. This results in a wider possible zoom range — ~0.5-1.5: Old: z4.6 → z5.6 (+1.0), z4.4 → z5.4 (+1.0) New: z4.6 → z6.0 (+1.4), z4.4 → z5.0 (+0.6) --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index c81ae31e2c7..5a299b9186a 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -42,6 +42,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added a `MGLDistanceFormatter` class for formatting geographic distances. ([#7888](https://github.com/mapbox/mapbox-gl-native/pull/7888)) * Added a method to MGLMapViewDelegate, `-mapView:shouldChangeFromCamera:toCamera:`, that you can implement to restrict which parts the user can navigate to using gestures. ([#5584](https://github.com/mapbox/mapbox-gl-native/pull/5584)) * Annotations are no longer deselected when the map is panned or zoomed, even if the annotation moves out of the visible bounds. ([#8022](https://github.com/mapbox/mapbox-gl-native/pull/8022)) +* Double-tap and two-finger tap gestures now zoom to the nearest integer zoom level. ([#8027](https://github.com/mapbox/mapbox-gl-native/pull/8027)) ## 3.4.1 - January 25, 2017 diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 77fd810e162..0b0bf4a34b4 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1556,10 +1556,12 @@ - (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap if (doubleTap.state == UIGestureRecognizerStateEnded) { MGLMapCamera *oldCamera = self.camera; - + + double newZoom = round(self.zoomLevel) + 1.0; + CGPoint gesturePoint = [self anchorPointForGesture:doubleTap]; - - MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:self.zoomLevel + 1.0 aroundAnchorPoint:gesturePoint]; + + MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:newZoom aroundAnchorPoint:gesturePoint]; if (![self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] || [self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:toCamera]) @@ -1567,7 +1569,7 @@ - (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap [self trackGestureEvent:MGLEventGestureDoubleTap forRecognizer:doubleTap]; mbgl::ScreenCoordinate center(gesturePoint.x, gesturePoint.y); - _mbglMap->scaleBy(2, center, MGLDurationInSecondsFromTimeInterval(MGLAnimationDuration)); + _mbglMap->setZoom(newZoom, center, MGLDurationInSecondsFromTimeInterval(MGLAnimationDuration)); __weak MGLMapView *weakSelf = self; @@ -1595,16 +1597,17 @@ - (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap { MGLMapCamera *oldCamera = self.camera; - double zoom = self.zoomLevel; + double newZoom = round(self.zoomLevel) - 1.0; + CGPoint gesturePoint = [self anchorPointForGesture:twoFingerTap]; - - MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:zoom - 1.0 aroundAnchorPoint:gesturePoint]; + + MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:newZoom aroundAnchorPoint:gesturePoint]; if (![self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] || [self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:toCamera]) { mbgl::ScreenCoordinate center(gesturePoint.x, gesturePoint.y); - _mbglMap->scaleBy(0.5, center, MGLDurationInSecondsFromTimeInterval(MGLAnimationDuration)); + _mbglMap->setZoom(newZoom, center, MGLDurationInSecondsFromTimeInterval(MGLAnimationDuration)); __weak MGLMapView *weakSelf = self; From 74b190194ccdf1811790d2f86ae5b80e278360d7 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Sat, 11 Feb 2017 02:39:19 -0500 Subject: [PATCH 3/4] [ios] Add iosapp Show Zoom Level debug option --- platform/ios/app/MBXViewController.m | 29 +++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 7df54ba65b1..d82bc18f781 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -77,6 +77,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { MBXSettingsMiscellaneousShowReuseQueueStats = 0, MBXSettingsMiscellaneousWorldTour, MBXSettingsMiscellaneousCustomUserDot, + MBXSettingsMiscellaneousShowZoomLevel, MBXSettingsMiscellaneousPrintLogFile, MBXSettingsMiscellaneousDeleteLogFile, }; @@ -113,6 +114,7 @@ @interface MBXViewController () Date: Sat, 11 Feb 2017 16:57:09 -0500 Subject: [PATCH 4/4] [macos] Round non-freeform zoom gestures/commands to nearest integer Affects: - Double-tap gestures - Two-finger tap gestures - +/- button pushes - Shortcut keys - Menu items and shortcut keys (in macapp) --- platform/macos/CHANGELOG.md | 1 + platform/macos/app/MapDocument.m | 4 ++-- platform/macos/src/MGLMapView.mm | 21 ++++++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index b52d1d70553..87790f75c2b 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -39,6 +39,7 @@ * Fixed flickering that occurred when panning past the antimeridian. ([#7574](https://github.com/mapbox/mapbox-gl-native/pull/7574)) * Added a method to MGLMapViewDelegate, `-mapView:shouldChangeFromCamera:toCamera:`, that you can implement to restrict which parts the user can navigate to using gestures. ([#5584](https://github.com/mapbox/mapbox-gl-native/pull/5584)) * Added a `MGLDistanceFormatter` class for formatting geographic distances. ([#7888](https://github.com/mapbox/mapbox-gl-native/pull/7888)) +* Zooming by double-tap, two-finger tap, zoom buttons, shortcut keys, or demo app menu items or shortcut keys now zooms to the nearest integer zoom level. ([#8027](https://github.com/mapbox/mapbox-gl-native/pull/8027)) ## 0.3.1 diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 6f635425276..2de189c856f 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -217,11 +217,11 @@ - (IBAction)chooseCustomStyle:(id)sender { } - (IBAction)zoomIn:(id)sender { - [self.mapView setZoomLevel:self.mapView.zoomLevel + 1 animated:YES]; + [self.mapView setZoomLevel:round(self.mapView.zoomLevel) + 1 animated:YES]; } - (IBAction)zoomOut:(id)sender { - [self.mapView setZoomLevel:self.mapView.zoomLevel - 1 animated:YES]; + [self.mapView setZoomLevel:round(self.mapView.zoomLevel) - 1 animated:YES]; } - (IBAction)snapToNorth:(id)sender { diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 3d5f71feb18..654ca84fd08 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -1042,7 +1042,22 @@ - (void)setZoomLevel:(double)zoomLevel animated:(BOOL)animated { } - (void)zoomBy:(double)zoomDelta animated:(BOOL)animated { - [self setZoomLevel:self.zoomLevel + zoomDelta animated:animated]; + [self setZoomLevel:round(self.zoomLevel) + zoomDelta animated:animated]; +} + +- (void)zoomBy:(double)zoomDelta atPoint:(NSPoint)point animated:(BOOL)animated { + [self willChangeValueForKey:@"centerCoordinate"]; + [self willChangeValueForKey:@"zoomLevel"]; + double newZoom = round(self.zoomLevel) + zoomDelta; + MGLMapCamera *oldCamera = self.camera; + mbgl::ScreenCoordinate center(point.x, self.bounds.size.height - point.y); + _mbglMap->setZoom(newZoom, center, MGLDurationInSecondsFromTimeInterval(animated ? MGLAnimationDuration : 0)); + if ([self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] + && ![self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:self.camera]) { + self.camera = oldCamera; + } + [self didChangeValueForKey:@"zoomLevel"]; + [self didChangeValueForKey:@"centerCoordinate"]; } - (void)scaleBy:(double)scaleFactor atPoint:(NSPoint)point animated:(BOOL)animated { @@ -1500,7 +1515,7 @@ - (void)handleDoubleClickGesture:(NSClickGestureRecognizer *)gestureRecognizer { _mbglMap->cancelTransitions(); NSPoint gesturePoint = [gestureRecognizer locationInView:self]; - [self scaleBy:2 atPoint:gesturePoint animated:YES]; + [self zoomBy:1 atPoint:gesturePoint animated:YES]; } - (void)smartMagnifyWithEvent:(NSEvent *)event { @@ -1512,7 +1527,7 @@ - (void)smartMagnifyWithEvent:(NSEvent *)event { // Tap with two fingers (“right-click”) to zoom out on mice but not trackpads. NSPoint gesturePoint = [self convertPoint:event.locationInWindow fromView:nil]; - [self scaleBy:0.5 atPoint:gesturePoint animated:YES]; + [self zoomBy:-1 atPoint:gesturePoint animated:YES]; } /// Rotate fingers to rotate.