diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm index c45b0bbda15..ba2ea6e6056 100644 --- a/platform/darwin/src/MGLFeature.mm +++ b/platform/darwin/src/MGLFeature.mm @@ -1,4 +1,5 @@ #import "MGLFeature_Private.h" +#import "MGLShapeCollectionFeature_Private.h" #import "MGLPointAnnotation.h" #import "MGLPolyline.h" @@ -177,6 +178,15 @@ - (NSDictionary *)geoJSONDictionary { return mbgl::Feature{geometry}; } +- (mbgl::FeatureCollection)mbglFeatureCollection { + mbgl::FeatureCollection featureCollection; + featureCollection.reserve(self.shapes.count); + for (id feature in self.shapes) { + featureCollection.push_back([feature mbglFeature]); + } + return featureCollection; +} + @end /** @@ -277,8 +287,7 @@ static CLLocationCoordinate2D toLocationCoordinate2D(const mbgl::Point &point } MGLShape * operator()(const mbgl::Feature &feature) const { - GeometryEvaluator evaluator; - MGLShape *shape = mapbox::geometry::geometry::visit(feature.geometry, evaluator); + MGLShape *shape = (MGLShape *)MGLFeatureFromMBGLFeature(feature); return shape; } diff --git a/platform/darwin/src/MGLShapeCollectionFeature_Private.h b/platform/darwin/src/MGLShapeCollectionFeature_Private.h new file mode 100644 index 00000000000..4f07a93b354 --- /dev/null +++ b/platform/darwin/src/MGLShapeCollectionFeature_Private.h @@ -0,0 +1,13 @@ +#import "MGLFeature.h" + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGLShapeCollectionFeature () + +- (mbgl::FeatureCollection)mbglFeatureCollection; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm index 434e6fcb1b7..987306a228e 100644 --- a/platform/darwin/src/MGLShapeSource.mm +++ b/platform/darwin/src/MGLShapeSource.mm @@ -3,6 +3,7 @@ #import "MGLMapView_Private.h" #import "MGLSource_Private.h" #import "MGLFeature_Private.h" +#import "MGLShapeCollectionFeature_Private.h" #import "MGLShape_Private.h" #import "NSURL+MGLAdditions.h" @@ -99,8 +100,15 @@ - (void)commonInit source->setGeoJSON(geojson); _shape = MGLShapeFromGeoJSON(geojson); } else { - const auto geojson = mbgl::GeoJSON{self.shape.geometryObject}; - source->setGeoJSON(geojson); + if ([self.shape isKindOfClass:[MGLShapeCollectionFeature class]]) { + MGLShapeCollectionFeature *feature = (MGLShapeCollectionFeature *)self.shape; + source->setGeoJSON(mbgl::GeoJSON{[feature mbglFeatureCollection]}); + } else if ([self.shape conformsToProtocol:@protocol(MGLFeature)]) { + id feature = (id)self.shape; + source->setGeoJSON(mbgl::GeoJSON{[feature mbglFeature]}); + } else { + source->setGeoJSON(mbgl::GeoJSON{self.shape.geometryObject}); + } } _pendingSource = std::move(source); diff --git a/platform/darwin/test/MGLShapeSourceTests.mm b/platform/darwin/test/MGLShapeSourceTests.mm index c4273e6e3f3..df90ea74d7f 100644 --- a/platform/darwin/test/MGLShapeSourceTests.mm +++ b/platform/darwin/test/MGLShapeSourceTests.mm @@ -53,7 +53,7 @@ - (void)testMGLShapeSourceWithDataMultipleFeatures { XCTAssertTrue([collection.shapes.firstObject isMemberOfClass:[MGLPolylineFeature class]]); } -- (void)testMGLShapeSourceWithSingleFeature { +- (void)testMGLShapeSourceWithSingleGeometry { MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"geojson" geoJSONData:[@"{\"type\": \"Point\", \"coordinates\": [0, 0]}" dataUsingEncoding:NSUTF8StringEncoding] options:nil]; @@ -61,6 +61,17 @@ - (void)testMGLShapeSourceWithSingleFeature { XCTAssert([source.shape isKindOfClass:[MGLPointFeature class]]); } +- (void)testMGLGeoJSONSourceWithSingleFeature { + NSString *geoJSON = @"{\"type\": \"Feature\", \"properties\": {\"color\": \"green\"}, \"geometry\": { \"type\": \"Point\", \"coordinates\": [ -114.06847000122069, 51.050459433092655 ] }}"; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"geojson" + geoJSONData:[geoJSON dataUsingEncoding:NSUTF8StringEncoding] + options:nil]; + XCTAssertNotNil(source.shape); + XCTAssert([source.shape isKindOfClass:[MGLPointFeature class]]); + MGLPointFeature *feature = (MGLPointFeature *)source.shape; + XCTAssert([feature.attributes.allKeys containsObject:@"color"]); +} + - (void)testMGLShapeSourceWithPolylineFeatures { CLLocationCoordinate2D coordinates[] = { CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(10, 10)}; MGLPolylineFeature *polylineFeature = [MGLPolylineFeature polylineWithCoordinates:coordinates count:2]; @@ -240,15 +251,11 @@ - (void)testMGLShapeSourceWithShapeCollectionFeatures { MGLShapeCollectionFeature *shapeCollectionFeature = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, pointCollectionFeature, pointFeature]]; - MGLShapeCollectionFeature *shapeCollectionFeature_1 = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, pointCollectionFeature, pointFeature, shapeCollectionFeature]]; - - - MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"source-id" shape:shapeCollectionFeature_1 options:nil]; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"source-id" shape:shapeCollectionFeature options:nil]; MGLShapeCollectionFeature *shape = (MGLShapeCollectionFeature *)source.shape; - XCTAssertNotNil(shape); - XCTAssert(shape.shapes.count == 7, @"Shape collection should contain 7 shapes"); + XCTAssert(shape.shapes.count == 6, @"Shape collection should contain 6 shapes"); } @end diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 2858753e838..9b3d003e23c 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -954,10 +954,37 @@ - (void)styleFeature [self.mapView.style addSource:source]; MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"leaf-fill-layer" source:source]; - layer.predicate = [NSPredicate predicateWithFormat:@"color = %@", @"red"]; + layer.predicate = [NSPredicate predicateWithFormat:@"color = 'red'"]; MGLStyleValue *fillColor = [MGLStyleValue valueWithRawValue:[UIColor redColor]]; layer.fillColor = fillColor; [self.mapView.style addLayer:layer]; + + NSString *geoJSON = @"{\"type\": \"Feature\", \"properties\": {\"color\": \"green\"}, \"geometry\": { \"type\": \"Point\", \"coordinates\": [ -114.06847000122069, 51.050459433092655 ] }}"; + + NSData *data = [geoJSON dataUsingEncoding:NSUTF8StringEncoding]; + MGLShapeSource *pointSource = [[MGLShapeSource alloc] initWithIdentifier:@"leaf-point-source" geoJSONData:data options:nil]; + [self.mapView.style addSource:pointSource]; + + MGLCircleStyleLayer *circleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"leaf-circle-layer" source:pointSource]; + circleLayer.circleColor = [MGLStyleValue valueWithRawValue:[UIColor greenColor]]; + circleLayer.predicate = [NSPredicate predicateWithFormat:@"color = 'green'"]; + [self.mapView.style addLayer:circleLayer]; + + + CLLocationCoordinate2D squareCoords[] = { + {51.056070541830934, -114.0274429321289}, + {51.07937094724242, -114.0274429321289}, + {51.07937094724242, -113.98761749267578}, + {51.05607054183093, -113.98761749267578}, + {51.056070541830934, -114.0274429321289}, + }; + MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:squareCoords count:sizeof(squareCoords)/sizeof(squareCoords[0])]; + MGLShapeSource *plainShapeSource = [[MGLShapeSource alloc] initWithIdentifier:@"leaf-plain-shape-source" shape:polygon options:nil]; + [self.mapView.style addSource:plainShapeSource]; + + MGLFillStyleLayer *plainFillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"leaf-plain-fill-layer" source:plainShapeSource]; + plainFillLayer.fillColor = [MGLStyleValue valueWithRawValue:[UIColor yellowColor]]; + [self.mapView.style addLayer:plainFillLayer]; } - (void)updateShapeSourceData diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 8c69d7105ec..6d778c571aa 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -592,6 +592,7 @@ 4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLTileSetTests.mm; path = ../../darwin/test/MGLTileSetTests.mm; sourceTree = ""; }; 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = ""; }; 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = ""; }; + 40986FE51DFA2B5C004A7E6E /* MGLShapeCollectionFeature_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShapeCollectionFeature_Private.h; sourceTree = ""; }; 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = ""; }; 40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLShapeSourceTests.mm; path = ../../darwin/test/MGLShapeSourceTests.mm; sourceTree = ""; }; 40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView.h; sourceTree = ""; }; @@ -1299,6 +1300,7 @@ DA8847E01CBAFA5100AB86E3 /* MGLAnnotation.h */, DAD165691CF41981001FF4B9 /* MGLFeature.h */, DAD1656A1CF41981001FF4B9 /* MGLFeature_Private.h */, + 40986FE51DFA2B5C004A7E6E /* MGLShapeCollectionFeature_Private.h */, DAD1656B1CF41981001FF4B9 /* MGLFeature.mm */, DA8847E11CBAFA5100AB86E3 /* MGLGeometry.h */, DA8848011CBAFA6200AB86E3 /* MGLGeometry_Private.h */, diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index b74260ebd8d..4997ed06312 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -300,6 +300,7 @@ 40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLAdditions.h"; sourceTree = ""; }; 40E1601A1DF216E6005EA6D9 /* MGLStyleLayerTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayerTests.h; sourceTree = ""; }; 40E1601B1DF216E6005EA6D9 /* MGLStyleLayerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLStyleLayerTests.m; sourceTree = ""; }; + 40EA2D951DFF163700103590 /* MGLShapeCollectionFeature_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShapeCollectionFeature_Private.h; sourceTree = ""; }; 52BECB091CC5A26F009CD791 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 5548BE791D0ACBB2005DDE81 /* libmbgl-loop-darwin.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-loop-darwin.a"; path = "cmake/Debug/libmbgl-loop-darwin.a"; sourceTree = ""; }; 5548BE7B1D0ACBBD005DDE81 /* libmbgl-loop-darwin.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-loop-darwin.a"; path = "cmake/Debug/libmbgl-loop-darwin.a"; sourceTree = ""; }; @@ -751,6 +752,7 @@ DAE6C34B1CC31E0400DB3429 /* MGLAnnotation.h */, DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */, DACC22121CF3D3E200D220D9 /* MGLFeature.h */, + 40EA2D951DFF163700103590 /* MGLShapeCollectionFeature_Private.h */, DACC22131CF3D3E200D220D9 /* MGLFeature.mm */, DAE6C36C1CC31E2A00DB3429 /* MGLGeometry_Private.h */, DAE6C34C1CC31E0400DB3429 /* MGLGeometry.h */,