Mapbox filters based on array
Asked Answered
E

5

8

I have the following array:

test = ['a', 'b', 'c']

I would like to filter objects on the map if they exist in the array. Is it possible to use this filter with array:

mapObj.setFilter("hover", ['all', ["in", "letter", test[0]]]);

Or alternately, what is the best way to filter object that exist in the array?

Emmett answered 9/8, 2017 at 16:51 Comment(0)
F
13

Well mapbox's setFilter function does not accept an array as a parameter. You will need to use a format that fits their API which is basically described here under "Set Membership Filters".

https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#filter

To filter multiple variables the Set Membership Filters require a specific format which is

["in", key, v0, ..., vn]

Where v0 to vn are elements of your array which yields

["in", "letter", "a", "b", "c"]

One could write a function to convert an array to this format. Maybe like this:

function buildFilter(arr) {
  var filter = ['in', 'letter'];

  if (arr.length === 0) {
     return filter;
  }
  
  for(var i = 0; i < arr.length; i += 1) {
    filter.push(arr[i]);
  }
  
  return filter;
}

var filterBy = ['a', 'b', 'c'];
var myFilter = buildFilter(filterBy);

console.log(myFilter);

// then you would use it like this:
// mapObj.setFilter("hover", buildFilter(['a', 'b', 'c']));
Fotheringhay answered 9/8, 2017 at 17:24 Comment(0)
A
5

["in", "letter", ...test] in ES6

should work.

Acetanilide answered 2/12, 2020 at 16:9 Comment(1)
It's an elegant way to do it. ThanksConverter
S
3

You can also use:

['in', 'letter'].concat(test);

Where test is your array of values.

Sweepback answered 24/3, 2020 at 16:41 Comment(0)
E
0

Actually there is a native way of doing this, as shown in the "Filter features within mapview" example.

You will have to use a unique attribute of your elements (ideally a unique ID). In your case, given that the attribute is "letter", the code would be the following:

mapObj.setFilter('hover', ['match', ['get', 'letter'], test, true, false])

For a better understanding of the code, take a look at the documentation about the match expression.

Englert answered 23/5, 2018 at 10:9 Comment(0)
N
0

I used it with .map like in this. I think you should avoid an extra method for concatenation.

         this.$store.map.setFilter(layerName, [
          'match',
          ['get', filterPropertyName],
          currentValues.map((feature) => {
            return feature;
          }),
          true,
          false
        ])
Naughton answered 11/10, 2021 at 15:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.