10

I've got a relational dataset broken into two layers: members and organizations. They're GeoJSON, with features that look something like this:

// Org Features
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [-78.34998, 37.784]
  },
  "properties": {
    "id": 46391,
    "name": "A Big Organization",
    "lifetime_profiles": 7013,
    "present_profiles": 49
  }
}
// Member Features
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [-80.99998, 47.7624]
  },
  "properties": {
    "id": 21446,
    "given_name": "John",
    "family_name": "Doe",
    "orgs": [21437, 117028]
  }
}

I want to show which members are linked to which organizations when I click on the map. I'm trying to do so using the following filter:

const handleClick = (target) => {
  const bbox = [
     [target.point.x - 5, target.point.y - 5], 
     [target.point.x + 5, target.point.y + 5]
  ];
  const opt = { layers: ['orgs'] };
  const targetIDs = map.queryRenderedFeatures(bbox, opt).map((feature) => {
    return feature.properties.id;
  });
  // find clicked orgs
  map.setFilter('users', ['in', 'orgs', ...targetIDs]);
};

From my earlier research, I've gathered that the "in" filter is deprecated now. How can I accomplish this aim using current filters?

3
  • Did you find out ?
    – gordie
    Apr 28, 2022 at 17:36
  • 1
    I did ! stackoverflow.com/questions/72046546/…
    – gordie
    Apr 28, 2022 at 18:07
  • 1
    @gordie you're bang on the money with that after so long! If you add it as an answer here (or at least link to it) I'll mark it correct.
    – nronnei
    Jan 23, 2023 at 21:40

2 Answers 2

3

adapted from here:

const handleClick = target => {
  const bbox = [
     [target.point.x - 5, target.point.y - 5], 
     [target.point.x + 5, target.point.y + 5]
  ];
  const opt = { layers: ['orgs'] };

  //get matching orgs ids
  const orgIds = map.queryRenderedFeatures(bbox, opt).map((feature) => {
    return feature.properties.id;
  });

  if (orgIds){

    const filterByOrgs = ids => {
      if ( (ids || []).length === 0) return;
    
      //single expression for each org ID
      const orgFilters = ids.map(id=>['in',id,['get', 'orgs']])
    
      //merge all expressions
      return ['any'].concat(orgFilters);
    
    }
  
    map.setFilter("users",filterByOrgs(orgIds));
  }

};
0

I guess you're referring to "deprecated syntax" from https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter ?

I don't really get why it is, because all those filters syntax still works on last MapBox versions. However it seems that "match" now replace "in". From https://github.com/mapbox/mapbox-gl-js/issues/6144:

The match expression provides an equivalent that's almost as concise as "in"

1
  • That's correct, I found the same GH issue while digging. My problem is that I'd like to use ["match", 123, ["get", "orgs"], true, false] to see if 123 is in a property of the feature on the target layer. All the examples I've found say the "get" part has to come before the comparison array.
    – nronnei
    Oct 11, 2018 at 0:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.