Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[ios, macos] Introduce visible annotations API (#6061)
Browse files Browse the repository at this point in the history
Add visibleAnnotations API to make it easier for clients of MGLMapView
to query for all visible annotations in the map or all visible annotations
in a subsection of the map.
  • Loading branch information
boundsj authored Oct 27, 2016
1 parent 67ffc96 commit d5af9b6
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 0 deletions.
19 changes: 19 additions & 0 deletions platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
MBXSettingsAnnotations10000Sprites,
MBXSettingsAnnotationsTestShapes,
MBXSettingsAnnotationsCustomCallout,
MBXSettingsAnnotationsQueryAnnotations,
MBXSettingsAnnotationsRemoveAnnotations,
};

Expand Down Expand Up @@ -296,6 +297,7 @@ - (void)dismissSettings:(__unused id)sender
@"Add 10,000 Sprites",
@"Add Test Shapes",
@"Add Point With Custom Callout",
@"Query Annotations",
@"Remove Annotations",
]];
break;
Expand Down Expand Up @@ -401,6 +403,9 @@ - (void)performActionForSettingAtIndexPath:(NSIndexPath *)indexPath
case MBXSettingsAnnotationsCustomCallout:
[self addAnnotationWithCustomCallout];
break;
case MBXSettingsAnnotationsQueryAnnotations:
[self testQueryPointAnnotations];
break;
case MBXSettingsAnnotationsRemoveAnnotations:
[self.mapView removeAnnotations:self.mapView.annotations];
break;
Expand Down Expand Up @@ -1091,6 +1096,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];
Expand Down
21 changes: 21 additions & 0 deletions platform/ios/src/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,16 @@ IB_DESIGNABLE
*/
@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLAnnotation>) *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 <MGLAnnotation>) *visibleAnnotations;

/**
Adds an annotation to the map view.
Expand Down Expand Up @@ -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 <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect;

#pragma mark Managing Annotation Selections

/**
Expand Down
29 changes: 29 additions & 0 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2811,6 +2811,35 @@ - (void)removeStyleClass:(NSString *)styleClass
return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()];
}

- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotations
{
return [self visibleAnnotationsInRect:self.bounds];
}

- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect
{
if (_annotationContextsByAnnotationTag.empty())
{
return nil;
}

std::vector<MGLAnnotationTag> 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 <MGLAnnotation>)annotationWithTag:(MGLAnnotationTag)tag
{
Expand Down
21 changes: 21 additions & 0 deletions platform/macos/src/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,16 @@ IB_DESIGNABLE
*/
- (void)addAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)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 <MGLAnnotation>) *visibleAnnotations;

/**
Removes an annotation from the map view, deselecting it if it is selected.
Expand Down Expand Up @@ -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 <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect;

#pragma mark Managing Annotation Selections

/**
Expand Down
29 changes: 29 additions & 0 deletions platform/macos/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,35 @@ - (IBAction)rotate:(NSSlider *)sender {
return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()];
}

- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotations
{
return [self visibleFeaturesInRect:self.bounds];
}

- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect
{
if (_annotationContextsByAnnotationTag.empty())
{
return nil;
}

std::vector<MGLAnnotationTag> 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 <MGLAnnotation>)annotationWithTag:(MGLAnnotationTag)tag {
if (!_annotationContextsByAnnotationTag.count(tag)) {
Expand Down

0 comments on commit d5af9b6

Please sign in to comment.