summaryrefslogtreecommitdiff
path: root/platform/ios
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios')
-rw-r--r--platform/ios/MGLMapView.mm139
-rw-r--r--platform/ios/MGLMultiPoint.mm102
-rw-r--r--platform/ios/MGLMultiPoint_Private.h8
-rw-r--r--platform/ios/MGLPointAnnotation.m7
-rw-r--r--platform/ios/MGLPolygon.m15
-rw-r--r--platform/ios/MGLPolyline.m15
-rw-r--r--platform/ios/MGLShape.m14
7 files changed, 280 insertions, 20 deletions
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 4ef63d4bf8..63e3b516ab 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -1015,7 +1015,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
tapBounds.extend(MGLLatLngFromLocationCoordinate2D(coordinate));
// query for nearby annotations
- std::vector<uint32_t> nearbyAnnotations = _mbglMap->getAnnotationsInBounds(tapBounds);
+ std::vector<uint32_t> nearbyAnnotations = _mbglMap->getAnnotationsInBounds(tapBounds, mbgl::AnnotationType::Point);
int32_t newSelectedAnnotationID = -1;
@@ -1669,36 +1669,131 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng)
{
if ( ! annotations) return;
- std::vector<mbgl::LatLng> latLngs;
- latLngs.reserve(annotations.count);
-
+ std::vector<mbgl::LatLng> points;
std::vector<std::string> symbols;
- symbols.reserve(annotations.count);
+
+ std::vector<mbgl::AnnotationSegments> shapes;
+ std::vector<mbgl::StyleProperties> shapesProperties;
BOOL delegateImplementsSymbolLookup = [self.delegate respondsToSelector:@selector(mapView:symbolNameForAnnotation:)];
+ BOOL delegateImplementsAlphaForShape = [self.delegate respondsToSelector:@selector(mapView:alphaForShapeAnnotation:)];
+ BOOL delegateImplementsStrokeColorForShape = [self.delegate respondsToSelector:@selector(mapView:strokeColorForShapeAnnotation:)];
+ BOOL delegateImplementsFillColorForPolygon = [self.delegate respondsToSelector:@selector(mapView:fillColorForPolygonAnnotation:)];
+ BOOL delegateImplementsLineWidthForPolyline = [self.delegate respondsToSelector:@selector(mapView:lineWidthForPolylineAnnotation:)];
for (id <MGLAnnotation> annotation in annotations)
{
assert([annotation conformsToProtocol:@protocol(MGLAnnotation)]);
- latLngs.push_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate));
+ if ([annotation isKindOfClass:[MGLMultiPoint class]])
+ {
+ CGFloat alpha = (delegateImplementsAlphaForShape ?
+ [self.delegate mapView:self alphaForShapeAnnotation:annotation] :
+ 1.0);
- NSString *symbolName = nil;
+ UIColor *strokeColor = (delegateImplementsStrokeColorForShape ?
+ [self.delegate mapView:self strokeColorForShapeAnnotation:annotation] :
+ [UIColor blackColor]);
- if (delegateImplementsSymbolLookup)
- {
- symbolName = [self.delegate mapView:self symbolNameForAnnotation:annotation];
+ assert(strokeColor);
+
+ CGFloat r,g,b,a;
+ [strokeColor getRed:&r green:&g blue:&b alpha:&a];
+ mbgl::Color strokeNativeColor({{ (float)r, (float)g, (float)b, (float)a }});
+
+ mbgl::StyleProperties shapeProperties;
+
+ if ([annotation isKindOfClass:[MGLPolyline class]])
+ {
+ CGFloat lineWidth = (delegateImplementsLineWidthForPolyline ?
+ [self.delegate mapView:self lineWidthForPolylineAnnotation:(MGLPolyline *)annotation] :
+ 3.0);
+
+ mbgl::LineProperties lineProperties;
+ lineProperties.opacity = alpha;
+ lineProperties.color = strokeNativeColor;
+ lineProperties.width = lineWidth;
+ shapeProperties.set<mbgl::LineProperties>(lineProperties);
+
+ }
+ else if ([annotation isKindOfClass:[MGLPolygon class]])
+ {
+ UIColor *fillColor = (delegateImplementsFillColorForPolygon ?
+ [self.delegate mapView:self fillColorForPolygonAnnotation:(MGLPolygon *)annotation] :
+ [UIColor blueColor]);
+
+ assert(fillColor);
+
+ [fillColor getRed:&r green:&g blue:&b alpha:&a];
+ mbgl::Color fillNativeColor({{ (float)r, (float)g, (float)b, (float)a }});
+
+ mbgl::FillProperties fillProperties;
+ fillProperties.opacity = alpha;
+ fillProperties.stroke_color = strokeNativeColor;
+ fillProperties.fill_color = fillNativeColor;
+ shapeProperties.set<mbgl::FillProperties>(fillProperties);
+ }
+ else
+ {
+ [[NSException exceptionWithName:@"MGLUnknownShapeClassException"
+ reason:[NSString stringWithFormat:@"%@ is an unknown shape class", [annotation class]]
+ userInfo:nil] raise];
+ }
+
+ shapesProperties.push_back(shapeProperties);
+
+ NSUInteger count = [(MGLMultiPoint *)annotation pointCount];
+
+ CLLocationCoordinate2D *coordinates = (CLLocationCoordinate2D *)malloc(count * sizeof(CLLocationCoordinate2D));
+ [(MGLMultiPoint *)annotation getCoordinates:coordinates range:NSMakeRange(0, count)];
+
+ mbgl::AnnotationSegment shape;
+ shape.reserve(count);
+
+ for (NSUInteger i = 0; i < count; i++)
+ {
+ shape.push_back(mbgl::LatLng(coordinates[i].latitude, coordinates[i].longitude));
+ }
+
+ free(coordinates);
+
+ shapes.push_back({{ shape }});
}
+ else
+ {
+ points.push_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate));
+
+ NSString *symbolName = nil;
- symbols.push_back((symbolName ? [symbolName UTF8String] : ""));
+ if (delegateImplementsSymbolLookup)
+ {
+ symbolName = [self.delegate mapView:self symbolNameForAnnotation:annotation];
+ }
+
+ symbols.push_back((symbolName ? [symbolName UTF8String] : ""));
+ }
}
- std::vector<uint32_t> annotationIDs = _mbglMap->addPointAnnotations(latLngs, symbols);
+ if (points.size())
+ {
+ std::vector<uint32_t> pointAnnotationIDs = _mbglMap->addPointAnnotations(points, symbols);
- for (size_t i = 0; i < annotationIDs.size(); ++i)
+ for (size_t i = 0; i < pointAnnotationIDs.size(); ++i)
+ {
+ [self.annotationIDsByAnnotation setObject:@{ MGLAnnotationIDKey : @(pointAnnotationIDs[i]) }
+ forKey:annotations[i]];
+ }
+ }
+
+ if (shapes.size())
{
- [self.annotationIDsByAnnotation setObject:@{ MGLAnnotationIDKey : @(annotationIDs[i]) }
- forKey:annotations[i]];
+ std::vector<uint32_t> shapeAnnotationIDs = _mbglMap->addShapeAnnotations(shapes, shapesProperties);
+
+ for (size_t i = 0; i < shapeAnnotationIDs.size(); ++i)
+ {
+ [self.annotationIDsByAnnotation setObject:@{ MGLAnnotationIDKey : @(shapeAnnotationIDs[i]) }
+ forKey:annotations[i]];
+ }
}
}
@@ -1750,6 +1845,8 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng)
assert([firstAnnotation conformsToProtocol:@protocol(MGLAnnotation)]);
+ if ([firstAnnotation isKindOfClass:[MGLMultiPoint class]]) return;
+
if ( ! [self viewportBounds].contains(MGLLatLngFromLocationCoordinate2D(firstAnnotation.coordinate))) return;
[self selectAnnotation:firstAnnotation animated:NO];
@@ -1759,6 +1856,8 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng)
{
if ( ! annotation) return;
+ if ([annotation isKindOfClass:[MGLMultiPoint class]]) return;
+
if ( ! [self viewportBounds].contains(MGLLatLngFromLocationCoordinate2D(annotation.coordinate))) return;
if (annotation == self.selectedAnnotation) return;
@@ -1865,12 +1964,12 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng)
// clean up
self.selectedAnnotationCalloutView = nil;
self.selectedAnnotation = nil;
- }
- // notify delegate
- if ([self.delegate respondsToSelector:@selector(mapView:didDeselectAnnotation:)])
- {
- [self.delegate mapView:self didDeselectAnnotation:annotation];
+ // notify delegate
+ if ([self.delegate respondsToSelector:@selector(mapView:didDeselectAnnotation:)])
+ {
+ [self.delegate mapView:self didDeselectAnnotation:annotation];
+ }
}
}
diff --git a/platform/ios/MGLMultiPoint.mm b/platform/ios/MGLMultiPoint.mm
new file mode 100644
index 0000000000..ef8a18e493
--- /dev/null
+++ b/platform/ios/MGLMultiPoint.mm
@@ -0,0 +1,102 @@
+#import "MGLMultiPoint.h"
+#import "MGLTypes.h"
+
+#import <mbgl/util/geo.hpp>
+
+@implementation MGLMultiPoint
+{
+ CLLocationCoordinate2D *_coords;
+ size_t _count;
+ mbgl::LatLngBounds _bounds;
+}
+
+- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords
+ count:(NSUInteger)count
+{
+ self = [super init];
+
+ if (self)
+ {
+ _count = count;
+ _coords = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D));
+
+ for (NSUInteger i = 0; i < _count; i++)
+ {
+ _coords[i] = coords[i];
+ _bounds.extend(mbgl::LatLng(coords[i].latitude, coords[i].longitude));
+ }
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ free(_coords);
+}
+
+- (CLLocationCoordinate2D)coordinate
+{
+ if ([self isMemberOfClass:[MGLMultiPoint class]])
+ {
+ [[NSException exceptionWithName:@"MGLAbstractClassException"
+ reason:@"MGLMultiPoint is an abstract class"
+ userInfo:nil] raise];
+ }
+
+ assert(_count > 0);
+
+ return CLLocationCoordinate2DMake(_coords[0].latitude, _coords[0].longitude);
+}
+
+- (NSUInteger)pointCount
+{
+ if ([self isMemberOfClass:[MGLMultiPoint class]])
+ {
+ [[NSException exceptionWithName:@"MGLAbstractClassException"
+ reason:@"MGLMultiPoint is an abstract class"
+ userInfo:nil] raise];
+ }
+
+ return _count;
+}
+
+- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range
+{
+ if ([self isMemberOfClass:[MGLMultiPoint class]])
+ {
+ [[NSException exceptionWithName:@"MGLAbstractClassException"
+ reason:@"MGLMultiPoint is an abstract class"
+ userInfo:nil] raise];
+ }
+
+ assert(range.location + range.length <= _count);
+
+ NSUInteger index = 0;
+
+ for (NSUInteger i = range.location; i < range.location + range.length; i++)
+ {
+ coords[index] = _coords[i];
+ index++;
+ }
+}
+
+- (MGLCoordinateBounds)overlayBounds
+{
+ return {
+ CLLocationCoordinate2DMake(_bounds.sw.latitude, _bounds.sw.longitude),
+ CLLocationCoordinate2DMake(_bounds.ne.longitude, _bounds.ne.longitude)
+ };
+}
+
+- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds
+{
+ mbgl::LatLngBounds area(
+ mbgl::LatLng(overlayBounds.sw.latitude, overlayBounds.sw.longitude),
+ mbgl::LatLng(overlayBounds.ne.latitude, overlayBounds.ne.longitude)
+ );
+
+ return _bounds.intersects(area);
+}
+
+@end
diff --git a/platform/ios/MGLMultiPoint_Private.h b/platform/ios/MGLMultiPoint_Private.h
new file mode 100644
index 0000000000..a1a70a6778
--- /dev/null
+++ b/platform/ios/MGLMultiPoint_Private.h
@@ -0,0 +1,8 @@
+#import "MGLMultiPoint.h"
+
+@interface MGLMultiPoint (Private)
+
+- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds;
+
+@end
diff --git a/platform/ios/MGLPointAnnotation.m b/platform/ios/MGLPointAnnotation.m
new file mode 100644
index 0000000000..13fbba1083
--- /dev/null
+++ b/platform/ios/MGLPointAnnotation.m
@@ -0,0 +1,7 @@
+#import "MGLPointAnnotation.h"
+
+@implementation MGLPointAnnotation
+
+@synthesize coordinate;
+
+@end
diff --git a/platform/ios/MGLPolygon.m b/platform/ios/MGLPolygon.m
new file mode 100644
index 0000000000..d3b5f2c2a4
--- /dev/null
+++ b/platform/ios/MGLPolygon.m
@@ -0,0 +1,15 @@
+#import "MGLPolygon.h"
+
+#import "MGLMultiPoint_Private.h"
+
+@implementation MGLPolygon
+
+@synthesize overlayBounds;
+
++ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords
+ count:(NSUInteger)count
+{
+ return [[self alloc] initWithCoordinates:coords count:count];
+}
+
+@end
diff --git a/platform/ios/MGLPolyline.m b/platform/ios/MGLPolyline.m
new file mode 100644
index 0000000000..86d113bd16
--- /dev/null
+++ b/platform/ios/MGLPolyline.m
@@ -0,0 +1,15 @@
+#import "MGLPolyline.h"
+
+#import "MGLMultiPoint_Private.h"
+
+@implementation MGLPolyline
+
+@synthesize overlayBounds;
+
++ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords
+ count:(NSUInteger)count
+{
+ return [[self alloc] initWithCoordinates:coords count:count];
+}
+
+@end
diff --git a/platform/ios/MGLShape.m b/platform/ios/MGLShape.m
new file mode 100644
index 0000000000..e3d92c38c8
--- /dev/null
+++ b/platform/ios/MGLShape.m
@@ -0,0 +1,14 @@
+#import "MGLShape.h"
+
+@implementation MGLShape
+
+- (CLLocationCoordinate2D)coordinate
+{
+ [[NSException exceptionWithName:@"MGLAbstractClassException"
+ reason:@"MGLShape is an abstract class"
+ userInfo:nil] raise];
+
+ return CLLocationCoordinate2DMake(MAXFLOAT, MAXFLOAT);
+}
+
+@end