mapbox / mapbox/mapbox-maps-ios
feature-state styling not working.
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 601
- Forks
- 196
- PR merge metrics
- No merged PRs in 30d
Description
## Environment
- Xcode version: 15.0.1
- iOS version: 17.0.1
- Devices affected: all
- Maps SDK Version: 11.0.0-rc.1
## Observed behavior and steps to reproduce
I have created a custom map style on Mapbox Studio and uploaded a GeoJSON with several multipolygon features, the file looks like this:
```json
{
"type": "FeatureCollection",
"name": "AD_micro-regions",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"id": "AD-01_low_high",
"properties": {
"id": "AD-01",
"elevation": "low_high"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [...]
}
},
... other fetures
]
```
I defined a custom styling for the layer I created so that each feature will be colored according to the `danger_level` feature state (1, 2, 3, 4, 5):
```
[
"match",
["feature-state", "danger_level"],
[1],
"rgb(134, 231, 75)",
[2],
"rgb(249, 219, 73)",
[3],
"rgb(235, 134, 52)",
[4],
"rgb(216, 69, 49)",
[5],
"rgb(184, 64, 46)",
"rgba(0, 0, 0, 0)"
]
```
Now my plan would be to set the `danger_level` for each feature from the iOS SDK, but I can't really find a way to do it.
I tried using `setFeatureState` but it has no effect:
```swift
map.setFeatureState(
sourceId: "composite",
//sourceLayerId: "micro-regions_elevation-2p16jz",
featureId: "AD-01_low_high",
state: ["danger_level": 4],
callback: { result in
// This returns `success()`
print(result)
map.getFeatureState(
sourceId: "composite",
featureId: "AD-01_low_high",
callback: { state in
// This correctly prints `success(["danger_level": 4])`
// but the map style is not updated
print(state)
}
)
}
)
```
The code above has no effect, the state seems to be set correctly but no updates happen on the rendered map.
If I also specify the `sourceLayerId`, the second `print` statement returns an empty dictionary.
If I print `map.allSourceIdentifiers` I only see this:
```
[
MapboxMaps.SourceInfo(id: "composite", type: MapboxMaps.SourceType(rawValue: "vector")),
MapboxMaps.SourceInfo(id: "6D9AE", type: MapboxMaps.SourceType(rawValue: "geojson"))
]
```
My map has two geojson layers, not one, and 6D9AE changes id on each render. I tried using `map.allSourceIdentifiers.last!.id` as `sourceId` for the `setFeatureState` call but it had no effect.
I tried to retrieve the layer with `map.layer(withId: "micro-regions_elevation")` and it correctly returned the layer data:
```
FillLayer(id: "micro-regions_elevations", type: MapboxMaps.LayerType(rawValue: "fill"), filter: nil, source: Optional("composite"), sourceLayer: Optional("micro-regions_elevation-2p16jz"), slot: nil, minZoom: nil, maxZoom: nil, visibility: MapboxMaps.Value.constant(MapboxMaps.Visibility.visible), fillSortKey: nil, fillAntialias: nil, fillColor: Optional(MapboxMaps.Value.expression([match, [get, danger_level], 1, [rgba, 134.0, 231.00001525878906, 75.0, 1.0], 2, [rgba, 249.00001525878906, 219.00001525878906, 73.0, 1.0], 3, [rgba, 235.00001525878906, 134.0, 52.000003814697266, 1.0], 4, [rgba, 216.00001525878906, 69.0, 49.000003814697266, 1.0], 5, [rgba, 184.0, 64.0, 46.0, 1.0], [rgba, 0.0, 0.0, 0.0, 0.0]])), fillColorTransition: nil, fillEmissiveStrength: nil, fillEmissiveStrengthTransition: nil, fillOpacity: Optional(MapboxMaps.Value.constant(0.5)), fillOpacityTransition: nil, fillOutlineColor: Optional(MapboxMaps.Value.constant(MapboxMaps.StyleColor(rawValue: "rgba(0.00, 0.00, 0.00, 0.00)"))), fillOutlineColorTransition: nil, fillPattern: nil, fillTranslate: nil, fillTranslateTransition: nil, fillTranslateAnchor: nil)
```
But I still get the same result.
I also tried this alternative fill color formula wit the same result though:
```
[
"case",
["==", ["feature-state", "danger_level"], 1],
"rgb(134, 231, 75)",
["==", ["feature-state", "danger_level"], 2],
"rgb(249, 219, 73)",
["==", ["feature-state", "danger_level"], 3],
"rgb(235, 134, 52)",
["==", ["feature-state", "danger_level"], 4],
"rgb(216, 69, 49)",
["==", ["feature-state", "danger_level"], 5],
"rgb(184, 64, 46)",
"rgba(0, 0, 0, 0)"
]
```
This is my map style ID for reference: mapbox://styles/fezvrasta/clol7m5uj008q01qocvyg1fzx
What am I doing wrong?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the issue with the shown setFeatureState and getFeatureState calls, comparing the composite source, sourceLayerId, featureId, and the rendered FillLayer configuration. Check the Mapbox Maps iOS feature-state API and the referenced style to determine why the stored danger_level does not affect the fill color; done means the rendered multipolygon colors change for each feature state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, swift
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100