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

Commit

Permalink
[ios, macos] fixes #6160: allow updating multipoint coordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
incanus committed Oct 3, 2016
1 parent d4151c9 commit 086297d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 10 deletions.
10 changes: 10 additions & 0 deletions platform/darwin/src/MGLMultiPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range;

/**
Updates the coordinates for the shape, which will instantaneously redraw the
shape if it is currently visible on the map.
@param coords The array of coordinates defining the shape. The data in this
array is copied to the object.
@param count The number of items in the `coords` array.
*/
- (void)updateCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;

@end

NS_ASSUME_NONNULL_END
43 changes: 33 additions & 10 deletions platform/darwin/src/MGLMultiPoint.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,28 @@ - (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords

if (self)
{
_count = count;
_coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D));
[self setupWithCoordinates:coords count:count];
}

return self;
}

- (void)setupWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
if (_coordinates) free(_coordinates);

mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
_count = count;
_coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D));

for (NSUInteger i = 0; i < _count; i++)
{
_coordinates[i] = coords[i];
bounds.extend(mbgl::LatLng(coords[i].latitude, coords[i].longitude));
}
mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();

_bounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
for (NSUInteger i = 0; i < _count; i++)
{
_coordinates[i] = coords[i];
bounds.extend(mbgl::LatLng(coords[i].latitude, coords[i].longitude));
}

return self;
_bounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
}

- (void)dealloc
Expand Down Expand Up @@ -93,6 +100,22 @@ - (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range
}
}

- (void)updateCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
if ([self isMemberOfClass:[MGLMultiPoint class]])
{
[[NSException exceptionWithName:@"MGLAbstractClassException"
reason:@"MGLMultiPoint is an abstract class"
userInfo:nil] raise];
}

assert(_count > 0);

[self willChangeValueForKey:@"coordinates"];
[self setupWithCoordinates:coords count:count];
[self didChangeValueForKey:@"coordinates"];
}

- (MGLCoordinateBounds)overlayBounds
{
return _bounds;
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 @@ -1795,6 +1795,29 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
}
}
}
else if ([keyPath isEqualToString:@"coordinates"] && [object isKindOfClass:[MGLMultiPoint class]])
{
MGLMultiPoint *annotation = object;
MGLAnnotationTag annotationTag = (MGLAnnotationTag)(NSUInteger)context;
// We can get here because a subclass registered itself as an observer
// of the coordinates key path of a multipoint annotation but failed
// to handle the change. This check deters us from treating the
// subclass’s context as an annotation tag. If the context happens to
// match a valid annotation tag, the annotation will be unnecessarily
// but safely updated.
if (annotation == [self annotationWithTag:annotationTag])
{
// Update the annotation’s backing geometry to match the annotation model object.
_mbglMap->updateAnnotation(annotationTag, [annotation annotationObjectWithDelegate:self]);

// We don't current support shape multipoint annotation selection, but let's make sure
// deselection is handled just to avoid problems in the future.
if (annotationTag == _selectedAnnotationTag)
{
[self deselectAnnotation:annotation animated:YES];
}
}
}
}

+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingZoomEnabled
Expand Down Expand Up @@ -2840,6 +2863,8 @@ - (void)addAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)annotations
MGLAnnotationContext context;
context.annotation = annotation;
_annotationContextsByAnnotationTag[annotationTag] = context;

[(NSObject *)annotation addObserver:self forKeyPath:@"coordinates" options:0 context:(void *)(NSUInteger)annotationTag];
}
else if ( ! [annotation isKindOfClass:[MGLMultiPolyline class]]
|| ![annotation isKindOfClass:[MGLMultiPolygon class]]
Expand Down Expand Up @@ -3132,6 +3157,10 @@ - (void)removeAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)annotations
{
[(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag];
}
else if ([annotation isKindOfClass:[MGLMultiPoint class]])
{
[(NSObject *)annotation removeObserver:self forKeyPath:@"coordinates" context:(void *)(NSUInteger)annotationTag];
}

_mbglMap->removeAnnotation(annotationTag);
}
Expand Down

2 comments on commit 086297d

@AlexisMedinaM
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can I use this?, I have a MGLPolygon and I want to update his interiorPolygon coordinate to avoid flicker when add and remove MGLPolygon.

@1ec5
Copy link
Contributor

@1ec5 1ec5 commented on 086297d Jun 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexisMedinaM, interiorPolygon doesn’t currently track mutations correctly; see #6576.

Please sign in to comment.