-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[ios, macos] Load features into shape source if possible #7339
Conversation
@boundsj, thanks for your PR! By analyzing this pull request, we identified @1ec5, @incanus and @friedbunny to be potential reviewers. |
This attempts to keep the features object intact if that is what we actually get in a "shape". Features have The WIP commit so far breaks a GeoJSON source test where a shape collection feature is nested in a shape collection feature. |
if ([feature isMemberOfClass:[MGLShapeCollectionFeature class]]) { | ||
featureCollection.push_back([self mbglFeatureCollection]); | ||
} | ||
featureCollection.push_back([feature mbglFeature]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MGLShapeCollectionFeature raises an exception upon -mbglFeature
so this would result in either a crash or a duplicate. I guess this should be in an else statement? Sorry for overlooking this. I should've added regression tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was the intent of the if statement just above here. However I don't think we need to support this case (see comment)
mbgl::FeatureCollection featureCollection; | ||
featureCollection.reserve(self.shapes.count); | ||
for (id <MGLFeaturePrivate> feature in self.shapes) { | ||
if ([feature isMemberOfClass:[MGLShapeCollectionFeature class]]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-isKindOfClass:
is more forward-compatible than -isMemberOfClass:
. Use the latter only if you want to avoid subclasses, for instance if you want to check for a shape collection that isn’t a shape collection feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. We won't ever get here if the super class, MGLShapeCollection
, is used since that is a geometry that'll be handled on a different track than what we are doing here for features.
I don't think we actually need to support nested feature collections since it does not look like they are supported in geometry.hpp
@@ -42,4 +42,10 @@ NS_DICTIONARY_OF(NSString *, id) *NSDictionaryFeatureForGeometry(NSDictionary *g | |||
|
|||
@end | |||
|
|||
@protocol MGLFeatureCollectionPrivate <NSObject> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hidden protocols are dangerous because they make it easy to write code that crashes on unrecognized selectors. MGLFeaturePrivate is necessary because MGLFeature is a protocol, but if MGLShapeCollectionFeature is the only class that would conform to this hidden protocol, it’d be safer to declare a Private
extension on MGLShapeCollectionFeature specifically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.
MGLShapeCollectionFeature
declares conformance to MGLFeaturePrivate
(and raises an exception) if you call the only method in that protocol. I just realized / remembered that this allows for the transformation in GeometryEvaluator
.
b245a63
to
24f8abb
Compare
It looks like plain old shapes (i.e. MGLPolygon instead of MGLPolygonFeature) still don't get drawn. I'm going to try and fix that, if possible, before this lands. |
Actually this works fine. Not sure what I was seeing before, probably crossed lat/lng in my test data. |
cfed7a8
to
4ad4f8d
Compare
Squashed and rebased on top of #7334 |
4ad4f8d
to
a2a66bf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two more changes to make, but otherwise this looks good.
@@ -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 isMemberOfClass:[MGLShapeCollectionFeature class]]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using -isKindOfClass:
will also avoid latent bugs if we ever end up needing to subclass MGLShapeCollectionFeature ourselves.
@@ -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>"; }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this file to macos.xcodeproj too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's strange... it is added locally. I'll try to figure out why it is not in this changeset
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR blocks #7377, where the conversion from an MGLFeature to an mbgl feature will be used as part of a general-purpose GeoJSON (de)serialization utility. |
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
a2a66bf
to
219aea8
Compare
* release-ios-v3.4.0: [ios] Fixed crash on launch in iosapp [ios] Fix iosapp runtime styling examples (#7395) [ios, macos] handle duplicate layer error [core] guard against duplicate layer ids [core] use raii to guard backend deactivation [ios, macos] Override references to property names in property requirements lists (#7391) [ios, macos] Load features into shape source if possible (#7339) [ios, macos] Expanded source documentation [ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334) [ios, macos] Silence -Wc++11-narrowing warning in open gl layer (#7355) [ios, macos] Source-driven attribution (#5999) [ios, macos] renamed raster-hue-rotate # Conflicts: # platform/darwin/src/MGLRasterSource.h # platform/darwin/src/MGLShapeSource.h # platform/darwin/src/MGLSource.h # platform/darwin/src/MGLVectorSource.h
* release-ios-v3.4.0: [ios] Fixed crash on launch in iosapp [ios] Fix iosapp runtime styling examples (#7395) [ios, macos] handle duplicate layer error [core] guard against duplicate layer ids [core] use raii to guard backend deactivation [ios, macos] Override references to property names in property requirements lists (#7391) [ios, macos] Load features into shape source if possible (#7339) [ios, macos] Expanded source documentation [ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334) [ios, macos] Silence -Wc++11-narrowing warning in open gl layer (#7355) [ios, macos] Source-driven attribution (#5999) [ios, macos] renamed raster-hue-rotate
* release-ios-v3.4.0: [ios] Fixed crash on launch in iosapp [ios] Fix iosapp runtime styling examples (#7395) [ios, macos] handle duplicate layer error [core] guard against duplicate layer ids [core] use raii to guard backend deactivation [ios, macos] Override references to property names in property requirements lists (#7391) [ios, macos] Load features into shape source if possible (#7339) [ios, macos] Expanded source documentation [ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334) [ios, macos] Silence -Wc++11-narrowing warning in open gl layer (#7355) [ios, macos] Source-driven attribution (#5999) [ios, macos] renamed raster-hue-rotate # Conflicts: # platform/ios/jazzy.yml
fixes #7336