mapbox / mapbox/mapbox-maps-ios

SourceQueryOptions filter does not work correctly

Open
#1,947 0 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auto-triaged bug :beetle:
Dominant language
Swift
Stars
601
Forks
196
PR merge metrics
No merged PRs in 30d

Description

## Environment

- Xcode version: 13-14 many versions
- iOS version: 15-16 many versions
- Devices affected: all tested iOS devices
- Maps SDK Version: the most recent stable one

## Observed behavior and steps to reproduce

**I'd like to filter features from a source based on (some property) AND (distance within a radius).**

### I could not find a way to convert the point to the filter expression.
There is not much document about SourceQueryOptions in iOS SDK, and there is no example using that neither.
I've been struggling to make it work for the last few days. I've checked many iOS and GL-JS documents and stack overflow, none of them worked for me.

The code is pretty much like the one below

```swift
let coord = CLLocationCoordinate2D(xxx)
let point = Turf.Feature(geometry: Point(coord))
var sqo = SourceQueryOptions(sourceLayerIds: [xxx],
filter: ["all", ["==", ["get", "SUMLEV"], 750], ["<", ["distance", GeoJSONObject.feature(point)], 100]])
mapboxMap.querySourceFeatures(for: layerAllPopStats.sourceData.sourceStrId, options: sqo) { xxxx }
```

However, the app would crash and the Xcode error log reads:
```terminal
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Value Turf.GeoJSONObject.feature(feature id:
empty_features: ) of type __SwiftValue must be either NSNumber, NSString, NSArray, NSDictionary, NSNull'
```

I tried to replace ```GeoJSONObject.feature(point)``` to ```Turf.Point(coord)``` and many other values, none would work.

### Standard Swift/iOS expression does not work for filter.
I also noticed the standard Swift/iOS way to define ```expression``` does not work for the filter case.
For example, if I use as simple as
```swift
let filter = Exp(.eq) {
Exp(.get) { "SUMLEV"}
750
}
var sqo = SourceQueryOptions(sourceLayerIds: [xxx], filter: filter)
```
It would not work, the Xcode would crash with error:
```terminal
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Value [==, [get, SUMLEV], 750.0] of type __SwiftValue must be either NSNumber, NSString, NSArray, NSDictionary, NSNull'
```
But if I use
```swift
let filter: [Any] = ["==", "SUMLEV", 750]
var sqo = SourceQueryOptions(sourceLayerIds: [xxx], filter: filter)
```
It would work.

### The ```'all'``` expression seems not working correctly
For example:
```swift
let filter: [Any] = ["==", "SUMLEV", 750]
```
will return me ~5k features;
But when I also used
```swift
let filter: [Any] = ["all", ["==", ["get", "SUMLEV"], 750], ["<", ["distance", "userPosition", "meters"], 100]]
```
It will return me >7k features and the result seems not correct. It returns many features have ```SUMLEV != 750```.
So it looks like the ```"all"``` AND condition is not respected.

## Expected behavior

**I'd like to filter features from a source based on (some property) AND (distance within a radius).**

## Notes / preliminary analysis

## Additional links and references

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the examples using SourceQueryOptions and querySourceFeatures, comparing the raw [Any] filters with the Swift Exp expression and distance forms. Investigate the reported crashes and the incorrect all results; done means filtering by SUMLEV and distance works together without crashing and excludes nonmatching features.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, swift
Domain
api, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.