summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wray <jason@mapbox.com>2017-10-03 18:08:13 -0700
committerJason Wray <jason@mapbox.com>2017-10-19 11:03:15 -0400
commitcabf5d2970148d47b9b1ecba02bfa1f36e1f94ac (patch)
tree77b48c0916715abbedfb1ce62ed8c32dd60fd221
parent6523b16c61d988960e24713d0198685801147c45 (diff)
downloadqtlocation-mapboxgl-cabf5d2970148d47b9b1ecba02bfa1f36e1f94ac.tar.gz
[ios] Avoid drawing view annotations across pixel boundaries
-rw-r--r--platform/darwin/src/MGLGeometry.mm13
-rw-r--r--platform/darwin/src/MGLGeometry_Private.h2
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--platform/ios/src/MGLFaux3DUserLocationAnnotationView.m12
-rw-r--r--platform/ios/src/MGLMapView.mm11
5 files changed, 28 insertions, 11 deletions
diff --git a/platform/darwin/src/MGLGeometry.mm b/platform/darwin/src/MGLGeometry.mm
index 1540a3a741..43bf74c407 100644
--- a/platform/darwin/src/MGLGeometry.mm
+++ b/platform/darwin/src/MGLGeometry.mm
@@ -4,6 +4,10 @@
#import <mbgl/util/projection.hpp>
+#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
+#import <Cocoa/Cocoa.h>
+#endif
+
/** Vertical field of view, measured in degrees, for determining the altitude
of the viewpoint.
@@ -57,3 +61,12 @@ double MGLZoomLevelForAltitude(CLLocationDistance altitude, CGFloat pitch, CLLoc
CGFloat mapPixelWidthAtZoom = std::cos(MGLRadiansFromDegrees(latitude)) * mbgl::util::M2PI * mbgl::util::EARTH_RADIUS_M / metersPerPixel;
return ::log2(mapPixelWidthAtZoom / mbgl::util::tileSize);
}
+
+CGPoint MGLPointRounded(CGPoint point) {
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+ CGFloat scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [UIScreen mainScreen].nativeScale : [UIScreen mainScreen].scale;
+#elif TARGET_OS_MAC
+ CGFloat scaleFactor = [NSScreen mainScreen].backingScaleFactor;
+#endif
+ return CGPointMake(round(point.x * scaleFactor) / scaleFactor, round(point.y * scaleFactor) / scaleFactor);
+}
diff --git a/platform/darwin/src/MGLGeometry_Private.h b/platform/darwin/src/MGLGeometry_Private.h
index 88fcf5b576..87a19989c1 100644
--- a/platform/darwin/src/MGLGeometry_Private.h
+++ b/platform/darwin/src/MGLGeometry_Private.h
@@ -138,3 +138,5 @@ NS_INLINE MGLRadianCoordinate2D MGLRadianCoordinateAtDistanceFacingDirection(MGL
cos(distance) - sin(coordinate.latitude) * sin(otherLatitude));
return MGLRadianCoordinate2DMake(otherLatitude, otherLongitude);
}
+
+CGPoint MGLPointRounded(CGPoint point);
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 3dd46f3e93..eca338db13 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -31,6 +31,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Selecting an annotation no longer sets the user tracking mode to `MGLUserTrackingModeNone`. ([#10094](https://github.com/mapbox/mapbox-gl-native/pull/10094))
* Added `-[MGLMapView cameraThatFitsShape:direction:edgePadding:]` to get a camera with zoom level and center coordinate computed to fit a shape. ([#10107](https://github.com/mapbox/mapbox-gl-native/pull/10107))
* Added support selection of shape and polyline annotations.([#9984](https://github.com/mapbox/mapbox-gl-native/pull/9984))
+* Fixed an issue where view annotations could be slightly misaligned. View annotation placement is now rounded to the nearest pixel. ([#10219](https://github.com/mapbox/mapbox-gl-native/pull/10219))
### Other changes
diff --git a/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m b/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m
index 63e754d9c6..1ed3d86ad1 100644
--- a/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m
+++ b/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m
@@ -175,8 +175,8 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01;
_puckArrow = [CAShapeLayer layer];
_puckArrow.path = [[self puckArrow] CGPath];
_puckArrow.fillColor = [self.mapView.tintColor CGColor];
- _puckArrow.bounds = CGRectMake(0, 0, MGLUserLocationAnnotationArrowSize, MGLUserLocationAnnotationArrowSize);
- _puckArrow.position = CGPointMake(super.bounds.size.width / 2.0, super.bounds.size.height / 2.0);
+ _puckArrow.bounds = CGRectMake(0, 0, round(MGLUserLocationAnnotationArrowSize), round(MGLUserLocationAnnotationArrowSize));
+ _puckArrow.position = CGPointMake(CGRectGetMidX(super.bounds), CGRectGetMidY(super.bounds));
_puckArrow.shouldRasterize = YES;
_puckArrow.rasterizationScale = [UIScreen mainScreen].scale;
_puckArrow.drawsAsynchronously = YES;
@@ -306,7 +306,7 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01;
[CATransaction setDisableActions:shouldDisableActions];
_accuracyRingLayer.bounds = CGRectMake(0, 0, accuracyRingSize, accuracyRingSize);
- _accuracyRingLayer.cornerRadius = accuracyRingSize / 2;
+ _accuracyRingLayer.cornerRadius = accuracyRingSize / 2.0;
// match the halo to the accuracy ring
_haloLayer.bounds = _accuracyRingLayer.bounds;
@@ -435,9 +435,11 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01;
- (CALayer *)circleLayerWithSize:(CGFloat)layerSize
{
+ layerSize = round(layerSize);
+
CALayer *circleLayer = [CALayer layer];
circleLayer.bounds = CGRectMake(0, 0, layerSize, layerSize);
- circleLayer.position = CGPointMake(super.bounds.size.width / 2.0, super.bounds.size.height / 2.0);
+ circleLayer.position = CGPointMake(CGRectGetMidX(super.bounds), CGRectGetMidY(super.bounds));
circleLayer.cornerRadius = layerSize / 2.0;
circleLayer.shouldRasterize = YES;
circleLayer.rasterizationScale = [UIScreen mainScreen].scale;
@@ -460,7 +462,7 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01;
- (CGFloat)calculateAccuracyRingSize
{
// diameter in screen points
- return self.userLocation.location.horizontalAccuracy / [self.mapView metersPerPointAtLatitude:self.userLocation.coordinate.latitude] * 2.0;
+ return round(self.userLocation.location.horizontalAccuracy / [self.mapView metersPerPointAtLatitude:self.userLocation.coordinate.latitude] * 2.0);
}
@end
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 4112df6e76..d0d34dbfa9 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -3379,7 +3379,7 @@ public:
{
annotationViewsForAnnotation[annotationValue] = annotationView;
annotationView.annotation = annotation;
- annotationView.center = [self convertCoordinate:annotation.coordinate toPointToView:self];
+ annotationView.center = MGLPointRounded([self convertCoordinate:annotation.coordinate toPointToView:self]);
[newAnnotationViews addObject:annotationView];
MGLAnnotationImage *annotationImage = self.invisibleAnnotationImage;
@@ -3805,7 +3805,7 @@ public:
return true;
}
- CGPoint calloutAnchorPoint = [self convertCoordinate:annotation.coordinate toPointToView:self];
+ CGPoint calloutAnchorPoint = MGLPointRounded([self convertCoordinate:annotation.coordinate toPointToView:self]);
CGRect frame = CGRectInset({ calloutAnchorPoint, CGSizeZero }, -CGRectGetWidth(annotationView.frame) / 2, -CGRectGetHeight(annotationView.frame) / 2);
annotationRect = UIEdgeInsetsInsetRect(frame, annotationView.alignmentRectInsets);
}
@@ -4143,7 +4143,7 @@ public:
/// image centered at the given coordinate.
- (CGRect)frameOfImage:(UIImage *)image centeredAtCoordinate:(CLLocationCoordinate2D)coordinate
{
- CGPoint calloutAnchorPoint = [self convertCoordinate:coordinate toPointToView:self];
+ CGPoint calloutAnchorPoint = MGLPointRounded([self convertCoordinate:coordinate toPointToView:self]);
CGRect frame = CGRectInset({ calloutAnchorPoint, CGSizeZero }, -image.size.width / 2, -image.size.height / 2);
return UIEdgeInsetsInsetRect(frame, image.alignmentRectInsets);
}
@@ -4582,7 +4582,6 @@ public:
if (_showsUserHeadingIndicator)
{
self.showsUserLocation = YES;
-
}
[self validateUserHeadingUpdating];
}
@@ -5288,7 +5287,7 @@ public:
if (annotationView)
{
- annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
+ annotationView.center = MGLPointRounded([self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self]);
}
}
@@ -5406,7 +5405,7 @@ public:
}
else
{
- userPoint = [self convertCoordinate:self.userLocation.coordinate toPointToView:self];
+ userPoint = MGLPointRounded([self convertCoordinate:self.userLocation.coordinate toPointToView:self]);
}
if ( ! annotationView.superview)