diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 3a58c1163a9..92f23da6752 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -46,6 +46,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) { MBXSettingsAnnotations10000Sprites, MBXSettingsAnnotationsTestShapes, MBXSettingsAnnotationsCustomCallout, + MBXSettingsAnnotationsQueryAnnotations, MBXSettingsAnnotationsRemoveAnnotations, }; @@ -291,6 +292,7 @@ - (void)dismissSettings:(__unused id)sender @"Add 10,000 Sprites", @"Add Test Shapes", @"Add Point With Custom Callout", + @"Query Annotations", @"Remove Annotations", ]]; break; @@ -391,6 +393,9 @@ - (void)performActionForSettingAtIndexPath:(NSIndexPath *)indexPath case MBXSettingsAnnotationsCustomCallout: [self addAnnotationWithCustomCallout]; break; + case MBXSettingsAnnotationsQueryAnnotations: + [self testQueryPointAnnotations]; + break; case MBXSettingsAnnotationsRemoveAnnotations: [self.mapView removeAnnotations:self.mapView.annotations]; break; @@ -955,6 +960,20 @@ - (void)toggleCustomUserDot self.mapView.userTrackingMode = MGLUserTrackingModeFollow; } +- (void)testQueryPointAnnotations { + NSNumber *visibleAnnotationCount = @(self.mapView.visibleAnnotations.count); + NSString *message; + if ([visibleAnnotationCount integerValue] == 1) { + message = [NSString stringWithFormat:@"There is %@ visible annotation.", visibleAnnotationCount]; + } else { + message = [NSString stringWithFormat:@"There are %@ visible annotations.", visibleAnnotationCount]; + } + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Visible Annotations" message:message preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:alertController animated:YES completion:nil]; +} + - (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 5a89632db82..e467495a4af 100644 --- a/platform/ios/src/MGLMapView.h +++ b/platform/ios/src/MGLMapView.h @@ -892,6 +892,16 @@ IB_DESIGNABLE */ @property (nonatomic, readonly, nullable) NS_ARRAY_OF(id ) *annotations; +/** + The complete list of annotations associated with the receiver that are + currently visible. + + The objects in this array must adopt the `MGLAnnotation` protocol. If no + annotations are associated with the map view or if no annotations associated + with the map view are currently visible, the value of this property is `nil`. + */ +@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id ) *visibleAnnotations; + /** Adds an annotation to the map view. @@ -986,6 +996,17 @@ IB_DESIGNABLE */ - (nullable __kindof MGLAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier; +/** + Returns the list of annotations associated with the receiver that intersect with + the given rectangle. + + @param rect A rectangle expressed in the map view’s coordinate system. + @return An array of objects that adopt the `MGLAnnotation` protocol or `nil` if + no annotations associated with the map view are currently visible in the + rectangle. + */ +- (nullable NS_ARRAY_OF(id ) *)visibleAnnotationsInRect:(CGRect)rect; + #pragma mark Managing Annotation Selections /** diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index c6c0920f56e..24a69e1d5a5 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -2811,6 +2811,35 @@ - (void)removeStyleClass:(NSString *)styleClass return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()]; } +- (nullable NS_ARRAY_OF(id ) *)visibleAnnotations +{ + return [self visibleAnnotationsInRect:self.bounds]; +} + +- (nullable NS_ARRAY_OF(id ) *)visibleAnnotationsInRect:(CGRect)rect +{ + if (_annotationContextsByAnnotationTag.empty()) + { + return nil; + } + + std::vector annotationTags = [self annotationTagsInRect:rect]; + if (annotationTags.size()) + { + NSMutableArray *annotations = [NSMutableArray arrayWithCapacity:annotationTags.size()]; + + for (auto const& annotationTag: annotationTags) + { + MGLAnnotationContext annotationContext = _annotationContextsByAnnotationTag[annotationTag]; + [annotations addObject:annotationContext.annotation]; + } + + return [annotations copy]; + } + + return nil; +} + /// Returns the annotation assigned the given tag. Cheap. - (id )annotationWithTag:(MGLAnnotationTag)tag { diff --git a/platform/macos/src/MGLMapView.h b/platform/macos/src/MGLMapView.h index 3499671ff1e..3dbbbe3d827 100644 --- a/platform/macos/src/MGLMapView.h +++ b/platform/macos/src/MGLMapView.h @@ -568,6 +568,16 @@ IB_DESIGNABLE */ - (void)addAnnotations:(NS_ARRAY_OF(id ) *)annotations; +/** + The complete list of annotations associated with the receiver that are + currently visible. + + The objects in this array must adopt the `MGLAnnotation` protocol. If no + annotations are associated with the map view or if no annotations associated + with the map view are currently visible, the value of this property is `nil`. + */ +@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id ) *visibleAnnotations; + /** Removes an annotation from the map view, deselecting it if it is selected. @@ -608,6 +618,17 @@ IB_DESIGNABLE */ - (nullable MGLAnnotationImage *)dequeueReusableAnnotationImageWithIdentifier:(NSString *)identifier; +/** + Returns the list of annotations associated with the receiver that intersect with + the given rectangle. + + @param rect A rectangle expressed in the map view’s coordinate system. + @return An array of objects that adopt the `MGLAnnotation` protocol or `nil` if + no annotations associated with the map view are currently visible in the + rectangle. + */ +- (nullable NS_ARRAY_OF(id ) *)visibleAnnotationsInRect:(CGRect)rect; + #pragma mark Managing Annotation Selections /** diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 14b83762a32..4d1f00359df 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -1616,6 +1616,35 @@ - (IBAction)rotate:(NSSlider *)sender { return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()]; } +- (nullable NS_ARRAY_OF(id ) *)visibleAnnotations +{ + return [self visibleFeaturesInRect:self.bounds]; +} + +- (nullable NS_ARRAY_OF(id ) *)visibleAnnotationsInRect:(CGRect)rect +{ + if (_annotationContextsByAnnotationTag.empty()) + { + return nil; + } + + std::vector annotationTags = [self annotationTagsInRect:rect]; + if (annotationTags.size()) + { + NSMutableArray *annotations = [NSMutableArray arrayWithCapacity:annotationTags.size()]; + + for (auto const& annotationTag: annotationTags) + { + MGLAnnotationContext annotationContext = _annotationContextsByAnnotationTag[annotationTag]; + [annotations addObject:annotationContext.annotation]; + } + + return [annotations copy]; + } + + return nil; +} + /// Returns the annotation assigned the given tag. Cheap. - (id )annotationWithTag:(MGLAnnotationTag)tag { if (!_annotationContextsByAnnotationTag.count(tag)) {