summaryrefslogtreecommitdiff
path: root/platform/darwin/src
diff options
context:
space:
mode:
authorJesse Bounds <jesse@rebounds.net>2016-10-20 17:14:19 -0700
committerGitHub <noreply@github.com>2016-10-20 17:14:19 -0700
commit1216050f9c5c472f1c8edcc32447004a40680ec7 (patch)
tree77f937aaeaa6e34f8b2fa84e5f7c721e8f3d541f /platform/darwin/src
parentbaf82fc4d4882480e6dd16ea9821be29d390bf00 (diff)
downloadqtlocation-mapboxgl-1216050f9c5c472f1c8edcc32447004a40680ec7.tar.gz
Add MGLPointCollection for GeoJSON multipoints (#6742)
* [ios, macos] Introduce MGLPointCollection This makes MGLMultiPoint abstract again so that it is only a place for shared functionality of polygons and polylines. The multipoint feature replaces the point collection feature and can be used to initialize a MGLGeoJSONSource. The previously added swift_names for polyline and polygon are removed, for now. This also updates the iOS and macOS annotation adding logic so that unwanted shapes really are avoided. Previously the combined OR conditions meant that an annotation had to logically be NOT a kind of all three types so the check always let the annotation slip through. This also expands the guard to deflect the new MGLPointCollection.
Diffstat (limited to 'platform/darwin/src')
-rw-r--r--platform/darwin/src/MGLFeature.h5
-rw-r--r--platform/darwin/src/MGLFeature.mm8
-rw-r--r--platform/darwin/src/MGLMultiPoint.h21
-rw-r--r--platform/darwin/src/MGLMultiPoint.mm28
-rw-r--r--platform/darwin/src/MGLPointCollection.h51
-rw-r--r--platform/darwin/src/MGLPointCollection.mm112
-rw-r--r--platform/darwin/src/MGLPointCollection_Private.h11
-rw-r--r--platform/darwin/src/MGLPolygon.h2
-rw-r--r--platform/darwin/src/MGLPolyline.h2
9 files changed, 189 insertions, 51 deletions
diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h
index 05f0baf6c1..384c5a073e 100644
--- a/platform/darwin/src/MGLFeature.h
+++ b/platform/darwin/src/MGLFeature.h
@@ -3,6 +3,7 @@
#import "MGLPolyline.h"
#import "MGLPolygon.h"
#import "MGLPointAnnotation.h"
+#import "MGLPointCollection.h"
#import "MGLShapeCollection.h"
NS_ASSUME_NONNULL_BEGIN
@@ -134,10 +135,10 @@ NS_ASSUME_NONNULL_BEGIN
@end
/**
- The `MGLMultiPointFeature` class represents a multipoint in a
+ The `MGLPointCollectionFeature` class represents a multipoint in a
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
*/
-@interface MGLMultiPointFeature : MGLMultiPoint <MGLFeature>
+@interface MGLPointCollectionFeature : MGLPointCollection <MGLFeature>
@end
/**
diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm
index 84dcc4f0bb..5483433710 100644
--- a/platform/darwin/src/MGLFeature.mm
+++ b/platform/darwin/src/MGLFeature.mm
@@ -6,7 +6,7 @@
#import "MGLValueEvaluator.h"
#import "MGLShape_Private.h"
-#import "MGLMultiPoint_Private.h"
+#import "MGLPointCollection_Private.h"
#import "MGLPolyline+MGLAdditions.h"
#import "MGLPolygon+MGLAdditions.h"
#import "NSDictionary+MGLAdditions.h"
@@ -82,10 +82,10 @@
@end
-@interface MGLMultiPointFeature () <MGLFeaturePrivate>
+@interface MGLPointCollectionFeature () <MGLFeaturePrivate>
@end
-@implementation MGLMultiPointFeature
+@implementation MGLPointCollectionFeature
@synthesize identifier;
@synthesize attributes;
@@ -202,7 +202,7 @@ public:
MGLShape <MGLFeaturePrivate> * operator()(const mbgl::MultiPoint<T> &geometry) const {
std::vector<CLLocationCoordinate2D> coordinates = toLocationCoordinates2D(geometry);
- return [[MGLMultiPointFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()];
+ return [[MGLPointCollectionFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()];
}
MGLShape <MGLFeaturePrivate> * operator()(const mbgl::MultiLineString<T> &geometry) const {
diff --git a/platform/darwin/src/MGLMultiPoint.h b/platform/darwin/src/MGLMultiPoint.h
index b936205ab2..69c7295842 100644
--- a/platform/darwin/src/MGLMultiPoint.h
+++ b/platform/darwin/src/MGLMultiPoint.h
@@ -6,25 +6,16 @@
NS_ASSUME_NONNULL_BEGIN
/**
- The `MGLMultiPoint` class is used to define shapes composed of multiple points.
- This class is also the superclass of `MGLPolyline` and `MGLPolygon`. The
- methods and properties of this class can be used to access information about
- the specific points associated with a line or polygon.
+ The `MGLMultiPoint` class is an abstract superclass used to define shapes
+ composed of multiple points. You should not create instances of this class
+ directly. Instead, you should create instances of the `MGLPolyline` or
+ `MGLPolygon` classes. However, you can use the method and properties of this
+ class to access information about the specific points associated with the line
+ or polygon.
*/
@interface MGLMultiPoint : MGLShape
/**
- Creates and returns an `MGLMultiPoint` object from the specified set of
- coordinates.
-
- @param coords The array of coordinates defining the shape. The data in this
- array is copied to the new object.
- @param count The number of items in the `coords` array.
- @return A new multipoint object.
- */
-+ (instancetype)multiPointWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(multiPoint(coordinates:count:));
-
-/**
The array of coordinates associated with the shape.
This C array is a pointer to a structure inside the multipoint object,
diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm
index 0090c5e35f..17a61ed081 100644
--- a/platform/darwin/src/MGLMultiPoint.mm
+++ b/platform/darwin/src/MGLMultiPoint.mm
@@ -18,11 +18,6 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
MGLCoordinateBounds _bounds;
}
-+ (instancetype)multiPointWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
-{
- return [[self alloc] initWithCoordinates:coords count:count];
-}
-
- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
self = [super init];
@@ -146,29 +141,6 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
return mbgl::SymbolAnnotation({mbgl::Point<double>()});
}
-- (mbgl::Feature)featureObject
-{
- mbgl::MultiPoint<double> multiPoint;
- multiPoint.reserve(self.pointCount);
- for (NSInteger i = 0; i< self.pointCount; i++)
- {
- multiPoint.push_back(mbgl::Point<double>(self.coordinates[i].longitude, self.coordinates[i].latitude));
- }
- return mbgl::Feature {multiPoint};
-}
-
-- (NSDictionary *)geoJSONDictionary
-{
- NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount];
- for (NSUInteger index = 0; index < self.pointCount; index++) {
- CLLocationCoordinate2D coordinate = self.coordinates[index];
- [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
- }
-
- return @{@"type": @"MultiPoint",
- @"coordinates": coordinates};
-}
-
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>",
diff --git a/platform/darwin/src/MGLPointCollection.h b/platform/darwin/src/MGLPointCollection.h
new file mode 100644
index 0000000000..db497d0a52
--- /dev/null
+++ b/platform/darwin/src/MGLPointCollection.h
@@ -0,0 +1,51 @@
+#import <Foundation/Foundation.h>
+#import <CoreLocation/CoreLocation.h>
+
+#import "MGLOverlay.h"
+#import "MGLShape.h"
+
+/**
+ The `MGLPointCollection` class is used to define an array of disconnected
+ coordinates. The points in the collection may be related but are not
+ connected visually in any way.
+
+ @note `MGLPointCollection` objects cannot be added to a map view using
+ `-[MGLMapView addAnnotations:]` and related methods. However, when used in a
+ `MGLPointCollectionFeature` to initialize a `MGLGeoJSONSource` that is added
+ to the map view's style, the point collection represents as a group of distinct
+ annotations.
+ */
+@interface MGLPointCollection : MGLShape <MGLOverlay>
+
+/**
+ Creates and returns a `MGLPointCollection` object from the specified set of
+ coordinates.
+
+ @param coords The array of coordinates defining the shape. The data in this
+ array is copied to the new object.
+ @param count The number of items in the `coords` array.
+ @return A new point collection object.
+ */
++ (instancetype)pointCollectionWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+
+/** The array of coordinates associated with the shape. */
+@property (nonatomic, readonly) CLLocationCoordinate2D *coordinates NS_RETURNS_INNER_POINTER;
+
+/** The number of coordinates associated with the shape. */
+@property (nonatomic, readonly) NSUInteger pointCount;
+
+/**
+ Retrieves one or more coordinates associated with the shape.
+
+ @param coords On input, you must provide a C array of structures large enough
+ to hold the desired number of coordinates. On output, this structure
+ contains the requested coordinate data.
+ @param range The range of points you want. The `location` field indicates the
+ first point you are requesting, with `0` being the first point, `1` being
+ the second point, and so on. The `length` field indicates the number of
+ points you want. The array in _`coords`_ must be large enough to accommodate
+ the number of requested coordinates.
+ */
+- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range;
+
+@end
diff --git a/platform/darwin/src/MGLPointCollection.mm b/platform/darwin/src/MGLPointCollection.mm
new file mode 100644
index 0000000000..5871915b5d
--- /dev/null
+++ b/platform/darwin/src/MGLPointCollection.mm
@@ -0,0 +1,112 @@
+#import "MGLPointCollection_Private.h"
+#import "MGLGeometry_Private.h"
+
+#import <mbgl/util/geometry.hpp>
+#import <mbgl/util/feature.hpp>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation MGLPointCollection
+{
+ size_t _count;
+ MGLCoordinateBounds _bounds;
+}
+
++ (instancetype)pointCollectionWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
+{
+ return [[self alloc] initWithCoordinates:coords count:count];
+}
+
+- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
+{
+ self = [super init];
+ if (self)
+ {
+ _count = count;
+ _coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D));
+
+ 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));
+ }
+
+ _bounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
+ }
+ return self;
+}
+
+- (NSUInteger)pointCount
+{
+ return _count;
+}
+
+- (CLLocationCoordinate2D)coordinate
+{
+ assert(_count > 0);
+
+ return CLLocationCoordinate2DMake(_coordinates[0].latitude, _coordinates[0].longitude);
+}
+
+- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range
+{
+ if (range.location + range.length > _count)
+ {
+ [NSException raise:NSRangeException
+ format:@"Invalid coordinate range %@ extends beyond current coordinate count of %zu",
+ NSStringFromRange(range), _count];
+ }
+
+ NSUInteger index = 0;
+
+ for (NSUInteger i = range.location; i < range.location + range.length; i++)
+ {
+ coords[index] = _coordinates[i];
+ index++;
+ }
+}
+
+- (MGLCoordinateBounds)overlayBounds
+{
+ return _bounds;
+}
+
+- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds
+{
+ return MGLLatLngBoundsFromCoordinateBounds(_bounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds));
+}
+
+- (mbgl::Feature)featureObject
+{
+ mbgl::MultiPoint<double> multiPoint;
+ multiPoint.reserve(self.pointCount);
+ for (NSInteger i = 0; i< self.pointCount; i++)
+ {
+ multiPoint.push_back(mbgl::Point<double>(self.coordinates[i].longitude, self.coordinates[i].latitude));
+ }
+ return mbgl::Feature {multiPoint};
+}
+
+- (NSDictionary *)geoJSONDictionary
+{
+ NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount];
+ for (NSUInteger index = 0; index < self.pointCount; index++) {
+ CLLocationCoordinate2D coordinate = self.coordinates[index];
+ [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
+ }
+
+ return @{@"type": @"MultiPoint",
+ @"coordinates": coordinates};
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; count = %lu>",
+ NSStringFromClass([self class]), (void *)self, (unsigned long)_count];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLPointCollection_Private.h b/platform/darwin/src/MGLPointCollection_Private.h
new file mode 100644
index 0000000000..039c1f18be
--- /dev/null
+++ b/platform/darwin/src/MGLPointCollection_Private.h
@@ -0,0 +1,11 @@
+#import "MGLPointCollection.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MGLPointCollection (Private)
+
+- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLPolygon.h b/platform/darwin/src/MGLPolygon.h
index 6d53356ba4..3d5b36abb6 100644
--- a/platform/darwin/src/MGLPolygon.h
+++ b/platform/darwin/src/MGLPolygon.h
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polygon object.
*/
-+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(polygon(coordinates:count:));
++ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
/**
Creates and returns an `MGLPolygon` object from the specified set of
diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h
index 6642afef7e..d0274b44e3 100644
--- a/platform/darwin/src/MGLPolyline.h
+++ b/platform/darwin/src/MGLPolyline.h
@@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polyline object.
*/
-+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(polyline(coordinates:count:));
++ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
@end