Search code examples
mapboxgeojson

Mapbox Filter : Wanting to display display layers separately based on a property key


Using the two objects in the geojson collection as and example :

{
  "type": "Feature",
 "properties": {
      "name": "Eau minérale Mélodie",
      "id_osm": 7041403159,
      "image": "File:Eau min%C3%A9rale M%C3%A9lodie.jpg",
      "refill" : "yes"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [
        6.1281257,
        46.3431274
      ]
    }
  },
  {
    "type": "Feature",
    "properties": {
      "id_osm": 7041937865,
      "id_wikidata": "Q55169831",
      "image": "File:Alterszentrum%20Bullinger-Hardau.jpg",
      "name": "Fountain by Retirement Home Bullinger-Hardau",
      "mergedOn": "id_wikidata"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [
        8.5098981,
        47.3803762
      ]
    }
  }

I want to display the points with the key refill in a separate layer. Never cluster and a different color.

I tried :

filter: ["==", ['get', 'refill']], to no avail.

What is the best way to proceed ?

Thank you,

Stuart


Solution

  • There are a few ways to style circles added to your map based on properties in your data. The recommended approach is to add circle layer, where the circle-color of the paint property is determined by a has expression:

    map.addLayer({
      'id': 'colored-circles',
      'type': 'circle',
      'source': 'points',
      'paint': {
        'circle-radius': 10,
        /**
         * color circles by the refill property, using a 'case' and 'has' expression
         * https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/#case
         * https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/#has
         */
        'circle-color': [
          'case',
          ['has', 'refill'],
          '#fbb03b',
          /* other */ '#3bb2d0'
         ]
       }
    });
    

    The full implementation details can be found in this JSFiddle: https://jsfiddle.net/3r8zxf17/3/. Add your own Mapbox access token where indicated in order to view the resulting map and circles.

    However, with the above approach, the circles will all be in the same layer. If you would like all features with the refill property to be in a separate layer, you can add two layers to your map, as shown below, by making use of the circle-opacity property.

    /* Add a circle layer for features with the 'refill' property. */
    map.addLayer({
      'id': 'has-refill',
      'type': 'circle',
      'source': 'points',
      'paint': {
        'circle-radius': 10,
        'circle-color': '#fbb03b',
        'circle-opacity': [
          'case',
          ['has', 'refill'],
          1,
          /* other */ 0
        ]
      }
    });
    
    /* Add a circle layer for features without the 'refill' property. */
    map.addLayer({
      'id': 'no-refill',
      'type': 'circle',
      'source': 'points',
      'paint': {
        'circle-radius': 10,
        'circle-color': '#3bb2d0',
        'circle-opacity': [
          'case',
          ['has', 'refill'],
          0,
          /* other */ 1
        ]
      }
    });
    

    The complete code is in this JSFiddle: https://jsfiddle.net/9apcge3n/. You may also add your Mapbox access token to view the result here.

    Here is a screenshot of the visual result for both of the two approaches above:

    Resulting map with circle layer(s)