Querying features in Mapbox iOS SDK 10

Viewed 183

I'm currently migrating from Mapbox Maps SDK 6.x.x to mapbox-maps-ios 10.2.0 and I'm attempting to add a symbol layer by querying for feature data containing location coordinates to assign those coordinates to points in the layer.

Previously in Mapbox 6.x.x, I would query for these coordinates through a style's MGLVectorTileSource using featuresInSourceLayersWithIdentifiers like:

((style.source(withIdentifier: "source-identifier") as? MGLVectorTileSource)?.features(sourceLayerIdentifiers: Set(["layer-feature-centers"]), predicate: nil))

mapbox-maps-ios 10.2.0 does not directly appear to support getting features in source layers like this. The data in our source is VectorSource data and not GeoJSONSourceData so I can't directly obtain the features / feature collection from the vector source.

Instead, there appears to be a function to query source features through the mapboxMap like:

mapView.mapboxMap
.querySourceFeatures(for: "source-identifier", options: SourceQueryOptions(sourceLayerIds: ["layer-feature-centers"], filter: [:])) 
{ result in }

However, while the featuresInSourceLayersWithIdentifiers appears to return items, querySourceFeatures used the same way does not. Is the second function intended to replace the old querying behavior or are there differences in how features are queried for in Mapbox 10.2.0 vs 6.x.x?

1 Answers

I used a similar function to query for rendered features, here's my code, hope you can adapt it to your use:

    // Get the CGPoint where the user tapped.
    let spot = gesture.location(in: mapView)

    // Access the feature at that point within the waypoints layer.
    let options = RenderedQueryOptions(layerIds: ["waypoint4"], filter: nil)
    self.mapView.mapboxMap.queryRenderedFeatures(with: spot, options: options) { res in
        switch res {
        case .success(let queriedFeature):
            guard let props = queriedFeature.first?.feature.properties else { return }
            guard let name = props["name"] else { return }
            switch name {
            case .string(let name):
                // do something with name
            default: break
            }
        case .failure(let error):
            print(error.localizedDescription)
        }
    }
Related