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

Allow annotation images to be updated #3146

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gyp/platform-ios.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
'../platform/ios/MGLUserLocationAnnotationView.h',
'../platform/ios/MGLUserLocationAnnotationView.m',
'../include/mbgl/ios/MGLAnnotationImage.h',
'../platform/ios/MGLAnnotationImage_Private.h',
'../platform/ios/MGLAnnotationImage.m',
'../platform/ios/MGLCategoryLoader.h',
'../platform/ios/MGLCategoryLoader.m',
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/ios/MGLAnnotationImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
/** @name Getting and Setting Attributes */

/** The image to be displayed for the annotation. */
@property (nonatomic, readonly) UIImage *image;
@property (nonatomic, strong) UIImage *image;

/** The string that identifies that this annotation image is reusable. (read-only)
*
Expand Down
11 changes: 8 additions & 3 deletions platform/ios/MGLAnnotationImage.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#import "MGLAnnotationImage.h"
#import "MGLAnnotationImage_Private.h"

@interface MGLAnnotationImage ()

@property (nonatomic) UIImage *image;
@property (nonatomic) NSString *reuseIdentifier;
@property (nonatomic, strong) NSString *reuseIdentifier;
@property (nonatomic, weak) id<MGLAnnotationImageDelegate> delegate;

@end

Expand All @@ -28,4 +28,9 @@ - (instancetype)initWithImage:(UIImage *)image reuseIdentifier:(NSString *)reuse
return self;
}

- (void)setImage:(UIImage *)image {
_image = image;
[self.delegate annotationImageNeedsRedisplay:self];
}

@end
18 changes: 18 additions & 0 deletions platform/ios/MGLAnnotationImage_Private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#import "MGLAnnotationImage.h"

NS_ASSUME_NONNULL_BEGIN

@protocol MGLAnnotationImageDelegate <NSObject>

@required
- (void)annotationImageNeedsRedisplay:(MGLAnnotationImage *)annotationImage;

@end

@interface MGLAnnotationImage (Private)

@property (nonatomic, weak) id<MGLAnnotationImageDelegate> delegate;

@end

NS_ASSUME_NONNULL_END
16 changes: 15 additions & 1 deletion platform/ios/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#import "MGLUserLocationAnnotationView.h"
#import "MGLUserLocation_Private.h"
#import "MGLAccountManager_Private.h"
#import "MGLAnnotationImage_Private.h"
#import "MGLMapboxEvents.h"

#import "SMCalloutView.h"
Expand Down Expand Up @@ -120,7 +121,8 @@ @interface MGLMapView () <UIGestureRecognizerDelegate,
CLLocationManagerDelegate,
UIActionSheetDelegate,
SMCalloutViewDelegate,
MGLMultiPointDelegate>
MGLMultiPointDelegate,
MGLAnnotationImageDelegate>

@property (nonatomic) EAGLContext *context;
@property (nonatomic) GLKView *glView;
Expand Down Expand Up @@ -2144,6 +2146,7 @@ - (void)addAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)annotations
{
self.annotationImagesByIdentifier[annotationImage.reuseIdentifier] = annotationImage;
[self installAnnotationImage:annotationImage];
annotationImage.delegate = self;
}

NSString *symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
Expand Down Expand Up @@ -2687,6 +2690,17 @@ - (void)showAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)annotations animated:
animated:animated];
}

#pragma mark Annotation Image Delegate

- (void)annotationImageNeedsRedisplay:(MGLAnnotationImage *)annotationImage
{
// remove sprite
NSString *symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
_mbglMap->removeAnnotationIcon(symbolName.UTF8String);
[self installAnnotationImage:annotationImage];
_mbglMap->update(mbgl::Update::Annotations);
}

#pragma mark - User Location -

- (void)setShowsUserLocation:(BOOL)showsUserLocation
Expand Down
5 changes: 5 additions & 0 deletions src/mbgl/annotation/annotation_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ void AnnotationManager::addIcon(const std::string& name, std::shared_ptr<const S
spriteStore.setSprite(name, sprite);
spriteAtlas.updateDirty();
}

void AnnotationManager::removeIcon(const std::string& name) {
spriteStore.removeSprite(name);
spriteAtlas.updateDirty();
}

double AnnotationManager::getTopOffsetPixelsForIcon(const std::string& name) {
auto sprite = spriteStore.getSprite(name);
Expand Down
1 change: 1 addition & 0 deletions src/mbgl/annotation/annotation_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AnnotationManager : private util::noncopyable {
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&) const;

void addIcon(const std::string& name, std::shared_ptr<const SpriteImage>);
void removeIcon(const std::string& name);
double getTopOffsetPixelsForIcon(const std::string& name);
SpriteAtlas& getSpriteAtlas() { return spriteAtlas; }

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ void Map::addAnnotationIcon(const std::string& name, std::shared_ptr<const Sprit
}

void Map::removeAnnotationIcon(const std::string& name) {
addAnnotationIcon(name, nullptr);
removeAnnotationIcon(name);
}

double Map::getTopOffsetPixelsForAnnotationIcon(const std::string& symbol) {
Expand Down
7 changes: 6 additions & 1 deletion src/mbgl/map/map_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ void MapContext::addAnnotationIcon(const std::string& name, std::shared_ptr<cons
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
data.getAnnotationManager()->addIcon(name, sprite);
}

void MapContext::removeAnnotationIcon(const std::string& name) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
data.getAnnotationManager()->removeIcon(name);
}

double MapContext::getTopOffsetPixelsForAnnotationIcon(const std::string& name) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
Expand All @@ -298,7 +303,7 @@ void MapContext::onLowMemory() {
style->onLowMemory();
asyncInvalidate.send();
}

void MapContext::onTileDataChanged() {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
updateFlags |= Update::Repaint;
Expand Down
1 change: 1 addition & 0 deletions src/mbgl/map/map_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class MapContext : public Style::Observer {

// Annotations
void addAnnotationIcon(const std::string&, std::shared_ptr<const SpriteImage>);
void removeAnnotationIcon(const std::string&);
double getTopOffsetPixelsForAnnotationIcon(const std::string&);
void updateAnnotations();

Expand Down
8 changes: 6 additions & 2 deletions src/mbgl/sprite/sprite_atlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,12 @@ void SpriteAtlas::updateDirty() {
// The two names match;
Holder& holder = imageIterator->second;
holder.texture = spriteIterator->second;
copy(holder, imageIterator->first.second);

if (holder.texture != nullptr) {
copy(holder, imageIterator->first.second);
} else {
images.erase(imageIterator);
}

++imageIterator;
// Don't advance the spriteIterator because there might be another sprite with the same
// name, but a different wrap value.
Expand Down