[macos] Map annotations to annotation tags

Optimized lookup of annotation tags by annotation from O(n) to a simple map lookup, for better performance and consistency with the iOS implementation of MGLMapView.
This commit is contained in:
Minh Nguyễn
2016-11-07 23:00:55 -08:00
committed by Minh Nguyễn
parent 5e65d8109a
commit b91bbbef10

View File

@@ -35,6 +35,7 @@
#import <mbgl/util/chrono.hpp>
#import <mbgl/util/run_loop.hpp>
#import <map>
#import <unordered_map>
#import <unordered_set>
@@ -110,6 +111,9 @@ enum { MGLAnnotationTagNotFound = UINT32_MAX };
/// the annotation itself.
typedef std::unordered_map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationTagContextMap;
/// Mapping from an annotation object to an annotation tag.
typedef std::map<id<MGLAnnotation>, MGLAnnotationTag> MGLAnnotationObjectTagMap;
/// Returns an NSImage for the default marker image.
NSImage *MGLDefaultMarkerImage() {
NSString *path = [[NSBundle mgl_frameworkBundle] pathForResource:MGLDefaultStyleMarkerSymbolName
@@ -172,6 +176,7 @@ public:
BOOL _didHideCursorDuringGesture;
MGLAnnotationTagContextMap _annotationContextsByAnnotationTag;
MGLAnnotationObjectTagMap _annotationTagsByAnnotation;
MGLAnnotationTag _selectedAnnotationTag;
MGLAnnotationTag _lastSelectedAnnotationTag;
/// Size of the rectangle formed by unioning the maximum slop area around every annotation image.
@@ -293,6 +298,7 @@ public:
// Set up annotation management and selection state.
_annotationImagesByIdentifier = [NSMutableDictionary dictionary];
_annotationContextsByAnnotationTag = {};
_annotationTagsByAnnotation = {};
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_lastSelectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastClick = {};
@@ -1708,6 +1714,7 @@ public:
MGLAnnotationContext context;
context.annotation = annotation;
_annotationContextsByAnnotationTag[annotationTag] = context;
_annotationTagsByAnnotation[annotation] = annotationTag;
[(NSObject *)annotation addObserver:self forKeyPath:@"coordinates" options:0 context:(void *)(NSUInteger)annotationTag];
} else if (![annotation isKindOfClass:[MGLMultiPolyline class]]
@@ -1745,6 +1752,7 @@ public:
context.annotation = annotation;
context.imageReuseIdentifier = annotationImage.reuseIdentifier;
_annotationContextsByAnnotationTag[annotationTag] = context;
_annotationTagsByAnnotation[annotation] = annotationTag;
if ([annotation isKindOfClass:[NSObject class]]) {
NSAssert(![annotation isKindOfClass:[MGLMultiPoint class]], @"Point annotation should not be MGLMultiPoint.");
@@ -1831,6 +1839,7 @@ public:
}
_annotationContextsByAnnotationTag.erase(annotationTag);
_annotationTagsByAnnotation.erase(annotation);
if ([annotation isKindOfClass:[NSObject class]] &&
![annotation isKindOfClass:[MGLMultiPoint class]]) {