[ios, macos] Load features into shape source if possible (#7339)
This checks the kind of MGLShape passed into the source and, if it is a feature, it mbgl feature objects to pass to core. This keeps the feature id and attributes data intact. If the shape is a `MGLShapeCollectionFeature` it creates an `mbgl::FeatureCollection` object (also to keep feature properties). If the shape is not any sort of feature, it passes along just the geometry. This also uses the MGLFeatureFromMBGLFeature converter for the case where GeoJSON data passed in to a source contains a single feature. The converter has logic to keep the id and attributes properties intact. Before, these properties were lost because only geometry conversion was done. Finally, logic to handle (and associated tests) of nested shape collection features is removed since that is not supported by the GeoJSON spec or the core implementation. [ios] Add test of drawing plain shape to iosapp
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#import "MGLFeature_Private.h"
|
||||
#import "MGLShapeCollectionFeature_Private.h"
|
||||
|
||||
#import "MGLPointAnnotation.h"
|
||||
#import "MGLPolyline.h"
|
||||
@@ -177,6 +178,15 @@
|
||||
return mbgl::Feature{geometry};
|
||||
}
|
||||
|
||||
- (mbgl::FeatureCollection)mbglFeatureCollection {
|
||||
mbgl::FeatureCollection featureCollection;
|
||||
featureCollection.reserve(self.shapes.count);
|
||||
for (id <MGLFeaturePrivate> feature in self.shapes) {
|
||||
featureCollection.push_back([feature mbglFeature]);
|
||||
}
|
||||
return featureCollection;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
@@ -277,8 +287,7 @@ public:
|
||||
}
|
||||
|
||||
MGLShape <MGLFeaturePrivate> * operator()(const mbgl::Feature &feature) const {
|
||||
GeometryEvaluator<T> evaluator;
|
||||
MGLShape <MGLFeaturePrivate> *shape = mapbox::geometry::geometry<T>::visit(feature.geometry, evaluator);
|
||||
MGLShape <MGLFeaturePrivate> *shape = (MGLShape <MGLFeaturePrivate> *)MGLFeatureFromMBGLFeature(feature);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
13
platform/darwin/src/MGLShapeCollectionFeature_Private.h
Normal file
13
platform/darwin/src/MGLShapeCollectionFeature_Private.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#import "MGLFeature.h"
|
||||
|
||||
#import <mbgl/util/feature.hpp>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MGLShapeCollectionFeature ()
|
||||
|
||||
- (mbgl::FeatureCollection)mbglFeatureCollection;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -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 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh
|
||||
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<MGLFeaturePrivate> feature = (id<MGLFeaturePrivate>)self.shape;
|
||||
source->setGeoJSON(mbgl::GeoJSON{[feature mbglFeature]});
|
||||
} else {
|
||||
source->setGeoJSON(mbgl::GeoJSON{self.shape.geometryObject});
|
||||
}
|
||||
}
|
||||
|
||||
_pendingSource = std::move(source);
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
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 @@
|
||||
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 @@
|
||||
|
||||
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
|
||||
|
||||
@@ -954,10 +954,37 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
|
||||
[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<UIColor *> 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
|
||||
|
||||
@@ -592,6 +592,7 @@
|
||||
4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLTileSetTests.mm; path = ../../darwin/test/MGLTileSetTests.mm; sourceTree = "<group>"; };
|
||||
408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = "<group>"; };
|
||||
408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = "<group>"; };
|
||||
40986FE51DFA2B5C004A7E6E /* MGLShapeCollectionFeature_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShapeCollectionFeature_Private.h; sourceTree = "<group>"; };
|
||||
40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = "<group>"; };
|
||||
40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLShapeSourceTests.mm; path = ../../darwin/test/MGLShapeSourceTests.mm; sourceTree = "<group>"; };
|
||||
40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView.h; sourceTree = "<group>"; };
|
||||
@@ -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 */,
|
||||
|
||||
@@ -300,6 +300,7 @@
|
||||
40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLAdditions.h"; sourceTree = "<group>"; };
|
||||
40E1601A1DF216E6005EA6D9 /* MGLStyleLayerTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayerTests.h; sourceTree = "<group>"; };
|
||||
40E1601B1DF216E6005EA6D9 /* MGLStyleLayerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLStyleLayerTests.m; sourceTree = "<group>"; };
|
||||
40EA2D951DFF163700103590 /* MGLShapeCollectionFeature_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShapeCollectionFeature_Private.h; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
5548BE7B1D0ACBBD005DDE81 /* libmbgl-loop-darwin.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-loop-darwin.a"; path = "cmake/Debug/libmbgl-loop-darwin.a"; sourceTree = "<group>"; };
|
||||
@@ -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 */,
|
||||
|
||||
Reference in New Issue
Block a user