summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@mapbox.com>2018-02-19 22:28:13 -0500
committerJulian Rex <julian.rex@mapbox.com>2018-03-20 15:19:20 -0400
commita4e149431a218dc24b30541c940c6c1c0441a903 (patch)
tree099587441392b4a28b230a3e8593f4b575e26bdf
parent68fcbf0a7274516555bcc44f932c8bbe8f1eb073 (diff)
downloadqtlocation-mapboxgl-a4e149431a218dc24b30541c940c6c1c0441a903.tar.gz
[ios,macos] Removes check for on-screen in setSelectedAnnotations (#9790). Adds partial test.
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--platform/ios/app/MBXViewController.m57
-rw-r--r--platform/ios/src/MGLMapView.h3
-rw-r--r--platform/ios/src/MGLMapView.mm8
-rw-r--r--platform/ios/test/MGLAnnotationViewTests.m61
-rw-r--r--platform/macos/CHANGELOG.md1
-rw-r--r--platform/macos/app/Base.lproj/MainMenu.xib18
-rw-r--r--platform/macos/app/MapDocument.m60
-rw-r--r--platform/macos/src/MGLMapView.h3
-rw-r--r--platform/macos/src/MGLMapView.mm5
10 files changed, 195 insertions, 22 deletions
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 4288517265..fa5f1a7fab 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -36,6 +36,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Fixed an issue preventing `MGLAnnotationImage.image` from being updated. ([#10372](https://github.com/mapbox/mapbox-gl-native/pull/10372))
* Improved performance of `MGLAnnotationView`-backed annotations that have `scalesWithViewingDistance` enabled. ([#10951](https://github.com/mapbox/mapbox-gl-native/pull/10951))
* Fix an issue where a wrong annotation may selected if annotations were set close together. ([#11438](https://github.com/mapbox/mapbox-gl-native/pull/11438))
+* The `MGLMapView.selectedAnnotations` property (backed by `-[MGLMapView setSelectedAnnotations:]`) now selects annotations that are off-screen. ([#9790](https://github.com/mapbox/mapbox-gl-native/issues/9790))
### Map snapshots
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index a472e3a221..fcdc9af2b3 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -54,6 +54,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
MBXSettingsAnnotationsQueryAnnotations,
MBXSettingsAnnotationsCustomUserDot,
MBXSettingsAnnotationsRemoveAnnotations,
+ MBXSettingsAnnotationSelectRandomOffscreenAnnotation,
+ MBXSettingsAnnotationCenterSelectedAnnotation
};
typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
@@ -340,6 +342,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Query Annotations",
[NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
@"Remove Annotations",
+ @"Select an offscreen annotation",
+ @"Center selected annotation"
]];
break;
case MBXSettingsRuntimeStyling:
@@ -468,6 +472,14 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsAnnotationsRemoveAnnotations:
[self.mapView removeAnnotations:self.mapView.annotations];
break;
+ case MBXSettingsAnnotationSelectRandomOffscreenAnnotation:
+ [self selectAnOffscreenAnnotation];
+ break;
+
+ case MBXSettingsAnnotationCenterSelectedAnnotation:
+ [self centerSelectedAnnotation];
+ break;
+
default:
NSAssert(NO, @"All annotations setting rows should be implemented");
break;
@@ -1551,6 +1563,51 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[self presentViewController:alertController animated:YES completion:nil];
}
+- (id<MGLAnnotation>)randomOffscreenAnnotation {
+ NSArray *annotations = self.mapView.annotations;
+
+ if (annotations.count == 0)
+ return nil;
+
+ NSArray *visibleAnnotations = self.mapView.visibleAnnotations;
+
+ if (visibleAnnotations.count == annotations.count)
+ return nil;
+
+ NSMutableArray *invisibleAnnotations = [annotations mutableCopy];
+
+ if (visibleAnnotations.count > 0) {
+ [invisibleAnnotations removeObjectsInArray:visibleAnnotations];
+ }
+
+ // Now pick a random offscreen annotation.
+ uint32_t index = arc4random_uniform((uint32_t)invisibleAnnotations.count);
+ return invisibleAnnotations[index];
+}
+
+- (void)selectAnOffscreenAnnotation {
+ id<MGLAnnotation> annotation = [self randomOffscreenAnnotation];
+ [self.mapView selectAnnotation:annotation animated:NO];
+
+ // Alternative method to select the annotation (NOT ANIMATED). These two should do the same thing.
+ // self.mapView.selectedAnnotations = @[annotation];
+
+ NSAssert(self.mapView.selectedAnnotations.firstObject, @"The annotation was not selected");
+}
+
+- (void)centerSelectedAnnotation {
+ id<MGLAnnotation> annotation = self.mapView.selectedAnnotations.firstObject;
+
+ if (!annotation)
+ return;
+
+ CGPoint point = [self.mapView convertCoordinate:annotation.coordinate toPointToView:self.mapView];
+
+ // Animate, so that point becomes the the center
+ CLLocationCoordinate2D center = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
+ [self.mapView setCenterCoordinate:center animated:YES];
+}
+
- (void)printTelemetryLogFile
{
NSString *fileContents = [NSString stringWithContentsOfFile:[self telemetryDebugLogFilePath] encoding:NSUTF8StringEncoding error:nil];
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 52d28d871c..22fa58643d 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -1206,9 +1206,6 @@ MGL_EXPORT IB_DESIGNABLE
/**
Selects an annotation and displays a callout view for it.
- If the given annotation is not visible within the current viewport, this
- method has no effect.
-
@param annotation The annotation object to select.
@param animated If `YES`, the callout view is animated into position.
*/
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 6b47dc05f7..a639588caa 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -272,7 +272,7 @@ public:
CADisplayLink *_displayLink;
BOOL _needsDisplayRefresh;
- NSUInteger _changeDelimiterSuppressionDepth;
+ NSInteger _changeDelimiterSuppressionDepth;
/// Center coordinate of the pinch gesture on the previous iteration of the gesture.
CLLocationCoordinate2D _previousPinchCenterCoordinate;
@@ -4274,11 +4274,7 @@ public:
if ([firstAnnotation isKindOfClass:[MGLMultiPoint class]]) return;
- // Select the annotation if it’s visible.
- if (MGLCoordinateInCoordinateBounds(firstAnnotation.coordinate, self.visibleCoordinateBounds))
- {
- [self selectAnnotation:firstAnnotation animated:NO];
- }
+ [self selectAnnotation:firstAnnotation animated:NO];
}
- (void)selectAnnotation:(id <MGLAnnotation>)annotation animated:(BOOL)animated
diff --git a/platform/ios/test/MGLAnnotationViewTests.m b/platform/ios/test/MGLAnnotationViewTests.m
index fc4f35a9e1..128fab472e 100644
--- a/platform/ios/test/MGLAnnotationViewTests.m
+++ b/platform/ios/test/MGLAnnotationViewTests.m
@@ -57,6 +57,7 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReu
@property (nonatomic) XCTestExpectation *expectation;
@property (nonatomic) MGLMapView *mapView;
@property (nonatomic, weak) MGLAnnotationView *annotationView;
+@property (nonatomic) NSInteger annotationSelectedCount;
@end
@implementation MGLAnnotationViewTests
@@ -98,6 +99,61 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReu
XCTAssertNotNil(customAnnotationView);
}
+- (void)testSelectingOffscreenAnnotation
+{
+ // Partial test for https://github.com/mapbox/mapbox-gl-native/issues/9790
+
+ // This isn't quite the same as in updateAnnotationViews, but should be sufficient for this test.
+ MGLCoordinateBounds coordinateBounds = [_mapView convertRect:_mapView.bounds toCoordinateBoundsFromView:_mapView];
+
+ // -90 latitude is invalid. TBD.
+ BOOL anyOffscreen = NO;
+ NSInteger selectionCount = 0;
+
+ for (NSInteger latitude = -89; latitude <= 90; latitude += 10)
+ {
+ for (NSInteger longitude = -180; longitude <= 180; longitude += 10)
+ {
+ MGLTestAnnotation *annotation = [[MGLTestAnnotation alloc] init];
+
+ annotation.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
+ [_mapView addAnnotation:annotation];
+
+ if (!(MGLCoordinateInCoordinateBounds(annotation.coordinate, coordinateBounds)))
+ anyOffscreen = YES;
+
+ XCTAssertNil(_mapView.selectedAnnotations.firstObject, @"There should be no selected annotation");
+
+ // First selection
+ [_mapView selectAnnotation:annotation animated:NO];
+ selectionCount++;
+
+ XCTAssert(_mapView.selectedAnnotations.count == 1, @"There should only be 1 selected annotation");
+ XCTAssertEqualObjects(_mapView.selectedAnnotations.firstObject, annotation, @"The annotation should be selected");
+
+ // Deselect
+ [_mapView deselectAnnotation:annotation animated:NO];
+ XCTAssert(_mapView.selectedAnnotations.count == 0, @"There should be no selected annotations");
+
+ // Second selection
+ _mapView.selectedAnnotations = @[annotation];
+ selectionCount++;
+
+ XCTAssert(_mapView.selectedAnnotations.count == 1, @"There should be 1 selected annotation");
+ XCTAssertEqualObjects(_mapView.selectedAnnotations.firstObject, annotation, @"The annotation should be selected");
+
+ // Deselect
+ [_mapView deselectAnnotation:annotation animated:NO];
+ XCTAssert(_mapView.selectedAnnotations.count == 0, @"There should be no selected annotations");
+ }
+ }
+
+ XCTAssert(anyOffscreen, @"At least one of these annotations should be offscreen");
+ XCTAssertEqual(selectionCount, self.annotationSelectedCount, @"-mapView:didSelectAnnotation: should be called for each selection");
+}
+
+#pragma mark - MGLMapViewDelegate -
+
- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAnnotation>)annotation
{
MGLAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:MGLTestAnnotationReuseIdentifer];
@@ -117,4 +173,9 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReu
[_expectation fulfill];
}
+- (void)mapView:(MGLMapView *)mapView didSelectAnnotation:(id<MGLAnnotation>)annotation
+{
+ self.annotationSelectedCount++;
+}
+
@end
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index 6de2a4e87e..4bbb2dfb63 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -37,6 +37,7 @@
* The `-[MGLMapView convertRect:toCoordinateBoundsFromView:]` method and the `MGLMapView.visibleCoordinateBounds` property’s getter now indicate that the coordinate bounds straddles the antimeridian by extending one side beyond ±180 degrees longitude. ([#11265](https://github.com/mapbox/mapbox-gl-native/pull/11265))
* Feature querying results now account for the `MGLSymbolStyleLayer.circleStrokeWidth` property. ([#10897](https://github.com/mapbox/mapbox-gl-native/pull/10897))
* Removed methods, properties, and constants that had been deprecated as of v0.6.1. ([#11205](https://github.com/mapbox/mapbox-gl-native/pull/11205))
+* The `MGLMapView.selectedAnnotations` property (backed by `-[MGLMapView setSelectedAnnotations:]`) now selects annotations that are off-screen. ([#9790](https://github.com/mapbox/mapbox-gl-native/issues/9790))
## v0.6.1 - January 16, 2018
diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib
index 4cf8d87653..64d776832f 100644
--- a/platform/macos/app/Base.lproj/MainMenu.xib
+++ b/platform/macos/app/Base.lproj/MainMenu.xib
@@ -545,7 +545,13 @@
<action selector="drawAnimatedAnnotation:" target="-1" id="CYM-WB-s97"/>
</connections>
</menuItem>
- <menuItem title="Show All Annnotations" keyEquivalent="A" id="yMj-uM-8SN">
+ <menuItem title="Select and Center Offscreen Annotation" id="Xy2-Cc-RUB">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="selectAndCenterOffscreenAnnotation:" target="-1" id="W0A-AH-NqK"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Show All Annotations" keyEquivalent="A" id="yMj-uM-8SN">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="showAllAnnotations:" target="-1" id="ahr-OR-Em2"/>
@@ -664,7 +670,7 @@ CA
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="109" y="131" width="350" height="84"/>
- <rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="eA4-n3-qPe">
<rect key="frame" x="0.0" y="0.0" width="350" height="84"/>
<autoresizingMask key="autoresizingMask"/>
@@ -740,7 +746,7 @@ CA
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" utility="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="830" y="430" width="400" height="300"/>
- <rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="8ha-hw-zOD">
<rect key="frame" x="0.0" y="0.0" width="400" height="300"/>
<autoresizingMask key="autoresizingMask"/>
@@ -748,11 +754,11 @@ CA
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q8b-0e-dLv">
<rect key="frame" x="-1" y="20" width="402" height="281"/>
<clipView key="contentView" id="J9U-Yx-o2S">
- <rect key="frame" x="1" y="0.0" width="400" height="280"/>
+ <rect key="frame" x="1" y="0.0" width="400" height="265"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" autosaveColumns="NO" headerView="MAZ-Iq-hBi" id="Ato-Vu-HYT">
- <rect key="frame" x="0.0" y="0.0" width="423" height="257"/>
+ <rect key="frame" x="0.0" y="0.0" width="423" height="242"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -891,7 +897,7 @@ CA
</subviews>
</clipView>
<scroller key="horizontalScroller" verticalHuggingPriority="750" horizontal="YES" id="QLr-6P-Ogs">
- <rect key="frame" x="1" y="264" width="400" height="16"/>
+ <rect key="frame" x="1" y="265" width="400" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="q0K-eE-mzL">
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index 03557caca2..9127df9346 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -641,6 +641,63 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
repeats:YES];
}
+
+- (id<MGLAnnotation>)randomOffscreenAnnotation {
+ NSArray *annotations = self.mapView.annotations;
+
+ if (annotations.count == 0)
+ return nil;
+
+ // NOTE: This occasionally returns nil - see
+ // https://github.com/mapbox/mapbox-gl-native/issues/11296
+ NSArray *visibleAnnotations = self.mapView.visibleAnnotations;
+
+ NSLog(@"Number of visible annotations = %d", visibleAnnotations.count);
+
+ if (visibleAnnotations.count == annotations.count)
+ return nil;
+
+ NSMutableArray *invisibleAnnotations = [annotations mutableCopy];
+
+ if (visibleAnnotations.count > 0) {
+ [invisibleAnnotations removeObjectsInArray:visibleAnnotations];
+ }
+
+ // Now pick a random offscreen annotation.
+ uint32_t index = arc4random_uniform((uint32_t)invisibleAnnotations.count);
+ return invisibleAnnotations[index];
+}
+
+- (void)selectAnOffscreenAnnotation {
+ id<MGLAnnotation> annotation = [self randomOffscreenAnnotation];
+ [self.mapView selectAnnotation:annotation];
+
+ // Alternative method to select the annotation. These two should do the same thing.
+// self.mapView.selectedAnnotations = @[annotation];
+
+ NSAssert(self.mapView.selectedAnnotations.firstObject, @"The annotation was not selected");
+}
+
+- (void)centerSelectedAnnotation {
+ id<MGLAnnotation> annotation = self.mapView.selectedAnnotations.firstObject;
+
+ if (!annotation)
+ return;
+
+ CGPoint point = [self.mapView convertCoordinate:annotation.coordinate toPointToView:self.mapView];
+
+ // Animate, so that point becomes the the center
+ CLLocationCoordinate2D center = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
+ [self.mapView setCenterCoordinate:center animated:YES];
+}
+
+- (IBAction)selectAndCenterOffscreenAnnotation:(id)sender {
+ [self selectAnOffscreenAnnotation];
+ [self centerSelectedAnnotation];
+}
+
+
+
- (void)updateAnimatedAnnotation:(NSTimer *)timer {
DroppedPinAnnotation *annotation = timer.userInfo;
double angle = timer.fireDate.timeIntervalSinceReferenceDate;
@@ -1111,6 +1168,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
if (menuItem.action == @selector(insertGraticuleLayer:)) {
return ![self.mapView.style sourceWithIdentifier:@"graticule"];
}
+ if (menuItem.action == @selector(selectAndCenterOffscreenAnnotation:)) {
+ return YES;
+ }
if (menuItem.action == @selector(showAllAnnotations:) || menuItem.action == @selector(removeAllAnnotations:)) {
return self.mapView.annotations.count > 0;
}
diff --git a/platform/macos/src/MGLMapView.h b/platform/macos/src/MGLMapView.h
index 050145b80b..344052c310 100644
--- a/platform/macos/src/MGLMapView.h
+++ b/platform/macos/src/MGLMapView.h
@@ -727,9 +727,6 @@ MGL_EXPORT IB_DESIGNABLE
/**
Selects an annotation and displays a callout popover for it.
- If the given annotation is not visible within the current viewport, this method
- has no effect.
-
@param annotation The annotation object to select.
*/
- (void)selectAnnotation:(id <MGLAnnotation>)annotation;
diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm
index 353b2bf2f1..ffca1d30ad 100644
--- a/platform/macos/src/MGLMapView.mm
+++ b/platform/macos/src/MGLMapView.mm
@@ -2205,10 +2205,7 @@ public:
return;
}
- // Select the annotation if it’s visible.
- if (MGLCoordinateInCoordinateBounds(firstAnnotation.coordinate, self.visibleCoordinateBounds)) {
- [self selectAnnotation:firstAnnotation];
- }
+ [self selectAnnotation:firstAnnotation];
}
- (void)selectAnnotation:(id <MGLAnnotation>)annotation