summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/darwin/src/MGLFeature.h164
-rw-r--r--platform/darwin/src/MGLFeature.mm244
-rw-r--r--platform/darwin/src/MGLFeature_Private.h7
-rw-r--r--platform/darwin/src/MGLPolygon.h24
-rw-r--r--platform/darwin/src/MGLPolygon.mm37
-rw-r--r--platform/darwin/src/MGLPolyline.h24
-rw-r--r--platform/darwin/src/MGLPolyline.mm37
-rw-r--r--platform/darwin/src/MGLShapeCollection.h32
-rw-r--r--platform/darwin/src/MGLShapeCollection.m21
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--platform/ios/app/MBXViewController.m19
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj198
-rw-r--r--platform/ios/jazzy.yml13
-rw-r--r--platform/ios/src/MGLMapView.h127
-rw-r--r--platform/ios/src/MGLMapView.mm68
-rw-r--r--platform/ios/src/Mapbox.h4
-rw-r--r--platform/osx/CHANGELOG.md1
-rw-r--r--platform/osx/app/MapDocument.m17
-rw-r--r--platform/osx/jazzy.yml13
-rw-r--r--platform/osx/osx.xcodeproj/project.pbxproj135
-rw-r--r--platform/osx/src/MGLMapView.h127
-rw-r--r--platform/osx/src/MGLMapView.mm60
-rw-r--r--platform/osx/src/Mapbox.h2
23 files changed, 1265 insertions, 110 deletions
diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h
new file mode 100644
index 0000000000..389b8ab67f
--- /dev/null
+++ b/platform/darwin/src/MGLFeature.h
@@ -0,0 +1,164 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLPolyline.h"
+#import "MGLPolygon.h"
+#import "MGLPointAnnotation.h"
+#import "MGLShapeCollection.h"
+
+#import "MGLTypes.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ The `MGLFeature` protocol is used to provide details about geographic features
+ contained in a map view’s
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile sources</a>.
+ Each concrete subclass of `MGLShape` in turn has a subclass that conforms to
+ this protocol.
+
+ Typically, you do not create feature objects yourself but rather obtain them
+ using `-[MGLMapView visibleFeaturesAtPoint:]` and related methods. Each feature
+ object associates a shape with an identifier and attributes as specified by the
+ source. Like any `MGLAnnotation` object, an `MGLFeature` object can be added to
+ a map view using `-[MGLMapView addAnnotations:]` and related methods.
+ */
+@protocol MGLFeature <MGLAnnotation>
+
+/**
+ An object that uniquely identifies the feature in its containing
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+
+ The value of this property is currently always an `NSNumber` object but may in
+ the future be an instance of another class, such as `NSString`.
+
+ The identifier corresponds to the
+ <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#42-features">feature identifier</a>
+ (`id`) in the tile source. If the source does not specify the feature’s
+ identifier, the value of this property is `nil`.
+
+ For details about the identifiers used in most Mapbox-provided styles, consult
+ the
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets</a>
+ layer reference.
+ */
+@property (nonatomic, copy, nullable, readonly) id identifier;
+
+/**
+ A dictionary of attributes for this feature specified by the
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+
+ The keys and values of this dictionary are determined by the tile source. In
+ the tile source, each attribute name is a string, while each attribute value
+ may be a null value, Boolean value, integer, floating-point number, or string.
+ These data types are mapped to instances of the following Foundation classes:
+
+ <table>
+ <thead>
+ <tr><th>In the tile source</th><th>In this dictionary</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>Null</td> <td><code>NSNull</code></td></tr>
+ <tr><td>Boolean</td> <td><code>NSNumber</code> (use the <code>boolValue</code> property)</td></tr>
+ <tr><td>Integer</td> <td><code>NSNumber</code> (use the <code>unsignedLongLongValue</code> or <code>longLongValue</code> property)</td></tr>
+ <tr><td>Floating-point number</td> <td><code>NSNumber</code> (use the <code>doubleValue</code> property)</td></tr>
+ <tr><td>String</td> <td><code>NSString</code></td></tr>
+ </tbody>
+ </table>
+
+ For details about the attribute names and values found in Mapbox-provided
+ vector tile sources, consult the
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets</a>
+ and
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-terrain/">Mapbox Terrain</a>
+ layer references.
+ */
+@property (nonatomic, copy, readonly) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+/**
+ Returns the feature attribute for the given attribute name.
+
+ See the `attributes` property’s documentation for details on keys and values
+ associated with this method.
+ */
+- (nullable id)attributeForKey:(NSString *)key;
+
+@end
+
+/**
+ The `MGLPointFeature` class represents a point in a
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+ */
+@interface MGLPointFeature : MGLPointAnnotation <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+@end
+
+/**
+ The `MGLPolylineFeature` class represents a polyline in a
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+ */
+@interface MGLPolylineFeature : MGLPolyline <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+@end
+
+/**
+ The `MGLPolygonFeature` class represents a polygon in a
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+ */
+@interface MGLPolygonFeature : MGLPolygon <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+@end
+
+/**
+ The `MGLMultiPointFeature` class represents a multipoint in a
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+ */
+@interface MGLMultiPointFeature : MGLMultiPoint <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+@end
+
+/**
+ The `MGLMultiPolylineFeature` class represents a multipolyline in a
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+ */
+@interface MGLMultiPolylineFeature : MGLMultiPolyline <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+@end
+
+/**
+ The `MGLMultiPolygonFeature` class represents a multipolygon in a
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+ */
+@interface MGLMultiPolygonFeature : MGLMultiPolygon <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+@end
+
+/**
+ The `MGLShapeCollectionFeature` class represents a shape collection in a
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
+ */
+@interface MGLShapeCollectionFeature : MGLShapeCollection <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm
new file mode 100644
index 0000000000..68c57a193a
--- /dev/null
+++ b/platform/darwin/src/MGLFeature.mm
@@ -0,0 +1,244 @@
+#import "MGLFeature_Private.h"
+
+#import "MGLPointAnnotation.h"
+#import "MGLPolyline.h"
+#import "MGLPolygon.h"
+
+#import "MGLMultiPoint_Private.h"
+
+class PropertyValueEvaluator {
+public:
+ PropertyValueEvaluator() {}
+
+ id operator()(const std::nullptr_t &) const {
+ return [NSNull null];
+ }
+
+ id operator()(const bool &value) const {
+ return value ? @YES : @NO;
+ }
+
+ id operator()(const uint64_t &value) const {
+ return @(value);
+ }
+
+ id operator()(const int64_t &value) const {
+ return @(value);
+ }
+
+ id operator()(const double &value) const {
+ return @(value);
+ }
+
+ id operator()(const std::string &value) const {
+ return @(value.c_str());
+ }
+
+ id operator()(const std::vector<mbgl::Value> &values) const {
+ std::vector<id> objects;
+ objects.reserve(values.size());
+ std::transform(values.begin(), values.end(), std::back_inserter(objects), ^id (const mbgl::Value &value) {
+ PropertyValueEvaluator evaluator;
+ return mbgl::Value::visit(value, evaluator);
+ });
+ return [NSArray arrayWithObjects:&objects[0] count:objects.size()];
+ }
+
+ id operator()(const std::unordered_map<std::string, mbgl::Value> &items) const {
+ std::vector<NSString *> keys;
+ keys.reserve(items.size());
+ std::vector<id> objects;
+ objects.reserve(items.size());
+ for (auto &item : items) {
+ keys.push_back(@(item.first.c_str()));
+ PropertyValueEvaluator evaluator;
+ objects.push_back(mbgl::Value::visit(item.second, evaluator));
+ }
+ return [NSDictionary dictionaryWithObjects:&objects[0] forKeys:&keys[0] count:keys.size()];
+ }
+};
+
+template <typename T>
+class GeometryEvaluator {
+public:
+ GeometryEvaluator()
+ : attributes([NSMutableDictionary dictionary]) {}
+
+ GeometryEvaluator(const mbgl::Feature &feature)
+ : tag(feature.id ? @(*feature.id) : nullptr),
+ attributes([NSMutableDictionary dictionaryWithCapacity:feature.properties.size()]) {
+ for (auto &pair : feature.properties) {
+ auto &value = pair.second;
+ PropertyValueEvaluator evaluator;
+ attributes[@(pair.first.c_str())] = mbgl::Value::visit(value, evaluator);
+ }
+ }
+
+ MGLShape <MGLFeature> * operator()(const mapbox::geometry::point<T> &geometry) const {
+ MGLPointFeature *feature = [[MGLPointFeature alloc] init];
+ feature.coordinate = coordinateFromPoint(geometry);
+ feature.identifier = tag;
+ feature.attributes = attributes;
+ return feature;
+ }
+
+ MGLShape <MGLFeature> * operator()(const mapbox::geometry::line_string<T> &geometry) const {
+ std::vector<CLLocationCoordinate2D> coordinates;
+ coordinates.reserve(geometry.size());
+ std::transform(geometry.begin(), geometry.end(), std::back_inserter(coordinates), coordinateFromPoint);
+
+ MGLPolylineFeature *feature = [[MGLPolylineFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()];
+ feature.identifier = tag;
+ feature.attributes = attributes;
+ return feature;
+ }
+
+ MGLShape <MGLFeature> * operator()(const mapbox::geometry::polygon<T> &geometry) const {
+ // TODO: MGLPolygon doesn’t support holes, so what to do?
+ auto &linearRing = geometry.front();
+
+ std::vector<CLLocationCoordinate2D> coordinates;
+ coordinates.reserve(linearRing.size());
+ std::transform(linearRing.begin(), linearRing.end(), std::back_inserter(coordinates), coordinateFromPoint);
+
+ MGLPolygonFeature *feature = [[MGLPolygonFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()];
+ feature.identifier = tag;
+ feature.attributes = attributes;
+ return feature;
+ }
+
+ MGLShape <MGLFeature> * operator()(const mapbox::geometry::multi_point<T> &geometry) const {
+ std::vector<CLLocationCoordinate2D> coordinates;
+ coordinates.reserve(geometry.size());
+ std::transform(geometry.begin(), geometry.end(), std::back_inserter(coordinates), coordinateFromPoint);
+
+ MGLMultiPointFeature *feature = [[MGLMultiPointFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()];
+ feature.identifier = tag;
+ feature.attributes = attributes;
+ return feature;
+ }
+
+ MGLShape <MGLFeature> * operator()(const mapbox::geometry::multi_line_string<T> &geometry) const {
+ NSMutableArray *polylines = [NSMutableArray arrayWithCapacity:geometry.size()];
+ for (auto &lineString : geometry) {
+ std::vector<CLLocationCoordinate2D> coordinates;
+ coordinates.reserve(lineString.size());
+ std::transform(lineString.begin(), lineString.end(), std::back_inserter(coordinates), coordinateFromPoint);
+
+ MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:&coordinates[0] count:coordinates.size()];
+ [polylines addObject:polyline];
+ }
+
+ MGLMultiPolylineFeature *feature = [MGLMultiPolylineFeature multiPolylineWithPolylines:polylines];
+ feature.identifier = tag;
+ feature.attributes = attributes;
+ return feature;
+ }
+
+ MGLShape <MGLFeature> * operator()(const mapbox::geometry::multi_polygon<T> &geometry) const {
+ NSMutableArray *polygons = [NSMutableArray arrayWithCapacity:geometry.size()];
+ for (auto &polygon : geometry) {
+ // TODO: MGLPolygon doesn’t support holes, so what to do?
+ auto &linearRing = polygon.front();
+
+ std::vector<CLLocationCoordinate2D> coordinates;
+ coordinates.reserve(linearRing.size());
+ std::transform(linearRing.begin(), linearRing.end(), std::back_inserter(coordinates), coordinateFromPoint);
+
+ MGLPolygon *polygonObject = [MGLPolygon polygonWithCoordinates:&coordinates[0] count:coordinates.size()];
+ [polygons addObject:polygonObject];
+ }
+
+ MGLMultiPolygonFeature *feature = [MGLMultiPolygonFeature multiPolygonWithPolygons:polygons];
+ feature.identifier = tag;
+ feature.attributes = attributes;
+ return feature;
+ }
+
+ MGLShape <MGLFeature> * operator()(const mapbox::geometry::geometry_collection<T> &collection) const {
+ NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:collection.size()];
+ for (auto &geometry : collection) {
+ GeometryEvaluator<T> evaluator;
+ id <MGLFeature> feature = mapbox::geometry::geometry<T>::visit(geometry, evaluator);
+ [shapes addObject:feature];
+ }
+ MGLShapeCollectionFeature *feature = [MGLShapeCollectionFeature shapeCollectionWithShapes:shapes];
+ feature.identifier = tag;
+ feature.attributes = attributes;
+ return feature;
+ }
+
+private:
+ NSNumber *tag = nullptr;
+ NS_MUTABLE_DICTIONARY_OF(NSString *, id) *attributes;
+
+ static CLLocationCoordinate2D coordinateFromPoint(const mapbox::geometry::point<T> &point) {
+ return CLLocationCoordinate2DMake(point.y, point.x);
+ }
+};
+
+NS_ARRAY_OF(MGLShape <MGLFeature> *) *MGLFeaturesFromMBGLFeatures(const std::vector<mbgl::Feature> &features) {
+ std::vector<MGLShape <MGLFeature> *> shapes;
+ shapes.reserve(features.size());
+ std::transform(features.begin(), features.end(), std::back_inserter(shapes), ^MGLShape <MGLFeature> * (const mbgl::Feature &feature) {
+ GeometryEvaluator<double> evaluator(feature);
+ return mapbox::geometry::geometry<double>::visit(feature.geometry, evaluator);
+ });
+ return [NSArray arrayWithObjects:&shapes[0] count:shapes.size()];
+}
+
+@implementation MGLPointFeature
+
+- (id)attributeForKey:(NSString *)key {
+ return self.attributes[key];
+}
+
+@end
+
+@implementation MGLPolylineFeature
+
+- (id)attributeForKey:(NSString *)key {
+ return self.attributes[key];
+}
+
+@end
+
+@implementation MGLPolygonFeature
+
+- (id)attributeForKey:(NSString *)key {
+ return self.attributes[key];
+}
+
+@end
+
+@implementation MGLMultiPointFeature
+
+- (id)attributeForKey:(NSString *)key {
+ return self.attributes[key];
+}
+
+@end
+
+@implementation MGLMultiPolylineFeature
+
+- (id)attributeForKey:(NSString *)key {
+ return self.attributes[key];
+}
+
+@end
+
+@implementation MGLMultiPolygonFeature
+
+- (id)attributeForKey:(NSString *)key {
+ return self.attributes[key];
+}
+
+@end
+
+@implementation MGLShapeCollectionFeature
+
+- (id)attributeForKey:(NSString *)key {
+ return self.attributes[key];
+}
+
+@end
diff --git a/platform/darwin/src/MGLFeature_Private.h b/platform/darwin/src/MGLFeature_Private.h
new file mode 100644
index 0000000000..837461871e
--- /dev/null
+++ b/platform/darwin/src/MGLFeature_Private.h
@@ -0,0 +1,7 @@
+#import "MGLFeature.h"
+#import "MGLShape.h"
+
+#import <mbgl/util/geo.hpp>
+#import <mbgl/util/feature.hpp>
+
+NS_ARRAY_OF(MGLShape <MGLFeature> *) *MGLFeaturesFromMBGLFeatures(const std::vector<mbgl::Feature> &features);
diff --git a/platform/darwin/src/MGLPolygon.h b/platform/darwin/src/MGLPolygon.h
index 1a158874bb..a12e62b106 100644
--- a/platform/darwin/src/MGLPolygon.h
+++ b/platform/darwin/src/MGLPolygon.h
@@ -30,4 +30,28 @@ NS_ASSUME_NONNULL_BEGIN
@end
+/**
+ The `MGLMultiPolygon` class represents a shape consisting of one or more
+ polygons that do not overlap. For example, you would use an `MGLMultiPolygon`
+ object to represent an atoll together with an island in the atoll’s lagoon:
+ the atoll itself would be one `MGLPolygon` object, while the inner island would
+ be another.
+ */
+@interface MGLMultiPolygon : MGLShape <MGLOverlay>
+
+/**
+ An array of polygons forming the multipolygon.
+ */
+@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLPolygon *) *polygons;
+
+/**
+ Creates and returns a multipolygon object consisting of the given polygons.
+
+ @param polygons The array of polygons defining the shape.
+ @return A new multipolygon object.
+ */
++ (instancetype)multiPolygonWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons;
+
+@end
+
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm
index 5019385cb2..6febf6d81b 100644
--- a/platform/darwin/src/MGLPolygon.mm
+++ b/platform/darwin/src/MGLPolygon.mm
@@ -1,6 +1,7 @@
#import "MGLPolygon.h"
#import "MGLMultiPoint_Private.h"
+#import "MGLGeometry_Private.h"
@implementation MGLPolygon
@@ -26,3 +27,39 @@
}
@end
+
+@interface MGLMultiPolygon ()
+
+@property (nonatomic, copy, readwrite) NS_ARRAY_OF(MGLPolygon *) *polygons;
+
+@end
+
+@implementation MGLMultiPolygon {
+ MGLCoordinateBounds _overlayBounds;
+}
+
+@synthesize overlayBounds = _overlayBounds;
+
++ (instancetype)multiPolygonWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons {
+ return [[self alloc] initWithPolygons:polygons];
+}
+
+- (instancetype)initWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons {
+ if (self = [super init]) {
+ _polygons = polygons;
+
+ mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
+
+ for (MGLPolygon *polygon in _polygons) {
+ bounds.extend(MGLLatLngBoundsFromCoordinateBounds(polygon.overlayBounds));
+ }
+ _overlayBounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
+ }
+ return self;
+}
+
+- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds {
+ return MGLLatLngBoundsFromCoordinateBounds(_overlayBounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds));
+}
+
+@end
diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h
index 5e45513735..a453a43a41 100644
--- a/platform/darwin/src/MGLPolyline.h
+++ b/platform/darwin/src/MGLPolyline.h
@@ -30,4 +30,28 @@ NS_ASSUME_NONNULL_BEGIN
@end
+/**
+ The `MGLMultiPolyline` class represents a shape consisting of one or more
+ polylines. For example, you could use an `MGLMultiPolyline` object to represent
+ both sides of a divided highway (dual carriageway), excluding the median
+ (central reservation): each carriageway would be a distinct `MGLPolyline`
+ object.
+ */
+@interface MGLMultiPolyline : MGLShape <MGLOverlay>
+
+/**
+ An array of polygons forming the multipolyline.
+ */
+@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLPolyline *) *polylines;
+
+/**
+ Creates and returns a multipolyline object consisting of the given polylines.
+
+ @param polylines The array of polylines defining the shape.
+ @return A new multipolyline object.
+ */
++ (instancetype)multiPolylineWithPolylines:(NS_ARRAY_OF(MGLPolyline *) *)polylines;
+
+@end
+
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm
index f560a571bc..810b359bb0 100644
--- a/platform/darwin/src/MGLPolyline.mm
+++ b/platform/darwin/src/MGLPolyline.mm
@@ -1,6 +1,7 @@
#import "MGLPolyline.h"
#import "MGLMultiPoint_Private.h"
+#import "MGLGeometry_Private.h"
@implementation MGLPolyline
@@ -26,3 +27,39 @@
}
@end
+
+@interface MGLMultiPolyline ()
+
+@property (nonatomic, copy, readwrite) NS_ARRAY_OF(MGLPolyline *) *polylines;
+
+@end
+
+@implementation MGLMultiPolyline {
+ MGLCoordinateBounds _overlayBounds;
+}
+
+@synthesize overlayBounds = _overlayBounds;
+
++ (instancetype)multiPolylineWithPolylines:(NS_ARRAY_OF(MGLPolyline *) *)polylines {
+ return [[self alloc] initWithPolylines:polylines];
+}
+
+- (instancetype)initWithPolylines:(NS_ARRAY_OF(MGLPolyline *) *)polylines {
+ if (self = [super init]) {
+ _polylines = polylines;
+
+ mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
+
+ for (MGLPolyline *polyline in _polylines) {
+ bounds.extend(MGLLatLngBoundsFromCoordinateBounds(polyline.overlayBounds));
+ }
+ _overlayBounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
+ }
+ return self;
+}
+
+- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds {
+ return MGLLatLngBoundsFromCoordinateBounds(_overlayBounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds));
+}
+
+@end
diff --git a/platform/darwin/src/MGLShapeCollection.h b/platform/darwin/src/MGLShapeCollection.h
new file mode 100644
index 0000000000..f4dc226228
--- /dev/null
+++ b/platform/darwin/src/MGLShapeCollection.h
@@ -0,0 +1,32 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLShape.h"
+
+#import "MGLTypes.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ The `MGLShapeCollection` class represents a shape consisting of one or more
+ distinct but related shapes that are instances of `MGLShape`. The constituent
+ shapes can be a mixture of different kinds of shapes.
+ */
+@interface MGLShapeCollection : MGLShape
+
+/**
+ An array of shapes forming the shape collection.
+ */
+@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLShape <MGLAnnotation> *) *shapes;
+
+/**
+ Creates and returns a shape collection consisting of the given shapes.
+
+ @param shapes The array of shapes defining the shape collection. The data in
+ this array is copied to the new object.
+ @return A new shape collection object.
+ */
++ (instancetype)shapeCollectionWithShapes:(NS_ARRAY_OF(MGLShape <MGLAnnotation> *) *)shapes;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLShapeCollection.m b/platform/darwin/src/MGLShapeCollection.m
new file mode 100644
index 0000000000..3fc4cdda75
--- /dev/null
+++ b/platform/darwin/src/MGLShapeCollection.m
@@ -0,0 +1,21 @@
+#import "MGLShapeCollection.h"
+
+@implementation MGLShapeCollection
+
++ (instancetype)shapeCollectionWithShapes:(NS_ARRAY_OF(MGLShape <MGLAnnotation> *) *)shapes {
+ return [[self alloc] initWithShapes:shapes];
+}
+
+- (instancetype)initWithShapes:(NS_ARRAY_OF(MGLShape <MGLAnnotation> *) *)shapes {
+ if (self = [super init]) {
+ NSAssert(shapes.count, @"Cannot create an empty shape collection");
+ _shapes = shapes.copy;
+ }
+ return self;
+}
+
+- (CLLocationCoordinate2D)coordinate {
+ return _shapes.firstObject.coordinate;
+}
+
+@end
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 012688ab17..0754aa2a0d 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -10,6 +10,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CON
- The user dot now moves smoothly between user location updates while user location tracking is disabled. ([#1582](https://github.com/mapbox/mapbox-gl-native/pull/1582))
- An MGLAnnotation can be relocated by changing its `coordinate` property in a KVO-compliant way. An MGLMultiPoint cannot be relocated. ([#3835](https://github.com/mapbox/mapbox-gl-native/pull/3835))
- Setting the `image` property of an MGLAnnotationImage to `nil` resets it to the default red pin image and reclaims resources that can be used to customize additional annotations. ([#3835](https://github.com/mapbox/mapbox-gl-native/pull/3835))
+- Added methods to MGLMapView for obtaining the underlying map data rendered by the current style. ([#5110](https://github.com/mapbox/mapbox-gl-native/pull/5110))
- `MGLOfflinePackProgress` now indicates how many tiles have been downloaded and how much space they take up. ([#4874](https://github.com/mapbox/mapbox-gl-native/pull/4874))
- The compass, user dot, and visible annotations are now accessible to VoiceOver users. ([#1496](https://github.com/mapbox/mapbox-gl-native/pull/1496))
- The SDK is now localizable. No localizations are currently provided, other than English, but if you need a particular localization, you can install the SDK manually and drop a .lproj folder into the framework. ([#4783](https://github.com/mapbox/mapbox-gl-native/pull/4783))
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 13b4fbffec..2f5aacfe6c 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -395,13 +395,22 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
{
if (longPress.state == UIGestureRecognizerStateBegan)
{
- MBXDroppedPinAnnotation *point = [[MBXDroppedPinAnnotation alloc] init];
- point.coordinate = [self.mapView convertPoint:[longPress locationInView:longPress.view]
+ CGPoint point = [longPress locationInView:longPress.view];
+ NSArray *features = [self.mapView visibleFeaturesAtPoint:point];
+ NSString *title;
+ for (id <MGLFeature> feature in features) {
+ if (!title) {
+ title = [feature attributeForKey:@"name_en"] ?: [feature attributeForKey:@"name"];
+ }
+ }
+
+ MBXDroppedPinAnnotation *pin = [[MBXDroppedPinAnnotation alloc] init];
+ pin.coordinate = [self.mapView convertPoint:point
toCoordinateFromView:self.mapView];
- point.title = @"Dropped Pin";
- point.subtitle = [[[MGLCoordinateFormatter alloc] init] stringFromCoordinate:point.coordinate];
+ pin.title = title ?: @"Dropped Pin";
+ pin.subtitle = [[[MGLCoordinateFormatter alloc] init] stringFromCoordinate:pin.coordinate];
// Calling `addAnnotation:` on mapView is not required since `selectAnnotation:animated` has the side effect of adding the annotation if required
- [self.mapView selectAnnotation:point animated:YES];
+ [self.mapView selectAnnotation:pin animated:YES];
}
}
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index cf48b869e3..3f233441f7 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -228,6 +228,15 @@
DABFB8731CBE9A9900D62B32 /* Mapbox.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88485E1CBAFC2E00AB86E3 /* Mapbox.h */; settings = {ATTRIBUTES = (Public, ); }; };
DAC49C5C1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DAC49C5F1CD02BC9009E1AA3 /* Localizable.stringsdict */; };
DAC49C5D1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DAC49C5F1CD02BC9009E1AA3 /* Localizable.stringsdict */; };
+ DAD1656C1CF41981001FF4B9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD165691CF41981001FF4B9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAD1656D1CF41981001FF4B9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD165691CF41981001FF4B9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAD1656E1CF41981001FF4B9 /* MGLFeature_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD1656A1CF41981001FF4B9 /* MGLFeature_Private.h */; };
+ DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAD1656B1CF41981001FF4B9 /* MGLFeature.mm */; };
+ DAD165711CF41981001FF4B9 /* MGLFeature.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAD1656B1CF41981001FF4B9 /* MGLFeature.mm */; };
+ DAD165781CF4CDFF001FF4B9 /* MGLShapeCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD165761CF4CDFF001FF4B9 /* MGLShapeCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAD165791CF4CDFF001FF4B9 /* MGLShapeCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD165761CF4CDFF001FF4B9 /* MGLShapeCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAD1657A1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD165771CF4CDFF001FF4B9 /* MGLShapeCollection.m */; };
+ DAD1657B1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD165771CF4CDFF001FF4B9 /* MGLShapeCollection.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -474,6 +483,11 @@
DABCABC01CB80717000A7C39 /* locations.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = locations.hpp; sourceTree = "<group>"; };
DAC07C961CBB2CD6000CB309 /* mbgl.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = mbgl.xcconfig; path = ../../build/ios/mbgl.xcconfig; sourceTree = "<group>"; };
DAC49C621CD07D74009E1AA3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
+ DAD165691CF41981001FF4B9 /* MGLFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature.h; sourceTree = "<group>"; };
+ DAD1656A1CF41981001FF4B9 /* MGLFeature_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature_Private.h; sourceTree = "<group>"; };
+ DAD1656B1CF41981001FF4B9 /* MGLFeature.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFeature.mm; sourceTree = "<group>"; };
+ DAD165761CF4CDFF001FF4B9 /* MGLShapeCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShapeCollection.h; sourceTree = "<group>"; };
+ DAD165771CF4CDFF001FF4B9 /* MGLShapeCollection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLShapeCollection.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -654,56 +668,19 @@
DA8847DE1CBAFA3E00AB86E3 /* Foundation */ = {
isa = PBXGroup;
children = (
+ DAD165831CF4CFED001FF4B9 /* Categories */,
+ DAD165801CF4CF9A001FF4B9 /* Formatters */,
+ DAD165811CF4CFC4001FF4B9 /* Geometry */,
+ DAD165821CF4CFE3001FF4B9 /* Offline Maps */,
DA8847DF1CBAFA5100AB86E3 /* MGLAccountManager.h */,
DA8847FF1CBAFA6200AB86E3 /* MGLAccountManager_Private.h */,
DA8848001CBAFA6200AB86E3 /* MGLAccountManager.m */,
- DA8847E01CBAFA5100AB86E3 /* MGLAnnotation.h */,
- DA35A2BA1CCA9A6900E826B2 /* MGLClockDirectionFormatter.h */,
- DA35A2B71CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m */,
- DA35A2AF1CCA141D00E826B2 /* MGLCompassDirectionFormatter.h */,
- DA35A2B01CCA141D00E826B2 /* MGLCompassDirectionFormatter.m */,
- DA35A29D1CC9E94C00E826B2 /* MGLCoordinateFormatter.h */,
- DA35A2A01CC9E95F00E826B2 /* MGLCoordinateFormatter.m */,
- DA8847E11CBAFA5100AB86E3 /* MGLGeometry.h */,
- DA8848011CBAFA6200AB86E3 /* MGLGeometry_Private.h */,
- DA8848021CBAFA6200AB86E3 /* MGLGeometry.mm */,
DA8847E21CBAFA5100AB86E3 /* MGLMapCamera.h */,
DA8848031CBAFA6200AB86E3 /* MGLMapCamera.mm */,
- DA8847E31CBAFA5100AB86E3 /* MGLMultiPoint.h */,
- DA8848041CBAFA6200AB86E3 /* MGLMultiPoint_Private.h */,
- DA8848051CBAFA6200AB86E3 /* MGLMultiPoint.mm */,
- DA8847E41CBAFA5100AB86E3 /* MGLOfflinePack.h */,
- DA8848061CBAFA6200AB86E3 /* MGLOfflinePack_Private.h */,
- DA8848071CBAFA6200AB86E3 /* MGLOfflinePack.mm */,
- DA8847E51CBAFA5100AB86E3 /* MGLOfflineRegion.h */,
- DA8848081CBAFA6200AB86E3 /* MGLOfflineRegion_Private.h */,
- DA8847E61CBAFA5100AB86E3 /* MGLOfflineStorage.h */,
- DA8848091CBAFA6200AB86E3 /* MGLOfflineStorage_Private.h */,
- DA88480A1CBAFA6200AB86E3 /* MGLOfflineStorage.mm */,
- DA8847E71CBAFA5100AB86E3 /* MGLOverlay.h */,
- DA8847E81CBAFA5100AB86E3 /* MGLPointAnnotation.h */,
- DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.m */,
- DA8847E91CBAFA5100AB86E3 /* MGLPolygon.h */,
- DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */,
- DA8847EA1CBAFA5100AB86E3 /* MGLPolyline.h */,
- DA88480D1CBAFA6200AB86E3 /* MGLPolyline.mm */,
- DA8847EB1CBAFA5100AB86E3 /* MGLShape.h */,
- DA88480E1CBAFA6200AB86E3 /* MGLShape.m */,
DA8847EC1CBAFA5100AB86E3 /* MGLStyle.h */,
DA88480F1CBAFA6200AB86E3 /* MGLStyle.mm */,
- DA8847ED1CBAFA5100AB86E3 /* MGLTilePyramidOfflineRegion.h */,
- DA8848101CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm */,
DA8847EE1CBAFA5100AB86E3 /* MGLTypes.h */,
DA8848111CBAFA6200AB86E3 /* MGLTypes.m */,
- DA8848121CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h */,
- DA8848131CBAFA6200AB86E3 /* NSBundle+MGLAdditions.m */,
- DA8848141CBAFA6200AB86E3 /* NSException+MGLAdditions.h */,
- DA8848151CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.h */,
- DA8848161CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.m */,
- DA8848171CBAFA6200AB86E3 /* NSString+MGLAdditions.h */,
- DA8848181CBAFA6200AB86E3 /* NSString+MGLAdditions.m */,
- DA35A2C71CCAAAD200E826B2 /* NSValue+MGLAdditions.h */,
- DA35A2C81CCAAAD200E826B2 /* NSValue+MGLAdditions.m */,
DA8848911CBB049300AB86E3 /* reachability */,
);
name = Foundation;
@@ -713,31 +690,13 @@
DA8848331CBAFB2A00AB86E3 /* Kit */ = {
isa = PBXGroup;
children = (
- 4018B1C31CDC277F00F666AF /* MGLAnnotationView_Private.h */,
- 4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */,
- 4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */,
- DA8848341CBAFB8500AB86E3 /* MGLAnnotationImage.h */,
- DA8848401CBAFB9800AB86E3 /* MGLAnnotationImage_Private.h */,
- DA8848411CBAFB9800AB86E3 /* MGLAnnotationImage.m */,
- DA8848421CBAFB9800AB86E3 /* MGLAPIClient.h */,
- DA8848431CBAFB9800AB86E3 /* MGLAPIClient.m */,
- DA8848351CBAFB8500AB86E3 /* MGLCalloutView.h */,
- DA8848441CBAFB9800AB86E3 /* MGLCompactCalloutView.h */,
- DA8848451CBAFB9800AB86E3 /* MGLCompactCalloutView.m */,
- DA8848461CBAFB9800AB86E3 /* MGLLocationManager.h */,
- DA8848471CBAFB9800AB86E3 /* MGLLocationManager.m */,
- DA8848481CBAFB9800AB86E3 /* MGLMapboxEvents.h */,
- DA8848491CBAFB9800AB86E3 /* MGLMapboxEvents.m */,
+ DAD165841CF4D06B001FF4B9 /* Annotations */,
+ DAD165851CF4D08B001FF4B9 /* Telemetry */,
DA8848361CBAFB8500AB86E3 /* MGLMapView.h */,
DA17BE2F1CC4BAC300402C41 /* MGLMapView_Internal.h */,
DA8848371CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h */,
DA8848381CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h */,
DA88484A1CBAFB9800AB86E3 /* MGLMapView.mm */,
- DA8848391CBAFB8500AB86E3 /* MGLUserLocation.h */,
- DA88484B1CBAFB9800AB86E3 /* MGLUserLocation_Private.h */,
- DA88484C1CBAFB9800AB86E3 /* MGLUserLocation.m */,
- DA88484D1CBAFB9800AB86E3 /* MGLUserLocationAnnotationView.h */,
- DA88484E1CBAFB9800AB86E3 /* MGLUserLocationAnnotationView.m */,
DA88487F1CBB033F00AB86E3 /* Fabric */,
DA8848881CBB036000AB86E3 /* SMCalloutView */,
);
@@ -858,6 +817,114 @@
name = Configuration;
sourceTree = "<group>";
};
+ DAD165801CF4CF9A001FF4B9 /* Formatters */ = {
+ isa = PBXGroup;
+ children = (
+ DA35A2BA1CCA9A6900E826B2 /* MGLClockDirectionFormatter.h */,
+ DA35A2B71CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m */,
+ DA35A2AF1CCA141D00E826B2 /* MGLCompassDirectionFormatter.h */,
+ DA35A2B01CCA141D00E826B2 /* MGLCompassDirectionFormatter.m */,
+ DA35A29D1CC9E94C00E826B2 /* MGLCoordinateFormatter.h */,
+ DA35A2A01CC9E95F00E826B2 /* MGLCoordinateFormatter.m */,
+ );
+ name = Formatters;
+ sourceTree = "<group>";
+ };
+ DAD165811CF4CFC4001FF4B9 /* Geometry */ = {
+ isa = PBXGroup;
+ children = (
+ DA8847E01CBAFA5100AB86E3 /* MGLAnnotation.h */,
+ DAD165691CF41981001FF4B9 /* MGLFeature.h */,
+ DAD1656A1CF41981001FF4B9 /* MGLFeature_Private.h */,
+ DAD1656B1CF41981001FF4B9 /* MGLFeature.mm */,
+ DA8847E11CBAFA5100AB86E3 /* MGLGeometry.h */,
+ DA8848011CBAFA6200AB86E3 /* MGLGeometry_Private.h */,
+ DA8848021CBAFA6200AB86E3 /* MGLGeometry.mm */,
+ DA8847E31CBAFA5100AB86E3 /* MGLMultiPoint.h */,
+ DA8848041CBAFA6200AB86E3 /* MGLMultiPoint_Private.h */,
+ DA8848051CBAFA6200AB86E3 /* MGLMultiPoint.mm */,
+ DA8847E71CBAFA5100AB86E3 /* MGLOverlay.h */,
+ DA8847E81CBAFA5100AB86E3 /* MGLPointAnnotation.h */,
+ DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.m */,
+ DA8847E91CBAFA5100AB86E3 /* MGLPolygon.h */,
+ DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */,
+ DA8847EA1CBAFA5100AB86E3 /* MGLPolyline.h */,
+ DA88480D1CBAFA6200AB86E3 /* MGLPolyline.mm */,
+ DA8847EB1CBAFA5100AB86E3 /* MGLShape.h */,
+ DA88480E1CBAFA6200AB86E3 /* MGLShape.m */,
+ DAD165761CF4CDFF001FF4B9 /* MGLShapeCollection.h */,
+ DAD165771CF4CDFF001FF4B9 /* MGLShapeCollection.m */,
+ );
+ name = Geometry;
+ sourceTree = "<group>";
+ };
+ DAD165821CF4CFE3001FF4B9 /* Offline Maps */ = {
+ isa = PBXGroup;
+ children = (
+ DA8847E41CBAFA5100AB86E3 /* MGLOfflinePack.h */,
+ DA8848061CBAFA6200AB86E3 /* MGLOfflinePack_Private.h */,
+ DA8848071CBAFA6200AB86E3 /* MGLOfflinePack.mm */,
+ DA8847E51CBAFA5100AB86E3 /* MGLOfflineRegion.h */,
+ DA8848081CBAFA6200AB86E3 /* MGLOfflineRegion_Private.h */,
+ DA8847E61CBAFA5100AB86E3 /* MGLOfflineStorage.h */,
+ DA8848091CBAFA6200AB86E3 /* MGLOfflineStorage_Private.h */,
+ DA88480A1CBAFA6200AB86E3 /* MGLOfflineStorage.mm */,
+ DA8847ED1CBAFA5100AB86E3 /* MGLTilePyramidOfflineRegion.h */,
+ DA8848101CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm */,
+ );
+ name = "Offline Maps";
+ sourceTree = "<group>";
+ };
+ DAD165831CF4CFED001FF4B9 /* Categories */ = {
+ isa = PBXGroup;
+ children = (
+ DA8848121CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h */,
+ DA8848131CBAFA6200AB86E3 /* NSBundle+MGLAdditions.m */,
+ DA8848141CBAFA6200AB86E3 /* NSException+MGLAdditions.h */,
+ DA8848151CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.h */,
+ DA8848161CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.m */,
+ DA8848171CBAFA6200AB86E3 /* NSString+MGLAdditions.h */,
+ DA8848181CBAFA6200AB86E3 /* NSString+MGLAdditions.m */,
+ DA35A2C71CCAAAD200E826B2 /* NSValue+MGLAdditions.h */,
+ DA35A2C81CCAAAD200E826B2 /* NSValue+MGLAdditions.m */,
+ );
+ name = Categories;
+ sourceTree = "<group>";
+ };
+ DAD165841CF4D06B001FF4B9 /* Annotations */ = {
+ isa = PBXGroup;
+ children = (
+ 4018B1C31CDC277F00F666AF /* MGLAnnotationView_Private.h */,
+ 4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */,
+ 4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */,
+ DA8848341CBAFB8500AB86E3 /* MGLAnnotationImage.h */,
+ DA8848401CBAFB9800AB86E3 /* MGLAnnotationImage_Private.h */,
+ DA8848411CBAFB9800AB86E3 /* MGLAnnotationImage.m */,
+ DA8848351CBAFB8500AB86E3 /* MGLCalloutView.h */,
+ DA8848441CBAFB9800AB86E3 /* MGLCompactCalloutView.h */,
+ DA8848451CBAFB9800AB86E3 /* MGLCompactCalloutView.m */,
+ DA8848391CBAFB8500AB86E3 /* MGLUserLocation.h */,
+ DA88484B1CBAFB9800AB86E3 /* MGLUserLocation_Private.h */,
+ DA88484C1CBAFB9800AB86E3 /* MGLUserLocation.m */,
+ DA88484D1CBAFB9800AB86E3 /* MGLUserLocationAnnotationView.h */,
+ DA88484E1CBAFB9800AB86E3 /* MGLUserLocationAnnotationView.m */,
+ );
+ name = Annotations;
+ sourceTree = "<group>";
+ };
+ DAD165851CF4D08B001FF4B9 /* Telemetry */ = {
+ isa = PBXGroup;
+ children = (
+ DA8848421CBAFB9800AB86E3 /* MGLAPIClient.h */,
+ DA8848431CBAFB9800AB86E3 /* MGLAPIClient.m */,
+ DA8848461CBAFB9800AB86E3 /* MGLLocationManager.h */,
+ DA8848471CBAFB9800AB86E3 /* MGLLocationManager.m */,
+ DA8848481CBAFB9800AB86E3 /* MGLMapboxEvents.h */,
+ DA8848491CBAFB9800AB86E3 /* MGLMapboxEvents.m */,
+ );
+ name = Telemetry;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -894,6 +961,7 @@
DA88483F1CBAFB8500AB86E3 /* MGLUserLocation.h in Headers */,
DA88483D1CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h in Headers */,
DA17BE301CC4BAC300402C41 /* MGLMapView_Internal.h in Headers */,
+ DAD165781CF4CDFF001FF4B9 /* MGLShapeCollection.h in Headers */,
DA88481E1CBAFA6200AB86E3 /* MGLMultiPoint_Private.h in Headers */,
DA35A29E1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DA8847F71CBAFA5100AB86E3 /* MGLOverlay.h in Headers */,
@@ -905,6 +973,7 @@
DA8847F91CBAFA5100AB86E3 /* MGLPolygon.h in Headers */,
DA8847F81CBAFA5100AB86E3 /* MGLPointAnnotation.h in Headers */,
DA8847F31CBAFA5100AB86E3 /* MGLMultiPoint.h in Headers */,
+ DAD1656C1CF41981001FF4B9 /* MGLFeature.h in Headers */,
DA88484F1CBAFB9800AB86E3 /* MGLAnnotationImage_Private.h in Headers */,
DA8847F21CBAFA5100AB86E3 /* MGLMapCamera.h in Headers */,
DA8847F51CBAFA5100AB86E3 /* MGLOfflineRegion.h in Headers */,
@@ -917,6 +986,7 @@
DA88482F1CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.h in Headers */,
DA8848601CBAFC2E00AB86E3 /* Mapbox.h in Headers */,
DA8847F61CBAFA5100AB86E3 /* MGLOfflineStorage.h in Headers */,
+ DAD1656E1CF41981001FF4B9 /* MGLFeature_Private.h in Headers */,
DA88483C1CBAFB8500AB86E3 /* MGLMapView.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -928,6 +998,7 @@
DA35A2CA1CCAAAD200E826B2 /* NSValue+MGLAdditions.h in Headers */,
DABFB85E1CBE99E500D62B32 /* MGLAnnotation.h in Headers */,
DABFB8641CBE99E500D62B32 /* MGLOfflineStorage.h in Headers */,
+ DAD165791CF4CDFF001FF4B9 /* MGLShapeCollection.h in Headers */,
DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DABFB8711CBE9A0F00D62B32 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */,
DABFB8611CBE99E500D62B32 /* MGLMultiPoint.h in Headers */,
@@ -935,6 +1006,7 @@
DABFB8721CBE9A0F00D62B32 /* MGLUserLocation.h in Headers */,
DABFB8661CBE99E500D62B32 /* MGLPointAnnotation.h in Headers */,
DABFB8621CBE99E500D62B32 /* MGLOfflinePack.h in Headers */,
+ DAD1656D1CF41981001FF4B9 /* MGLFeature.h in Headers */,
DA17BE311CC4BDAA00402C41 /* MGLMapView_Internal.h in Headers */,
DABFB86C1CBE99E500D62B32 /* MGLTypes.h in Headers */,
DABFB8691CBE99E500D62B32 /* MGLShape.h in Headers */,
@@ -1270,12 +1342,14 @@
buildActionMask = 2147483647;
files = (
DA88485D1CBAFB9800AB86E3 /* MGLUserLocationAnnotationView.m in Sources */,
+ DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */,
DA8848541CBAFB9800AB86E3 /* MGLCompactCalloutView.m in Sources */,
DA8848251CBAFA6200AB86E3 /* MGLPointAnnotation.m in Sources */,
DA88482D1CBAFA6200AB86E3 /* NSBundle+MGLAdditions.m in Sources */,
DA88485B1CBAFB9800AB86E3 /* MGLUserLocation.m in Sources */,
DA88488C1CBB037E00AB86E3 /* SMCalloutView.m in Sources */,
DA35A2B81CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
+ DAD1657A1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */,
DA8848901CBB048E00AB86E3 /* reachability.m in Sources */,
DA8848211CBAFA6200AB86E3 /* MGLOfflinePack.mm in Sources */,
DA8848591CBAFB9800AB86E3 /* MGLMapView.mm in Sources */,
@@ -1308,12 +1382,14 @@
buildActionMask = 2147483647;
files = (
DAA4E4221CBB730400178DFB /* MGLPointAnnotation.m in Sources */,
+ DAD165711CF41981001FF4B9 /* MGLFeature.mm in Sources */,
DAA4E4291CBB730400178DFB /* NSBundle+MGLAdditions.m in Sources */,
DAA4E42E1CBB730400178DFB /* MGLAPIClient.m in Sources */,
DAA4E4201CBB730400178DFB /* MGLOfflinePack.mm in Sources */,
DAA4E4331CBB730400178DFB /* MGLUserLocation.m in Sources */,
DAA4E4351CBB730400178DFB /* SMCalloutView.m in Sources */,
DA35A2B91CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
+ DAD1657B1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */,
DAA4E4251CBB730400178DFB /* MGLShape.m in Sources */,
DAA4E42B1CBB730400178DFB /* NSString+MGLAdditions.m in Sources */,
DAA4E4261CBB730400178DFB /* MGLStyle.mm in Sources */,
diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml
index f6a5cfba4b..61570994d5 100644
--- a/platform/ios/jazzy.yml
+++ b/platform/ios/jazzy.yml
@@ -33,12 +33,25 @@ custom_categories:
- MGLCalloutView
- MGLCalloutViewDelegate
- MGLMultiPoint
+ - MGLMultiPolygon
+ - MGLMultiPolyline
- MGLPointAnnotation
- MGLPolygon
- MGLPolyline
- MGLOverlay
- MGLShape
+ - MGLShapeCollection
- MGLUserLocation
+ - name: Map Data
+ children:
+ - MGLFeature
+ - MGLMultiPointFeature
+ - MGLMultiPolygonFeature
+ - MGLMultiPolylineFeature
+ - MGLPointFeature
+ - MGLPolygonFeature
+ - MGLPolylineFeature
+ - MGLShapeCollectionFeature
- name: Offline Maps
children:
- MGLOfflineRegion
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 3f54b07f41..725677a65b 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -19,6 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
@protocol MGLAnnotation;
@protocol MGLOverlay;
@protocol MGLCalloutView;
+@protocol MGLFeature;
/** The vertical alignment of an annotation within a map view. */
typedef NS_ENUM(NSUInteger, MGLAnnotationVerticalAlignment) {
@@ -1021,6 +1022,132 @@ IB_DESIGNABLE
*/
- (void)removeOverlays:(NS_ARRAY_OF(id <MGLOverlay>) *)overlays;
+#pragma mark Accessing the Underlying Map Data
+
+/**
+ Returns an array of rendered map features that intersect with a given point.
+
+ This method may return features from any of the map’s style layers. To restrict
+ the search to a particular layer or layers, use the
+ `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:` method. For more
+ information about searching for map features, see that method’s documentation.
+
+ @param point A point expressed in the map view’s coordinate system.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(CGPoint)point NS_SWIFT_NAME(visibleFeatures(at:));
+
+/**
+ Returns an array of rendered map features that intersect with a given point,
+ restricted to the given style layers.
+
+ Each object in the returned array represents a feature rendered by the
+ current style and provides access to attributes specified by the relevant
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile sources</a>.
+ The returned array includes features specified in vector and GeoJSON tile
+ sources but does not include anything from raster, image, or video sources.
+
+ Only visible features are returned. For example, suppose the current style uses
+ the
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets source</a>,
+ but none of the specified style layers includes features that have the `maki`
+ property set to `bus`. If you pass a point corresponding to the location of a
+ bus stop into this method, the bus stop feature does not appear in the
+ resulting array. On the other hand, if the style does include bus stops, an
+ `MGLFeature` object representing that bus stop is returned and its
+ `featureAttributes` dictionary has the `maki` key set to `bus` (along with
+ other attributes). The dictionary contains only the attributes provided by the
+ tile source; it does not include computed attribute values or rules about how
+ the feature is rendered by the current style.
+
+ The returned array is sorted by z-order, starting with the topmost rendered
+ feature and ending with the bottommost rendered feature. A feature that is
+ rendered multiple times due to wrapping across the antimeridian at low zoom
+ levels is included only once, subject to the caveat that follows.
+
+ Features come from tiled vector data or GeoJSON data that is converted to tiles
+ internally, so feature geometries are clipped at tile boundaries and features
+ may appear duplicated across tiles. For example, suppose the specified point
+ lies along a road that spans the screen. The resulting array includes those
+ parts of the road that lie within the map tile that contain the specified
+ point, even if the road extends into other tiles.
+
+ To find out the layer names in a particular style, view the style in
+ <a href="https://www.mapbox.com/studio/">Mapbox Studio</a>.
+
+ @param point A point expressed in the map view’s coordinate system.
+ @param styleLayerIdentifiers A set of strings that correspond to the names of
+ layers defined in the current style. Only the features contained in these
+ layers are included in the returned array.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(at:styleLayerIdentifiers:));
+
+/**
+ Returns an array of rendered map features that intersect with the given
+ rectangle.
+
+ This method may return features from any of the map’s style layers. To restrict
+ the search to a particular layer or layers, use the
+ `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:` method. For more
+ information about searching for map features, see that method’s documentation.
+
+ @param rect A rectangle expressed in the map view’s coordinate system.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(CGRect)rect NS_SWIFT_NAME(visibleFeatures(in:));
+
+/**
+ Returns an array of rendered map features that intersect with the given
+ rectangle, restricted to the given style layers.
+
+ Each object in the returned array represents a feature rendered by the
+ current style and provides access to attributes specified by the relevant
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile sources</a>.
+ The returned array includes features specified in vector and GeoJSON tile
+ sources but does not include anything from raster, image, or video sources.
+
+ Only visible features are returned. For example, suppose the current style uses
+ the
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets source</a>,
+ but none of the specified style layers includes features that have the `maki`
+ property set to `bus`. If you pass a rectangle containing the location of a bus
+ stop into this method, the bus stop feature does not appear in the resulting
+ array. On the other hand, if the style does include bus stops, an `MGLFeature`
+ object representing that bus stop is returned and its `featureAttributes`
+ dictionary has the `maki` key set to `bus` (along with other attributes). The
+ dictionary contains only the attributes provided by the tile source; it does
+ not include computed attribute values or rules about how the feature is
+ rendered by the current style.
+
+ The returned array is sorted by z-order, starting with the topmost rendered
+ feature and ending with the bottommost rendered feature. A feature that is
+ rendered multiple times due to wrapping across the antimeridian at low zoom
+ levels is included only once, subject to the caveat that follows.
+
+ Features come from tiled vector data or GeoJSON data that is converted to tiles
+ internally, so feature geometries are clipped at tile boundaries and features
+ may appear duplicated across tiles. For example, suppose the specified
+ rectangle intersects with a road that spans the screen. The resulting array
+ includes those parts of the road that lie within the map tiles covering the
+ specified rectangle, even if the road extends into other tiles. The portion of
+ the road within each map tile is included individually.
+
+ To find out the layer names in a particular style, view the style in
+ <a href="https://www.mapbox.com/studio/">Mapbox Studio</a>.
+
+ @param rect A rectangle expressed in the map view’s coordinate system.
+ @param styleLayerIdentifiers A set of strings that correspond to the names of
+ layers defined in the current style. Only the features contained in these
+ layers are included in the returned array.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(in:styleLayerIdentifiers:));
+
#pragma mark Debugging the Map
/**
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index b9acdfb1d5..44a3cbc4c8 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -26,6 +26,7 @@
#include <mbgl/util/chrono.hpp>
#import "Mapbox.h"
+#import "MGLFeature_Private.h"
#import "MGLGeometry_Private.h"
#import "MGLMultiPoint_Private.h"
#import "MGLOfflineStorage_Private.h"
@@ -2814,6 +2815,22 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
[(MGLMultiPoint *)annotation addShapeAnnotationObjectToCollection:shapes withDelegate:self];
[userShapes addObject:annotation];
}
+ else if ([annotation isKindOfClass:[MGLMultiPolyline class]])
+ {
+ // TODO: Add real support for these types down in mbgl instead of breaking the annotation apart.
+ NS_ARRAY_OF(MGLPolyline *) *polylines = [(MGLMultiPolyline *)annotation polylines];
+ [self addAnnotations:polylines];
+ }
+ else if ([annotation isKindOfClass:[MGLMultiPolygon class]])
+ {
+ NS_ARRAY_OF(MGLPolygon *) *polygons = [(MGLMultiPolygon *)annotation polygons];
+ [self addAnnotations:polygons];
+ }
+ else if ([annotation isKindOfClass:[MGLShapeCollection class]])
+ {
+ NS_ARRAY_OF(MGLShape <MGLAnnotation> *) *shapes = [(MGLShapeCollection *)annotation shapes];
+ [self addAnnotations:shapes];
+ }
else
{
MGLAnnotationView *annotationView;
@@ -4184,6 +4201,57 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
}
}
+#pragma mark Data
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(CGPoint)point
+{
+ return [self visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:nil];
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers
+{
+ mbgl::ScreenCoordinate screenCoordinate = { point.x, point.y };
+
+ mbgl::optional<std::vector<std::string>> optionalLayerIDs;
+ if (styleLayerIdentifiers)
+ {
+ __block std::vector<std::string> layerIDs;
+ layerIDs.reserve(styleLayerIdentifiers.count);
+ [styleLayerIdentifiers enumerateObjectsUsingBlock:^(NSString * _Nonnull identifier, BOOL * _Nonnull stop)
+ {
+ layerIDs.push_back(identifier.UTF8String);
+ }];
+ optionalLayerIDs = layerIDs;
+ }
+
+ std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenCoordinate, optionalLayerIDs);
+ return MGLFeaturesFromMBGLFeatures(features);
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(CGRect)rect {
+ return [self visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:nil];
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers {
+ mbgl::ScreenBox screenBox = {
+ { CGRectGetMinX(rect), CGRectGetMinY(rect) },
+ { CGRectGetMaxX(rect), CGRectGetMaxY(rect) },
+ };
+
+ mbgl::optional<std::vector<std::string>> optionalLayerIDs;
+ if (styleLayerIdentifiers) {
+ __block std::vector<std::string> layerIDs;
+ layerIDs.reserve(styleLayerIdentifiers.count);
+ [styleLayerIdentifiers enumerateObjectsUsingBlock:^(NSString * _Nonnull identifier, BOOL * _Nonnull stop) {
+ layerIDs.push_back(identifier.UTF8String);
+ }];
+ optionalLayerIDs = layerIDs;
+ }
+
+ std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenBox, optionalLayerIDs);
+ return MGLFeaturesFromMBGLFeatures(features);
+}
+
#pragma mark - Utility -
- (void)animateWithDelay:(NSTimeInterval)delay animations:(void (^)(void))animations
diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h
index 3b7361a756..013bb81614 100644
--- a/platform/ios/src/Mapbox.h
+++ b/platform/ios/src/Mapbox.h
@@ -14,8 +14,9 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLClockDirectionFormatter.h"
#import "MGLCompassDirectionFormatter.h"
#import "MGLCoordinateFormatter.h"
-#import "MGLMapCamera.h"
+#import "MGLFeature.h"
#import "MGLGeometry.h"
+#import "MGLMapCamera.h"
#import "MGLMapView.h"
#import "MGLMapView+IBAdditions.h"
#import "MGLMapView+MGLCustomStyleLayerAdditions.h"
@@ -28,6 +29,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLPolygon.h"
#import "MGLPolyline.h"
#import "MGLShape.h"
+#import "MGLShapeCollection.h"
#import "MGLStyle.h"
#import "MGLTilePyramidOfflineRegion.h"
#import "MGLTypes.h"
diff --git a/platform/osx/CHANGELOG.md b/platform/osx/CHANGELOG.md
index 67bdce1e6c..0e4da04545 100644
--- a/platform/osx/CHANGELOG.md
+++ b/platform/osx/CHANGELOG.md
@@ -3,6 +3,7 @@
## master
* Fixed an issue in which Mapbox.framework was nested inside another folder named Mapbox.framework. ([#4998](https://github.com/mapbox/mapbox-gl-native/pull/4998))
+* Added methods to MGLMapView for obtaining the underlying map data rendered by the current style. ([#5110](https://github.com/mapbox/mapbox-gl-native/pull/5110))
* Fixed a crash passing a mixture of point and shape annotations into `-[MGLMapView addAnnotations:]`. ([#5097](https://github.com/mapbox/mapbox-gl-native/pull/5097))
* Added new options to `MGLMapDebugMaskOptions` that show wireframes and the stencil buffer instead of the color buffer. ([#4359](https://github.com/mapbox/mapbox-gl-native/pull/4359))
* Fixed a memory leak when using raster resources. ([#5141](https://github.com/mapbox/mapbox-gl-native/pull/5141))
diff --git a/platform/osx/app/MapDocument.m b/platform/osx/app/MapDocument.m
index 9bff4603e4..6fcfc7ce5d 100644
--- a/platform/osx/app/MapDocument.m
+++ b/platform/osx/app/MapDocument.m
@@ -420,7 +420,8 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
if (!NSPointInRect([gestureRecognizer locationInView:self.mapView.compass], self.mapView.compass.bounds)
&& !NSPointInRect([gestureRecognizer locationInView:self.mapView.zoomControls], self.mapView.zoomControls.bounds)
&& !NSPointInRect([gestureRecognizer locationInView:self.mapView.attributionView], self.mapView.attributionView.bounds)) {
- [self dropPinAtPoint:location];
+ NSArray *features = [self.mapView visibleFeaturesAtPoint:location];
+ [self.mapView addAnnotations:features];
}
}
}
@@ -436,9 +437,17 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
}
- (DroppedPinAnnotation *)pinAtPoint:(NSPoint)point {
+ NSArray *features = [self.mapView visibleFeaturesAtPoint:point];
+ NSString *title;
+ for (id <MGLFeature> feature in features) {
+ if (!title) {
+ title = [feature attributeForKey:@"name_en"] ?: [feature attributeForKey:@"name"];
+ }
+ }
+
DroppedPinAnnotation *annotation = [[DroppedPinAnnotation alloc] init];
annotation.coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
- annotation.title = @"Dropped Pin";
+ annotation.title = title ?: @"Dropped Pin";
_spellOutNumberFormatter.numberStyle = NSNumberFormatterSpellOutStyle;
if (_showsToolTipsOnDroppedPins) {
NSString *formattedNumber = [_spellOutNumberFormatter stringFromNumber:@(++_droppedPinCounter)];
@@ -706,6 +715,10 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
}
}
+- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation {
+ return 0.8;
+}
+
@end
@interface ValidatedToolbarItem : NSToolbarItem
diff --git a/platform/osx/jazzy.yml b/platform/osx/jazzy.yml
index b1aca9bb45..9e160d050f 100644
--- a/platform/osx/jazzy.yml
+++ b/platform/osx/jazzy.yml
@@ -29,11 +29,24 @@ custom_categories:
- MGLAnnotation
- MGLAnnotationImage
- MGLMultiPoint
+ - MGLMultiPolygon
+ - MGLMultiPolyline
- MGLPointAnnotation
- MGLPolygon
- MGLPolyline
- MGLOverlay
- MGLShape
+ - MGLShapeCollection
+ - name: Map Data
+ children:
+ - MGLFeature
+ - MGLMultiPointFeature
+ - MGLMultiPolygonFeature
+ - MGLMultiPolylineFeature
+ - MGLPointFeature
+ - MGLPolygonFeature
+ - MGLPolylineFeature
+ - MGLShapeCollectionFeature
- name: Offline Maps
children:
- MGLOfflineRegion
diff --git a/platform/osx/osx.xcodeproj/project.pbxproj b/platform/osx/osx.xcodeproj/project.pbxproj
index 270b2e33d2..762cd39fa1 100644
--- a/platform/osx/osx.xcodeproj/project.pbxproj
+++ b/platform/osx/osx.xcodeproj/project.pbxproj
@@ -31,6 +31,11 @@
DA8933B81CCD2C2D00E68420 /* Foundation.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DA8933B61CCD2C2D00E68420 /* Foundation.stringsdict */; };
DAB6924A1CC75A31005AAB54 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAE6C3451CC31D1200DB3429 /* libmbgl-core.a */; };
DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */; };
+ DACC22141CF3D3E200D220D9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DACC22121CF3D3E200D220D9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACC22131CF3D3E200D220D9 /* MGLFeature.mm */; };
+ DACC22181CF3D4F700D220D9 /* MGLFeature_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */; };
+ DAD165741CF4CD7A001FF4B9 /* MGLShapeCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD165721CF4CD7A001FF4B9 /* MGLShapeCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAD165751CF4CD7A001FF4B9 /* MGLShapeCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD165731CF4CD7A001FF4B9 /* MGLShapeCollection.m */; };
DAE6C2E21CC304F900DB3429 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = DAE6C2E11CC304F900DB3429 /* Credits.rtf */; };
DAE6C2ED1CC3050F00DB3429 /* DroppedPinAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C2E41CC3050F00DB3429 /* DroppedPinAnnotation.m */; };
DAE6C2EE1CC3050F00DB3429 /* LocationCoordinate2DTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C2E61CC3050F00DB3429 /* LocationCoordinate2DTransformer.m */; };
@@ -167,6 +172,11 @@
DA8933B41CCD2C2500E68420 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Foundation.strings; sourceTree = "<group>"; };
DA8933B71CCD2C2D00E68420 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Foundation.stringsdict; sourceTree = "<group>"; };
DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationImage_Private.h; sourceTree = "<group>"; };
+ DACC22121CF3D3E200D220D9 /* MGLFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature.h; sourceTree = "<group>"; };
+ DACC22131CF3D3E200D220D9 /* MGLFeature.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFeature.mm; sourceTree = "<group>"; };
+ DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature_Private.h; sourceTree = "<group>"; };
+ DAD165721CF4CD7A001FF4B9 /* MGLShapeCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShapeCollection.h; sourceTree = "<group>"; };
+ DAD165731CF4CD7A001FF4B9 /* MGLShapeCollection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLShapeCollection.m; sourceTree = "<group>"; };
DAE6C2E11CC304F900DB3429 /* Credits.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
DAE6C2E31CC3050F00DB3429 /* DroppedPinAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DroppedPinAnnotation.h; sourceTree = "<group>"; };
DAE6C2E41CC3050F00DB3429 /* DroppedPinAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DroppedPinAnnotation.m; sourceTree = "<group>"; };
@@ -359,6 +369,80 @@
path = ../../darwin/resources;
sourceTree = "<group>";
};
+ DAD1657C1CF4CE6B001FF4B9 /* Formatters */ = {
+ isa = PBXGroup;
+ children = (
+ DA35A2BD1CCA9B1A00E826B2 /* MGLClockDirectionFormatter.h */,
+ DA35A2BE1CCA9B1A00E826B2 /* MGLClockDirectionFormatter.m */,
+ DA35A2AB1CCA091800E826B2 /* MGLCompassDirectionFormatter.h */,
+ DA35A2AC1CCA091800E826B2 /* MGLCompassDirectionFormatter.m */,
+ DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */,
+ DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */,
+ );
+ name = Formatters;
+ sourceTree = "<group>";
+ };
+ DAD1657D1CF4CECB001FF4B9 /* Geometry */ = {
+ isa = PBXGroup;
+ children = (
+ DAE6C34B1CC31E0400DB3429 /* MGLAnnotation.h */,
+ DACC22121CF3D3E200D220D9 /* MGLFeature.h */,
+ DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */,
+ DACC22131CF3D3E200D220D9 /* MGLFeature.mm */,
+ DAE6C34C1CC31E0400DB3429 /* MGLGeometry.h */,
+ DAE6C36C1CC31E2A00DB3429 /* MGLGeometry_Private.h */,
+ DAE6C36D1CC31E2A00DB3429 /* MGLGeometry.mm */,
+ DAE6C34E1CC31E0400DB3429 /* MGLMultiPoint.h */,
+ DAE6C36F1CC31E2A00DB3429 /* MGLMultiPoint_Private.h */,
+ DAE6C3701CC31E2A00DB3429 /* MGLMultiPoint.mm */,
+ DAE6C3521CC31E0400DB3429 /* MGLOverlay.h */,
+ DAE6C3531CC31E0400DB3429 /* MGLPointAnnotation.h */,
+ DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.m */,
+ DAE6C3541CC31E0400DB3429 /* MGLPolygon.h */,
+ DAE6C3771CC31E2A00DB3429 /* MGLPolygon.mm */,
+ DAE6C3551CC31E0400DB3429 /* MGLPolyline.h */,
+ DAE6C3781CC31E2A00DB3429 /* MGLPolyline.mm */,
+ DAE6C3561CC31E0400DB3429 /* MGLShape.h */,
+ DAE6C3791CC31E2A00DB3429 /* MGLShape.m */,
+ DAD165721CF4CD7A001FF4B9 /* MGLShapeCollection.h */,
+ DAD165731CF4CD7A001FF4B9 /* MGLShapeCollection.m */,
+ );
+ name = Geometry;
+ sourceTree = "<group>";
+ };
+ DAD1657E1CF4CF04001FF4B9 /* Offline Maps */ = {
+ isa = PBXGroup;
+ children = (
+ DAE6C34F1CC31E0400DB3429 /* MGLOfflinePack.h */,
+ DAE6C3711CC31E2A00DB3429 /* MGLOfflinePack_Private.h */,
+ DAE6C3721CC31E2A00DB3429 /* MGLOfflinePack.mm */,
+ DAE6C3501CC31E0400DB3429 /* MGLOfflineRegion.h */,
+ DAE6C3731CC31E2A00DB3429 /* MGLOfflineRegion_Private.h */,
+ DAE6C3511CC31E0400DB3429 /* MGLOfflineStorage.h */,
+ DAE6C3741CC31E2A00DB3429 /* MGLOfflineStorage_Private.h */,
+ DAE6C3751CC31E2A00DB3429 /* MGLOfflineStorage.mm */,
+ DAE6C3581CC31E0400DB3429 /* MGLTilePyramidOfflineRegion.h */,
+ DAE6C37B1CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm */,
+ );
+ name = "Offline Maps";
+ sourceTree = "<group>";
+ };
+ DAD1657F1CF4CF50001FF4B9 /* Categories */ = {
+ isa = PBXGroup;
+ children = (
+ DAE6C37D1CC31E2A00DB3429 /* NSBundle+MGLAdditions.h */,
+ DAE6C37E1CC31E2A00DB3429 /* NSBundle+MGLAdditions.m */,
+ DAE6C37F1CC31E2A00DB3429 /* NSException+MGLAdditions.h */,
+ DAE6C3801CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.h */,
+ DAE6C3811CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.m */,
+ DAE6C3821CC31E2A00DB3429 /* NSString+MGLAdditions.h */,
+ DAE6C3831CC31E2A00DB3429 /* NSString+MGLAdditions.m */,
+ DA35A2CD1CCAAED300E826B2 /* NSValue+MGLAdditions.h */,
+ DA35A2CE1CCAAED300E826B2 /* NSValue+MGLAdditions.m */,
+ );
+ name = Categories;
+ sourceTree = "<group>";
+ };
DAE6C31E1CC308BC00DB3429 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -404,56 +488,19 @@
DAE6C3491CC31DF500DB3429 /* Foundation */ = {
isa = PBXGroup;
children = (
+ DAD1657F1CF4CF50001FF4B9 /* Categories */,
+ DAD1657C1CF4CE6B001FF4B9 /* Formatters */,
+ DAD1657D1CF4CECB001FF4B9 /* Geometry */,
+ DAD1657E1CF4CF04001FF4B9 /* Offline Maps */,
DAE6C34A1CC31E0400DB3429 /* MGLAccountManager.h */,
DAE6C36A1CC31E2A00DB3429 /* MGLAccountManager_Private.h */,
DAE6C36B1CC31E2A00DB3429 /* MGLAccountManager.m */,
- DAE6C34B1CC31E0400DB3429 /* MGLAnnotation.h */,
- DA35A2BD1CCA9B1A00E826B2 /* MGLClockDirectionFormatter.h */,
- DA35A2BE1CCA9B1A00E826B2 /* MGLClockDirectionFormatter.m */,
- DA35A2AB1CCA091800E826B2 /* MGLCompassDirectionFormatter.h */,
- DA35A2AC1CCA091800E826B2 /* MGLCompassDirectionFormatter.m */,
- DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */,
- DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */,
- DAE6C34C1CC31E0400DB3429 /* MGLGeometry.h */,
- DAE6C36C1CC31E2A00DB3429 /* MGLGeometry_Private.h */,
- DAE6C36D1CC31E2A00DB3429 /* MGLGeometry.mm */,
DAE6C34D1CC31E0400DB3429 /* MGLMapCamera.h */,
DAE6C36E1CC31E2A00DB3429 /* MGLMapCamera.mm */,
- DAE6C34E1CC31E0400DB3429 /* MGLMultiPoint.h */,
- DAE6C36F1CC31E2A00DB3429 /* MGLMultiPoint_Private.h */,
- DAE6C3701CC31E2A00DB3429 /* MGLMultiPoint.mm */,
- DAE6C34F1CC31E0400DB3429 /* MGLOfflinePack.h */,
- DAE6C3711CC31E2A00DB3429 /* MGLOfflinePack_Private.h */,
- DAE6C3721CC31E2A00DB3429 /* MGLOfflinePack.mm */,
- DAE6C3501CC31E0400DB3429 /* MGLOfflineRegion.h */,
- DAE6C3731CC31E2A00DB3429 /* MGLOfflineRegion_Private.h */,
- DAE6C3511CC31E0400DB3429 /* MGLOfflineStorage.h */,
- DAE6C3741CC31E2A00DB3429 /* MGLOfflineStorage_Private.h */,
- DAE6C3751CC31E2A00DB3429 /* MGLOfflineStorage.mm */,
- DAE6C3521CC31E0400DB3429 /* MGLOverlay.h */,
- DAE6C3531CC31E0400DB3429 /* MGLPointAnnotation.h */,
- DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.m */,
- DAE6C3541CC31E0400DB3429 /* MGLPolygon.h */,
- DAE6C3771CC31E2A00DB3429 /* MGLPolygon.mm */,
- DAE6C3551CC31E0400DB3429 /* MGLPolyline.h */,
- DAE6C3781CC31E2A00DB3429 /* MGLPolyline.mm */,
- DAE6C3561CC31E0400DB3429 /* MGLShape.h */,
- DAE6C3791CC31E2A00DB3429 /* MGLShape.m */,
DAE6C3571CC31E0400DB3429 /* MGLStyle.h */,
DAE6C37A1CC31E2A00DB3429 /* MGLStyle.mm */,
- DAE6C3581CC31E0400DB3429 /* MGLTilePyramidOfflineRegion.h */,
- DAE6C37B1CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm */,
DAE6C3591CC31E0400DB3429 /* MGLTypes.h */,
DAE6C37C1CC31E2A00DB3429 /* MGLTypes.m */,
- DAE6C37D1CC31E2A00DB3429 /* NSBundle+MGLAdditions.h */,
- DAE6C37E1CC31E2A00DB3429 /* NSBundle+MGLAdditions.m */,
- DAE6C37F1CC31E2A00DB3429 /* NSException+MGLAdditions.h */,
- DAE6C3801CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.h */,
- DAE6C3811CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.m */,
- DAE6C3821CC31E2A00DB3429 /* NSString+MGLAdditions.h */,
- DAE6C3831CC31E2A00DB3429 /* NSString+MGLAdditions.m */,
- DA35A2CD1CCAAED300E826B2 /* NSValue+MGLAdditions.h */,
- DA35A2CE1CCAAED300E826B2 /* NSValue+MGLAdditions.m */,
);
name = Foundation;
path = ../darwin/src;
@@ -506,6 +553,7 @@
DAE6C3611CC31E0400DB3429 /* MGLOfflineStorage.h in Headers */,
DAE6C35E1CC31E0400DB3429 /* MGLMultiPoint.h in Headers */,
DAE6C3971CC31E2A00DB3429 /* NSBundle+MGLAdditions.h in Headers */,
+ DAD165741CF4CD7A001FF4B9 /* MGLShapeCollection.h in Headers */,
DAE6C3631CC31E0400DB3429 /* MGLPointAnnotation.h in Headers */,
DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */,
DAE6C35F1CC31E0400DB3429 /* MGLOfflinePack.h in Headers */,
@@ -528,6 +576,7 @@
DA35A2CF1CCAAED300E826B2 /* NSValue+MGLAdditions.h in Headers */,
DAE6C3A61CC31E9400DB3429 /* MGLMapViewDelegate.h in Headers */,
DAE6C38B1CC31E2A00DB3429 /* MGLOfflinePack_Private.h in Headers */,
+ DACC22141CF3D3E200D220D9 /* MGLFeature.h in Headers */,
DAE6C35C1CC31E0400DB3429 /* MGLGeometry.h in Headers */,
DAE6C35A1CC31E0400DB3429 /* MGLAccountManager.h in Headers */,
DAE6C35D1CC31E0400DB3429 /* MGLMapCamera.h in Headers */,
@@ -536,6 +585,7 @@
DAE6C3891CC31E2A00DB3429 /* MGLMultiPoint_Private.h in Headers */,
DAE6C3A51CC31E9400DB3429 /* MGLMapView+IBAdditions.h in Headers */,
DA35A2AD1CCA091800E826B2 /* MGLCompassDirectionFormatter.h in Headers */,
+ DACC22181CF3D4F700D220D9 /* MGLFeature_Private.h in Headers */,
DAE6C3671CC31E0400DB3429 /* MGLStyle.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -718,6 +768,7 @@
DAE6C3B71CC31EF300DB3429 /* MGLMapView.mm in Sources */,
DAE6C38C1CC31E2A00DB3429 /* MGLOfflinePack.mm in Sources */,
DAE6C3B11CC31EF300DB3429 /* MGLAnnotationImage.m in Sources */,
+ DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */,
DAE6C3B31CC31EF300DB3429 /* MGLAttributionButton.m in Sources */,
DAE6C3931CC31E2A00DB3429 /* MGLShape.m in Sources */,
DAE6C39D1CC31E2A00DB3429 /* NSString+MGLAdditions.m in Sources */,
@@ -738,6 +789,7 @@
DAE6C3851CC31E2A00DB3429 /* MGLAccountManager.m in Sources */,
DAE6C3921CC31E2A00DB3429 /* MGLPolyline.mm in Sources */,
DAE6C3B51CC31EF300DB3429 /* MGLCompassCell.m in Sources */,
+ DAD165751CF4CD7A001FF4B9 /* MGLShapeCollection.m in Sources */,
DA35A2AE1CCA091800E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1094,6 +1146,7 @@
DAAA17981CE13BAE00731EFE /* Release */,
);
defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
};
DAE6C3431CC30DB200DB3429 /* Build configuration list for PBXNativeTarget "dynamic" */ = {
isa = XCConfigurationList;
diff --git a/platform/osx/src/MGLMapView.h b/platform/osx/src/MGLMapView.h
index 749b3561d2..c08a257bea 100644
--- a/platform/osx/src/MGLMapView.h
+++ b/platform/osx/src/MGLMapView.h
@@ -35,6 +35,7 @@ typedef NS_OPTIONS(NSUInteger, MGLMapDebugMaskOptions) {
@protocol MGLAnnotation;
@protocol MGLMapViewDelegate;
@protocol MGLOverlay;
+@protocol MGLFeature;
/**
An interactive, customizable map view with an interface similar to the one
@@ -687,6 +688,132 @@ IB_DESIGNABLE
*/
- (void)removeOverlays:(NS_ARRAY_OF(id <MGLOverlay>) *)overlays;
+#pragma mark Accessing the Underlying Map Data
+
+/**
+ Returns an array of rendered map features that intersect with a given point.
+
+ This method may return features from any of the map’s style layers. To restrict
+ the search to a particular layer or layers, use the
+ `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:` method. For more
+ information about searching for map features, see that method’s documentation.
+
+ @param point A point expressed in the map view’s coordinate system.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(NSPoint)point NS_SWIFT_NAME(visibleFeatures(_:));
+
+/**
+ Returns an array of rendered map features that intersect with a given point,
+ restricted to the given style layers.
+
+ Each object in the returned array represents a feature rendered by the
+ current style and provides access to attributes specified by the relevant
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile sources</a>.
+ The returned array includes features specified in vector and GeoJSON tile
+ sources but does not include anything from raster, image, or video sources.
+
+ Only visible features are returned. For example, suppose the current style uses
+ the
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets source</a>,
+ but none of the specified style layers includes features that have the `maki`
+ property set to `bus`. If you pass a point corresponding to the location of a
+ bus stop into this method, the bus stop feature does not appear in the
+ resulting array. On the other hand, if the style does include bus stops, an
+ `MGLFeature` object representing that bus stop is returned and its
+ `attributes` dictionary has the `maki` key set to `bus` (along with other
+ attributes). The dictionary contains only the attributes provided by the
+ tile source; it does not include computed attribute values or rules about how
+ the feature is rendered by the current style.
+
+ The returned array is sorted by z-order, starting with the topmost rendered
+ feature and ending with the bottommost rendered feature. A feature that is
+ rendered multiple times due to wrapping across the antimeridian at low zoom
+ levels is included only once, subject to the caveat that follows.
+
+ Features come from tiled vector data or GeoJSON data that is converted to tiles
+ internally, so feature geometries are clipped at tile boundaries and features
+ may appear duplicated across tiles. For example, suppose the specified point
+ lies along a road that spans the screen. The resulting array includes those
+ parts of the road that lie within the map tile that contain the specified
+ point, even if the road extends into other tiles.
+
+ To find out the layer names in a particular style, view the style in
+ <a href="https://www.mapbox.com/studio/">Mapbox Studio</a>.
+
+ @param point A point expressed in the map view’s coordinate system.
+ @param styleLayerIdentifiers A set of strings that correspond to the names of
+ layers defined in the current style. Only the features contained in these
+ layers are included in the returned array.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(_:styleLayerIdentifiers:));
+
+/**
+ Returns an array of rendered map features that intersect with the given
+ rectangle.
+
+ This method may return features from any of the map’s style layers. To restrict
+ the search to a particular layer or layers, use the
+ `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:` method. For more
+ information about searching for map features, see that method’s documentation.
+
+ @param rect A rectangle expressed in the map view’s coordinate system.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(NSRect)rect NS_SWIFT_NAME(visibleFeatures(_:));
+
+/**
+ Returns an array of rendered map features that intersect with the given
+ rectangle, restricted to the given style layers.
+
+ Each object in the returned array represents a feature rendered by the
+ current style and provides access to attributes specified by the relevant
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile sources</a>.
+ The returned array includes features specified in vector and GeoJSON tile
+ sources but does not include anything from raster, image, or video sources.
+
+ Only visible features are returned. For example, suppose the current style uses
+ the
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets source</a>,
+ but none of the specified style layers includes features that have the `maki`
+ property set to `bus`. If you pass a rectangle containing the location of a bus
+ stop into this method, the bus stop feature does not appear in the resulting
+ array. On the other hand, if the style does include bus stops, an `MGLFeature`
+ object representing that bus stop is returned and its `attributes` dictionary
+ has the `maki` key set to `bus` (along with other attributes). The dictionary
+ contains only the attributes provided by the tile source; it does not include
+ computed attribute values or rules about how the feature is rendered by the
+ current style.
+
+ The returned array is sorted by z-order, starting with the topmost rendered
+ feature and ending with the bottommost rendered feature. A feature that is
+ rendered multiple times due to wrapping across the antimeridian at low zoom
+ levels is included only once, subject to the caveat that follows.
+
+ Features come from tiled vector data or GeoJSON data that is converted to tiles
+ internally, so feature geometries are clipped at tile boundaries and features
+ may appear duplicated across tiles. For example, suppose the specified
+ rectangle intersects with a road that spans the screen. The resulting array
+ includes those parts of the road that lie within the map tiles covering the
+ specified rectangle, even if the road extends into other tiles. The portion of
+ the road within each map tile is included individually.
+
+ To find out the layer names in a particular style, view the style in
+ <a href="https://www.mapbox.com/studio/">Mapbox Studio</a>.
+
+ @param rect A rectangle expressed in the map view’s coordinate system.
+ @param styleLayerIdentifiers A set of strings that correspond to the names of
+ layers defined in the current style. Only the features contained in these
+ layers are included in the returned array.
+ @return An array of objects conforming to the `MGLFeature` protocol that
+ represent features in the sources used by the current style.
+ */
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(_:styleLayerIdentifiers:));
+
#pragma mark Converting Geographic Coordinates
/**
diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm
index 5b85ff7ec2..20e59505b4 100644
--- a/platform/osx/src/MGLMapView.mm
+++ b/platform/osx/src/MGLMapView.mm
@@ -5,6 +5,7 @@
#import "MGLOpenGLLayer.h"
#import "MGLStyle.h"
+#import "MGLFeature_Private.h"
#import "MGLGeometry_Private.h"
#import "MGLMultiPoint_Private.h"
#import "MGLOfflineStorage_Private.h"
@@ -1616,6 +1617,16 @@ public:
// The multipoint knows how to style itself (with the map view’s help).
[(MGLMultiPoint *)annotation addShapeAnnotationObjectToCollection:shapes withDelegate:self];
[userShapes addObject:annotation];
+ } else if ([annotation isKindOfClass:[MGLMultiPolyline class]]) {
+ // TODO: Add real support for these types down in mbgl instead of breaking the annotation apart.
+ NS_ARRAY_OF(MGLPolyline *) *polylines = [(MGLMultiPolyline *)annotation polylines];
+ [self addAnnotations:polylines];
+ } else if ([annotation isKindOfClass:[MGLMultiPolygon class]]) {
+ NS_ARRAY_OF(MGLPolygon *) *polygons = [(MGLMultiPolygon *)annotation polygons];
+ [self addAnnotations:polygons];
+ } else if ([annotation isKindOfClass:[MGLShapeCollection class]]) {
+ NS_ARRAY_OF(MGLShape <MGLAnnotation> *) *shapes = [(MGLShapeCollection *)annotation shapes];
+ [self addAnnotations:shapes];
} else {
MGLAnnotationImage *annotationImage = nil;
if (delegateHasImagesForAnnotations) {
@@ -2246,6 +2257,55 @@ public:
}
}
+#pragma mark Data
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(NSPoint)point {
+ return [self visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:nil];
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers {
+ // Cocoa origin is at the lower-left corner.
+ mbgl::ScreenCoordinate screenCoordinate = { point.x, NSHeight(self.bounds) - point.y };
+
+ mbgl::optional<std::vector<std::string>> optionalLayerIDs;
+ if (styleLayerIdentifiers) {
+ __block std::vector<std::string> layerIDs;
+ layerIDs.reserve(styleLayerIdentifiers.count);
+ [styleLayerIdentifiers enumerateObjectsUsingBlock:^(NSString * _Nonnull identifier, BOOL * _Nonnull stop) {
+ layerIDs.push_back(identifier.UTF8String);
+ }];
+ optionalLayerIDs = layerIDs;
+ }
+
+ std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenCoordinate, optionalLayerIDs);
+ return MGLFeaturesFromMBGLFeatures(features);
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(NSRect)rect {
+ return [self visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:nil];
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers {
+ // Cocoa origin is at the lower-left corner.
+ mbgl::ScreenBox screenBox = {
+ { NSMinX(rect), NSHeight(self.bounds) - NSMaxY(rect) },
+ { NSMaxX(rect), NSHeight(self.bounds) - NSMinY(rect) },
+ };
+
+ mbgl::optional<std::vector<std::string>> optionalLayerIDs;
+ if (styleLayerIdentifiers) {
+ __block std::vector<std::string> layerIDs;
+ layerIDs.reserve(styleLayerIdentifiers.count);
+ [styleLayerIdentifiers enumerateObjectsUsingBlock:^(NSString * _Nonnull identifier, BOOL * _Nonnull stop) {
+ layerIDs.push_back(identifier.UTF8String);
+ }];
+ optionalLayerIDs = layerIDs;
+ }
+
+ std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenBox, optionalLayerIDs);
+ return MGLFeaturesFromMBGLFeatures(features);
+}
+
#pragma mark Interface Builder methods
- (void)prepareForInterfaceBuilder {
diff --git a/platform/osx/src/Mapbox.h b/platform/osx/src/Mapbox.h
index a98aea9bcf..e4545e04bc 100644
--- a/platform/osx/src/Mapbox.h
+++ b/platform/osx/src/Mapbox.h
@@ -12,6 +12,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLClockDirectionFormatter.h"
#import "MGLCompassDirectionFormatter.h"
#import "MGLCoordinateFormatter.h"
+#import "MGLFeature.h"
#import "MGLGeometry.h"
#import "MGLMapCamera.h"
#import "MGLMapView.h"
@@ -26,6 +27,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLPolygon.h"
#import "MGLPolyline.h"
#import "MGLShape.h"
+#import "MGLShapeCollection.h"
#import "MGLStyle.h"
#import "MGLTilePyramidOfflineRegion.h"
#import "MGLTypes.h"