diff options
author | Justin R. Miller <incanus@users.noreply.github.com> | 2016-10-04 18:42:12 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-04 18:42:12 -0700 |
commit | 105673efc1c59e19f5352fb770405aa591cdebeb (patch) | |
tree | 7b57c89ad346a4e62c60c404338d0b34853ad02b /platform/darwin/src/MGLMultiPoint.mm | |
parent | 07315711d6b191a5812065bb76ab5beb33d995d9 (diff) | |
download | qtlocation-mapboxgl-105673efc1c59e19f5352fb770405aa591cdebeb.tar.gz |
[ios, macos] fixes #6160: allow updating multipoint coordinates (#6565)
Diffstat (limited to 'platform/darwin/src/MGLMultiPoint.mm')
-rw-r--r-- | platform/darwin/src/MGLMultiPoint.mm | 109 |
1 files changed, 71 insertions, 38 deletions
diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm index a5b9eb8efc..17a61ed081 100644 --- a/platform/darwin/src/MGLMultiPoint.mm +++ b/platform/darwin/src/MGLMultiPoint.mm @@ -1,12 +1,12 @@ #import "MGLMultiPoint_Private.h" #import "MGLGeometry_Private.h" +#import "MGLTypes.h" #import <mbgl/util/geo.hpp> -mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) { - if (!cgColor) { - return { 0, 0, 0, 0 }; - } +mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) +{ + if (!cgColor) return { 0, 0, 0, 0 }; NSCAssert(CGColorGetNumberOfComponents(cgColor) >= 4, @"Color must have at least 4 components"); const CGFloat *components = CGColorGetComponents(cgColor); return { (float)components[0], (float)components[1], (float)components[2], (float)components[3] }; @@ -18,28 +18,34 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) { MGLCoordinateBounds _bounds; } -- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords - count:(NSUInteger)count +- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count { self = [super init]; if (self) { - _count = count; - _coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D)); + [self setupWithCoordinates:coords count:count]; + } - mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty(); + return self; +} - for (NSUInteger i = 0; i < _count; i++) - { - _coordinates[i] = coords[i]; - bounds.extend(mbgl::LatLng(coords[i].latitude, coords[i].longitude)); - } +- (void)setupWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count +{ + if (_coordinates) free(_coordinates); + + _count = count; + _coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D)); - _bounds = MGLCoordinateBoundsFromLatLngBounds(bounds); + mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty(); + + 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 @@ -49,13 +55,6 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) { - (CLLocationCoordinate2D)coordinate { - if ([self isMemberOfClass:[MGLMultiPoint class]]) - { - [[NSException exceptionWithName:@"MGLAbstractClassException" - reason:@"MGLMultiPoint is an abstract class" - userInfo:nil] raise]; - } - assert(_count > 0); return CLLocationCoordinate2DMake(_coordinates[0].latitude, _coordinates[0].longitude); @@ -63,27 +62,23 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) { - (NSUInteger)pointCount { - if ([self isMemberOfClass:[MGLMultiPoint class]]) - { - [[NSException exceptionWithName:@"MGLAbstractClassException" - reason:@"MGLMultiPoint is an abstract class" - userInfo:nil] raise]; - } - return _count; } ++ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingPointCount +{ + return [NSSet setWithObjects:@"coordinates", nil]; +} + - (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range { - if ([self isMemberOfClass:[MGLMultiPoint class]]) + if (range.location + range.length > _count) { - [[NSException exceptionWithName:@"MGLAbstractClassException" - reason:@"MGLMultiPoint is an abstract class" - userInfo:nil] raise]; + [NSException raise:NSRangeException + format:@"Invalid coordinate range %@ extends beyond current coordinate count of %zu", + NSStringFromRange(range), _count]; } - assert(range.location + range.length <= _count); - NSUInteger index = 0; for (NSUInteger i = range.location; i < range.location + range.length; i++) @@ -93,6 +88,43 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) { } } +- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(CLLocationCoordinate2D *)coords +{ + if ((coords >= _coordinates && coords < _coordinates + _count) || + (coords + range.length >= _coordinates && coords + range.length < _coordinates + _count)) + { + [NSException raise:NSRangeException format:@"Reuse of existing coordinates array %p not supported", coords]; + } + else if (range.length == 0) + { + [NSException raise:NSRangeException format:@"Empty coordinate range %@", NSStringFromRange(range)]; + } + else if (range.location > _count) + { + [NSException raise:NSRangeException + format:@"Invalid range %@ for existing coordinate count %zu", + NSStringFromRange(range), _count]; + } + + [self willChangeValueForKey:@"coordinates"]; + if (NSMaxRange(range) <= _count) + { + // replacing existing coordinate(s) + memcpy(_coordinates + range.location, coords, range.length * sizeof(CLLocationCoordinate2D)); + } + else + { + // appending new coordinate(s) + NSUInteger newCount = NSMaxRange(range); + CLLocationCoordinate2D *newCoordinates = (CLLocationCoordinate2D *)malloc(newCount * sizeof(CLLocationCoordinate2D)); + memcpy(newCoordinates, _coordinates, fmin(_count, range.location) * sizeof(CLLocationCoordinate2D)); + memcpy(newCoordinates + range.location, coords, range.length * sizeof(CLLocationCoordinate2D)); + [self setupWithCoordinates:newCoordinates count:newCount]; + free(newCoordinates); + } + [self didChangeValueForKey:@"coordinates"]; +} + - (MGLCoordinateBounds)overlayBounds { return _bounds; @@ -103,7 +135,8 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) { return MGLLatLngBoundsFromCoordinateBounds(_bounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds)); } -- (mbgl::Annotation)annotationObjectWithDelegate:(__unused id <MGLMultiPointDelegate>)delegate { +- (mbgl::Annotation)annotationObjectWithDelegate:(__unused id <MGLMultiPointDelegate>)delegate +{ NSAssert(NO, @"Cannot add an annotation from an instance of %@", NSStringFromClass([self class])); return mbgl::SymbolAnnotation({mbgl::Point<double>()}); } @@ -111,7 +144,7 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) { - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>", - NSStringFromClass([self class]), (void *)self, (unsigned long)_count, MGLStringFromCoordinateBounds(_bounds)]; + NSStringFromClass([self class]), (void *)self, (unsigned long)_count, MGLStringFromCoordinateBounds(_bounds)]; } @end |